@sap-ux/app-config-writer 0.6.113 → 0.6.115

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.
@@ -1,5 +1,6 @@
1
1
  import type { FlpConfig, MiddlewareConfig as PreviewConfig } from '@sap-ux/preview-middleware';
2
2
  import type { Editor } from 'mem-fs-editor';
3
+ import { type Package } from '@sap-ux/project-access';
3
4
  export type Script = {
4
5
  name: string;
5
6
  value: string;
@@ -92,4 +93,14 @@ export declare function isFlpPath(script: Script, configuration: PreviewConfig):
92
93
  * @returns the related test path
93
94
  */
94
95
  export declare function getTestPathForUi5TestRunner(scriptName: string): string | undefined;
96
+ /**
97
+ * Check if the version of the given package is lower than the minimal version.
98
+ *
99
+ * @param packageJson - the package.json file content
100
+ * @param dependencyName - the name of the (dev)dependency to check
101
+ * @param minVersionInfo - the minimal version to check against
102
+ * @param mandatory - (default true) if the existence of the dependency is mandatory
103
+ * @returns indicator if the version is lower than the minimal version
104
+ */
105
+ export declare function isLowerThanMinimalVersion(packageJson: Package, dependencyName: string, minVersionInfo: string, mandatory?: boolean): boolean;
95
106
  //# sourceMappingURL=package-json.d.ts.map
@@ -8,8 +8,10 @@ exports.extractYamlConfigFileName = extractYamlConfigFileName;
8
8
  exports.isTestPath = isTestPath;
9
9
  exports.isFlpPath = isFlpPath;
10
10
  exports.getTestPathForUi5TestRunner = getTestPathForUi5TestRunner;
11
+ exports.isLowerThanMinimalVersion = isLowerThanMinimalVersion;
11
12
  const node_path_1 = require("node:path");
12
13
  const project_access_1 = require("@sap-ux/project-access");
14
+ const semver_1 = require("semver");
13
15
  /**
14
16
  * Map of scripts from the package.json file.
15
17
  */
@@ -196,4 +198,33 @@ function getTestPathForUi5TestRunner(scriptName) {
196
198
  }
197
199
  return url ? new URL(url).pathname : undefined;
198
200
  }
201
+ /**
202
+ * Check if the version of the given package is lower than the minimal version.
203
+ *
204
+ * @param packageJson - the package.json file content
205
+ * @param dependencyName - the name of the (dev)dependency to check
206
+ * @param minVersionInfo - the minimal version to check against
207
+ * @param mandatory - (default true) if the existence of the dependency is mandatory
208
+ * @returns indicator if the version is lower than the minimal version
209
+ */
210
+ function isLowerThanMinimalVersion(packageJson, dependencyName, minVersionInfo, mandatory = true) {
211
+ let versionInfo = packageJson?.devDependencies?.[dependencyName] ?? packageJson?.dependencies?.[dependencyName];
212
+ if (!versionInfo) {
213
+ // In case no dependency is found we assume the minimal version is not met depending on the mandatory flag
214
+ return mandatory;
215
+ }
216
+ if (versionInfo === 'latest') {
217
+ // In case of 'latest' we know the minimal version is met
218
+ return false;
219
+ }
220
+ if ((0, semver_1.validRange)(versionInfo)) {
221
+ // In case of a valid range the minimal version must not be outside the range in high direction
222
+ return (0, semver_1.outside)(minVersionInfo, versionInfo, '>');
223
+ }
224
+ if ((0, semver_1.valid)(versionInfo)) {
225
+ // In case of a valid version we add a prefix to make it a range
226
+ versionInfo = `<=${versionInfo}`;
227
+ }
228
+ return !(0, semver_1.satisfies)(minVersionInfo, versionInfo);
229
+ }
199
230
  //# sourceMappingURL=package-json.js.map
