@sap-ux/fiori-migration-writer 0.0.5 → 0.0.6

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.
Files changed (108) hide show
  1. package/dist/ProjectMigrator.d.ts +20 -8
  2. package/dist/ProjectMigrator.js +121 -123
  3. package/dist/adapters/ui5-config-adapter.js +64 -18
  4. package/dist/adapters/ui5-config-helpers.js +3 -10
  5. package/dist/components/extension.d.ts +3 -1
  6. package/dist/components/extension.js +5 -4
  7. package/dist/config/backend-i18n.d.ts +27 -6
  8. package/dist/config/backend-i18n.js +5 -11
  9. package/dist/config/flp/intent.d.ts +6 -3
  10. package/dist/config/flp/intent.js +6 -4
  11. package/dist/config/flp/sandbox.d.ts +3 -1
  12. package/dist/config/flp/sandbox.js +17 -12
  13. package/dist/config/launch-config.d.ts +4 -3
  14. package/dist/config/launch-config.js +5 -16
  15. package/dist/config/manifest-update.d.ts +21 -1
  16. package/dist/config/manifest-update.js +7 -12
  17. package/dist/config/package-json.d.ts +3 -1
  18. package/dist/config/package-json.js +15 -9
  19. package/dist/config/ui5-yaml.d.ts +9 -4
  20. package/dist/config/ui5-yaml.js +14 -10
  21. package/dist/data/sap-libraries.d.ts +3 -1
  22. package/dist/data/sap-libraries.js +4 -3
  23. package/dist/data/ui5-version.js +1 -1
  24. package/dist/files/project-files.d.ts +4 -3
  25. package/dist/files/project-files.js +10 -16
  26. package/dist/files/webapp.d.ts +5 -2
  27. package/dist/files/webapp.js +30 -35
  28. package/dist/index.d.ts +2 -2
  29. package/dist/index.js +2 -2
  30. package/dist/migration-process/configuration.d.ts +3 -1
  31. package/dist/migration-process/configuration.js +3 -2
  32. package/dist/migration-process/legacy-helpers.d.ts +3 -1
  33. package/dist/migration-process/legacy-helpers.js +19 -32
  34. package/dist/migration-process/legacy.d.ts +3 -1
  35. package/dist/migration-process/legacy.js +66 -79
  36. package/dist/migration-process/migration-phases.d.ts +6 -1
  37. package/dist/migration-process/migration-phases.js +26 -14
  38. package/dist/migration-process/setup.d.ts +9 -6
  39. package/dist/migration-process/setup.js +19 -10
  40. package/dist/migration-process/validation.d.ts +5 -2
  41. package/dist/migration-process/validation.js +6 -4
  42. package/dist/migration-types.d.ts +5 -2
  43. package/dist/project/adaptation-project.js +1 -0
  44. package/dist/project/project-data.js +1 -1
  45. package/dist/project/project-detection.d.ts +3 -1
  46. package/dist/project/project-detection.js +10 -4
  47. package/dist/project/project-extension.d.ts +1 -1
  48. package/dist/project/project-extension.js +3 -1
  49. package/dist/project/project-info.d.ts +3 -1
  50. package/dist/project/project-info.js +6 -3
  51. package/dist/project/regular-project.js +17 -9
  52. package/dist/template/application.d.ts +2 -0
  53. package/dist/template/application.js +11 -9
  54. package/dist/template/assembly.js +4 -4
  55. package/dist/template/base.d.ts +2 -0
  56. package/dist/template/base.js +2 -30
  57. package/dist/template/details.d.ts +3 -1
  58. package/dist/template/details.js +7 -5
  59. package/dist/template/template-helpers.d.ts +3 -1
  60. package/dist/template/template-helpers.js +6 -5
  61. package/dist/template/theme.d.ts +3 -1
  62. package/dist/template/theme.js +3 -2
  63. package/dist/types/mem-fs-types.d.ts +1 -1
  64. package/dist/utils/Project.d.ts +17 -14
  65. package/dist/utils/Project.js +94 -72
  66. package/dist/utils/checkForMigration.d.ts +4 -3
  67. package/dist/utils/checkForMigration.js +11 -8
  68. package/dist/utils/file-access.d.ts +36 -34
  69. package/dist/utils/file-access.js +61 -93
  70. package/dist/utils/file-discovery.d.ts +5 -2
  71. package/dist/utils/file-discovery.js +6 -4
  72. package/dist/utils/file-system-utils.d.ts +15 -5
  73. package/dist/utils/file-system-utils.js +34 -11
  74. package/dist/utils/fs-adapter.d.ts +5 -63
  75. package/dist/utils/fs-adapter.js +6 -111
  76. package/dist/utils/manifest-and-version-utils.d.ts +3 -1
  77. package/dist/utils/manifest-and-version-utils.js +6 -3
  78. package/dist/utils/migration-utils.d.ts +3 -1
  79. package/dist/utils/migration-utils.js +5 -4
  80. package/dist/utils/project-access-adapters.d.ts +3 -1
  81. package/dist/utils/project-access-adapters.js +3 -2
  82. package/dist/utils/project-discovery.d.ts +6 -2
  83. package/dist/utils/project-discovery.js +44 -18
  84. package/dist/utils/project-readers/adaptation-project-utils.d.ts +5 -2
  85. package/dist/utils/project-readers/adaptation-project-utils.js +21 -16
  86. package/dist/utils/project-readers/backend-utils.d.ts +3 -1
  87. package/dist/utils/project-readers/backend-utils.js +4 -3
  88. package/dist/utils/project-readers/extension-project-utils.d.ts +5 -2
  89. package/dist/utils/project-readers/extension-project-utils.js +15 -11
  90. package/dist/utils/project-readers/manifest-reader.d.ts +3 -1
  91. package/dist/utils/project-readers/manifest-reader.js +3 -2
  92. package/dist/utils/project-readers/manifest-utils.d.ts +5 -2
  93. package/dist/utils/project-readers/manifest-utils.js +9 -6
  94. package/dist/utils/project-readers/package-reader.d.ts +3 -1
  95. package/dist/utils/project-readers/package-reader.js +3 -2
  96. package/dist/utils/project-readers/reuse-lib-utils.d.ts +7 -3
  97. package/dist/utils/project-readers/reuse-lib-utils.js +13 -7
  98. package/dist/utils/project-readers/webapp-path-resolver.d.ts +3 -1
  99. package/dist/utils/project-readers/webapp-path-resolver.js +24 -19
  100. package/dist/utils/service.d.ts +3 -2
  101. package/dist/utils/service.js +10 -6
  102. package/dist/utils/template/template-post-processors.d.ts +3 -1
  103. package/dist/utils/template/template-post-processors.js +4 -3
  104. package/dist/utils/template/template-renderer.d.ts +3 -1
  105. package/dist/utils/template/template-renderer.js +3 -2
  106. package/dist/utils/template-generators/file-handlers.d.ts +5 -2
  107. package/dist/utils/template-generators/file-handlers.js +59 -32
  108. package/package.json +4 -4
