@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
@@ -34,6 +34,7 @@ export async function processAdaptationProject(config) {
34
34
  ui5Version,
35
35
  isFioriToolsProject,
36
36
  destination,
37
+ targetMockHtmlFile: 'test/flpSandboxMockServer.html',
37
38
  ...neoAppData
38
39
  };
39
40
  if (neoAppData?.destination) {
@@ -60,7 +60,7 @@ export function createProjectData(config) {
60
60
  ui5Theme: ui5Theme,
61
61
  ui5Version: projectUI5Version,
62
62
  minSupportedUI5Version: odataVersion === ODataVersion.v4 ? minUi5VersionV4Template : defaultMinUi5Version,
63
- localUI5Version: projectUI5Version.length > 0 ? projectUI5Version : localUI5Version,
63
+ localUI5Version: localUI5Version,
64
64
  manifestUI5Version,
65
65
  neoAppUI5Version,
66
66
  sapux: !isSAPApp,
@@ -1,9 +1,11 @@
1
+ import type { Editor } from 'mem-fs-editor';
1
2
  /**
2
3
  * Validates that the project is suitable for migration.
3
4
  * Checks if project is within a CAP project structure and rejects if so.
4
5
  *
6
+ * @param fs - mem-fs editor
5
7
  * @param projectRoot - Root directory of the project to validate
6
8
  * @throws {MigrationError} If project is a Fiori app within a CAP project
7
9
  */
8
- export declare function validateProjectForMigration(projectRoot: string): Promise<void>;
10
+ export declare function validateProjectForMigration(fs: Editor, projectRoot: string): Promise<void>;
9
11
  //# sourceMappingURL=project-detection.d.ts.map
@@ -1,16 +1,22 @@
1
- import { findProjectRoot, getProjectType, fileExists } from '../utils/index.js';
1
+ import { access } from 'node:fs/promises';
2
+ import { findProjectRoot, getProjectType } from '../utils/index.js';
2
3
  import { MigrationError } from '../utils/common.js';
3
4
  import { i18nText } from '../i18n.js';
4
5
  /**
5
6
  * Validates that the project is suitable for migration.
6
7
  * Checks if project is within a CAP project structure and rejects if so.
7
8
  *
9
+ * @param fs - mem-fs editor
8
10
  * @param projectRoot - Root directory of the project to validate
9
11
  * @throws {MigrationError} If project is a Fiori app within a CAP project
10
12
  */
11
- export async function validateProjectForMigration(projectRoot) {
12
- // Quick existence check to avoid hanging on non-existent paths
13
- if (!(await fileExists(projectRoot))) {
13
+ export async function validateProjectForMigration(fs, projectRoot) {
14
+ // Quick existence check to avoid hanging on non-existent paths.
15
+ // This is a directory check on the real filesystem (mem-fs exists() only reports files).
16
+ try {
17
+ await access(projectRoot);
18
+ }
19
+ catch {
14
20
  // Path doesn't exist - skip validation (will fail later with appropriate error)
15
21
  return;
16
22
  }
@@ -24,7 +24,7 @@ export interface ProcessProjectExtensionConfig {
24
24
  url?: string;
25
25
  };
26
26
  getClientFromDestinationName: (destination: string) => string;
27
- getFlpIntentFromHtml: (path: string) => Promise<string | undefined>;
27
+ getFlpIntentFromHtml: (path: string) => string | undefined;
28
28
  getManifestJson: (projectRoot: string, webappPath: string) => Promise<Manifest>;
29
29
  }
30
30
  /**
@@ -85,7 +85,9 @@ export async function processProjectExtension(config) {
85
85
  neoappDestinations,
86
86
  extensionProjectSettings,
87
87
  ui5Version,
88
- appVersion
88
+ appVersion,
89
+ targetMockHtmlFile: 'test/flpSandboxMockServer.html',
90
+ ...(projectInfo.flpSandboxFlpIntent ? { flpSandboxFlpIntent: projectInfo.flpSandboxFlpIntent } : {})
89
91
  };
90
92
  if (manifest) {
91
93
  result.manifestUI5Version = getMinUI5VersionAsArray(manifest, true)[0] || '';
@@ -1,12 +1,14 @@
1
1
  import type { ImportProjectInfo, Message } from '../types.js';
2
+ import type { Editor } from 'mem-fs-editor';
2
3
  /**
3
4
  * Loads project information either from provided data or by fetching from project root.
4
5
  *
5
6
  * @param projectRoot - Root directory of the project
6
7
  * @param importProjectInfo - Optional project info (complete or partial overrides)
8
+ * @param fsEditor - optional mem-fs editor; a fresh one is created when omitted
7
9
  * @returns Project info and any messages
8
10
  */
9
- export declare function loadOrFetchProjectInfo(projectRoot: string, importProjectInfo?: Partial<ImportProjectInfo>): Promise<{
11
+ export declare function loadOrFetchProjectInfo(projectRoot: string, importProjectInfo?: Partial<ImportProjectInfo>, fsEditor?: Editor): Promise<{
10
12
  projectInfo: ImportProjectInfo;
11
13
  messages: Message[];
12
14
  }>;
@@ -1,12 +1,15 @@
1
1
  import { ProjectAccess } from '../utils/Project.js';
2
+ import { createMemFsEditor } from '../utils/fs-adapter.js';
2
3
  /**
3
4
  * Loads project information either from provided data or by fetching from project root.
4
5
  *
5
6
  * @param projectRoot - Root directory of the project
6
7
  * @param importProjectInfo - Optional project info (complete or partial overrides)
8
+ * @param fsEditor - optional mem-fs editor; a fresh one is created when omitted
7
9
  * @returns Project info and any messages
8
10
  */
9
- export async function loadOrFetchProjectInfo(projectRoot, importProjectInfo) {
11
+ export async function loadOrFetchProjectInfo(projectRoot, importProjectInfo, fsEditor) {
12
+ const fs = fsEditor ?? createMemFsEditor();
10
13
  let messages = [];
11
14
  let projectInfo;
12
15
  // Check if importProjectInfo is complete (has critical fields)
@@ -17,14 +20,14 @@ export async function loadOrFetchProjectInfo(projectRoot, importProjectInfo) {
17
20
  }
18
21
  else if (importProjectInfo) {
19
22
  // Fetch project info and merge with partial overrides (CLI usage)
20
- const { messages: projectInfoMsgs, projectInfo: accessProjectInfo } = await ProjectAccess.getProjectInfo(projectRoot);
23
+ const { messages: projectInfoMsgs, projectInfo: accessProjectInfo } = await ProjectAccess.getProjectInfo(projectRoot, undefined, undefined, undefined, fs);
21
24
  messages = messages.concat(projectInfoMsgs);
22
25
  // Merge CLI overrides with fetched project info
23
26
  projectInfo = { ...accessProjectInfo, ...importProjectInfo };
24
27
  }
25
28
  else {
26
29
  // No project info provided, fetch it
27
- const { messages: projectInfoMsgs, projectInfo: accessProjectInfo } = await ProjectAccess.getProjectInfo(projectRoot);
30
+ const { messages: projectInfoMsgs, projectInfo: accessProjectInfo } = await ProjectAccess.getProjectInfo(projectRoot, undefined, undefined, undefined, fs);
28
31
  messages = messages.concat(projectInfoMsgs);
29
32
  projectInfo = accessProjectInfo;
30
33
  }
@@ -16,7 +16,7 @@ import { generateSapLibsStr, checkManifestUI5Version } from '../utils/common.js'
16
16
  * @returns Project info for regular project and any messages
17
17
  */
18
18
  export async function processRegularProject(context) {
19
- const { projectRoot, manifest, defaultProjectInfo, services } = context;
19
+ const { fs, projectRoot, manifest, defaultProjectInfo, services } = context;
20
20
  let projectInfo = context.projectInfo; // Use let since this is reassigned
21
21
  const { projectData, manifestAnalysis, backendConfig } = services;
22
22
  // Extract service methods
@@ -65,7 +65,7 @@ export async function processRegularProject(context) {
65
65
  }
66
66
  // Step3. Get the template details
67
67
  try {
68
- const templateDetails = await extractTemplateDetails(manifest, projectRoot, mainService ?? '', appVersion, getVersionFromManifest, getFloorPlan);
68
+ const templateDetails = extractTemplateDetails(fs, manifest, projectRoot, mainService ?? '', appVersion, getVersionFromManifest, getFloorPlan);
69
69
  feVersion = templateDetails.feVersion;
70
70
  isSAPApp = templateDetails.isSAPApp;
71
71
  floorPlan = templateDetails.floorPlan;
@@ -75,7 +75,16 @@ export async function processRegularProject(context) {
75
75
  projectName = sapAppId;
76
76
  namespace = namespace || '';
77
77
  // Extract backend configuration and app title from i18n
78
- const backendConfig = await extractBackendAndI18nConfig(projectRoot, projectInfo.webappPath, getFirstBackend, destination, scp, hostname, sapClient);
78
+ const backendConfig = await extractBackendAndI18nConfig({
79
+ fs,
80
+ projectRoot,
81
+ webappPath: projectInfo.webappPath,
82
+ getFirstBackend,
83
+ existingDestination: destination,
84
+ existingScp: scp,
85
+ existingHostname: hostname,
86
+ existingSapClient: sapClient
87
+ });
79
88
  // Note: destination will be set from neoAppResult later (line 192)
80
89
  scp = backendConfig.scp;
81
90
  hostname = backendConfig.hostname;
@@ -86,18 +95,16 @@ export async function processRegularProject(context) {
86
95
  // @ts-ignore
87
96
  const manifestLibsTmp = manifest['sap.ui5']?.dependencies?.libs || {};
88
97
  // Extract and filter SAP libraries from manifest
89
- const { manifestLibs, reuseManifestLibs } = await extractSapLibraries(manifestLibsTmp, projectRoot, projectInfo.webappPath);
98
+ const { manifestLibs, reuseManifestLibs } = extractSapLibraries(fs, manifestLibsTmp, projectRoot, projectInfo.webappPath);
90
99
  // Process FLP sandbox files to extract libs, intents, and root intent flags
91
- const flpResult = await processFlpSandboxFiles(projectRoot, projectInfo.webappPath, getFlpIntentFromHtml, flpSandboxFlpIntent);
100
+ const flpResult = await processFlpSandboxFiles(fs, projectRoot, projectInfo.webappPath, getFlpIntentFromHtml, flpSandboxFlpIntent);
92
101
  // Assign to existing variables
93
102
  flpSandboxLibs = flpResult.flpSandboxLibs;
94
103
  flpSandboxFlpIntent = flpResult.flpSandboxFlpIntent;
95
104
  flpSandboxMockFlpIntent = flpResult.flpSandboxMockFlpIntent;
96
105
  hasRootIntent.flpSandboxRootIntent = flpResult.hasRootIntent.flpSandboxRootIntent;
97
106
  hasRootIntent.flpSandboxMockRootIntent = flpResult.hasRootIntent.flpSandboxMockRootIntent;
98
- if (flpResult.targetMockHtmlFile) {
99
- projectInfo.targetMockHtmlFile = flpResult.targetMockHtmlFile;
100
- }
107
+ const targetMockHtmlFile = flpResult.targetMockHtmlFile;
101
108
  // Process neo-app configuration and determine OData version
102
109
  const neoAppResult = await processNeoAppAndODataVersion(projectRoot, projectInfo.destination, // Use projectInfo.destination, not the local 'destination' variable
103
110
  sapClient, mainServiceDatasource, feVersion, getDestinationFromNeoApp, getClientFromDestinationName);
@@ -154,7 +161,8 @@ export async function processRegularProject(context) {
154
161
  neoappDestinations,
155
162
  firstNeoAppDestination,
156
163
  hasRootIntent,
157
- reuseLibs: Object.keys(reuseManifestLibs || {}).join(',')
164
+ reuseLibs: Object.keys(reuseManifestLibs || {}).join(','),
165
+ ...(targetMockHtmlFile ? { targetMockHtmlFile } : {})
158
166
  };
159
167
  }
160
168
  catch (error) {
@@ -1,3 +1,4 @@
1
+ import type { Editor } from 'mem-fs-editor';
1
2
  import type { FioriElementsVersion } from '../project-spec-types.js';
2
3
  import type { ImportProjectInfo, TemplateData } from '../types.js';
3
4
  import type { MigrationTypes } from '../utils/constants.js';
@@ -5,6 +6,7 @@ import type { MigrationTypes } from '../utils/constants.js';
5
6
  * Configuration for applying application templates
6
7
  */
7
8
  export interface ApplyApplicationTemplatesConfig {
9
+ fs: Editor;
8
10
  projectInfo: ImportProjectInfo;
9
11
  templateData: TemplateData;
10
12
  rootPath: string;
@@ -10,10 +10,10 @@ import { applyTemplates } from './template-helpers.js';
10
10
  * @param config - Configuration object containing all required parameters
11
11
  */
12
12
  export async function applyApplicationTemplates(config) {
13
- const { projectInfo, templateData, rootPath, appIntent, appMockIntent, hasDataSource, isSAPApp, ui5Version, MigrationTypesEnum: migrationTypesEnum, FioriElementsVersionEnum: fioriElementsVersionEnum } = config;
13
+ const { fs, projectInfo, templateData, rootPath, appIntent, appMockIntent, hasDataSource, isSAPApp, ui5Version, MigrationTypesEnum: migrationTypesEnum, FioriElementsVersionEnum: fioriElementsVersionEnum } = config;
14
14
  // Step4b. Apply specific application templates
15
15
  if (isSAPApp || projectInfo.FEVersion === fioriElementsVersionEnum.v2) {
16
- await applyV2OrSapAppTemplates(projectInfo, templateData, rootPath, {
16
+ await applyV2OrSapAppTemplates(fs, projectInfo, templateData, rootPath, {
17
17
  appIntent,
18
18
  appMockIntent,
19
19
  hasDataSource,
@@ -23,18 +23,19 @@ export async function applyApplicationTemplates(config) {
23
23
  });
24
24
  }
25
25
  else if (projectInfo.FEVersion === fioriElementsVersionEnum.v4) {
26
- await applyV4Templates(projectInfo, templateData, rootPath, appIntent, ui5Version);
26
+ await applyV4Templates(fs, projectInfo, templateData, rootPath, appIntent, ui5Version);
27
27
  }
28
28
  }
29
29
  /**
30
30
  * Applies templates for V2 Fiori Elements or SAP apps
31
31
  *
32
+ * @param fs
32
33
  * @param projectInfo
33
34
  * @param templateData
34
35
  * @param rootPath
35
36
  * @param config
36
37
  */
37
- async function applyV2OrSapAppTemplates(projectInfo, templateData, rootPath, config) {
38
+ async function applyV2OrSapAppTemplates(fs, projectInfo, templateData, rootPath, config) {
38
39
  const { appIntent, appMockIntent, hasDataSource, isSAPApp, ui5Version, migrationTypesEnum } = config;
39
40
  const appTemplates = isSAPApp ? getSapTemplatesMap() : getFeTemplatesMap(projectInfo.webappPath);
40
41
  // Only update component.js in case app has namespace and is v2
@@ -57,7 +58,7 @@ async function applyV2OrSapAppTemplates(projectInfo, templateData, rootPath, con
57
58
  templateDataFlpMock.project.flpAppId = appMockIntent?.replace('#', '');
58
59
  // Apply FLP sandbox templates (unless extension project)
59
60
  if (projectInfo.type !== migrationTypesEnum.projectExtension) {
60
- await applyTemplates({ ...getFLPSandboxTemplatesMap(projectInfo.webappPath), ...appTemplates }, templateDataFlp, rootPath, isSAPApp ? TemplateFileName.SAPApp : TemplateFileName.AppSettings, ui5Version);
61
+ await applyTemplates(fs, { ...getFLPSandboxTemplatesMap(projectInfo.webappPath), ...appTemplates }, templateDataFlp, rootPath, isSAPApp ? TemplateFileName.SAPApp : TemplateFileName.AppSettings, ui5Version);
61
62
  }
62
63
  // Apply mock server templates if data source exists
63
64
  let mockServerFiles;
@@ -66,7 +67,7 @@ async function applyV2OrSapAppTemplates(projectInfo, templateData, rootPath, con
66
67
  const mockServerFileName = templateData.mockServerJSFileName || 'mockserver';
67
68
  const mockServerJsPath = join(projectInfo.rootPath, projectInfo.webappPath, DirName.LocalService, mockServerFileName.endsWith('.js') ? mockServerFileName : `${mockServerFileName}.js`);
68
69
  // Create mockserver.js if it doesn't exist
69
- if (!(await fileExists(mockServerJsPath))) {
70
+ if (!fileExists(fs, mockServerJsPath)) {
70
71
  mockServerFiles[TemplateFileName.MockServer] = {
71
72
  path: join(DirName.Webapp, DirName.LocalService),
72
73
  targetPath: join(projectInfo.webappPath, DirName.LocalService),
@@ -74,22 +75,23 @@ async function applyV2OrSapAppTemplates(projectInfo, templateData, rootPath, con
74
75
  };
75
76
  }
76
77
  }
77
- await applyTemplates({ ...mockServerFiles, ...appTemplates }, templateDataFlpMock, rootPath, isSAPApp ? TemplateFileName.SAPApp : TemplateFileName.AppSettings, ui5Version);
78
+ await applyTemplates(fs, { ...mockServerFiles, ...appTemplates }, templateDataFlpMock, rootPath, isSAPApp ? TemplateFileName.SAPApp : TemplateFileName.AppSettings, ui5Version);
78
79
  }
79
80
  /**
80
81
  * Applies templates for V4 Fiori Elements apps
81
82
  *
83
+ * @param fs
82
84
  * @param projectInfo
83
85
  * @param templateData
84
86
  * @param rootPath
85
87
  * @param appIntent
86
88
  * @param ui5Version
87
89
  */
88
- async function applyV4Templates(projectInfo, templateData, rootPath, appIntent, ui5Version) {
90
+ async function applyV4Templates(fs, projectInfo, templateData, rootPath, appIntent, ui5Version) {
89
91
  const templateDataFlp = { ...templateData };
90
92
  templateDataFlp.project = { ...templateData.project };
91
93
  templateDataFlp.project.semanticObject = appIntent.replace('#', '');
92
94
  templateDataFlp.project.flpAppId = appIntent.replace('#', '');
93
- await applyTemplates({ ...getCommonV4TemplatesMap(projectInfo.webappPath) }, templateDataFlp, rootPath, TemplateFileName.AppSettingsV4, ui5Version);
95
+ await applyTemplates(fs, { ...getCommonV4TemplatesMap(projectInfo.webappPath) }, templateDataFlp, rootPath, TemplateFileName.AppSettingsV4, ui5Version);
94
96
  }
95
97
  //# sourceMappingURL=application.js.map
@@ -15,7 +15,7 @@ import { createUi5YamlConfig, createTemplateData, addV4MockMiddleware, setProjec
15
15
  * @returns Assembled template data and configurations
16
16
  */
17
17
  export async function assembleTemplateData(context) {
18
- const { projectInfo, rootPath, projectData, serviceData, config, moduleInfo, ui5Config, backendConfig, libraryConfig, flags } = context;
18
+ const { fs, projectInfo, rootPath, projectData, serviceData, config, moduleInfo, ui5Config, backendConfig, libraryConfig, flags } = context;
19
19
  // Extract configuration values
20
20
  const { semanticObject, fullyQualifiedProjectName, fullyQualifiedProjectNameAMD, sapUiLibs, ui5Theme, sapClientParam } = config;
21
21
  const { moduleName, moduleDescription, destination } = moduleInfo;
@@ -26,14 +26,14 @@ export async function assembleTemplateData(context) {
26
26
  const isSAPApp = projectInfo.isSAPApp || false;
27
27
  const testFlpSandboxHtml = 'test/flpSandbox.html';
28
28
  // Prepare FLP sandbox configuration and intents
29
- const { flpSandboxAvailable, appIntent, appMockIntent } = await prepareFlpConfiguration(projectInfo, semanticObject);
29
+ const { flpSandboxAvailable, appIntent, appMockIntent } = prepareFlpConfiguration(fs, projectInfo, semanticObject);
30
30
  // Generate URL parameters for different scenarios
31
31
  const urlParam = buildUrlParam(sapClientParam, disableCacheParam);
32
32
  const variantCmdUrlParam = buildUrlParam(sapClientParam, disableCacheParam, 'fiori-tools-rta-mode=true', 'sap-ui-rta-skip-flex-validation=true');
33
33
  // Read manifest.json
34
34
  let manifestJSON;
35
35
  try {
36
- manifestJSON = await readManifest(rootPath, projectInfo.webappPath, projectInfo.uiAdaptation);
36
+ manifestJSON = await readManifest(rootPath, projectInfo.webappPath, projectInfo.uiAdaptation, fs);
37
37
  }
38
38
  catch (e) {
39
39
  throw new MigrationError(e, FileName.Manifest);
@@ -44,7 +44,7 @@ export async function assembleTemplateData(context) {
44
44
  const devDependenciesTmp = {
45
45
  ...devDependencies
46
46
  };
47
- const packageJson = await generatePackageJsonConfig({
47
+ const packageJson = generatePackageJsonConfig(fs, {
48
48
  projectInfo,
49
49
  moduleName,
50
50
  moduleDescription,
@@ -1,9 +1,11 @@
1
1
  import type { FioriElementsVersion } from '../project-spec-types.js';
2
+ import type { Editor } from 'mem-fs-editor';
2
3
  import type { ImportProjectInfo, TemplateData } from '../types.js';
3
4
  /**
4
5
  * Configuration for applying base templates
5
6
  */
6
7
  export interface ApplyBaseTemplatesConfig {
8
+ fs: Editor;
7
9
  projectInfo: ImportProjectInfo;
8
10
  templateData: TemplateData;
9
11
  rootPath: string;
@@ -3,7 +3,6 @@ import { DirName } from '../project-spec-types.js';
3
3
  import { TemplateFileName } from '../index.js';
4
4
  import { trueCasePath } from 'true-case-path';
5
5
  import { getBaseTemplatesMap, isGenerateIndex } from '../utils/index.js';
6
- import { isMemFsEnabled } from '../utils/fs-adapter.js';
7
6
  import { applyTemplates } from './template-helpers.js';
8
7
  /**
9
8
  * Applies base application templates (index.html, etc.)
@@ -12,7 +11,7 @@ import { applyTemplates } from './template-helpers.js';
12
11
  * @param config - Configuration object containing all required parameters
13
12
  */
14
13
  export async function applyBaseTemplates(config) {
15
- const { projectInfo, templateData, rootPath, keepIndex, internalToggle, ui5Version, FioriElementsVersionEnum } = config;
14
+ const { fs, projectInfo, templateData, rootPath, keepIndex, internalToggle, ui5Version, FioriElementsVersionEnum } = config;
16
15
  // Step3. Apply base application templates
17
16
  // Determine mock server filename (handle case sensitivity)
18
17
  const mockServerJsPath = join(projectInfo.rootPath, projectInfo.webappPath, DirName.LocalService, TemplateFileName.MockServer);
@@ -32,33 +31,6 @@ export async function applyBaseTemplates(config) {
32
31
  ? TemplateFileName.V4IndexHtml
33
32
  : TemplateFileName.V2IndexHtml].targetName = 'index_new.html';
34
33
  }
35
- await applyTemplates(templates, templateData, rootPath, undefined, ui5Version);
36
- // Step4a. Fix local service case (handle case-sensitive filesystems)
37
- await fixLocalServiceCase(projectInfo);
38
- }
39
- /**
40
- * Fixes local service directory case on case-sensitive filesystems
41
- * Renames directory if case doesn't match expected case
42
- *
43
- * @param projectInfo - Project information
44
- */
45
- async function fixLocalServiceCase(projectInfo) {
46
- // Skip in mem-fs mode - not supported
47
- if (isMemFsEnabled()) {
48
- return;
49
- }
50
- const localServicePath = join(projectInfo.rootPath, projectInfo.webappPath, DirName.LocalService);
51
- try {
52
- const localServiceRealPath = await trueCasePath(localServicePath);
53
- // file exists. Check filename cases matches
54
- if (basename(localServiceRealPath) !== basename(localServicePath)) {
55
- // Use copy+delete pattern for mem-fs compatibility
56
- const fs = await import('node:fs');
57
- fs.renameSync(localServiceRealPath, localServicePath);
58
- }
59
- }
60
- catch (error) {
61
- // do nothing - path doesn't exist or other error
62
- }
34
+ await applyTemplates(fs, templates, templateData, rootPath, undefined, ui5Version);
63
35
  }
64
36
  //# sourceMappingURL=base.js.map
@@ -1,3 +1,4 @@
1
+ import type { Editor } from 'mem-fs-editor';
1
2
  import type { Manifest, ManifestNamespace, FioriElementsVersion } from '../project-spec-types.js';
2
3
  /**
3
4
  * Result of template details extraction
@@ -13,6 +14,7 @@ export interface TemplateDetailsExtractionResult {
13
14
  /**
14
15
  * Extract template details including FE version, floor plan, and app metadata from manifest and pom.xml
15
16
  *
17
+ * @param fs - mem-fs editor
16
18
  * @param manifest - The manifest object
17
19
  * @param projectRoot - Root path of the project
18
20
  * @param mainService - Main service name
@@ -21,5 +23,5 @@ export interface TemplateDetailsExtractionResult {
21
23
  * @param getFloorPlan - Function to get floor plan from manifest
22
24
  * @returns Template details extraction result
23
25
  */
24
- export declare function extractTemplateDetails(manifest: Manifest, projectRoot: string, mainService: string, existingAppVersion: string, getVersionFromManifest: (manifest: Manifest) => FioriElementsVersion | undefined, getFloorPlan: (manifest: Manifest, feVersion: FioriElementsVersion | undefined) => string): Promise<TemplateDetailsExtractionResult>;
26
+ export declare function extractTemplateDetails(fs: Editor, manifest: Manifest, projectRoot: string, mainService: string, existingAppVersion: string, getVersionFromManifest: (manifest: Manifest) => FioriElementsVersion | undefined, getFloorPlan: (manifest: Manifest, feVersion: FioriElementsVersion | undefined) => string): TemplateDetailsExtractionResult;
25
27
  //# sourceMappingURL=details.d.ts.map
@@ -9,6 +9,7 @@ import { isAppFreestyle } from '../utils/common.js';
9
9
  /**
10
10
  * Extract template details including FE version, floor plan, and app metadata from manifest and pom.xml
11
11
  *
12
+ * @param fs - mem-fs editor
12
13
  * @param manifest - The manifest object
13
14
  * @param projectRoot - Root path of the project
14
15
  * @param mainService - Main service name
@@ -17,12 +18,12 @@ import { isAppFreestyle } from '../utils/common.js';
17
18
  * @param getFloorPlan - Function to get floor plan from manifest
18
19
  * @returns Template details extraction result
19
20
  */
20
- export async function extractTemplateDetails(manifest, projectRoot, mainService, existingAppVersion, getVersionFromManifest, getFloorPlan) {
21
+ export function extractTemplateDetails(fs, manifest, projectRoot, mainService, existingAppVersion, getVersionFromManifest, getFloorPlan) {
21
22
  const feVersion = getVersionFromManifest(manifest);
22
23
  const isSAPApp = !feVersion ? isAppFreestyle(manifest, feVersion) : false;
23
24
  const floorPlan = !isSAPApp ? getFloorPlan(manifest, feVersion) : undefined;
24
25
  const mainServiceDatasource = extractMainServiceDatasource(manifest, mainService);
25
- const { sapAppId, appVersion } = await extractPomDetails(manifest, projectRoot, existingAppVersion);
26
+ const { sapAppId, appVersion } = extractPomDetails(fs, manifest, projectRoot, existingAppVersion);
26
27
  return {
27
28
  feVersion,
28
29
  isSAPApp,
@@ -51,19 +52,20 @@ function extractMainServiceDatasource(manifest, mainService) {
51
52
  /**
52
53
  * Extract app ID and version from pom.xml
53
54
  *
55
+ * @param fs - mem-fs editor
54
56
  * @param manifest
55
57
  * @param projectRoot
56
58
  * @param existingAppVersion
57
59
  */
58
- async function extractPomDetails(manifest, projectRoot, existingAppVersion) {
60
+ function extractPomDetails(fs, manifest, projectRoot, existingAppVersion) {
59
61
  let sapAppId = manifest['sap.app']?.id || '';
60
62
  let appVersion = existingAppVersion;
61
63
  const pomXmlPath = join(projectRoot, TemplateFileName.Pom);
62
- if (!(await fileExists(pomXmlPath))) {
64
+ if (!fileExists(fs, pomXmlPath)) {
63
65
  return { sapAppId, appVersion };
64
66
  }
65
67
  try {
66
- const pomFileStr = readFile(pomXmlPath);
68
+ const pomFileStr = readFile(fs, pomXmlPath);
67
69
  const pomJSON = xmlToJson(pomFileStr);
68
70
  if (!pomJSON) {
69
71
  return { sapAppId, appVersion };
@@ -1,12 +1,14 @@
1
+ import type { Editor } from 'mem-fs-editor';
1
2
  import type { TemplateData, TemplateMap } from '../types.js';
2
3
  /**
3
4
  * Applies EJS templates to generate project files
4
5
  *
6
+ * @param fs - mem-fs editor
5
7
  * @param templates - Map of template names to their properties
6
8
  * @param templateData - Data to populate templates with
7
9
  * @param projectRoot - Root path of the project
8
10
  * @param templateRoot - Optional root directory for templates (defaults to AppSettings)
9
11
  * @param ui5Version - Optional UI5 version for theme updates
10
12
  */
11
- export declare function applyTemplates(templates: TemplateMap, templateData: TemplateData, projectRoot: string, templateRoot?: string, ui5Version?: string): Promise<void>;
13
+ export declare function applyTemplates(fs: Editor, templates: TemplateMap, templateData: TemplateData, projectRoot: string, templateRoot?: string, ui5Version?: string): Promise<void>;
12
14
  //# sourceMappingURL=template-helpers.d.ts.map
@@ -6,20 +6,21 @@ import { MigrationTypes } from '../utils/constants.js';
6
6
  /**
7
7
  * Applies EJS templates to generate project files
8
8
  *
9
+ * @param fs - mem-fs editor
9
10
  * @param templates - Map of template names to their properties
10
11
  * @param templateData - Data to populate templates with
11
12
  * @param projectRoot - Root path of the project
12
13
  * @param templateRoot - Optional root directory for templates (defaults to AppSettings)
13
14
  * @param ui5Version - Optional UI5 version for theme updates
14
15
  */
15
- export async function applyTemplates(templates, templateData, projectRoot, templateRoot, ui5Version) {
16
+ export async function applyTemplates(fs, templates, templateData, projectRoot, templateRoot, ui5Version) {
16
17
  const baseTemplateRoot = join(templatesDirPath, templateRoot || TemplateFileName.AppSettings);
17
18
  await Promise.all(Object.keys(templates).map(async (templateName) => {
18
19
  const templateProps = templates[templateName];
19
- await generateTemplate(templateData, projectRoot, baseTemplateRoot, templateName, templateProps);
20
+ await generateTemplate(fs, templateData, projectRoot, baseTemplateRoot, templateName, templateProps);
20
21
  }));
21
22
  if (templateData.project.type === MigrationTypes.projectExtension &&
22
- (await fileExists(join(projectRoot, DirName.Webapp, TemplateFileName.IndexHtml)))) {
23
+ fileExists(fs, join(projectRoot, DirName.Webapp, TemplateFileName.IndexHtml))) {
23
24
  // For project extensions, we usually leave the index.html file unchanged.
24
25
  // However, since the Belize theme is no longer available after UI5 version 1.136.0,
25
26
  // we need to update the `data-sap-ui-theme` attribute in the index.html file
@@ -27,9 +28,9 @@ export async function applyTemplates(templates, templateData, projectRoot, templ
27
28
  const templateName = TemplateFileName.IndexHtml;
28
29
  try {
29
30
  const htmlPath = join(projectRoot, DirName.Webapp, templateName);
30
- const html = readFile(htmlPath).toString();
31
+ const html = readFile(fs, htmlPath).toString();
31
32
  const updatedHtml = updateThemeAttribute(html, ui5Version ?? '', templateData.project.ui5Theme ?? '');
32
- updateFile(htmlPath, updatedHtml);
33
+ updateFile(fs, htmlPath, updatedHtml);
33
34
  return;
34
35
  }
35
36
  catch {
@@ -1,11 +1,13 @@
1
1
  import type { ImportProjectInfo } from '../types.js';
2
+ import type { Editor } from 'mem-fs-editor';
2
3
  /**
3
4
  * Gets supported themes for the project, excluding deprecated themes.
4
5
  * Adds 'sap_bluecrystal' if not present and prefixes all with 'themelib_'.
5
6
  *
7
+ * @param fs - mem-fs editor
6
8
  * @param projectInfo - Project information containing root path and theme settings
7
9
  * @param ui5Version - UI5 version to determine excluded themes
8
10
  * @returns Array of supported theme names with 'themelib_' prefix
9
11
  */
10
- export declare function getSupportedThemes(projectInfo: ImportProjectInfo, ui5Version: string | undefined): Promise<string[]>;
12
+ export declare function getSupportedThemes(fs: Editor, projectInfo: ImportProjectInfo, ui5Version: string | undefined): Promise<string[]>;
11
13
  //# sourceMappingURL=theme.d.ts.map
@@ -4,15 +4,16 @@ import { getExcludedThemes } from '../utils/UI5Theme.js';
4
4
  * Gets supported themes for the project, excluding deprecated themes.
5
5
  * Adds 'sap_bluecrystal' if not present and prefixes all with 'themelib_'.
6
6
  *
7
+ * @param fs - mem-fs editor
7
8
  * @param projectInfo - Project information containing root path and theme settings
8
9
  * @param ui5Version - UI5 version to determine excluded themes
9
10
  * @returns Array of supported theme names with 'themelib_' prefix
10
11
  */
11
- export async function getSupportedThemes(projectInfo, ui5Version) {
12
+ export async function getSupportedThemes(fs, projectInfo, ui5Version) {
12
13
  let supportedThemes = [];
13
14
  // Try to read the manifest and extract supported themes
14
15
  try {
15
- const manifest = await readManifest(projectInfo.rootPath, projectInfo.webappPath, projectInfo.uiAdaptation);
16
+ const manifest = await readManifest(projectInfo.rootPath, projectInfo.webappPath, projectInfo.uiAdaptation, fs);
16
17
  // Get supported themes, filtering out deprecated ones
17
18
  supportedThemes =
18
19
  manifest?.['sap.ui']?.supportedThemes?.filter((theme) =>
@@ -38,7 +38,7 @@ export interface MemFsStore {
38
38
  *
39
39
  * @example
40
40
  * ```typescript
41
- * const editor = getCurrentEditor() as EditorWithStore;
41
+ * const editor = fs as EditorWithStore;
42
42
  * editor.store.each((file) => {
43
43
  * console.log(file.path);
44
44
  * });
@@ -1,3 +1,4 @@
1
+ import type { Editor } from 'mem-fs-editor';
1
2
  import type { Manifest, Package } from '../project-spec-types.js';
2
3
  import type { ImportProjectInfo, Message, MigratableFolder, ProjectFolder } from '../types.js';
3
4
  import { MigrationTypes } from './constants.js';
@@ -10,14 +11,16 @@ export declare class ProjectAccess {
10
11
  * @param migrationType
11
12
  * @param workspaceFolders
12
13
  * @param libPath
14
+ * @param fsEditor - optional mem-fs editor; a fresh one is created when omitted (standalone discovery)
13
15
  */
14
- static getProjectInfo(projectRoot: string, migrationType?: MigrationTypes, workspaceFolders?: readonly ProjectFolder[], libPath?: string): Promise<{
16
+ static getProjectInfo(projectRoot: string, migrationType?: MigrationTypes, workspaceFolders?: readonly ProjectFolder[], libPath?: string, fsEditor?: Editor): Promise<{
15
17
  projectInfo: ImportProjectInfo;
16
18
  messages: Message[];
17
19
  }>;
18
20
  /**
19
21
  * Process project based on its type
20
22
  *
23
+ * @param fs - mem-fs editor
21
24
  * @param projectType - Type of project to process
22
25
  * @param projectRoot - Project root path
23
26
  * @param manifest - Project manifest
@@ -26,36 +29,36 @@ export declare class ProjectAccess {
26
29
  * @returns Processed project info and messages
27
30
  */
28
31
  private static processProjectByType;
29
- static getWebappPath(projectRoot: string, type?: MigrationTypes, libPath?: string): Promise<string>;
32
+ static getWebappPath(projectRoot: string, type?: MigrationTypes, libPath?: string, fsEditor?: Editor): Promise<string>;
30
33
  static getManifestPath(projectRoot: string, webappPath: string): string;
31
34
  static getPackageJsonPath(projectRoot: string): string;
32
- static getPackageJson(filePath: string): Promise<any>;
33
- static getManifestJson(projectRoot: string, webappPath: string): Promise<Manifest>;
35
+ static getPackageJson(filePath: string, fsEditor?: Editor): Promise<any>;
36
+ static getManifestJson(projectRoot: string, webappPath: string, fsEditor?: Editor): Promise<Manifest>;
34
37
  static getVersionFromManifest(manifest: Manifest): import("../project-spec-types.js").FioriElementsVersion | undefined;
35
38
  static getSemanticObjectAction(manifest: Manifest): string | undefined;
36
- static getFlpIntentFromHtml(htmlFilePath: string): Promise<string | undefined>;
39
+ static getFlpIntentFromHtml(htmlFilePath: string, fsEditor?: Editor): string | undefined;
37
40
  static getFloorPlan(manifest: Manifest, feVersion: any): string;
38
41
  static getMainEntity(manifest: Manifest): string;
39
- static getFirstBackend(projectRoot: string): ReturnType<typeof getFirstBackend>;
40
- static checkMigratableAdaptationProject(projectRoot: string): Promise<any>;
41
- static checkIfReuseLib(projectRoot: string, type?: MigrationTypes, manifest?: Manifest): Promise<boolean>;
42
- static readProjectExtensionSettings(projectRoot: string): Promise<unknown>;
43
- static checkIfProjectExtension(projectRoot: string): Promise<boolean>;
44
- static isFioriToolsAdaptationProject(projectRoot: string): Promise<boolean>;
45
- static getReuseLibModuleName(projectRoot: string, workspaceFolders?: readonly ProjectFolder[], manifest?: Manifest): Promise<string>;
42
+ static getFirstBackend(projectRoot: string, fsEditor?: Editor): ReturnType<typeof getFirstBackend>;
43
+ static checkMigratableAdaptationProject(projectRoot: string, fsEditor?: Editor): Promise<any>;
44
+ static checkIfReuseLib(projectRoot: string, type?: MigrationTypes, manifest?: Manifest, fsEditor?: Editor): Promise<boolean>;
45
+ static readProjectExtensionSettings(projectRoot: string, fsEditor?: Editor): Promise<unknown>;
46
+ static checkIfProjectExtension(projectRoot: string, fsEditor?: Editor): Promise<boolean>;
47
+ static isFioriToolsAdaptationProject(projectRoot: string, fsEditor?: Editor): boolean;
48
+ static getReuseLibModuleName(projectRoot: string, workspaceFolders?: readonly ProjectFolder[], manifest?: Manifest, fsEditor?: Editor): Promise<string>;
46
49
  static getExtensionProjectModuleName(projectRoot: string, projectSettings: any, manifest?: Manifest): string;
47
50
  static getNeoAppData(neoAppJson: any, destination: string, isUiAdaptation?: boolean): {
48
51
  destination: string;
49
52
  neoAppUI5Version: string | undefined;
50
53
  neoappDestinations: import("../migration-types.js").NeoappDestination[];
51
54
  };
52
- static getDestinationFromNeoApp(projectRoot: string, destinationIn: string): Promise<{
55
+ static getDestinationFromNeoApp(projectRoot: string, destinationIn: string, fsEditor?: Editor): Promise<{
53
56
  destination: string;
54
57
  neoAppUI5Version?: string;
55
58
  neoappDestinations?: import("../migration-types.js").NeoappDestination[];
56
59
  } | undefined>;
57
60
  static getClientFromDestinationName(destination: string): string;
58
- static getProjectRoots(workspaceRoots: readonly ProjectFolder[], sapuxRequired?: boolean): Promise<MigratableFolder[]>;
61
+ static getProjectRoots(workspaceRoots: readonly ProjectFolder[], sapuxRequired?: boolean, fsEditor?: Editor): Promise<MigratableFolder[]>;
59
62
  static hasUI5Tooling(packageJSON?: Package): boolean;
60
63
  }
61
64
  //# sourceMappingURL=Project.d.ts.map