@@ -0,0 +1,21 @@
1
+ import { type Editor } from 'mem-fs-editor';
2
+ import { type ToolsLogger } from '@sap-ux/logger';
3
+ /**
4
+ * Adds eslint configuration to the project.
5
+ *
6
+ * It checks the prerequisites to add the configuration.
7
+ * If the prerequisites are met, the corresponding eslint configuration and packages are added.
8
+ *
9
+ * @param basePath - base path to be used for the conversion
10
+ * @param options - options for the conversion
11
+ * @param options.logger - logger to report info to the user
12
+ * @param options.fs - file system reference
13
+ * @param options.config - the name of the SAP Fiori tools eslint plugin config to be used
14
+ * @returns file system reference
15
+ */
16
+ export declare function generateEslintConfig(basePath: string, options: {
17
+ logger?: ToolsLogger;
18
+ fs?: Editor;
19
+ config?: string;
20
+ }): Promise<Editor>;
21
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateEslintConfig = generateEslintConfig;
4
+ const mem_fs_1 = require("mem-fs");
5
+ const mem_fs_editor_1 = require("mem-fs-editor");
6
+ const project_access_1 = require("@sap-ux/project-access");
7
+ const node_path_1 = require("node:path");
8
+ const ui5_application_writer_1 = require("@sap-ux/ui5-application-writer");
9
+ /**
10
+ * Adds eslint configuration to the project.
11
+ *
12
+ * It checks the prerequisites to add the configuration.
13
+ * If the prerequisites are met, the corresponding eslint configuration and packages are added.
14
+ *
15
+ * @param basePath - base path to be used for the conversion
16
+ * @param options - options for the conversion
17
+ * @param options.logger - logger to report info to the user
18
+ * @param options.fs - file system reference
19
+ * @param options.config - the name of the SAP Fiori tools eslint plugin config to be used
20
+ * @returns file system reference
21
+ */
22
+ async function generateEslintConfig(basePath, options) {
23
+ const fs = options.fs ?? (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
24
+ const logger = options.logger;
25
+ if (!(await checkPrerequisites(basePath, fs, logger))) {
26
+ throw new Error('The prerequisites are not met. For more information, see the log messages above.');
27
+ }
28
+ await addEslintConfig(basePath, fs, options?.config);
29
+ return fs;
30
+ }
31
+ /**
32
+ * Checks the prerequisites for adding an eslint configuration to the project.
33
+ *
34
+ * @param basePath - base path to be used for the conversion
35
+ * @param fs - file system reference
36
+ * @param logger - logger to report info to the user
37
+ * @returns true if the prerequisites are met, false otherwise
38
+ */
39
+ async function checkPrerequisites(basePath, fs, logger) {
40
+ const packageJsonPath = (0, node_path_1.join)(basePath, project_access_1.FileName.Package);
41
+ const packageJson = fs.readJSON(packageJsonPath);
42
+ if (!packageJson) {
43
+ logger?.error(`No package.json found at path '${packageJsonPath}'`);
44
+ return false;
45
+ }
46
+ const eslintExists = (0, project_access_1.hasDependency)(packageJson, 'eslint');
47
+ if (eslintExists) {
48
+ logger?.error(`EsLint already exists in this project. Found 'eslint' dependency in package.json at path '${packageJsonPath}'`);
49
+ return false;
50
+ }
51
+ return true;
52
+ }
53
+ /**
54
+ * Adds the eslint configuration file to the project.
55
+ *
56
+ * @param basePath - base path to be used for the conversion
57
+ * @param fs - file system reference
58
+ * @param config - the name of the SAP Fiori tools eslint plugin config to be used
59
+ */
60
+ async function addEslintConfig(basePath, fs, config = 'recommended') {
61
+ await (0, ui5_application_writer_1.addEslintFeature)(basePath, fs);
62
+ if (config === 'recommended-for-s4hana') {
63
+ const eslintConfigPath = (0, node_path_1.join)(basePath, 'eslint.config.mjs');
64
+ let eslintConfigContent = fs.read(eslintConfigPath);
65
+ eslintConfigContent = eslintConfigContent.replace('...fioriTools.configs.recommended', "...fioriTools.configs['recommended-for-s4hana']");
66
+ await fs.write((0, node_path_1.join)(basePath, 'eslint.config.mjs'), eslintConfigContent);
67
+ }
68
+ }
69
+ //# sourceMappingURL=add.js.map
@@ -0,0 +1,36 @@
1
+ import { type Editor } from 'mem-fs-editor';
2
+ import type { ToolsLogger } from '@sap-ux/logger';
3
+ /**
4
+ * Partial type definition of an eslint configuration file (.eslintrc.json) that is relevant for the conversion.
5
+ */
6
+ export type EslintRcJson = {
7
+ /**
8
+ * A list of plugins to load.
9
+ */
10
+ plugins?: string[];
11
+ /**
12
+ * Configurations to extend.
13
+ * Either a string that represents a single configuration or an array of strings that represents multiple configurations.
14
+ */
15
+ extends?: string | string[];
16
+ };
17
+ /**
18
+ * Converts an eslint config to flat config format (eslint version 9).
19
+ *
20
+ * It checks the prerequisites to add the configuration.
21
+ * If the prerequisites are met, the corresponding eslint configuration is converted and packages are added/removed.
22
+ *
23
+ * @param basePath - base path to be used for the conversion
24
+ * @param options - options for the conversion
25
+ * @param options.logger - logger to report info to the user
26
+ * @param options.fs - file system reference
27
+ * @param options.config - the name of the SAP Fiori tools eslint plugin config to be used
28
+ * @returns file system reference
29
+ * @throws {Error} if the prerequisites are not met or if the conversion fails
30
+ */
31
+ export declare function convertEslintConfig(basePath: string, options: {
32
+ logger?: ToolsLogger;
33
+ fs?: Editor;
34
+ config?: string;
35
+ }): Promise<Editor>;
36
+ //# sourceMappingURL=convert.d.ts.map
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.convertEslintConfig = convertEslintConfig;
7
+ const mem_fs_editor_1 = require("mem-fs-editor");
8
+ const mem_fs_1 = require("mem-fs");
9
+ const node_path_1 = require("node:path");
10
+ const project_access_1 = require("@sap-ux/project-access");
11
+ const package_json_1 = require("../common/package-json");
12
+ const cross_spawn_1 = __importDefault(require("cross-spawn"));
13
+ const node_fs_1 = require("node:fs");
14
+ const node_os_1 = require("node:os");
15
+ const packageName = {
16
+ ESLINT: 'eslint',
17
+ ESLINT_MIGRATE_CONFIG: '@eslint/migrate-config',
18
+ ESLINT_PLUGIN_FIORI_TOOLS: '@sap-ux/eslint-plugin-fiori-tools',
19
+ ESLINT_PLUGIN_FIORI_CUSTOM: 'eslint-plugin-fiori-custom'
20
+ };
21
+ const MIGRATION_ERROR_TEXT = `Migration to eslint version 9 failed. Check if there are error messages above. You can also delete the existing eslint \`devDependency\` and run \`create add eslint\` to create a eslint.config.mjs file with the flat config where you can transfer your old eslint config manually.\` For more information, see [https://eslint.org/docs/latest/use/migrate-to-9.0.0#flat-config](Migrate to v9.x).`;
22
+ /**
23
+ * Converts an eslint config to flat config format (eslint version 9).
24
+ *
25
+ * It checks the prerequisites to add the configuration.
26
+ * If the prerequisites are met, the corresponding eslint configuration is converted and packages are added/removed.
27
+ *
28
+ * @param basePath - base path to be used for the conversion
29
+ * @param options - options for the conversion
30
+ * @param options.logger - logger to report info to the user
31
+ * @param options.fs - file system reference
32
+ * @param options.config - the name of the SAP Fiori tools eslint plugin config to be used
33
+ * @returns file system reference
34
+ * @throws {Error} if the prerequisites are not met or if the conversion fails
35
+ */
36
+ async function convertEslintConfig(basePath, options) {
37
+ const fs = options.fs ?? (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
38
+ const logger = options.logger;
39
+ if (!(await checkPrerequisites(basePath, fs, logger))) {
40
+ throw new Error('The prerequisites are not met. For more information, see the log messages above.');
41
+ }
42
+ await removeFioriToolsFromExistingConfig(basePath, fs, logger);
43
+ await runMigrationCommand(basePath, fs);
44
+ await injectFioriToolsIntoMigratedConfig(basePath, fs, options.config, logger);
45
+ await updatePackageJson(basePath, fs);
46
+ return fs;
47
+ }
48
+ /**
49
+ * Checks the prerequisites for adding an eslint configuration to the project.
50
+ *
51
+ * @param basePath - base path to be used for the conversion
52
+ * @param fs - file system reference
53
+ * @param logger - logger to report info to the user
54
+ * @returns true if the prerequisites are met, false otherwise
55
+ */
56
+ async function checkPrerequisites(basePath, fs, logger) {
57
+ const packageJsonPath = (0, node_path_1.join)(basePath, project_access_1.FileName.Package);
58
+ const packageJson = fs.readJSON(packageJsonPath);
59
+ if (!packageJson) {
60
+ logger?.error(`No package.json found at path '${packageJsonPath}'`);
61
+ return false;
62
+ }
63
+ if (!(0, project_access_1.hasDependency)(packageJson, packageName.ESLINT)) {
64
+ logger?.error(`Did not find ESLint dependency in package.json at path '${packageJsonPath}'. You might want to use the \`add eslint-config\` command instead.'`);
65
+ return false;
66
+ }
67
+ if (!(0, package_json_1.isLowerThanMinimalVersion)(packageJson, packageName.ESLINT, '9.0.0')) {
68
+ logger?.error(`ESLint version is already 9.0.0 or higher in this project. Found ESLint dependency with version '${packageJson.devDependencies?.eslint}' in package.json at path '${packageJsonPath}'`);
69
+ return false;
70
+ }
71
+ if ((0, project_access_1.hasDependency)(packageJson, '@fxu/fincode')) {
72
+ logger?.error(`Dependency to '@fxu/fincode' found at path '${basePath}'. Please remove the dependency and any usage of this package before running the conversion.`);
73
+ return false;
74
+ }
75
+ if (!fs.exists((0, node_path_1.join)(basePath, '.eslintrc.json')) && !fs.exists((0, node_path_1.join)(basePath, '.eslintrc'))) {
76
+ logger?.error(`No .eslintrc.json or .eslintrc found at path '${basePath}'`);
77
+ return false;
78
+ }
79
+ return true;
80
+ }
81
+ /**
82
+ * Removes all traces of the SAP Fiori tools plugin from the existing legacy eslint configuration,
83
+ * so that the migration tool does not attempt to translate it and produce broken output.
84
+ *
85
+ * @param basePath - base path to be used for the conversion
86
+ * @param fs - file system reference
87
+ * @param logger - logger to report info to the user
88
+ * @throws {Error} if the existing .eslintrc.json file is not a valid JSON object
89
+ */
90
+ async function removeFioriToolsFromExistingConfig(basePath, fs, logger) {
91
+ const eslintrcJsonPath = (0, node_path_1.join)(basePath, '.eslintrc.json');
92
+ const eslintrcPath = (0, node_path_1.join)(basePath, '.eslintrc');
93
+ const configPath = fs.exists(eslintrcJsonPath) ? eslintrcJsonPath : eslintrcPath;
94
+ const eslintConfig = fs.readJSON(configPath);
95
+ if (!eslintConfig || typeof eslintConfig !== 'object') {
96
+ throw new Error(`Existing eslint config at path '${configPath}' is not a valid JSON object.`);
97
+ }
98
+ // Remove fiori-tools from plugins array
99
+ if (Array.isArray(eslintConfig.plugins)) {
100
+ eslintConfig.plugins = eslintConfig.plugins.filter((plugin) => !plugin.includes(packageName.ESLINT_PLUGIN_FIORI_TOOLS));
101
+ if (eslintConfig.plugins.length === 0) {
102
+ delete eslintConfig.plugins;
103
+ }
104
+ }
105
+ // Remove fiori-tools entries from extends
106
+ if (typeof eslintConfig.extends === 'string') {
107
+ if (eslintConfig.extends.includes(packageName.ESLINT_PLUGIN_FIORI_TOOLS)) {
108
+ delete eslintConfig.extends;
109
+ }
110
+ }
111
+ else if (Array.isArray(eslintConfig.extends)) {
112
+ eslintConfig.extends = eslintConfig.extends.filter((ext) => !ext.includes(packageName.ESLINT_PLUGIN_FIORI_TOOLS));
113
+ if (eslintConfig.extends.length === 0) {
114
+ delete eslintConfig.extends;
115
+ }
116
+ }
117
+ fs.writeJSON(configPath, eslintConfig);
118
+ logger?.debug(`Removed SAP Fiori tools plugin references from ${configPath}`);
119
+ }
120
+ /**
121
+ * Injects the SAP Fiori tools plugin import and config spread into the migrated flat-config file.
122
+ *
123
+ * After the migration tool produces `eslint.config.mjs`, this function:
124
+ * 1. Prepends `import fioriTools from '@sap-ux/eslint-plugin-fiori-tools';` to the imports section.
125
+ * 2. Inserts `...fioriTools.configs.recommended` (or the requested config variant) as the last
126
+ * element of the exported config array, right before the closing `]);`.
127
+ *
128
+ * @param basePath - base path of the project
129
+ * @param fs - file system reference
130
+ * @param config - the name of the SAP Fiori tools eslint plugin config to be used
131
+ * @param logger - logger to report info to the user
132
+ */
133
+ async function injectFioriToolsIntoMigratedConfig(basePath, fs, config = 'recommended', logger) {
134
+ const migratedConfigPath = (0, node_path_1.join)(basePath, 'eslint.config.mjs');
135
+ let content = fs.read(migratedConfigPath);
136
+ const importStatement = `import fioriTools from '${packageName.ESLINT_PLUGIN_FIORI_TOOLS}';\n`;
137
+ if (!content.includes(importStatement)) {
138
+ content = importStatement + content;
139
+ }
140
+ const lastBracketIndex = content.lastIndexOf(']);');
141
+ if (lastBracketIndex !== -1) {
142
+ content =
143
+ content.slice(0, lastBracketIndex) +
144
+ `,\n ...fioriTools.configs['${config}'],\n` +
145
+ content.slice(lastBracketIndex);
146
+ }
147
+ else {
148
+ throw new Error('Unexpected format of migrated eslint config. Could not inject the SAP Fiori tools plugin configuration.');
149
+ }
150
+ fs.write(migratedConfigPath, content);
151
+ logger?.debug(`Injected SAP Fiori tools plugin into ${migratedConfigPath}`);
152
+ }
153
+ /**
154
+ * Runs the eslint migration command to convert the existing eslint configuration to flat config format.
155
+ * The command is executed in a temporary directory to avoid modifying the project files directly.
156
+ *
157
+ * @param basePath - base path to be used for the conversion
158
+ * @param fs - file system reference
159
+ * @returns a promise that resolves when the migration command finishes successfully, or rejects if the command fails
160
+ */
161
+ async function runMigrationCommand(basePath, fs) {
162
+ const tempDir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'eslint-migration-'));
163
+ try {
164
+ // 1. Copy necessary files to temp directory
165
+ const eslintrcJsonPath = (0, node_path_1.join)(basePath, '.eslintrc.json');
166
+ const eslintrcPath = (0, node_path_1.join)(basePath, '.eslintrc');
167
+ const configPath = fs.exists(eslintrcJsonPath) ? eslintrcJsonPath : eslintrcPath;
168
+ const configFileName = fs.exists(eslintrcJsonPath) ? '.eslintrc.json' : '.eslintrc';
169
+ // Read from mem-fs (which has the modified content) and write to temp directory
170
+ const eslintrcContent = fs.read(configPath);
171
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(tempDir, configFileName), eslintrcContent, 'utf-8');
172
+ const eslintignorePath = (0, node_path_1.join)(basePath, '.eslintignore');
173
+ if ((0, node_fs_1.existsSync)(eslintignorePath)) {
174
+ (0, node_fs_1.writeFileSync)((0, node_path_1.join)(tempDir, '.eslintignore'), (0, node_fs_1.readFileSync)(eslintignorePath, 'utf-8'), 'utf-8');
175
+ }
176
+ // 2. Run migration in temp directory
177
+ await spawnMigrationCommand(tempDir, configFileName);
178
+ // 3. Write migrated config to mem-fs
179
+ const migratedConfigPath = (0, node_path_1.join)(basePath, 'eslint.config.mjs');
180
+ const migratedContent = (0, node_fs_1.readFileSync)((0, node_path_1.join)(tempDir, 'eslint.config.mjs'), 'utf-8');
181
+ fs.write(migratedConfigPath, migratedContent);
182
+ }
183
+ finally {
184
+ (0, node_fs_1.rmSync)(tempDir, { recursive: true, force: true });
185
+ }
186
+ }
187
+ /**
188
+ * Spawns the eslint migration command using cross-spawn to convert the eslint configuration to flat config format.
189
+ *
190
+ * @param basePath - base path to be used for the conversion
191
+ * @param configFileName - the name of the config file to migrate
192
+ * @returns a promise that resolves when the migration command finishes successfully, or rejects if the command fails
193
+ */
194
+ async function spawnMigrationCommand(basePath, configFileName) {
195
+ return new Promise((resolve, reject) => {
196
+ const child = (0, cross_spawn_1.default)('npx', ['--yes', packageName.ESLINT_MIGRATE_CONFIG, configFileName], {
197
+ cwd: basePath,
198
+ shell: false,
199
+ stdio: 'inherit'
200
+ });
201
+ child.on('close', (code) => {
202
+ if (code === 0) {
203
+ resolve();
204
+ }
205
+ else {
206
+ reject(new Error(`Migration command failed with exit code ${code ?? 'unknown'}. ${MIGRATION_ERROR_TEXT}`));
207
+ }
208
+ });
209
+ child.on('error', (error) => {
210
+ reject(new Error(`Migration command failed: ${error.message}. ${MIGRATION_ERROR_TEXT}`));
211
+ });
212
+ });
213
+ }
214
+ /**
215
+ * Updates the package.json file of the project by adding or updating the required devDependencies.
216
+ *
217
+ * @param basePath - base path to be used for the conversion
218
+ * @param fs - file system reference
219
+ */
220
+ async function updatePackageJson(basePath, fs) {
221
+ const packageJsonPath = (0, node_path_1.join)(basePath, project_access_1.FileName.Package);
222
+ const packageJson = fs.readJSON(packageJsonPath);
223
+ packageJson.devDependencies ??= {};
224
+ packageJson.devDependencies[packageName.ESLINT] = '^9.0.0';
225
+ packageJson.devDependencies[packageName.ESLINT_PLUGIN_FIORI_TOOLS] = '^9.0.0';
226
+ delete packageJson.devDependencies[packageName.ESLINT_PLUGIN_FIORI_CUSTOM];
227
+ fs.writeJSON(packageJsonPath, packageJson);
228
+ }
229
+ //# sourceMappingURL=convert.js.map
@@ -1,21 +1,3 @@
1
- import { type Editor } from 'mem-fs-editor';
2
- import { type ToolsLogger } from '@sap-ux/logger';
3
- /**
4
- * Adds eslint configuration to the project.
5
- *
6
- * It checks the prerequisites and confirms an explicit approval to add the configuration.
7
- * If the prerequisites and approval are met, the corresponding eslint configuration and packages are added.
8
- *
9
- * @param basePath - base path to be used for the conversion
10
- * @param options - options for the conversion
11
- * @param options.logger - logger to report info to the user
12
- * @param options.fs - file system reference
13
- * @param options.config - the name of the SAP Fiori tools eslint plugin config to be used
14
- * @returns file system reference
15
- */
16
- export declare function generateEslintConfig(basePath: string, options: {
17
- logger?: ToolsLogger;
18
- fs?: Editor;
19
- config?: string;
20
- }): Promise<Editor>;
1
+ export { generateEslintConfig } from './add';
2
+ export { convertEslintConfig } from './convert';
21
3
  //# sourceMappingURL=index.d.ts.map