@@ -2,69 +2,73 @@
2
2
  * Helper functions for migrating legacy Fiori Elements folder structures
3
3
  * Handles migration from /src/main/webapp to /webapp structure
4
4
  */
5
- import { join } from 'node:path';
5
+ import { join, sep } from 'node:path';
6
6
  import { readFile, updateFile, readJSON, updateJSON, fileExists } from '../utils/index.js';
7
- import { exists, copyFile, deleteFile } from '../utils/fs-adapter.js';
7
+ import { editorHasPath } from '../utils/fs-adapter.js';
8
8
  import { TemplateFileName } from '../index.js';
9
9
  import { FileName } from '../project-spec-types.js';
10
10
  import { legacyPath, getFFTestSuiteMap, MigrationError } from '../utils/common.js';
11
11
  import { ProjectAccess } from '../utils/Project.js';
12
+ import { hasStore } from '../types/mem-fs-types.js';
12
13
  import { buildLegacyPaths, tryGitMove, fallbackFsMove, cleanupEmptyDirs } from './legacy-helpers.js';
13
14
  /**
14
15
  * Migrate project from legacy Fiori Elements folder structure (/src/main/webapp) to new structure (/webapp)
15
16
  *
17
+ * @param fs - mem-fs editor
16
18
  * @param projectInfo - Project information including current webapp path
17
19
  * @param rootPath - Root path of the project
18
20
  * @returns Object containing updated keepIndex flag and updated webapp path
19
21
  */
