@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
@@ -1,3 +1,4 @@
1
+ import type { Editor } from 'mem-fs-editor';
1
2
  /**
2
3
  * Result of backend and i18n configuration extraction
3
4
  */
@@ -12,6 +13,7 @@ export interface BackendAndI18nConfigResult {
12
13
  * Extract backend configuration and app title from i18n properties
13
14
  * Combines backend settings from UI5 backend config with i18n app title extraction
14
15
  *
16
+ * @param fs - mem-fs editor
15
17
  * @param projectRoot - Root path of the project
16
18
  * @param webappPath - Webapp path within the project
17
19
  * @param getFirstBackend - Function to get the first backend configuration
@@ -21,10 +23,29 @@ export interface BackendAndI18nConfigResult {
21
23
  * @param existingSapClient - Existing sapClient value
22
24
  * @returns Backend and i18n configuration result
23
25
  */
24
- export declare function extractBackendAndI18nConfig(projectRoot: string, webappPath: string, getFirstBackend: (projectRoot: string) => {
25
- destination?: string;
26
- scp?: boolean;
27
- url?: string;
28
- sapClient?: string;
29
- }, existingDestination: string, existingScp: boolean | undefined, existingHostname: string, existingSapClient: string): Promise<BackendAndI18nConfigResult>;
26
+ /**
27
+ * Options for extractBackendAndI18nConfig
28
+ */
29
+ export interface ExtractBackendAndI18nConfigOptions {
30
+ fs: Editor;
31
+ projectRoot: string;
32
+ webappPath: string;
33
+ getFirstBackend: (projectRoot: string) => {
34
+ destination?: string;
35
+ scp?: boolean;
36
+ url?: string;
37
+ sapClient?: string;
38
+ };
39
+ existingDestination: string;
40
+ existingScp: boolean | undefined;
41
+ existingHostname: string;
42
+ existingSapClient: string;
43
+ }
44
+ /**
45
+ * Extract backend configuration and app title from i18n.
46
+ *
47
+ * @param options - Backend/i18n extraction options
48
+ * @returns Backend and i18n configuration result
49
+ */
50
+ export declare function extractBackendAndI18nConfig(options: ExtractBackendAndI18nConfigOptions): Promise<BackendAndI18nConfigResult>;
30
51
  //# sourceMappingURL=backend-i18n.d.ts.map
@@ -5,19 +5,13 @@ import { join } from 'node:path';
5
5
  import { fileExists } from '../utils/index.js';
6
6
  import { getPropertiesI18nBundle } from '@sap-ux/i18n';
7
7
  /**
8
- * Extract backend configuration and app title from i18n properties
9
- * Combines backend settings from UI5 backend config with i18n app title extraction
8
+ * Extract backend configuration and app title from i18n.
10
9
  *
11
- * @param projectRoot - Root path of the project
12
- * @param webappPath - Webapp path within the project
13
- * @param getFirstBackend - Function to get the first backend configuration
14
- * @param existingDestination - Existing destination value
15
- * @param existingScp - Existing scp value
16
- * @param existingHostname - Existing hostname value
17
- * @param existingSapClient - Existing sapClient value
10
+ * @param options - Backend/i18n extraction options
18
11
  * @returns Backend and i18n configuration result
19
12
  */
20
- export async function extractBackendAndI18nConfig(projectRoot, webappPath, getFirstBackend, existingDestination, existingScp, existingHostname, existingSapClient) {
13
+ export async function extractBackendAndI18nConfig(options) {
14
+ const { fs, projectRoot, webappPath, getFirstBackend, existingDestination, existingScp, existingHostname, existingSapClient } = options;
21
15
  // Get backend configuration
22
16
  const ui5Backend = getFirstBackend(projectRoot);
23
17
  const destination = ui5Backend?.destination ?? existingDestination;
@@ -27,7 +21,7 @@ export async function extractBackendAndI18nConfig(projectRoot, webappPath, getFi
27
21
  // Extract app title from i18n
28
22
  let appTitle = '';
29
23
  const i18Path = join(projectRoot, webappPath, 'i18n/i18n.properties');
30
- if (await fileExists(i18Path)) {
24
+ if (fileExists(fs, i18Path)) {
31
25
  try {
32
26
  const i18nProperties = await getPropertiesI18nBundle(i18Path);
33
27
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -1,6 +1,7 @@
1
1
  /**
2
2
  * Helper functions for FLP (Fiori Launchpad) sandbox and app intent generation
3
3
  */
4
+ import type { Editor } from 'mem-fs-editor';
4
5
  import type { ImportProjectInfo } from '../../types.js';
5
6
  /**
6
7
  * Check if FLP sandbox is available
@@ -9,12 +10,13 @@ import type { ImportProjectInfo } from '../../types.js';
9
10
  * - OR it's a Fiori Elements V2/V4 project (will be generated)
10
11
  * - OR it's a SAP app
11
12
  *
13
+ * @param fs
12
14
  * @param rootPath
13
15
  * @param webappPath
14
16
  * @param FEVersion
15
17
  * @param isSAPApp
16
18
  */
17
- export declare function checkFlpSandboxAvailability(rootPath: string, webappPath: string, FEVersion: string | undefined, isSAPApp: boolean): Promise<boolean>;
19
+ export declare function checkFlpSandboxAvailability(fs: Editor, rootPath: string, webappPath: string, FEVersion: string | undefined, isSAPApp: boolean): boolean;
18
20
  /**
19
21
  * Generate app intent based on project configuration and semantic object
20
22
  * App intent format depends on FE version and whether FLP sandbox is available
@@ -39,12 +41,13 @@ export declare function generateAppMockIntent(semanticObject: string, flpSandbox
39
41
  * Generate all FLP-related intents and availability flags
40
42
  * Consolidates FLP sandbox checking and intent generation
41
43
  *
44
+ * @param fs
42
45
  * @param projectInfo
43
46
  * @param semanticObject
44
47
  */
45
- export declare function prepareFlpConfiguration(projectInfo: ImportProjectInfo, semanticObject: string): Promise<{
48
+ export declare function prepareFlpConfiguration(fs: Editor, projectInfo: ImportProjectInfo, semanticObject: string): {
46
49
  flpSandboxAvailable: boolean;
47
50
  appIntent: string;
48
51
  appMockIntent: string;
49
- }>;
52
+ };
50
53
  //# sourceMappingURL=intent.d.ts.map
@@ -12,15 +12,16 @@ import { MigrationTypes } from '../../utils/constants.js';
12
12
  * - OR it's a Fiori Elements V2/V4 project (will be generated)
13
13
  * - OR it's a SAP app
14
14
  *
15
+ * @param fs
15
16
  * @param rootPath
16
17
  * @param webappPath
17
18
  * @param FEVersion
18
19
  * @param isSAPApp
19
20
  */
20
- export async function checkFlpSandboxAvailability(rootPath, webappPath, FEVersion, isSAPApp) {
21
+ export function checkFlpSandboxAvailability(fs, rootPath, webappPath, FEVersion, isSAPApp) {
21
22
  const testFlpSandboxHtml = 'test/flpSandbox.html';
22
23
  const flpSandboxPath = join(rootPath, webappPath, testFlpSandboxHtml);
23
- return ((await fileExists(flpSandboxPath)) ||
24
+ return (fileExists(fs, flpSandboxPath) ||
24
25
  FEVersion === FioriElementsVersion.v2 ||
25
26
  FEVersion === FioriElementsVersion.v4 ||
26
27
  isSAPApp);
@@ -63,13 +64,14 @@ export function generateAppMockIntent(semanticObject, flpSandboxAvailable, flpSa
63
64
  * Generate all FLP-related intents and availability flags
64
65
  * Consolidates FLP sandbox checking and intent generation
65
66
  *
67
+ * @param fs
66
68
  * @param projectInfo
67
69
  * @param semanticObject
68
70
  */
69
- export async function prepareFlpConfiguration(projectInfo, semanticObject) {
71
+ export function prepareFlpConfiguration(fs, projectInfo, semanticObject) {
70
72
  const { rootPath, webappPath, FEVersion, isSAPApp = false, flpSandboxFlpIntent, flpSandboxMockFlpIntent } = projectInfo;
71
73
  // Check FLP sandbox availability
72
- const flpSandboxAvailable = await checkFlpSandboxAvailability(rootPath, webappPath, FEVersion, isSAPApp);
74
+ const flpSandboxAvailable = checkFlpSandboxAvailability(fs, rootPath, webappPath, FEVersion, isSAPApp);
73
75
  // Generate app intents
74
76
  const appIntent = generateAppIntent(projectInfo, semanticObject, flpSandboxAvailable, flpSandboxFlpIntent);
75
77
  const appMockIntent = generateAppMockIntent(semanticObject, flpSandboxAvailable, flpSandboxMockFlpIntent, flpSandboxFlpIntent);
@@ -1,3 +1,4 @@
1
+ import type { Editor } from 'mem-fs-editor';
1
2
  /**
2
3
  * Result of FLP sandbox processing
3
4
  */
@@ -15,11 +16,12 @@ export interface FlpSandboxProcessingResult {
15
16
  * Process FLP sandbox HTML files to extract libraries, intents, and root intent flags
16
17
  * Handles both flpSandbox.html and flpSandboxMockServer.html in parallel
17
18
  *
19
+ * @param fs - mem-fs editor
18
20
  * @param projectRoot - Root path of the project
19
21
  * @param webappPath - Webapp path within the project
20
22
  * @param getFlpIntentFromHtml - Function to extract intent from HTML file
21
23
  * @param existingFlpIntent - Existing FLP intent (optional)
22
24
  * @returns FLP sandbox processing result
23
25
  */
24
- export declare function processFlpSandboxFiles(projectRoot: string, webappPath: string, getFlpIntentFromHtml: (path: string) => Promise<string | undefined>, existingFlpIntent?: string): Promise<FlpSandboxProcessingResult>;
26
+ export declare function processFlpSandboxFiles(fs: Editor, projectRoot: string, webappPath: string, getFlpIntentFromHtml: (path: string) => string | undefined, existingFlpIntent?: string): Promise<FlpSandboxProcessingResult>;
25
27
  //# sourceMappingURL=sandbox.d.ts.map
@@ -7,19 +7,20 @@ import { fileExists, readFile } from '../../utils/index.js';
7
7
  * Process FLP sandbox HTML files to extract libraries, intents, and root intent flags
8
8
  * Handles both flpSandbox.html and flpSandboxMockServer.html in parallel
9
9
  *
10
+ * @param fs - mem-fs editor
10
11
  * @param projectRoot - Root path of the project
11
12
  * @param webappPath - Webapp path within the project
12
13
  * @param getFlpIntentFromHtml - Function to extract intent from HTML file
13
14
  * @param existingFlpIntent - Existing FLP intent (optional)
14
15
  * @returns FLP sandbox processing result
15
16
  */
16
- export async function processFlpSandboxFiles(projectRoot, webappPath, getFlpIntentFromHtml, existingFlpIntent) {
17
+ export async function processFlpSandboxFiles(fs, projectRoot, webappPath, getFlpIntentFromHtml, existingFlpIntent) {
17
18
  const flpSandboxPath = join(projectRoot, webappPath, 'test', 'flpSandbox.html');
18
19
  const flpSandboxMockPath = join(projectRoot, webappPath, 'test', 'flpSandboxMockServer.html');
19
20
  // Process both files in parallel for better performance
20
21
  const [sandboxResult, mockResult] = await Promise.all([
21
- processSandboxFile(flpSandboxPath, getFlpIntentFromHtml, existingFlpIntent),
22
- processMockSandboxFile(flpSandboxMockPath, getFlpIntentFromHtml)
22
+ processSandboxFile(fs, flpSandboxPath, getFlpIntentFromHtml, existingFlpIntent),
23
+ processMockSandboxFile(fs, flpSandboxMockPath, getFlpIntentFromHtml)
23
24
  ]);
24
25
  return {
25
26
  flpSandboxLibs: sandboxResult.libs,
@@ -35,17 +36,18 @@ export async function processFlpSandboxFiles(projectRoot, webappPath, getFlpInte
35
36
  /**
36
37
  * Process main FLP sandbox file
37
38
  *
39
+ * @param fs - mem-fs editor
38
40
  * @param filePath - Path to flpSandbox.html
39
41
  * @param getFlpIntentFromHtml - Function to extract intent from HTML
40
42
  * @param existingFlpIntent - Existing FLP intent
41
43
  * @returns Sandbox processing result
42
44
  */
43
- async function processSandboxFile(filePath, getFlpIntentFromHtml, existingFlpIntent) {
45
+ async function processSandboxFile(fs, filePath, getFlpIntentFromHtml, existingFlpIntent) {
44
46
  try {
45
- if (!(await fileExists(filePath))) {
47
+ if (!fileExists(fs, filePath)) {
46
48
  return { libs: '', hasRootIntent: false };
47
49
  }
48
- const content = readFile(filePath);
50
+ const content = readFile(fs, filePath);
49
51
  const libs = extractDataSapUiLibs(content);
50
52
  const hasRootIntent = content.includes('rootIntent');
51
53
  const intent = await getFlpIntentFromHtml(filePath);
@@ -63,17 +65,21 @@ async function processSandboxFile(filePath, getFlpIntentFromHtml, existingFlpInt
63
65
  /**
64
66
  * Process mock FLP sandbox file
65
67
  *
68
+ * @param fs - mem-fs editor
66
69
  * @param filePath - Path to flpSandboxMockServer.html
67
70
  * @param getFlpIntentFromHtml - Function to extract intent from HTML
68
71
  * @returns Mock sandbox processing result
69
72
  */
70
- async function processMockSandboxFile(filePath, getFlpIntentFromHtml) {
73
+ async function processMockSandboxFile(fs, filePath, getFlpIntentFromHtml) {
71
74
  try {
72
- const [intent, exists] = await Promise.all([getFlpIntentFromHtml(filePath), fileExists(filePath)]);
75
+ const intent = await getFlpIntentFromHtml(filePath);
76
+ const exists = fileExists(fs, filePath);
73
77
  if (!exists) {
74
- return { hasRootIntent: false };
78
+ // flpSandboxMockServer.html is generated by the migration for any project that has a
79
+ // mock sandbox, so the launch config must target it even when it is not yet on disk.
80
+ return { hasRootIntent: false, targetFile: 'test/flpSandboxMockServer.html' };
75
81
  }
76
- const content = readFile(filePath);
82
+ const content = readFile(fs, filePath);
77
83
  const hasRootIntent = content.includes('rootIntent');
78
84
  return {
79
85
  intent,
@@ -83,8 +89,7 @@ async function processMockSandboxFile(filePath, getFlpIntentFromHtml) {
83
89
  }
84
90
  catch {
85
91
  // Expected: flpSandboxMockServer.html may not exist or may be unreadable in legacy projects.
86
- // Safe to return empty defaults - mock server configuration is optional.
87
- return { hasRootIntent: false };
92
+ return { hasRootIntent: false, targetFile: 'test/flpSandboxMockServer.html' };
88
93
  }
89
94
  }
90
95
  /**
@@ -1,16 +1,17 @@
1
1
  /**
2
2
  * Helper functions for generating VS Code launch configuration during migration
3
3
  */
4
- import type { ImportProjectInfo, Message } from '../types.js';
4
+ import type { Editor } from 'mem-fs-editor';
5
+ import type { ImportProjectInfo } from '../types.js';
5
6
  /**
6
7
  * Generate and write VS Code launch configuration for the migrated project
7
8
  *
9
+ * @param fs - mem-fs editor
8
10
  * @param projectInfo - Project information
9
11
  * @param vscode - VS Code context
10
12
  * @param appIntent - FLP app intent string (e.g., "#SemanticObject-Action")
11
13
  * @param appMockIntent - Mock intent string for FLP sandbox
12
14
  * @param flpSandboxAvailable - Whether FLP sandbox is available
13
- * @param messages - Array to collect warning/error messages
14
15
  */
15
- export declare function generateLaunchConfiguration(projectInfo: ImportProjectInfo, vscode: any, appIntent: string | undefined, appMockIntent: string | undefined, flpSandboxAvailable: boolean, messages: Message[]): Promise<void>;
16
+ export declare function generateLaunchConfiguration(fs: Editor, projectInfo: ImportProjectInfo, vscode: any, appIntent: string | undefined, appMockIntent: string | undefined, flpSandboxAvailable: boolean): Promise<void>;
16
17
  //# sourceMappingURL=launch-config.d.ts.map
@@ -9,14 +9,14 @@ import { ODataVersion } from '../types.js';
9
9
  /**
10
10
  * Generate and write VS Code launch configuration for the migrated project
11
11
  *
12
+ * @param fs - mem-fs editor
12
13
  * @param projectInfo - Project information
13
14
  * @param vscode - VS Code context
14
15
  * @param appIntent - FLP app intent string (e.g., "#SemanticObject-Action")
15
16
  * @param appMockIntent - Mock intent string for FLP sandbox
16
17
  * @param flpSandboxAvailable - Whether FLP sandbox is available
17
- * @param messages - Array to collect warning/error messages
18
18
  */
19
- export async function generateLaunchConfiguration(projectInfo, vscode, appIntent, appMockIntent, flpSandboxAvailable, messages) {
19
+ export async function generateLaunchConfiguration(fs, projectInfo, vscode, appIntent, appMockIntent, flpSandboxAvailable) {
20
20
  const projectName = projectInfo.rootPath.split(pathSep).pop();
21
21
  const targetFolder = join(projectInfo.rootPath, '..');
22
22
  const projectPath = join(targetFolder, projectName);
@@ -42,19 +42,8 @@ export async function generateLaunchConfiguration(projectInfo, vscode, appIntent
42
42
  projectRoot: projectPath,
43
43
  debugOptions
44
44
  };
45
- // Generate launch config using @sap-ux/launch-config
46
- const fsEditor = await createLaunchConfig(projectPath, fioriOptions);
47
- // Commit the changes to filesystem
48
- await new Promise((resolve) => {
49
- fsEditor.commit((err) => {
50
- if (err) {
51
- messages.push({
52
- type: 'ERROR',
53
- description: `Error committing changes while configuring launch json file: ${err}`
54
- });
55
- }
56
- resolve();
57
- });
58
- });
45
+ // Generate launch config using @sap-ux/launch-config, writing into the shared editor.
46
+ // The migration commits the editor once at the end, so no separate commit here.
47
+ await createLaunchConfig(projectPath, fioriOptions, fs);
59
48
  }
60
49
  //# sourceMappingURL=launch-config.js.map
@@ -1,11 +1,13 @@
1
1
  /**
2
2
  * Helper functions for updating manifest.json during migration
3
3
  */
4
+ import type { Editor } from 'mem-fs-editor';
4
5
  import type { SapAppSourceTemplate } from '../project-spec-types.js';
5
6
  import type { TemplateData, Message } from '../types.js';
6
7
  /**
7
8
  * Update manifest.json file with migration-specific changes
8
9
  *
10
+ * @param fs - mem-fs editor
9
11
  * @param rootPath - Root path of the project
10
12
  * @param webappPath - Webapp path relative to root
11
13
  * @param templateData - Template data containing project configuration
@@ -14,5 +16,23 @@ import type { TemplateData, Message } from '../types.js';
14
16
  * @param sourceTemplateTest - Test-only source template values
15
17
  * @param strict - Enable strict validation mode (WARNING becomes ERROR)
16
18
  */
17
- export declare function updateManifestForMigration(rootPath: string, webappPath: string, templateData: TemplateData, floorplan: string, messages: Message[], sourceTemplateTest?: SapAppSourceTemplate, strict?: boolean): Promise<void>;
19
+ /**
20
+ * Options for updateManifestForMigration
21
+ */
22
+ export interface UpdateManifestForMigrationOptions {
23
+ fs: Editor;
24
+ rootPath: string;
25
+ webappPath: string;
26
+ templateData: TemplateData;
27
+ floorplan: string;
28
+ messages: Message[];
29
+ sourceTemplateTest?: SapAppSourceTemplate;
30
+ strict?: boolean;
31
+ }
32
+ /**
33
+ * Update manifest.json for migration.
34
+ *
35
+ * @param options - Manifest update options
36
+ */
37
+ export declare function updateManifestForMigration(options: UpdateManifestForMigrationOptions): Promise<void>;
18
38
  //# sourceMappingURL=manifest-update.d.ts.map
@@ -10,24 +10,19 @@ import { i18nText } from '../i18n.js';
10
10
  import { processDataSource } from './manifest-update-helpers.js';
11
11
  import { getMessageType } from '../utils/validation-severity.js';
12
12
  /**
13
- * Update manifest.json file with migration-specific changes
13
+ * Update manifest.json for migration.
14
14
  *
15
- * @param rootPath - Root path of the project
16
- * @param webappPath - Webapp path relative to root
17
- * @param templateData - Template data containing project configuration
18
- * @param floorplan - Floor plan type
19
- * @param messages - Array to collect warning messages
20
- * @param sourceTemplateTest - Test-only source template values
21
- * @param strict - Enable strict validation mode (WARNING becomes ERROR)
15
+ * @param options - Manifest update options
22
16
  */
23
- export async function updateManifestForMigration(rootPath, webappPath, templateData, floorplan, messages, sourceTemplateTest, strict = false) {
17
+ export async function updateManifestForMigration(options) {
18
+ const { fs, rootPath, webappPath, templateData, floorplan, messages, sourceTemplateTest, strict = false } = options;
24
19
  const manifestPath = join(webappPath, TemplateFileName.ManifestJson);
25
- if (!(await fileExists(join(rootPath, manifestPath)))) {
20
+ if (!fileExists(fs, join(rootPath, manifestPath))) {
26
21
  return;
27
22
  }
28
23
  let manifestJson;
29
24
  try {
30
- manifestJson = await readJSON(join(rootPath, manifestPath));
25
+ manifestJson = await readJSON(fs, join(rootPath, manifestPath));
31
26
  }
32
27
  catch (e) {
33
28
  throw new MigrationError(e, TemplateFileName.ManifestJson);
@@ -55,7 +50,7 @@ export async function updateManifestForMigration(rootPath, webappPath, templateD
55
50
  });
56
51
  }
57
52
  if (saveFile === true) {
58
- updateJSON(join(rootPath, manifestPath), manifestJson);
53
+ updateJSON(fs, join(rootPath, manifestPath), manifestJson);
59
54
  }
60
55
  }
61
56
  /**
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * Helper functions for generating package.json configuration during migration
3
3
  */
4
+ import type { Editor } from 'mem-fs-editor';
4
5
  import type { PackageJsonMigrate, PackageJsonContext } from '../types.js';
5
6
  /**
6
7
  * Generate package.json configuration for migration
7
8
  *
9
+ * @param fs - mem-fs editor
8
10
  * @param context - Configuration context containing all necessary parameters
9
11
  * @returns Package.json configuration object
10
12
  */
11
- export declare function generatePackageJsonConfig(context: PackageJsonContext): Promise<PackageJsonMigrate>;
13
+ export declare function generatePackageJsonConfig(fs: Editor, context: PackageJsonContext): PackageJsonMigrate;
12
14
  //# sourceMappingURL=package-json.d.ts.map
@@ -22,10 +22,11 @@ const TEST_FILES = [
22
22
  /**
23
23
  * Generate package.json configuration for migration
24
24
  *
25
+ * @param fs - mem-fs editor
25
26
  * @param context - Configuration context containing all necessary parameters
26
27
  * @returns Package.json configuration object
27
28
  */
28
- export async function generatePackageJsonConfig(context) {
29
+ export function generatePackageJsonConfig(fs, context) {
29
30
  const { projectInfo, moduleName, moduleDescription, sapClient, dependencies, flpConfig, flags } = context;
30
31
  const { devDependencies, ui5Dependencies, v4MockServerDep } = dependencies;
31
32
  const { semanticObject, appIntent, appMockIntent, testFlpSandboxHtml, urlParam } = flpConfig;
@@ -49,21 +50,26 @@ export async function generatePackageJsonConfig(context) {
49
50
  command: `fiori run --open 'editor.html'`
50
51
  });
51
52
  }
52
- // Check for test files and add corresponding scripts in parallel
53
- const testScriptResults = await Promise.all(TEST_FILES.map(async (testFile) => {
53
+ // Check for test files and add corresponding scripts
54
+ const testScriptResults = TEST_FILES.map((testFile) => {
54
55
  const scriptName = `${testFile.type}-tests`;
55
- const exists = await fileExists(join(projectInfo.rootPath, projectInfo.webappPath, testFile.path));
56
- const alreadyExists = runTasks.some((runTask) => runTask.name === scriptName);
57
- if (exists && !alreadyExists) {
56
+ const exists = fileExists(fs, join(projectInfo.rootPath, projectInfo.webappPath, testFile.path));
57
+ if (exists) {
58
58
  return {
59
59
  name: scriptName,
60
60
  command: String.raw `fiori run --open \"${testFile.path}\"`
61
61
  };
62
62
  }
63
63
  return null;
64
- }));
65
- // Add non-null test scripts to runTasks
66
- runTasks.push(...testScriptResults.filter((script) => script !== null));
64
+ });
65
+ // Add non-null test scripts to runTasks, deduplicating by script name (first match wins)
66
+ const seenScriptNames = new Set(runTasks.map((t) => t.name));
67
+ for (const script of testScriptResults) {
68
+ if (script !== null && !seenScriptNames.has(script.name)) {
69
+ runTasks.push(script);
70
+ seenScriptNames.add(script.name);
71
+ }
72
+ }
67
73
  // Clone UI5 dependencies and add V4 mock server if needed
68
74
  const ui5DepsCloned = [...ui5Dependencies];
69
75
  if (odataVersion === ODataVersion.v4) {
@@ -4,6 +4,7 @@
4
4
  *
5
5
  * Uses modern @sap-ux/ui5-config API via adapter layer instead of EJS templates.
6
6
  */
7
+ import type { Editor } from 'mem-fs-editor';
7
8
  import type { TemplateData, NeoappDestination, Message } from '../types.js';
8
9
  /**
9
10
  * Configuration for generating UI5 YAML files
@@ -60,26 +61,30 @@ export interface UI5YamlAllFilesConfig {
60
61
  /**
61
62
  * Generate and write ui5.yaml file using modern @sap-ux/ui5-config API
62
63
  *
64
+ * @param fs - mem-fs editor
63
65
  * @param config - Configuration object containing all required parameters
64
66
  */
65
- export declare function generateAndWriteUI5Yaml(config: UI5YamlGenerationConfig): Promise<void>;
67
+ export declare function generateAndWriteUI5Yaml(fs: Editor, config: UI5YamlGenerationConfig): Promise<void>;
66
68
  /**
67
69
  * Generate and write ui5-local.yaml file using modern @sap-ux/ui5-config API
68
70
  *
71
+ * @param fs - mem-fs editor
69
72
  * @param config - Configuration object containing all required parameters
70
73
  */
71
- export declare function generateAndWriteUI5LocalYaml(config: UI5LocalYamlGenerationConfig): Promise<void>;
74
+ export declare function generateAndWriteUI5LocalYaml(fs: Editor, config: UI5LocalYamlGenerationConfig): Promise<void>;
72
75
  /**
73
76
  * Generate and write ui5-mock.yaml file if required using modern @sap-ux/ui5-config API
74
77
  *
78
+ * @param fs - mem-fs editor
75
79
  * @param config - Configuration object containing all required parameters
76
80
  */
77
- export declare function generateAndWriteUI5MockYaml(config: UI5MockYamlGenerationConfig): Promise<void>;
81
+ export declare function generateAndWriteUI5MockYaml(fs: Editor, config: UI5MockYamlGenerationConfig): Promise<void>;
78
82
  /**
79
83
  * Generate all UI5 YAML files (ui5.yaml, ui5-local.yaml, ui5-mock.yaml)
80
84
  * using modern @sap-ux/ui5-config API
81
85
  *
86
+ * @param fs - mem-fs editor
82
87
  * @param config - Configuration object containing all required parameters
83
88
  */
84
- export declare function generateAllUI5YamlFiles(config: UI5YamlAllFilesConfig): Promise<void>;
89
+ export declare function generateAllUI5YamlFiles(fs: Editor, config: UI5YamlAllFilesConfig): Promise<void>;
85
90
  //# sourceMappingURL=ui5-yaml.d.ts.map
@@ -12,9 +12,10 @@ import { generateUI5YamlContent, generateUI5LocalYamlContent, generateUI5MockYam
12
12
  /**
13
13
  * Generate and write ui5.yaml file using modern @sap-ux/ui5-config API
14
14
  *
15
+ * @param fs - mem-fs editor
15
16
  * @param config - Configuration object containing all required parameters
16
17
  */
17
- export async function generateAndWriteUI5Yaml(config) {
18
+ export async function generateAndWriteUI5Yaml(fs, config) {
18
19
  const { templateData, neoappDestinations, messages, destination, firstNeoAppDestination, webappPath, setUI5version, rootPath, strict = false } = config;
19
20
  const ui5YamlContent = await generateUI5YamlContent({
20
21
  templateData,
@@ -26,14 +27,15 @@ export async function generateAndWriteUI5Yaml(config) {
26
27
  setUI5Version: setUI5version,
27
28
  strict
28
29
  });
29
- updateFile(join(rootPath, TemplateFileName.UI5Yaml), ui5YamlContent);
30
+ updateFile(fs, join(rootPath, TemplateFileName.UI5Yaml), ui5YamlContent);
30
31
  }
31
32
  /**
32
33
  * Generate and write ui5-local.yaml file using modern @sap-ux/ui5-config API
33
34
  *
35
+ * @param fs - mem-fs editor
34
36
  * @param config - Configuration object containing all required parameters
35
37
  */
36
- export async function generateAndWriteUI5LocalYaml(config) {
38
+ export async function generateAndWriteUI5LocalYaml(fs, config) {
37
39
  const { templateData, neoappDestinations, messages, destination, firstNeoAppDestination, webappPath, rootPath, strict = false } = config;
38
40
  // Only generate for regular projects, not library or extension projects
39
41
  if (templateData.project.type !== MigrationTypes.project) {
@@ -48,14 +50,15 @@ export async function generateAndWriteUI5LocalYaml(config) {
48
50
  webappPath,
49
51
  strict
50
52
  });
51
- updateFile(join(rootPath, TemplateFileName.UI5LocalYaml), ui5LocalYamlContent);
53
+ updateFile(fs, join(rootPath, TemplateFileName.UI5LocalYaml), ui5LocalYamlContent);
52
54
  }
53
55
  /**
54
56
  * Generate and write ui5-mock.yaml file if required using modern @sap-ux/ui5-config API
55
57
  *
58
+ * @param fs - mem-fs editor
56
59
  * @param config - Configuration object containing all required parameters
57
60
  */
58
- export async function generateAndWriteUI5MockYaml(config) {
61
+ export async function generateAndWriteUI5MockYaml(fs, config) {
59
62
  const { templateData, webappPath, setUI5version, rootPath, hasDataSource } = config;
60
63
  if (!hasDataSource) {
61
64
  return;
@@ -65,19 +68,20 @@ export async function generateAndWriteUI5MockYaml(config) {
65
68
  return;
66
69
  }
67
70
  const ui5MockYamlContent = await generateUI5MockYamlContent(templateData, webappPath, setUI5version);
68
- updateFile(join(rootPath, TemplateFileName.UI5MockYaml), ui5MockYamlContent);
71
+ updateFile(fs, join(rootPath, TemplateFileName.UI5MockYaml), ui5MockYamlContent);
69
72
  }
70
73
  /**
71
74
  * Generate all UI5 YAML files (ui5.yaml, ui5-local.yaml, ui5-mock.yaml)
72
75
  * using modern @sap-ux/ui5-config API
73
76
  *
77
+ * @param fs - mem-fs editor
74
78
  * @param config - Configuration object containing all required parameters
75
79
  */
76
- export async function generateAllUI5YamlFiles(config) {
80
+ export async function generateAllUI5YamlFiles(fs, config) {
77
81
  const { templateData, neoappDestinations, messages, destination, firstNeoAppDestination, webappPath, setUI5version, rootPath, hasDataSource, strict = false } = config;
78
82
  // Generate all YAML files in parallel for better performance
79
83
  await Promise.all([
80
- generateAndWriteUI5Yaml({
84
+ generateAndWriteUI5Yaml(fs, {
81
85
  templateData,
82
86
  neoappDestinations,
83
87
  messages,
@@ -88,7 +92,7 @@ export async function generateAllUI5YamlFiles(config) {
88
92
  rootPath,
89
93
  strict
90
94
  }),
91
- generateAndWriteUI5LocalYaml({
95
+ generateAndWriteUI5LocalYaml(fs, {
92
96
  templateData,
93
97
  neoappDestinations,
94
98
  messages,
@@ -98,7 +102,7 @@ export async function generateAllUI5YamlFiles(config) {
98
102
  rootPath,
99
103
  strict
100
104
  }),
101
- generateAndWriteUI5MockYaml({
105
+ generateAndWriteUI5MockYaml(fs, {
102
106
  templateData,
103
107
  webappPath,
104
108
  setUI5version,
@@ -1,3 +1,4 @@
1
+ import type { Editor } from 'mem-fs-editor';
1
2
  /**
2
3
  * Result of SAP libraries extraction
3
4
  */
@@ -9,10 +10,11 @@ export interface SapLibrariesExtractionResult {
9
10
  * Extract and filter SAP libraries from manifest into SAPUI5 libs and reuse libs
10
11
  * Handles filtering by SAP namespaces and checking for legacy sap.ca.scfld.md in Component.js
11
12
  *
13
+ * @param fs - mem-fs editor
12
14
  * @param manifestLibsTmp - Raw libraries object from manifest['sap.ui5'].dependencies.libs
13
15
  * @param projectRoot - Root path of the project
14
16
  * @param webappPath - Webapp path within the project
15
17
  * @returns SAP libraries extraction result
16
18
  */
17
- export declare function extractSapLibraries(manifestLibsTmp: Record<string, any>, projectRoot: string, webappPath: string): Promise<SapLibrariesExtractionResult>;
19
+ export declare function extractSapLibraries(fs: Editor, manifestLibsTmp: Record<string, any>, projectRoot: string, webappPath: string): SapLibrariesExtractionResult;
18
20
  //# sourceMappingURL=sap-libraries.d.ts.map
@@ -8,12 +8,13 @@ import { sapUI5LibsNS } from '../utils/constants.js';
8
8
  * Extract and filter SAP libraries from manifest into SAPUI5 libs and reuse libs
9
9
  * Handles filtering by SAP namespaces and checking for legacy sap.ca.scfld.md in Component.js
10
10
  *
11
+ * @param fs - mem-fs editor
11
12
  * @param manifestLibsTmp - Raw libraries object from manifest['sap.ui5'].dependencies.libs
12
13
  * @param projectRoot - Root path of the project
13
14
  * @param webappPath - Webapp path within the project
14
15
  * @returns SAP libraries extraction result
15
16
  */
16
- export async function extractSapLibraries(manifestLibsTmp, projectRoot, webappPath) {
17
+ export function extractSapLibraries(fs, manifestLibsTmp, projectRoot, webappPath) {
17
18
  const manifestLibs = {};
18
19
  const reuseManifestLibs = {};
19
20
  // Filter libraries by SAP namespaces
@@ -31,9 +32,9 @@ export async function extractSapLibraries(manifestLibsTmp, projectRoot, webappPa
31
32
  // Check for sap.ca.scfld.md in component.js in older projects
32
33
  try {
33
34
  const componentJSPath = join(projectRoot, webappPath, 'Component.js');
34
- if (await fileExists(componentJSPath)) {
35
+ if (fileExists(fs, componentJSPath)) {
35
36
  // sap.ca.scfld.md
36
- const componentJsContent = readFile(componentJSPath);
37
+ const componentJsContent = readFile(fs, componentJSPath);
37
38
  if (componentJsContent.indexOf('sap.ca.scfld.md') > 0) {
38
39
  manifestLibs['sap.ca.scfld.md'] = {};
39
40
  manifestLibs['sap.collaboration'] = {};