@@ -1,90 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.generateEslintConfig = generateEslintConfig;
4
- const mem_fs_1 = require("mem-fs");
5
- const mem_fs_editor_1 = require("mem-fs-editor");
6
- const project_access_1 = require("@sap-ux/project-access");
7
- const node_path_1 = require("node:path");
8
- /**
9
- * Adds eslint configuration to the project.
10
- *
11
- * It checks the prerequisites and confirms an explicit approval to add the configuration.
12
- * If the prerequisites and approval are met, the corresponding eslint configuration and packages are added.
13
- *
14
- * @param basePath - base path to be used for the conversion
15
- * @param options - options for the conversion
16
- * @param options.logger - logger to report info to the user
17
- * @param options.fs - file system reference
18
- * @param options.config - the name of the SAP Fiori tools eslint plugin config to be used
19
- * @returns file system reference
20
- */
21
- async function generateEslintConfig(basePath, options) {
22
- const fs = options.fs ?? (0, mem_fs_editor_1.create)((0, mem_fs_1.create)());
23
- const logger = options.logger;
24
- if (!(await checkPrerequisites(basePath, fs, logger))) {
25
- throw new Error('The prerequisites are not met. For more information, see the log messages above.');
26
- }
27
- await updatePackageJson(basePath, fs, logger);
28
- await addEslintConfig(basePath, fs, options?.config);
29
- return fs;
30
- }
31
- /**
32
- * Checks the prerequisites for adding an eslint configuration to the project.
33
- *
34
- * @param basePath - base path to be used for the conversion
35
- * @param fs - file system reference
36
- * @param logger - logger to report info to the user
37
- * @returns true if the prerequisites are met, false otherwise
38
- */
39
- async function checkPrerequisites(basePath, fs, logger) {
40
- const packageJsonPath = (0, node_path_1.join)(basePath, project_access_1.FileName.Package);
41
- const packageJson = fs.readJSON(packageJsonPath);
42
- if (!packageJson) {
43
- logger?.error(`No package.json found at path '${packageJsonPath}'`);
44
- return false;
45
- }
46
- const eslintExists = (0, project_access_1.hasDependency)(packageJson, 'eslint');
47
- if (eslintExists) {
48
- logger?.error(`EsLint already exists in this project. Found 'eslint' dependency in package.json at path '${packageJsonPath}'`);
49
- return false;
50
- }
51
- return true;
52
- }
53
- /**
54
- * Updates the package.json file of the project by adding the required eslint dependency.
55
- *
56
- * @param basePath - base path to be used for the conversion
57
- * @param fs - file system reference
58
- * @param logger - logger to report info to the user
59
- */
60
- async function updatePackageJson(basePath, fs, logger) {
61
- const packageJsonPath = (0, node_path_1.join)(basePath, project_access_1.FileName.Package);
62
- const packageJson = fs.readJSON(packageJsonPath);
63
- packageJson.devDependencies ??= {};
64
- packageJson.devDependencies['eslint'] = '^9.0.0';
65
- packageJson.devDependencies['@sap-ux/eslint-plugin-fiori-tools'] = '^9.0.0';
66
- packageJson.scripts ??= {};
67
- if (packageJson.scripts['lint']) {
68
- logger?.warn(`A 'lint' script already exists in package.json at path '${packageJsonPath}'. Adding lint script skipped.`);
69
- }
70
- else {
71
- packageJson.scripts['lint'] = 'eslint .';
72
- }
73
- fs.writeJSON(packageJsonPath, packageJson);
74
- }
75
- /**
76
- * Adds the eslint configuration file to the project.
77
- *
78
- * @param basePath - base path to be used for the conversion
79
- * @param fs - file system reference
80
- * @param config - the name of the SAP Fiori tools eslint plugin config to be used
81
- */
82
- async function addEslintConfig(basePath, fs, config = 'recommended') {
83
- const templatePath = require.resolve('@sap-ux/ui5-application-writer/templates/optional/eslint/eslint.config.mjs');
84
- let templateContent = await fs.read(templatePath);
85
- if (config === 'recommended-for-s4hana') {
86
- templateContent = templateContent.replace('...fioriTools.configs.recommended', "...fioriTools.configs['recommended-for-s4hana']");
87
- }
88
- await fs.write((0, node_path_1.join)(basePath, 'eslint.config.mjs'), templateContent);
89
- }
3
+ exports.convertEslintConfig = exports.generateEslintConfig = void 0;
4
+ var add_1 = require("./add");
5
+ Object.defineProperty(exports, "generateEslintConfig", { enumerable: true, get: function () { return add_1.generateEslintConfig; } });
6
+ var convert_1 = require("./convert");
7
+ Object.defineProperty(exports, "convertEslintConfig", { enumerable: true, get: function () { return convert_1.convertEslintConfig; } });
90
8
  //# sourceMappingURL=index.js.map
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { getSmartLinksTargetFromPrompt, simulatePrompt, includeTestRunnersPrompt } from './prompt';
2
2
  export { generateSmartLinksConfig } from './smartlinks-config';
