From ba8b36c17b6e1230d48843c0a8cadae18f434092 Mon Sep 17 00:00:00 2001 From: Annemarie Date: Tue, 10 Sep 2024 14:51:39 +0200 Subject: [PATCH 01/37] feat: add varinats config --- packages/app-config-writer/src/index.ts | 1 + .../variants-config/generateVariantsConfig.ts | 23 +++++ .../src/variants-config/index.ts | 2 + .../src/variants-config/package-json.ts | 95 +++++++++++++++++++ .../src/variants-config/ui5-yaml.ts | 69 ++++++++++++++ .../src/variants-config/utils.ts | 0 packages/create/src/cli/add/index.ts | 4 +- .../create/src/cli/add/variants-config.ts | 45 +++++++++ 8 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 packages/app-config-writer/src/variants-config/generateVariantsConfig.ts create mode 100644 packages/app-config-writer/src/variants-config/index.ts create mode 100644 packages/app-config-writer/src/variants-config/package-json.ts create mode 100644 packages/app-config-writer/src/variants-config/ui5-yaml.ts create mode 100644 packages/app-config-writer/src/variants-config/utils.ts create mode 100644 packages/create/src/cli/add/variants-config.ts diff --git a/packages/app-config-writer/src/index.ts b/packages/app-config-writer/src/index.ts index fd9d14a966..82136dee1f 100644 --- a/packages/app-config-writer/src/index.ts +++ b/packages/app-config-writer/src/index.ts @@ -1,3 +1,4 @@ export { getSmartLinksTargetFromPrompt, promptInboundNavigationConfig } from './prompt'; export { generateSmartLinksConfig } from './smartlinks-config'; export { generateInboundNavigationConfig } from './navigation-config'; +export { generateVariantsConfig } from './variants-config'; diff --git a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts new file mode 100644 index 0000000000..342ca6f0a3 --- /dev/null +++ b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts @@ -0,0 +1,23 @@ +import { create as createStorage } from 'mem-fs'; +import { create } from 'mem-fs-editor'; +import type { Editor } from 'mem-fs-editor'; +import type { ToolsLogger } from '@sap-ux/logger'; +import { addVariantsManagementScript } from './package-json'; +import { addPreviewMiddlewareToYaml } from './ui5-yaml'; + +/** + * Add variants configuration to a UI5 application. + * + * @param basePath - the base path where the package.json and ui5.yaml is + * @param logger - logger + * @param fs - the memfs editor instance + * @returns Promise - memfs editor instance with updated files + */ +export async function generateVariantsConfig(basePath: string, logger?: ToolsLogger, fs?: Editor): Promise { + if (!fs) { + fs = create(createStorage()); + } + await addVariantsManagementScript(fs, basePath); + await addPreviewMiddlewareToYaml(basePath, args, logger); + return fs; +} diff --git a/packages/app-config-writer/src/variants-config/index.ts b/packages/app-config-writer/src/variants-config/index.ts new file mode 100644 index 0000000000..626062d696 --- /dev/null +++ b/packages/app-config-writer/src/variants-config/index.ts @@ -0,0 +1,2 @@ +export * from './generateVariantsConfig'; +// export { getTargetDefinition, getLocalStoredCredentials } from './utils'; diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts new file mode 100644 index 0000000000..8a34d5971f --- /dev/null +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -0,0 +1,95 @@ +import { join } from 'path'; +import type { Editor } from 'mem-fs-editor'; +// import { createApplicationAccess } from '@sap-ux/project-access'; +import type { Package } from '@sap-ux/project-access'; +import { stringify } from 'querystring'; + +//TDo: check for i18n +const SAP_CLIENT_REGEX = /sap-client=([0-9]{3})/; +const FIORI_TOOLS_RTA_MODE_TRUE = 'true'; +const FIORI_TOOLS_RTA_MODE_VARIANTS = 'forVariants'; +const FIORI_TOOLS_RTA_MODE_ADAPTATION = 'forAdaptation'; +type FioriToolsRtaMode = + | typeof FIORI_TOOLS_RTA_MODE_TRUE + | typeof FIORI_TOOLS_RTA_MODE_VARIANTS + | typeof FIORI_TOOLS_RTA_MODE_ADAPTATION; +//TDo: check for endpoint and hash +const PREVIEW_PAGE = 'preview.html'; +const PREVIEW_APP_NAME = 'preview-app'; + +/** + * Extracts sap client string from existing scripts in package.json. + * + * @param packageJson - parsed package.json content + * @returns - sap-client string or undefined + */ +function getSapClientFromPackageJson(packageJson: Package): string | undefined { + const scripts = packageJson.script; + // check if sap-client is needed when starting the app + for (const script of scripts) { + const match = script.match(SAP_CLIENT_REGEX); + if (match) { + return match[1]; + } + } +} + +/** + * Returns the UI5 url parameters. + * + * @param rtaMode - path to package.json + * @param overwritingParams - parameters to be overwritten + * @returns - overwritten parameters + */ +function getUi5UrlParameters( + rtaMode: FioriToolsRtaMode, + overwritingParams: Record = {} +): string { + const parameters: Record = { + 'fiori-tools-rta-mode': rtaMode, + 'sap-ui-rta-skip-flex-validation': 'true', + 'sap-ui-xx-condense-changes': 'true' + }; + return stringify(Object.assign(parameters, overwritingParams)); +} + +/** + * Returns the preview url parameters. + * + * @param query - query to create fragment + * @returns - review url parameters + */ +function getPreviewUrl(query?: string): string { + const queryFragment = query ? `?${query}` : ''; + return `/${PREVIEW_PAGE}${queryFragment}#${PREVIEW_APP_NAME}`; +} + +/** + * Add the start-variants-management script to the package.json. + * + * @param fs - mem-fs reference to be used for file access + * @param basePath - path to application root, where package.json is + */ +export function addVariantsManagementScript(fs: Editor, basePath: string): void { + const packageJsonPath = join(basePath, 'package.json'); + const packageJson = fs.readJSON(packageJsonPath) as Package; + + if (packageJson.scripts) { + // check if sap-client is needed when starting the app + const urlParameters: Record = {}; + const sapClient = getSapClientFromPackageJson(packageJson); + if (sapClient) { + urlParameters['sap-client'] = sapClient; + } + const query = getUi5UrlParameters(FIORI_TOOLS_RTA_MODE_TRUE, urlParameters); + // Remove / + const url = getPreviewUrl(query).slice(1); + //TDo: check script name + const startVariantsManagement = 'start-variants-management'; + const variantsScript = { [startVariantsManagement]: `fiori run --open "${url}"` }; + //TDo: check for packageJSON update -> use fs.writeJSON + Object.assign(packageJson.scripts, variantsScript); + // const appAccess = createApplicationAccess(basePath, fs); + // (await appAccess).updatePackageJSON(packageJson); + } +} diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts new file mode 100644 index 0000000000..f969fb4742 --- /dev/null +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -0,0 +1,69 @@ +import type { UI5Config } from '@sap-ux/ui5-config'; + +/** + * Adds the fiori-tools-preview middleware to the ui5.yaml file + * @param yamlContent YAML content as JSON + * @param yamlFile path to the YAML file + */ +async function addPreviewMiddleware(yamlContent: UI5Config, yamlFile: string): Promise { + const previewMiddlewareTemplate = { + name: 'fiori-tools-preview', + afterMiddleware: 'compression' + }; + + // replace null occurrences with an empty string + yamlContent = JSON.parse(JSON.stringify(yamlContent).replace(/null/g, '""')); + if (yamlContent.server) { + if (yamlContent.server.customMiddleware) { + let previewMiddleware = yamlContent.server.customMiddleware.find((middleware) => { + return middleware.name === 'fiori-tools-preview'; + }); + + const livereloadMiddleware = yamlContent.server.customMiddleware.find((middleware) => { + return middleware.name === 'fiori-tools-appreload'; + }); + + if (livereloadMiddleware) { + previewMiddlewareTemplate.afterMiddleware = 'fiori-tools-appreload'; + livereloadMiddleware.configuration.delay = 300; + } + + if (!previewMiddleware) { + yamlContent.server.customMiddleware.push(previewMiddlewareTemplate); + await promises.writeFile(yamlFile, YAML.stringify(yamlContent), { encoding: 'utf8' }); + } else { + previewMiddleware = previewMiddlewareTemplate; + await promises.writeFile(yamlFile, YAML.stringify(yamlContent), { encoding: 'utf8' }); + } + } else { + yamlContent.server.customMiddleware = []; + yamlContent.server.customMiddleware.push(previewMiddlewareTemplate); + await promises.writeFile(yamlFile, YAML.stringify(yamlContent), { encoding: 'utf8' }); + } + } else { + yamlContent.server = { customMiddleware: [] }; + yamlContent.server.customMiddleware.push(previewMiddlewareTemplate); + await promises.writeFile(yamlFile, YAML.stringify(yamlContent), { encoding: 'utf8' }); + } +} + +/** + * Checks the project for ui5 yaml files and adds the fiori-tools-preview middleware to it + * @param projectPath path to the project root + * @param args arguments passed by cli + */ +export async function addPreviewMiddlewareToYaml(projectPath: string, args: string[]): Promise { + const ui5YamlFileName = getYamlFile(args); + const ui5YamlPaths = [ + join(projectPath, ui5YamlFileName), + join(projectPath, FileName.Ui5LocalYaml), + join(projectPath, FileName.Ui5MockYaml) + ]; + + for (const ui5YamlPath of ui5YamlPaths) { + if (existsSync(ui5YamlPath)) { + const ui5Yaml = await readUi5Yaml(projectPath, FileName.UI5DeployYaml); + await addPreviewMiddleware(ui5Yaml, ui5YamlPath); + } + } +} diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/create/src/cli/add/index.ts b/packages/create/src/cli/add/index.ts index 94ae1c5ee0..60b0eadee5 100644 --- a/packages/create/src/cli/add/index.ts +++ b/packages/create/src/cli/add/index.ts @@ -9,7 +9,7 @@ import { addAnnotationsToOdataCommand } from './annotations-to-odata'; import { addAddHtmlFilesCmd } from './html'; import { addComponentUsagesCommand } from './component-usages'; import { addDeployConfigCommand } from './deploy-config'; - +import { addAddVariantsConfigCommand } from './variants-config'; /** * Return 'create-fiori add *' commands. Commands include also the handler action. * @@ -37,5 +37,7 @@ export function getAddCommands(): Command { addComponentUsagesCommand(addCommands); // create-fiori add deploy-config addDeployConfigCommand(addCommands); + // create-fiori add variants-config + addAddVariantsConfigCommand(addCommands); return addCommands; } diff --git a/packages/create/src/cli/add/variants-config.ts b/packages/create/src/cli/add/variants-config.ts new file mode 100644 index 0000000000..bfc2bc271f --- /dev/null +++ b/packages/create/src/cli/add/variants-config.ts @@ -0,0 +1,45 @@ +import type { Command } from 'commander'; +import { getLogger, traceChanges, setLogLevelVerbose } from '../../tracing'; +import { validateBasePath } from '../../validation'; +import { generateVariantsConfig } from '@sap-ux/app-config-writer'; + +/** + * Add the "add variants config" command to a passed command. + * + * @param cmd - commander command for adding config command + */ +export function addAddVariantsConfigCommand(cmd: Command): void { + cmd.command('variants-config [path]') + .option('-s, --simulate', 'simulate only do not write config; sets also --verbose') + .option('-v, --verbose', 'show verbose information') + .action(async (path, options) => { + if (options.verbose === true || options.simulate) { + setLogLevelVerbose(); + } + await addVariantsConfig(path || process.cwd(), !!options.simulate); + }); +} + +/** + * Adds a variants config to an app or project. + * + * @param basePath - path to application root + * @param simulate - if true, do not write but just show what would be change; otherwise write + */ +async function addVariantsConfig(basePath: string, simulate: boolean): Promise { + const logger = getLogger(); + try { + logger.debug(`Called add variants-config for path '${basePath}', simulate is '${simulate}'`); + //ToDo: check if validate is needed + await validateBasePath(basePath); + const fs = await generateVariantsConfig(basePath, logger); + await traceChanges(fs); + if (!simulate) { + //ToDo: check if skip install is needed -> mockserver-config.ts + fs.commit(() => logger.info(`Variants configuration written.`)); + } + } catch (error) { + logger.error(`Error while executing add variants-config '${(error as Error).message}'`); + logger.debug(error as Error); + } +} From 631b9dc7f283868b59b145f5dc0dafaf0338aca8 Mon Sep 17 00:00:00 2001 From: Annemarie Date: Mon, 16 Sep 2024 16:24:04 +0200 Subject: [PATCH 02/37] feat: add varinats config --- .../variants-config/generateVariantsConfig.ts | 2 +- .../src/variants-config/package-json.ts | 29 ++-- .../src/variants-config/types.ts | 56 ++++++++ .../src/variants-config/ui5-yaml.ts | 124 +++++++++++------- 4 files changed, 148 insertions(+), 63 deletions(-) create mode 100644 packages/app-config-writer/src/variants-config/types.ts diff --git a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts index 342ca6f0a3..3da38d1426 100644 --- a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts +++ b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts @@ -18,6 +18,6 @@ export async function generateVariantsConfig(basePath: string, logger?: ToolsLog fs = create(createStorage()); } await addVariantsManagementScript(fs, basePath); - await addPreviewMiddlewareToYaml(basePath, args, logger); + await addPreviewMiddlewareToYaml(fs, basePath, logger); return fs; } diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index 8a34d5971f..b28f583320 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -20,18 +20,19 @@ const PREVIEW_APP_NAME = 'preview-app'; /** * Extracts sap client string from existing scripts in package.json. * - * @param packageJson - parsed package.json content - * @returns - sap-client string or undefined + * @param packageJson - path to package.json */ -function getSapClientFromPackageJson(packageJson: Package): string | undefined { - const scripts = packageJson.script; - // check if sap-client is needed when starting the app - for (const script of scripts) { - const match = script.match(SAP_CLIENT_REGEX); +function getSapClientFromPackageJson(packageJson: Package): any { + const scripts = (packageJson.script ||= {}); + // ToDo: check for different iteration + const scriptValues = Object.values(scripts); + scriptValues.forEach((scriptValue) => { + const match = scriptValue.match(SAP_CLIENT_REGEX); if (match) { - return match[1]; + return match; } - } + return undefined; + }); } /** @@ -86,10 +87,10 @@ export function addVariantsManagementScript(fs: Editor, basePath: string): void const url = getPreviewUrl(query).slice(1); //TDo: check script name const startVariantsManagement = 'start-variants-management'; - const variantsScript = { [startVariantsManagement]: `fiori run --open "${url}"` }; - //TDo: check for packageJSON update -> use fs.writeJSON - Object.assign(packageJson.scripts, variantsScript); - // const appAccess = createApplicationAccess(basePath, fs); - // (await appAccess).updatePackageJSON(packageJson); + const variantsScript = `fiori run --open "${url}"`; + + packageJson.scripts[startVariantsManagement] = variantsScript; + + fs.writeJSON(packageJsonPath, packageJson); } } diff --git a/packages/app-config-writer/src/variants-config/types.ts b/packages/app-config-writer/src/variants-config/types.ts new file mode 100644 index 0000000000..23a3313b6e --- /dev/null +++ b/packages/app-config-writer/src/variants-config/types.ts @@ -0,0 +1,56 @@ +type UI5FlexLayer = 'VENDOR' | 'CUSTOMER_BASE'; +interface RtaConfig { + layer: UI5FlexLayer; + options?: { + [key: string]: unknown; + baseId?: string; + projectId?: string; + scenario?: string; + appName?: string; + }; + editors: any[]; +} +interface Intent { + object: string; + action: string; +} +interface App { + target: string; + local?: string; + componentId?: string; + intent?: Intent; +} +interface FlpConfig { + path: string; + intent: Intent; + libs?: boolean; + apps: App[]; + theme?: string; + init?: string; +} +interface OptionalTestConfig { + path: string; + init: string; + pattern: string; +} +interface TestConfig extends Partial { + framework: 'OPA5' | 'QUnit' | 'Testsuite'; +} +interface AdpPreviewConfig { + target: any; + ignoreCertErrors?: boolean; +} +export interface MiddlewareConfig { + flp?: Partial; + test?: TestConfig[]; + rta?: RtaConfig; + adp?: AdpPreviewConfig; + debug?: boolean; +} +export interface DeprecatedConfig { + component: string; + libs?: boolean; + ui5Theme?: string; +} + +export type PreviewConfigOptions = DeprecatedConfig | MiddlewareConfig; diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index f969fb4742..73c1c45cce 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -1,69 +1,97 @@ +import { join } from 'path'; +import { FileName, readUi5Yaml } from '@sap-ux/project-access'; import type { UI5Config } from '@sap-ux/ui5-config'; +import type { Editor } from 'mem-fs-editor'; +import type { CustomMiddleware } from '@sap-ux/ui5-config'; +import type { ToolsLogger } from '@sap-ux/logger'; +import type { PreviewConfigOptions, DeprecatedConfig, MiddlewareConfig } from './types'; /** - * Adds the fiori-tools-preview middleware to the ui5.yaml file - * @param yamlContent YAML content as JSON - * @param yamlFile path to the YAML file + * Checks if a fiori-tools-preview middleware configuration is decprecated. + * + * @param config fiori-tools-preview middleware configuration + * @returns type conversion if true */ -async function addPreviewMiddleware(yamlContent: UI5Config, yamlFile: string): Promise { - const previewMiddlewareTemplate = { +function isDeprecatedConfig(config: PreviewConfigOptions): config is DeprecatedConfig { + return (config as DeprecatedConfig)?.component !== undefined; +} + +/** + * Adds the fiori-tools-preview middleware configuration. + * + * @param ui5YamlConfig existing ui5 yaml configurations + * @returns 'fiori-tools-preview' configuration + */ +async function addPreviewMiddleware( + ui5YamlConfig: UI5Config + // ToDo: create middleware type +): Promise> { + const previewMiddlewareConfig = { name: 'fiori-tools-preview', - afterMiddleware: 'compression' + afterMiddleware: 'compression', + configuration: {} }; + // ToDo: check if needed // replace null occurrences with an empty string - yamlContent = JSON.parse(JSON.stringify(yamlContent).replace(/null/g, '""')); - if (yamlContent.server) { - if (yamlContent.server.customMiddleware) { - let previewMiddleware = yamlContent.server.customMiddleware.find((middleware) => { - return middleware.name === 'fiori-tools-preview'; - }); - - const livereloadMiddleware = yamlContent.server.customMiddleware.find((middleware) => { - return middleware.name === 'fiori-tools-appreload'; - }); + // yamlContent = JSON.parse(JSON.stringify(yamlContent).replace(/null/g, '""')); - if (livereloadMiddleware) { - previewMiddlewareTemplate.afterMiddleware = 'fiori-tools-appreload'; - livereloadMiddleware.configuration.delay = 300; - } + const existingPreviewMiddleware = ui5YamlConfig.findCustomMiddleware('firoi-tools-preview'); + const existingLivereloadMiddleware = ui5YamlConfig.findCustomMiddleware('fiori-tools-appreload'); - if (!previewMiddleware) { - yamlContent.server.customMiddleware.push(previewMiddlewareTemplate); - await promises.writeFile(yamlFile, YAML.stringify(yamlContent), { encoding: 'utf8' }); - } else { - previewMiddleware = previewMiddlewareTemplate; - await promises.writeFile(yamlFile, YAML.stringify(yamlContent), { encoding: 'utf8' }); + if (isDeprecatedConfig(existingPreviewMiddleware!.configuration)) { + previewMiddlewareConfig.configuration = { + flp: { + path: '/test/flpSandbox.html', + intent: { object: 'preview', action: 'app' }, + theme: existingPreviewMiddleware?.configuration.ui5Theme, + libs: existingPreviewMiddleware?.configuration.libs } - } else { - yamlContent.server.customMiddleware = []; - yamlContent.server.customMiddleware.push(previewMiddlewareTemplate); - await promises.writeFile(yamlFile, YAML.stringify(yamlContent), { encoding: 'utf8' }); - } + }; } else { - yamlContent.server = { customMiddleware: [] }; - yamlContent.server.customMiddleware.push(previewMiddlewareTemplate); - await promises.writeFile(yamlFile, YAML.stringify(yamlContent), { encoding: 'utf8' }); + previewMiddlewareConfig.configuration = existingPreviewMiddleware?.configuration + ? { ...existingPreviewMiddleware?.configuration } + : {}; + } + + if (existingLivereloadMiddleware) { + previewMiddlewareConfig.afterMiddleware = 'fiori-tools-appreload'; + existingLivereloadMiddleware.configuration.delay = 300; } + + return previewMiddlewareConfig; } /** - * Checks the project for ui5 yaml files and adds the fiori-tools-preview middleware to it - * @param projectPath path to the project root - * @param args arguments passed by cli + * Checks the project for ui5 yaml files and adds the fiori-tools-preview middleware to it. + * + * @param fs - mem-fs reference to be used for file access + * @param basePath - path to project root, where package.json and ui5.yaml is + * @param logger - logger */ -export async function addPreviewMiddlewareToYaml(projectPath: string, args: string[]): Promise { - const ui5YamlFileName = getYamlFile(args); - const ui5YamlPaths = [ - join(projectPath, ui5YamlFileName), - join(projectPath, FileName.Ui5LocalYaml), - join(projectPath, FileName.Ui5MockYaml) - ]; +export async function addPreviewMiddlewareToYaml(fs: Editor, basePath: string, logger?: ToolsLogger): Promise { + const ui5Yamls = [FileName.Ui5Yaml, FileName.Ui5MockYaml, FileName.Ui5LocalYaml]; + for (const ui5Yaml of ui5Yamls) { + let existingUi5YamlConfig: UI5Config; + try { + // existingUi5YamlConfig = await UI5Config.newInstance(fs.read(ui5Yaml)); + existingUi5YamlConfig = await readUi5Yaml(basePath, ui5Yaml); + // previewMiddlewareConfig = await addPreviewMiddleware(fs, existingUi5YamlConfig, ui5YamlPath); + } catch (error) { + logger?.debug(`File ${ui5Yaml} not existing`); + //ToDo: check continue + continue; + } + + //ToDo: check for logic if middleware is there + const previewMiddlewareConfig = existingUi5YamlConfig.updateCustomMiddleware( + await addPreviewMiddleware(existingUi5YamlConfig) + ); - for (const ui5YamlPath of ui5YamlPaths) { - if (existsSync(ui5YamlPath)) { - const ui5Yaml = await readUi5Yaml(projectPath, FileName.UI5DeployYaml); - await addPreviewMiddleware(ui5Yaml, ui5YamlPath); + if (previewMiddlewareConfig) { + // const yamlConfig = existingUi5YamlConfig.updateCustomMiddleware(previewMiddlewareConfig); + const yamlConfig = previewMiddlewareConfig.toString(); + fs.write(join(basePath, ui5Yaml), yamlConfig); } } } From 834e46d458b02b762c408a1ec3e262e1dc07d92c Mon Sep 17 00:00:00 2001 From: Annemarie Date: Thu, 19 Sep 2024 11:04:29 +0200 Subject: [PATCH 03/37] feat: add varinats config --- packages/app-config-writer/package.json | 1 + packages/app-config-writer/src/types/index.ts | 1 + .../src/types/variantsConfig.ts | 24 +++++++ .../variants-config/generateVariantsConfig.ts | 9 ++- .../src/variants-config/index.ts | 1 - .../src/variants-config/package-json.ts | 22 +++---- .../src/variants-config/types.ts | 56 ----------------- .../src/variants-config/ui5-yaml.ts | 62 +++++++------------ .../src/variants-config/utils.ts | 28 +++++++++ packages/app-config-writer/tsconfig.json | 57 +++++++++-------- .../create/src/cli/add/variants-config.ts | 1 - pnpm-lock.yaml | 3 + 12 files changed, 121 insertions(+), 144 deletions(-) create mode 100644 packages/app-config-writer/src/types/variantsConfig.ts delete mode 100644 packages/app-config-writer/src/variants-config/types.ts diff --git a/packages/app-config-writer/package.json b/packages/app-config-writer/package.json index 4e4c923b8a..f4247d954a 100644 --- a/packages/app-config-writer/package.json +++ b/packages/app-config-writer/package.json @@ -29,6 +29,7 @@ "!dist/**/*.map" ], "dependencies": { + "@sap-ux/preview-middleware": "workspace:*", "@sap-ux/axios-extension": "workspace:*", "@sap-ux/btp-utils": "workspace:*", "@sap-ux/logger": "workspace:*", diff --git a/packages/app-config-writer/src/types/index.ts b/packages/app-config-writer/src/types/index.ts index 8a5a98d7a7..76e818e9fd 100644 --- a/packages/app-config-writer/src/types/index.ts +++ b/packages/app-config-writer/src/types/index.ts @@ -1 +1,2 @@ export * from './smartLinks'; +export * from './variantsConfig'; diff --git a/packages/app-config-writer/src/types/variantsConfig.ts b/packages/app-config-writer/src/types/variantsConfig.ts new file mode 100644 index 0000000000..d2188608c3 --- /dev/null +++ b/packages/app-config-writer/src/types/variantsConfig.ts @@ -0,0 +1,24 @@ +import type { MiddlewareConfig } from '@sap-ux/preview-middleware'; + +export const SAP_CLIENT_REGEX = /sap-client=([0-9]{3})/; +export const FIORI_TOOLS_RTA_MODE_TRUE = 'true'; +export const FIORI_TOOLS_RTA_MODE_VARIANTS = 'forVariants'; +export const FIORI_TOOLS_RTA_MODE_ADAPTATION = 'forAdaptation'; + +export type FioriToolsRtaMode = + | typeof FIORI_TOOLS_RTA_MODE_TRUE + | typeof FIORI_TOOLS_RTA_MODE_VARIANTS + | typeof FIORI_TOOLS_RTA_MODE_ADAPTATION; + +export interface FioriToolsDeprecatedPreviewConfig { + component: string; + libs?: boolean; + ui5Theme?: string; +} +export type FioriToolsPreviewConfig = MiddlewareConfig; +export type FioriPreviewConfigOptions = FioriToolsDeprecatedPreviewConfig | FioriToolsPreviewConfig; + +export enum MiddlewareConfigs { + 'FioriToolsPreview' = 'fiori-tools-preview', + 'FioriToolsAppreload' = 'fiori-tools-appreload' +} diff --git a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts index 3da38d1426..b3f4186141 100644 --- a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts +++ b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts @@ -1,10 +1,9 @@ -import { create as createStorage } from 'mem-fs'; import { create } from 'mem-fs-editor'; +import { create as createStorage } from 'mem-fs'; +import { addPreviewMiddlewareToYaml } from './ui5-yaml'; +import { addVariantsManagementScript } from './package-json'; import type { Editor } from 'mem-fs-editor'; import type { ToolsLogger } from '@sap-ux/logger'; -import { addVariantsManagementScript } from './package-json'; -import { addPreviewMiddlewareToYaml } from './ui5-yaml'; - /** * Add variants configuration to a UI5 application. * @@ -17,7 +16,7 @@ export async function generateVariantsConfig(basePath: string, logger?: ToolsLog if (!fs) { fs = create(createStorage()); } - await addVariantsManagementScript(fs, basePath); + addVariantsManagementScript(fs, basePath); await addPreviewMiddlewareToYaml(fs, basePath, logger); return fs; } diff --git a/packages/app-config-writer/src/variants-config/index.ts b/packages/app-config-writer/src/variants-config/index.ts index 626062d696..a0fc895336 100644 --- a/packages/app-config-writer/src/variants-config/index.ts +++ b/packages/app-config-writer/src/variants-config/index.ts @@ -1,2 +1 @@ export * from './generateVariantsConfig'; -// export { getTargetDefinition, getLocalStoredCredentials } from './utils'; diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index b28f583320..d412c3f3cb 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -1,18 +1,10 @@ import { join } from 'path'; +import { stringify } from 'querystring'; +import { SAP_CLIENT_REGEX, FIORI_TOOLS_RTA_MODE_TRUE } from '../types'; import type { Editor } from 'mem-fs-editor'; -// import { createApplicationAccess } from '@sap-ux/project-access'; +import type { FioriToolsRtaMode } from '../types'; import type { Package } from '@sap-ux/project-access'; -import { stringify } from 'querystring'; -//TDo: check for i18n -const SAP_CLIENT_REGEX = /sap-client=([0-9]{3})/; -const FIORI_TOOLS_RTA_MODE_TRUE = 'true'; -const FIORI_TOOLS_RTA_MODE_VARIANTS = 'forVariants'; -const FIORI_TOOLS_RTA_MODE_ADAPTATION = 'forAdaptation'; -type FioriToolsRtaMode = - | typeof FIORI_TOOLS_RTA_MODE_TRUE - | typeof FIORI_TOOLS_RTA_MODE_VARIANTS - | typeof FIORI_TOOLS_RTA_MODE_ADAPTATION; //TDo: check for endpoint and hash const PREVIEW_PAGE = 'preview.html'; const PREVIEW_APP_NAME = 'preview-app'; @@ -24,7 +16,6 @@ const PREVIEW_APP_NAME = 'preview-app'; */ function getSapClientFromPackageJson(packageJson: Package): any { const scripts = (packageJson.script ||= {}); - // ToDo: check for different iteration const scriptValues = Object.values(scripts); scriptValues.forEach((scriptValue) => { const match = scriptValue.match(SAP_CLIENT_REGEX); @@ -40,7 +31,7 @@ function getSapClientFromPackageJson(packageJson: Package): any { * * @param rtaMode - path to package.json * @param overwritingParams - parameters to be overwritten - * @returns - overwritten parameters + * @returns - UI5 url parameters */ function getUi5UrlParameters( rtaMode: FioriToolsRtaMode, @@ -79,13 +70,14 @@ export function addVariantsManagementScript(fs: Editor, basePath: string): void // check if sap-client is needed when starting the app const urlParameters: Record = {}; const sapClient = getSapClientFromPackageJson(packageJson); + if (sapClient) { urlParameters['sap-client'] = sapClient; } + const query = getUi5UrlParameters(FIORI_TOOLS_RTA_MODE_TRUE, urlParameters); - // Remove / const url = getPreviewUrl(query).slice(1); - //TDo: check script name + const startVariantsManagement = 'start-variants-management'; const variantsScript = `fiori run --open "${url}"`; diff --git a/packages/app-config-writer/src/variants-config/types.ts b/packages/app-config-writer/src/variants-config/types.ts deleted file mode 100644 index 23a3313b6e..0000000000 --- a/packages/app-config-writer/src/variants-config/types.ts +++ /dev/null @@ -1,56 +0,0 @@ -type UI5FlexLayer = 'VENDOR' | 'CUSTOMER_BASE'; -interface RtaConfig { - layer: UI5FlexLayer; - options?: { - [key: string]: unknown; - baseId?: string; - projectId?: string; - scenario?: string; - appName?: string; - }; - editors: any[]; -} -interface Intent { - object: string; - action: string; -} -interface App { - target: string; - local?: string; - componentId?: string; - intent?: Intent; -} -interface FlpConfig { - path: string; - intent: Intent; - libs?: boolean; - apps: App[]; - theme?: string; - init?: string; -} -interface OptionalTestConfig { - path: string; - init: string; - pattern: string; -} -interface TestConfig extends Partial { - framework: 'OPA5' | 'QUnit' | 'Testsuite'; -} -interface AdpPreviewConfig { - target: any; - ignoreCertErrors?: boolean; -} -export interface MiddlewareConfig { - flp?: Partial; - test?: TestConfig[]; - rta?: RtaConfig; - adp?: AdpPreviewConfig; - debug?: boolean; -} -export interface DeprecatedConfig { - component: string; - libs?: boolean; - ui5Theme?: string; -} - -export type PreviewConfigOptions = DeprecatedConfig | MiddlewareConfig; diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index 73c1c45cce..01a4845d9f 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -1,20 +1,13 @@ import { join } from 'path'; +import { MiddlewareConfigs } from '../types'; import { FileName, readUi5Yaml } from '@sap-ux/project-access'; -import type { UI5Config } from '@sap-ux/ui5-config'; +import { convertDeprecatedConfig, isDeprecatedConfig } from './utils'; import type { Editor } from 'mem-fs-editor'; -import type { CustomMiddleware } from '@sap-ux/ui5-config'; import type { ToolsLogger } from '@sap-ux/logger'; -import type { PreviewConfigOptions, DeprecatedConfig, MiddlewareConfig } from './types'; - -/** - * Checks if a fiori-tools-preview middleware configuration is decprecated. - * - * @param config fiori-tools-preview middleware configuration - * @returns type conversion if true - */ -function isDeprecatedConfig(config: PreviewConfigOptions): config is DeprecatedConfig { - return (config as DeprecatedConfig)?.component !== undefined; -} +import type { UI5Config } from '@sap-ux/ui5-config'; +import type { CustomMiddleware } from '@sap-ux/ui5-config'; +import type { FioriAppReloadConfig } from '@sap-ux/ui5-config'; +import type { FioriToolsPreviewConfig, FioriPreviewConfigOptions } from '../types'; /** * Adds the fiori-tools-preview middleware configuration. @@ -22,41 +15,33 @@ function isDeprecatedConfig(config: PreviewConfigOptions): config is DeprecatedC * @param ui5YamlConfig existing ui5 yaml configurations * @returns 'fiori-tools-preview' configuration */ -async function addPreviewMiddleware( - ui5YamlConfig: UI5Config - // ToDo: create middleware type -): Promise> { +async function getPreviewMiddleware(ui5YamlConfig: UI5Config): Promise> { + // ToDO: check for needed flp config const previewMiddlewareConfig = { name: 'fiori-tools-preview', afterMiddleware: 'compression', configuration: {} }; - // ToDo: check if needed - // replace null occurrences with an empty string - // yamlContent = JSON.parse(JSON.stringify(yamlContent).replace(/null/g, '""')); - - const existingPreviewMiddleware = ui5YamlConfig.findCustomMiddleware('firoi-tools-preview'); - const existingLivereloadMiddleware = ui5YamlConfig.findCustomMiddleware('fiori-tools-appreload'); + const existingPreviewMiddleware = ui5YamlConfig.findCustomMiddleware( + MiddlewareConfigs.FioriToolsPreview + ); + const existingLivereloadMiddleware = ui5YamlConfig.findCustomMiddleware( + MiddlewareConfigs.FioriToolsAppreload + ); - if (isDeprecatedConfig(existingPreviewMiddleware!.configuration)) { - previewMiddlewareConfig.configuration = { - flp: { - path: '/test/flpSandbox.html', - intent: { object: 'preview', action: 'app' }, - theme: existingPreviewMiddleware?.configuration.ui5Theme, - libs: existingPreviewMiddleware?.configuration.libs - } - }; + if (existingPreviewMiddleware && isDeprecatedConfig(existingPreviewMiddleware.configuration)) { + previewMiddlewareConfig.configuration = convertDeprecatedConfig(existingPreviewMiddleware.configuration); } else { previewMiddlewareConfig.configuration = existingPreviewMiddleware?.configuration ? { ...existingPreviewMiddleware?.configuration } - : {}; + : ''; } if (existingLivereloadMiddleware) { previewMiddlewareConfig.afterMiddleware = 'fiori-tools-appreload'; - existingLivereloadMiddleware.configuration.delay = 300; + // ToDo: check for app-reload config and update + // ui5YamlConfig.addFioriToolsAppReloadMiddleware(); } return previewMiddlewareConfig; @@ -74,24 +59,19 @@ export async function addPreviewMiddlewareToYaml(fs: Editor, basePath: string, l for (const ui5Yaml of ui5Yamls) { let existingUi5YamlConfig: UI5Config; try { - // existingUi5YamlConfig = await UI5Config.newInstance(fs.read(ui5Yaml)); existingUi5YamlConfig = await readUi5Yaml(basePath, ui5Yaml); - // previewMiddlewareConfig = await addPreviewMiddleware(fs, existingUi5YamlConfig, ui5YamlPath); } catch (error) { logger?.debug(`File ${ui5Yaml} not existing`); //ToDo: check continue continue; } - //ToDo: check for logic if middleware is there const previewMiddlewareConfig = existingUi5YamlConfig.updateCustomMiddleware( - await addPreviewMiddleware(existingUi5YamlConfig) + await getPreviewMiddleware(existingUi5YamlConfig) ); if (previewMiddlewareConfig) { - // const yamlConfig = existingUi5YamlConfig.updateCustomMiddleware(previewMiddlewareConfig); - const yamlConfig = previewMiddlewareConfig.toString(); - fs.write(join(basePath, ui5Yaml), yamlConfig); + fs.write(join(basePath, ui5Yaml), previewMiddlewareConfig.toString()); } } } diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index e69de29bb2..8a7cdadcab 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -0,0 +1,28 @@ +import type { FioriToolsDeprecatedPreviewConfig, FioriToolsPreviewConfig, FioriPreviewConfigOptions } from '../types'; + +/** + * Checks if a fiori-tools-preview middleware configuration is decprecated. + * + * @param config fiori-tools-preview middleware configuration + * @returns type conversion if true + */ +export function isDeprecatedConfig(config: FioriPreviewConfigOptions): config is FioriToolsDeprecatedPreviewConfig { + return (config as FioriToolsDeprecatedPreviewConfig)?.component !== undefined; +} + +/** + * Converts a deprecated preview middleware configuration internally to match the configurations provided by the open source @sap-ux/preview-middleware. + * + * @param config configuration from the ui5.yaml. + * @returns {PreviewConfig} configuration for the preview middleware. + */ +export function convertDeprecatedConfig(config: FioriToolsDeprecatedPreviewConfig): FioriToolsPreviewConfig { + return { + flp: { + path: '/test/flpSandbox.html', + intent: { object: 'preview', action: 'app' }, + theme: config.ui5Theme, + libs: config.libs + } + }; +} diff --git a/packages/app-config-writer/tsconfig.json b/packages/app-config-writer/tsconfig.json index e916ad9dc2..9e316fcc6b 100644 --- a/packages/app-config-writer/tsconfig.json +++ b/packages/app-config-writer/tsconfig.json @@ -1,28 +1,35 @@ { - "extends": "../../tsconfig.json", - "include": ["../../types/mem-fs-editor.d.ts", "src", "src/**/*.json"], - "compilerOptions": { - "rootDir": "src", - "outDir": "dist" + "extends": "../../tsconfig.json", + "include": [ + "../../types/mem-fs-editor.d.ts", + "src", + "src/**/*.json" + ], + "compilerOptions": { + "rootDir": "src", + "outDir": "dist" + }, + "references": [ + { + "path": "../axios-extension" }, - "references": [ - { - "path": "../axios-extension" - }, - { - "path": "../btp-utils" - }, - { - "path": "../logger" - }, - { - "path": "../project-access" - }, - { - "path": "../store" - }, - { - "path": "../ui5-config" - } - ] + { + "path": "../btp-utils" + }, + { + "path": "../logger" + }, + { + "path": "../preview-middleware" + }, + { + "path": "../project-access" + }, + { + "path": "../store" + }, + { + "path": "../ui5-config" + } + ] } diff --git a/packages/create/src/cli/add/variants-config.ts b/packages/create/src/cli/add/variants-config.ts index bfc2bc271f..e1d06c569d 100644 --- a/packages/create/src/cli/add/variants-config.ts +++ b/packages/create/src/cli/add/variants-config.ts @@ -30,7 +30,6 @@ async function addVariantsConfig(basePath: string, simulate: boolean): Promise Date: Thu, 19 Sep 2024 12:24:23 +0200 Subject: [PATCH 04/37] feat: add varinats config --- .../src/variants-config/package-json.ts | 20 ++++++++++--------- .../src/variants-config/ui5-yaml.ts | 3 ++- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index d412c3f3cb..b801a513fa 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -15,15 +15,17 @@ const PREVIEW_APP_NAME = 'preview-app'; * @param packageJson - path to package.json */ function getSapClientFromPackageJson(packageJson: Package): any { - const scripts = (packageJson.script ||= {}); - const scriptValues = Object.values(scripts); - scriptValues.forEach((scriptValue) => { - const match = scriptValue.match(SAP_CLIENT_REGEX); - if (match) { - return match; - } - return undefined; - }); + const scripts = packageJson.scripts; + if (scripts) { + const scriptValues = Object.values(scripts); + scriptValues.forEach((scriptValue) => { + const match = scriptValue?.match(SAP_CLIENT_REGEX); + if (match) { + return match; + } + return undefined; + }); + } } /** diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index 01a4845d9f..75c99bf882 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -16,7 +16,7 @@ import type { FioriToolsPreviewConfig, FioriPreviewConfigOptions } from '../type * @returns 'fiori-tools-preview' configuration */ async function getPreviewMiddleware(ui5YamlConfig: UI5Config): Promise> { - // ToDO: check for needed flp config + // ToDo: check for needed flp config const previewMiddlewareConfig = { name: 'fiori-tools-preview', afterMiddleware: 'compression', @@ -41,6 +41,7 @@ async function getPreviewMiddleware(ui5YamlConfig: UI5Config): Promise Date: Wed, 25 Sep 2024 10:36:55 +0200 Subject: [PATCH 05/37] feat: add varinats config --- .../src/types/variantsConfig.ts | 5 +- .../variants-config/generateVariantsConfig.ts | 5 +- .../src/variants-config/package-json.ts | 78 +++++++++---------- .../src/variants-config/ui5-yaml.ts | 60 +++++++------- .../src/variants-config/utils.ts | 42 ++++++---- .../create/src/cli/add/variants-config.ts | 5 +- 6 files changed, 109 insertions(+), 86 deletions(-) diff --git a/packages/app-config-writer/src/types/variantsConfig.ts b/packages/app-config-writer/src/types/variantsConfig.ts index d2188608c3..59490765c8 100644 --- a/packages/app-config-writer/src/types/variantsConfig.ts +++ b/packages/app-config-writer/src/types/variantsConfig.ts @@ -1,6 +1,5 @@ import type { MiddlewareConfig } from '@sap-ux/preview-middleware'; -export const SAP_CLIENT_REGEX = /sap-client=([0-9]{3})/; export const FIORI_TOOLS_RTA_MODE_TRUE = 'true'; export const FIORI_TOOLS_RTA_MODE_VARIANTS = 'forVariants'; export const FIORI_TOOLS_RTA_MODE_ADAPTATION = 'forAdaptation'; @@ -15,10 +14,14 @@ export interface FioriToolsDeprecatedPreviewConfig { libs?: boolean; ui5Theme?: string; } + export type FioriToolsPreviewConfig = MiddlewareConfig; export type FioriPreviewConfigOptions = FioriToolsDeprecatedPreviewConfig | FioriToolsPreviewConfig; export enum MiddlewareConfigs { 'FioriToolsPreview' = 'fiori-tools-preview', + // ToDo: check for preview-middleware + 'PreviewMiddleware' = 'preview-middleware', + 'ReloadMiddleware' = 'reload-middleware', 'FioriToolsAppreload' = 'fiori-tools-appreload' } diff --git a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts index b3f4186141..3019eaae66 100644 --- a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts +++ b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts @@ -4,8 +4,9 @@ import { addPreviewMiddlewareToYaml } from './ui5-yaml'; import { addVariantsManagementScript } from './package-json'; import type { Editor } from 'mem-fs-editor'; import type { ToolsLogger } from '@sap-ux/logger'; + /** - * Add variants configuration to a UI5 application. + * Add variants configuration to an app or project. * * @param basePath - the base path where the package.json and ui5.yaml is * @param logger - logger @@ -16,7 +17,7 @@ export async function generateVariantsConfig(basePath: string, logger?: ToolsLog if (!fs) { fs = create(createStorage()); } - addVariantsManagementScript(fs, basePath); + await addVariantsManagementScript(fs, basePath, logger); await addPreviewMiddlewareToYaml(fs, basePath, logger); return fs; } diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index b801a513fa..e95471771d 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -1,45 +1,38 @@ import { join } from 'path'; import { stringify } from 'querystring'; -import { SAP_CLIENT_REGEX, FIORI_TOOLS_RTA_MODE_TRUE } from '../types'; +import { FIORI_TOOLS_RTA_MODE_TRUE } from '../types'; +import { checkDeprecatedPreviewMiddleware } from './utils'; import type { Editor } from 'mem-fs-editor'; import type { FioriToolsRtaMode } from '../types'; import type { Package } from '@sap-ux/project-access'; - -//TDo: check for endpoint and hash -const PREVIEW_PAGE = 'preview.html'; -const PREVIEW_APP_NAME = 'preview-app'; +import type { ToolsLogger } from '@sap-ux/logger'; /** * Extracts sap client string from existing scripts in package.json. * - * @param packageJson - path to package.json + * @param scripts - script section of the package.json + * @returns sap client */ -function getSapClientFromPackageJson(packageJson: Package): any { - const scripts = packageJson.scripts; - if (scripts) { - const scriptValues = Object.values(scripts); - scriptValues.forEach((scriptValue) => { - const match = scriptValue?.match(SAP_CLIENT_REGEX); - if (match) { - return match; - } - return undefined; - }); - } +function getSapClientFromPackageJson(scripts: Partial>): string | undefined { + let sapClient; + Object.values(scripts).forEach((script) => { + const match = script?.match(/sap-client=([0-9]{3})/); + if (match) { + sapClient = match[1]; + } + }); + return sapClient; } /** * Returns the UI5 url parameters. * - * @param rtaMode - path to package.json + * @param rtaMode - RTA Mode parameters * @param overwritingParams - parameters to be overwritten * @returns - UI5 url parameters */ -function getUi5UrlParameters( - rtaMode: FioriToolsRtaMode, - overwritingParams: Record = {} -): string { - const parameters: Record = { +function getUi5UrlParameters(rtaMode: FioriToolsRtaMode, overwritingParams: Record = {}): string { + const parameters: Record = { 'fiori-tools-rta-mode': rtaMode, 'sap-ui-rta-skip-flex-validation': 'true', 'sap-ui-xx-condense-changes': 'true' @@ -50,12 +43,15 @@ function getUi5UrlParameters( /** * Returns the preview url parameters. * + * @param basePath - path to project root, where package.json and ui5.yaml is * @param query - query to create fragment * @returns - review url parameters */ -function getPreviewUrl(query?: string): string { +async function getPreviewUrl(basePath: string, query?: string): Promise { const queryFragment = query ? `?${query}` : ''; - return `/${PREVIEW_PAGE}${queryFragment}#${PREVIEW_APP_NAME}`; + // checks if a ui5.yaml configuration is deprecated and therefore needs a different hash + const previewHash = (await checkDeprecatedPreviewMiddleware(basePath)) ? 'preview-app' : 'app-preview'; + return `/preview.html${queryFragment}#${previewHash}`; } /** @@ -63,28 +59,30 @@ function getPreviewUrl(query?: string): string { * * @param fs - mem-fs reference to be used for file access * @param basePath - path to application root, where package.json is + * @param logger - logger */ -export function addVariantsManagementScript(fs: Editor, basePath: string): void { +export async function addVariantsManagementScript(fs: Editor, basePath: string, logger?: ToolsLogger): Promise { const packageJsonPath = join(basePath, 'package.json'); const packageJson = fs.readJSON(packageJsonPath) as Package; - if (packageJson.scripts) { - // check if sap-client is needed when starting the app - const urlParameters: Record = {}; - const sapClient = getSapClientFromPackageJson(packageJson); + const scripts = packageJson.scripts ?? {}; + const urlParameters: Record = {}; + if (!packageJson.scripts) { + logger?.warn(`File 'package.json' does not contain a script section. Script section added.`); + packageJson['scripts'] = scripts; + } else { + // check if sap-client is needed when starting the app + const sapClient = getSapClientFromPackageJson(packageJson.scripts); if (sapClient) { urlParameters['sap-client'] = sapClient; } + } - const query = getUi5UrlParameters(FIORI_TOOLS_RTA_MODE_TRUE, urlParameters); - const url = getPreviewUrl(query).slice(1); - - const startVariantsManagement = 'start-variants-management'; - const variantsScript = `fiori run --open "${url}"`; - - packageJson.scripts[startVariantsManagement] = variantsScript; + const query = getUi5UrlParameters(FIORI_TOOLS_RTA_MODE_TRUE, urlParameters); + const url = await getPreviewUrl(basePath, query); - fs.writeJSON(packageJsonPath, packageJson); - } + scripts['start-variants-management'] = `fiori run --open "${url.slice(1)}"`; + fs.writeJSON(packageJsonPath, packageJson); + logger?.info(`Script 'start-variants-management' written to 'package.json'.`); } diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index 75c99bf882..3c28e16d83 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -1,55 +1,63 @@ import { join } from 'path'; import { MiddlewareConfigs } from '../types'; import { FileName, readUi5Yaml } from '@sap-ux/project-access'; -import { convertDeprecatedConfig, isDeprecatedConfig } from './utils'; import type { Editor } from 'mem-fs-editor'; import type { ToolsLogger } from '@sap-ux/logger'; import type { UI5Config } from '@sap-ux/ui5-config'; import type { CustomMiddleware } from '@sap-ux/ui5-config'; import type { FioriAppReloadConfig } from '@sap-ux/ui5-config'; -import type { FioriToolsPreviewConfig, FioriPreviewConfigOptions } from '../types'; +import type { FioriPreviewConfigOptions } from '../types'; /** - * Adds the fiori-tools-preview middleware configuration. + * Gets the fiori-tools-preview middleware configuration. * - * @param ui5YamlConfig existing ui5 yaml configurations + * @param ui5YamlConfig existing ui5.yaml configurations * @returns 'fiori-tools-preview' configuration */ -async function getPreviewMiddleware(ui5YamlConfig: UI5Config): Promise> { - // ToDo: check for needed flp config - const previewMiddlewareConfig = { +function getFioriToolsPreviewConfig(ui5YamlConfig: UI5Config): CustomMiddleware { + let previewMiddlewareConfig = { name: 'fiori-tools-preview', - afterMiddleware: 'compression', - configuration: {} - }; + afterMiddleware: 'compression' + } as CustomMiddleware; const existingPreviewMiddleware = ui5YamlConfig.findCustomMiddleware( MiddlewareConfigs.FioriToolsPreview ); - const existingLivereloadMiddleware = ui5YamlConfig.findCustomMiddleware( + const existingReloadMiddleware = ui5YamlConfig.findCustomMiddleware( MiddlewareConfigs.FioriToolsAppreload ); - if (existingPreviewMiddleware && isDeprecatedConfig(existingPreviewMiddleware.configuration)) { - previewMiddlewareConfig.configuration = convertDeprecatedConfig(existingPreviewMiddleware.configuration); - } else { - previewMiddlewareConfig.configuration = existingPreviewMiddleware?.configuration - ? { ...existingPreviewMiddleware?.configuration } - : ''; + if (existingPreviewMiddleware?.configuration) { + const config = Object.defineProperty(previewMiddlewareConfig, 'configuration', { + writable: true, + enumerable: true, + configurable: true, + value: existingPreviewMiddleware.configuration + }); + previewMiddlewareConfig = config; } - if (existingLivereloadMiddleware) { - previewMiddlewareConfig.afterMiddleware = 'fiori-tools-appreload'; - // ToDo: check for app-reload config and update - // existingLivereloadMiddleware.configuration.delay = 300; - // ui5YamlConfig.addFioriToolsAppReloadMiddleware(); + if (existingReloadMiddleware) { + previewMiddlewareConfig.afterMiddleware = MiddlewareConfigs.FioriToolsAppreload; + // ToDo: check if this is needed + if (existingReloadMiddleware.configuration) { + existingReloadMiddleware.configuration['delay'] = 300; + + ui5YamlConfig.updateCustomMiddleware({ + name: 'fiori-tools-appreload', + afterMiddleware: existingReloadMiddleware.afterMiddleware, + configuration: { + ...existingReloadMiddleware.configuration + } + }); + } } return previewMiddlewareConfig; } /** - * Checks the project for ui5 yaml files and adds the fiori-tools-preview middleware to it. + * Checks the project for ui5.yaml files and adds the fiori-tools-preview middleware to it. * * @param fs - mem-fs reference to be used for file access * @param basePath - path to project root, where package.json and ui5.yaml is @@ -62,17 +70,17 @@ export async function addPreviewMiddlewareToYaml(fs: Editor, basePath: string, l try { existingUi5YamlConfig = await readUi5Yaml(basePath, ui5Yaml); } catch (error) { - logger?.debug(`File ${ui5Yaml} not existing`); - //ToDo: check continue + logger?.debug(`Cannot write varinats-config to ${ui5Yaml}. File not existing`); continue; } const previewMiddlewareConfig = existingUi5YamlConfig.updateCustomMiddleware( - await getPreviewMiddleware(existingUi5YamlConfig) + getFioriToolsPreviewConfig(existingUi5YamlConfig) ); if (previewMiddlewareConfig) { fs.write(join(basePath, ui5Yaml), previewMiddlewareConfig.toString()); + logger?.info(`Updated preview middleware in ${ui5Yaml}.`); } } } diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index 8a7cdadcab..d582b6b668 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -1,4 +1,7 @@ -import type { FioriToolsDeprecatedPreviewConfig, FioriToolsPreviewConfig, FioriPreviewConfigOptions } from '../types'; +import { FileName, readUi5Yaml } from '@sap-ux/project-access'; +import { MiddlewareConfigs } from '../types'; +import type { CustomMiddleware } from '@sap-ux/ui5-config'; +import type { FioriPreviewConfigOptions, FioriToolsDeprecatedPreviewConfig } from '../types'; /** * Checks if a fiori-tools-preview middleware configuration is decprecated. @@ -6,23 +9,34 @@ import type { FioriToolsDeprecatedPreviewConfig, FioriToolsPreviewConfig, FioriP * @param config fiori-tools-preview middleware configuration * @returns type conversion if true */ -export function isDeprecatedConfig(config: FioriPreviewConfigOptions): config is FioriToolsDeprecatedPreviewConfig { +function isDeprecatedConfig(config: FioriPreviewConfigOptions): config is FioriToolsDeprecatedPreviewConfig { return (config as FioriToolsDeprecatedPreviewConfig)?.component !== undefined; } /** - * Converts a deprecated preview middleware configuration internally to match the configurations provided by the open source @sap-ux/preview-middleware. + * Gets the fiori-tools-preview middleware configuration. * - * @param config configuration from the ui5.yaml. - * @returns {PreviewConfig} configuration for the preview middleware. + * @param basePath - path to project root, where package.json and ui5.yaml is + * @returns 'fiori-tools-preview' configuration if given */ -export function convertDeprecatedConfig(config: FioriToolsDeprecatedPreviewConfig): FioriToolsPreviewConfig { - return { - flp: { - path: '/test/flpSandbox.html', - intent: { object: 'preview', action: 'app' }, - theme: config.ui5Theme, - libs: config.libs - } - }; +async function getFioriToolsPreviewMiddleware( + basePath: string +): Promise | undefined> { + const existingUi5YamlConfig = await readUi5Yaml(basePath, FileName.Ui5Yaml); + return existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview); +} + +/** + * Gets the the fiori-tools-preview middleware configuration and checks if it's decprecated. + * + * @param basePath - path to project root, where package.json and ui5.yaml is + * @returns true, if a fiori-tools-previewre middleware configuration is deprecated + */ +export async function checkDeprecatedPreviewMiddleware(basePath: string): Promise { + const existingPreviewMiddleware = await getFioriToolsPreviewMiddleware(basePath); + if (existingPreviewMiddleware && isDeprecatedConfig(existingPreviewMiddleware.configuration)) { + return true; + } else { + return false; + } } diff --git a/packages/create/src/cli/add/variants-config.ts b/packages/create/src/cli/add/variants-config.ts index e1d06c569d..b29da78584 100644 --- a/packages/create/src/cli/add/variants-config.ts +++ b/packages/create/src/cli/add/variants-config.ts @@ -6,7 +6,7 @@ import { generateVariantsConfig } from '@sap-ux/app-config-writer'; /** * Add the "add variants config" command to a passed command. * - * @param cmd - commander command for adding config command + * @param cmd - commander command for adding variants config command */ export function addAddVariantsConfigCommand(cmd: Command): void { cmd.command('variants-config [path]') @@ -23,7 +23,7 @@ export function addAddVariantsConfigCommand(cmd: Command): void { /** * Adds a variants config to an app or project. * - * @param basePath - path to application root + * @param basePath - the base path where the package.json and ui5.yaml is * @param simulate - if true, do not write but just show what would be change; otherwise write */ async function addVariantsConfig(basePath: string, simulate: boolean): Promise { @@ -34,7 +34,6 @@ async function addVariantsConfig(basePath: string, simulate: boolean): Promise mockserver-config.ts fs.commit(() => logger.info(`Variants configuration written.`)); } } catch (error) { From 7e4941aeff819c683c746857a67bbd645fa41e82 Mon Sep 17 00:00:00 2001 From: Annemarie Date: Wed, 25 Sep 2024 17:27:27 +0200 Subject: [PATCH 06/37] feat: add varinats config --- .../src/types/variantsConfig.ts | 10 --- .../variants-config/generateVariantsConfig.ts | 4 +- .../src/variants-config/package-json.ts | 54 +-------------- .../src/variants-config/ui5-yaml.ts | 38 ++++------- .../src/variants-config/utils.ts | 65 ++++++++++++++----- 5 files changed, 64 insertions(+), 107 deletions(-) diff --git a/packages/app-config-writer/src/types/variantsConfig.ts b/packages/app-config-writer/src/types/variantsConfig.ts index 59490765c8..ffeb0446f0 100644 --- a/packages/app-config-writer/src/types/variantsConfig.ts +++ b/packages/app-config-writer/src/types/variantsConfig.ts @@ -1,14 +1,4 @@ import type { MiddlewareConfig } from '@sap-ux/preview-middleware'; - -export const FIORI_TOOLS_RTA_MODE_TRUE = 'true'; -export const FIORI_TOOLS_RTA_MODE_VARIANTS = 'forVariants'; -export const FIORI_TOOLS_RTA_MODE_ADAPTATION = 'forAdaptation'; - -export type FioriToolsRtaMode = - | typeof FIORI_TOOLS_RTA_MODE_TRUE - | typeof FIORI_TOOLS_RTA_MODE_VARIANTS - | typeof FIORI_TOOLS_RTA_MODE_ADAPTATION; - export interface FioriToolsDeprecatedPreviewConfig { component: string; libs?: boolean; diff --git a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts index 3019eaae66..4ee5c12f70 100644 --- a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts +++ b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts @@ -1,6 +1,6 @@ import { create } from 'mem-fs-editor'; import { create as createStorage } from 'mem-fs'; -import { addPreviewMiddlewareToYaml } from './ui5-yaml'; +import { updateFioriToolsPreviewMiddleware } from './ui5-yaml'; import { addVariantsManagementScript } from './package-json'; import type { Editor } from 'mem-fs-editor'; import type { ToolsLogger } from '@sap-ux/logger'; @@ -18,6 +18,6 @@ export async function generateVariantsConfig(basePath: string, logger?: ToolsLog fs = create(createStorage()); } await addVariantsManagementScript(fs, basePath, logger); - await addPreviewMiddlewareToYaml(fs, basePath, logger); + await updateFioriToolsPreviewMiddleware(fs, basePath, logger); return fs; } diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index e95471771d..62c9cff362 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -1,59 +1,9 @@ import { join } from 'path'; -import { stringify } from 'querystring'; -import { FIORI_TOOLS_RTA_MODE_TRUE } from '../types'; -import { checkDeprecatedPreviewMiddleware } from './utils'; +import { getSapClientFromPackageJson, getUi5UrlParameters, getPreviewUrl } from './utils'; import type { Editor } from 'mem-fs-editor'; -import type { FioriToolsRtaMode } from '../types'; import type { Package } from '@sap-ux/project-access'; import type { ToolsLogger } from '@sap-ux/logger'; -/** - * Extracts sap client string from existing scripts in package.json. - * - * @param scripts - script section of the package.json - * @returns sap client - */ -function getSapClientFromPackageJson(scripts: Partial>): string | undefined { - let sapClient; - Object.values(scripts).forEach((script) => { - const match = script?.match(/sap-client=([0-9]{3})/); - if (match) { - sapClient = match[1]; - } - }); - return sapClient; -} - -/** - * Returns the UI5 url parameters. - * - * @param rtaMode - RTA Mode parameters - * @param overwritingParams - parameters to be overwritten - * @returns - UI5 url parameters - */ -function getUi5UrlParameters(rtaMode: FioriToolsRtaMode, overwritingParams: Record = {}): string { - const parameters: Record = { - 'fiori-tools-rta-mode': rtaMode, - 'sap-ui-rta-skip-flex-validation': 'true', - 'sap-ui-xx-condense-changes': 'true' - }; - return stringify(Object.assign(parameters, overwritingParams)); -} - -/** - * Returns the preview url parameters. - * - * @param basePath - path to project root, where package.json and ui5.yaml is - * @param query - query to create fragment - * @returns - review url parameters - */ -async function getPreviewUrl(basePath: string, query?: string): Promise { - const queryFragment = query ? `?${query}` : ''; - // checks if a ui5.yaml configuration is deprecated and therefore needs a different hash - const previewHash = (await checkDeprecatedPreviewMiddleware(basePath)) ? 'preview-app' : 'app-preview'; - return `/preview.html${queryFragment}#${previewHash}`; -} - /** * Add the start-variants-management script to the package.json. * @@ -79,7 +29,7 @@ export async function addVariantsManagementScript(fs: Editor, basePath: string, } } - const query = getUi5UrlParameters(FIORI_TOOLS_RTA_MODE_TRUE, urlParameters); + const query = getUi5UrlParameters(urlParameters); const url = await getPreviewUrl(basePath, query); scripts['start-variants-management'] = `fiori run --open "${url.slice(1)}"`; diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index 3c28e16d83..6efa66920d 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -15,7 +15,7 @@ import type { FioriPreviewConfigOptions } from '../types'; * @returns 'fiori-tools-preview' configuration */ function getFioriToolsPreviewConfig(ui5YamlConfig: UI5Config): CustomMiddleware { - let previewMiddlewareConfig = { + const previewMiddlewareTemplate = { name: 'fiori-tools-preview', afterMiddleware: 'compression' } as CustomMiddleware; @@ -28,49 +28,35 @@ function getFioriToolsPreviewConfig(ui5YamlConfig: UI5Config): CustomMiddleware< ); if (existingPreviewMiddleware?.configuration) { - const config = Object.defineProperty(previewMiddlewareConfig, 'configuration', { - writable: true, - enumerable: true, - configurable: true, - value: existingPreviewMiddleware.configuration - }); - previewMiddlewareConfig = config; + previewMiddlewareTemplate.configuration = { ...existingPreviewMiddleware.configuration }; } if (existingReloadMiddleware) { - previewMiddlewareConfig.afterMiddleware = MiddlewareConfigs.FioriToolsAppreload; - // ToDo: check if this is needed - if (existingReloadMiddleware.configuration) { - existingReloadMiddleware.configuration['delay'] = 300; - - ui5YamlConfig.updateCustomMiddleware({ - name: 'fiori-tools-appreload', - afterMiddleware: existingReloadMiddleware.afterMiddleware, - configuration: { - ...existingReloadMiddleware.configuration - } - }); - } + previewMiddlewareTemplate.afterMiddleware = MiddlewareConfigs.FioriToolsAppreload; } - return previewMiddlewareConfig; + return previewMiddlewareTemplate; } /** - * Checks the project for ui5.yaml files and adds the fiori-tools-preview middleware to it. + * Checks the project for ui5.yaml files and updates the fiori-tools-preview middleware. * * @param fs - mem-fs reference to be used for file access * @param basePath - path to project root, where package.json and ui5.yaml is * @param logger - logger */ -export async function addPreviewMiddlewareToYaml(fs: Editor, basePath: string, logger?: ToolsLogger): Promise { +export async function updateFioriToolsPreviewMiddleware( + fs: Editor, + basePath: string, + logger?: ToolsLogger +): Promise { const ui5Yamls = [FileName.Ui5Yaml, FileName.Ui5MockYaml, FileName.Ui5LocalYaml]; for (const ui5Yaml of ui5Yamls) { let existingUi5YamlConfig: UI5Config; try { existingUi5YamlConfig = await readUi5Yaml(basePath, ui5Yaml); } catch (error) { - logger?.debug(`Cannot write varinats-config to ${ui5Yaml}. File not existing`); + logger?.debug(`Cannot write variants-config to ${ui5Yaml}. File not existing`); continue; } @@ -80,7 +66,7 @@ export async function addPreviewMiddlewareToYaml(fs: Editor, basePath: string, l if (previewMiddlewareConfig) { fs.write(join(basePath, ui5Yaml), previewMiddlewareConfig.toString()); - logger?.info(`Updated preview middleware in ${ui5Yaml}.`); + logger?.debug(`Updated preview middleware in ${ui5Yaml}.`); } } } diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index d582b6b668..2e1c02ad75 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -1,18 +1,9 @@ import { FileName, readUi5Yaml } from '@sap-ux/project-access'; import { MiddlewareConfigs } from '../types'; +import { stringify } from 'querystring'; import type { CustomMiddleware } from '@sap-ux/ui5-config'; import type { FioriPreviewConfigOptions, FioriToolsDeprecatedPreviewConfig } from '../types'; -/** - * Checks if a fiori-tools-preview middleware configuration is decprecated. - * - * @param config fiori-tools-preview middleware configuration - * @returns type conversion if true - */ -function isDeprecatedConfig(config: FioriPreviewConfigOptions): config is FioriToolsDeprecatedPreviewConfig { - return (config as FioriToolsDeprecatedPreviewConfig)?.component !== undefined; -} - /** * Gets the fiori-tools-preview middleware configuration. * @@ -27,16 +18,56 @@ async function getFioriToolsPreviewMiddleware( } /** - * Gets the the fiori-tools-preview middleware configuration and checks if it's decprecated. + * Gets the fiori-tools-preview middleware configuration and checks if it's deprecated. * * @param basePath - path to project root, where package.json and ui5.yaml is - * @returns true, if a fiori-tools-previewre middleware configuration is deprecated + * @returns true, if a fiori-tools-preview middleware configuration is deprecated */ -export async function checkDeprecatedPreviewMiddleware(basePath: string): Promise { +async function checkDeprecatedPreviewMiddleware(basePath: string): Promise { const existingPreviewMiddleware = await getFioriToolsPreviewMiddleware(basePath); - if (existingPreviewMiddleware && isDeprecatedConfig(existingPreviewMiddleware.configuration)) { - return true; - } else { - return false; + return (existingPreviewMiddleware?.configuration as FioriToolsDeprecatedPreviewConfig)?.component !== undefined; +} + +/** + * Extracts sap client string from existing scripts in package.json. + * + * @param scripts - script section of the package.json + * @returns sap client + */ +export function getSapClientFromPackageJson(scripts: Partial>): string | undefined { + for (const value of Object.values(scripts)) { + const match = value?.match(/sap-client=([0-9]{3})/); + if (match) { + return match[1]; + } } + return undefined; +} + +/** + * Returns the UI5 url parameters. + * + * @param overwritingParams - parameters to be overwritten + * @returns - UI5 url parameters + */ +export function getUi5UrlParameters(overwritingParams: Record = {}): string { + const parameters: Record = { + 'fiori-tools-rta-mode': 'true', + 'sap-ui-rta-skip-flex-validation': 'true', + 'sap-ui-xx-condense-changes': 'true' + }; + return stringify(Object.assign(parameters, overwritingParams)); +} + +/** + * Returns the preview url parameters. + * + * @param basePath - path to project root, where package.json and ui5.yaml is + * @param query - query to create fragment + * @returns - review url parameters + */ +export async function getPreviewUrl(basePath: string, query: string): Promise { + // checks if a ui5.yaml configuration is deprecated and therefore needs a different hash + const previewHash = (await checkDeprecatedPreviewMiddleware(basePath)) ? 'preview-app' : 'app-preview'; + return `/preview.html?${query}#${previewHash}`; } From d10a3145e96c386bd440c3eac1c53bc92528c7bf Mon Sep 17 00:00:00 2001 From: D048415 Date: Wed, 25 Sep 2024 18:03:07 +0200 Subject: [PATCH 07/37] adjust type in getSapClientFromPackageJson and refactor addVariantsManagementScript --- .../app-config-writer/src/variants-config/package-json.ts | 5 ++--- packages/app-config-writer/src/variants-config/utils.ts | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index 62c9cff362..efc760f47b 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -15,12 +15,11 @@ export async function addVariantsManagementScript(fs: Editor, basePath: string, const packageJsonPath = join(basePath, 'package.json'); const packageJson = fs.readJSON(packageJsonPath) as Package; - const scripts = packageJson.scripts ?? {}; const urlParameters: Record = {}; if (!packageJson.scripts) { logger?.warn(`File 'package.json' does not contain a script section. Script section added.`); - packageJson['scripts'] = scripts; + packageJson.scripts = {}; } else { // check if sap-client is needed when starting the app const sapClient = getSapClientFromPackageJson(packageJson.scripts); @@ -32,7 +31,7 @@ export async function addVariantsManagementScript(fs: Editor, basePath: string, const query = getUi5UrlParameters(urlParameters); const url = await getPreviewUrl(basePath, query); - scripts['start-variants-management'] = `fiori run --open "${url.slice(1)}"`; + packageJson.scripts['start-variants-management'] = `fiori run --open "${url}"`; fs.writeJSON(packageJsonPath, packageJson); logger?.info(`Script 'start-variants-management' written to 'package.json'.`); } diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index 2e1c02ad75..29ec983a71 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -1,4 +1,5 @@ import { FileName, readUi5Yaml } from '@sap-ux/project-access'; +import type { Package } from '@sap-ux/project-access'; import { MiddlewareConfigs } from '../types'; import { stringify } from 'querystring'; import type { CustomMiddleware } from '@sap-ux/ui5-config'; @@ -34,8 +35,8 @@ async function checkDeprecatedPreviewMiddleware(basePath: string): Promise>): string | undefined { - for (const value of Object.values(scripts)) { +export function getSapClientFromPackageJson(scripts: Package['scripts']): string | undefined { + for (const value of Object.values(scripts!)) { const match = value?.match(/sap-client=([0-9]{3})/); if (match) { return match[1]; @@ -69,5 +70,5 @@ export function getUi5UrlParameters(overwritingParams: Record = export async function getPreviewUrl(basePath: string, query: string): Promise { // checks if a ui5.yaml configuration is deprecated and therefore needs a different hash const previewHash = (await checkDeprecatedPreviewMiddleware(basePath)) ? 'preview-app' : 'app-preview'; - return `/preview.html?${query}#${previewHash}`; + return `preview.html?${query}#${previewHash}`; } From 8d43c14a1a0421f12aa1ce41f1016f8af9025aaf Mon Sep 17 00:00:00 2001 From: D048415 Date: Thu, 26 Sep 2024 09:59:28 +0200 Subject: [PATCH 08/37] refactor check for deprecated preview middleware and related types --- .../src/types/variantsConfig.ts | 16 ++++++++-------- .../src/variants-config/utils.ts | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/app-config-writer/src/types/variantsConfig.ts b/packages/app-config-writer/src/types/variantsConfig.ts index ffeb0446f0..c40ca8ff51 100644 --- a/packages/app-config-writer/src/types/variantsConfig.ts +++ b/packages/app-config-writer/src/types/variantsConfig.ts @@ -1,17 +1,17 @@ -import type { MiddlewareConfig } from '@sap-ux/preview-middleware'; -export interface FioriToolsDeprecatedPreviewConfig { +import type { MiddlewareConfig as FioriToolsPreviewConfig } from '@sap-ux/preview-middleware'; + +export type FioriToolsDeprecatedPreviewConfig = { component: string; libs?: boolean; ui5Theme?: string; -} +}; -export type FioriToolsPreviewConfig = MiddlewareConfig; export type FioriPreviewConfigOptions = FioriToolsDeprecatedPreviewConfig | FioriToolsPreviewConfig; export enum MiddlewareConfigs { - 'FioriToolsPreview' = 'fiori-tools-preview', + FioriToolsPreview = 'fiori-tools-preview', // ToDo: check for preview-middleware - 'PreviewMiddleware' = 'preview-middleware', - 'ReloadMiddleware' = 'reload-middleware', - 'FioriToolsAppreload' = 'fiori-tools-appreload' + PreviewMiddleware = 'preview-middleware', + ReloadMiddleware = 'reload-middleware', + FioriToolsAppreload = 'fiori-tools-appreload' } diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index 29ec983a71..f9c50a7c2d 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -24,9 +24,9 @@ async function getFioriToolsPreviewMiddleware( * @param basePath - path to project root, where package.json and ui5.yaml is * @returns true, if a fiori-tools-preview middleware configuration is deprecated */ -async function checkDeprecatedPreviewMiddleware(basePath: string): Promise { +async function isDeprecatedPreviewMiddleware(basePath: string): Promise { const existingPreviewMiddleware = await getFioriToolsPreviewMiddleware(basePath); - return (existingPreviewMiddleware?.configuration as FioriToolsDeprecatedPreviewConfig)?.component !== undefined; + return !!(existingPreviewMiddleware?.configuration as FioriToolsDeprecatedPreviewConfig)?.component; } /** @@ -69,6 +69,6 @@ export function getUi5UrlParameters(overwritingParams: Record = */ export async function getPreviewUrl(basePath: string, query: string): Promise { // checks if a ui5.yaml configuration is deprecated and therefore needs a different hash - const previewHash = (await checkDeprecatedPreviewMiddleware(basePath)) ? 'preview-app' : 'app-preview'; + const previewHash = (await isDeprecatedPreviewMiddleware(basePath)) ? 'preview-app' : 'app-preview'; return `preview.html?${query}#${previewHash}`; } From 0319d6ea8f787974c9d7679b458ef61345668580 Mon Sep 17 00:00:00 2001 From: D048415 Date: Thu, 26 Sep 2024 14:31:56 +0200 Subject: [PATCH 09/37] fix typo --- packages/create/src/cli/add/cards-editor.ts | 2 +- packages/create/src/cli/add/cds-plugin-ui.ts | 2 +- packages/create/src/cli/add/html.ts | 2 +- packages/create/src/cli/add/mockserver-config.ts | 2 +- packages/create/src/cli/add/navigation-config.ts | 2 +- packages/create/src/cli/add/smartlinks-config.ts | 2 +- packages/create/src/cli/add/variants-config.ts | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/create/src/cli/add/cards-editor.ts b/packages/create/src/cli/add/cards-editor.ts index 50977adc40..84db9e1cc8 100644 --- a/packages/create/src/cli/add/cards-editor.ts +++ b/packages/create/src/cli/add/cards-editor.ts @@ -26,7 +26,7 @@ export function addCardsEditorConfigCommand(cmd: Command): void { * Adds an cards editor config to an app. To prevent overwriting existing inbounds will be checked. * * @param basePath - path to application root - * @param simulate - if true, do not write but just show what would be change; otherwise write + * @param simulate - if true, do not write but just show what would be changed; otherwise write * @param skipInstall - if true, do not run npm install */ async function addCardsEditorConfig(basePath: string, simulate: boolean, skipInstall: boolean): Promise { diff --git a/packages/create/src/cli/add/cds-plugin-ui.ts b/packages/create/src/cli/add/cds-plugin-ui.ts index a2703c9ca5..0fd96659e5 100644 --- a/packages/create/src/cli/add/cds-plugin-ui.ts +++ b/packages/create/src/cli/add/cds-plugin-ui.ts @@ -26,7 +26,7 @@ export function addAddCdsPluginUi5Command(cmd: Command): void { * Add cds-plugin-ui5 and all prerequisites to a CAP project. * * @param basePath - CAP project root - * @param simulate - if true, do not write but just show what would be change; otherwise write + * @param simulate - if true, do not write but just show what would be changed; otherwise write * @param skipInstall - if true, skip execution of npm install */ async function addCdsPluginUi5(basePath: string, simulate: boolean, skipInstall: boolean): Promise { diff --git a/packages/create/src/cli/add/html.ts b/packages/create/src/cli/add/html.ts index 29d620c1e6..e04a6d336c 100644 --- a/packages/create/src/cli/add/html.ts +++ b/packages/create/src/cli/add/html.ts @@ -30,7 +30,7 @@ export function addAddHtmlFilesCmd(cmd: Command): void { * Adds the virtual html files hosted by the preview middleware to the file system. * * @param basePath - path to application root - * @param simulate - if true, do not write but just show what would be change; otherwise write + * @param simulate - if true, do not write but just show what would be changed; otherwise write * @param yamlPath - path to the ui5*.yaml file */ async function addHtmlFiles(basePath: string, simulate: boolean, yamlPath: string): Promise { diff --git a/packages/create/src/cli/add/mockserver-config.ts b/packages/create/src/cli/add/mockserver-config.ts index 3d640ec7e4..0dcb0cf0c5 100644 --- a/packages/create/src/cli/add/mockserver-config.ts +++ b/packages/create/src/cli/add/mockserver-config.ts @@ -36,7 +36,7 @@ export function addAddMockserverConfigCommand(cmd: Command): void { * Adds a mockserver config to an app or project. * * @param basePath - path to application root - * @param simulate - if true, do not write but just show what would be change; otherwise write + * @param simulate - if true, do not write but just show what would be changed; otherwise write * @param skipInstall - if true, skip execution of npm install * @param interactive - if true, prompt user for config options, otherwise use defaults */ diff --git a/packages/create/src/cli/add/navigation-config.ts b/packages/create/src/cli/add/navigation-config.ts index afeab43720..85e369297c 100644 --- a/packages/create/src/cli/add/navigation-config.ts +++ b/packages/create/src/cli/add/navigation-config.ts @@ -24,7 +24,7 @@ export function addInboundNavigationConfigCommand(cmd: Command): void { * Adds an inbound navigation config to an app. To prevent overwriting existing inbounds will be checked. * * @param basePath - path to application root - * @param simulate - if true, do not write but just show what would be change; otherwise write + * @param simulate - if true, do not write but just show what would be changed; otherwise write */ async function addInboundNavigationConfig(basePath: string, simulate: boolean): Promise { const logger = getLogger(); diff --git a/packages/create/src/cli/add/smartlinks-config.ts b/packages/create/src/cli/add/smartlinks-config.ts index 68a365017f..16a5e88e18 100644 --- a/packages/create/src/cli/add/smartlinks-config.ts +++ b/packages/create/src/cli/add/smartlinks-config.ts @@ -24,7 +24,7 @@ export function addAddSmartLinksConfigCommand(cmd: Command): void { * Adds a smartLinks config to an app or project. * * @param basePath - path to application root - * @param simulate - if true, do not write but just show what would be change; otherwise write + * @param simulate - if true, do not write but just show what would be changed; otherwise write */ async function addSmartLinksConfig(basePath: string, simulate: boolean): Promise { const logger = getLogger(); diff --git a/packages/create/src/cli/add/variants-config.ts b/packages/create/src/cli/add/variants-config.ts index b29da78584..03d9ae9c09 100644 --- a/packages/create/src/cli/add/variants-config.ts +++ b/packages/create/src/cli/add/variants-config.ts @@ -24,7 +24,7 @@ export function addAddVariantsConfigCommand(cmd: Command): void { * Adds a variants config to an app or project. * * @param basePath - the base path where the package.json and ui5.yaml is - * @param simulate - if true, do not write but just show what would be change; otherwise write + * @param simulate - if true, do not write but just show what would be changed; otherwise write */ async function addVariantsConfig(basePath: string, simulate: boolean): Promise { const logger = getLogger(); From 9a1074d514a5532ce930dded45065c186993a6bd Mon Sep 17 00:00:00 2001 From: D048415 Date: Thu, 26 Sep 2024 14:37:43 +0200 Subject: [PATCH 10/37] adjust log level --- packages/app-config-writer/src/variants-config/package-json.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index efc760f47b..9d1684ee81 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -33,5 +33,5 @@ export async function addVariantsManagementScript(fs: Editor, basePath: string, packageJson.scripts['start-variants-management'] = `fiori run --open "${url}"`; fs.writeJSON(packageJsonPath, packageJson); - logger?.info(`Script 'start-variants-management' written to 'package.json'.`); + logger?.debug(`Script 'start-variants-management' written to 'package.json'.`); } From e923cc4251aa9e09cc1383501d299b366655b8ff Mon Sep 17 00:00:00 2001 From: Annemarie Date: Fri, 27 Sep 2024 17:57:54 +0200 Subject: [PATCH 11/37] feat: add varinats config --- .../src/types/variantsConfig.ts | 1 - .../variants-config/generateVariantsConfig.ts | 4 +- .../src/variants-config/package-json.ts | 34 ++++--- .../src/variants-config/ui5-yaml.ts | 93 +++++++++++++------ .../src/variants-config/utils.ts | 7 +- 5 files changed, 92 insertions(+), 47 deletions(-) diff --git a/packages/app-config-writer/src/types/variantsConfig.ts b/packages/app-config-writer/src/types/variantsConfig.ts index c40ca8ff51..e4023ba7dc 100644 --- a/packages/app-config-writer/src/types/variantsConfig.ts +++ b/packages/app-config-writer/src/types/variantsConfig.ts @@ -10,7 +10,6 @@ export type FioriPreviewConfigOptions = FioriToolsDeprecatedPreviewConfig | Fior export enum MiddlewareConfigs { FioriToolsPreview = 'fiori-tools-preview', - // ToDo: check for preview-middleware PreviewMiddleware = 'preview-middleware', ReloadMiddleware = 'reload-middleware', FioriToolsAppreload = 'fiori-tools-appreload' diff --git a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts index 4ee5c12f70..6edbf960ba 100644 --- a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts +++ b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts @@ -1,6 +1,6 @@ import { create } from 'mem-fs-editor'; import { create as createStorage } from 'mem-fs'; -import { updateFioriToolsPreviewMiddleware } from './ui5-yaml'; +import { updateMiddlewares } from './ui5-yaml'; import { addVariantsManagementScript } from './package-json'; import type { Editor } from 'mem-fs-editor'; import type { ToolsLogger } from '@sap-ux/logger'; @@ -18,6 +18,6 @@ export async function generateVariantsConfig(basePath: string, logger?: ToolsLog fs = create(createStorage()); } await addVariantsManagementScript(fs, basePath, logger); - await updateFioriToolsPreviewMiddleware(fs, basePath, logger); + await updateMiddlewares(fs, basePath, logger); return fs; } diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index 9d1684ee81..9be298c1e6 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -15,23 +15,27 @@ export async function addVariantsManagementScript(fs: Editor, basePath: string, const packageJsonPath = join(basePath, 'package.json'); const packageJson = fs.readJSON(packageJsonPath) as Package; - const urlParameters: Record = {}; + if (!packageJson.scripts || !packageJson.scripts['start-variants-management']) { + const urlParameters: Record = {}; - if (!packageJson.scripts) { - logger?.warn(`File 'package.json' does not contain a script section. Script section added.`); - packageJson.scripts = {}; - } else { - // check if sap-client is needed when starting the app - const sapClient = getSapClientFromPackageJson(packageJson.scripts); - if (sapClient) { - urlParameters['sap-client'] = sapClient; + if (!packageJson.scripts) { + logger?.warn(`File 'package.json' does not contain a script section. Script section added.`); + packageJson.scripts = {}; + } else { + // check if sap-client is needed when starting the app + const sapClient = getSapClientFromPackageJson(packageJson.scripts); + if (sapClient) { + urlParameters['sap-client'] = sapClient; + } } - } - const query = getUi5UrlParameters(urlParameters); - const url = await getPreviewUrl(basePath, query); + const query = getUi5UrlParameters(urlParameters); + const url = await getPreviewUrl(basePath, query); + packageJson.scripts['start-variants-management'] = `fiori run --open "${url}"`; - packageJson.scripts['start-variants-management'] = `fiori run --open "${url}"`; - fs.writeJSON(packageJsonPath, packageJson); - logger?.debug(`Script 'start-variants-management' written to 'package.json'.`); + fs.writeJSON(packageJsonPath, packageJson); + logger?.debug(`Script 'start-variants-management' written to 'package.json'.`); + } else { + logger?.warn(`Script 'start-variants-management' cannot be written to 'package.json. Script already exists'.`); + } } diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index 6efa66920d..c7e2067ce2 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -9,50 +9,86 @@ import type { FioriAppReloadConfig } from '@sap-ux/ui5-config'; import type { FioriPreviewConfigOptions } from '../types'; /** - * Gets the fiori-tools-preview middleware configuration. + * Writes the given middleware to a ui5.yaml file. + * + * @param fs - mem-fs reference to be used for file access + * @param path - path to the ui5.yaml file + * @param content - middleware configuration to be written + * @param ui5YamlConfig - existing ui5.yaml configuration + */ +export function writeMiddlewareToYaml( + fs: Editor, + path: string, + content: CustomMiddleware, + ui5YamlConfig: UI5Config +): void { + const middlewareConfig = ui5YamlConfig.updateCustomMiddleware(content); + fs.write(path, middlewareConfig.toString()); +} + +/** + * Gets the preview middleware configuration. + * The middleware can either be named fiori-tools-preview or preview-middleware. + * If no preview configuration is given, then one will be created. * * @param ui5YamlConfig existing ui5.yaml configurations - * @returns 'fiori-tools-preview' configuration + * @returns 'fiori-tools-preview' or 'preview-middleware' configuration */ -function getFioriToolsPreviewConfig(ui5YamlConfig: UI5Config): CustomMiddleware { +function getPreviewMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware { const previewMiddlewareTemplate = { + // ToDo: How to know the default if there is no preview middleware... name: 'fiori-tools-preview', afterMiddleware: 'compression' } as CustomMiddleware; - const existingPreviewMiddleware = ui5YamlConfig.findCustomMiddleware( - MiddlewareConfigs.FioriToolsPreview - ); - const existingReloadMiddleware = ui5YamlConfig.findCustomMiddleware( - MiddlewareConfigs.FioriToolsAppreload - ); - - if (existingPreviewMiddleware?.configuration) { - previewMiddlewareTemplate.configuration = { ...existingPreviewMiddleware.configuration }; - } + const existingPreviewMiddleware = + ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? + ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.PreviewMiddleware); - if (existingReloadMiddleware) { - previewMiddlewareTemplate.afterMiddleware = MiddlewareConfigs.FioriToolsAppreload; + if (existingPreviewMiddleware) { + previewMiddlewareTemplate.name = existingPreviewMiddleware.name; + if (existingPreviewMiddleware.configuration) { + previewMiddlewareTemplate.configuration = { ...existingPreviewMiddleware.configuration }; + } } return previewMiddlewareTemplate; } /** - * Checks the project for ui5.yaml files and updates the fiori-tools-preview middleware. + * Gets the reload middleware configuration and sets a delay of 300ms if not given. + * The middleware can either be named fiori-tools-appreload or reload-middleware. + * + * @param ui5YamlConfig existing ui5.yaml configurations + * @returns 'fiori-tools-appreload' or reload-middleware configuration + */ +function getReloadMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware | undefined { + const existingReloadMiddleware = + ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsAppreload) ?? + ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.ReloadMiddleware); + + if (!existingReloadMiddleware) { + return undefined; + } + if (!existingReloadMiddleware?.configuration?.delay) { + existingReloadMiddleware.configuration = { ...existingReloadMiddleware.configuration, delay: 300 }; + } + return existingReloadMiddleware; +} + +/** + * Checks the project for ui5.yaml files and reads out the configuration to update the preview and reload middlewares. + * If a reload middleware exists, then a delay of 300ms will be insterted and the preview middleware will be set afterwards. * * @param fs - mem-fs reference to be used for file access * @param basePath - path to project root, where package.json and ui5.yaml is * @param logger - logger */ -export async function updateFioriToolsPreviewMiddleware( - fs: Editor, - basePath: string, - logger?: ToolsLogger -): Promise { +export async function updateMiddlewares(fs: Editor, basePath: string, logger?: ToolsLogger): Promise { const ui5Yamls = [FileName.Ui5Yaml, FileName.Ui5MockYaml, FileName.Ui5LocalYaml]; for (const ui5Yaml of ui5Yamls) { let existingUi5YamlConfig: UI5Config; + const yamlPath = join(basePath, ui5Yaml); try { existingUi5YamlConfig = await readUi5Yaml(basePath, ui5Yaml); } catch (error) { @@ -60,13 +96,16 @@ export async function updateFioriToolsPreviewMiddleware( continue; } - const previewMiddlewareConfig = existingUi5YamlConfig.updateCustomMiddleware( - getFioriToolsPreviewConfig(existingUi5YamlConfig) - ); + const previewMiddlewareConfig = getPreviewMiddlewareConfig(existingUi5YamlConfig); + const reloadMiddlewareConfig = getReloadMiddlewareConfig(existingUi5YamlConfig); - if (previewMiddlewareConfig) { - fs.write(join(basePath, ui5Yaml), previewMiddlewareConfig.toString()); - logger?.debug(`Updated preview middleware in ${ui5Yaml}.`); + if (reloadMiddlewareConfig) { + previewMiddlewareConfig.afterMiddleware = reloadMiddlewareConfig.name; + writeMiddlewareToYaml(fs, yamlPath, reloadMiddlewareConfig, existingUi5YamlConfig); + logger?.debug(`Updated reload middleware in ${ui5Yaml}.`); } + + writeMiddlewareToYaml(fs, yamlPath, previewMiddlewareConfig, existingUi5YamlConfig); + logger?.debug(`Updated preview middleware in ${ui5Yaml}.`); } } diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index f9c50a7c2d..ad633d5d74 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -1,7 +1,7 @@ import { FileName, readUi5Yaml } from '@sap-ux/project-access'; -import type { Package } from '@sap-ux/project-access'; import { MiddlewareConfigs } from '../types'; import { stringify } from 'querystring'; +import type { Package } from '@sap-ux/project-access'; import type { CustomMiddleware } from '@sap-ux/ui5-config'; import type { FioriPreviewConfigOptions, FioriToolsDeprecatedPreviewConfig } from '../types'; @@ -15,7 +15,10 @@ async function getFioriToolsPreviewMiddleware( basePath: string ): Promise | undefined> { const existingUi5YamlConfig = await readUi5Yaml(basePath, FileName.Ui5Yaml); - return existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview); + return ( + existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? + existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.PreviewMiddleware) + ); } /** From f2abaf574a974539be178327772c9242831f73fe Mon Sep 17 00:00:00 2001 From: D048415 Date: Sun, 29 Sep 2024 18:11:27 +0200 Subject: [PATCH 12/37] add type guard --- .../src/variants-config/utils.ts | 24 ++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index f9c50a7c2d..0dc1293a43 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -19,14 +19,15 @@ async function getFioriToolsPreviewMiddleware( } /** - * Gets the fiori-tools-preview middleware configuration and checks if it's deprecated. + * Type guard to check if the given configuration is a deprecated preview middleware configuration. * - * @param basePath - path to project root, where package.json and ui5.yaml is - * @returns true, if a fiori-tools-preview middleware configuration is deprecated + * @param configuration preview middleware configuration + * @returns true, if a preview middleware configuration is deprecated */ -async function isDeprecatedPreviewMiddleware(basePath: string): Promise { - const existingPreviewMiddleware = await getFioriToolsPreviewMiddleware(basePath); - return !!(existingPreviewMiddleware?.configuration as FioriToolsDeprecatedPreviewConfig)?.component; +function isFioriToolsDeprecatedPreviewConfig( + configuration: FioriPreviewConfigOptions | undefined +): configuration is FioriToolsDeprecatedPreviewConfig { + return (configuration as FioriToolsDeprecatedPreviewConfig)?.component !== undefined; } /** @@ -61,14 +62,15 @@ export function getUi5UrlParameters(overwritingParams: Record = } /** - * Returns the preview url parameters. + * Returns the preview url. * - * @param basePath - path to project root, where package.json and ui5.yaml is + * @param basePath - path to project root, where package.json and ui5.yaml is located * @param query - query to create fragment * @returns - review url parameters */ export async function getPreviewUrl(basePath: string, query: string): Promise { - // checks if a ui5.yaml configuration is deprecated and therefore needs a different hash - const previewHash = (await isDeprecatedPreviewMiddleware(basePath)) ? 'preview-app' : 'app-preview'; - return `preview.html?${query}#${previewHash}`; + const existingPreviewMiddleware = await getFioriToolsPreviewMiddleware(basePath); + return isFioriToolsDeprecatedPreviewConfig(existingPreviewMiddleware?.configuration) + ? `preview.html?${query}#preview-app` + : `preview.html?${query}#app-preview`; } From 685c0c761a6cf5e3b10cae64a26c3d9ba37396f4 Mon Sep 17 00:00:00 2001 From: Annemarie Date: Mon, 30 Sep 2024 18:25:34 +0200 Subject: [PATCH 13/37] test: utils and package.json --- .../deprecated-config/package.json | 16 +++++++ .../deprecated-config/ui5.yaml | 12 +++++ .../fixtures/variants-config/package.json | 28 +++++++++++ .../fixtures/variants-config/ui5-local.yaml | 19 ++++++++ .../fixtures/variants-config/ui5-mock.yaml | 21 +++++++++ .../test/fixtures/variants-config/ui5.yaml | 26 ++++++++++ .../unit/variants-config/package-json.test.ts | 28 +++++++++++ .../test/unit/variants-config/utils.test.ts | 47 +++++++++++++++++++ 8 files changed, 197 insertions(+) create mode 100644 packages/app-config-writer/test/fixtures/variants-config/deprecated-config/package.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/deprecated-config/ui5.yaml create mode 100644 packages/app-config-writer/test/fixtures/variants-config/package.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/ui5-local.yaml create mode 100644 packages/app-config-writer/test/fixtures/variants-config/ui5-mock.yaml create mode 100644 packages/app-config-writer/test/fixtures/variants-config/ui5.yaml create mode 100644 packages/app-config-writer/test/unit/variants-config/package-json.test.ts create mode 100644 packages/app-config-writer/test/unit/variants-config/utils.test.ts diff --git a/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/package.json b/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/package.json new file mode 100644 index 0000000000..9412d31bfd --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/package.json @@ -0,0 +1,16 @@ +{ + "name": "v2-lrop-0909", + "version": "0.0.1", + "description": "An SAP Fiori application.", + "keywords": [ + "ui5", + "openui5", + "sapui5" + ], + "main": "webapp/index.html", + "scripts": { + "start-variants-management": "fiori run --open \"preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true&sap-client=500#app-preview\"" + }, + "sapux": true, + "sapuxLayer": "VENDOR" +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/ui5.yaml new file mode 100644 index 0000000000..da529ad43a --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/ui5.yaml @@ -0,0 +1,12 @@ +specVersion: "3.1" +metadata: + name: v2lrop0909 +type: application +server: + customMiddleware: + - name: fiori-tools-preview + afterMiddleware: compression + configuration: + component: v2lrop0909 + ui5Theme: sap_horizon +# Test variants-config with no fiori-tools-preview middleware config and missing delay for fiori-tools-appreload \ No newline at end of file diff --git a/packages/app-config-writer/test/fixtures/variants-config/package.json b/packages/app-config-writer/test/fixtures/variants-config/package.json new file mode 100644 index 0000000000..e004106b1f --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/package.json @@ -0,0 +1,28 @@ +{ + "name": "v2-lrop-0909", + "version": "0.0.1", + "description": "An SAP Fiori application.", + "keywords": [ + "ui5", + "openui5", + "sapui5" + ], + "main": "webapp/index.html", + "devDependencies": { + "@sap-ux/ui5-middleware-fe-mockserver": "2", + "@sap/ux-specification": "^1.124.1", + "@sap/ux-ui5-tooling": "^1.15.0", + "@ui5/cli": "^3.0.0" + }, + "scripts": { + "start": "fiori run --open \"test/flpSandbox.html?sap-client=500&sap-ui-xx-viewCache=false#v2lrop0909-tile\"", + "start-local": "fiori run --config ./ui5-local.yaml --open \"test/flpSandbox.html?sap-ui-xx-viewCache=false#v2lrop0909-tile\"", + "build": "ui5 build --config=ui5.yaml --clean-dest --dest dist", + "start-mock": "fiori run --config ./ui5-mock.yaml --open \"test/flpSandbox.html?sap-ui-xx-viewCache=false#v2lrop0909-tile\"", + "deploy": "fiori verify", + "deploy-config": "fiori add deploy-config", + "start-noflp": "fiori run --open \"index.html?sap-ui-xx-viewCache=false\"" + }, + "sapux": true, + "sapuxLayer": "VENDOR" +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/ui5-local.yaml b/packages/app-config-writer/test/fixtures/variants-config/ui5-local.yaml new file mode 100644 index 0000000000..6fcfebc944 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/ui5-local.yaml @@ -0,0 +1,19 @@ +specVersion: "3.1" +metadata: + name: v2lrop0909 +type: application +server: + customMiddleware: + - name: fiori-tools-proxy + afterMiddleware: compression + configuration: + ignoreCertError: false + backend: + - path: /sap + url: https://sap-ux-mock-services-v2-lrop.cfapps.us10.hana.ondemand.com + - name: fiori-tools-preview + afterMiddleware: fiori-tools-appreload + configuration: + component: v2lrop0909 + ui5Theme: sap_horizon +# Test variants-config with a deprecated fiori-tools-preview middleware config and no fiori-tools-appreload diff --git a/packages/app-config-writer/test/fixtures/variants-config/ui5-mock.yaml b/packages/app-config-writer/test/fixtures/variants-config/ui5-mock.yaml new file mode 100644 index 0000000000..4d823d6a68 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/ui5-mock.yaml @@ -0,0 +1,21 @@ +specVersion: "3.1" +metadata: + name: v2lrop0909 +type: application +server: + customMiddleware: + - name: fiori-tools-proxy + afterMiddleware: compression + configuration: + ignoreCertError: false + ui5: + path: + - /resources + - /test-resources + url: https://ui5.sap.com + backend: + - path: /sap + url: https://sap-ux-mock-services-v2-lrop.cfapps.us10.hana.ondemand.com + - name: fiori-tools-appreload + afterMiddleware: compression +# Test variants-config with no fiori-tools-preview middleware given and no config for fiori-tools-appreload \ No newline at end of file diff --git a/packages/app-config-writer/test/fixtures/variants-config/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/ui5.yaml new file mode 100644 index 0000000000..d54c072b62 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/ui5.yaml @@ -0,0 +1,26 @@ +specVersion: "3.1" +metadata: + name: v2lrop0909 +type: application +server: + customMiddleware: + - name: fiori-tools-proxy + afterMiddleware: compression + configuration: + ignoreCertError: false + ui5: + path: + - /resources + - /test-resources + url: https://ui5.sap.com + backend: + - path: /sap + url: https://sap-ux-mock-services-v2-lrop.cfapps.us10.hana.ondemand.com + - name: fiori-tools-appreload + afterMiddleware: compression + configuration: + port: 35729 + path: webapp + - name: fiori-tools-preview + afterMiddleware: compression +# Test variants-config with no fiori-tools-preview middleware config and missing delay for fiori-tools-appreload \ No newline at end of file diff --git a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts new file mode 100644 index 0000000000..57d4e92840 --- /dev/null +++ b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts @@ -0,0 +1,28 @@ +import { addVariantsManagementScript } from '../../../src/variants-config/package-json'; +import { create as createStorage } from 'mem-fs'; +import { create } from 'mem-fs-editor'; +import * as projectAccessMock from '@sap-ux/project-access'; +import type { Editor } from 'mem-fs-editor'; +import type { ToolsLogger } from '@sap-ux/logger'; + +import { join } from 'path'; + +describe('addVariantsManagementScript', () => { + const basePath = join(__dirname, '../../fixtures/variants-config'); + const legacyBasePath = join(__dirname, '../../fixtures/variants-config/deprecated-config'); + + const loggerMock: ToolsLogger = { debug: jest.fn() } as Partial as ToolsLogger; + let fs: Editor; + let debugMock: jest.SpyInstance; + + beforeEach(() => { + jest.clearAllMocks(); + fs = create(createStorage()); + debugMock = loggerMock.debug as any; + }); + + test('add variants-management script to package.json', async () => { + await addVariantsManagementScript(fs, basePath, loggerMock); + expect(debugMock.mock.calls[0][0]).toEqual(`Script 'start-variants-management' written to 'package.json'.`); + }); +}); diff --git a/packages/app-config-writer/test/unit/variants-config/utils.test.ts b/packages/app-config-writer/test/unit/variants-config/utils.test.ts new file mode 100644 index 0000000000..cdaa9960ea --- /dev/null +++ b/packages/app-config-writer/test/unit/variants-config/utils.test.ts @@ -0,0 +1,47 @@ +import { join } from 'path'; +import * as utils from '../../../src/variants-config/utils'; + +describe('utils', () => { + describe('getSapClientFromPackageJson', () => { + test('scripts with no sap client', () => { + expect(utils.getSapClientFromPackageJson({ start: 'fiori run --open preview.html' })).toStrictEqual( + undefined + ); + }); + + test('scripts with sap client', () => { + expect( + utils.getSapClientFromPackageJson({ start: 'fiori run --open preview.html?sap-client=000' }) + ).toStrictEqual('000'); + }); + }); + describe('getUi5UrlParameters', () => { + test('defaults', () => { + expect(utils.getUi5UrlParameters()).toStrictEqual( + 'fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true' + ); + }); + + test('parameters overwrite with sap-client', () => { + expect(utils.getUi5UrlParameters({ 'sap-client': '500' })).toStrictEqual( + 'fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true&sap-client=500' + ); + }); + }); + describe('getPreviewUrl', () => { + const query = 'fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true'; + const path = join(__dirname, '../../fixtures/variants-config'); + + test('defaults', async () => { + expect(await utils.getPreviewUrl(path, query)).toStrictEqual( + 'preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true#app-preview' + ); + }); + + test('deprecated config', async () => { + expect(await utils.getPreviewUrl(join(path, 'deprecated-config'), query)).toStrictEqual( + 'preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true#preview-app' + ); + }); + }); +}); From bdcb731d49df0ae0e4d93314a0c46035b72a09a0 Mon Sep 17 00:00:00 2001 From: Md Imam Hasan Date: Tue, 1 Oct 2024 12:21:51 +0200 Subject: [PATCH 14/37] test: unit test for create command package.json and .yaml files --- .../app-with-client-in-script/package.json | 6 ++ .../app-with-client-in-script/ui5.yaml | 17 ++++ .../webapp/manifest.json | 6 ++ .../app-with-reload-middleware/package.json | 3 + .../app-with-reload-middleware/ui5-mock.yaml | 10 +++ .../app-with-reload-middleware/ui5.yaml | 26 ++++++ .../webapp/manifest.json | 6 ++ .../variants-config/simple-app/package.json | 3 + .../variants-config/simple-app/ui5.yaml | 26 ++++++ .../simple-app/webapp/manifest.json | 6 ++ .../__snapshots__/index.test.ts.snap | 33 +++++++ .../__snapshots__/ui5-yaml.test.ts.snap | 70 +++++++++++++++ .../test/unit/variants-config/index.test.ts | 17 ++++ .../unit/variants-config/package-json.test.ts | 62 ++++++++++++- .../unit/variants-config/ui5-yaml.test.ts | 46 ++++++++++ .../test/unit/cli/add/variants-config.test.ts | 86 +++++++++++++++++++ 16 files changed, 419 insertions(+), 4 deletions(-) create mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/package.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/ui5.yaml create mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/webapp/manifest.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/package.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5-mock.yaml create mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5.yaml create mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/webapp/manifest.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/simple-app/package.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/simple-app/ui5.yaml create mode 100644 packages/app-config-writer/test/fixtures/variants-config/simple-app/webapp/manifest.json create mode 100644 packages/app-config-writer/test/unit/variants-config/__snapshots__/index.test.ts.snap create mode 100644 packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap create mode 100644 packages/app-config-writer/test/unit/variants-config/index.test.ts create mode 100644 packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts create mode 100644 packages/create/test/unit/cli/add/variants-config.test.ts diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/package.json b/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/package.json new file mode 100644 index 0000000000..aea2e1ac25 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/package.json @@ -0,0 +1,6 @@ +{ + "name": "app-client", + "scripts": { + "start": "fiori run --open \"test/flpSandbox.html?sap-client=100&sap-ui-xx-viewCache=false#test-tile\"" + } +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/ui5.yaml new file mode 100644 index 0000000000..438ac71211 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/ui5.yaml @@ -0,0 +1,17 @@ +specVersion: '2.4' +metadata: + name: 'app-client' +type: application +server: + customMiddleware: + - name: fiori-tools-servestatic + beforeMiddleware: fiori-tools-proxy + configuration: + paths: + - path: /appconfig + src: appconfig + fallthrough: false + - name: fiori-tools-preview + afterMiddleware: compression + configuration: + ui5Theme: sap_horizon \ No newline at end of file diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/webapp/manifest.json b/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/webapp/manifest.json new file mode 100644 index 0000000000..3fdb8bb13f --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/webapp/manifest.json @@ -0,0 +1,6 @@ +{ + "sap.app": { + "id": "app-client", + "type": "application" + } +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/package.json b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/package.json new file mode 100644 index 0000000000..0f0da8cc30 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/package.json @@ -0,0 +1,3 @@ +{ + "name": "app-with-reload-middleware" +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5-mock.yaml b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5-mock.yaml new file mode 100644 index 0000000000..488d8eacf2 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5-mock.yaml @@ -0,0 +1,10 @@ +specVersion: "2.4" +metadata: + name: app-with-reload-middleware +type: application +server: + customMiddleware: + - name: fiori-tools-appreload + afterMiddleware: fiori-tools-appreload + - name: fiori-tools-preview + afterMiddleware: compression diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5.yaml new file mode 100644 index 0000000000..6246c24b20 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5.yaml @@ -0,0 +1,26 @@ +specVersion: '2.4' +metadata: + name: 'app-with-reload-middleware' +type: application +server: + customMiddleware: + - name: fiori-tools-proxy + afterMiddleware: compression + configuration: + ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted + backend: + - path: /sap + url: https://abc.ondemand.example + ui5: + path: + - /resources + - /test-resources + url: https://ui5.sap.com.example + version: 1.91.0 # The UI5 version, for instance, 1.78.1. Empty means latest version + - name: fiori-tools-servestatic + beforeMiddleware: fiori-tools-proxy + configuration: + paths: + - path: /appconfig + src: appconfig + fallthrough: false diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/webapp/manifest.json b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/webapp/manifest.json new file mode 100644 index 0000000000..e7d3e07a0a --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/webapp/manifest.json @@ -0,0 +1,6 @@ +{ + "sap.app": { + "id": "app-with-reload-middleware", + "type": "application" + } +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/simple-app/package.json b/packages/app-config-writer/test/fixtures/variants-config/simple-app/package.json new file mode 100644 index 0000000000..03cbc8457d --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/simple-app/package.json @@ -0,0 +1,3 @@ +{ + "name": "simple-app" +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/simple-app/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/simple-app/ui5.yaml new file mode 100644 index 0000000000..6f126496ed --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/simple-app/ui5.yaml @@ -0,0 +1,26 @@ +specVersion: '2.4' +metadata: + name: 'simple-app' +type: application +server: + customMiddleware: + - name: fiori-tools-proxy + afterMiddleware: compression + configuration: + ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted + backend: + - path: /sap + url: https://abc.ondemand.example + ui5: + path: + - /resources + - /test-resources + url: https://ui5.sap.com.example + version: 1.91.0 # The UI5 version, for instance, 1.78.1. Empty means latest version + - name: fiori-tools-servestatic + beforeMiddleware: fiori-tools-proxy + configuration: + paths: + - path: /appconfig + src: appconfig + fallthrough: false diff --git a/packages/app-config-writer/test/fixtures/variants-config/simple-app/webapp/manifest.json b/packages/app-config-writer/test/fixtures/variants-config/simple-app/webapp/manifest.json new file mode 100644 index 0000000000..39b8e03593 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/simple-app/webapp/manifest.json @@ -0,0 +1,6 @@ +{ + "sap.app": { + "id": "simple-app", + "type": "application" + } +} diff --git a/packages/app-config-writer/test/unit/variants-config/__snapshots__/index.test.ts.snap b/packages/app-config-writer/test/unit/variants-config/__snapshots__/index.test.ts.snap new file mode 100644 index 0000000000..be293fb8dd --- /dev/null +++ b/packages/app-config-writer/test/unit/variants-config/__snapshots__/index.test.ts.snap @@ -0,0 +1,33 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Test generateVariantsConfig() Add config to the project 1`] = ` +"specVersion: '2.4' +metadata: + name: 'simple-app' +type: application +server: + customMiddleware: + - name: fiori-tools-proxy + afterMiddleware: compression + configuration: + ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted + backend: + - path: /sap + url: https://abc.ondemand.example + ui5: + path: + - /resources + - /test-resources + url: https://ui5.sap.com.example + version: 1.91.0 # The UI5 version, for instance, 1.78.1. Empty means latest version + - name: fiori-tools-servestatic + beforeMiddleware: fiori-tools-proxy + configuration: + paths: + - path: /appconfig + src: appconfig + fallthrough: false + - name: fiori-tools-preview + afterMiddleware: compression +" +`; diff --git a/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap b/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap new file mode 100644 index 0000000000..be02767358 --- /dev/null +++ b/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap @@ -0,0 +1,70 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Test update middleware ui5.yaml - add fiori-tools-preview 1`] = ` +"specVersion: '2.4' +metadata: + name: 'simple-app' +type: application +server: + customMiddleware: + - name: fiori-tools-proxy + afterMiddleware: compression + configuration: + ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted + backend: + - path: /sap + url: https://abc.ondemand.example + ui5: + path: + - /resources + - /test-resources + url: https://ui5.sap.com.example + version: 1.91.0 # The UI5 version, for instance, 1.78.1. Empty means latest version + - name: fiori-tools-servestatic + beforeMiddleware: fiori-tools-proxy + configuration: + paths: + - path: /appconfig + src: appconfig + fallthrough: false + - name: fiori-tools-preview + afterMiddleware: compression +" +`; + +exports[`Test update middleware ui5.yaml - do nothing when fiori-tools-preview is present 1`] = ` +"specVersion: '2.4' +metadata: + name: 'app-client' +type: application +server: + customMiddleware: + - name: fiori-tools-servestatic + beforeMiddleware: fiori-tools-proxy + configuration: + paths: + - path: /appconfig + src: appconfig + fallthrough: false + - name: fiori-tools-preview + afterMiddleware: compression + configuration: + ui5Theme: sap_horizon +" +`; + +exports[`Test update middleware ui5-mock.yaml - add fiori-tools-appreload 1`] = ` +"specVersion: \\"2.4\\" +metadata: + name: app-with-reload-middleware +type: application +server: + customMiddleware: + - name: fiori-tools-appreload + afterMiddleware: fiori-tools-appreload + configuration: + delay: 300 + - name: fiori-tools-preview + afterMiddleware: fiori-tools-appreload +" +`; diff --git a/packages/app-config-writer/test/unit/variants-config/index.test.ts b/packages/app-config-writer/test/unit/variants-config/index.test.ts new file mode 100644 index 0000000000..2e067a5875 --- /dev/null +++ b/packages/app-config-writer/test/unit/variants-config/index.test.ts @@ -0,0 +1,17 @@ +import { join } from 'path'; +import { generateVariantsConfig } from '../../../src'; + +describe('Test generateVariantsConfig()', () => { + test('Add config to the project', async () => { + const basePath = join(__dirname, '../../fixtures/variants-config/simple-app'); + const fs = await generateVariantsConfig(basePath); + + expect(fs.readJSON(join(basePath, 'package.json'))).toEqual({ + 'name': 'simple-app', + 'scripts': { + 'start-variants-management': `fiori run --open \"preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true#app-preview\"` + } + }); + expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); + }); +}); diff --git a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts index 57d4e92840..3251b89430 100644 --- a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts @@ -1,11 +1,65 @@ -import { addVariantsManagementScript } from '../../../src/variants-config/package-json'; +import { join } from 'path'; import { create as createStorage } from 'mem-fs'; -import { create } from 'mem-fs-editor'; -import * as projectAccessMock from '@sap-ux/project-access'; import type { Editor } from 'mem-fs-editor'; +import { create, create as createFS } from 'mem-fs-editor'; +import { addVariantsManagementScript } from '../../../src/variants-config/package-json'; import type { ToolsLogger } from '@sap-ux/logger'; -import { join } from 'path'; +describe('Test for adding start-variants-management script in package.json', () => { + test('Add new start-variants-management script to package.json and keep the existing one', async () => { + const basePath = join(__dirname, '../../fixtures/variants-config/app-with-client-in-script'); + const fs = createFS(createStorage()); + await addVariantsManagementScript(fs, basePath); + expect(fs.readJSON(join(basePath, 'package.json'))).toEqual({ + 'name': 'app-client', + 'scripts': { + 'start': 'fiori run --open "test/flpSandbox.html?sap-client=100&sap-ui-xx-viewCache=false#test-tile"', + 'start-variants-management': `fiori run --open \"preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true&sap-client=100#app-preview\"` + } + }); + }); + + test('No sap client present in script', async () => { + const basePath = join(__dirname, '../../fixtures/variants-config/simple-app/'); + const fs = createFS(createStorage()); + interface PackageJson { + scripts?: { + [key: string]: string; + }; + } + await addVariantsManagementScript(fs, basePath); + const script = fs.readJSON(join(basePath, 'package.json')) as PackageJson; + expect(script?.scripts?.['start-variants-management']?.includes('sap-client=100')).toEqual(false); + }); + + test('Add script to package.json when there is no script', async () => { + const basePath = join(__dirname, '../../fixtures/variants-config/simple-app/'); + const fs = createFS(createStorage()); + const loggerMock = { + debug: jest.fn(), + info: jest.fn(), + warn: jest.fn() + } as Partial as ToolsLogger; + await addVariantsManagementScript(fs, basePath, loggerMock); + expect(loggerMock.warn).toHaveBeenCalledWith( + `File 'package.json' does not contain a script section. Script section added.` + ); + }); + + test('No script inserted to package.json when there is already a script', async () => { + const basePath = join(__dirname, '../../fixtures/variants-config/deprecated-config/'); + const fs = createFS(createStorage()); + const loggerMock = { + debug: jest.fn(), + info: jest.fn(), + warn: jest.fn() + } as Partial as ToolsLogger; + await addVariantsManagementScript(fs, basePath, loggerMock); + expect(loggerMock.warn).toHaveBeenCalledWith( + `Script 'start-variants-management' cannot be written to 'package.json. Script already exists'.` + ); + }); +}); describe('addVariantsManagementScript', () => { const basePath = join(__dirname, '../../fixtures/variants-config'); diff --git a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts new file mode 100644 index 0000000000..94489d5376 --- /dev/null +++ b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts @@ -0,0 +1,46 @@ +import { create as createStorage } from 'mem-fs'; +import { create } from 'mem-fs-editor'; +import type { Editor } from 'mem-fs-editor'; +import { join } from 'path'; +import type { ToolsLogger } from '@sap-ux/logger'; +import { updateMiddlewares } from '../../../src/variants-config/ui5-yaml'; + +describe('Test update middleware', () => { + const loggerMock: ToolsLogger = { debug: jest.fn() } as Partial as ToolsLogger; + let fs: Editor; + let debugMock: jest.SpyInstance; + + beforeEach(() => { + jest.clearAllMocks(); + fs = create(createStorage()); + debugMock = loggerMock.debug as any; + }); + + test('ui5.yaml - add fiori-tools-preview', async () => { + const basePath = join(__dirname, '../../fixtures/variants-config/simple-app/'); + await updateMiddlewares(fs, basePath, loggerMock); + expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); + expect(debugMock.mock.calls[0][0]).toMatchInlineSnapshot(`"Updated preview middleware in ui5.yaml."`); + expect(debugMock.mock.calls[1][0]).toMatchInlineSnapshot( + `"Cannot write variants-config to ui5-mock.yaml. File not existing"` + ); + }); + + test('ui5.yaml - do nothing when fiori-tools-preview is present', async () => { + const basePath = join(__dirname, '../../fixtures/variants-config/app-with-client-in-script/'); + await updateMiddlewares(fs, basePath, loggerMock); + expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); + expect(debugMock.mock.calls[0][0]).toMatchInlineSnapshot(`"Updated preview middleware in ui5.yaml."`); + expect(debugMock.mock.calls[1][0]).toMatchInlineSnapshot( + `"Cannot write variants-config to ui5-mock.yaml. File not existing"` + ); + }); + + test('ui5-mock.yaml - add fiori-tools-appreload', async () => { + const basePath = join(__dirname, '../../fixtures/variants-config/app-with-reload-middleware/'); + await updateMiddlewares(fs, basePath, loggerMock); + expect(fs.read(join(basePath, 'ui5-mock.yaml'))).toMatchSnapshot(); + expect(debugMock.mock.calls[0][0]).toMatchInlineSnapshot(`"Updated preview middleware in ui5.yaml."`); + expect(debugMock.mock.calls[1][0]).toMatchInlineSnapshot(`"Updated reload middleware in ui5-mock.yaml."`); + }); +}); diff --git a/packages/create/test/unit/cli/add/variants-config.test.ts b/packages/create/test/unit/cli/add/variants-config.test.ts new file mode 100644 index 0000000000..6724f5fe2e --- /dev/null +++ b/packages/create/test/unit/cli/add/variants-config.test.ts @@ -0,0 +1,86 @@ +import { Command } from 'commander'; +import type { Editor } from 'mem-fs-editor'; +import type { ToolsLogger } from '@sap-ux/logger'; +import { addAddVariantsConfigCommand } from '../../../../src/cli/add/variants-config'; +import * as appConfigWriter from '@sap-ux/app-config-writer'; +import * as logger from '../../../../src/tracing/logger'; +import * as childProcess from 'child_process'; +import { join } from 'path'; + +jest.mock('child_process'); +jest.mock('prompts'); + +describe('Test command add variants-config', () => { + const appRoot = join(__dirname, '../../../fixtures/bare-minimum'); + let loggerMock: ToolsLogger; + let fsMock: Editor; + let logLevelSpy: jest.SpyInstance; + let spawnSpy: jest.SpyInstance; + + const getArgv = (arg: string[]) => ['', '', ...arg]; + + beforeEach(() => { + jest.clearAllMocks(); + + // Mock setup + loggerMock = { + debug: jest.fn(), + info: jest.fn(), + warn: jest.fn(), + error: jest.fn() + } as Partial as ToolsLogger; + jest.spyOn(logger, 'getLogger').mockImplementation(() => loggerMock); + logLevelSpy = jest.spyOn(logger, 'setLogLevelVerbose').mockImplementation(() => undefined); + fsMock = { + dump: jest.fn(), + exists: jest.fn(), + commit: jest.fn().mockImplementation((callback) => callback()) + } as Partial as Editor; + jest.spyOn(appConfigWriter, 'generateVariantsConfig').mockResolvedValue(fsMock); + spawnSpy = jest.spyOn(childProcess, 'spawnSync'); + }); + + test('Test create-fiori add variants-config ', async () => { + // Test execution + const command = new Command('add'); + addAddVariantsConfigCommand(command); + await command.parseAsync(getArgv(['variants-config', appRoot])); + + // Result check + expect(logLevelSpy).not.toBeCalled(); + expect(loggerMock.debug).toBeCalled(); + expect(loggerMock.info).toBeCalled(); + expect(loggerMock.warn).not.toBeCalled(); + expect(loggerMock.error).not.toBeCalled(); + expect(fsMock.commit).toBeCalled(); + expect(spawnSpy).not.toBeCalled(); + }); + + test('Test create-fiori add variants-config --simulate', async () => { + // Test execution + const command = new Command('add'); + addAddVariantsConfigCommand(command); + await command.parseAsync(getArgv(['variants-config', appRoot, '-s'])); + + // Result check + expect(logLevelSpy).toBeCalled(); + expect(loggerMock.warn).not.toBeCalled(); + expect(loggerMock.error).not.toBeCalled(); + expect(spawnSpy).not.toBeCalled(); + expect(fsMock.commit).not.toBeCalled(); + }); + + test('Test create-fiori add variants-config --verbose', async () => { + // Test execution + const command = new Command('add'); + addAddVariantsConfigCommand(command); + await command.parseAsync(getArgv(['variants-config', '--verbose'])); + + // Result check + expect(logLevelSpy).toBeCalled(); + expect(loggerMock.debug).toBeCalled(); + expect(loggerMock.error).toBeCalled(); + expect(fsMock.commit).not.toBeCalled(); + expect(spawnSpy).not.toBeCalled(); + }); +}); From ee9da5241769201487e41585b5917e099a4d002f Mon Sep 17 00:00:00 2001 From: D048415 Date: Mon, 7 Oct 2024 14:28:57 +0200 Subject: [PATCH 15/37] fix typo --- packages/app-config-writer/src/variants-config/ui5-yaml.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index c7e2067ce2..a5a0a89ade 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -78,7 +78,7 @@ function getReloadMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware Date: Mon, 7 Oct 2024 15:21:16 +0200 Subject: [PATCH 16/37] adjust unit tests --- .../unit/variants-config/package-json.test.ts | 61 ++++++------------- .../unit/variants-config/ui5-yaml.test.ts | 43 +++++++------ 2 files changed, 46 insertions(+), 58 deletions(-) diff --git a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts index 3251b89430..4087eaef3e 100644 --- a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts @@ -3,13 +3,22 @@ import { create as createStorage } from 'mem-fs'; import type { Editor } from 'mem-fs-editor'; import { create, create as createFS } from 'mem-fs-editor'; import { addVariantsManagementScript } from '../../../src/variants-config/package-json'; -import type { ToolsLogger } from '@sap-ux/logger'; +import { ToolsLogger } from '@sap-ux/logger'; describe('Test for adding start-variants-management script in package.json', () => { + const logger = new ToolsLogger(); + let fs: Editor; + const warnLogMock = jest.spyOn(ToolsLogger.prototype, 'warn').mockImplementation(() => {}); + const debugLogMock = jest.spyOn(ToolsLogger.prototype, 'debug').mockImplementation(() => {}); + + beforeEach(() => { + jest.clearAllMocks(); + fs = createFS(createStorage()); + }); + test('Add new start-variants-management script to package.json and keep the existing one', async () => { const basePath = join(__dirname, '../../fixtures/variants-config/app-with-client-in-script'); - const fs = createFS(createStorage()); - await addVariantsManagementScript(fs, basePath); + await addVariantsManagementScript(fs, basePath, logger); expect(fs.readJSON(join(basePath, 'package.json'))).toEqual({ 'name': 'app-client', 'scripts': { @@ -17,66 +26,36 @@ describe('Test for adding start-variants-management script in package.json', () 'start-variants-management': `fiori run --open \"preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true&sap-client=100#app-preview\"` } }); + expect(debugLogMock).toHaveBeenCalledWith(`Script 'start-variants-management' written to 'package.json'.`); }); test('No sap client present in script', async () => { const basePath = join(__dirname, '../../fixtures/variants-config/simple-app/'); - const fs = createFS(createStorage()); interface PackageJson { scripts?: { [key: string]: string; }; } - await addVariantsManagementScript(fs, basePath); + await addVariantsManagementScript(fs, basePath, logger); const script = fs.readJSON(join(basePath, 'package.json')) as PackageJson; expect(script?.scripts?.['start-variants-management']?.includes('sap-client=100')).toEqual(false); + expect(debugLogMock).toHaveBeenCalledWith(`Script 'start-variants-management' written to 'package.json'.`); }); test('Add script to package.json when there is no script', async () => { const basePath = join(__dirname, '../../fixtures/variants-config/simple-app/'); - const fs = createFS(createStorage()); - const loggerMock = { - debug: jest.fn(), - info: jest.fn(), - warn: jest.fn() - } as Partial as ToolsLogger; - await addVariantsManagementScript(fs, basePath, loggerMock); - expect(loggerMock.warn).toHaveBeenCalledWith( + await addVariantsManagementScript(fs, basePath, logger); + expect(warnLogMock).toHaveBeenCalledWith( `File 'package.json' does not contain a script section. Script section added.` ); + expect(debugLogMock).toHaveBeenCalledWith(`Script 'start-variants-management' written to 'package.json'.`); }); test('No script inserted to package.json when there is already a script', async () => { const basePath = join(__dirname, '../../fixtures/variants-config/deprecated-config/'); - const fs = createFS(createStorage()); - const loggerMock = { - debug: jest.fn(), - info: jest.fn(), - warn: jest.fn() - } as Partial as ToolsLogger; - await addVariantsManagementScript(fs, basePath, loggerMock); - expect(loggerMock.warn).toHaveBeenCalledWith( + await addVariantsManagementScript(fs, basePath, logger); + expect(warnLogMock).toHaveBeenCalledWith( `Script 'start-variants-management' cannot be written to 'package.json. Script already exists'.` ); }); }); - -describe('addVariantsManagementScript', () => { - const basePath = join(__dirname, '../../fixtures/variants-config'); - const legacyBasePath = join(__dirname, '../../fixtures/variants-config/deprecated-config'); - - const loggerMock: ToolsLogger = { debug: jest.fn() } as Partial as ToolsLogger; - let fs: Editor; - let debugMock: jest.SpyInstance; - - beforeEach(() => { - jest.clearAllMocks(); - fs = create(createStorage()); - debugMock = loggerMock.debug as any; - }); - - test('add variants-management script to package.json', async () => { - await addVariantsManagementScript(fs, basePath, loggerMock); - expect(debugMock.mock.calls[0][0]).toEqual(`Script 'start-variants-management' written to 'package.json'.`); - }); -}); diff --git a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts index 94489d5376..46247f2619 100644 --- a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts @@ -2,45 +2,54 @@ import { create as createStorage } from 'mem-fs'; import { create } from 'mem-fs-editor'; import type { Editor } from 'mem-fs-editor'; import { join } from 'path'; -import type { ToolsLogger } from '@sap-ux/logger'; +import { ToolsLogger } from '@sap-ux/logger'; import { updateMiddlewares } from '../../../src/variants-config/ui5-yaml'; +const middlewareUpdatedMessage = ( + middleware: 'preview' | 'reload', + filename: 'ui5-mock.yaml' | 'ui5-local.yaml' | 'ui5.yaml' +) => `Updated ${middleware} middleware in ${filename}.`; + +const noFileMessage = (filename: 'ui5-mock.yaml' | 'ui5-local.yaml') => + `Cannot write variants-config to ${filename}. File not existing`; + describe('Test update middleware', () => { - const loggerMock: ToolsLogger = { debug: jest.fn() } as Partial as ToolsLogger; + const logger = new ToolsLogger(); let fs: Editor; - let debugMock: jest.SpyInstance; + const debugLogMock = jest.spyOn(ToolsLogger.prototype, 'debug').mockImplementation(() => {}); beforeEach(() => { jest.clearAllMocks(); fs = create(createStorage()); - debugMock = loggerMock.debug as any; }); test('ui5.yaml - add fiori-tools-preview', async () => { const basePath = join(__dirname, '../../fixtures/variants-config/simple-app/'); - await updateMiddlewares(fs, basePath, loggerMock); + await updateMiddlewares(fs, basePath, logger); expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); - expect(debugMock.mock.calls[0][0]).toMatchInlineSnapshot(`"Updated preview middleware in ui5.yaml."`); - expect(debugMock.mock.calls[1][0]).toMatchInlineSnapshot( - `"Cannot write variants-config to ui5-mock.yaml. File not existing"` - ); + expect(debugLogMock).toHaveBeenCalledTimes(3); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-mock.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-local.yaml')); }); test('ui5.yaml - do nothing when fiori-tools-preview is present', async () => { const basePath = join(__dirname, '../../fixtures/variants-config/app-with-client-in-script/'); - await updateMiddlewares(fs, basePath, loggerMock); + await updateMiddlewares(fs, basePath, logger); expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); - expect(debugMock.mock.calls[0][0]).toMatchInlineSnapshot(`"Updated preview middleware in ui5.yaml."`); - expect(debugMock.mock.calls[1][0]).toMatchInlineSnapshot( - `"Cannot write variants-config to ui5-mock.yaml. File not existing"` - ); + expect(debugLogMock).toHaveBeenCalledTimes(3); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-mock.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-local.yaml')); }); test('ui5-mock.yaml - add fiori-tools-appreload', async () => { const basePath = join(__dirname, '../../fixtures/variants-config/app-with-reload-middleware/'); - await updateMiddlewares(fs, basePath, loggerMock); + await updateMiddlewares(fs, basePath, logger); expect(fs.read(join(basePath, 'ui5-mock.yaml'))).toMatchSnapshot(); - expect(debugMock.mock.calls[0][0]).toMatchInlineSnapshot(`"Updated preview middleware in ui5.yaml."`); - expect(debugMock.mock.calls[1][0]).toMatchInlineSnapshot(`"Updated reload middleware in ui5-mock.yaml."`); + expect(debugLogMock).toHaveBeenCalledTimes(4); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('reload', 'ui5-mock.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5-mock.yaml')); }); }); From 9cf6c8765e11970e749fc3aeada9b2af0d15e188 Mon Sep 17 00:00:00 2001 From: D048415 Date: Mon, 7 Oct 2024 17:13:57 +0200 Subject: [PATCH 17/37] adjust unit tests --- .../unit/variants-config/ui5-yaml.test.ts | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts index 46247f2619..9f6b07136d 100644 --- a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts @@ -4,14 +4,14 @@ import type { Editor } from 'mem-fs-editor'; import { join } from 'path'; import { ToolsLogger } from '@sap-ux/logger'; import { updateMiddlewares } from '../../../src/variants-config/ui5-yaml'; +import { FileName } from '@sap-ux/project-access'; -const middlewareUpdatedMessage = ( - middleware: 'preview' | 'reload', - filename: 'ui5-mock.yaml' | 'ui5-local.yaml' | 'ui5.yaml' -) => `Updated ${middleware} middleware in ${filename}.`; +type YamlFileName = typeof FileName.Ui5MockYaml | typeof FileName.Ui5LocalYaml | typeof FileName.Ui5Yaml; -const noFileMessage = (filename: 'ui5-mock.yaml' | 'ui5-local.yaml') => - `Cannot write variants-config to ${filename}. File not existing`; +const middlewareUpdatedMessage = (middleware: 'preview' | 'reload', filename: YamlFileName) => + `Updated ${middleware} middleware in ${filename}.`; + +const noFileMessage = (filename: YamlFileName) => `Cannot write variants-config to ${filename}. File not existing`; describe('Test update middleware', () => { const logger = new ToolsLogger(); @@ -28,9 +28,9 @@ describe('Test update middleware', () => { await updateMiddlewares(fs, basePath, logger); expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); expect(debugLogMock).toHaveBeenCalledTimes(3); - expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5.yaml')); - expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-mock.yaml')); - expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-local.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5Yaml)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5MockYaml)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5LocalYaml)); }); test('ui5.yaml - do nothing when fiori-tools-preview is present', async () => { @@ -38,9 +38,9 @@ describe('Test update middleware', () => { await updateMiddlewares(fs, basePath, logger); expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); expect(debugLogMock).toHaveBeenCalledTimes(3); - expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5.yaml')); - expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-mock.yaml')); - expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-local.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5Yaml)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5MockYaml)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5LocalYaml)); }); test('ui5-mock.yaml - add fiori-tools-appreload', async () => { @@ -48,8 +48,8 @@ describe('Test update middleware', () => { await updateMiddlewares(fs, basePath, logger); expect(fs.read(join(basePath, 'ui5-mock.yaml'))).toMatchSnapshot(); expect(debugLogMock).toHaveBeenCalledTimes(4); - expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5.yaml')); - expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('reload', 'ui5-mock.yaml')); - expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5-mock.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5Yaml)); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('reload', FileName.Ui5MockYaml)); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5MockYaml)); }); }); From 600d8a9fee97ab7bb5ba5dfd848c88a827666457 Mon Sep 17 00:00:00 2001 From: Annemarie Date: Mon, 7 Oct 2024 21:55:06 +0200 Subject: [PATCH 18/37] feat: rta editor --- .../src/types/variantsConfig.ts | 6 +- .../src/variants-config/package-json.ts | 18 +++-- .../src/variants-config/ui5-yaml.ts | 12 +-- .../src/variants-config/utils.ts | 78 +++++++++++++++---- 4 files changed, 84 insertions(+), 30 deletions(-) diff --git a/packages/app-config-writer/src/types/variantsConfig.ts b/packages/app-config-writer/src/types/variantsConfig.ts index e4023ba7dc..281e694783 100644 --- a/packages/app-config-writer/src/types/variantsConfig.ts +++ b/packages/app-config-writer/src/types/variantsConfig.ts @@ -1,12 +1,12 @@ -import type { MiddlewareConfig as FioriToolsPreviewConfig } from '@sap-ux/preview-middleware'; +import type { MiddlewareConfig } from '@sap-ux/preview-middleware'; export type FioriToolsDeprecatedPreviewConfig = { component: string; libs?: boolean; ui5Theme?: string; }; - -export type FioriPreviewConfigOptions = FioriToolsDeprecatedPreviewConfig | FioriToolsPreviewConfig; +export type PreviewConfig = MiddlewareConfig; +export type PreviewConfigOptions = FioriToolsDeprecatedPreviewConfig | PreviewConfig; export enum MiddlewareConfigs { FioriToolsPreview = 'fiori-tools-preview', diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index 9be298c1e6..e325118648 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -1,5 +1,5 @@ import { join } from 'path'; -import { getSapClientFromPackageJson, getUi5UrlParameters, getPreviewUrl } from './utils'; +import { getSapClientFromPackageJson, getUI5UrlParameters, getRTAUrl } from './utils'; import type { Editor } from 'mem-fs-editor'; import type { Package } from '@sap-ux/project-access'; import type { ToolsLogger } from '@sap-ux/logger'; @@ -29,12 +29,18 @@ export async function addVariantsManagementScript(fs: Editor, basePath: string, } } - const query = getUi5UrlParameters(urlParameters); - const url = await getPreviewUrl(basePath, query); - packageJson.scripts['start-variants-management'] = `fiori run --open "${url}"`; + const query = getUI5UrlParameters(urlParameters); + const url = await getRTAUrl(basePath, query, logger); - fs.writeJSON(packageJsonPath, packageJson); - logger?.debug(`Script 'start-variants-management' written to 'package.json'.`); + if (url) { + packageJson.scripts['start-variants-management'] = `fiori run --open "${url}"`; + fs.writeJSON(packageJsonPath, packageJson); + logger?.debug(`Script 'start-variants-management' written to 'package.json'.`); + } else { + logger?.warn( + `Script 'start-variants-management' cannot be written to 'package.json. No RTA editor specified in ui5.yaml.` + ); + } } else { logger?.warn(`Script 'start-variants-management' cannot be written to 'package.json. Script already exists'.`); } diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index a5a0a89ade..5d80b52889 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -6,7 +6,7 @@ import type { ToolsLogger } from '@sap-ux/logger'; import type { UI5Config } from '@sap-ux/ui5-config'; import type { CustomMiddleware } from '@sap-ux/ui5-config'; import type { FioriAppReloadConfig } from '@sap-ux/ui5-config'; -import type { FioriPreviewConfigOptions } from '../types'; +import type { PreviewConfigOptions } from '../types'; /** * Writes the given middleware to a ui5.yaml file. @@ -27,23 +27,23 @@ export function writeMiddlewareToYaml( } /** - * Gets the preview middleware configuration. + * Gets the preview middleware configuration form the ui5.yaml. * The middleware can either be named fiori-tools-preview or preview-middleware. * If no preview configuration is given, then one will be created. * * @param ui5YamlConfig existing ui5.yaml configurations * @returns 'fiori-tools-preview' or 'preview-middleware' configuration */ -function getPreviewMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware { +function getPreviewMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware { const previewMiddlewareTemplate = { // ToDo: How to know the default if there is no preview middleware... name: 'fiori-tools-preview', afterMiddleware: 'compression' - } as CustomMiddleware; + } as CustomMiddleware; const existingPreviewMiddleware = - ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? - ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.PreviewMiddleware); + ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? + ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.PreviewMiddleware); if (existingPreviewMiddleware) { previewMiddlewareTemplate.name = existingPreviewMiddleware.name; diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index 197ea50afa..b73795a384 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -3,21 +3,21 @@ import { MiddlewareConfigs } from '../types'; import { stringify } from 'querystring'; import type { Package } from '@sap-ux/project-access'; import type { CustomMiddleware } from '@sap-ux/ui5-config'; -import type { FioriPreviewConfigOptions, FioriToolsDeprecatedPreviewConfig } from '../types'; +import type { PreviewConfigOptions, FioriToolsDeprecatedPreviewConfig } from '../types'; +import { ToolsLogger } from '@sap-ux/logger'; /** - * Gets the fiori-tools-preview middleware configuration. + * Gets the preview middleware form the ui5.yaml file. + * The middleware can either be named fiori-tools-preview or preview-middleware. * * @param basePath - path to project root, where package.json and ui5.yaml is * @returns 'fiori-tools-preview' configuration if given */ -async function getFioriToolsPreviewMiddleware( - basePath: string -): Promise | undefined> { +async function getPreviewMiddleware(basePath: string): Promise | undefined> { const existingUi5YamlConfig = await readUi5Yaml(basePath, FileName.Ui5Yaml); return ( - existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? - existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.PreviewMiddleware) + existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? + existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.PreviewMiddleware) ); } @@ -28,7 +28,7 @@ async function getFioriToolsPreviewMiddleware( * @returns true, if a preview middleware configuration is deprecated */ function isFioriToolsDeprecatedPreviewConfig( - configuration: FioriPreviewConfigOptions | undefined + configuration: PreviewConfigOptions | undefined ): configuration is FioriToolsDeprecatedPreviewConfig { return (configuration as FioriToolsDeprecatedPreviewConfig)?.component !== undefined; } @@ -51,11 +51,12 @@ export function getSapClientFromPackageJson(scripts: Package['scripts']): string /** * Returns the UI5 url parameters. + * This is needed for the UI5 run time adaptation. * * @param overwritingParams - parameters to be overwritten * @returns - UI5 url parameters */ -export function getUi5UrlParameters(overwritingParams: Record = {}): string { +export function getUI5UrlParameters(overwritingParams: Record = {}): string { const parameters: Record = { 'fiori-tools-rta-mode': 'true', 'sap-ui-rta-skip-flex-validation': 'true', @@ -65,15 +66,62 @@ export function getUi5UrlParameters(overwritingParams: Record = } /** - * Returns the preview url. + * Returns the RTA mount point of the preview middleware configuration from the ui5.yaml file, if given. + * + * @param previewMiddleware - configuration of the preview middleware + * @returns - RTA mount point or undefined + */ +function getRTAMountPoint(previewMiddlewareConfig: PreviewConfigOptions | undefined): string | undefined { + if (!isFioriToolsDeprecatedPreviewConfig(previewMiddlewareConfig) && previewMiddlewareConfig?.rta?.editors) { + const editors = previewMiddlewareConfig.rta.editors; + for (const editor of editors) { + if ('developerMode' in editor === false) { + return editor.path; + } + } + } else { + return undefined; + } +} + +/** + * Returns the intent of the preview middleware configuration from the ui5.yaml file, if given. + * + * @param previewMiddleware - configuration of the preview middleware + * @returns - preview intent or undefined + */ +function getRTAIntent(previewMiddlewareConfig: PreviewConfigOptions | undefined): string | undefined { + if (isFioriToolsDeprecatedPreviewConfig(previewMiddlewareConfig)) { + return undefined; + } else { + const intent = previewMiddlewareConfig?.flp?.intent; + return intent ? `#${intent.object}-${intent.action}` : undefined; + } +} + +/** + * Returns the url for variants management in RTA mode. + * The url consist of a specified mount point and intent given from the ui5.yaml file as well as parameters for the RTA mode. * * @param basePath - path to project root, where package.json and ui5.yaml is located * @param query - query to create fragment + * @param logger - logger * @returns - review url parameters */ -export async function getPreviewUrl(basePath: string, query: string): Promise { - const existingPreviewMiddleware = await getFioriToolsPreviewMiddleware(basePath); - return isFioriToolsDeprecatedPreviewConfig(existingPreviewMiddleware?.configuration) - ? `preview.html?${query}#preview-app` - : `preview.html?${query}#app-preview`; +export async function getRTAUrl(basePath: string, query: string, logger?: ToolsLogger): Promise { + const existingPreviewMiddleware = await getPreviewMiddleware(basePath); + if ( + existingPreviewMiddleware?.name === MiddlewareConfigs.PreviewMiddleware && + !getRTAMountPoint(existingPreviewMiddleware?.configuration) + ) { + return undefined; + } else { + //ToDo: what about a default mount point for os? Why in tools suite it's preview.html? + const mountPoint = getRTAMountPoint(existingPreviewMiddleware?.configuration) ?? '/preview.html'; + const intent = getRTAIntent(existingPreviewMiddleware?.configuration) ?? '#app-preview'; + + return isFioriToolsDeprecatedPreviewConfig(existingPreviewMiddleware?.configuration) + ? `${mountPoint}?${query}#preview-app` + : `${mountPoint}?${query}${intent}`; + } } From 27aaf526032dc640aa4e0fabb60b97d379630837 Mon Sep 17 00:00:00 2001 From: Annemarie Date: Mon, 7 Oct 2024 21:55:42 +0200 Subject: [PATCH 19/37] test: unit test rta editor --- .../app-with-client-in-script/package.json | 6 -- .../app-with-client-in-script/ui5.yaml | 17 ----- .../webapp/manifest.json | 6 -- .../app-with-reload-middleware/package.json | 3 - .../app-with-reload-middleware/ui5.yaml | 26 ------- .../webapp/manifest.json | 6 -- .../deprecated-config/package.json | 7 -- .../deprecated-config/ui5.yaml | 1 - .../fiori-tools-config/package.json | 9 +++ .../fiori-tools-config/ui5-local.yaml | 10 +++ .../ui5-mock.yaml | 6 +- .../fiori-tools-config/ui5.yaml | 10 +++ .../open-source-config/package.json | 9 +++ .../open-source-config/ui5.yaml | 15 ++++ .../fixtures/variants-config/package.json | 25 +------ .../variants-config/simple-app/package.json | 3 - .../variants-config/simple-app/ui5.yaml | 26 ------- .../simple-app/webapp/manifest.json | 6 -- .../fixtures/variants-config/ui5-local.yaml | 19 ----- .../fixtures/variants-config/ui5-mock.yaml | 21 ------ .../test/fixtures/variants-config/ui5.yaml | 35 ++++----- .../generateVariantsConfig.test.ts.snap | 35 +++++++++ .../__snapshots__/index.test.ts.snap | 33 -------- .../__snapshots__/package-json.test.ts.snap | 14 ++++ .../__snapshots__/ui5-yaml.test.ts.snap | 75 +++++++------------ .../generateVariantsConfig.test.ts | 12 +++ .../test/unit/variants-config/index.test.ts | 17 ----- .../unit/variants-config/package-json.test.ts | 56 ++++++-------- .../unit/variants-config/ui5-yaml.test.ts | 33 ++++---- .../test/unit/variants-config/utils.test.ts | 52 ++++++++++--- 30 files changed, 241 insertions(+), 352 deletions(-) delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/package.json delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/ui5.yaml delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/webapp/manifest.json delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/package.json delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5.yaml delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/webapp/manifest.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/package.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5-local.yaml rename packages/app-config-writer/test/fixtures/variants-config/{app-with-reload-middleware => fiori-tools-config}/ui5-mock.yaml (61%) create mode 100644 packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5.yaml create mode 100644 packages/app-config-writer/test/fixtures/variants-config/open-source-config/package.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/open-source-config/ui5.yaml delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/simple-app/package.json delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/simple-app/ui5.yaml delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/simple-app/webapp/manifest.json delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/ui5-local.yaml delete mode 100644 packages/app-config-writer/test/fixtures/variants-config/ui5-mock.yaml create mode 100644 packages/app-config-writer/test/unit/variants-config/__snapshots__/generateVariantsConfig.test.ts.snap delete mode 100644 packages/app-config-writer/test/unit/variants-config/__snapshots__/index.test.ts.snap create mode 100644 packages/app-config-writer/test/unit/variants-config/__snapshots__/package-json.test.ts.snap create mode 100644 packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts delete mode 100644 packages/app-config-writer/test/unit/variants-config/index.test.ts diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/package.json b/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/package.json deleted file mode 100644 index aea2e1ac25..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "app-client", - "scripts": { - "start": "fiori run --open \"test/flpSandbox.html?sap-client=100&sap-ui-xx-viewCache=false#test-tile\"" - } -} diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/ui5.yaml deleted file mode 100644 index 438ac71211..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/ui5.yaml +++ /dev/null @@ -1,17 +0,0 @@ -specVersion: '2.4' -metadata: - name: 'app-client' -type: application -server: - customMiddleware: - - name: fiori-tools-servestatic - beforeMiddleware: fiori-tools-proxy - configuration: - paths: - - path: /appconfig - src: appconfig - fallthrough: false - - name: fiori-tools-preview - afterMiddleware: compression - configuration: - ui5Theme: sap_horizon \ No newline at end of file diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/webapp/manifest.json b/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/webapp/manifest.json deleted file mode 100644 index 3fdb8bb13f..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/app-with-client-in-script/webapp/manifest.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "sap.app": { - "id": "app-client", - "type": "application" - } -} diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/package.json b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/package.json deleted file mode 100644 index 0f0da8cc30..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "app-with-reload-middleware" -} diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5.yaml deleted file mode 100644 index 6246c24b20..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5.yaml +++ /dev/null @@ -1,26 +0,0 @@ -specVersion: '2.4' -metadata: - name: 'app-with-reload-middleware' -type: application -server: - customMiddleware: - - name: fiori-tools-proxy - afterMiddleware: compression - configuration: - ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted - backend: - - path: /sap - url: https://abc.ondemand.example - ui5: - path: - - /resources - - /test-resources - url: https://ui5.sap.com.example - version: 1.91.0 # The UI5 version, for instance, 1.78.1. Empty means latest version - - name: fiori-tools-servestatic - beforeMiddleware: fiori-tools-proxy - configuration: - paths: - - path: /appconfig - src: appconfig - fallthrough: false diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/webapp/manifest.json b/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/webapp/manifest.json deleted file mode 100644 index e7d3e07a0a..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/webapp/manifest.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "sap.app": { - "id": "app-with-reload-middleware", - "type": "application" - } -} diff --git a/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/package.json b/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/package.json index 9412d31bfd..3022f7af8e 100644 --- a/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/package.json +++ b/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/package.json @@ -1,13 +1,6 @@ { "name": "v2-lrop-0909", - "version": "0.0.1", "description": "An SAP Fiori application.", - "keywords": [ - "ui5", - "openui5", - "sapui5" - ], - "main": "webapp/index.html", "scripts": { "start-variants-management": "fiori run --open \"preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true&sap-client=500#app-preview\"" }, diff --git a/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/ui5.yaml index da529ad43a..506a229c8b 100644 --- a/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/ui5.yaml +++ b/packages/app-config-writer/test/fixtures/variants-config/deprecated-config/ui5.yaml @@ -9,4 +9,3 @@ server: configuration: component: v2lrop0909 ui5Theme: sap_horizon -# Test variants-config with no fiori-tools-preview middleware config and missing delay for fiori-tools-appreload \ No newline at end of file diff --git a/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/package.json b/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/package.json new file mode 100644 index 0000000000..6204c29406 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/package.json @@ -0,0 +1,9 @@ +{ + "name": "test-app", + "description": "An SAP Fiori application.", + "scripts": { + "start": "fiori run --open \"test/flpSandbox.html?sap-client=500#test-app\"" + }, + "sapux": true, + "sapuxLayer": "VENDOR" +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5-local.yaml b/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5-local.yaml new file mode 100644 index 0000000000..2c0f881923 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5-local.yaml @@ -0,0 +1,10 @@ +specVersion: "3.1" +metadata: + name: fiori-tools-config +type: application +server: + customMiddleware: + - name: fiori-tools-appreload + afterMiddleware: compression + - name: fiori-tools-preview + afterMiddleware: compression diff --git a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5-mock.yaml b/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5-mock.yaml similarity index 61% rename from packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5-mock.yaml rename to packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5-mock.yaml index 488d8eacf2..2c0f881923 100644 --- a/packages/app-config-writer/test/fixtures/variants-config/app-with-reload-middleware/ui5-mock.yaml +++ b/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5-mock.yaml @@ -1,10 +1,10 @@ -specVersion: "2.4" +specVersion: "3.1" metadata: - name: app-with-reload-middleware + name: fiori-tools-config type: application server: customMiddleware: - name: fiori-tools-appreload - afterMiddleware: fiori-tools-appreload + afterMiddleware: compression - name: fiori-tools-preview afterMiddleware: compression diff --git a/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5.yaml new file mode 100644 index 0000000000..2c0f881923 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/fiori-tools-config/ui5.yaml @@ -0,0 +1,10 @@ +specVersion: "3.1" +metadata: + name: fiori-tools-config +type: application +server: + customMiddleware: + - name: fiori-tools-appreload + afterMiddleware: compression + - name: fiori-tools-preview + afterMiddleware: compression diff --git a/packages/app-config-writer/test/fixtures/variants-config/open-source-config/package.json b/packages/app-config-writer/test/fixtures/variants-config/open-source-config/package.json new file mode 100644 index 0000000000..17ae385f11 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/open-source-config/package.json @@ -0,0 +1,9 @@ +{ + "name": "test-app", + "description": "An SAP Fiori application.", + "scripts": { + "start": "fiori run --open \"test/flpSandbox.html?#v2lrop0909-tile\"" + }, + "sapux": true, + "sapuxLayer": "VENDOR" +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/open-source-config/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/open-source-config/ui5.yaml new file mode 100644 index 0000000000..4e2c4ea7e9 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/open-source-config/ui5.yaml @@ -0,0 +1,15 @@ +specVersion: "3.0" +metadata: + name: fe_lrop_v2 +type: application +server: + customMiddleware: + - name: fiori-tools-appreload + afterMiddleware: compression + - name: preview-middleware + configuration: + flp: + intent: + object: hello + action: world + diff --git a/packages/app-config-writer/test/fixtures/variants-config/package.json b/packages/app-config-writer/test/fixtures/variants-config/package.json index e004106b1f..32a726781e 100644 --- a/packages/app-config-writer/test/fixtures/variants-config/package.json +++ b/packages/app-config-writer/test/fixtures/variants-config/package.json @@ -1,28 +1,5 @@ { - "name": "v2-lrop-0909", - "version": "0.0.1", - "description": "An SAP Fiori application.", - "keywords": [ - "ui5", - "openui5", - "sapui5" - ], - "main": "webapp/index.html", - "devDependencies": { - "@sap-ux/ui5-middleware-fe-mockserver": "2", - "@sap/ux-specification": "^1.124.1", - "@sap/ux-ui5-tooling": "^1.15.0", - "@ui5/cli": "^3.0.0" - }, - "scripts": { - "start": "fiori run --open \"test/flpSandbox.html?sap-client=500&sap-ui-xx-viewCache=false#v2lrop0909-tile\"", - "start-local": "fiori run --config ./ui5-local.yaml --open \"test/flpSandbox.html?sap-ui-xx-viewCache=false#v2lrop0909-tile\"", - "build": "ui5 build --config=ui5.yaml --clean-dest --dest dist", - "start-mock": "fiori run --config ./ui5-mock.yaml --open \"test/flpSandbox.html?sap-ui-xx-viewCache=false#v2lrop0909-tile\"", - "deploy": "fiori verify", - "deploy-config": "fiori add deploy-config", - "start-noflp": "fiori run --open \"index.html?sap-ui-xx-viewCache=false\"" - }, + "name": "test-app", "sapux": true, "sapuxLayer": "VENDOR" } diff --git a/packages/app-config-writer/test/fixtures/variants-config/simple-app/package.json b/packages/app-config-writer/test/fixtures/variants-config/simple-app/package.json deleted file mode 100644 index 03cbc8457d..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/simple-app/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "simple-app" -} diff --git a/packages/app-config-writer/test/fixtures/variants-config/simple-app/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/simple-app/ui5.yaml deleted file mode 100644 index 6f126496ed..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/simple-app/ui5.yaml +++ /dev/null @@ -1,26 +0,0 @@ -specVersion: '2.4' -metadata: - name: 'simple-app' -type: application -server: - customMiddleware: - - name: fiori-tools-proxy - afterMiddleware: compression - configuration: - ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted - backend: - - path: /sap - url: https://abc.ondemand.example - ui5: - path: - - /resources - - /test-resources - url: https://ui5.sap.com.example - version: 1.91.0 # The UI5 version, for instance, 1.78.1. Empty means latest version - - name: fiori-tools-servestatic - beforeMiddleware: fiori-tools-proxy - configuration: - paths: - - path: /appconfig - src: appconfig - fallthrough: false diff --git a/packages/app-config-writer/test/fixtures/variants-config/simple-app/webapp/manifest.json b/packages/app-config-writer/test/fixtures/variants-config/simple-app/webapp/manifest.json deleted file mode 100644 index 39b8e03593..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/simple-app/webapp/manifest.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "sap.app": { - "id": "simple-app", - "type": "application" - } -} diff --git a/packages/app-config-writer/test/fixtures/variants-config/ui5-local.yaml b/packages/app-config-writer/test/fixtures/variants-config/ui5-local.yaml deleted file mode 100644 index 6fcfebc944..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/ui5-local.yaml +++ /dev/null @@ -1,19 +0,0 @@ -specVersion: "3.1" -metadata: - name: v2lrop0909 -type: application -server: - customMiddleware: - - name: fiori-tools-proxy - afterMiddleware: compression - configuration: - ignoreCertError: false - backend: - - path: /sap - url: https://sap-ux-mock-services-v2-lrop.cfapps.us10.hana.ondemand.com - - name: fiori-tools-preview - afterMiddleware: fiori-tools-appreload - configuration: - component: v2lrop0909 - ui5Theme: sap_horizon -# Test variants-config with a deprecated fiori-tools-preview middleware config and no fiori-tools-appreload diff --git a/packages/app-config-writer/test/fixtures/variants-config/ui5-mock.yaml b/packages/app-config-writer/test/fixtures/variants-config/ui5-mock.yaml deleted file mode 100644 index 4d823d6a68..0000000000 --- a/packages/app-config-writer/test/fixtures/variants-config/ui5-mock.yaml +++ /dev/null @@ -1,21 +0,0 @@ -specVersion: "3.1" -metadata: - name: v2lrop0909 -type: application -server: - customMiddleware: - - name: fiori-tools-proxy - afterMiddleware: compression - configuration: - ignoreCertError: false - ui5: - path: - - /resources - - /test-resources - url: https://ui5.sap.com - backend: - - path: /sap - url: https://sap-ux-mock-services-v2-lrop.cfapps.us10.hana.ondemand.com - - name: fiori-tools-appreload - afterMiddleware: compression -# Test variants-config with no fiori-tools-preview middleware given and no config for fiori-tools-appreload \ No newline at end of file diff --git a/packages/app-config-writer/test/fixtures/variants-config/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/ui5.yaml index d54c072b62..a53716a1b8 100644 --- a/packages/app-config-writer/test/fixtures/variants-config/ui5.yaml +++ b/packages/app-config-writer/test/fixtures/variants-config/ui5.yaml @@ -1,26 +1,21 @@ -specVersion: "3.1" +specVersion: "3.0" metadata: - name: v2lrop0909 + name: fe_lrop_v2 type: application server: customMiddleware: - - name: fiori-tools-proxy + - name: preview-middleware afterMiddleware: compression configuration: - ignoreCertError: false - ui5: - path: - - /resources - - /test-resources - url: https://ui5.sap.com - backend: - - path: /sap - url: https://sap-ux-mock-services-v2-lrop.cfapps.us10.hana.ondemand.com - - name: fiori-tools-appreload - afterMiddleware: compression - configuration: - port: 35729 - path: webapp - - name: fiori-tools-preview - afterMiddleware: compression -# Test variants-config with no fiori-tools-preview middleware config and missing delay for fiori-tools-appreload \ No newline at end of file + flp: + intent: + object: hello + action: world + rta: + layer: VENDOR + editors: + - path: /editor.html + developerMode: true + - path: /my-variants.html + + diff --git a/packages/app-config-writer/test/unit/variants-config/__snapshots__/generateVariantsConfig.test.ts.snap b/packages/app-config-writer/test/unit/variants-config/__snapshots__/generateVariantsConfig.test.ts.snap new file mode 100644 index 0000000000..92fd5e8493 --- /dev/null +++ b/packages/app-config-writer/test/unit/variants-config/__snapshots__/generateVariantsConfig.test.ts.snap @@ -0,0 +1,35 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`generateVariantsConfig add variants configuration to a project 1`] = ` +Object { + "name": "test-app", + "sapux": true, + "sapuxLayer": "VENDOR", + "scripts": Object { + "start-variants-management": "fiori run --open \\"/my-variants.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true#hello-world\\"", + }, +} +`; + +exports[`generateVariantsConfig add variants configuration to a project 2`] = ` +"specVersion: \\"3.0\\" +metadata: + name: fe_lrop_v2 +type: application +server: + customMiddleware: + - name: preview-middleware + afterMiddleware: compression + configuration: + flp: + intent: + object: hello + action: world + rta: + layer: VENDOR + editors: + - path: /editor.html + developerMode: true + - path: /my-variants.html +" +`; diff --git a/packages/app-config-writer/test/unit/variants-config/__snapshots__/index.test.ts.snap b/packages/app-config-writer/test/unit/variants-config/__snapshots__/index.test.ts.snap deleted file mode 100644 index be293fb8dd..0000000000 --- a/packages/app-config-writer/test/unit/variants-config/__snapshots__/index.test.ts.snap +++ /dev/null @@ -1,33 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Test generateVariantsConfig() Add config to the project 1`] = ` -"specVersion: '2.4' -metadata: - name: 'simple-app' -type: application -server: - customMiddleware: - - name: fiori-tools-proxy - afterMiddleware: compression - configuration: - ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted - backend: - - path: /sap - url: https://abc.ondemand.example - ui5: - path: - - /resources - - /test-resources - url: https://ui5.sap.com.example - version: 1.91.0 # The UI5 version, for instance, 1.78.1. Empty means latest version - - name: fiori-tools-servestatic - beforeMiddleware: fiori-tools-proxy - configuration: - paths: - - path: /appconfig - src: appconfig - fallthrough: false - - name: fiori-tools-preview - afterMiddleware: compression -" -`; diff --git a/packages/app-config-writer/test/unit/variants-config/__snapshots__/package-json.test.ts.snap b/packages/app-config-writer/test/unit/variants-config/__snapshots__/package-json.test.ts.snap new file mode 100644 index 0000000000..9d746a173c --- /dev/null +++ b/packages/app-config-writer/test/unit/variants-config/__snapshots__/package-json.test.ts.snap @@ -0,0 +1,14 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`addVariantsManagementScript add start-variants-management script to package.json 1`] = ` +Object { + "description": "An SAP Fiori application.", + "name": "test-app", + "sapux": true, + "sapuxLayer": "VENDOR", + "scripts": Object { + "start": "fiori run --open \\"test/flpSandbox.html?sap-client=500#test-app\\"", + "start-variants-management": "fiori run --open \\"/preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true&sap-client=500#app-preview\\"", + }, +} +`; diff --git a/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap b/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap index be02767358..ded3ca7b81 100644 --- a/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap +++ b/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap @@ -1,70 +1,45 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Test update middleware ui5.yaml - add fiori-tools-preview 1`] = ` -"specVersion: '2.4' +exports[`Test update middleware add preview and reload middleware config to ui5.yaml file 1`] = ` +"specVersion: \\"3.0\\" metadata: - name: 'simple-app' + name: fe_lrop_v2 type: application server: customMiddleware: - - name: fiori-tools-proxy + - name: fiori-tools-appreload afterMiddleware: compression configuration: - ignoreCertError: false # If set to true, certificate errors will be ignored. E.g. self-signed certificates will be accepted - backend: - - path: /sap - url: https://abc.ondemand.example - ui5: - path: - - /resources - - /test-resources - url: https://ui5.sap.com.example - version: 1.91.0 # The UI5 version, for instance, 1.78.1. Empty means latest version - - name: fiori-tools-servestatic - beforeMiddleware: fiori-tools-proxy + delay: 300 + - name: preview-middleware + afterMiddleware: fiori-tools-appreload configuration: - paths: - - path: /appconfig - src: appconfig - fallthrough: false - - name: fiori-tools-preview - afterMiddleware: compression + flp: + intent: + object: hello + action: world " `; -exports[`Test update middleware ui5.yaml - do nothing when fiori-tools-preview is present 1`] = ` -"specVersion: '2.4' +exports[`Test update middleware add preview middleware config to ui5.yaml file 1`] = ` +"specVersion: \\"3.0\\" metadata: - name: 'app-client' + name: fe_lrop_v2 type: application server: customMiddleware: - - name: fiori-tools-servestatic - beforeMiddleware: fiori-tools-proxy - configuration: - paths: - - path: /appconfig - src: appconfig - fallthrough: false - - name: fiori-tools-preview + - name: preview-middleware afterMiddleware: compression configuration: - ui5Theme: sap_horizon -" -`; - -exports[`Test update middleware ui5-mock.yaml - add fiori-tools-appreload 1`] = ` -"specVersion: \\"2.4\\" -metadata: - name: app-with-reload-middleware -type: application -server: - customMiddleware: - - name: fiori-tools-appreload - afterMiddleware: fiori-tools-appreload - configuration: - delay: 300 - - name: fiori-tools-preview - afterMiddleware: fiori-tools-appreload + flp: + intent: + object: hello + action: world + rta: + layer: VENDOR + editors: + - path: /editor.html + developerMode: true + - path: /my-variants.html " `; diff --git a/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts b/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts new file mode 100644 index 0000000000..c92a78ca42 --- /dev/null +++ b/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts @@ -0,0 +1,12 @@ +import { join } from 'path'; +import { generateVariantsConfig } from '../../../src'; + +describe('generateVariantsConfig', () => { + const basePath = join(__dirname, '../../fixtures/variants-config'); + + test('add variants configuration to a project', async () => { + const fs = await generateVariantsConfig(basePath); + expect(fs.readJSON(join(basePath, 'package.json'))).toMatchSnapshot(); + expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); + }); +}); diff --git a/packages/app-config-writer/test/unit/variants-config/index.test.ts b/packages/app-config-writer/test/unit/variants-config/index.test.ts deleted file mode 100644 index 2e067a5875..0000000000 --- a/packages/app-config-writer/test/unit/variants-config/index.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { join } from 'path'; -import { generateVariantsConfig } from '../../../src'; - -describe('Test generateVariantsConfig()', () => { - test('Add config to the project', async () => { - const basePath = join(__dirname, '../../fixtures/variants-config/simple-app'); - const fs = await generateVariantsConfig(basePath); - - expect(fs.readJSON(join(basePath, 'package.json'))).toEqual({ - 'name': 'simple-app', - 'scripts': { - 'start-variants-management': `fiori run --open \"preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true#app-preview\"` - } - }); - expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); - }); -}); diff --git a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts index 4087eaef3e..eb84766fed 100644 --- a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts @@ -1,49 +1,32 @@ +import { addVariantsManagementScript } from '../../../src/variants-config/package-json'; import { join } from 'path'; +import { create as createFS } from 'mem-fs-editor'; import { create as createStorage } from 'mem-fs'; -import type { Editor } from 'mem-fs-editor'; -import { create, create as createFS } from 'mem-fs-editor'; -import { addVariantsManagementScript } from '../../../src/variants-config/package-json'; import { ToolsLogger } from '@sap-ux/logger'; +import type { Editor } from 'mem-fs-editor'; -describe('Test for adding start-variants-management script in package.json', () => { - const logger = new ToolsLogger(); +describe('addVariantsManagementScript', () => { let fs: Editor; + const logger = new ToolsLogger(); const warnLogMock = jest.spyOn(ToolsLogger.prototype, 'warn').mockImplementation(() => {}); const debugLogMock = jest.spyOn(ToolsLogger.prototype, 'debug').mockImplementation(() => {}); + const basePath = join(__dirname, '../../fixtures/variants-config'); + beforeEach(() => { jest.clearAllMocks(); fs = createFS(createStorage()); }); - test('Add new start-variants-management script to package.json and keep the existing one', async () => { - const basePath = join(__dirname, '../../fixtures/variants-config/app-with-client-in-script'); - await addVariantsManagementScript(fs, basePath, logger); - expect(fs.readJSON(join(basePath, 'package.json'))).toEqual({ - 'name': 'app-client', - 'scripts': { - 'start': 'fiori run --open "test/flpSandbox.html?sap-client=100&sap-ui-xx-viewCache=false#test-tile"', - 'start-variants-management': `fiori run --open \"preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true&sap-client=100#app-preview\"` - } - }); - expect(debugLogMock).toHaveBeenCalledWith(`Script 'start-variants-management' written to 'package.json'.`); - }); + test('add start-variants-management script to package.json', async () => { + const fioriToolsConfig = join(basePath, 'fiori-tools-config'); + await addVariantsManagementScript(fs, fioriToolsConfig, logger); - test('No sap client present in script', async () => { - const basePath = join(__dirname, '../../fixtures/variants-config/simple-app/'); - interface PackageJson { - scripts?: { - [key: string]: string; - }; - } - await addVariantsManagementScript(fs, basePath, logger); - const script = fs.readJSON(join(basePath, 'package.json')) as PackageJson; - expect(script?.scripts?.['start-variants-management']?.includes('sap-client=100')).toEqual(false); expect(debugLogMock).toHaveBeenCalledWith(`Script 'start-variants-management' written to 'package.json'.`); + expect(fs.readJSON(join(fioriToolsConfig, 'package.json'))).toMatchSnapshot(); }); - test('Add script to package.json when there is no script', async () => { - const basePath = join(__dirname, '../../fixtures/variants-config/simple-app/'); + test('add script to package.json when there is no script section', async () => { await addVariantsManagementScript(fs, basePath, logger); expect(warnLogMock).toHaveBeenCalledWith( `File 'package.json' does not contain a script section. Script section added.` @@ -51,11 +34,20 @@ describe('Test for adding start-variants-management script in package.json', () expect(debugLogMock).toHaveBeenCalledWith(`Script 'start-variants-management' written to 'package.json'.`); }); - test('No script inserted to package.json when there is already a script', async () => { - const basePath = join(__dirname, '../../fixtures/variants-config/deprecated-config/'); - await addVariantsManagementScript(fs, basePath, logger); + test('add no script to package.json when there is already a script', async () => { + const deprecatedConfig = join(basePath, 'deprecated-config'); + await addVariantsManagementScript(fs, deprecatedConfig, logger); + expect(warnLogMock).toHaveBeenCalledWith( `Script 'start-variants-management' cannot be written to 'package.json. Script already exists'.` ); }); + + test('add no script to package.json when there is no RTA editor', async () => { + const openSourceConfig = join(basePath, 'open-source-config'); + await addVariantsManagementScript(fs, openSourceConfig, logger); + expect(warnLogMock).toHaveBeenCalledWith( + `Script 'start-variants-management' cannot be written to 'package.json. No RTA editor specified in ui5.yaml.` + ); + }); }); diff --git a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts index 46247f2619..05d705a43c 100644 --- a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts @@ -17,39 +17,44 @@ describe('Test update middleware', () => { const logger = new ToolsLogger(); let fs: Editor; const debugLogMock = jest.spyOn(ToolsLogger.prototype, 'debug').mockImplementation(() => {}); + const basePath = join(__dirname, '../../fixtures/variants-config'); beforeEach(() => { jest.clearAllMocks(); fs = create(createStorage()); }); - test('ui5.yaml - add fiori-tools-preview', async () => { - const basePath = join(__dirname, '../../fixtures/variants-config/simple-app/'); + test('add preview middleware config to ui5.yaml file', async () => { await updateMiddlewares(fs, basePath, logger); + expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); - expect(debugLogMock).toHaveBeenCalledTimes(3); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5.yaml')); expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-mock.yaml')); expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-local.yaml')); }); - test('ui5.yaml - do nothing when fiori-tools-preview is present', async () => { - const basePath = join(__dirname, '../../fixtures/variants-config/app-with-client-in-script/'); - await updateMiddlewares(fs, basePath, logger); - expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); - expect(debugLogMock).toHaveBeenCalledTimes(3); + test('add preview and reload middleware config to ui5.yaml file', async () => { + const openSourceConfig = join(basePath, 'open-source-config'); + await updateMiddlewares(fs, openSourceConfig, logger); + + expect(fs.read(join(openSourceConfig, 'ui5.yaml'))).toMatchSnapshot(); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('reload', 'ui5.yaml')); expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-mock.yaml')); expect(debugLogMock).toHaveBeenCalledWith(noFileMessage('ui5-local.yaml')); }); - test('ui5-mock.yaml - add fiori-tools-appreload', async () => { - const basePath = join(__dirname, '../../fixtures/variants-config/app-with-reload-middleware/'); - await updateMiddlewares(fs, basePath, logger); - expect(fs.read(join(basePath, 'ui5-mock.yaml'))).toMatchSnapshot(); - expect(debugLogMock).toHaveBeenCalledTimes(4); + test('add preview and reload middleware to local ui5.yaml files', async () => { + const fioriToolsConfig = join(basePath, 'fiori-tools-config'); + await updateMiddlewares(fs, fioriToolsConfig, logger); + + expect(debugLogMock).toHaveBeenCalledTimes(6); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5.yaml')); - expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('reload', 'ui5-mock.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5-local.yaml')); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', 'ui5-mock.yaml')); + + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('reload', 'ui5.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('reload', 'ui5-local.yaml')); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('reload', 'ui5-mock.yaml')); }); }); diff --git a/packages/app-config-writer/test/unit/variants-config/utils.test.ts b/packages/app-config-writer/test/unit/variants-config/utils.test.ts index cdaa9960ea..a2dc12d4fc 100644 --- a/packages/app-config-writer/test/unit/variants-config/utils.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/utils.test.ts @@ -15,33 +15,61 @@ describe('utils', () => { ).toStrictEqual('000'); }); }); - describe('getUi5UrlParameters', () => { + + describe('getUI5UrlParameters', () => { test('defaults', () => { - expect(utils.getUi5UrlParameters()).toStrictEqual( + expect(utils.getUI5UrlParameters()).toStrictEqual( 'fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true' ); }); test('parameters overwrite with sap-client', () => { - expect(utils.getUi5UrlParameters({ 'sap-client': '500' })).toStrictEqual( + expect(utils.getUI5UrlParameters({ 'sap-client': '500' })).toStrictEqual( 'fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true&sap-client=500' ); }); }); - describe('getPreviewUrl', () => { + + describe('getRTAUrl', () => { const query = 'fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true'; - const path = join(__dirname, '../../fixtures/variants-config'); + const basePath = join(__dirname, '../../fixtures/variants-config'); - test('defaults', async () => { - expect(await utils.getPreviewUrl(path, query)).toStrictEqual( - 'preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true#app-preview' - ); + test('given rta mount point in preview-middleware config', async () => { + const url = await utils.getRTAUrl(basePath, query); + + //check for rta mount point defined in ui5.yaml + expect(url).toContain('/my-variants.html'); + //check for flp intent defined in ui5.yaml + expect(url).toContain('#hello-world'); + expect(url).toContain(query); }); - test('deprecated config', async () => { - expect(await utils.getPreviewUrl(join(path, 'deprecated-config'), query)).toStrictEqual( - 'preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true#preview-app' + test('fiori-tools-preview defaults', async () => { + const fioriToolsConfig = join(basePath, 'fiori-tools-config'); + const url = await utils.getRTAUrl(fioriToolsConfig, query); + + expect(url).toStrictEqual( + '/preview.html?fiori-tools-rta-mode=true&sap-ui-rta-skip-flex-validation=true&sap-ui-xx-condense-changes=true#app-preview' ); }); + + test('fiori-tools-preview deprecated config', async () => { + const deprecatedConfig = join(basePath, 'deprecated-config'); + const url = await utils.getRTAUrl(deprecatedConfig, query); + + //check for fiori-tools default mount point provided over the ux-ui5-tooling + expect(url).toContain('/preview.html'); + //check for fiori-tools default intent provided over the ux-ui5-tooling + expect(url).toContain('#preview-app'); + expect(url).toContain(query); + }); + + test('open-source preview-middleware config with no rta mount point', async () => { + const openSourceConfig = join(basePath, 'open-source-config'); + const url = await utils.getRTAUrl(openSourceConfig, query); + + //check for fiori-tools default mount point provided over the ux-ui5-tooling + expect(url).toBe(undefined); + }); }); }); From 56e224b2a7585545403b4650c935783b70b242a4 Mon Sep 17 00:00:00 2001 From: D048415 Date: Tue, 8 Oct 2024 10:52:50 +0200 Subject: [PATCH 20/37] refactoring --- .../src/variants-config/package-json.ts | 2 +- .../src/variants-config/utils.ts | 34 ++++++++----------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index e325118648..c00bcb6716 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -30,7 +30,7 @@ export async function addVariantsManagementScript(fs: Editor, basePath: string, } const query = getUI5UrlParameters(urlParameters); - const url = await getRTAUrl(basePath, query, logger); + const url = await getRTAUrl(basePath, query); if (url) { packageJson.scripts['start-variants-management'] = `fiori run --open "${url}"`; diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index b73795a384..28d6b3093a 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -4,7 +4,6 @@ import { stringify } from 'querystring'; import type { Package } from '@sap-ux/project-access'; import type { CustomMiddleware } from '@sap-ux/ui5-config'; import type { PreviewConfigOptions, FioriToolsDeprecatedPreviewConfig } from '../types'; -import { ToolsLogger } from '@sap-ux/logger'; /** * Gets the preview middleware form the ui5.yaml file. @@ -68,60 +67,55 @@ export function getUI5UrlParameters(overwritingParams: Record = /** * Returns the RTA mount point of the preview middleware configuration from the ui5.yaml file, if given. * - * @param previewMiddleware - configuration of the preview middleware + * @param previewMiddlewareConfig - configuration of the preview middleware * @returns - RTA mount point or undefined */ function getRTAMountPoint(previewMiddlewareConfig: PreviewConfigOptions | undefined): string | undefined { if (!isFioriToolsDeprecatedPreviewConfig(previewMiddlewareConfig) && previewMiddlewareConfig?.rta?.editors) { const editors = previewMiddlewareConfig.rta.editors; for (const editor of editors) { - if ('developerMode' in editor === false) { + if (!('developerMode' in editor)) { return editor.path; } } - } else { - return undefined; } + return undefined; } /** * Returns the intent of the preview middleware configuration from the ui5.yaml file, if given. * - * @param previewMiddleware - configuration of the preview middleware + * @param previewMiddlewareConfig - configuration of the preview middleware * @returns - preview intent or undefined */ function getRTAIntent(previewMiddlewareConfig: PreviewConfigOptions | undefined): string | undefined { if (isFioriToolsDeprecatedPreviewConfig(previewMiddlewareConfig)) { return undefined; - } else { - const intent = previewMiddlewareConfig?.flp?.intent; - return intent ? `#${intent.object}-${intent.action}` : undefined; } + const intent = previewMiddlewareConfig?.flp?.intent; + return intent ? `#${intent.object}-${intent.action}` : undefined; } /** * Returns the url for variants management in RTA mode. - * The url consist of a specified mount point and intent given from the ui5.yaml file as well as parameters for the RTA mode. + * The url consist of a specified mount point and intent given from the ui5.yaml file as well as parameters for the RTA mode. * * @param basePath - path to project root, where package.json and ui5.yaml is located * @param query - query to create fragment - * @param logger - logger * @returns - review url parameters */ -export async function getRTAUrl(basePath: string, query: string, logger?: ToolsLogger): Promise { +export async function getRTAUrl(basePath: string, query: string): Promise { const existingPreviewMiddleware = await getPreviewMiddleware(basePath); if ( existingPreviewMiddleware?.name === MiddlewareConfigs.PreviewMiddleware && !getRTAMountPoint(existingPreviewMiddleware?.configuration) ) { return undefined; - } else { - //ToDo: what about a default mount point for os? Why in tools suite it's preview.html? - const mountPoint = getRTAMountPoint(existingPreviewMiddleware?.configuration) ?? '/preview.html'; - const intent = getRTAIntent(existingPreviewMiddleware?.configuration) ?? '#app-preview'; - - return isFioriToolsDeprecatedPreviewConfig(existingPreviewMiddleware?.configuration) - ? `${mountPoint}?${query}#preview-app` - : `${mountPoint}?${query}${intent}`; } + const mountPoint = getRTAMountPoint(existingPreviewMiddleware?.configuration) ?? '/preview.html'; + const intent = getRTAIntent(existingPreviewMiddleware?.configuration) ?? '#app-preview'; + + return isFioriToolsDeprecatedPreviewConfig(existingPreviewMiddleware?.configuration) + ? `${mountPoint}?${query}#preview-app` + : `${mountPoint}?${query}${intent}`; } From 9412b8775cdfc804131420dce4c944ad64d5bf5c Mon Sep 17 00:00:00 2001 From: D048415 Date: Tue, 8 Oct 2024 12:10:40 +0200 Subject: [PATCH 21/37] minor refactoring --- .../app-config-writer/src/variants-config/ui5-yaml.ts | 8 +++++--- packages/app-config-writer/src/variants-config/utils.ts | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index 5d80b52889..a5425abf0a 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -36,7 +36,6 @@ export function writeMiddlewareToYaml( */ function getPreviewMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware { const previewMiddlewareTemplate = { - // ToDo: How to know the default if there is no preview middleware... name: 'fiori-tools-preview', afterMiddleware: 'compression' } as CustomMiddleware; @@ -50,6 +49,9 @@ function getPreviewMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware< if (existingPreviewMiddleware.configuration) { previewMiddlewareTemplate.configuration = { ...existingPreviewMiddleware.configuration }; } + } else { + //todo: if ux-ui5-tooling dependency does not exists in package.json + // previewMiddlewareTemplate.name = MiddlewareConfigs.PreviewMiddleware } return previewMiddlewareTemplate; @@ -57,10 +59,10 @@ function getPreviewMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware< /** * Gets the reload middleware configuration and sets a delay of 300ms if not given. - * The middleware can either be named fiori-tools-appreload or reload-middleware. + * The middleware can either be named 'fiori-tools-appreload' or 'reload-middleware'. * * @param ui5YamlConfig existing ui5.yaml configurations - * @returns 'fiori-tools-appreload' or reload-middleware configuration + * @returns 'fiori-tools-appreload' or 'reload-middleware' configuration */ function getReloadMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware | undefined { const existingReloadMiddleware = diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index 28d6b3093a..f18f992e69 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -13,6 +13,7 @@ import type { PreviewConfigOptions, FioriToolsDeprecatedPreviewConfig } from '.. * @returns 'fiori-tools-preview' configuration if given */ async function getPreviewMiddleware(basePath: string): Promise | undefined> { + //todo: what to do in case there is not ui5.yaml file? try FileName.Ui5MockYaml or FileName.Ui5LocalYaml as fallback? const existingUi5YamlConfig = await readUi5Yaml(basePath, FileName.Ui5Yaml); return ( existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? From 8125256d07167798e35d5cc95a0e5d8786716cf3 Mon Sep 17 00:00:00 2001 From: D048415 Date: Tue, 8 Oct 2024 12:24:47 +0200 Subject: [PATCH 22/37] refactor addVariantsManagementScript --- .../variants-config/generateVariantsConfig.ts | 5 +- .../src/variants-config/package-json.ts | 47 +++++++++---------- .../unit/variants-config/package-json.test.ts | 11 ++--- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts index 6edbf960ba..75667311bf 100644 --- a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts +++ b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts @@ -17,7 +17,10 @@ export async function generateVariantsConfig(basePath: string, logger?: ToolsLog if (!fs) { fs = create(createStorage()); } - await addVariantsManagementScript(fs, basePath, logger); + await addVariantsManagementScript(fs, basePath, logger).catch((error) => { + logger?.error(`Script 'start-variants-management' cannot be written to package.json. ${error.message}.`); + return fs; + }); await updateMiddlewares(fs, basePath, logger); return fs; } diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index c00bcb6716..bcb4afd61b 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -10,38 +10,37 @@ import type { ToolsLogger } from '@sap-ux/logger'; * @param fs - mem-fs reference to be used for file access * @param basePath - path to application root, where package.json is * @param logger - logger + * @returns Promise - rejects in case variants management script can't be added to package.json */ export async function addVariantsManagementScript(fs: Editor, basePath: string, logger?: ToolsLogger): Promise { const packageJsonPath = join(basePath, 'package.json'); const packageJson = fs.readJSON(packageJsonPath) as Package; - if (!packageJson.scripts || !packageJson.scripts['start-variants-management']) { - const urlParameters: Record = {}; + if (packageJson?.scripts?.['start-variants-management']) { + return Promise.reject(new Error(`Script already exists`)); + } + + const urlParameters: Record = {}; - if (!packageJson.scripts) { - logger?.warn(`File 'package.json' does not contain a script section. Script section added.`); - packageJson.scripts = {}; - } else { - // check if sap-client is needed when starting the app - const sapClient = getSapClientFromPackageJson(packageJson.scripts); - if (sapClient) { - urlParameters['sap-client'] = sapClient; - } + if (!packageJson.scripts) { + logger?.warn(`File 'package.json' does not contain a script section. Script section added.`); + packageJson.scripts = {}; + } else { + // check if sap-client is needed when starting the app + const sapClient = getSapClientFromPackageJson(packageJson.scripts); + if (sapClient) { + urlParameters['sap-client'] = sapClient; } + } - const query = getUI5UrlParameters(urlParameters); - const url = await getRTAUrl(basePath, query); + const url = await getRTAUrl(basePath, getUI5UrlParameters(urlParameters)); - if (url) { - packageJson.scripts['start-variants-management'] = `fiori run --open "${url}"`; - fs.writeJSON(packageJsonPath, packageJson); - logger?.debug(`Script 'start-variants-management' written to 'package.json'.`); - } else { - logger?.warn( - `Script 'start-variants-management' cannot be written to 'package.json. No RTA editor specified in ui5.yaml.` - ); - } - } else { - logger?.warn(`Script 'start-variants-management' cannot be written to 'package.json. Script already exists'.`); + if (!url) { + return Promise.reject(new Error(`No RTA editor specified in ui5.yaml.`)); } + + packageJson.scripts['start-variants-management'] = `fiori run --open "${url}"`; + fs.writeJSON(packageJsonPath, packageJson); + logger?.debug(`Script 'start-variants-management' written to 'package.json'.`); + return Promise.resolve(); } diff --git a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts index eb84766fed..6c940e764a 100644 --- a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts @@ -36,18 +36,15 @@ describe('addVariantsManagementScript', () => { test('add no script to package.json when there is already a script', async () => { const deprecatedConfig = join(basePath, 'deprecated-config'); - await addVariantsManagementScript(fs, deprecatedConfig, logger); - - expect(warnLogMock).toHaveBeenCalledWith( - `Script 'start-variants-management' cannot be written to 'package.json. Script already exists'.` + await expect(addVariantsManagementScript(fs, deprecatedConfig, logger)).rejects.toThrow( + new Error('Script already exists') ); }); test('add no script to package.json when there is no RTA editor', async () => { const openSourceConfig = join(basePath, 'open-source-config'); - await addVariantsManagementScript(fs, openSourceConfig, logger); - expect(warnLogMock).toHaveBeenCalledWith( - `Script 'start-variants-management' cannot be written to 'package.json. No RTA editor specified in ui5.yaml.` + await expect(addVariantsManagementScript(fs, openSourceConfig, logger)).rejects.toThrow( + new Error('No RTA editor specified in ui5.yaml.') ); }); }); From a0ed8d9d95e20e3d8c27a0b3506f549fded25e26 Mon Sep 17 00:00:00 2001 From: D048415 Date: Tue, 8 Oct 2024 12:28:22 +0200 Subject: [PATCH 23/37] tiny refactoring --- packages/app-config-writer/src/variants-config/package-json.ts | 2 +- .../test/unit/variants-config/package-json.test.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index bcb4afd61b..ad00721e25 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -17,7 +17,7 @@ export async function addVariantsManagementScript(fs: Editor, basePath: string, const packageJson = fs.readJSON(packageJsonPath) as Package; if (packageJson?.scripts?.['start-variants-management']) { - return Promise.reject(new Error(`Script already exists`)); + return Promise.reject(new Error(`Script already exists.`)); } const urlParameters: Record = {}; diff --git a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts index 6c940e764a..245da39a2c 100644 --- a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts @@ -37,7 +37,7 @@ describe('addVariantsManagementScript', () => { test('add no script to package.json when there is already a script', async () => { const deprecatedConfig = join(basePath, 'deprecated-config'); await expect(addVariantsManagementScript(fs, deprecatedConfig, logger)).rejects.toThrow( - new Error('Script already exists') + new Error('Script already exists.') ); }); From 4c4b869f13220e9aa1d0522f670ddd6718acbdc3 Mon Sep 17 00:00:00 2001 From: Annemarie Date: Tue, 8 Oct 2024 15:26:51 +0200 Subject: [PATCH 24/37] changeset --- .changeset/little-ties-cry.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/little-ties-cry.md diff --git a/.changeset/little-ties-cry.md b/.changeset/little-ties-cry.md new file mode 100644 index 0000000000..8571ebaa1d --- /dev/null +++ b/.changeset/little-ties-cry.md @@ -0,0 +1,6 @@ +--- +'@sap-ux/app-config-writer': patch +'@sap-ux/create': patch +--- + +Introduce create command to add Configuration for Variants Creation. From 1902cc7070e835e29ea8749d73e3e73bc638ee0e Mon Sep 17 00:00:00 2001 From: Annemarie Date: Tue, 8 Oct 2024 15:35:26 +0200 Subject: [PATCH 25/37] fix: sonar --- packages/app-config-writer/src/variants-config/ui5-yaml.ts | 4 +--- packages/app-config-writer/src/variants-config/utils.ts | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index a5425abf0a..2b5569abd0 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -3,10 +3,8 @@ import { MiddlewareConfigs } from '../types'; import { FileName, readUi5Yaml } from '@sap-ux/project-access'; import type { Editor } from 'mem-fs-editor'; import type { ToolsLogger } from '@sap-ux/logger'; -import type { UI5Config } from '@sap-ux/ui5-config'; -import type { CustomMiddleware } from '@sap-ux/ui5-config'; -import type { FioriAppReloadConfig } from '@sap-ux/ui5-config'; import type { PreviewConfigOptions } from '../types'; +import type { CustomMiddleware, FioriAppReloadConfig, UI5Config } from '@sap-ux/ui5-config'; /** * Writes the given middleware to a ui5.yaml file. diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index f18f992e69..067ef1927c 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -41,7 +41,7 @@ function isFioriToolsDeprecatedPreviewConfig( */ export function getSapClientFromPackageJson(scripts: Package['scripts']): string | undefined { for (const value of Object.values(scripts!)) { - const match = value?.match(/sap-client=([0-9]{3})/); + const match = value?.match(/sap-client=(\d{3})/); if (match) { return match[1]; } From 974f32ce0c0ae3ce276ba4fe6f3a6a00f8993511 Mon Sep 17 00:00:00 2001 From: D048415 Date: Tue, 8 Oct 2024 17:50:39 +0200 Subject: [PATCH 26/37] add unit test --- .../src/variants-config/package-json.ts | 6 +++++- .../variants-config/generateVariantsConfig.test.ts | 14 ++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index ad00721e25..8fd324af8c 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -14,7 +14,11 @@ import type { ToolsLogger } from '@sap-ux/logger'; */ export async function addVariantsManagementScript(fs: Editor, basePath: string, logger?: ToolsLogger): Promise { const packageJsonPath = join(basePath, 'package.json'); - const packageJson = fs.readJSON(packageJsonPath) as Package; + const packageJson = fs.readJSON(packageJsonPath) as Package | undefined; + + if (!packageJson) { + return Promise.reject(new Error(`File 'package.json' not found at ${basePath}`)); + } if (packageJson?.scripts?.['start-variants-management']) { return Promise.reject(new Error(`Script already exists.`)); diff --git a/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts b/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts index c92a78ca42..ada3adf2e4 100644 --- a/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts @@ -1,12 +1,26 @@ import { join } from 'path'; import { generateVariantsConfig } from '../../../src'; +import { ToolsLogger } from '@sap-ux/logger'; describe('generateVariantsConfig', () => { const basePath = join(__dirname, '../../fixtures/variants-config'); + beforeEach(() => { + jest.clearAllMocks(); + }); + test('add variants configuration to a project', async () => { const fs = await generateVariantsConfig(basePath); expect(fs.readJSON(join(basePath, 'package.json'))).toMatchSnapshot(); expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); }); + + test('adding variants configuration to a non existing project', async () => { + const errorLogMock = jest.spyOn(ToolsLogger.prototype, 'error').mockImplementation(() => {}); + const basePath = join(__dirname, '../../fixtures/a-folder-that-does-not-exist'); + const fs = await generateVariantsConfig(basePath, new ToolsLogger()); + expect(errorLogMock).toHaveBeenCalledWith( + `Script 'start-variants-management' cannot be written to package.json. File 'package.json' not found at ${basePath}.` + ); + }); }); From 505535551c39f14c345d39ac4a60d27dc89dcdef Mon Sep 17 00:00:00 2001 From: D048415 Date: Wed, 9 Oct 2024 09:34:33 +0200 Subject: [PATCH 27/37] minor refactoring --- .../src/variants-config/package-json.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index 8fd324af8c..495d00a91e 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -24,17 +24,15 @@ export async function addVariantsManagementScript(fs: Editor, basePath: string, return Promise.reject(new Error(`Script already exists.`)); } - const urlParameters: Record = {}; - if (!packageJson.scripts) { logger?.warn(`File 'package.json' does not contain a script section. Script section added.`); packageJson.scripts = {}; - } else { - // check if sap-client is needed when starting the app - const sapClient = getSapClientFromPackageJson(packageJson.scripts); - if (sapClient) { - urlParameters['sap-client'] = sapClient; - } + } + + const urlParameters: Record = {}; + const sapClient = getSapClientFromPackageJson(packageJson.scripts); + if (sapClient) { + urlParameters['sap-client'] = sapClient; } const url = await getRTAUrl(basePath, getUI5UrlParameters(urlParameters)); From f74c5f91d4845dee89efb20813487690fce5ec4c Mon Sep 17 00:00:00 2001 From: D048415 Date: Wed, 9 Oct 2024 15:57:45 +0200 Subject: [PATCH 28/37] adjust types --- packages/app-config-writer/src/types/variantsConfig.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/app-config-writer/src/types/variantsConfig.ts b/packages/app-config-writer/src/types/variantsConfig.ts index 281e694783..60305835ff 100644 --- a/packages/app-config-writer/src/types/variantsConfig.ts +++ b/packages/app-config-writer/src/types/variantsConfig.ts @@ -1,11 +1,11 @@ -import type { MiddlewareConfig } from '@sap-ux/preview-middleware'; +import type { MiddlewareConfig as PreviewConfig } from '@sap-ux/preview-middleware'; export type FioriToolsDeprecatedPreviewConfig = { component: string; libs?: boolean; ui5Theme?: string; }; -export type PreviewConfig = MiddlewareConfig; + export type PreviewConfigOptions = FioriToolsDeprecatedPreviewConfig | PreviewConfig; export enum MiddlewareConfigs { From 1adaa49a7c1b15022eea28ad7c819251d7816228 Mon Sep 17 00:00:00 2001 From: D048415 Date: Thu, 10 Oct 2024 12:56:50 +0200 Subject: [PATCH 29/37] fix test data error --- .../test/fixtures/variants-config/open-source-config/ui5.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/app-config-writer/test/fixtures/variants-config/open-source-config/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/open-source-config/ui5.yaml index 4e2c4ea7e9..8639a35445 100644 --- a/packages/app-config-writer/test/fixtures/variants-config/open-source-config/ui5.yaml +++ b/packages/app-config-writer/test/fixtures/variants-config/open-source-config/ui5.yaml @@ -7,6 +7,7 @@ server: - name: fiori-tools-appreload afterMiddleware: compression - name: preview-middleware + afterMiddleware: compression configuration: flp: intent: From c4f8e10e2b06e6ac835a3b2cbf5ff95299fd5568 Mon Sep 17 00:00:00 2001 From: D048415 Date: Thu, 10 Oct 2024 13:15:17 +0200 Subject: [PATCH 30/37] enhance jsDoc of readUi5Yaml --- packages/project-access/src/project/ui5-config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/project-access/src/project/ui5-config.ts b/packages/project-access/src/project/ui5-config.ts index 3d716d2d62..5e2d0ac3c7 100644 --- a/packages/project-access/src/project/ui5-config.ts +++ b/packages/project-access/src/project/ui5-config.ts @@ -32,6 +32,7 @@ export async function getWebappPath(projectRoot: string, memFs?: Editor): Promis * @param fileName - name of yaml file to be read * @param [memFs] - optional mem-fs editor instance * @returns {UI5Config} UI5 config file in yaml format + * @throws {Error} if file is not found */ export async function readUi5Yaml(projectRoot: string, fileName: string, memFs?: Editor): Promise { const ui5YamlPath = join(projectRoot, fileName); From 28efeff5d99f19b71c87bbc5b7e7dfea8dc9299a Mon Sep 17 00:00:00 2001 From: D048415 Date: Thu, 10 Oct 2024 14:07:41 +0200 Subject: [PATCH 31/37] refactoring --- .../src/variants-config/ui5-yaml.ts | 116 ++++++++---------- .../src/variants-config/utils.ts | 49 +++++--- .../unit/variants-config/ui5-yaml.test.ts | 16 +-- 3 files changed, 89 insertions(+), 92 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index 2b5569abd0..74a0bb2fbb 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -1,79 +1,51 @@ import { join } from 'path'; import { MiddlewareConfigs } from '../types'; -import { FileName, readUi5Yaml } from '@sap-ux/project-access'; +import { FileName, type Package, readUi5Yaml } from '@sap-ux/project-access'; import type { Editor } from 'mem-fs-editor'; import type { ToolsLogger } from '@sap-ux/logger'; import type { PreviewConfigOptions } from '../types'; import type { CustomMiddleware, FioriAppReloadConfig, UI5Config } from '@sap-ux/ui5-config'; +import { getPreviewMiddleware } from './utils'; /** - * Writes the given middleware to a ui5.yaml file. + * Gets the reload middleware form the provided yamlConfig. + * The middleware can either be named 'fiori-tools-appreload' or 'reload-middleware'. + * If the middleware is found, a delay of 300ms will be inserted. * - * @param fs - mem-fs reference to be used for file access - * @param path - path to the ui5.yaml file - * @param content - middleware configuration to be written - * @param ui5YamlConfig - existing ui5.yaml configuration + * @param yamlConfig - the yaml configuration to use + * @returns reload middleware configuration if found or undefined */ -export function writeMiddlewareToYaml( - fs: Editor, - path: string, - content: CustomMiddleware, - ui5YamlConfig: UI5Config -): void { - const middlewareConfig = ui5YamlConfig.updateCustomMiddleware(content); - fs.write(path, middlewareConfig.toString()); +export async function getEnhancedReloadMiddleware( + yamlConfig: UI5Config +): Promise | undefined> { + const reloadMiddleware = + yamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsAppreload) ?? + yamlConfig.findCustomMiddleware(MiddlewareConfigs.ReloadMiddleware); + if (!reloadMiddleware) { + return undefined; + } + if (!reloadMiddleware?.configuration?.delay) { + reloadMiddleware.configuration = { ...reloadMiddleware.configuration, delay: 300 }; + } + return reloadMiddleware; } /** - * Gets the preview middleware configuration form the ui5.yaml. - * The middleware can either be named fiori-tools-preview or preview-middleware. - * If no preview configuration is given, then one will be created. + * Creates a preview middleware configuration based on the presence of the @sap/ux-ui5-tooling dependency. * - * @param ui5YamlConfig existing ui5.yaml configurations + * @param fs - mem-fs reference to be used for file access + * @param basePath - path to project root, where package.json and ui5.yaml is * @returns 'fiori-tools-preview' or 'preview-middleware' configuration */ -function getPreviewMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware { - const previewMiddlewareTemplate = { - name: 'fiori-tools-preview', +export function createPreviewMiddlewareConfig(fs: Editor, basePath: string): CustomMiddleware { + const packageJsonPath = join(basePath, 'package.json'); + const packageJson = fs.readJSON(packageJsonPath) as Package | undefined; + return { + name: packageJson?.devDependencies?.['@sap/ux-ui5-tooling'] + ? MiddlewareConfigs.FioriToolsPreview + : MiddlewareConfigs.PreviewMiddleware, afterMiddleware: 'compression' } as CustomMiddleware; - - const existingPreviewMiddleware = - ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? - ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.PreviewMiddleware); - - if (existingPreviewMiddleware) { - previewMiddlewareTemplate.name = existingPreviewMiddleware.name; - if (existingPreviewMiddleware.configuration) { - previewMiddlewareTemplate.configuration = { ...existingPreviewMiddleware.configuration }; - } - } else { - //todo: if ux-ui5-tooling dependency does not exists in package.json - // previewMiddlewareTemplate.name = MiddlewareConfigs.PreviewMiddleware - } - - return previewMiddlewareTemplate; -} - -/** - * Gets the reload middleware configuration and sets a delay of 300ms if not given. - * The middleware can either be named 'fiori-tools-appreload' or 'reload-middleware'. - * - * @param ui5YamlConfig existing ui5.yaml configurations - * @returns 'fiori-tools-appreload' or 'reload-middleware' configuration - */ -function getReloadMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware | undefined { - const existingReloadMiddleware = - ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsAppreload) ?? - ui5YamlConfig.findCustomMiddleware(MiddlewareConfigs.ReloadMiddleware); - - if (!existingReloadMiddleware) { - return undefined; - } - if (!existingReloadMiddleware?.configuration?.delay) { - existingReloadMiddleware.configuration = { ...existingReloadMiddleware.configuration, delay: 300 }; - } - return existingReloadMiddleware; } /** @@ -87,25 +59,33 @@ function getReloadMiddlewareConfig(ui5YamlConfig: UI5Config): CustomMiddleware { const ui5Yamls = [FileName.Ui5Yaml, FileName.Ui5MockYaml, FileName.Ui5LocalYaml]; for (const ui5Yaml of ui5Yamls) { - let existingUi5YamlConfig: UI5Config; - const yamlPath = join(basePath, ui5Yaml); + let ui5YamlConfig: UI5Config; + try { - existingUi5YamlConfig = await readUi5Yaml(basePath, ui5Yaml); + ui5YamlConfig = await readUi5Yaml(basePath, ui5Yaml); } catch (error) { - logger?.debug(`Cannot write variants-config to ${ui5Yaml}. File not existing`); + logger?.debug((error as Error).message); continue; } - const previewMiddlewareConfig = getPreviewMiddlewareConfig(existingUi5YamlConfig); - const reloadMiddlewareConfig = getReloadMiddlewareConfig(existingUi5YamlConfig); + let previewMiddleware = await getPreviewMiddleware(ui5YamlConfig); - if (reloadMiddlewareConfig) { - previewMiddlewareConfig.afterMiddleware = reloadMiddlewareConfig.name; - writeMiddlewareToYaml(fs, yamlPath, reloadMiddlewareConfig, existingUi5YamlConfig); + if (!previewMiddleware) { + logger?.warn(`No preview middleware found in ${ui5Yaml}. Preview middleware will be added.`); + previewMiddleware = createPreviewMiddlewareConfig(fs, basePath); + } + + const reloadMiddleware = await getEnhancedReloadMiddleware(ui5YamlConfig); + + if (reloadMiddleware) { + previewMiddleware.afterMiddleware = reloadMiddleware.name; + ui5YamlConfig.updateCustomMiddleware(reloadMiddleware); logger?.debug(`Updated reload middleware in ${ui5Yaml}.`); } - writeMiddlewareToYaml(fs, yamlPath, previewMiddlewareConfig, existingUi5YamlConfig); + ui5YamlConfig.updateCustomMiddleware(previewMiddleware); + const yamlPath = join(basePath, ui5Yaml); + fs.write(yamlPath, ui5YamlConfig.toString()); logger?.debug(`Updated preview middleware in ${ui5Yaml}.`); } } diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index 067ef1927c..3a7af6628b 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -2,22 +2,32 @@ import { FileName, readUi5Yaml } from '@sap-ux/project-access'; import { MiddlewareConfigs } from '../types'; import { stringify } from 'querystring'; import type { Package } from '@sap-ux/project-access'; -import type { CustomMiddleware } from '@sap-ux/ui5-config'; +import type { CustomMiddleware, UI5Config } from '@sap-ux/ui5-config'; import type { PreviewConfigOptions, FioriToolsDeprecatedPreviewConfig } from '../types'; /** - * Gets the preview middleware form the ui5.yaml file. - * The middleware can either be named fiori-tools-preview or preview-middleware. + * Gets the preview middleware form the yamlConfig or provided path. + * The middleware can either be named 'fiori-tools-preview' or 'preview-middleware'. * - * @param basePath - path to project root, where package.json and ui5.yaml is - * @returns 'fiori-tools-preview' configuration if given + * @param yamlConfig - the yaml configuration to use; if not provided, the file will be read with the provided basePath and filename + * @param basePath - path to project root, where ui5.yaml is located + * @param filename - name of the ui5 yaml file to read from basePath; default is 'ui5.yaml' + * @returns preview middleware configuration if found or undefined + * @throws {Error} if filename is not found at basePath + * @throws {Error} if basePath and yamlConfig are undefined */ -async function getPreviewMiddleware(basePath: string): Promise | undefined> { - //todo: what to do in case there is not ui5.yaml file? try FileName.Ui5MockYaml or FileName.Ui5LocalYaml as fallback? - const existingUi5YamlConfig = await readUi5Yaml(basePath, FileName.Ui5Yaml); +export async function getPreviewMiddleware( + yamlConfig?: UI5Config, + basePath?: string, + filename: string = FileName.Ui5Yaml +): Promise | undefined> { + if (!basePath && !yamlConfig) { + throw new Error('Either base path or yaml config must be provided'); + } + yamlConfig = yamlConfig ?? (await readUi5Yaml(basePath!, filename)); return ( - existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? - existingUi5YamlConfig.findCustomMiddleware(MiddlewareConfigs.PreviewMiddleware) + yamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? + yamlConfig.findCustomMiddleware(MiddlewareConfigs.PreviewMiddleware) ); } @@ -106,17 +116,24 @@ function getRTAIntent(previewMiddlewareConfig: PreviewConfigOptions | undefined) * @returns - review url parameters */ export async function getRTAUrl(basePath: string, query: string): Promise { - const existingPreviewMiddleware = await getPreviewMiddleware(basePath); + let previewMiddleware: CustomMiddleware | undefined; + try { + previewMiddleware = await getPreviewMiddleware(undefined, basePath); + } catch (error) { + //todo: what to do in case there is no ui5.yaml file? try FileName.Ui5MockYaml or FileName.Ui5LocalYaml as fallback? + return undefined; + } + if ( - existingPreviewMiddleware?.name === MiddlewareConfigs.PreviewMiddleware && - !getRTAMountPoint(existingPreviewMiddleware?.configuration) + previewMiddleware?.name === MiddlewareConfigs.PreviewMiddleware && + !getRTAMountPoint(previewMiddleware?.configuration) ) { return undefined; } - const mountPoint = getRTAMountPoint(existingPreviewMiddleware?.configuration) ?? '/preview.html'; - const intent = getRTAIntent(existingPreviewMiddleware?.configuration) ?? '#app-preview'; + const mountPoint = getRTAMountPoint(previewMiddleware?.configuration) ?? '/preview.html'; + const intent = getRTAIntent(previewMiddleware?.configuration) ?? '#app-preview'; - return isFioriToolsDeprecatedPreviewConfig(existingPreviewMiddleware?.configuration) + return isFioriToolsDeprecatedPreviewConfig(previewMiddleware?.configuration) ? `${mountPoint}?${query}#preview-app` : `${mountPoint}?${query}${intent}`; } diff --git a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts index e6d1eb2657..917b38fc61 100644 --- a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts @@ -11,7 +11,7 @@ type YamlFileName = typeof FileName.Ui5MockYaml | typeof FileName.Ui5LocalYaml | const middlewareUpdatedMessage = (middleware: 'preview' | 'reload', filename: YamlFileName) => `Updated ${middleware} middleware in ${filename}.`; -const noFileMessage = (filename: YamlFileName) => `Cannot write variants-config to ${filename}. File not existing`; +const noFileMessage = (filename: YamlFileName, path: string) => `File '${filename}' not found in project '${path}'`; describe('Test update middleware', () => { const logger = new ToolsLogger(); @@ -29,19 +29,19 @@ describe('Test update middleware', () => { expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5Yaml)); - expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5MockYaml)); - expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5LocalYaml)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5MockYaml, basePath)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5LocalYaml, basePath)); }); test('add preview and reload middleware config to ui5.yaml file', async () => { - const openSourceConfig = join(basePath, 'open-source-config'); - await updateMiddlewares(fs, openSourceConfig, logger); + const openSourceConfigPath = join(basePath, 'open-source-config'); + await updateMiddlewares(fs, openSourceConfigPath, logger); - expect(fs.read(join(openSourceConfig, 'ui5.yaml'))).toMatchSnapshot(); + expect(fs.read(join(openSourceConfigPath, 'ui5.yaml'))).toMatchSnapshot(); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5Yaml)); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('reload', FileName.Ui5Yaml)); - expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5MockYaml)); - expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5LocalYaml)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5MockYaml, openSourceConfigPath)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5LocalYaml, openSourceConfigPath)); }); test('add preview and reload middleware to local ui5.yaml files', async () => { From 93b5a14ac99eb7274eba516b0abc64e1f07041cb Mon Sep 17 00:00:00 2001 From: D048415 Date: Thu, 10 Oct 2024 15:10:56 +0200 Subject: [PATCH 32/37] add unit test --- .../no-middleware-config/package.json | 5 +++++ .../variants-config/no-middleware-config/ui5.yaml | 6 ++++++ .../__snapshots__/ui5-yaml.test.ts.snap | 12 ++++++++++++ .../test/unit/variants-config/ui5-yaml.test.ts | 14 ++++++++++++++ 4 files changed, 37 insertions(+) create mode 100644 packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/package.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/ui5.yaml diff --git a/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/package.json b/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/package.json new file mode 100644 index 0000000000..32a726781e --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/package.json @@ -0,0 +1,5 @@ +{ + "name": "test-app", + "sapux": true, + "sapuxLayer": "VENDOR" +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/ui5.yaml new file mode 100644 index 0000000000..600769c2b9 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/ui5.yaml @@ -0,0 +1,6 @@ +specVersion: "3.0" +metadata: + name: fe_lrop_v2 +type: application +server: + customMiddleware: diff --git a/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap b/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap index ded3ca7b81..da95b02342 100644 --- a/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap +++ b/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap @@ -43,3 +43,15 @@ server: - path: /my-variants.html " `; + +exports[`Test update middleware add preview middleware config to ui5.yaml file w/o middlewares 1`] = ` +"specVersion: \\"3.0\\" +metadata: + name: fe_lrop_v2 +type: application +server: + customMiddleware: + - name: preview-middleware + afterMiddleware: compression +" +`; diff --git a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts index 917b38fc61..6f5fa70060 100644 --- a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts @@ -17,6 +17,7 @@ describe('Test update middleware', () => { const logger = new ToolsLogger(); let fs: Editor; const debugLogMock = jest.spyOn(ToolsLogger.prototype, 'debug').mockImplementation(() => {}); + const warnLogMock = jest.spyOn(ToolsLogger.prototype, 'warn').mockImplementation(() => {}); const basePath = join(__dirname, '../../fixtures/variants-config'); beforeEach(() => { @@ -33,6 +34,19 @@ describe('Test update middleware', () => { expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5LocalYaml, basePath)); }); + test('add preview middleware config to ui5.yaml file w/o middlewares', async () => { + const missingMiddlewareConfigPath = join(basePath, 'no-middleware-config'); + await updateMiddlewares(fs, missingMiddlewareConfigPath, logger); + + expect(fs.read(join(missingMiddlewareConfigPath, 'ui5.yaml'))).toMatchSnapshot(); + expect(warnLogMock).toHaveBeenCalledWith( + `No preview middleware found in ${FileName.Ui5Yaml}. Preview middleware will be added.` + ); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5Yaml)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5MockYaml, missingMiddlewareConfigPath)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5LocalYaml, missingMiddlewareConfigPath)); + }); + test('add preview and reload middleware config to ui5.yaml file', async () => { const openSourceConfigPath = join(basePath, 'open-source-config'); await updateMiddlewares(fs, openSourceConfigPath, logger); From c22b0dd281313a4c1699591c6a5712088ddb8524 Mon Sep 17 00:00:00 2001 From: D048415 Date: Thu, 10 Oct 2024 15:16:54 +0200 Subject: [PATCH 33/37] add unit test --- .../no-middleware-config-os/package.json | 5 +++++ .../no-middleware-config-os/ui5.yaml | 6 ++++++ .../no-middleware-config/package.json | 5 ++++- .../__snapshots__/ui5-yaml.test.ts.snap | 14 +++++++++++++- .../test/unit/variants-config/ui5-yaml.test.ts | 15 ++++++++++++++- 5 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 packages/app-config-writer/test/fixtures/variants-config/no-middleware-config-os/package.json create mode 100644 packages/app-config-writer/test/fixtures/variants-config/no-middleware-config-os/ui5.yaml diff --git a/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config-os/package.json b/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config-os/package.json new file mode 100644 index 0000000000..32a726781e --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config-os/package.json @@ -0,0 +1,5 @@ +{ + "name": "test-app", + "sapux": true, + "sapuxLayer": "VENDOR" +} diff --git a/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config-os/ui5.yaml b/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config-os/ui5.yaml new file mode 100644 index 0000000000..600769c2b9 --- /dev/null +++ b/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config-os/ui5.yaml @@ -0,0 +1,6 @@ +specVersion: "3.0" +metadata: + name: fe_lrop_v2 +type: application +server: + customMiddleware: diff --git a/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/package.json b/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/package.json index 32a726781e..23f73beeb8 100644 --- a/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/package.json +++ b/packages/app-config-writer/test/fixtures/variants-config/no-middleware-config/package.json @@ -1,5 +1,8 @@ { "name": "test-app", "sapux": true, - "sapuxLayer": "VENDOR" + "sapuxLayer": "VENDOR", + "devDependencies": { + "@sap/ux-ui5-tooling": "1.15.1" + } } diff --git a/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap b/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap index da95b02342..747d7faabb 100644 --- a/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap +++ b/packages/app-config-writer/test/unit/variants-config/__snapshots__/ui5-yaml.test.ts.snap @@ -1,5 +1,17 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Test update middleware add fiori-tools-preview to ui5.yaml file w/o middlewares 1`] = ` +"specVersion: \\"3.0\\" +metadata: + name: fe_lrop_v2 +type: application +server: + customMiddleware: + - name: fiori-tools-preview + afterMiddleware: compression +" +`; + exports[`Test update middleware add preview and reload middleware config to ui5.yaml file 1`] = ` "specVersion: \\"3.0\\" metadata: @@ -44,7 +56,7 @@ server: " `; -exports[`Test update middleware add preview middleware config to ui5.yaml file w/o middlewares 1`] = ` +exports[`Test update middleware add preview-middleware to ui5.yaml file w/o middlewares 1`] = ` "specVersion: \\"3.0\\" metadata: name: fe_lrop_v2 diff --git a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts index 6f5fa70060..18ac272254 100644 --- a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts @@ -34,7 +34,20 @@ describe('Test update middleware', () => { expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5LocalYaml, basePath)); }); - test('add preview middleware config to ui5.yaml file w/o middlewares', async () => { + test('add preview-middleware to ui5.yaml file w/o middlewares', async () => { + const missingMiddlewareConfigPath = join(basePath, 'no-middleware-config-os'); + await updateMiddlewares(fs, missingMiddlewareConfigPath, logger); + + expect(fs.read(join(missingMiddlewareConfigPath, 'ui5.yaml'))).toMatchSnapshot(); + expect(warnLogMock).toHaveBeenCalledWith( + `No preview middleware found in ${FileName.Ui5Yaml}. Preview middleware will be added.` + ); + expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5Yaml)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5MockYaml, missingMiddlewareConfigPath)); + expect(debugLogMock).toHaveBeenCalledWith(noFileMessage(FileName.Ui5LocalYaml, missingMiddlewareConfigPath)); + }); + + test('add fiori-tools-preview to ui5.yaml file w/o middlewares', async () => { const missingMiddlewareConfigPath = join(basePath, 'no-middleware-config'); await updateMiddlewares(fs, missingMiddlewareConfigPath, logger); From 8be57d19e564ff62e7fe8754153801b516575512 Mon Sep 17 00:00:00 2001 From: D048415 Date: Thu, 10 Oct 2024 16:43:12 +0200 Subject: [PATCH 34/37] add unit test --- .../app-config-writer/src/variants-config/utils.ts | 13 ++++++++----- .../test/unit/variants-config/package-json.test.ts | 8 ++++---- .../test/unit/variants-config/utils.test.ts | 8 ++++++++ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index 3a7af6628b..62d83aea56 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -12,9 +12,8 @@ import type { PreviewConfigOptions, FioriToolsDeprecatedPreviewConfig } from '.. * @param yamlConfig - the yaml configuration to use; if not provided, the file will be read with the provided basePath and filename * @param basePath - path to project root, where ui5.yaml is located * @param filename - name of the ui5 yaml file to read from basePath; default is 'ui5.yaml' - * @returns preview middleware configuration if found or undefined - * @throws {Error} if filename is not found at basePath - * @throws {Error} if basePath and yamlConfig are undefined + * @returns preview middleware configuration if found
+ * Rejects if neither yamlConfig nor basePath is provided or if the file can't be read */ export async function getPreviewMiddleware( yamlConfig?: UI5Config, @@ -22,9 +21,13 @@ export async function getPreviewMiddleware( filename: string = FileName.Ui5Yaml ): Promise | undefined> { if (!basePath && !yamlConfig) { - throw new Error('Either base path or yaml config must be provided'); + return Promise.reject(new Error('Either base path or yaml config must be provided')); + } + try { + yamlConfig = yamlConfig ?? (await readUi5Yaml(basePath!, filename)); + } catch (error) { + return Promise.reject(error); } - yamlConfig = yamlConfig ?? (await readUi5Yaml(basePath!, filename)); return ( yamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? yamlConfig.findCustomMiddleware(MiddlewareConfigs.PreviewMiddleware) diff --git a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts index 245da39a2c..f271352e91 100644 --- a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts @@ -36,15 +36,15 @@ describe('addVariantsManagementScript', () => { test('add no script to package.json when there is already a script', async () => { const deprecatedConfig = join(basePath, 'deprecated-config'); - await expect(addVariantsManagementScript(fs, deprecatedConfig, logger)).rejects.toThrow( - new Error('Script already exists.') + await expect(addVariantsManagementScript(fs, deprecatedConfig, logger)).rejects.toThrowError( + 'Script already exists.' ); }); test('add no script to package.json when there is no RTA editor', async () => { const openSourceConfig = join(basePath, 'open-source-config'); - await expect(addVariantsManagementScript(fs, openSourceConfig, logger)).rejects.toThrow( - new Error('No RTA editor specified in ui5.yaml.') + await expect(addVariantsManagementScript(fs, openSourceConfig, logger)).rejects.toThrowError( + 'No RTA editor specified in ui5.yaml.' ); }); }); diff --git a/packages/app-config-writer/test/unit/variants-config/utils.test.ts b/packages/app-config-writer/test/unit/variants-config/utils.test.ts index a2dc12d4fc..1a6224e99e 100644 --- a/packages/app-config-writer/test/unit/variants-config/utils.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/utils.test.ts @@ -72,4 +72,12 @@ describe('utils', () => { expect(url).toBe(undefined); }); }); + + describe('getPreviewMiddleware', () => { + test('exception handling', async () => { + await expect(utils.getPreviewMiddleware()).rejects.toThrowError( + 'Either base path or yaml config must be provided' + ); + }); + }); }); From e3a20bd7d764e74bb790b852552779d0fa3d086f Mon Sep 17 00:00:00 2001 From: D048415 Date: Thu, 10 Oct 2024 17:07:29 +0200 Subject: [PATCH 35/37] fix sonar issue --- packages/app-config-writer/src/variants-config/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index 62d83aea56..6fa47aa4ec 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -26,7 +26,7 @@ export async function getPreviewMiddleware( try { yamlConfig = yamlConfig ?? (await readUi5Yaml(basePath!, filename)); } catch (error) { - return Promise.reject(error); + return Promise.reject(error as Error); } return ( yamlConfig.findCustomMiddleware(MiddlewareConfigs.FioriToolsPreview) ?? From ee1d6797e3d829b0cc6364ed794607be1e1bdc20 Mon Sep 17 00:00:00 2001 From: Annemarie Date: Tue, 15 Oct 2024 16:42:42 +0200 Subject: [PATCH 36/37] feat: path to yaml by cli and error handling --- .../variants-config/generateVariantsConfig.ts | 15 +++++++++------ .../src/variants-config/package-json.ts | 18 +++++++++++++----- .../src/variants-config/ui5-yaml.ts | 16 ++++++++++++---- .../src/variants-config/utils.ts | 7 +++++-- packages/create/src/cli/add/variants-config.ts | 14 +++++++++----- 5 files changed, 48 insertions(+), 22 deletions(-) diff --git a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts index 75667311bf..6b07c257ec 100644 --- a/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts +++ b/packages/app-config-writer/src/variants-config/generateVariantsConfig.ts @@ -9,18 +9,21 @@ import type { ToolsLogger } from '@sap-ux/logger'; * Add variants configuration to an app or project. * * @param basePath - the base path where the package.json and ui5.yaml is + * @param yamlPath - the path where the ui5.yaml is * @param logger - logger * @param fs - the memfs editor instance * @returns Promise - memfs editor instance with updated files */ -export async function generateVariantsConfig(basePath: string, logger?: ToolsLogger, fs?: Editor): Promise { +export async function generateVariantsConfig( + basePath: string, + yamlPath?: string, + logger?: ToolsLogger, + fs?: Editor +): Promise { if (!fs) { fs = create(createStorage()); } - await addVariantsManagementScript(fs, basePath, logger).catch((error) => { - logger?.error(`Script 'start-variants-management' cannot be written to package.json. ${error.message}.`); - return fs; - }); - await updateMiddlewares(fs, basePath, logger); + await addVariantsManagementScript(fs, basePath, yamlPath, logger); + await updateMiddlewares(fs, basePath, yamlPath, logger); return fs; } diff --git a/packages/app-config-writer/src/variants-config/package-json.ts b/packages/app-config-writer/src/variants-config/package-json.ts index 495d00a91e..50e6ea7c44 100644 --- a/packages/app-config-writer/src/variants-config/package-json.ts +++ b/packages/app-config-writer/src/variants-config/package-json.ts @@ -4,24 +4,32 @@ import type { Editor } from 'mem-fs-editor'; import type { Package } from '@sap-ux/project-access'; import type { ToolsLogger } from '@sap-ux/logger'; +const ERROR_MSG = `Script 'start-variants-management' cannot be written to package.json.`; + /** * Add the start-variants-management script to the package.json. * * @param fs - mem-fs reference to be used for file access * @param basePath - path to application root, where package.json is + * @param yamlPath - path to the ui5*.yaml file * @param logger - logger * @returns Promise - rejects in case variants management script can't be added to package.json */ -export async function addVariantsManagementScript(fs: Editor, basePath: string, logger?: ToolsLogger): Promise { +export async function addVariantsManagementScript( + fs: Editor, + basePath: string, + yamlPath?: string, + logger?: ToolsLogger +): Promise { const packageJsonPath = join(basePath, 'package.json'); const packageJson = fs.readJSON(packageJsonPath) as Package | undefined; if (!packageJson) { - return Promise.reject(new Error(`File 'package.json' not found at ${basePath}`)); + return Promise.reject(new Error(`${ERROR_MSG} File 'package.json' not found at ${basePath}`)); } if (packageJson?.scripts?.['start-variants-management']) { - return Promise.reject(new Error(`Script already exists.`)); + return Promise.reject(new Error(`${ERROR_MSG} Script already exists.`)); } if (!packageJson.scripts) { @@ -35,10 +43,10 @@ export async function addVariantsManagementScript(fs: Editor, basePath: string, urlParameters['sap-client'] = sapClient; } - const url = await getRTAUrl(basePath, getUI5UrlParameters(urlParameters)); + const url = await getRTAUrl(basePath, getUI5UrlParameters(urlParameters), yamlPath); if (!url) { - return Promise.reject(new Error(`No RTA editor specified in ui5.yaml.`)); + return Promise.reject(new Error(`${ERROR_MSG} No RTA editor specified in ui5.yaml.`)); } packageJson.scripts['start-variants-management'] = `fiori run --open "${url}"`; diff --git a/packages/app-config-writer/src/variants-config/ui5-yaml.ts b/packages/app-config-writer/src/variants-config/ui5-yaml.ts index 74a0bb2fbb..0684b318e9 100644 --- a/packages/app-config-writer/src/variants-config/ui5-yaml.ts +++ b/packages/app-config-writer/src/variants-config/ui5-yaml.ts @@ -1,4 +1,4 @@ -import { join } from 'path'; +import { basename, join } from 'path'; import { MiddlewareConfigs } from '../types'; import { FileName, type Package, readUi5Yaml } from '@sap-ux/project-access'; import type { Editor } from 'mem-fs-editor'; @@ -54,13 +54,21 @@ export function createPreviewMiddlewareConfig(fs: Editor, basePath: string): Cus * * @param fs - mem-fs reference to be used for file access * @param basePath - path to project root, where package.json and ui5.yaml is + * @param yamlPath - the path where the ui5.yaml is * @param logger - logger */ -export async function updateMiddlewares(fs: Editor, basePath: string, logger?: ToolsLogger): Promise { - const ui5Yamls = [FileName.Ui5Yaml, FileName.Ui5MockYaml, FileName.Ui5LocalYaml]; +export async function updateMiddlewares( + fs: Editor, + basePath: string, + yamlPath?: string, + logger?: ToolsLogger +): Promise { + const ui5Yamls: string[] = [FileName.Ui5Yaml, FileName.Ui5MockYaml, FileName.Ui5LocalYaml]; + if (yamlPath) { + ui5Yamls.unshift(basename(yamlPath)); + } for (const ui5Yaml of ui5Yamls) { let ui5YamlConfig: UI5Config; - try { ui5YamlConfig = await readUi5Yaml(basePath, ui5Yaml); } catch (error) { diff --git a/packages/app-config-writer/src/variants-config/utils.ts b/packages/app-config-writer/src/variants-config/utils.ts index 6fa47aa4ec..1e51ed80f6 100644 --- a/packages/app-config-writer/src/variants-config/utils.ts +++ b/packages/app-config-writer/src/variants-config/utils.ts @@ -4,6 +4,7 @@ import { stringify } from 'querystring'; import type { Package } from '@sap-ux/project-access'; import type { CustomMiddleware, UI5Config } from '@sap-ux/ui5-config'; import type { PreviewConfigOptions, FioriToolsDeprecatedPreviewConfig } from '../types'; +import { basename } from 'path'; /** * Gets the preview middleware form the yamlConfig or provided path. @@ -116,12 +117,14 @@ function getRTAIntent(previewMiddlewareConfig: PreviewConfigOptions | undefined) * * @param basePath - path to project root, where package.json and ui5.yaml is located * @param query - query to create fragment + * @param yamlPath - path of the ui5 yaml file provided by cli' * @returns - review url parameters */ -export async function getRTAUrl(basePath: string, query: string): Promise { +export async function getRTAUrl(basePath: string, query: string, yamlPath?: string): Promise { let previewMiddleware: CustomMiddleware | undefined; try { - previewMiddleware = await getPreviewMiddleware(undefined, basePath); + const fileName = yamlPath ? basename(yamlPath) : FileName.Ui5Yaml; + previewMiddleware = await getPreviewMiddleware(undefined, basePath, fileName); } catch (error) { //todo: what to do in case there is no ui5.yaml file? try FileName.Ui5MockYaml or FileName.Ui5LocalYaml as fallback? return undefined; diff --git a/packages/create/src/cli/add/variants-config.ts b/packages/create/src/cli/add/variants-config.ts index 03d9ae9c09..bc37ce5157 100644 --- a/packages/create/src/cli/add/variants-config.ts +++ b/packages/create/src/cli/add/variants-config.ts @@ -2,6 +2,7 @@ import type { Command } from 'commander'; import { getLogger, traceChanges, setLogLevelVerbose } from '../../tracing'; import { validateBasePath } from '../../validation'; import { generateVariantsConfig } from '@sap-ux/app-config-writer'; +import { isAbsolute, join } from 'path'; /** * Add the "add variants config" command to a passed command. @@ -10,13 +11,14 @@ import { generateVariantsConfig } from '@sap-ux/app-config-writer'; */ export function addAddVariantsConfigCommand(cmd: Command): void { cmd.command('variants-config [path]') + .option('-c, --config ', 'Path to project configuration file in YAML format', 'ui5.yaml') .option('-s, --simulate', 'simulate only do not write config; sets also --verbose') .option('-v, --verbose', 'show verbose information') .action(async (path, options) => { if (options.verbose === true || options.simulate) { setLogLevelVerbose(); } - await addVariantsConfig(path || process.cwd(), !!options.simulate); + await addVariantsConfig(path || process.cwd(), !!options.simulate, options.config); }); } @@ -25,19 +27,21 @@ export function addAddVariantsConfigCommand(cmd: Command): void { * * @param basePath - the base path where the package.json and ui5.yaml is * @param simulate - if true, do not write but just show what would be changed; otherwise write + * @param yamlPath - path to the ui5*.yaml file */ -async function addVariantsConfig(basePath: string, simulate: boolean): Promise { +async function addVariantsConfig(basePath: string, simulate: boolean, yamlPath: string): Promise { const logger = getLogger(); try { logger.debug(`Called add variants-config for path '${basePath}', simulate is '${simulate}'`); - await validateBasePath(basePath); - const fs = await generateVariantsConfig(basePath, logger); + const ui5ConfigPath = isAbsolute(yamlPath) ? yamlPath : join(basePath, yamlPath); + await validateBasePath(basePath, ui5ConfigPath); + const fs = await generateVariantsConfig(basePath, ui5ConfigPath, logger); await traceChanges(fs); if (!simulate) { fs.commit(() => logger.info(`Variants configuration written.`)); } } catch (error) { - logger.error(`Error while executing add variants-config '${(error as Error).message}'`); + logger.error(`Error while executing add variants-config: ${(error as Error).message}`); logger.debug(error as Error); } } From ae367b2eb41b829d28b4979d53a0b9a58e613fcf Mon Sep 17 00:00:00 2001 From: Annemarie Date: Tue, 15 Oct 2024 16:43:20 +0200 Subject: [PATCH 37/37] test: update unit tests and readMe --- .../generateVariantsConfig.test.ts | 6 ++---- .../unit/variants-config/package-json.test.ts | 10 +++++----- .../test/unit/variants-config/ui5-yaml.test.ts | 13 +++++++------ .../test/unit/variants-config/utils.test.ts | 17 +++++++++++++---- packages/create/README.md | 8 +++++++- 5 files changed, 34 insertions(+), 20 deletions(-) diff --git a/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts b/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts index ada3adf2e4..cc9d7a6427 100644 --- a/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/generateVariantsConfig.test.ts @@ -16,11 +16,9 @@ describe('generateVariantsConfig', () => { }); test('adding variants configuration to a non existing project', async () => { - const errorLogMock = jest.spyOn(ToolsLogger.prototype, 'error').mockImplementation(() => {}); const basePath = join(__dirname, '../../fixtures/a-folder-that-does-not-exist'); - const fs = await generateVariantsConfig(basePath, new ToolsLogger()); - expect(errorLogMock).toHaveBeenCalledWith( - `Script 'start-variants-management' cannot be written to package.json. File 'package.json' not found at ${basePath}.` + await expect(generateVariantsConfig(basePath, 'hugo.yaml', new ToolsLogger())).rejects.toThrowError( + `Script 'start-variants-management' cannot be written to package.json. File 'package.json' not found at ${basePath}` ); }); }); diff --git a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts index f271352e91..9c14a657f8 100644 --- a/packages/app-config-writer/test/unit/variants-config/package-json.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/package-json.test.ts @@ -12,7 +12,7 @@ describe('addVariantsManagementScript', () => { const debugLogMock = jest.spyOn(ToolsLogger.prototype, 'debug').mockImplementation(() => {}); const basePath = join(__dirname, '../../fixtures/variants-config'); - + const yamlPath = 'path/to/my/ui5.yaml'; beforeEach(() => { jest.clearAllMocks(); fs = createFS(createStorage()); @@ -20,14 +20,14 @@ describe('addVariantsManagementScript', () => { test('add start-variants-management script to package.json', async () => { const fioriToolsConfig = join(basePath, 'fiori-tools-config'); - await addVariantsManagementScript(fs, fioriToolsConfig, logger); + await addVariantsManagementScript(fs, fioriToolsConfig, yamlPath, logger); expect(debugLogMock).toHaveBeenCalledWith(`Script 'start-variants-management' written to 'package.json'.`); expect(fs.readJSON(join(fioriToolsConfig, 'package.json'))).toMatchSnapshot(); }); test('add script to package.json when there is no script section', async () => { - await addVariantsManagementScript(fs, basePath, logger); + await addVariantsManagementScript(fs, basePath, yamlPath, logger); expect(warnLogMock).toHaveBeenCalledWith( `File 'package.json' does not contain a script section. Script section added.` ); @@ -36,14 +36,14 @@ describe('addVariantsManagementScript', () => { test('add no script to package.json when there is already a script', async () => { const deprecatedConfig = join(basePath, 'deprecated-config'); - await expect(addVariantsManagementScript(fs, deprecatedConfig, logger)).rejects.toThrowError( + await expect(addVariantsManagementScript(fs, deprecatedConfig, yamlPath, logger)).rejects.toThrowError( 'Script already exists.' ); }); test('add no script to package.json when there is no RTA editor', async () => { const openSourceConfig = join(basePath, 'open-source-config'); - await expect(addVariantsManagementScript(fs, openSourceConfig, logger)).rejects.toThrowError( + await expect(addVariantsManagementScript(fs, openSourceConfig, yamlPath, logger)).rejects.toThrowError( 'No RTA editor specified in ui5.yaml.' ); }); diff --git a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts index 18ac272254..0f4443ac87 100644 --- a/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/ui5-yaml.test.ts @@ -19,6 +19,7 @@ describe('Test update middleware', () => { const debugLogMock = jest.spyOn(ToolsLogger.prototype, 'debug').mockImplementation(() => {}); const warnLogMock = jest.spyOn(ToolsLogger.prototype, 'warn').mockImplementation(() => {}); const basePath = join(__dirname, '../../fixtures/variants-config'); + const yamlPath = 'path/to/my/ui5.yaml'; beforeEach(() => { jest.clearAllMocks(); @@ -26,7 +27,7 @@ describe('Test update middleware', () => { }); test('add preview middleware config to ui5.yaml file', async () => { - await updateMiddlewares(fs, basePath, logger); + await updateMiddlewares(fs, basePath, yamlPath, logger); expect(fs.read(join(basePath, 'ui5.yaml'))).toMatchSnapshot(); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5Yaml)); @@ -36,7 +37,7 @@ describe('Test update middleware', () => { test('add preview-middleware to ui5.yaml file w/o middlewares', async () => { const missingMiddlewareConfigPath = join(basePath, 'no-middleware-config-os'); - await updateMiddlewares(fs, missingMiddlewareConfigPath, logger); + await updateMiddlewares(fs, missingMiddlewareConfigPath, yamlPath, logger); expect(fs.read(join(missingMiddlewareConfigPath, 'ui5.yaml'))).toMatchSnapshot(); expect(warnLogMock).toHaveBeenCalledWith( @@ -49,7 +50,7 @@ describe('Test update middleware', () => { test('add fiori-tools-preview to ui5.yaml file w/o middlewares', async () => { const missingMiddlewareConfigPath = join(basePath, 'no-middleware-config'); - await updateMiddlewares(fs, missingMiddlewareConfigPath, logger); + await updateMiddlewares(fs, missingMiddlewareConfigPath, yamlPath, logger); expect(fs.read(join(missingMiddlewareConfigPath, 'ui5.yaml'))).toMatchSnapshot(); expect(warnLogMock).toHaveBeenCalledWith( @@ -62,7 +63,7 @@ describe('Test update middleware', () => { test('add preview and reload middleware config to ui5.yaml file', async () => { const openSourceConfigPath = join(basePath, 'open-source-config'); - await updateMiddlewares(fs, openSourceConfigPath, logger); + await updateMiddlewares(fs, openSourceConfigPath, yamlPath, logger); expect(fs.read(join(openSourceConfigPath, 'ui5.yaml'))).toMatchSnapshot(); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5Yaml)); @@ -73,9 +74,9 @@ describe('Test update middleware', () => { test('add preview and reload middleware to local ui5.yaml files', async () => { const fioriToolsConfig = join(basePath, 'fiori-tools-config'); - await updateMiddlewares(fs, fioriToolsConfig, logger); + await updateMiddlewares(fs, fioriToolsConfig, yamlPath, logger); - expect(debugLogMock).toHaveBeenCalledTimes(6); + expect(debugLogMock).toHaveBeenCalledTimes(8); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5Yaml)); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5LocalYaml)); expect(debugLogMock).toHaveBeenCalledWith(middlewareUpdatedMessage('preview', FileName.Ui5MockYaml)); diff --git a/packages/app-config-writer/test/unit/variants-config/utils.test.ts b/packages/app-config-writer/test/unit/variants-config/utils.test.ts index 1a6224e99e..833833736c 100644 --- a/packages/app-config-writer/test/unit/variants-config/utils.test.ts +++ b/packages/app-config-writer/test/unit/variants-config/utils.test.ts @@ -66,18 +66,27 @@ describe('utils', () => { test('open-source preview-middleware config with no rta mount point', async () => { const openSourceConfig = join(basePath, 'open-source-config'); - const url = await utils.getRTAUrl(openSourceConfig, query); - //check for fiori-tools default mount point provided over the ux-ui5-tooling - expect(url).toBe(undefined); + expect(await utils.getRTAUrl(openSourceConfig, query)).toBe(undefined); + }); + + test('exception handling - file not found', async () => { + expect(await utils.getRTAUrl('', '')).toBeUndefined(); }); }); describe('getPreviewMiddleware', () => { - test('exception handling', async () => { + test('exception handling - parameters not provided', async () => { await expect(utils.getPreviewMiddleware()).rejects.toThrowError( 'Either base path or yaml config must be provided' ); }); + + test('exception handling - file not found', async () => { + const basePath = join(__dirname, '../../fixtures/a-folder-that-does-not-exist'); + await expect(utils.getPreviewMiddleware(undefined, basePath, 'chicken.html')).rejects.toThrowError( + `File 'chicken.html' not found in project '${basePath}'` + ); + }); }); }); diff --git a/packages/create/README.md b/packages/create/README.md index 9b5f352627..4ec174dc5d 100644 --- a/packages/create/README.md +++ b/packages/create/README.md @@ -21,10 +21,16 @@ npx sap-ux ## add Calling `sap-ux add` allows adding a feature to a project. +### variants-config +Calling `sap-ux add variants-config` will add the necessary configuration to existing yaml files and the script to package.json for variants management. It will use the configuration from the `ui5.yaml` as default, as provided by the `fiori-tools-preview` or `preview-middleware` e.g.: +```sh +sap-ux add variants-config ui5-test.yaml +``` + ### html Calling `sap-ux add html` will add html files for local preview and testing to the project. It will use the configuration from the `ui5.yaml` as default, as provided by the `fiori-tools-preview` or `preview-middleware` e.g.: ```sh -sap-ux change add html ui5-test.yaml +sap-ux add html ui5-test.yaml ``` ### annotations Calling `sap-ux add annotations` allows adding an annotation to the OData Source of the base application in an adaptation project.