@sap-ux/app-config-writer 0.5.9 → 0.5.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,9 +8,15 @@ import { type ToolsLogger } from '@sap-ux/logger';
8
8
  * Corresponding files which are used for the preview are renamed or deleted.
9
9
  *
10
10
  * @param basePath - base path to be used for the conversion
11
- * @param logger logger to report info to the user
12
- * @param fs - file system reference
11
+ * @param options - options for the conversion
12
+ * @param options.convertTests - if set to true, then test suite and test runners fill be included in the conversion
13
+ * @param options.logger - logger to report info to the user
14
+ * @param options.fs - file system reference
13
15
  * @returns file system reference
14
16
  */
15
- export declare function convertToVirtualPreview(basePath: string, logger?: ToolsLogger, fs?: Editor): Promise<Editor>;
17
+ export declare function convertToVirtualPreview(basePath: string, options: {
18
+ convertTests?: boolean;
19
+ logger?: ToolsLogger;
20
+ fs?: Editor;
21
+ }): Promise<Editor>;
16
22
  //# sourceMappingURL=index.d.ts.map
@@ -15,14 +15,16 @@ const package_json_1 = require("./package-json");
15
15
  * Corresponding files which are used for the preview are renamed or deleted.
16
16
  *
17
17
  * @param basePath - base path to be used for the conversion
18
- * @param logger logger to report info to the user
19
- * @param fs - file system reference
18
+ * @param options - options for the conversion
19
+ * @param options.convertTests - if set to true, then test suite and test runners fill be included in the conversion
20
+ * @param options.logger - logger to report info to the user
21
+ * @param options.fs - file system reference
20
22
  * @returns file system reference
21
23
  */