3
- export { generateEslintConfig } from './eslint-config';
3
+ export { generateEslintConfig, convertEslintConfig } from './eslint-config';
4
4
  export { generateInboundNavigationConfig, readManifest } from './navigation-config';
5
5
  export { generateVariantsConfig } from './variants-config';
6
6
  export { convertToVirtualPreview } from './preview-config';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.enableCardGeneratorConfig = exports.convertToVirtualPreview = exports.generateVariantsConfig = exports.readManifest = exports.generateInboundNavigationConfig = exports.generateEslintConfig = exports.generateSmartLinksConfig = exports.includeTestRunnersPrompt = exports.simulatePrompt = exports.getSmartLinksTargetFromPrompt = void 0;
3
+ exports.enableCardGeneratorConfig = exports.convertToVirtualPreview = exports.generateVariantsConfig = exports.readManifest = exports.generateInboundNavigationConfig = exports.convertEslintConfig = exports.generateEslintConfig = exports.generateSmartLinksConfig = exports.includeTestRunnersPrompt = exports.simulatePrompt = exports.getSmartLinksTargetFromPrompt = void 0;
4
4
  var prompt_1 = require("./prompt");
5
5
  Object.defineProperty(exports, "getSmartLinksTargetFromPrompt", { enumerable: true, get: function () { return prompt_1.getSmartLinksTargetFromPrompt; } });