20
- export async function migrateLegacyFolderStructure(projectInfo, rootPath) {
22
+ export async function migrateLegacyFolderStructure(fs, projectInfo, rootPath) {
21
23
  let keepIndex = false;
22
24
  // Check if project uses legacy folder structure
23
25
  if (!join(projectInfo.webappPath).includes(legacyPath)) {
24
26
  return { keepIndex, webappPath: projectInfo.webappPath };
25
27
  }
26
28
  const paths = buildLegacyPaths(rootPath, legacyPath);
27
- if (!(await exists(paths.ffLegacyWebappPath))) {
29
+ if (!fileExists(fs, paths.ffLegacyWebappPath)) {
28
30
  return { keepIndex, webappPath: projectInfo.webappPath };
29
31
  }
30
32
  // Try to use git to move files (preserves history)
31
- await tryGitMove(rootPath, paths);
33
+ await tryGitMove(fs, rootPath, paths);
32
34
  // Fallback using node fs to move folders (handles cases where git fails or isn't available)
33
35
  await fallbackFsMove(rootPath, paths);
34
36
  // Remove old src dirs if empty
35
37
  await cleanupEmptyDirs(rootPath, legacyPath, paths);
36
38
  // Update webapp path after migration
37
- const updatedWebappPath = await ProjectAccess.getWebappPath(rootPath);
39
+ const updatedWebappPath = await ProjectAccess.getWebappPath(rootPath, undefined, undefined, fs);
38
40
  const ffTestMap = getFFTestSuiteMap(updatedWebappPath);
39
41
  // Process legacy qunit runner file
40
- await processLegacyQunitRunner(paths.ffNewTestPath, ffTestMap);
42
+ processLegacyQunitRunner(fs, paths.ffNewTestPath, ffTestMap);
41
43
  // Update ModulePathForTests.js files
42
- await updateModulePathForTests(paths.ffNewTestPath);
44
+ await updateModulePathForTests(fs, paths.ffNewTestPath);
43
45
  // Update paths in test files
44
- if (await exists(paths.ffNewTestPath)) {
45
- await updateTestFilePaths(paths.ffNewTestPath);
46
+ if (editorHasPath(fs, paths.ffNewTestPath)) {
47
+ updateTestFilePaths(fs, paths.ffNewTestPath);
46
48
  }
47
49
  // Update various config files
48
- await Promise.all([updateGitignore(rootPath), updateNeoApp(rootPath), updateProjectJson(rootPath)]);
50
+ updateGitignore(fs, rootPath);
51
+ await Promise.all([updateNeoApp(fs, rootPath), updateProjectJson(fs, rootPath)]);
49
52
  // Check for mockserver in index.html
50
- keepIndex = await checkForMockserver(rootPath, updatedWebappPath);
53
+ keepIndex = checkForMockserver(fs, rootPath, updatedWebappPath);
51
54
  return { keepIndex, webappPath: updatedWebappPath };
52
55
  }
53
56
  /**
54
57
  * Process legacy qunit runner file and generate new test suite
55
58
  *
59
+ * @param fs
56
60
  * @param ffNewTestPath
57
61
  * @param ffTestMap
58
62
  */
59
- async function processLegacyQunitRunner(ffNewTestPath, ffTestMap) {
63
+ function processLegacyQunitRunner(fs, ffNewTestPath, ffTestMap) {
60
64
  const qunitRunner = 'qunit.runner.testsuite.html';
61
65
  const legacyRunner = join(ffNewTestPath, qunitRunner);
62
- if (!(await fileExists(legacyRunner))) {
66
+ if (!fileExists(fs, legacyRunner)) {
63
67
  return;
64
68
  }
65
69
  let legacyRunnerContent = '';
66
70
  try {
67
- legacyRunnerContent = readFile(legacyRunner);
71
+ legacyRunnerContent = readFile(fs, legacyRunner);
68
72
  }
69
73
  catch (e) {
70
74
  throw new MigrationError(e, qunitRunner);
@@ -98,36 +102,37 @@ async function processLegacyQunitRunner(ffNewTestPath, ffTestMap) {
98
102
  }
99
103
  // Handle testsuite.qunit.html file
100
104
  const testSuiteRunner = join(ffNewTestPath, TemplateFileName.TestsuiteQunitHtml);
101
- if (!(await fileExists(testSuiteRunner))) {
102
- updateFile(testSuiteRunner, legacyRunnerContent);
105
+ if (!fileExists(fs, testSuiteRunner)) {
106
+ updateFile(fs, testSuiteRunner, legacyRunnerContent);
103
107
  delete ffTestMap[TemplateFileName.TestsuiteQunitHtml];
104
108
  }
105
109
  else {
106
110
  // Rename using copy+delete pattern (mem-fs compatible)
107
111
  const oldTestSuite = join(ffNewTestPath, 'testsuite_old.qunit.html');
108
- copyFile(testSuiteRunner, oldTestSuite);
109
- deleteFile(testSuiteRunner);
112
+ fs.copy(testSuiteRunner, oldTestSuite);
113
+ fs.delete(testSuiteRunner);
110
114
  // Update references to testsuite.qunit.html
111
115
  if (legacyRunnerContent.includes('testsuite.qunit.html')) {
112
116
  legacyRunnerContent = legacyRunnerContent.replaceAll('testsuite.qunit.html', 'testsuite_old.qunit.html');
113
117
  }
114
- updateFile(testSuiteRunner, legacyRunnerContent);
118
+ updateFile(fs, testSuiteRunner, legacyRunnerContent);
115
119
  delete ffTestMap[TemplateFileName.TestsuiteQunitHtml];
116
120
  }
117
121
  }
118
122
  /**
119
123
  * Update ModulePathForTests.js files to fix path calculations for new structure
120
124
  *
125
+ * @param fs
121
126
  * @param ffNewTestPath
122
127
  */
123
- async function updateModulePathForTests(ffNewTestPath) {
128
+ async function updateModulePathForTests(fs, ffNewTestPath) {
124
129
  const { findAll } = await import('../utils/file-discovery.js');
125
130
  const moduleFilePath = [];
126
131
  await findAll(ffNewTestPath, TemplateFileName.ModulePathForTests, moduleFilePath, []);
127
132
  for (const path of moduleFilePath) {
128
133
  let moduleFileContent;
129
134
  try {
130
- moduleFileContent = readFile(join(path, TemplateFileName.ModulePathForTests));
135
+ moduleFileContent = readFile(fs, join(path, TemplateFileName.ModulePathForTests));
131
136
  }
132
137
  catch (e) {
133
138
  throw new MigrationError(e, TemplateFileName.ModulePathForTests);
@@ -140,7 +145,7 @@ async function updateModulePathForTests(ffNewTestPath) {
140
145
  if (functionStart !== -1 && posReturn !== -1) {
141
146
  const replaceContent = "\r\n\t\tvar number = window.location.href.indexOf(\"/webapp/test/\") !== -1 ? 3 : 1;\r\n\t\tvar iGoUp = URI(window.location.href).segment().length - number;\r\n\t\tvar sRel = '';\r\n\t\tfor (var i = 0; i < iGoUp; i++) {\r\n\t\t\tsRel += '../';\r\n\t\t}\r\n\t\t";
142
147
  moduleFileContent = `${moduleFileContent.slice(0, functionStart + funcBracket.length)}${replaceContent}${moduleFileContent.slice(posReturn)}`;
143
- updateFile(join(path, TemplateFileName.ModulePathForTests), moduleFileContent);
148
+ updateFile(fs, join(path, TemplateFileName.ModulePathForTests), moduleFileContent);
144
149
  }
145
150
  }
146
151
  }
@@ -148,75 +153,54 @@ async function updateModulePathForTests(ffNewTestPath) {
148
153
  /**
149
154
  * Update paths in test HTML files from legacy structure to new structure
150
155
  *
156
+ * @param fs
151
157
  * @param ffNewTestPath
152
158
  */
153
- async function updateTestFilePaths(ffNewTestPath) {
154
- const { getCurrentEditor } = await import('../utils/fs-adapter.js');
155
- const { hasStore } = await import('../types/mem-fs-types.js');
156
- const { sep } = await import('node:path');
157
- const editor = getCurrentEditor();
158
- // Use mem-fs store.each() to iterate over files (works in mem-fs mode)
159
- // hasStore is a type guard that narrows editor to EditorWithStore
160
- if (editor && hasStore(editor)) {
161
- const htmlFiles = [];
162
- editor.store.each((file) => {
163
- const filePath = file.path;
164
- // Check if file is directly under ffNewTestPath (not nested) and ends with .html
165
- if (filePath.startsWith(ffNewTestPath + sep) && filePath.endsWith('.html')) {
166
- // Only include files directly in the test path (no further path separators after the base)
167
- const relativePath = filePath.substring(ffNewTestPath.length + 1);
168
- if (!relativePath.includes(sep)) {
169
- htmlFiles.push(filePath);
170
- }
171
- }
172
- });
173
- for (const filePath of htmlFiles) {
174
- let content;
175
- try {
176
- content = readFile(filePath);
177
- }
178
- catch (e) {
179
- throw new MigrationError(e, filePath);
180
- }
181
- content = content.replaceAll('../../main/webapp', '../../webapp');
182
- content = content.replaceAll('/src/test/qunit', '/webapp/test');
183
- content = content.replace('<script src="../../webapp/test-resources/sap/ushell/shells/sandbox/fioriSandboxConfig.js"></script>', '');
184
- updateFile(filePath, content);
185
- }
159
+ function updateTestFilePaths(fs, ffNewTestPath) {
160
+ if (!hasStore(fs)) {
186
161
  return;
187
162
  }
188
- // Fallback to fs.promises.readdir when not in mem-fs mode (e.g., direct disk operations)
189
- const { readdir } = await import('node:fs/promises');
190
- const htmlFiles = (await readdir(ffNewTestPath)).filter((file) => file.endsWith('.html'));
191
- for (const file of htmlFiles) {
192
- const filePath = join(ffNewTestPath, file);
163
+ const htmlFiles = [];
164
+ fs.store.each((file) => {
165
+ const filePath = file.path;
166
+ // Check if file is directly under ffNewTestPath (not nested) and ends with .html
167
+ if (filePath.startsWith(ffNewTestPath + sep) && filePath.endsWith('.html')) {
168
+ // Only include files directly in the test path (no further path separators after the base)
169
+ const relativePath = filePath.substring(ffNewTestPath.length + 1);
170
+ if (!relativePath.includes(sep)) {
171
+ htmlFiles.push(filePath);
172
+ }
173
+ }
174
+ });
175
+ for (const filePath of htmlFiles) {
193
176
  let content;
194
177
  try {
195
- content = readFile(filePath);
178
+ content = readFile(fs, filePath);
196
179
  }
197
180
  catch (e) {
198
- throw new MigrationError(e, file);
181
+ throw new MigrationError(e, filePath);
199
182
  }
200
183
  content = content.replaceAll('../../main/webapp', '../../webapp');
201
184
  content = content.replaceAll('/src/test/qunit', '/webapp/test');
202
185
  content = content.replace('<script src="../../webapp/test-resources/sap/ushell/shells/sandbox/fioriSandboxConfig.js"></script>', '');
203
- updateFile(filePath, content);
186
+ updateFile(fs, filePath, content);
204
187
  }
205
188
  }
206
189
  /**
207
190
  * Update .gitignore to remove legacy path references
208
191
  *
192
+ * @param fs
209
193
  * @param rootPath
210
194
  */
211
- async function updateGitignore(rootPath) {
195
+ function updateGitignore(fs, rootPath) {
212
196
  const gitignore = join(rootPath, '.gitignore');
213
- if (!(await fileExists(gitignore))) {
197
+ if (!fileExists(fs, gitignore)) {
214
198
  return;
215
199
  }
216
200
  try {
217
- let gitignoreContent = readFile(gitignore);
201
+ let gitignoreContent = readFile(fs, gitignore);
218
202
  gitignoreContent = gitignoreContent.replaceAll('/src/main', '');
219
- updateFile(gitignore, gitignoreContent);
203
+ updateFile(fs, gitignore, gitignoreContent);
220
204
  }
221
205
  catch (e) {
222
206
  throw new MigrationError(e, '.gitignore');
@@ -227,15 +211,16 @@ async function updateGitignore(rootPath) {
227
211
  * Updates path properties structurally rather than via string replacement
228
212
  * to avoid corrupting other string-valued properties.
229
213
  *
214
+ * @param fs
230
215
  * @param rootPath
231
216
  */
232
- async function updateNeoApp(rootPath) {
217
+ async function updateNeoApp(fs, rootPath) {
233
218
  const neoapp = join(rootPath, FileName.NeoApp);
234
- if (!(await fileExists(neoapp))) {
219
+ if (!fileExists(fs, neoapp)) {
235
220
  return;
236
221
  }
237
222
  try {
238
- const neoappContent = await readJSON(neoapp);
223
+ const neoappContent = await readJSON(fs, neoapp);
239
224
  if (Array.isArray(neoappContent.routes)) {
240
225
  neoappContent.routes = neoappContent.routes.map((route) => ({
241
226
  ...route,
@@ -250,7 +235,7 @@ async function updateNeoApp(rootPath) {
250
235
  : route.target
251
236
  }));
252
237
  }
253
- updateJSON(neoapp, neoappContent);
238
+ updateJSON(fs, neoapp, neoappContent);
254
239
  }
255
240
  catch (e) {
256
241
  throw new MigrationError(e, FileName.NeoApp);
@@ -260,22 +245,23 @@ async function updateNeoApp(rootPath) {
260
245
  * Update .project.json (WEB IDE) to remove legacy path references.
261
246
  * Updates path properties structurally rather than via string replacement.
262
247
  *
248
+ * @param fs
263
249
  * @param rootPath
264
250
  */
265
- async function updateProjectJson(rootPath) {
251
+ async function updateProjectJson(fs, rootPath) {
266
252
  const projectJson = join(rootPath, '.che', 'project.json');
267
- if (!(await fileExists(projectJson))) {
253
+ if (!fileExists(fs, projectJson)) {
268
254
  return;
269
255
  }
270
256
  try {
271
- const projectJsonContent = await readJSON(projectJson);
257
+ const projectJsonContent = await readJSON(fs, projectJson);
272
258
  if (projectJsonContent.contentRoot) {
273
259
  projectJsonContent.contentRoot = projectJsonContent.contentRoot.replace('src/main', '');
274
260
  }
275
261
  if (projectJsonContent.path) {
276
262
  projectJsonContent.path = projectJsonContent.path.replace('src/main', '');
277
263
  }
278
- updateJSON(projectJson, projectJsonContent);
264
+ updateJSON(fs, projectJson, projectJsonContent);
279
265
  }
280
266
  catch (e) {
281
267
  throw new MigrationError(e, 'project.json');
@@ -285,17 +271,18 @@ async function updateProjectJson(rootPath) {
285
271
  * Check if index.html contains mockserver references
286
272
  * If it does, the file should be preserved and new index will be named index_new.html
287
273
  *
274
+ * @param fs - mem-fs editor
288
275
  * @param rootPath - Root path of the project
289
276
  * @param webappPath - Updated webapp path
290
277
  * @returns true if mockserver found and index.html should be preserved
291
278
  */
292
- async function checkForMockserver(rootPath, webappPath) {
279
+ function checkForMockserver(fs, rootPath, webappPath) {
293
280
  const indexPath = join(rootPath, webappPath, TemplateFileName.IndexHtml);
294
- if (!(await fileExists(indexPath))) {
281
+ if (!fileExists(fs, indexPath)) {
295
282
  return false;
296
283
  }
297
284
  try {
298
- const indexFile = readFile(indexPath);
285
+ const indexFile = readFile(fs, indexPath);
299
286
  // Check if mockserver is referenced (case-insensitive)
300
287
  if (indexFile.toLowerCase().includes('mockserver')) {
301
288
  // Found mockserver reference - mark that index.html should be renamed
@@ -6,10 +6,12 @@
6
6
  */
7
7
  import type { ImportProjectInfo, Message, TemplateData, NeoappDestination } from '../types.js';
8
8
  import type { SapAppSourceTemplate } from '../project-spec-types.js';
9
+ import type { Editor } from 'mem-fs-editor';
9
10
  /**
10
11
  * Configuration for generating app settings phase
11
12
  */
12
13
  export interface GenerateAppSettingsConfig {
14
+ fs: Editor;
13
15
  rootPath: string;
14
16
  templateData: TemplateData;
15
17
  destination: string;
@@ -26,6 +28,7 @@ export interface GenerateAppSettingsConfig {
26
28
  * Configuration for applying all templates phase
27
29
  */
28
30
  export interface ApplyAllTemplatesConfig {
31
+ fs: Editor;
29
32
  projectInfo: ImportProjectInfo;
30
33
  rootPath: string;
31
34
  templateData: TemplateData;
@@ -41,6 +44,7 @@ export interface ApplyAllTemplatesConfig {
41
44
  * Configuration for post-processing migration phase
42
45
  */
43
46
  export interface PostProcessMigrationConfig {
47
+ fs: Editor;
44
48
  projectInfo: ImportProjectInfo;
45
49
  rootPath: string;
46
50
  manifestJSON: any;
@@ -57,11 +61,12 @@ export interface PostProcessMigrationConfig {
57
61
  * - Create extension project manifest
58
62
  * - Create webapp folder and migrate files
59
63
  *
64
+ * @param fs - mem-fs editor
60
65
  * @param projectInfo - Project information
61
66
  * @param rootPath - Project root path
62
67
  * @returns Updated webapp path and keepIndex flag
63
68
  */
64
- export declare function setupProjectStructure(projectInfo: ImportProjectInfo, rootPath: string): Promise<{
69
+ export declare function setupProjectStructure(fs: Editor, projectInfo: ImportProjectInfo, rootPath: string): Promise<{
65
70
  webappPath: string;
66
71
  keepIndex: boolean;
67
72
  }>;
@@ -18,21 +18,22 @@ import { generateAllUI5YamlFiles, updateManifestForMigration, generateLaunchConf
18
18
  * - Create extension project manifest
19
19
  * - Create webapp folder and migrate files
20
20
  *
21
+ * @param fs - mem-fs editor
21
22
  * @param projectInfo - Project information
22
23
  * @param rootPath - Project root path
23
24
  * @returns Updated webapp path and keepIndex flag
24
25
  */
25
- export async function setupProjectStructure(projectInfo, rootPath) {
26
+ export async function setupProjectStructure(fs, projectInfo, rootPath) {
26
27
  // Migrate from FF legacy folder structure (/src/main) if applicable
27
- const { keepIndex, webappPath: updatedWebappPath } = await migrateLegacyFolderStructure(projectInfo, rootPath);
28
+ const { keepIndex, webappPath: updatedWebappPath } = await migrateLegacyFolderStructure(fs, projectInfo, rootPath);
28
29
  // Update projectInfo with the new webapp path if it changed
29
30
  if (updatedWebappPath !== projectInfo.webappPath) {
30
31
  projectInfo.webappPath = updatedWebappPath;
31
32
  }
32
33
  // Create extension project manifest if needed
33
- await createExtensionProjectManifest(rootPath, projectInfo);
34
+ createExtensionProjectManifest(fs, rootPath, projectInfo);
34
35
  // Create webapp folder and migrate files if needed
35
- await createWebappFolderAndMigrateFiles(rootPath, projectInfo);
36
+ await createWebappFolderAndMigrateFiles(fs, rootPath, projectInfo);
36
37
  // Return the final webapp path (which is now in projectInfo) and keepIndex
37
38
  return { webappPath: projectInfo.webappPath, keepIndex };
38
39
  }
@@ -44,13 +45,13 @@ export async function setupProjectStructure(projectInfo, rootPath) {
44
45
  * @param config - Configuration object containing all required parameters
45
46
  */
46
47
  export async function generateAppSettings(config) {
47
- const { rootPath, templateData, destination, webappPath, messages, sourceTemplateType, hasDataSource, neoappDestinations, sourceTemplateTest, firstNeoAppDestination, strict = false } = config;
48
+ const { fs, rootPath, templateData, destination, webappPath, messages, sourceTemplateType, hasDataSource, neoappDestinations, sourceTemplateTest, firstNeoAppDestination, strict = false } = config;
48
49
  // Determine if UI5 version should be written to YAML files
49
50
  const setUI5version = (templateData.project.manifestUI5Version !== templateData.project.ui5Version &&
50
51
  !(templateData.project.ui5Version === '' && templateData.project.manifestUI5Version === distVar)) ||
51
52
  (!templateData.project.manifestUI5Version && templateData.project.ui5Version === '');
52
53
  // Generate all UI5 YAML files
53
- await generateAllUI5YamlFiles({
54
+ await generateAllUI5YamlFiles(fs, {
54
55
  templateData,
55
56
  neoappDestinations,
56
57
  messages,
@@ -63,7 +64,16 @@ export async function generateAppSettings(config) {
63
64
  strict
64
65
  });
65
66
  // Update manifest.json
66
- await updateManifestForMigration(rootPath, webappPath, templateData, sourceTemplateType, messages, sourceTemplateTest, strict);
67
+ await updateManifestForMigration({
68
+ fs,
69
+ rootPath,
70
+ webappPath,
71
+ templateData,
72
+ floorplan: sourceTemplateType,
73
+ messages,
74
+ sourceTemplateTest,
75
+ strict
76
+ });
67
77
  }
68
78
  /**
69
79
  * Phase 3: Apply all templates
@@ -75,11 +85,12 @@ export async function generateAppSettings(config) {
75
85
  * @param config - Configuration object containing all required parameters
76
86
  */
77
87
  export async function applyAllTemplates(config) {
78
- const { projectInfo, rootPath, templateData, hasDataSource, finalKeepIndex, internalToggle, ui5Version, isSAPApp, appIntent, appMockIntent } = config;
88
+ const { fs, projectInfo, rootPath, templateData, hasDataSource, finalKeepIndex, internalToggle, ui5Version, isSAPApp, appIntent, appMockIntent } = config;
79
89
  // Setup env i.e. create necessary directories, if they don't already exist
80
- await setupMigrationDirectories(projectInfo, rootPath, hasDataSource);
90
+ await setupMigrationDirectories(fs, projectInfo, rootPath, hasDataSource);
81
91
  // Apply base application templates
82
92
  await applyBaseTemplates({
93
+ fs,
83
94
  projectInfo,
84
95
  templateData,
85
96
  rootPath,
@@ -90,6 +101,7 @@ export async function applyAllTemplates(config) {
90
101
  });
91
102
  // Apply specific application templates
92
103
  await applyApplicationTemplates({
104
+ fs,
93
105
  projectInfo,
94
106
  templateData,
95
107
  rootPath,
@@ -102,7 +114,7 @@ export async function applyAllTemplates(config) {
102
114
  FioriElementsVersionEnum: FioriElementsVersion
103
115
  });
104
116
  // Remove package-lock if exists
105
- await removePackageLock(projectInfo.rootPath);
117
+ removePackageLock(fs, projectInfo.rootPath);
106
118
  }
107
119
  /**
108
120
  * Phase 4: Post-processing
@@ -112,16 +124,16 @@ export async function applyAllTemplates(config) {
112
124
  * @param config - Configuration object containing all required parameters
113
125
  */
114
126
  export async function postProcessMigration(config) {
115
- const { projectInfo, rootPath, manifestJSON, vscode, appIntent, appMockIntent, flpSandboxAvailable, messages, strict = false } = config;
127
+ const { fs, projectInfo, rootPath, manifestJSON, vscode, appIntent, appMockIntent, flpSandboxAvailable, messages, strict = false } = config;
116
128
  // Validate metadata and add warning if missing
117
- await validateAndReportMetadata(rootPath, projectInfo, manifestJSON, messages, strict);
129
+ await validateAndReportMetadata(fs, rootPath, projectInfo, manifestJSON, messages, strict);
118
130
  if (projectInfo.type !== MigrationTypes.projectExtension) {
119
131
  // Generate Launch Config using @sap-ux/launch-config
120
- await generateLaunchConfiguration(projectInfo, vscode, appIntent, appMockIntent, flpSandboxAvailable, messages);
132
+ await generateLaunchConfiguration(fs, projectInfo, vscode, appIntent, appMockIntent, flpSandboxAvailable);
121
133
  }
122
134
  else {
123
135
  // Handle extension project configuration
124
- await handleExtensionProjectConfig(rootPath, projectInfo);
136
+ handleExtensionProjectConfig(fs, rootPath, projectInfo);
125
137
  }
126
138
  }
127
139
  //# sourceMappingURL=migration-phases.js.map
@@ -1,20 +1,23 @@
1
+ import type { Editor } from 'mem-fs-editor';
1
2
  import type { ImportProjectInfo } from '../types.js';
2
3
  /**
3
4
  * Sets up necessary directories for migration
4
- * Note: mem-fs handles directory creation implicitly when files are written
5
+ * Creates localService directory if data source exists, and test directory if webapp exists
5
6
  *
6
- * @param _projectInfo - Project information (unused - kept for API compatibility)
7
- * @param _rootPath - Root path of the project (unused - kept for API compatibility)
8
- * @param _hasDataSource - Whether project has a data source (unused - kept for API compatibility)
7
+ * @param fs - mem-fs editor
8
+ * @param projectInfo - Project information
9
+ * @param rootPath - Root path of the project
10
+ * @param hasDataSource - Whether project has a data source
9
11
  */
10
- export declare function setupMigrationDirectories(_projectInfo: ImportProjectInfo, _rootPath: string, _hasDataSource: boolean): Promise<void>;
12
+ export declare function setupMigrationDirectories(fs: Editor, projectInfo: ImportProjectInfo, rootPath: string, hasDataSource: boolean): Promise<void>;
11
13
  /**
12
14
  * Removes package-lock.json if it exists
13
15
  * Package-lock is regenerated during installation
14
16
  *
17
+ * @param fs - mem-fs editor
15
18
  * @param rootPath - Root path of the project
16
19
  */
17
- export declare function removePackageLock(rootPath: string): Promise<void>;
20
+ export declare function removePackageLock(fs: Editor, rootPath: string): void;
18
21
  /**
19
22
  * Determines the source template type for manifest.json
20
23
  *
@@ -1,28 +1,37 @@
1
1
  import { join } from 'node:path';
2
2
  import { fileExists, deleteFile } from '../utils/index.js';
3
+ import { createDirectory, doesDirectoryExists } from '../utils/file-system-utils.js';
4
+ import { DirName } from '../project-spec-types.js';
3
5
  /**
4
6
  * Sets up necessary directories for migration
5
- * Note: mem-fs handles directory creation implicitly when files are written
7
+ * Creates localService directory if data source exists, and test directory if webapp exists
6
8
  *
7
- * @param _projectInfo - Project information (unused - kept for API compatibility)
8
- * @param _rootPath - Root path of the project (unused - kept for API compatibility)
9
- * @param _hasDataSource - Whether project has a data source (unused - kept for API compatibility)
9
+ * @param fs - mem-fs editor
10
+ * @param projectInfo - Project information
11
+ * @param rootPath - Root path of the project
12
+ * @param hasDataSource - Whether project has a data source
10
13
  */
11
- export async function setupMigrationDirectories(_projectInfo, _rootPath, _hasDataSource) {
12
- // mem-fs handles directory creation implicitly when files are written to paths
13
- // No explicit directory creation needed
14
+ export async function setupMigrationDirectories(fs, projectInfo, rootPath, hasDataSource) {
15
+ if (hasDataSource) {
16
+ await createDirectory(join(rootPath, projectInfo.webappPath, DirName.LocalService), fs);
17
+ }
18
+ const webAppPath = join(rootPath, projectInfo.webappPath);
19
+ if (doesDirectoryExists(webAppPath, fs)) {
20
+ await createDirectory(join(rootPath, projectInfo.webappPath, DirName.Test), fs);
21
+ }
14
22
  }
15
23
  /**
16
24
  * Removes package-lock.json if it exists
17
25
  * Package-lock is regenerated during installation
18
26
  *
27
+ * @param fs - mem-fs editor
19
28
  * @param rootPath - Root path of the project
20
29
  */
21
- export async function removePackageLock(rootPath) {
30
+ export function removePackageLock(fs, rootPath) {
22
31
  try {
23
32
  const packageLockPath = join(rootPath, 'package-lock.json');
24
- if (await fileExists(packageLockPath)) {
25
- deleteFile(packageLockPath);
33
+ if (fileExists(fs, packageLockPath)) {
34
+ deleteFile(fs, packageLockPath);
26
35
  }
27
36
  }
28
37
  catch (error) {
@@ -1,21 +1,24 @@
1
1
  import type { Message, ImportProjectInfo } from '../types.js';
2
+ import type { Editor } from 'mem-fs-editor';
2
3
  /**
3
4
  * Validates metadata configuration and adds warning/error message if missing
4
5
  *
6
+ * @param fs - mem-fs editor
5
7
  * @param rootPath - Root path of the project
6
8
  * @param projectInfo - Project information
7
9
  * @param manifestJSON - Manifest JSON object
8
10
  * @param messages - Array to collect validation messages
9
11
  * @param strict - Enable strict validation mode (WARNING becomes ERROR)
10
12
  */
11
- export declare function validateAndReportMetadata(rootPath: string, projectInfo: ImportProjectInfo, manifestJSON: any, messages: Message[], strict?: boolean): Promise<void>;
13
+ export declare function validateAndReportMetadata(fs: Editor, rootPath: string, projectInfo: ImportProjectInfo, manifestJSON: any, messages: Message[], strict?: boolean): void;
12
14
  /**
13
15
  * Handles extension project configuration update
14
16
  *
17
+ * @param fs - mem-fs editor
15
18
  * @param rootPath - Root path of the project
16
19
  * @param projectInfo - Project information
17
20
  */
18
- export declare function handleExtensionProjectConfig(rootPath: string, projectInfo: ImportProjectInfo): Promise<void>;
21
+ export declare function handleExtensionProjectConfig(fs: Editor, rootPath: string, projectInfo: ImportProjectInfo): void;
19
22
  /**
20
23
  * Checks if any error messages exist in the messages array
21
24
  *
@@ -6,14 +6,15 @@ import { getMessageType } from '../utils/validation-severity.js';
6
6
  /**
7
7
  * Validates metadata configuration and adds warning/error message if missing
8
8
  *
9
+ * @param fs - mem-fs editor
9
10
  * @param rootPath - Root path of the project
10
11
  * @param projectInfo - Project information
11
12
  * @param manifestJSON - Manifest JSON object
12
13
  * @param messages - Array to collect validation messages
13
14
  * @param strict - Enable strict validation mode (WARNING becomes ERROR)
14
15
  */
15
- export async function validateAndReportMetadata(rootPath, projectInfo, manifestJSON, messages, strict = false) {
16
- const metadataValidation = await validateMetadata(rootPath, projectInfo.webappPath, projectInfo.isSAPApp, manifestJSON);
16
+ export function validateAndReportMetadata(fs, rootPath, projectInfo, manifestJSON, messages, strict = false) {
17
+ const metadataValidation = validateMetadata(rootPath, projectInfo.webappPath, projectInfo.isSAPApp, manifestJSON, fs);
17
18
  if (!(metadataValidation.config && metadataValidation.fileExists) &&
18
19
  projectInfo.type !== MigrationTypes.projectExtension) {
19
20
  messages.push({
@@ -26,12 +27,13 @@ export async function validateAndReportMetadata(rootPath, projectInfo, manifestJ
26
27
  /**
27
28
  * Handles extension project configuration update
28
29
  *
30
+ * @param fs - mem-fs editor
29
31
  * @param rootPath - Root path of the project
30
32
  * @param projectInfo - Project information
31
33
  */
32
- export async function handleExtensionProjectConfig(rootPath, projectInfo) {
34
+ export function handleExtensionProjectConfig(fs, rootPath, projectInfo) {
33
35
  if (projectInfo.type === MigrationTypes.projectExtension && projectInfo.extensionProjectSettings) {
34
- await updateExtConfigJson(rootPath, projectInfo);
36
+ updateExtConfigJson(fs, rootPath, projectInfo);
35
37
  }
36
38
  }
37
39
  /**
@@ -2,6 +2,7 @@ import type { FioriElementsVersion, SapAppSourceTemplate, Manifest } from './pro
2
2
  import type { MigrationTypes, postMigrationAction } from './utils/constants.js';
3
3
  import type { CdsUi5PluginInfo } from '@sap-ux/project-access';
4
4
  import type { Annotations } from '@sap-ux/axios-extension';
5
+ import type { Editor } from 'mem-fs-editor';
5
6
  export type { ProjectFolder } from './types/project-folder.js';
6
7
  export { isProjectFolderArray } from './types/project-folder.js';
7
8
  /**
@@ -496,6 +497,7 @@ export interface TemplateModuleInfo {
496
497
  * Context for assembleTemplateData function
497
498
  */
498
499
  export interface TemplateAssemblyContext {
500
+ fs: Editor;
499
501
  projectInfo: ImportProjectInfo;
500
502
  rootPath: string;
501
503
  projectData: any;
@@ -511,7 +513,7 @@ export interface TemplateAssemblyContext {
511
513
  * Service for project data operations (package.json, entities, UI5 tooling)
512
514
  */
513
515
  export interface ProjectDataService {
514
- getPackageJson: (projectRoot: string) => Promise<any>;
516
+ getPackageJson: (projectRoot: string) => any;
515
517
  getMainEntity: (manifest: Manifest) => string;
516
518
  hasUI5Tooling: (packageJson: any) => boolean;
517
519
  }
@@ -533,7 +535,7 @@ export interface BackendConfigService {
533
535
  scp?: boolean;
534
536
  sapClient?: string;
535
537
  };
536
- getFlpIntentFromHtml: (path: string) => Promise<string | undefined>;
538
+ getFlpIntentFromHtml: (path: string) => string | undefined;
537
539
  getDestinationFromNeoApp: (projectRoot: string, destination: string) => Promise<{
538
540
  destination?: string;
539
541
  neoAppUI5Version?: string;
@@ -545,6 +547,7 @@ export interface BackendConfigService {
545
547
  * Context for processRegularProject function
546
548
  */
547
549
  export interface RegularProjectContext {
550
+ fs: Editor;
548
551
  projectRoot: string;
549
552
  manifest: Manifest;
550
553
  defaultProjectInfo: ImportProjectInfo;