22
- async function convertToVirtualPreview(basePath, logger, fs) {
23
- if (!fs) {
24
- fs = (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
25
- }
24
+ async function convertToVirtualPreview(basePath, options) {
25
+ const fs = options.fs ?? (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
26
+ const logger = options.logger;
27
+ const convertTests = options.convertTests ?? false;
26
28
  if (!(await (0, prerequisites_1.checkPrerequisites)(basePath, fs, logger))) {
27
29
  throw Error('The prerequisites are not met. For more information, see the log messages above.');
28
30
  }
@@ -30,8 +32,12 @@ async function convertToVirtualPreview(basePath, logger, fs) {
30
32
  logger?.error('You have not approved the conversion. The conversion has been aborted.');
31
33
  return fs;
32
34
  }
33
- await (0, ui5_yaml_1.updatePreviewMiddlewareConfigs)(fs, basePath, logger);
35
+ await (0, ui5_yaml_1.updatePreviewMiddlewareConfigs)(fs, basePath, convertTests, logger);
34
36
  await (0, preview_files_1.renameDefaultSandboxes)(fs, basePath, logger);
37
+ if (convertTests) {
38
+ await (0, preview_files_1.renameDefaultTestFiles)(fs, basePath, logger);
39
+ await (0, ui5_yaml_1.updateDefaultTestConfig)(fs, basePath, logger);
40
+ }
35
41
  await (0, preview_files_1.deleteNoLongerUsedFiles)(fs, basePath, logger);
36
42
  await (0, package_json_1.updateVariantsCreationScript)(fs, basePath, logger);
37
43
  return fs;
@@ -38,9 +38,10 @@ export declare function extractUrlDetails(script: string): {
38
38
  *
39
39
  * @param scriptName - the name of the script from the package.json file
40
40
  * @param script - the content of the script from the package.json file
41
+ * @param convertTests - indicator if test suite and test runner should be included in the conversion (default: false)
41
42
  * @returns indicator if the script is valid
42
43
  */
43
- export declare function isValidPreviewScript(scriptName: string, script: string | undefined): boolean;
44
+ export declare function isValidPreviewScript(scriptName: string, script: string | undefined, convertTests?: boolean): boolean;
44
45
  /**
45
46
  * Updates the variants creation script in package.json if needed.
46
47
  *
@@ -38,8 +38,9 @@ function ensurePreviewMiddlewareDependency(packageJson, fs, packageJsonPath) {
38
38
  */
39
39
  function extractUrlDetails(script) {
40
40
  //extract the URL from the 'open' command of the script
41
- let url = / (?:--open|-o|--o) ([^"]?\S*)/.exec(script)?.[1] ?? undefined;
42
- url = url?.startsWith('"') ? url.slice(1) : url;
41
+ let url = / (?:--open|-o|--o) (\S*)/.exec(script)?.[1] ?? undefined;
42
+ //delete double or single quotes from the URL
43
+ url = url?.replace(/['"]/g, '');
43
44
  //extract the path from the URL
44
45
  const path = /^[^?#]+\.html/.exec(url ?? '')?.[0] ?? undefined;
45
46
  //extract the intent from the URL
@@ -68,16 +69,18 @@ function extractUrlDetails(script) {
68
69
  *
69
70
  * @param scriptName - the name of the script from the package.json file
70
71
  * @param script - the content of the script from the package.json file
72
+ * @param convertTests - indicator if test suite and test runner should be included in the conversion (default: false)
71
73
  * @returns indicator if the script is valid
72
74
  */
73
- function isValidPreviewScript(scriptName, script) {
75
+ function isValidPreviewScript(scriptName, script, convertTests = false) {
74
76
  const isValidScriptName = scriptName != 'start-variants-management' && scriptName != 'start-control-property-editor';
75
77
  //eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
76
78
  const startsWebServer = !!(script?.includes('ui5 serve') || script?.includes('fiori run'));
77
79
  const { path } = extractUrlDetails(script ?? '');
78
- const opensTest = path?.includes('qunit.html');
80
+ const opensTest = (0, ui5_yaml_1.isTestPath)(path);
79
81
  const opensIndexHtml = path === 'index.html';
80
- return isValidScriptName && startsWebServer && !opensTest && !opensIndexHtml;
82
+ //tests are only relevant if the conversion of test runners is excluded
83
+ return isValidScriptName && startsWebServer && !opensIndexHtml && (convertTests ? true : !opensTest);
81
84
  }
82
85
  /**
83
86
  * Updates the variants creation script in package.json if needed.
@@ -4,6 +4,23 @@ exports.checkPrerequisites = checkPrerequisites;
4
4
  exports.getExplicitApprovalToAdjustFiles = getExplicitApprovalToAdjustFiles;
5
5
  const path_1 = require("path");
6
6
  const prompts_1 = require("prompts");
7
+ const semver_1 = require("semver");
8
+ /**
9
+ * Check if the version of the given package is lower than the minimal version.
10
+ *
11
+ * @param packageJson - the package.json file content
12
+ * @param dependencyName - the name of the (dev)dependency to check
13
+ * @param minVersionInfo - the minimal version to check against
14
+ * @param mandatory - (default true) if the existence of the dependency is mandatory
15
+ * @returns indicator if the version is lower than the minimal version
16
+ */
17
+ function isLowerThanMinimalVersion(packageJson, dependencyName, minVersionInfo, mandatory = true) {
18
+ const versionInfo = packageJson?.devDependencies?.[dependencyName] ?? packageJson?.dependencies?.[dependencyName];
19
+ if (!versionInfo) {
20
+ return mandatory;
21
+ }
22
+ return !(0, semver_1.satisfies)(minVersionInfo, versionInfo);
23
+ }
7
24
  /**
8
25
  * Check if the prerequisites for the conversion are met.
9
26
  * - UI5 CLI version 3.0.0 or higher is being used.
@@ -28,11 +45,14 @@ async function checkPrerequisites(basePath, fs, logger) {
28
45
  logger?.error("Conversion from '@sap/grunt-sapui5-bestpractice-build' is not supported. You must migrate to UI5 CLI version 3.0.0 or higher. For more information, see https://sap.github.io/ui5-tooling/v3/updates/migrate-v3.");
29
46
  prerequisitesMet = false;
30
47
  }
31
- const ui5CliVersion = packageJson?.devDependencies?.['@ui5/cli'] ?? packageJson?.dependencies?.['@ui5/cli'] ?? '0';
32
- if (parseInt(ui5CliVersion.split('.')[0], 10) < 3) {
48
+ if (isLowerThanMinimalVersion(packageJson, '@ui5/cli', '3.0.0')) {
33
49
  logger?.error('UI5 CLI version 3.0.0 or higher is required to convert the preview to virtual files. For more information, see https://sap.github.io/ui5-tooling/v3/updates/migrate-v3.');
34
50
  prerequisitesMet = false;
35
51
  }
52
+ if (isLowerThanMinimalVersion(packageJson, '@sap/ux-ui5-tooling', '1.15.4', false)) {
53
+ logger?.error('UX UI5 Tooling version 1.15.4 or higher is required to convert the preview to virtual files. For more information, see https://www.npmjs.com/package/@sap/ux-ui5-tooling.');
54
+ prerequisitesMet = false;
55
+ }
36
56
  const ui5MiddlewareMockserverExists = !!packageJson?.devDependencies?.['@sap-ux/ui5-middleware-fe-mockserver'] ||
37
57
  !!packageJson?.dependencies?.['@sap-ux/ui5-middleware-fe-mockserver'];
38
58
  const cdsPluginUi5Exists = !!packageJson?.devDependencies?.['cds-plugin-ui5'] || !!packageJson?.dependencies?.['cds-plugin-ui5'];
@@ -52,7 +72,7 @@ async function getExplicitApprovalToAdjustFiles() {
52
72
  type: 'confirm',
53
73
  name: 'approval',
54
74
  initial: false,
55
- message: 'The converter will rename the HTML files and delete the JS and TS files used for the existing preview functionality and configure virtual files instead. Do you want to proceed with the conversion?'
75
+ message: 'The converter will rename the HTML files and delete the JS and TS files used for the existing preview functionality and configure virtual endpoints instead. Do you want to proceed with the conversion?'
56
76
  };
57
77
  return Boolean((await (0, prompts_1.prompt)([question])).approval);
58
78
  }
@@ -21,6 +21,16 @@ export declare function renameSandbox(fs: Editor, path: string, logger?: ToolsLo
21
21
  * @param logger logger to report info to the user
22
22
  */
23
23
  export declare function renameDefaultSandboxes(fs: Editor, basePath: string, logger?: ToolsLogger): Promise<void>;
24
+ /**
25
+ * Renames the default test suite and runner files.
26
+ *
27
+ * The default files are 'testsuite.qunit.html', 'integration/opaTests.qunit.html' and 'unit/unitTests.qunit.html' located under webapp/test.
28
+ *
29
+ * @param fs - file system reference
30
+ * @param basePath - base path to be used for the conversion
31
+ * @param logger logger to report info to the user
32
+ */
33
+ export declare function renameDefaultTestFiles(fs: Editor, basePath: string, logger?: ToolsLogger): Promise<void>;
24
34
  /**
25
35
  * Deletes the *.js and *.ts files which are no longer used for the virtual preview.
26
36
  *
@@ -2,10 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.renameSandbox = renameSandbox;
4
4
  exports.renameDefaultSandboxes = renameDefaultSandboxes;
5
+ exports.renameDefaultTestFiles = renameDefaultTestFiles;
5
6
  exports.deleteNoLongerUsedFiles = deleteNoLongerUsedFiles;
6
7
  const path_1 = require("path");
7
8
  const project_access_1 = require("@sap-ux/project-access");
8
- const renameMessage = (filename) => `Renamed '${filename}' to '${filename.slice(0, -5)}_old.html'. This file is no longer needed for the preview functionality. If you have not modified this file, you can delete it. If you have modified this file, move the modified content to a custom init script for the preview middleware. For more information, see https://www.npmjs.com/package/preview-middleware#migration.`;
9
+ const ui5_yaml_1 = require("./ui5-yaml");
10
+ const renameMessage = (filename) => `Renamed '${filename}' to '${filename.slice(0, -5)}_old.html'. This file is no longer needed for the preview functionality. If you have not modified this file, you can delete it. If you have modified this file, move the modified content to a custom init script for the preview middleware. For more information, see https://github.com/SAP/open-ux-tools/tree/main/packages/preview-middleware#migration.`;
9
11
  /**
10
12
  * Renames the sandbox file which is used in a given script.
11
13
  *
@@ -28,7 +30,7 @@ async function renameSandbox(fs, path, logger) {
28
30
  logger?.debug(`The file '${(0, path_1.basename)(path)}', has already been renamed. Skipping renaming.`);
29
31
  }
30
32
  else {
31
- logger?.warn(`The file '${(0, path_1.basename)(path)}', has not been found. Skipping renaming.`);
33
+ logger?.info(`The file '${(0, path_1.basename)(path)}', has not been found. Skipping renaming.`);
32
34
  }
33
35
  }
34
36
  /**
@@ -47,6 +49,20 @@ async function renameDefaultSandboxes(fs, basePath, logger) {
47
49
  await renameSandbox(fs, (0, path_1.join)(await (0, project_access_1.getWebappPath)(basePath), path), logger);
48
50
  }
49
51
  }
52
+ /**
53
+ * Renames the default test suite and runner files.
54
+ *
55
+ * The default files are 'testsuite.qunit.html', 'integration/opaTests.qunit.html' and 'unit/unitTests.qunit.html' located under webapp/test.
56
+ *
57
+ * @param fs - file system reference
58
+ * @param basePath - base path to be used for the conversion
59
+ * @param logger logger to report info to the user
60
+ */
61
+ async function renameDefaultTestFiles(fs, basePath, logger) {
62
+ for (const path of Object.values(ui5_yaml_1.TEST_CONFIG_DEFAULTS).map((config) => config.path)) {
63
+ await renameSandbox(fs, (0, path_1.join)(await (0, project_access_1.getWebappPath)(basePath), path), logger);
64
+ }
65
+ }
50
66
  /**
51
67
  * Deletes the *.js and *.ts files which are no longer used for the virtual preview.
52
68
  *
@@ -1,8 +1,21 @@
1
1
  import type { CustomMiddleware } from '@sap-ux/ui5-config';
2
2
  import type { Editor } from 'mem-fs-editor';
3
- import type { FlpConfig } from '@sap-ux/preview-middleware';
3
+ import type { FlpConfig, MiddlewareConfig as PreviewConfig } from '@sap-ux/preview-middleware';
4
4
  import type { PreviewConfigOptions } from '../types';
5
5
  import type { ToolsLogger } from '@sap-ux/logger';
6
+ type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType[number];
7
+ type PreviewTestConfig = ArrayElement<Required<PreviewConfig>['test']>;
8
+ export declare const TEST_CONFIG_DEFAULTS: Record<string, Readonly<Required<PreviewTestConfig>>>;
9
+ /**
10
+ * Check if the path is a test path.
11
+ * 1) path matches pattern '**.qunit.html'
12
+ * 2) path is being used as test configuration path in yaml configuration.
13
+ *
14
+ * @param path - the path
15
+ * @param configuration - the preview configuration
16
+ * @returns indicator if the path is a test path
17
+ */
18
+ export declare function isTestPath(path: string | undefined, configuration?: PreviewConfig): boolean;
6
19
  /**
7
20
  * Extract the UI5 yaml configuration file name from the script.
8
21
  *
@@ -34,6 +47,22 @@ export declare function processUi5YamlConfig(fs: Editor, basePath: string, ui5Ya
34
47
  * @returns the preview middleware configuration
35
48
  */
36
49
  export declare function updatePreviewMiddlewareConfig(previewMiddleware: CustomMiddleware<PreviewConfigOptions>, intent: FlpConfig['intent'] | undefined, path: string | undefined): CustomMiddleware<PreviewConfigOptions>;
50
+ /**
51
+ * Update the test configuration.
52
+ *
53
+ * @param testConfiguration - the test configuration
54
+ * @param path - the path
55
+ * @returns the updated test configuration
56
+ */
57
+ export declare function updateTestConfig(testConfiguration: PreviewConfig['test'], path: string | undefined): PreviewConfig['test'];
58
+ /**
59
+ * Updates the default test configurations in the 'ui5.yaml' in case no test config exists in any UI5 configuration file.
60
+ *
61
+ * @param fs - file system reference
62
+ * @param basePath - base path to be used for the conversion
63
+ * @param logger logger to report info to the user
64
+ */
65
+ export declare function updateDefaultTestConfig(fs: Editor, basePath: string, logger?: ToolsLogger): Promise<void>;
37
66
  /**
38
67
  * Updates the preview middleware configurations according to the scripts they are being used in package.json.
39
68
  *
@@ -43,7 +72,9 @@ export declare function updatePreviewMiddlewareConfig(previewMiddleware: CustomM
43
72
  *
44
73
  * @param fs - file system reference
45
74
  * @param basePath - base path to be used for the conversion
75
+ * @param convertTests - indicator if test suite and test runner should be included in the conversion
46
76
  * @param logger logger to report info to the user
47
77
  */
48
- export declare function updatePreviewMiddlewareConfigs(fs: Editor, basePath: string, logger?: ToolsLogger): Promise<void>;
78
+ export declare function updatePreviewMiddlewareConfigs(fs: Editor, basePath: string, convertTests: boolean, logger?: ToolsLogger): Promise<void>;
79
+ export {};
49
80
  //# sourceMappingURL=ui5-yaml.d.ts.map
@@ -1,8 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TEST_CONFIG_DEFAULTS = void 0;
4
+ exports.isTestPath = isTestPath;
3
5
  exports.extractYamlConfigFileName = extractYamlConfigFileName;
4
6
  exports.processUi5YamlConfig = processUi5YamlConfig;
5
7
  exports.updatePreviewMiddlewareConfig = updatePreviewMiddlewareConfig;
8
+ exports.updateTestConfig = updateTestConfig;
9
+ exports.updateDefaultTestConfig = updateDefaultTestConfig;
6
10
  exports.updatePreviewMiddlewareConfigs = updatePreviewMiddlewareConfigs;
7
11
  const path_1 = require("path");
8
12
  const ui5_yaml_1 = require("../variants-config/ui5-yaml");
@@ -15,6 +19,20 @@ const DEFAULT_INTENT = {
15
19
  object: 'app',
16
20
  action: 'preview'
17
21
  };
22
+ exports.TEST_CONFIG_DEFAULTS = {
23
+ qunit: {
24
+ path: '/test/unitTests.qunit.html',
25
+ framework: 'QUnit'
26
+ },
27
+ opa5: {
28
+ path: '/test/opaTests.qunit.html',
29
+ framework: 'OPA5'
30
+ },
31
+ testsuite: {
32
+ path: '/test/testsuite.qunit.html',
33
+ framework: 'Testsuite'
34
+ }
35
+ };
18
36
  /**
19
37
  * Checks if a script can be converted based on the used UI5 yaml configuration file.
20
38
  *
@@ -43,25 +61,22 @@ function isUi5YamlToBeConverted(ui5Yaml, scriptName, ui5YamlFileNames, logger) {
43
61
  * @param ui5Yaml - the name of the UI5 yaml configuration file
44
62
  * @param scriptName - the name of the script from the package.json file
45
63
  * @param script - the content of the script from the package.json file
64
+ * @param convertTests - indicator if test suite and test runner should be included in the conversion
46
65
  * @param logger logger to report info to the user
47
66
  * @returns indicator if the UI5 yaml configuration file has already been converted
48
67
  */
49
- async function isUi5YamlAlreadyConverted(fs, basePath, ui5Yaml, scriptName, script, logger) {
50
- if (Object.keys(fs.dump(basePath, (file) => {
68
+ async function isUi5YamlFlpPathAlreadyConverted(fs, basePath, ui5Yaml, scriptName, script, convertTests, logger) {
69
+ const yamlConfigAlreadyAdjusted = Object.keys(fs.dump(basePath, (file) => {
51
70
  return file.basename === ui5Yaml && file.state === 'modified';
52
- })).length === 0) {
53
- return false;
54
- }
71
+ })).length > 0;
55
72
  const flpPath = (await (0, utils_1.getPreviewMiddleware)(undefined, basePath, ui5Yaml, fs))
56
73
  ?.configuration?.flp?.path;
57
74
  const { path: scriptPath } = (0, package_json_1.extractUrlDetails)(script);
58
- if (flpPath != scriptPath) {
59
- logger?.warn(`Skipping script'${scriptName}', because another script also refers to UI5 YAML configuration file, '${ui5Yaml}'. Adjust the 'flp.path' property in the UI5 YAML configuration file to the correct endpoint or create a separate UI5 YAML configuration file for script '${scriptName}'. ${ui5Yaml} currently uses ${flpPath ?? DEFAULT_FLP_PATH} whereas script '${scriptName}' uses '${scriptPath}'.`);
75
+ if (yamlConfigAlreadyAdjusted && flpPath != scriptPath && (convertTests ? !isTestPath(scriptPath) : true)) {
76
+ logger?.warn(`Skipping script '${scriptName}', because another script also refers to UI5 YAML configuration file, '${ui5Yaml}'. Adjust the 'flp.path' property in the UI5 YAML configuration file to the correct endpoint or create a separate UI5 YAML configuration file for script '${scriptName}'. ${ui5Yaml} currently uses ${flpPath ?? DEFAULT_FLP_PATH} whereas script '${scriptName}' uses '${scriptPath}'.`);
77
+ return true;
60
78
  }
61
- else {
62
- logger?.info(`Skipping script '${scriptName}', because the UI5 YAML configuration file '${ui5Yaml}' has already been adjusted based on another script.`);
63
- }
64
- return true;
79
+ return false;
65
80
  }
66
81
  /**
67
82
  * Checks if the passed path is a FLP path.
@@ -70,13 +85,30 @@ async function isUi5YamlAlreadyConverted(fs, basePath, ui5Yaml, scriptName, scri
70
85
  * @param configuration - the preview configuration
71
86
  * @returns indicator if the path is an FLP path
72
87
  */
73
- function pathIsFlpPath(path, configuration) {
88
+ function isFlpPath(path, configuration) {
74
89
  if (!path) {
75
90
  return false;
76
91
  }
77
- const isNotRtaEditorPath = configuration.rta?.editors?.every((editor) => editor.path !== path) ?? true;
78
- const isNotTestPath = configuration.test?.every((test) => test.path !== path) ?? true;
79
- return isNotRtaEditorPath && isNotTestPath;
92
+ const isRtaEditorPath = configuration.rta?.editors?.some((editor) => editor.path === path) ?? false;
93
+ return !isRtaEditorPath && !isTestPath(path, configuration);
94
+ }
95
+ /**
96
+ * Check if the path is a test path.
97
+ * 1) path matches pattern '**.qunit.html'
98
+ * 2) path is being used as test configuration path in yaml configuration.
99
+ *
100
+ * @param path - the path
101
+ * @param configuration - the preview configuration
102
+ * @returns indicator if the path is a test path
103
+ */
104
+ function isTestPath(path, configuration) {
105
+ if (!path) {
106
+ return false;
107
+ }
108
+ if (path.includes('.qunit.html')) {
109
+ return true;
110
+ }
111
+ return configuration?.test?.some((testConfig) => testConfig.path === path) ?? false;
80
112
  }
81
113
  /**
82
114
  * Sanitizes the preview middleware configuration.
@@ -160,19 +192,26 @@ function updatePreviewMiddlewareConfig(previewMiddleware, intent, path) {
160
192
  const newMiddlewareConfig = sanitizePreviewMiddleware(previewMiddleware);
161
193
  //copy of configuration to avoid ending up with an empty configuration object in some cases
162
194
  const configuration = { ...newMiddlewareConfig.configuration };
163
- configuration.flp = configuration.flp ?? {};
164
195
  let writeConfig = false;
165
- //check path and respect defaults
166
- if (pathIsFlpPath(path, configuration) && !path?.includes(DEFAULT_FLP_PATH)) {
167
- configuration.flp.path = path;
168
- writeConfig = true;
196
+ if (isFlpPath(path, configuration)) {
197
+ //adjust path but respect defaults
198
+ if (!path?.includes(DEFAULT_FLP_PATH)) {
199
+ configuration.flp = configuration.flp ?? {};
200
+ configuration.flp.path = path;
201
+ writeConfig = true;
202
+ }
203
+ //adjust intent but respect defaults
204
+ if (intent && `${intent?.object}-${intent?.action}` !== defaultIntent) {
205
+ configuration.flp = configuration.flp ?? {};
206
+ configuration.flp.intent = {
207
+ object: intent.object,
208
+ action: intent.action
209
+ };
210
+ writeConfig = true;
211
+ }
169
212
  }
170
- //check intent and respect defaults
171
- if (intent && `${intent?.object}-${intent?.action}` !== defaultIntent) {
172
- configuration.flp.intent = {
173
- object: intent.object,
174
- action: intent.action
175
- };
213
+ else if (isTestPath(path, configuration)) {
214
+ configuration.test = updateTestConfig(configuration.test, path);
176
215
  writeConfig = true;
177
216
  }
178
217
  if (writeConfig) {
@@ -180,6 +219,82 @@ function updatePreviewMiddlewareConfig(previewMiddleware, intent, path) {
180
219
  }
181
220
  return newMiddlewareConfig;
182
221
  }
222
+ /**
223
+ * Update the test configuration.
224
+ *
225
+ * @param testConfiguration - the test configuration
226
+ * @param path - the path
227
+ * @returns the updated test configuration
228
+ */
229
+ function updateTestConfig(testConfiguration, path) {
230
+ testConfiguration = testConfiguration ?? [];
231
+ let framework;
232
+ if (path?.includes('testsuite.qunit.html')) {
233
+ framework = 'Testsuite';
234
+ }
235
+ else if (path?.includes('opaTests.qunit.html')) {
236
+ framework = 'OPA5';
237
+ }
238
+ else if (path?.includes('unitTests.qunit.html')) {
239
+ framework = 'QUnit';
240
+ }
241
+ if (!framework) {
242
+ return testConfiguration;
243
+ }
244
+ const defaultPath = exports.TEST_CONFIG_DEFAULTS[framework.toLowerCase()].path;
245
+ const testConfig = testConfiguration.find((test) => test.framework === framework);
246
+ if (testConfig) {
247
+ testConfig.path = path;
248
+ if (testConfig.path === defaultPath) {
249
+ //sanitize default path
250
+ delete testConfig.path;
251
+ }
252
+ }
253
+ else if (path?.includes(defaultPath)) {
254
+ testConfiguration.push({ framework });
255
+ }
256
+ else {
257
+ testConfiguration.push({ framework, path });
258
+ }
259
+ return testConfiguration;
260
+ }
261
+ /**
262
+ * Updates the default test configurations in the 'ui5.yaml' in case no test config exists in any UI5 configuration file.
263
+ *
264
+ * @param fs - file system reference
265
+ * @param basePath - base path to be used for the conversion
266
+ * @param logger logger to report info to the user
267
+ */
268
+ async function updateDefaultTestConfig(fs, basePath, logger) {
269
+ const ui5YamlFileNames = await (0, project_access_1.getAllUi5YamlFileNames)(basePath, fs);
270
+ for (const ui5Yaml of ui5YamlFileNames.filter((ui5Yaml) => ui5Yaml !== project_access_1.FileName.Ui5Yaml)) {
271
+ const ui5YamlConfig = await (0, project_access_1.readUi5Yaml)(basePath, ui5Yaml, fs);
272
+ const previewMiddleware = (await (0, utils_1.getPreviewMiddleware)(ui5YamlConfig));
273
+ if (previewMiddleware.configuration.test) {
274
+ return;
275
+ }
276
+ }
277
+ let ui5YamlConfig;
278
+ try {
279
+ ui5YamlConfig = await (0, project_access_1.readUi5Yaml)(basePath, project_access_1.FileName.Ui5Yaml, fs);
280
+ }
281
+ catch (error) {
282
+ logger?.warn(`The UI5 YAML configuration file 'ui5.yaml', can't be updated to support test frameworks: '${error}'. Please manually add the test configuration to the UI5 YAML configuration file used for testing according to https://github.com/SAP/open-ux-tools/tree/main/packages/preview-middleware#configuration-option-test.`);
283
+ return;
284
+ }
285
+ const previewMiddleware = (await (0, utils_1.getPreviewMiddleware)(ui5YamlConfig));
286
+ for (const defaultConfig of Object.values(exports.TEST_CONFIG_DEFAULTS)) {
287
+ if (previewMiddleware.configuration?.test?.some((testConfig) => testConfig.framework.toLowerCase() === defaultConfig.framework.toLowerCase())) {
288
+ //do not touch existing test config
289
+ break;
290
+ }
291
+ previewMiddleware.configuration.test = updateTestConfig(previewMiddleware.configuration.test, defaultConfig.path);
292
+ logger?.info(`The UI5 YAML configuration file 'ui5.yaml', has been updated to support the test framework '${defaultConfig.framework}'. Please consider transferring the test configuration to the UI5 YAML configuration file used for testing.`);
293
+ }
294
+ ui5YamlConfig.updateCustomMiddleware(previewMiddleware);
295
+ const yamlPath = (0, path_1.join)(basePath, project_access_1.FileName.Ui5Yaml);
296
+ fs.write(yamlPath, ui5YamlConfig.toString());
297
+ }
183
298
  /**
184
299
  * Updates the preview middleware configurations according to the scripts they are being used in package.json.
185
300
  *
@@ -189,21 +304,22 @@ function updatePreviewMiddlewareConfig(previewMiddleware, intent, path) {
189
304
  *
190
305
  * @param fs - file system reference
191
306
  * @param basePath - base path to be used for the conversion
307
+ * @param convertTests - indicator if test suite and test runner should be included in the conversion
192
308
  * @param logger logger to report info to the user
193
309
  */
194
- async function updatePreviewMiddlewareConfigs(fs, basePath, logger) {
310
+ async function updatePreviewMiddlewareConfigs(fs, basePath, convertTests, logger) {
195
311
  const ui5YamlFileNames = await (0, project_access_1.getAllUi5YamlFileNames)(basePath, fs);
196
312
  const unprocessedUi5YamlFileNames = [...ui5YamlFileNames];
197
313
  const packageJsonPath = (0, path_1.join)(basePath, 'package.json');
198
314
  const packageJson = fs.readJSON(packageJsonPath);
199
315
  for (const [scriptName, script] of Object.entries(packageJson?.scripts ?? {})) {
200
- if (!script || !(0, package_json_1.isValidPreviewScript)(scriptName, script)) {
316
+ if (!script || !(0, package_json_1.isValidPreviewScript)(scriptName, script, convertTests)) {
201
317
  continue;
202
318
  }
203
319
  const ui5Yaml = (0, path_1.basename)(extractYamlConfigFileName(script));
204
320
  unprocessedUi5YamlFileNames.splice(unprocessedUi5YamlFileNames.indexOf(ui5Yaml), 1);
205
321
  if (!isUi5YamlToBeConverted(ui5Yaml, scriptName, ui5YamlFileNames, logger) ||
206
- (await isUi5YamlAlreadyConverted(fs, basePath, ui5Yaml, scriptName, script, logger))) {
322
+ (await isUi5YamlFlpPathAlreadyConverted(fs, basePath, ui5Yaml, scriptName, script, convertTests, logger))) {
207
323
  continue;
208
324
  }
209
325
  try {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sap-ux/app-config-writer",
3
3
  "description": "Add or update configuration for SAP Fiori tools application",
4
- "version": "0.5.9",
4
+ "version": "0.5.11",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -26,7 +26,8 @@
26
26
  "mem-fs": "2.1.0",
27
27
  "mem-fs-editor": "9.4.0",
28
28
  "prompts": "2.4.2",
29
- "@sap-ux/axios-extension": "1.17.8",
29
+ "semver": "7.6.3",
30
+ "@sap-ux/axios-extension": "1.18.0",
30
31
  "@sap-ux/btp-utils": "0.17.2",
31
32
  "@sap-ux/logger": "0.6.0",
32
33
  "@sap-ux/project-access": "1.28.10",
@@ -38,9 +39,10 @@
38
39
  "@types/mem-fs": "1.1.2",
39
40
  "@types/mem-fs-editor": "7.0.1",
40
41
  "@types/prompts": "2.4.4",
42
+ "@types/semver": "7.5.8",
41
43
  "axios": "1.7.4",
42
44
  "nock": "13.4.0",
43
- "@sap-ux/preview-middleware": "0.16.152"
45
+ "@sap-ux/preview-middleware": "0.16.159"
44
46
  },
45
47
  "engines": {
46
48
  "node": ">=18.x"