6
6
  Object.defineProperty(exports, "simulatePrompt", { enumerable: true, get: function () { return prompt_1.simulatePrompt; } });
@@ -9,6 +9,7 @@ var smartlinks_config_1 = require("./smartlinks-config");
9
9
  Object.defineProperty(exports, "generateSmartLinksConfig", { enumerable: true, get: function () { return smartlinks_config_1.generateSmartLinksConfig; } });
10
10
  var eslint_config_1 = require("./eslint-config");
11
11
  Object.defineProperty(exports, "generateEslintConfig", { enumerable: true, get: function () { return eslint_config_1.generateEslintConfig; } });
12
+ Object.defineProperty(exports, "convertEslintConfig", { enumerable: true, get: function () { return eslint_config_1.convertEslintConfig; } });
12
13
  var navigation_config_1 = require("./navigation-config");
13
14
  Object.defineProperty(exports, "generateInboundNavigationConfig", { enumerable: true, get: function () { return navigation_config_1.generateInboundNavigationConfig; } });
14
15
  Object.defineProperty(exports, "readManifest", { enumerable: true, get: function () { return navigation_config_1.readManifest; } });
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.checkPrerequisites = checkPrerequisites;
4
4
  const node_path_1 = require("node:path");
5
5
  const project_access_1 = require("@sap-ux/project-access");
