From 3a847a3e78a64d50a645120f308cab82905140d5 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Mon, 24 Jun 2024 13:39:01 +0300 Subject: [PATCH 01/22] (feat) O3-3443 Command in the OpenMRS CLI to package up a configuratio --- .../tooling/openmrs/src/commands/index.ts | 1 + .../openmrs/src/commands/merge-configs.ts | 124 ++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 packages/tooling/openmrs/src/commands/merge-configs.ts diff --git a/packages/tooling/openmrs/src/commands/index.ts b/packages/tooling/openmrs/src/commands/index.ts index 65b4a360f..742a4c05e 100644 --- a/packages/tooling/openmrs/src/commands/index.ts +++ b/packages/tooling/openmrs/src/commands/index.ts @@ -3,3 +3,4 @@ export * from './build'; export * from './debug'; export * from './develop'; export * from './start'; +export * from './merge-configs'; diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts new file mode 100644 index 000000000..84d2a7ea4 --- /dev/null +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -0,0 +1,124 @@ +import express from 'express'; +import * as fs from 'fs/promises'; +import * as path from 'path'; +import { logInfo, logWarn } from '../utils'; + +interface Config { + [key: string]: any; +} + +interface MergeConfigArgs { + directories: string[]; + output: string; + port: number; +} + +interface ConfigModule { + configSchema: Config; +} + +async function readConfigFile(filePath: string): Promise { + try { + const data = await fs.readFile(filePath, 'utf8'); + const configFunction = new Function('exports', 'require', 'module', '__filename', '__dirname', data); + const module: ConfigModule = { configSchema: {} }; + configFunction(module, require, module, filePath, path.dirname(filePath)); + return module.configSchema; + } catch (error) { + logWarn(`Error reading or parsing file ${filePath}: ${error.message}`); + return null; + } +} + +function mergeConfigs(configs: (Config | null)[]): Config { + const mergedConfig: Config = {}; + + configs.forEach((config) => { + if (config === null) { + return; + } + + Object.keys(config).forEach((key) => { + if (typeof config[key] === 'object' && !Array.isArray(config[key])) { + mergedConfig[key] = { ...mergedConfig[key], ...config[key] }; + } else { + mergedConfig[key] = config[key]; + } + }); + }); + + return mergedConfig; +} + +async function writeConfigFile(filePath: string, config: Config): Promise { + try { + const content = `import { validators, Type } from '@openmrs/esm-framework'; + +export const configSchema = ${JSON.stringify(config, null, 2)}; +`; + await fs.writeFile(filePath, content, 'utf8'); + logInfo(`Merged configuration written to ${filePath}`); + } catch (error) { + logWarn(`Error writing to file ${filePath}: ${error.message}`); + } +} + +async function packageConfigs(configDirs: string[], outputFilePath: string): Promise { + const configs: (Config | null)[] = []; + + for (const dir of configDirs) { + try { + const files = await fs.readdir(dir); + for (const file of files) { + if (path.extname(file) === '.ts' || path.extname(file) === '.js') { + const filePath = path.join(dir, file); + const config = await readConfigFile(filePath); + configs.push(config); + } + } + } catch (error) { + logWarn(`Error reading directory ${dir}: ${error.message}`); + } + } + + const mergedConfig = mergeConfigs(configs.filter(Boolean) as Config[]); + await writeConfigFile(outputFilePath, mergedConfig); +} + +//server setup +const app = express(); +app.use(express.json()); + +app.post('/merge-configs', async (req, res) => { + const { directories, output } = req.body; + + if (!directories || !output) { + return res.status(400).send('directories and output are required'); + } + + try { + await packageConfigs(directories, output); + res.status(200).send(`Merged configuration written to ${output}`); + } catch (error) { + logWarn(`Failed to package configs: ${error.message}`); + res.status(500).send(`Failed to package configs: ${error.message}`); + } +}); + +export function runMergeConfigServer(args: MergeConfigArgs) { + const { directories, output, port } = args; + + app.post('/merge-configs', async (req, res) => { + try { + await packageConfigs(directories, output); + res.status(200).send(`Merged configuration written to ${output}`); + } catch (error) { + logWarn(`Failed to package configs: ${error.message}`); + res.status(500).send(`Failed to package configs: ${error.message}`); + } + }); + + app.listen(port, () => { + logInfo(`Server is running on port ${port}`); + }); +} From 0f32a94f7535c01918901b2cb0a212e8e687a637 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Mon, 24 Jun 2024 19:25:21 +0300 Subject: [PATCH 02/22] Attemped codeql cheak --- .../openmrs/src/commands/merge-configs.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index 84d2a7ea4..35d660dd3 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -89,26 +89,32 @@ async function packageConfigs(configDirs: string[], outputFilePath: string): Pro const app = express(); app.use(express.json()); +function cleanPath(inputPath: string): string { + return path.normalize(inputPath).replace(/^(\.\.(\/|\\|$))+/, ''); +} + app.post('/merge-configs', async (req, res) => { - const { directories, output } = req.body; + let { directories, output } = req.body; - if (!directories || !output) { - return res.status(400).send('directories and output are required'); + if (!Array.isArray(directories) || typeof output !== 'string') { + return res.status(400).send('Invalid directories or output path'); } + directories = directories.map(cleanPath); + output = cleanPath(output); + try { await packageConfigs(directories, output); res.status(200).send(`Merged configuration written to ${output}`); } catch (error) { logWarn(`Failed to package configs: ${error.message}`); - res.status(500).send(`Failed to package configs: ${error.message}`); } }); export function runMergeConfigServer(args: MergeConfigArgs) { const { directories, output, port } = args; - app.post('/merge-configs', async (req, res) => { + app.post('/merge-configs', async (_, res) => { try { await packageConfigs(directories, output); res.status(200).send(`Merged configuration written to ${output}`); From 590c84e123a370b104ae5e5eccd00f128737b911 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Mon, 24 Jun 2024 20:35:54 +0300 Subject: [PATCH 03/22] trying to fix codeQL failed test --- .../tooling/openmrs/src/commands/merge-configs.ts | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index 35d660dd3..4699d203a 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -89,20 +89,13 @@ async function packageConfigs(configDirs: string[], outputFilePath: string): Pro const app = express(); app.use(express.json()); -function cleanPath(inputPath: string): string { - return path.normalize(inputPath).replace(/^(\.\.(\/|\\|$))+/, ''); -} - app.post('/merge-configs', async (req, res) => { - let { directories, output } = req.body; + const { directories, output } = req.body; - if (!Array.isArray(directories) || typeof output !== 'string') { + if (!directories || !output) { return res.status(400).send('Invalid directories or output path'); } - directories = directories.map(cleanPath); - output = cleanPath(output); - try { await packageConfigs(directories, output); res.status(200).send(`Merged configuration written to ${output}`); From 01c7bb041c4d285ad78e8115311b51082bc1728f Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Mon, 24 Jun 2024 23:52:02 +0300 Subject: [PATCH 04/22] Clean Path --- .../openmrs/src/commands/merge-configs.ts | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index 4699d203a..ae0ffd230 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -96,14 +96,49 @@ app.post('/merge-configs', async (req, res) => { return res.status(400).send('Invalid directories or output path'); } + // Validate the output path + if (!isValidPath(output)) { + return res.status(400).send('Invalid output path'); + } + + // Sanitize and validate directories + const sanitizedDirectories = directories.filter((dir) => isValidPath(dir)); + if (sanitizedDirectories.length !== directories.length) { + return res.status(400).send('One or more directory paths are invalid'); + } + try { - await packageConfigs(directories, output); + await packageConfigs(sanitizedDirectories, path.resolve(output)); res.status(200).send(`Merged configuration written to ${output}`); } catch (error) { logWarn(`Failed to package configs: ${error.message}`); } }); +function isValidPath(p: string): boolean { + // Check if the path is empty + if (p === '') { + return false; + } + + // Check for absolute path (starting with / or \ on Windows) + const isAbsolutePath = p.startsWith('/') || /^[a-zA-Z]:[\\/]/.test(p); + + // Validate characters: allow only alphanumeric characters, underscores, dashes, periods, and slashes + const validCharactersRegex = /^[a-zA-Z0-9_\-./\\]+$/; + if (!validCharactersRegex.test(p)) { + return false; + } + + // Check for consecutive slashes or backslashes + if (/\/{2,}|\\{2,}/.test(p)) { + return false; + } + + // If it's an absolute path or passes all checks for relative paths, return true + return isAbsolutePath || !isAbsolutePath; +} + export function runMergeConfigServer(args: MergeConfigArgs) { const { directories, output, port } = args; From 938cacd49f14ec563db5197e95d2656ba6260bdf Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Tue, 25 Jun 2024 13:09:08 +0300 Subject: [PATCH 05/22] CodeQL --- .../tooling/openmrs/src/commands/merge-configs.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index ae0ffd230..4bda9f581 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -18,6 +18,14 @@ interface ConfigModule { } async function readConfigFile(filePath: string): Promise { + const safeDir = path.join(__dirname, 'config'); // Example safe directory + + // Check if filePath starts with safeDir + if (!filePath.startsWith(safeDir)) { + logWarn(`Attempted to read file from an unsafe location: ${filePath}`); + return null; + } + try { const data = await fs.readFile(filePath, 'utf8'); const configFunction = new Function('exports', 'require', 'module', '__filename', '__dirname', data); @@ -130,11 +138,15 @@ function isValidPath(p: string): boolean { return false; } - // Check for consecutive slashes or backslashes if (/\/{2,}|\\{2,}/.test(p)) { return false; } + if (p.includes('..') || p.includes('~') || p.includes(':')) { + // Disallow parent directory traversal (~), other special characters (:) + return false; + } + // If it's an absolute path or passes all checks for relative paths, return true return isAbsolutePath || !isAbsolutePath; } From e5d82cbc2c2ab248580a981c6fd336bf95565547 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Tue, 25 Jun 2024 15:41:53 +0300 Subject: [PATCH 06/22] Removed server side environment --- .../openmrs/src/commands/merge-configs.ts | 74 +------------------ 1 file changed, 4 insertions(+), 70 deletions(-) diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index 4bda9f581..ee3f8939e 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -1,4 +1,3 @@ -import express from 'express'; import * as fs from 'fs/promises'; import * as path from 'path'; import { logInfo, logWarn } from '../utils'; @@ -93,78 +92,13 @@ async function packageConfigs(configDirs: string[], outputFilePath: string): Pro await writeConfigFile(outputFilePath, mergedConfig); } -//server setup -const app = express(); -app.use(express.json()); - -app.post('/merge-configs', async (req, res) => { - const { directories, output } = req.body; - - if (!directories || !output) { - return res.status(400).send('Invalid directories or output path'); - } - - // Validate the output path - if (!isValidPath(output)) { - return res.status(400).send('Invalid output path'); - } - - // Sanitize and validate directories - const sanitizedDirectories = directories.filter((dir) => isValidPath(dir)); - if (sanitizedDirectories.length !== directories.length) { - return res.status(400).send('One or more directory paths are invalid'); - } +export async function runMergeConfigServer(args: MergeConfigArgs) { + const { directories, output, port } = args; try { - await packageConfigs(sanitizedDirectories, path.resolve(output)); - res.status(200).send(`Merged configuration written to ${output}`); + await packageConfigs(directories, output); + logInfo(`Merged configuration written to ${output}`); } catch (error) { logWarn(`Failed to package configs: ${error.message}`); } -}); - -function isValidPath(p: string): boolean { - // Check if the path is empty - if (p === '') { - return false; - } - - // Check for absolute path (starting with / or \ on Windows) - const isAbsolutePath = p.startsWith('/') || /^[a-zA-Z]:[\\/]/.test(p); - - // Validate characters: allow only alphanumeric characters, underscores, dashes, periods, and slashes - const validCharactersRegex = /^[a-zA-Z0-9_\-./\\]+$/; - if (!validCharactersRegex.test(p)) { - return false; - } - - if (/\/{2,}|\\{2,}/.test(p)) { - return false; - } - - if (p.includes('..') || p.includes('~') || p.includes(':')) { - // Disallow parent directory traversal (~), other special characters (:) - return false; - } - - // If it's an absolute path or passes all checks for relative paths, return true - return isAbsolutePath || !isAbsolutePath; -} - -export function runMergeConfigServer(args: MergeConfigArgs) { - const { directories, output, port } = args; - - app.post('/merge-configs', async (_, res) => { - try { - await packageConfigs(directories, output); - res.status(200).send(`Merged configuration written to ${output}`); - } catch (error) { - logWarn(`Failed to package configs: ${error.message}`); - res.status(500).send(`Failed to package configs: ${error.message}`); - } - }); - - app.listen(port, () => { - logInfo(`Server is running on port ${port}`); - }); } From 24a1420b600c4eb59c990e6f1adb53b034521e01 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Tue, 25 Jun 2024 16:03:10 +0300 Subject: [PATCH 07/22] Removed port number from args --- packages/tooling/openmrs/src/commands/merge-configs.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index ee3f8939e..f35a3e292 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -9,7 +9,6 @@ interface Config { interface MergeConfigArgs { directories: string[]; output: string; - port: number; } interface ConfigModule { @@ -93,7 +92,7 @@ async function packageConfigs(configDirs: string[], outputFilePath: string): Pro } export async function runMergeConfigServer(args: MergeConfigArgs) { - const { directories, output, port } = args; + const { directories, output } = args; try { await packageConfigs(directories, output); From 8ee14cedc6b793beba577053e0f0c118f12d02f5 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Tue, 25 Jun 2024 18:40:04 +0300 Subject: [PATCH 08/22] Added ending colon --- packages/tooling/openmrs/src/commands/merge-configs.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index f35a3e292..cfb4cc292 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -9,6 +9,7 @@ interface Config { interface MergeConfigArgs { directories: string[]; output: string; + port: number; } interface ConfigModule { From 417c5ed3e0364399a0da0bf062df0693661475dd Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Tue, 25 Jun 2024 19:24:45 +0300 Subject: [PATCH 09/22] Removed port number from MergeConfigArgs --- packages/tooling/openmrs/src/commands/merge-configs.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index cfb4cc292..f35a3e292 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -9,7 +9,6 @@ interface Config { interface MergeConfigArgs { directories: string[]; output: string; - port: number; } interface ConfigModule { From 44109f9732a3169b72b68ca4aeb84bbf80ed1a3f Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Thu, 27 Jun 2024 05:02:25 +0300 Subject: [PATCH 10/22] Trying to integrate CLI command --- packages/tooling/openmrs/src/cli.ts | 23 +++++++++++++++++++ .../openmrs/src/commands/merge-configs.ts | 6 ++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/packages/tooling/openmrs/src/cli.ts b/packages/tooling/openmrs/src/cli.ts index 7e126c1ac..76f7a01d1 100644 --- a/packages/tooling/openmrs/src/cli.ts +++ b/packages/tooling/openmrs/src/cli.ts @@ -2,6 +2,7 @@ import yargs from 'yargs'; import { fork } from 'child_process'; +import { MergeConfigArgs} from './commands/merge-configs'; import { resolve } from 'path'; import { getImportmapAndRoutes, mergeImportmapAndRoutes, proxyImportmapAndRoutes, runProject, trimEnd } from './utils'; @@ -324,6 +325,27 @@ yargs.command( }), ); +yargs.command( + 'merge-configs', + 'Merges configuration files from multiple directories into a single output file', + (argv) => + argv + .option('directories', { + alias: 'd', + describe: 'Directories to read config files from', + type: 'string', + demandOption: true, + }) + .option('output', { + alias: 'o', + describe: 'Output file path', + type: 'string', + demandOption: true, + }) + .help() + .argv, + (args) => runCommand('runMergeConfig', args as unknown as MergeConfigArgs) + ) yargs .epilog( 'The SPA build config JSON is a JSON file, typically `frontend.json`, which defines parameters for the `build` and `assemble` ' + @@ -341,3 +363,4 @@ yargs .help() .demandCommand() .strict().argv; + diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index f35a3e292..b79641ab0 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -6,7 +6,7 @@ interface Config { [key: string]: any; } -interface MergeConfigArgs { +export interface MergeConfigArgs { directories: string[]; output: string; } @@ -91,7 +91,7 @@ async function packageConfigs(configDirs: string[], outputFilePath: string): Pro await writeConfigFile(outputFilePath, mergedConfig); } -export async function runMergeConfigServer(args: MergeConfigArgs) { +export async function runMergeConfig(args: MergeConfigArgs) { const { directories, output } = args; try { @@ -100,4 +100,4 @@ export async function runMergeConfigServer(args: MergeConfigArgs) { } catch (error) { logWarn(`Failed to package configs: ${error.message}`); } -} +}; From 217310c4cd9936d4ec9ec2c5a46c8ed4ee81a95f Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Thu, 27 Jun 2024 05:18:59 +0300 Subject: [PATCH 11/22] Removed args dependency --- .../interfaces/WorkspaceContainerProps.md | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md diff --git a/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md b/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md new file mode 100644 index 000000000..300633b41 --- /dev/null +++ b/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md @@ -0,0 +1,52 @@ +[@openmrs/esm-framework](../API.md) / WorkspaceContainerProps + +# Interface: WorkspaceContainerProps + +## Table of contents + +### Properties + +- [additionalWorkspaceProps](WorkspaceContainerProps.md#additionalworkspaceprops) +- [contextKey](WorkspaceContainerProps.md#contextkey) +- [overlay](WorkspaceContainerProps.md#overlay) +- [showSiderailAndBottomNav](WorkspaceContainerProps.md#showsiderailandbottomnav) + +## Properties + +### additionalWorkspaceProps + +• `Optional` **additionalWorkspaceProps**: `object` + +#### Defined in + +[packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx:11](https://github.com/suubi-joshua/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx#L11) + +___ + +### contextKey + +• **contextKey**: `string` + +#### Defined in + +[packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx:8](https://github.com/suubi-joshua/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx#L8) + +___ + +### overlay + +• `Optional` **overlay**: `boolean` + +#### Defined in + +[packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx:9](https://github.com/suubi-joshua/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx#L9) + +___ + +### showSiderailAndBottomNav + +• `Optional` **showSiderailAndBottomNav**: `boolean` + +#### Defined in + +[packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx:10](https://github.com/suubi-joshua/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx#L10) From 3dc93c721ccc26cf12bf40092078057dab05eaae Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Thu, 27 Jun 2024 05:22:15 +0300 Subject: [PATCH 12/22] Added script merge-congigs --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index e85eb4a61..02d115c67 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "build": "turbo run build", "build:apps": "turbo run build --filter='@openmrs/*-app'", "setup": "yarn install && turbo run build", + "merge-configs": "openmrs merge-configs", "start": "openmrs develop", "verify": "turbo run lint test typescript", "postinstall": "husky install", From 917c6e5b82da1341ea548bcf99e7b3eaa677a843 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Thu, 27 Jun 2024 05:51:49 +0300 Subject: [PATCH 13/22] Added type --- packages/tooling/openmrs/src/cli.ts | 2 +- packages/tooling/openmrs/src/commands/merge-configs.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tooling/openmrs/src/cli.ts b/packages/tooling/openmrs/src/cli.ts index 76f7a01d1..57945244e 100644 --- a/packages/tooling/openmrs/src/cli.ts +++ b/packages/tooling/openmrs/src/cli.ts @@ -2,7 +2,7 @@ import yargs from 'yargs'; import { fork } from 'child_process'; -import { MergeConfigArgs} from './commands/merge-configs'; +import type { MergeConfigArgs} from './commands/merge-configs'; import { resolve } from 'path'; import { getImportmapAndRoutes, mergeImportmapAndRoutes, proxyImportmapAndRoutes, runProject, trimEnd } from './utils'; diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index b79641ab0..923159e42 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -100,4 +100,4 @@ export async function runMergeConfig(args: MergeConfigArgs) { } catch (error) { logWarn(`Failed to package configs: ${error.message}`); } -}; +} \ No newline at end of file From 5267e4453189272507c101bb1931555585b7f286 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Thu, 27 Jun 2024 16:29:45 +0300 Subject: [PATCH 14/22] Changed read files from ts to JSON --- .../openmrs/src/commands/merge-configs.ts | 26 +++---------------- 1 file changed, 4 insertions(+), 22 deletions(-) diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index 923159e42..08b1d4206 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -11,25 +11,10 @@ export interface MergeConfigArgs { output: string; } -interface ConfigModule { - configSchema: Config; -} - async function readConfigFile(filePath: string): Promise { - const safeDir = path.join(__dirname, 'config'); // Example safe directory - - // Check if filePath starts with safeDir - if (!filePath.startsWith(safeDir)) { - logWarn(`Attempted to read file from an unsafe location: ${filePath}`); - return null; - } - try { const data = await fs.readFile(filePath, 'utf8'); - const configFunction = new Function('exports', 'require', 'module', '__filename', '__dirname', data); - const module: ConfigModule = { configSchema: {} }; - configFunction(module, require, module, filePath, path.dirname(filePath)); - return module.configSchema; + return JSON.parse(data); } catch (error) { logWarn(`Error reading or parsing file ${filePath}: ${error.message}`); return null; @@ -58,10 +43,7 @@ function mergeConfigs(configs: (Config | null)[]): Config { async function writeConfigFile(filePath: string, config: Config): Promise { try { - const content = `import { validators, Type } from '@openmrs/esm-framework'; - -export const configSchema = ${JSON.stringify(config, null, 2)}; -`; + const content = JSON.stringify(config, null, 2); await fs.writeFile(filePath, content, 'utf8'); logInfo(`Merged configuration written to ${filePath}`); } catch (error) { @@ -76,7 +58,7 @@ async function packageConfigs(configDirs: string[], outputFilePath: string): Pro try { const files = await fs.readdir(dir); for (const file of files) { - if (path.extname(file) === '.ts' || path.extname(file) === '.js') { + if (path.extname(file) === '.json') { const filePath = path.join(dir, file); const config = await readConfigFile(filePath); configs.push(config); @@ -100,4 +82,4 @@ export async function runMergeConfig(args: MergeConfigArgs) { } catch (error) { logWarn(`Failed to package configs: ${error.message}`); } -} \ No newline at end of file +} From 1463eb402a69df681539173e9d6e4d583df47a68 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Thu, 27 Jun 2024 18:16:19 +0300 Subject: [PATCH 15/22] Removed inline markings from WorspaceContainerProps --- .../docs/interfaces/WorkspaceContainerProps.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md b/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md index 54a3496c6..cc6f738a4 100644 --- a/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md +++ b/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md @@ -19,9 +19,8 @@ #### Defined in -======= [packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx:11](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx#L11) ->>>>>>> upstream/main + ___ @@ -31,9 +30,8 @@ ___ #### Defined in -======= [packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx:8](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx#L8) ->>>>>>> upstream/main + ___ From 29e16159bf90008bd08a5d637ad0933e1ccaeb71 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Thu, 27 Jun 2024 18:20:50 +0300 Subject: [PATCH 16/22] Removed more inline marks --- .../docs/interfaces/WorkspaceContainerProps.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md b/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md index cc6f738a4..d283772f6 100644 --- a/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md +++ b/packages/framework/esm-framework/docs/interfaces/WorkspaceContainerProps.md @@ -21,7 +21,6 @@ [packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx:11](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx#L11) - ___ ### contextKey @@ -32,7 +31,6 @@ ___ [packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx:8](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx#L8) - ___ ### overlay @@ -41,9 +39,7 @@ ___ #### Defined in -======= [packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx:9](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx#L9) ->>>>>>> upstream/main ___ @@ -53,6 +49,5 @@ ___ #### Defined in -======= [packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx:10](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/workspaces/container/workspace-container.component.tsx#L10) ->>>>>>> upstream/main + From a5324380aaa8c15c48f65e73bbb6ad842ba7940e Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Mon, 1 Jul 2024 13:18:40 +0300 Subject: [PATCH 17/22] Testing logic --- packages/tooling/openmrs/src/cli.ts | 15 ++++++---- .../openmrs/src/commands/merge-configs.ts | 29 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/tooling/openmrs/src/cli.ts b/packages/tooling/openmrs/src/cli.ts index 57945244e..b5ce33d9a 100644 --- a/packages/tooling/openmrs/src/cli.ts +++ b/packages/tooling/openmrs/src/cli.ts @@ -2,7 +2,6 @@ import yargs from 'yargs'; import { fork } from 'child_process'; -import type { MergeConfigArgs} from './commands/merge-configs'; import { resolve } from 'path'; import { getImportmapAndRoutes, mergeImportmapAndRoutes, proxyImportmapAndRoutes, runProject, trimEnd } from './utils'; @@ -15,7 +14,8 @@ type Commands = typeof commands; type CommandNames = keyof Commands; function runCommand(type: T, args: Parameters[0]) { - const ps = fork(runner, [], { cwd: type === 'runBuild' ? root : process.cwd() }); + const ps = fork(runner, [], { cwd: type === 'runBuild' ? root : process.cwd() }) + console.log(`These are the args received by the runner: ${args}`); ps.send({ type, @@ -330,13 +330,13 @@ yargs.command( 'Merges configuration files from multiple directories into a single output file', (argv) => argv - .option('directories', { + .option('directoriesPath', { alias: 'd', describe: 'Directories to read config files from', type: 'string', demandOption: true, }) - .option('output', { + .option('outputPath', { alias: 'o', describe: 'Output file path', type: 'string', @@ -344,8 +344,11 @@ yargs.command( }) .help() .argv, - (args) => runCommand('runMergeConfig', args as unknown as MergeConfigArgs) - ) + (args) => runCommand('runMergeConfig', { + directoriesPath: args.directoriesPath as string, + outputPath: args.outputPath as string, + }) +); yargs .epilog( 'The SPA build config JSON is a JSON file, typically `frontend.json`, which defines parameters for the `build` and `assemble` ' + diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index 08b1d4206..9d66a967f 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -6,9 +6,9 @@ interface Config { [key: string]: any; } -export interface MergeConfigArgs { - directories: string[]; - output: string; +export interface MergeArgs { + directoriesPath: string; + outputPath: string; } async function readConfigFile(filePath: string): Promise { @@ -51,34 +51,31 @@ async function writeConfigFile(filePath: string, config: Config): Promise } } -async function packageConfigs(configDirs: string[], outputFilePath: string): Promise { +async function packageConfigs(configDirs: string, outputFilePath: string): Promise { const configs: (Config | null)[] = []; - - for (const dir of configDirs) { try { - const files = await fs.readdir(dir); + const files = await fs.readdir(configDirs); for (const file of files) { + const filePath = path.join(configDirs, file); if (path.extname(file) === '.json') { - const filePath = path.join(dir, file); const config = await readConfigFile(filePath); configs.push(config); } } } catch (error) { - logWarn(`Error reading directory ${dir}: ${error.message}`); + console.log(`Error reading directory ${configDirs}: ${error.message}`); } - } - const mergedConfig = mergeConfigs(configs.filter(Boolean) as Config[]); - await writeConfigFile(outputFilePath, mergedConfig); + const mergedConfig = mergeConfigs(configs.filter(Boolean) as Config[]); + await writeConfigFile(outputFilePath, mergedConfig); } -export async function runMergeConfig(args: MergeConfigArgs) { - const { directories, output } = args; + +export function runMergeConfig(args: MergeArgs) { try { - await packageConfigs(directories, output); - logInfo(`Merged configuration written to ${output}`); + packageConfigs(args.directoriesPath, args.outputPath); + logInfo(`Merged configuration written to ${args.outputPath}`); } catch (error) { logWarn(`Failed to package configs: ${error.message}`); } From 950aa603b3b2b17eb59b26d860ee4a67628e1038 Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Mon, 1 Jul 2024 14:51:16 +0300 Subject: [PATCH 18/22] Fuction runMergeConfig returns promise --- packages/tooling/openmrs/src/commands/merge-configs.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts index 9d66a967f..a0f91144c 100644 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ b/packages/tooling/openmrs/src/commands/merge-configs.ts @@ -63,7 +63,7 @@ async function packageConfigs(configDirs: string, outputFilePath: string): Promi } } } catch (error) { - console.log(`Error reading directory ${configDirs}: ${error.message}`); + logWarn(`Error reading directory ${configDirs}: ${error.message}`); } const mergedConfig = mergeConfigs(configs.filter(Boolean) as Config[]); @@ -71,7 +71,7 @@ async function packageConfigs(configDirs: string, outputFilePath: string): Promi } -export function runMergeConfig(args: MergeArgs) { +export function runMergeConfig(args: MergeArgs): Promise { try { packageConfigs(args.directoriesPath, args.outputPath); @@ -79,4 +79,5 @@ export function runMergeConfig(args: MergeArgs) { } catch (error) { logWarn(`Failed to package configs: ${error.message}`); } + return Promise.resolve(); } From 0f62144d2be4014ac051845a43f8faa1f592147c Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Tue, 2 Jul 2024 16:52:56 +0300 Subject: [PATCH 19/22] Trying to add the merge-config in assemble --- package.json | 2 +- packages/tooling/openmrs/src/cli.ts | 29 +------ .../tooling/openmrs/src/commands/assemble.ts | 34 +++++++- .../tooling/openmrs/src/commands/index.ts | 1 - .../openmrs/src/commands/merge-configs.ts | 83 ------------------- 5 files changed, 36 insertions(+), 113 deletions(-) delete mode 100644 packages/tooling/openmrs/src/commands/merge-configs.ts diff --git a/package.json b/package.json index 02d115c67..2baa382e7 100644 --- a/package.json +++ b/package.json @@ -15,9 +15,9 @@ "ci:publish": "yarn workspaces foreach --all --topological --exclude @openmrs/esm-core npm publish --access public --tag latest", "release": "yarn workspaces foreach --all --topological version", "build": "turbo run build", + "assemble": "openmrs assemble", "build:apps": "turbo run build --filter='@openmrs/*-app'", "setup": "yarn install && turbo run build", - "merge-configs": "openmrs merge-configs", "start": "openmrs develop", "verify": "turbo run lint test typescript", "postinstall": "husky install", diff --git a/packages/tooling/openmrs/src/cli.ts b/packages/tooling/openmrs/src/cli.ts index b5ce33d9a..606c6ddbe 100644 --- a/packages/tooling/openmrs/src/cli.ts +++ b/packages/tooling/openmrs/src/cli.ts @@ -290,10 +290,10 @@ yargs.command( type: 'boolean', }) .option('mode', { - choices: ['config', 'survey'], + choices: ['config', 'configFile', 'survey'], default: 'survey', description: - 'The source of the frontend modules to assemble. `config` uses a configuration file specified via `--config`. `survey` starts an interactive command-line survey.', + 'The source of the frontend modules to assemble. `config` uses a configuration file specified via `--config`. `configFile packages up configurations from file specified cia `--config-file`. survey` starts an interactive command-line survey.', type: 'string', }), (args) => runCommand('runAssemble', args), @@ -324,31 +324,6 @@ yargs.command( ...args, }), ); - -yargs.command( - 'merge-configs', - 'Merges configuration files from multiple directories into a single output file', - (argv) => - argv - .option('directoriesPath', { - alias: 'd', - describe: 'Directories to read config files from', - type: 'string', - demandOption: true, - }) - .option('outputPath', { - alias: 'o', - describe: 'Output file path', - type: 'string', - demandOption: true, - }) - .help() - .argv, - (args) => runCommand('runMergeConfig', { - directoriesPath: args.directoriesPath as string, - outputPath: args.outputPath as string, - }) -); yargs .epilog( 'The SPA build config JSON is a JSON file, typically `frontend.json`, which defines parameters for the `build` and `assemble` ' + diff --git a/packages/tooling/openmrs/src/commands/assemble.ts b/packages/tooling/openmrs/src/commands/assemble.ts index 14ddf1a7a..c38d38c2c 100644 --- a/packages/tooling/openmrs/src/commands/assemble.ts +++ b/packages/tooling/openmrs/src/commands/assemble.ts @@ -17,6 +17,7 @@ export interface AssembleArgs { target: string; mode: string; config: Array; + myConfigs: Array; registry?: string; hashImportmap: boolean; fresh: boolean; @@ -43,6 +44,7 @@ interface AssembleConfig { async function readConfig( mode: string, configs: Array, + myConfigs: Array, fetchOptions: npmRegistryFetch.Options, ): Promise { switch (mode) { @@ -101,6 +103,32 @@ async function readConfig( return config; }); } + case 'myConfigs':{ + if (!myConfigs.length) { + throw new Error('Please specify config files using the --config-file option.'); + } + + const results: { + myConfigs: Array; + errors: Array; + } = { + myConfigs: [], + errors: [], + }; + + for (const config of myConfigs) { + if (!existsSync(config)) { + results.errors.push(new Error(`Could not find the config file "${config}".`)); + continue; + } + + logInfo(`Reading configuration ${config} ...`); + + results.myConfigs.push({ + ...JSON.parse(await readFile(config, 'utf8')), + }); + } + } case 'survey': { logInfo(`Loading available frontend modules ...`); @@ -230,7 +258,7 @@ async function extractFiles(buffer: Buffer, targetDir: string): Promise<[string, export async function runAssemble(args: AssembleArgs) { const npmConf = getNpmRegistryConfiguration(args.registry); - const config = await readConfig(args.mode, args.config, npmConf); + const config = await readConfig(args.mode, args.config, args.myConfigs, npmConf); const importmap = { imports: {}, @@ -303,5 +331,9 @@ export async function runAssemble(args: AssembleArgs) { await writeFile(resolve(args.target, 'spa-assemble-config.json'), JSON.stringify(versionManifest), 'utf8'); } + if(args.mode === 'myConfigs'){ + await writeFile(resolve(args.target, 'My-Merged-configs.json'), JSON.stringify(config), 'utf8'); + } + logInfo(`Finished assembling frontend distribution`); } diff --git a/packages/tooling/openmrs/src/commands/index.ts b/packages/tooling/openmrs/src/commands/index.ts index 742a4c05e..65b4a360f 100644 --- a/packages/tooling/openmrs/src/commands/index.ts +++ b/packages/tooling/openmrs/src/commands/index.ts @@ -3,4 +3,3 @@ export * from './build'; export * from './debug'; export * from './develop'; export * from './start'; -export * from './merge-configs'; diff --git a/packages/tooling/openmrs/src/commands/merge-configs.ts b/packages/tooling/openmrs/src/commands/merge-configs.ts deleted file mode 100644 index a0f91144c..000000000 --- a/packages/tooling/openmrs/src/commands/merge-configs.ts +++ /dev/null @@ -1,83 +0,0 @@ -import * as fs from 'fs/promises'; -import * as path from 'path'; -import { logInfo, logWarn } from '../utils'; - -interface Config { - [key: string]: any; -} - -export interface MergeArgs { - directoriesPath: string; - outputPath: string; -} - -async function readConfigFile(filePath: string): Promise { - try { - const data = await fs.readFile(filePath, 'utf8'); - return JSON.parse(data); - } catch (error) { - logWarn(`Error reading or parsing file ${filePath}: ${error.message}`); - return null; - } -} - -function mergeConfigs(configs: (Config | null)[]): Config { - const mergedConfig: Config = {}; - - configs.forEach((config) => { - if (config === null) { - return; - } - - Object.keys(config).forEach((key) => { - if (typeof config[key] === 'object' && !Array.isArray(config[key])) { - mergedConfig[key] = { ...mergedConfig[key], ...config[key] }; - } else { - mergedConfig[key] = config[key]; - } - }); - }); - - return mergedConfig; -} - -async function writeConfigFile(filePath: string, config: Config): Promise { - try { - const content = JSON.stringify(config, null, 2); - await fs.writeFile(filePath, content, 'utf8'); - logInfo(`Merged configuration written to ${filePath}`); - } catch (error) { - logWarn(`Error writing to file ${filePath}: ${error.message}`); - } -} - -async function packageConfigs(configDirs: string, outputFilePath: string): Promise { - const configs: (Config | null)[] = []; - try { - const files = await fs.readdir(configDirs); - for (const file of files) { - const filePath = path.join(configDirs, file); - if (path.extname(file) === '.json') { - const config = await readConfigFile(filePath); - configs.push(config); - } - } - } catch (error) { - logWarn(`Error reading directory ${configDirs}: ${error.message}`); - } - - const mergedConfig = mergeConfigs(configs.filter(Boolean) as Config[]); - await writeConfigFile(outputFilePath, mergedConfig); -} - - -export function runMergeConfig(args: MergeArgs): Promise { - - try { - packageConfigs(args.directoriesPath, args.outputPath); - logInfo(`Merged configuration written to ${args.outputPath}`); - } catch (error) { - logWarn(`Failed to package configs: ${error.message}`); - } - return Promise.resolve(); -} From c675229658599ebeb3e68bbee645b21d074dba3c Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Tue, 2 Jul 2024 19:22:23 +0300 Subject: [PATCH 20/22] Edits --- packages/tooling/openmrs/src/cli.ts | 1 - packages/tooling/openmrs/src/commands/assemble.ts | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tooling/openmrs/src/cli.ts b/packages/tooling/openmrs/src/cli.ts index 606c6ddbe..6268487c9 100644 --- a/packages/tooling/openmrs/src/cli.ts +++ b/packages/tooling/openmrs/src/cli.ts @@ -15,7 +15,6 @@ type CommandNames = keyof Commands; function runCommand(type: T, args: Parameters[0]) { const ps = fork(runner, [], { cwd: type === 'runBuild' ? root : process.cwd() }) - console.log(`These are the args received by the runner: ${args}`); ps.send({ type, diff --git a/packages/tooling/openmrs/src/commands/assemble.ts b/packages/tooling/openmrs/src/commands/assemble.ts index c38d38c2c..f5cec46c4 100644 --- a/packages/tooling/openmrs/src/commands/assemble.ts +++ b/packages/tooling/openmrs/src/commands/assemble.ts @@ -128,6 +128,7 @@ async function readConfig( ...JSON.parse(await readFile(config, 'utf8')), }); } + break; } case 'survey': { logInfo(`Loading available frontend modules ...`); From 621c8f21a1c1c643b483672e4a2fba16896db07d Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Wed, 3 Jul 2024 15:43:42 +0300 Subject: [PATCH 21/22] Changed naming --- packages/tooling/openmrs/src/cli.ts | 4 ++-- .../tooling/openmrs/src/commands/assemble.ts | 22 +++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/tooling/openmrs/src/cli.ts b/packages/tooling/openmrs/src/cli.ts index 6268487c9..0cc1a52c9 100644 --- a/packages/tooling/openmrs/src/cli.ts +++ b/packages/tooling/openmrs/src/cli.ts @@ -289,10 +289,10 @@ yargs.command( type: 'boolean', }) .option('mode', { - choices: ['config', 'configFile', 'survey'], + choices: ['config', 'configFiles', 'survey'], default: 'survey', description: - 'The source of the frontend modules to assemble. `config` uses a configuration file specified via `--config`. `configFile packages up configurations from file specified cia `--config-file`. survey` starts an interactive command-line survey.', + 'The source of the frontend modules to assemble. `config` uses a configuration file specified via `--config`. `configFiles` packages up configurations from file specified via `--config-file`. `survey` starts an interactive command-line survey.', type: 'string', }), (args) => runCommand('runAssemble', args), diff --git a/packages/tooling/openmrs/src/commands/assemble.ts b/packages/tooling/openmrs/src/commands/assemble.ts index f5cec46c4..bce4748c4 100644 --- a/packages/tooling/openmrs/src/commands/assemble.ts +++ b/packages/tooling/openmrs/src/commands/assemble.ts @@ -17,7 +17,7 @@ export interface AssembleArgs { target: string; mode: string; config: Array; - myConfigs: Array; + configFiles: Array; registry?: string; hashImportmap: boolean; fresh: boolean; @@ -44,7 +44,7 @@ interface AssembleConfig { async function readConfig( mode: string, configs: Array, - myConfigs: Array, + configFiles: Array, fetchOptions: npmRegistryFetch.Options, ): Promise { switch (mode) { @@ -103,20 +103,20 @@ async function readConfig( return config; }); } - case 'myConfigs':{ - if (!myConfigs.length) { + case 'configFiles':{ + if (!configFiles.length) { throw new Error('Please specify config files using the --config-file option.'); } const results: { - myConfigs: Array; + configFiles: Array; errors: Array; } = { - myConfigs: [], + configFiles: [], errors: [], }; - for (const config of myConfigs) { + for (const config of configFiles) { if (!existsSync(config)) { results.errors.push(new Error(`Could not find the config file "${config}".`)); continue; @@ -124,7 +124,7 @@ async function readConfig( logInfo(`Reading configuration ${config} ...`); - results.myConfigs.push({ + results.configFiles.push({ ...JSON.parse(await readFile(config, 'utf8')), }); } @@ -259,7 +259,7 @@ async function extractFiles(buffer: Buffer, targetDir: string): Promise<[string, export async function runAssemble(args: AssembleArgs) { const npmConf = getNpmRegistryConfiguration(args.registry); - const config = await readConfig(args.mode, args.config, args.myConfigs, npmConf); + const config = await readConfig(args.mode, args.config, args.configFiles, npmConf); const importmap = { imports: {}, @@ -332,8 +332,8 @@ export async function runAssemble(args: AssembleArgs) { await writeFile(resolve(args.target, 'spa-assemble-config.json'), JSON.stringify(versionManifest), 'utf8'); } - if(args.mode === 'myConfigs'){ - await writeFile(resolve(args.target, 'My-Merged-configs.json'), JSON.stringify(config), 'utf8'); + if(args.mode === 'configFiles'){ + await writeFile(resolve(args.target, 'spa-config.jsons'), JSON.stringify(config), 'utf8'); } logInfo(`Finished assembling frontend distribution`); From 2e08f68fcd3e1e6c988c8a7b796720c144c8d86e Mon Sep 17 00:00:00 2001 From: suubi-joshua Date: Wed, 3 Jul 2024 22:24:48 +0300 Subject: [PATCH 22/22] Added Logic to return combinedConfig as AssembleConfig format --- packages/shell/esm-app-shell/src/index.ejs | 4 +- packages/tooling/openmrs/src/cli.ts | 2 +- .../tooling/openmrs/src/commands/assemble.ts | 46 +++++++++++++++---- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/packages/shell/esm-app-shell/src/index.ejs b/packages/shell/esm-app-shell/src/index.ejs index df1bd5654..a5f597a6a 100644 --- a/packages/shell/esm-app-shell/src/index.ejs +++ b/packages/shell/esm-app-shell/src/index.ejs @@ -90,8 +90,8 @@ apiUrl: "<%= openmrsApiUrl %>", spaPath: "<%= openmrsPublicPath %>", env: "<%= openmrsEnvironment %>", - offline: <%= openmrsOffline %>, - configUrls: [<%= openmrsConfigUrls %>], + offline: "<%= openmrsOffline %>", + configUrls: ["<%= openmrsConfigUrls %>"], }); diff --git a/packages/tooling/openmrs/src/cli.ts b/packages/tooling/openmrs/src/cli.ts index 0cc1a52c9..cd6fa087c 100644 --- a/packages/tooling/openmrs/src/cli.ts +++ b/packages/tooling/openmrs/src/cli.ts @@ -14,7 +14,7 @@ type Commands = typeof commands; type CommandNames = keyof Commands; function runCommand(type: T, args: Parameters[0]) { - const ps = fork(runner, [], { cwd: type === 'runBuild' ? root : process.cwd() }) + const ps = fork(runner, [], { cwd: type === 'runBuild' ? root : process.cwd() }); ps.send({ type, diff --git a/packages/tooling/openmrs/src/commands/assemble.ts b/packages/tooling/openmrs/src/commands/assemble.ts index bce4748c4..4e971517a 100644 --- a/packages/tooling/openmrs/src/commands/assemble.ts +++ b/packages/tooling/openmrs/src/commands/assemble.ts @@ -17,7 +17,7 @@ export interface AssembleArgs { target: string; mode: string; config: Array; - configFiles: Array; + configFiles: Array; registry?: string; hashImportmap: boolean; fresh: boolean; @@ -107,28 +107,54 @@ async function readConfig( if (!configFiles.length) { throw new Error('Please specify config files using the --config-file option.'); } - + const results: { - configFiles: Array; + configs: Array; errors: Array; } = { - configFiles: [], + configs: [], errors: [], }; - + for (const config of configFiles) { if (!existsSync(config)) { results.errors.push(new Error(`Could not find the config file "${config}".`)); continue; } - + logInfo(`Reading configuration ${config} ...`); - - results.configFiles.push({ + + results.configs.push({ ...JSON.parse(await readFile(config, 'utf8')), }); } - break; + + if (results.errors.length > 0) { + throw new Error( + results.errors.reduce((str, e, idx) => { + if (idx > 0) { + str += '\n\n'; + } + + return str + e.message; + }, ''), + ); + } + + const combinedConfig = results.configs.reduce((combinedConfig, newConfig) => { + if (newConfig.frontendModules) { + combinedConfig.frontendModules = { ...combinedConfig.frontendModules, ...newConfig.frontendModules }; + } + if (newConfig.publicUrl) { + combinedConfig.publicUrl = newConfig.publicUrl; + } + if (newConfig.frontendModuleExcludes) { + combinedConfig.frontendModuleExcludes = [...(combinedConfig.frontendModuleExcludes || []), ...newConfig.frontendModuleExcludes]; + } + return combinedConfig; + }, {} as AssembleConfig); + + return combinedConfig; } case 'survey': { logInfo(`Loading available frontend modules ...`); @@ -333,7 +359,7 @@ export async function runAssemble(args: AssembleArgs) { } if(args.mode === 'configFiles'){ - await writeFile(resolve(args.target, 'spa-config.jsons'), JSON.stringify(config), 'utf8'); + await writeFile(resolve(args.target, 'spa-config.json'), JSON.stringify(config), 'utf8'); } logInfo(`Finished assembling frontend distribution`);