6
- const semver_1 = require("semver");
6
+ const package_json_1 = require("../common/package-json");
7
7
  const packageName = {
8
8
  WDIO_QUNIT_SERVICE: 'wdio-qunit-service',
9
9
  KARMA_UI5: 'karma-ui5',
@@ -12,35 +12,6 @@ const packageName = {
12
12
  SAP_UX_UI5_MIDDLEWARE_FE_MOCKSERVER: '@sap-ux/ui5-middleware-fe-mockserver',
13
13
  SAP_GRUNT_SAPUI5_BESTPRACTICE_BUILD: '@sap/grunt-sapui5-bestpractice-build'
14
14
  };
15
- /**
16
- * Check if the version of the given package is lower than the minimal version.
17
- *
18
- * @param packageJson - the package.json file content
19
- * @param dependencyName - the name of the (dev)dependency to check
20
- * @param minVersionInfo - the minimal version to check against
21
- * @param mandatory - (default true) if the existence of the dependency is mandatory
22
- * @returns indicator if the version is lower than the minimal version
23
- */
24
- function isLowerThanMinimalVersion(packageJson, dependencyName, minVersionInfo, mandatory = true) {
25
- let versionInfo = packageJson?.devDependencies?.[dependencyName] ?? packageJson?.dependencies?.[dependencyName];
26
- if (!versionInfo) {
27
- // In case no dependency is found we assume the minimal version is not met depending on the mandatory flag
28
- return mandatory;
29
- }
30
- if (versionInfo === 'latest') {
31
- // In case of 'latest' we know the minimal version is met
32
- return false;
33
- }
34
- if ((0, semver_1.validRange)(versionInfo)) {
35
- // In case of a valid range the minimal version must not be outside the range in high direction
36
- return (0, semver_1.outside)(minVersionInfo, versionInfo, '>');
37
- }
38
- if ((0, semver_1.valid)(versionInfo)) {
39
- // In case of a valid version we add a prefix to make it a range
40
- versionInfo = `<=${versionInfo}`;
41
- }
42
- return !(0, semver_1.satisfies)(minVersionInfo, versionInfo);
43
- }
44
15
  /**
45
16
  * Check if the project is a CAP project that uses 'cds-plugin-ui5'.
46
17
  *
@@ -78,11 +49,11 @@ async function checkPrerequisites(basePath, fs, convertTests = false, logger) {
78
49
  logger?.error(`Conversion from '${packageName.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.`);
79
50
  prerequisitesMet = false;
80
51
  }
81
- if (isLowerThanMinimalVersion(packageJson, packageName.UI5_CLI, '3.0.0')) {
52
+ if ((0, package_json_1.isLowerThanMinimalVersion)(packageJson, packageName.UI5_CLI, '3.0.0')) {
82
53
  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.');
83
54
  prerequisitesMet = false;
84
55
  }
85
- if (isLowerThanMinimalVersion(packageJson, packageName.SAP_UX_UI5_TOOLING, '1.15.4', false)) {
56
+ if ((0, package_json_1.isLowerThanMinimalVersion)(packageJson, packageName.SAP_UX_UI5_TOOLING, '1.15.4', false)) {
86
57
  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.');
87
58
  prerequisitesMet = false;
88
59
  }
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.6.113",
4
+ "version": "0.6.115",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/SAP/open-ux-tools.git",
@@ -27,8 +27,9 @@
27
27
  "mem-fs-editor": "9.4.0",
28
28
  "prompts": "2.4.2",
29
29
  "semver": "7.7.4",
30
+ "cross-spawn": "7.0.6",
30
31
  "@sap-ux/axios-extension": "1.25.20",
31
- "@sap-ux/ui5-application-writer": "1.7.16",
32
+ "@sap-ux/ui5-application-writer": "1.7.17",
32
33
  "@sap-ux/btp-utils": "1.1.9",
33
34
  "@sap-ux/logger": "0.8.2",
34
35
  "@sap-ux/project-access": "1.35.11",
@@ -41,9 +42,10 @@
41
42
  "@types/mem-fs-editor": "7.0.1",
42
43
  "@types/prompts": "2.4.4",
43
44
  "@types/semver": "7.7.1",
45
+ "@types/cross-spawn": "6.0.6",
44
46
  "axios": "1.13.5",
45
47
  "nock": "13.4.0",
46
- "@sap-ux/preview-middleware": "0.23.143"
48
+ "@sap-ux/preview-middleware": "0.23.144"
47
49
  },
48
50
  "engines": {
49
51
  "node": ">=20.x"