@sap-ux/fiori-migration-writer 0.0.4 → 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.
- package/dist/ProjectMigrator.d.ts +20 -8
- package/dist/ProjectMigrator.js +121 -123
- package/dist/adapters/ui5-config-adapter.js +64 -18
- package/dist/adapters/ui5-config-helpers.js +3 -10
- package/dist/components/extension.d.ts +3 -1
- package/dist/components/extension.js +5 -4
- package/dist/config/backend-i18n.d.ts +27 -6
- package/dist/config/backend-i18n.js +5 -11
- package/dist/config/flp/intent.d.ts +6 -3
- package/dist/config/flp/intent.js +6 -4
- package/dist/config/flp/sandbox.d.ts +3 -1
- package/dist/config/flp/sandbox.js +17 -12
- package/dist/config/launch-config.d.ts +4 -3
- package/dist/config/launch-config.js +5 -16
- package/dist/config/manifest-update.d.ts +21 -1
- package/dist/config/manifest-update.js +7 -12
- package/dist/config/package-json.d.ts +3 -1
- package/dist/config/package-json.js +15 -9
- package/dist/config/ui5-yaml.d.ts +9 -4
- package/dist/config/ui5-yaml.js +14 -10
- package/dist/data/sap-libraries.d.ts +3 -1
- package/dist/data/sap-libraries.js +4 -3
- package/dist/data/ui5-version.js +1 -1
- package/dist/files/project-files.d.ts +4 -3
- package/dist/files/project-files.js +10 -16
- package/dist/files/webapp.d.ts +5 -2
- package/dist/files/webapp.js +30 -35
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/migration-process/configuration.d.ts +3 -1
- package/dist/migration-process/configuration.js +3 -2
- package/dist/migration-process/legacy-helpers.d.ts +3 -1
- package/dist/migration-process/legacy-helpers.js +19 -32
- package/dist/migration-process/legacy.d.ts +3 -1
- package/dist/migration-process/legacy.js +66 -79
- package/dist/migration-process/migration-phases.d.ts +6 -1
- package/dist/migration-process/migration-phases.js +26 -14
- package/dist/migration-process/setup.d.ts +9 -6
- package/dist/migration-process/setup.js +19 -10
- package/dist/migration-process/validation.d.ts +5 -2
- package/dist/migration-process/validation.js +6 -4
- package/dist/migration-types.d.ts +5 -2
- package/dist/project/adaptation-project.js +1 -0
- package/dist/project/project-data.js +1 -1
- package/dist/project/project-detection.d.ts +3 -1
- package/dist/project/project-detection.js +10 -4
- package/dist/project/project-extension.d.ts +1 -1
- package/dist/project/project-extension.js +3 -1
- package/dist/project/project-info.d.ts +3 -1
- package/dist/project/project-info.js +6 -3
- package/dist/project/regular-project.js +17 -9
- package/dist/template/application.d.ts +2 -0
- package/dist/template/application.js +11 -9
- package/dist/template/assembly.js +4 -4
- package/dist/template/base.d.ts +2 -0
- package/dist/template/base.js +2 -30
- package/dist/template/details.d.ts +3 -1
- package/dist/template/details.js +7 -5
- package/dist/template/template-helpers.d.ts +3 -1
- package/dist/template/template-helpers.js +6 -5
- package/dist/template/theme.d.ts +3 -1
- package/dist/template/theme.js +3 -2
- package/dist/types/mem-fs-types.d.ts +1 -1
- package/dist/utils/Project.d.ts +17 -14
- package/dist/utils/Project.js +94 -72
- package/dist/utils/checkForMigration.d.ts +4 -3
- package/dist/utils/checkForMigration.js +11 -8
- package/dist/utils/file-access.d.ts +36 -34
- package/dist/utils/file-access.js +61 -93
- package/dist/utils/file-discovery.d.ts +5 -2
- package/dist/utils/file-discovery.js +6 -4
- package/dist/utils/file-system-utils.d.ts +15 -5
- package/dist/utils/file-system-utils.js +34 -11
- package/dist/utils/fs-adapter.d.ts +5 -63
- package/dist/utils/fs-adapter.js +6 -111
- package/dist/utils/manifest-and-version-utils.d.ts +3 -1
- package/dist/utils/manifest-and-version-utils.js +6 -3
- package/dist/utils/migration-utils.d.ts +3 -1
- package/dist/utils/migration-utils.js +5 -4
- package/dist/utils/project-access-adapters.d.ts +3 -1
- package/dist/utils/project-access-adapters.js +3 -2
- package/dist/utils/project-discovery.d.ts +6 -2
- package/dist/utils/project-discovery.js +44 -18
- package/dist/utils/project-readers/adaptation-project-utils.d.ts +5 -2
- package/dist/utils/project-readers/adaptation-project-utils.js +21 -16
- package/dist/utils/project-readers/backend-utils.d.ts +3 -1
- package/dist/utils/project-readers/backend-utils.js +4 -3
- package/dist/utils/project-readers/extension-project-utils.d.ts +5 -2
- package/dist/utils/project-readers/extension-project-utils.js +15 -11
- package/dist/utils/project-readers/manifest-reader.d.ts +3 -1
- package/dist/utils/project-readers/manifest-reader.js +3 -2
- package/dist/utils/project-readers/manifest-utils.d.ts +5 -2
- package/dist/utils/project-readers/manifest-utils.js +9 -6
- package/dist/utils/project-readers/package-reader.d.ts +3 -1
- package/dist/utils/project-readers/package-reader.js +3 -2
- package/dist/utils/project-readers/reuse-lib-utils.d.ts +7 -3
- package/dist/utils/project-readers/reuse-lib-utils.js +13 -7
- package/dist/utils/project-readers/webapp-path-resolver.d.ts +3 -1
- package/dist/utils/project-readers/webapp-path-resolver.js +24 -19
- package/dist/utils/service.d.ts +3 -2
- package/dist/utils/service.js +10 -6
- package/dist/utils/template/template-post-processors.d.ts +3 -1
- package/dist/utils/template/template-post-processors.js +4 -3
- package/dist/utils/template/template-renderer.d.ts +3 -1
- package/dist/utils/template/template-renderer.js +3 -2
- package/dist/utils/template-generators/file-handlers.d.ts +5 -2
- package/dist/utils/template-generators/file-handlers.js +59 -32
- package/package.json +9 -9
package/dist/utils/Project.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { dirname, join, relative, sep } from 'node:path';
|
|
2
|
+
import { createMemFsEditor } from './fs-adapter.js';
|
|
2
3
|
import { getReuseLibs, findAllProjectRoots, ReuseLibType } from './file-discovery.js';
|
|
3
4
|
import { DirName } from '../project-spec-types.js';
|
|
4
5
|
import { legacyPath, findAllWebIDEProjectFolders, findProjectsByManifest } from './common.js';
|
|
@@ -11,18 +12,19 @@ import { processRegularProject } from '../project/regular-project.js';
|
|
|
11
12
|
import { processReuseLibrary } from '../project/reuse-library.js';
|
|
12
13
|
import { i18nText } from '../i18n.js';
|
|
13
14
|
// Import extracted readers and utilities
|
|
14
|
-
import { getWebappPath, getManifestJson, getManifestPath, getPackageJson, getPackageJsonPath, getVersionFromManifest, getSemanticObjectAction, getFlpIntentFromHtml, getFloorPlan, getMainEntity, getFirstBackend, checkMigratableAdaptationProject, isFioriToolsAdaptationProject, readProjectExtensionSettings, checkIfProjectExtension, getExtensionProjectModuleName, checkIfReuseLib, findNestedReuseLibManifest, getReuseLibModuleName,
|
|
15
|
+
import { getWebappPath, getManifestJson, getManifestPath, getPackageJson, getPackageJsonPath, getVersionFromManifest, getSemanticObjectAction, getFlpIntentFromHtml, getFloorPlan, getMainEntity, getFirstBackend, checkMigratableAdaptationProject, isFioriToolsAdaptationProject, readProjectExtensionSettings, checkIfProjectExtension, getExtensionProjectModuleName, checkIfReuseLib, findNestedReuseLibManifest, getReuseLibModuleName, getClientFromDestinationName, getNeoAppData, getDestinationFromNeoApp, isSamePath } from './project-readers/index.js';
|
|
15
16
|
/**
|
|
16
17
|
* Try to load manifest from standard or legacy paths
|
|
17
18
|
*
|
|
19
|
+
* @param fs - mem-fs editor
|
|
18
20
|
* @param projectRoot - Project root path
|
|
19
21
|
* @param webappPath - Webapp path
|
|
20
22
|
* @returns Manifest and updated webapp path, or undefined if not found
|
|
21
23
|
*/
|
|
22
|
-
async function tryLoadManifest(projectRoot, webappPath) {
|
|
24
|
+
async function tryLoadManifest(fs, projectRoot, webappPath) {
|
|
23
25
|
// Try standard location first
|
|
24
26
|
try {
|
|
25
|
-
const manifest = await getManifestJson(projectRoot, webappPath);
|
|
27
|
+
const manifest = await getManifestJson(fs, projectRoot, webappPath);
|
|
26
28
|
return { manifest, updatedWebappPath: webappPath };
|
|
27
29
|
}
|
|
28
30
|
catch {
|
|
@@ -30,7 +32,7 @@ async function tryLoadManifest(projectRoot, webappPath) {
|
|
|
30
32
|
}
|
|
31
33
|
// Try legacy path
|
|
32
34
|
try {
|
|
33
|
-
const manifest = await getManifestJson(join(projectRoot, legacyPath), webappPath);
|
|
35
|
+
const manifest = await getManifestJson(fs, join(projectRoot, legacyPath), webappPath);
|
|
34
36
|
return { manifest, updatedWebappPath: join(legacyPath, webappPath) };
|
|
35
37
|
}
|
|
36
38
|
catch {
|
|
@@ -41,11 +43,12 @@ async function tryLoadManifest(projectRoot, webappPath) {
|
|
|
41
43
|
/**
|
|
42
44
|
* Try to find manifest in nested reuse lib structure
|
|
43
45
|
*
|
|
46
|
+
* @param fs - mem-fs editor
|
|
44
47
|
* @param projectRoot - Project root path
|
|
45
48
|
* @returns Manifest and webapp path if found
|
|
46
49
|
*/
|
|
47
|
-
async function tryFindNestedLibManifest(projectRoot) {
|
|
48
|
-
const nestedLib = await findNestedReuseLibManifest(projectRoot);
|
|
50
|
+
async function tryFindNestedLibManifest(fs, projectRoot) {
|
|
51
|
+
const nestedLib = await findNestedReuseLibManifest(fs, projectRoot);
|
|
49
52
|
if (nestedLib) {
|
|
50
53
|
return {
|
|
51
54
|
manifest: nestedLib.manifest,
|
|
@@ -57,6 +60,7 @@ async function tryFindNestedLibManifest(projectRoot) {
|
|
|
57
60
|
/**
|
|
58
61
|
* Handle manifest resolution when no manifest was found in standard locations
|
|
59
62
|
*
|
|
63
|
+
* @param fs - mem-fs editor
|
|
60
64
|
* @param projectRoot - Project root path
|
|
61
65
|
* @param migrationType - Migration type
|
|
62
66
|
* @param isProjectExtension - Whether project is an extension
|
|
@@ -64,13 +68,13 @@ async function tryFindNestedLibManifest(projectRoot) {
|
|
|
64
68
|
* @param checkIfReuseLib - Function to check if reuse library
|
|
65
69
|
* @returns Resolution result with manifest, webappPath, isReuseLib flag, and messages
|
|
66
70
|
*/
|
|
67
|
-
async function resolveManifestForUnknownProject(projectRoot, migrationType, isProjectExtension, checkMigratableAdaptationProject, checkIfReuseLib) {
|
|
71
|
+
async function resolveManifestForUnknownProject(fs, projectRoot, migrationType, isProjectExtension, checkMigratableAdaptationProject, checkIfReuseLib) {
|
|
68
72
|
const messages = [];
|
|
69
73
|
let isReuseLib = await checkIfReuseLib(projectRoot, migrationType);
|
|
70
74
|
let manifest;
|
|
71
75
|
let webappPath;
|
|
72
76
|
if (!isReuseLib && !isProjectExtension) {
|
|
73
|
-
const nestedLib = await tryFindNestedLibManifest(projectRoot);
|
|
77
|
+
const nestedLib = await tryFindNestedLibManifest(fs, projectRoot);
|
|
74
78
|
if (nestedLib) {
|
|
75
79
|
manifest = nestedLib.manifest;
|
|
76
80
|
webappPath = nestedLib.webappPath;
|
|
@@ -135,8 +139,10 @@ export class ProjectAccess {
|
|
|
135
139
|
* @param migrationType
|
|
136
140
|
* @param workspaceFolders
|
|
137
141
|
* @param libPath
|
|
142
|
+
* @param fsEditor - optional mem-fs editor; a fresh one is created when omitted (standalone discovery)
|
|
138
143
|
*/
|
|
139
|
-
static async getProjectInfo(projectRoot, migrationType, workspaceFolders, libPath) {
|
|
144
|
+
static async getProjectInfo(projectRoot, migrationType, workspaceFolders, libPath, fsEditor) {
|
|
145
|
+
const fs = fsEditor ?? createMemFsEditor();
|
|
140
146
|
let manifest;
|
|
141
147
|
let messages = [];
|
|
142
148
|
let isReuseLib;
|
|
@@ -146,18 +152,18 @@ export class ProjectAccess {
|
|
|
146
152
|
hasRootIntent: { ...defaultProjectInfo.hasRootIntent }
|
|
147
153
|
};
|
|
148
154
|
// Get initial webapp path
|
|
149
|
-
projectInfo.webappPath = await this.getWebappPath(projectRoot, migrationType, libPath);
|
|
155
|
+
projectInfo.webappPath = await this.getWebappPath(projectRoot, migrationType, libPath, fs);
|
|
150
156
|
// Try to load manifest from standard or legacy paths
|
|
151
|
-
const manifestResult = await tryLoadManifest(projectRoot, projectInfo.webappPath);
|
|
157
|
+
const manifestResult = await tryLoadManifest(fs, projectRoot, projectInfo.webappPath);
|
|
152
158
|
if (manifestResult) {
|
|
153
159
|
manifest = manifestResult.manifest;
|
|
154
160
|
projectInfo.webappPath = manifestResult.updatedWebappPath;
|
|
155
161
|
}
|
|
156
162
|
// Check project type flags
|
|
157
|
-
const isProjectExtension = await this.checkIfProjectExtension(projectRoot);
|
|
163
|
+
const isProjectExtension = await this.checkIfProjectExtension(projectRoot, fs);
|
|
158
164
|
// If no manifest found, resolve from unknown project structure
|
|
159
165
|
if (!manifest) {
|
|
160
|
-
const resolution = await resolveManifestForUnknownProject(projectRoot, migrationType, isProjectExtension, this.checkMigratableAdaptationProject
|
|
166
|
+
const resolution = await resolveManifestForUnknownProject(fs, projectRoot, migrationType, isProjectExtension, (root) => this.checkMigratableAdaptationProject(root, fs), (root, type) => this.checkIfReuseLib(root, type, undefined, fs));
|
|
161
167
|
manifest = resolution.manifest;
|
|
162
168
|
if (resolution.webappPath) {
|
|
163
169
|
projectInfo.webappPath = resolution.webappPath;
|
|
@@ -166,13 +172,13 @@ export class ProjectAccess {
|
|
|
166
172
|
messages = messages.concat(resolution.messages);
|
|
167
173
|
}
|
|
168
174
|
// Determine reuse lib status if not yet known
|
|
169
|
-
isReuseLib ??= await this.checkIfReuseLib(projectRoot, migrationType, manifest);
|
|
175
|
+
isReuseLib ??= await this.checkIfReuseLib(projectRoot, migrationType, manifest, fs);
|
|
170
176
|
// Check adaptation project status
|
|
171
|
-
const adaptationCheck = await this.checkMigratableAdaptationProject(projectRoot);
|
|
177
|
+
const adaptationCheck = await this.checkMigratableAdaptationProject(projectRoot, fs);
|
|
172
178
|
const isAdaptationProject = adaptationCheck?.reference !== undefined;
|
|
173
179
|
// Process based on project type
|
|
174
180
|
const projectType = determineProjectType(isReuseLib, isProjectExtension, isAdaptationProject, manifest);
|
|
175
|
-
const result = await this.processProjectByType(projectType, projectRoot, manifest, projectInfo, workspaceFolders);
|
|
181
|
+
const result = await this.processProjectByType(fs, projectType, projectRoot, manifest, projectInfo, workspaceFolders);
|
|
176
182
|
projectInfo = result.projectInfo;
|
|
177
183
|
messages = messages.concat(result.messages);
|
|
178
184
|
return { projectInfo, messages };
|
|
@@ -180,6 +186,7 @@ export class ProjectAccess {
|
|
|
180
186
|
/**
|
|
181
187
|
* Process project based on its type
|
|
182
188
|
*
|
|
189
|
+
* @param fs - mem-fs editor
|
|
183
190
|
* @param projectType - Type of project to process
|
|
184
191
|
* @param projectRoot - Project root path
|
|
185
192
|
* @param manifest - Project manifest
|
|
@@ -187,17 +194,18 @@ export class ProjectAccess {
|
|
|
187
194
|
* @param workspaceFolders - Workspace folders
|
|
188
195
|
* @returns Processed project info and messages
|
|
189
196
|
*/
|
|
190
|
-
static async processProjectByType(projectType, projectRoot, manifest, projectInfo, workspaceFolders) {
|
|
197
|
+
static async processProjectByType(fs, projectType, projectRoot, manifest, projectInfo, workspaceFolders) {
|
|
191
198
|
switch (projectType) {
|
|
192
199
|
case 'regular':
|
|
193
200
|
return processRegularProject({
|
|
201
|
+
fs,
|
|
194
202
|
projectRoot,
|
|
195
203
|
manifest: manifest,
|
|
196
204
|
defaultProjectInfo,
|
|
197
205
|
projectInfo,
|
|
198
206
|
services: {
|
|
199
207
|
projectData: {
|
|
200
|
-
getPackageJson: this.getPackageJson
|
|
208
|
+
getPackageJson: (filePath) => this.getPackageJson(filePath, fs),
|
|
201
209
|
getMainEntity: this.getMainEntity.bind(this),
|
|
202
210
|
hasUI5Tooling: this.hasUI5Tooling.bind(this)
|
|
203
211
|
},
|
|
@@ -207,18 +215,28 @@ export class ProjectAccess {
|
|
|
207
215
|
getFloorPlan: this.getFloorPlan.bind(this)
|
|
208
216
|
},
|
|
209
217
|
backendConfig: {
|
|
210
|
-
getFirstBackend: this.getFirstBackend
|
|
211
|
-
getFlpIntentFromHtml: this.getFlpIntentFromHtml
|
|
212
|
-
getDestinationFromNeoApp: this.getDestinationFromNeoApp
|
|
218
|
+
getFirstBackend: (root) => this.getFirstBackend(root, fs),
|
|
219
|
+
getFlpIntentFromHtml: (htmlFilePath) => this.getFlpIntentFromHtml(htmlFilePath, fs),
|
|
220
|
+
getDestinationFromNeoApp: (root, destinationIn) => this.getDestinationFromNeoApp(root, destinationIn, fs),
|
|
213
221
|
getClientFromDestinationName: this.getClientFromDestinationName.bind(this)
|
|
214
222
|
}
|
|
215
223
|
}
|
|
216
224
|
});
|
|
217
|
-
case 'reuseLib':
|
|
225
|
+
case 'reuseLib': {
|
|
226
|
+
const reuseLibInfo = await processReuseLibrary(projectRoot, defaultProjectInfo, workspaceFolders, manifest, (filePath) => this.getPackageJson(filePath, fs), this.hasUI5Tooling.bind(this), (root, folders, mf) => this.getReuseLibModuleName(root, folders, mf, fs));
|
|
218
227
|
return {
|
|
219
|
-
|
|
228
|
+
// Preserve the webappPath resolved before processReuseLibrary (e.g. from .project.json)
|
|
229
|
+
// and set the default targetMockHtmlFile for libraries.
|
|
230
|
+
projectInfo: {
|
|
231
|
+
...reuseLibInfo,
|
|
232
|
+
webappPath: projectInfo.webappPath !== DirName.Webapp
|
|
233
|
+
? projectInfo.webappPath
|
|
234
|
+
: reuseLibInfo.webappPath,
|
|
235
|
+
targetMockHtmlFile: 'test/flpSandboxMockServer.html'
|
|
236
|
+
},
|
|
220
237
|
messages: []
|
|
221
238
|
};
|
|
239
|
+
}
|
|
222
240
|
case 'extension':
|
|
223
241
|
return {
|
|
224
242
|
projectInfo: await processProjectExtension({
|
|
@@ -226,15 +244,15 @@ export class ProjectAccess {
|
|
|
226
244
|
defaultProjectInfo,
|
|
227
245
|
projectInfo,
|
|
228
246
|
manifest,
|
|
229
|
-
getPackageJson: this.getPackageJson
|
|
247
|
+
getPackageJson: (filePath) => this.getPackageJson(filePath, fs),
|
|
230
248
|
hasUI5Tooling: this.hasUI5Tooling.bind(this),
|
|
231
|
-
readProjectExtensionSettings: this.readProjectExtensionSettings
|
|
249
|
+
readProjectExtensionSettings: (root) => this.readProjectExtensionSettings(root, fs),
|
|
232
250
|
getExtensionProjectModuleName: this.getExtensionProjectModuleName.bind(this),
|
|
233
|
-
getDestinationFromNeoApp: this.getDestinationFromNeoApp
|
|
234
|
-
getFirstBackend: this.getFirstBackend
|
|
251
|
+
getDestinationFromNeoApp: (root, destinationIn) => this.getDestinationFromNeoApp(root, destinationIn, fs),
|
|
252
|
+
getFirstBackend: (root) => this.getFirstBackend(root, fs),
|
|
235
253
|
getClientFromDestinationName: this.getClientFromDestinationName.bind(this),
|
|
236
|
-
getFlpIntentFromHtml: this.getFlpIntentFromHtml
|
|
237
|
-
getManifestJson: this.getManifestJson
|
|
254
|
+
getFlpIntentFromHtml: (htmlFilePath) => this.getFlpIntentFromHtml(htmlFilePath, fs),
|
|
255
|
+
getManifestJson: (root, webappPath) => this.getManifestJson(root, webappPath, fs)
|
|
238
256
|
}),
|
|
239
257
|
messages: []
|
|
240
258
|
};
|
|
@@ -245,12 +263,12 @@ export class ProjectAccess {
|
|
|
245
263
|
projectRoot,
|
|
246
264
|
defaultProjectInfo,
|
|
247
265
|
projectInfo,
|
|
248
|
-
checkMigratableAdaptationProject: this.checkMigratableAdaptationProject
|
|
249
|
-
getPackageJson: this.getPackageJson
|
|
266
|
+
checkMigratableAdaptationProject: (root) => this.checkMigratableAdaptationProject(root, fs),
|
|
267
|
+
getPackageJson: (filePath) => this.getPackageJson(filePath, fs),
|
|
250
268
|
hasUI5Tooling: this.hasUI5Tooling.bind(this),
|
|
251
|
-
getDestinationFromNeoApp: this.getDestinationFromNeoApp
|
|
269
|
+
getDestinationFromNeoApp: (root, destinationIn) => this.getDestinationFromNeoApp(root, destinationIn, fs),
|
|
252
270
|
getClientFromDestinationName: this.getClientFromDestinationName.bind(this),
|
|
253
|
-
getFirstBackend: this.getFirstBackend
|
|
271
|
+
getFirstBackend: (root) => this.getFirstBackend(root, fs)
|
|
254
272
|
}),
|
|
255
273
|
messages: []
|
|
256
274
|
};
|
|
@@ -258,8 +276,8 @@ export class ProjectAccess {
|
|
|
258
276
|
}
|
|
259
277
|
// ========== Delegated Methods to Utilities ==========
|
|
260
278
|
// These methods delegate to extracted utility modules for better organization
|
|
261
|
-
static async getWebappPath(projectRoot, type, libPath) {
|
|
262
|
-
return getWebappPath(projectRoot, type, libPath);
|
|
279
|
+
static async getWebappPath(projectRoot, type, libPath, fsEditor) {
|
|
280
|
+
return getWebappPath(fsEditor ?? createMemFsEditor(), projectRoot, type, libPath);
|
|
263
281
|
}
|
|
264
282
|
static getManifestPath(projectRoot, webappPath) {
|
|
265
283
|
return getManifestPath(projectRoot, webappPath);
|
|
@@ -267,11 +285,11 @@ export class ProjectAccess {
|
|
|
267
285
|
static getPackageJsonPath(projectRoot) {
|
|
268
286
|
return getPackageJsonPath(projectRoot);
|
|
269
287
|
}
|
|
270
|
-
static getPackageJson(filePath) {
|
|
271
|
-
return getPackageJson(filePath);
|
|
288
|
+
static getPackageJson(filePath, fsEditor) {
|
|
289
|
+
return getPackageJson(fsEditor ?? createMemFsEditor(), filePath);
|
|
272
290
|
}
|
|
273
|
-
static async getManifestJson(projectRoot, webappPath) {
|
|
274
|
-
return getManifestJson(projectRoot, webappPath);
|
|
291
|
+
static async getManifestJson(projectRoot, webappPath, fsEditor) {
|
|
292
|
+
return getManifestJson(fsEditor ?? createMemFsEditor(), projectRoot, webappPath);
|
|
275
293
|
}
|
|
276
294
|
static getVersionFromManifest(manifest) {
|
|
277
295
|
return getVersionFromManifest(manifest);
|
|
@@ -279,8 +297,8 @@ export class ProjectAccess {
|
|
|
279
297
|
static getSemanticObjectAction(manifest) {
|
|
280
298
|
return getSemanticObjectAction(manifest);
|
|
281
299
|
}
|
|
282
|
-
static
|
|
283
|
-
return getFlpIntentFromHtml(htmlFilePath);
|
|
300
|
+
static getFlpIntentFromHtml(htmlFilePath, fsEditor) {
|
|
301
|
+
return getFlpIntentFromHtml(fsEditor ?? createMemFsEditor(), htmlFilePath);
|
|
284
302
|
}
|
|
285
303
|
static getFloorPlan(manifest, feVersion) {
|
|
286
304
|
return getFloorPlan(manifest, feVersion);
|
|
@@ -288,26 +306,26 @@ export class ProjectAccess {
|
|
|
288
306
|
static getMainEntity(manifest) {
|
|
289
307
|
return getMainEntity(manifest);
|
|
290
308
|
}
|
|
291
|
-
static getFirstBackend(projectRoot) {
|
|
292
|
-
return getFirstBackend(projectRoot);
|
|
309
|
+
static getFirstBackend(projectRoot, fsEditor) {
|
|
310
|
+
return getFirstBackend(fsEditor ?? createMemFsEditor(), projectRoot);
|
|
293
311
|
}
|
|
294
|
-
static async checkMigratableAdaptationProject(projectRoot) {
|
|
295
|
-
return checkMigratableAdaptationProject(projectRoot);
|
|
312
|
+
static async checkMigratableAdaptationProject(projectRoot, fsEditor) {
|
|
313
|
+
return checkMigratableAdaptationProject(fsEditor ?? createMemFsEditor(), projectRoot);
|
|
296
314
|
}
|
|
297
|
-
static async checkIfReuseLib(projectRoot, type, manifest) {
|
|
298
|
-
return checkIfReuseLib(projectRoot, type, manifest);
|
|
315
|
+
static async checkIfReuseLib(projectRoot, type, manifest, fsEditor) {
|
|
316
|
+
return checkIfReuseLib(projectRoot, type, manifest, fsEditor ?? createMemFsEditor());
|
|
299
317
|
}
|
|
300
|
-
static async readProjectExtensionSettings(projectRoot) {
|
|
301
|
-
return readProjectExtensionSettings(projectRoot);
|
|
318
|
+
static async readProjectExtensionSettings(projectRoot, fsEditor) {
|
|
319
|
+
return readProjectExtensionSettings(fsEditor ?? createMemFsEditor(), projectRoot);
|
|
302
320
|
}
|
|
303
|
-
static async checkIfProjectExtension(projectRoot) {
|
|
304
|
-
return checkIfProjectExtension(projectRoot);
|
|
321
|
+
static async checkIfProjectExtension(projectRoot, fsEditor) {
|
|
322
|
+
return checkIfProjectExtension(fsEditor ?? createMemFsEditor(), projectRoot);
|
|
305
323
|
}
|
|
306
|
-
static
|
|
307
|
-
return isFioriToolsAdaptationProject(projectRoot);
|
|
324
|
+
static isFioriToolsAdaptationProject(projectRoot, fsEditor) {
|
|
325
|
+
return isFioriToolsAdaptationProject(fsEditor ?? createMemFsEditor(), projectRoot);
|
|
308
326
|
}
|
|
309
|
-
static async getReuseLibModuleName(projectRoot, workspaceFolders, manifest) {
|
|
310
|
-
return getReuseLibModuleName(projectRoot, workspaceFolders, manifest);
|
|
327
|
+
static async getReuseLibModuleName(projectRoot, workspaceFolders, manifest, fsEditor) {
|
|
328
|
+
return getReuseLibModuleName(projectRoot, workspaceFolders, manifest, fsEditor ?? createMemFsEditor());
|
|
311
329
|
}
|
|
312
330
|
static getExtensionProjectModuleName(projectRoot, projectSettings, manifest) {
|
|
313
331
|
return getExtensionProjectModuleName(projectRoot, projectSettings, manifest);
|
|
@@ -315,19 +333,20 @@ export class ProjectAccess {
|
|
|
315
333
|
static getNeoAppData(neoAppJson, destination, isUiAdaptation = false) {
|
|
316
334
|
return getNeoAppData(neoAppJson, destination, isUiAdaptation);
|
|
317
335
|
}
|
|
318
|
-
static async getDestinationFromNeoApp(projectRoot, destinationIn) {
|
|
319
|
-
return getDestinationFromNeoApp(projectRoot, destinationIn);
|
|
336
|
+
static async getDestinationFromNeoApp(projectRoot, destinationIn, fsEditor) {
|
|
337
|
+
return getDestinationFromNeoApp(fsEditor ?? createMemFsEditor(), projectRoot, destinationIn);
|
|
320
338
|
}
|
|
321
339
|
static getClientFromDestinationName(destination) {
|
|
322
340
|
return getClientFromDestinationName(destination);
|
|
323
341
|
}
|
|
324
342
|
// ========== Core Methods (Not Delegated) ==========
|
|
325
|
-
static async getProjectRoots(workspaceRoots, sapuxRequired = false) {
|
|
343
|
+
static async getProjectRoots(workspaceRoots, sapuxRequired = false, fsEditor) {
|
|
344
|
+
const fs = fsEditor ?? createMemFsEditor();
|
|
326
345
|
// find projects by package.json and pom.xml
|
|
327
346
|
// Convert ProjectFolder[] to string[] for project-access functions
|
|
328
347
|
const workspaceRootPaths = workspaceRoots.map((folder) => folder.uri.fsPath);
|
|
329
|
-
const packageRoots = await findAllProjectRoots(workspaceRootPaths, sapuxRequired);
|
|
330
|
-
const pomRoots = await findAllWebIDEProjectFolders(workspaceRoots);
|
|
348
|
+
const packageRoots = await findAllProjectRoots(fs, workspaceRootPaths, sapuxRequired);
|
|
349
|
+
const pomRoots = await findAllWebIDEProjectFolders(fs, workspaceRoots);
|
|
331
350
|
// find projects by manifest.json in the root
|
|
332
351
|
let manifestRoots = await findProjectsByManifest(workspaceRoots);
|
|
333
352
|
// A root can be discovered by more than one strategy (e.g. a project with both package.json
|
|
@@ -347,7 +366,7 @@ export class ProjectAccess {
|
|
|
347
366
|
};
|
|
348
367
|
});
|
|
349
368
|
// find reuse libs
|
|
350
|
-
let reuseLibsRoots = (await getReuseLibs(rootFolders)).filter((lib) => lib.value.type === ReuseLibType.LIBRARY);
|
|
369
|
+
let reuseLibsRoots = (await getReuseLibs(fs, rootFolders)).filter((lib) => lib.value.type === ReuseLibType.LIBRARY);
|
|
351
370
|
// Roots that are themselves reuse libraries must be emitted only as libraries, never also as
|
|
352
371
|
// plain projects. getReuseLibs assigns a nested library to its nearest package/pom root, so a
|
|
353
372
|
// freestyle app that merely embeds a library shares that libRoot — suppressing by libRoot alone
|
|
@@ -360,17 +379,18 @@ export class ProjectAccess {
|
|
|
360
379
|
if (reuseLibsRoots.length) {
|
|
361
380
|
const reuseLibRootPaths = new Set(reuseLibsRoots.map((lib) => lib.value.libRoot));
|
|
362
381
|
const appRoots = [];
|
|
363
|
-
//
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
382
|
+
// Resolve project info for all roots in parallel (independent lookups).
|
|
383
|
+
const rootInfos = await Promise.all(roots.map(async (root) => ({
|
|
384
|
+
root,
|
|
385
|
+
info: (await this.getProjectInfo(root, undefined, undefined, undefined, fs)).projectInfo
|
|
386
|
+
})));
|
|
387
|
+
for (const { root, info } of rootInfos) {
|
|
388
|
+
const isApp = !!(info.FEVersion || info.isSAPApp);
|
|
369
389
|
if (isApp) {
|
|
370
390
|
appRoots.push(root);
|
|
371
391
|
}
|
|
372
392
|
else if ([...reuseLibRootPaths].some((libRoot) => isSamePath(libRoot, root)) ||
|
|
373
|
-
|
|
393
|
+
info.type === MigrationTypes.library) {
|
|
374
394
|
libraryOnlyRoots.add(root);
|
|
375
395
|
}
|
|
376
396
|
}
|
|
@@ -388,14 +408,16 @@ export class ProjectAccess {
|
|
|
388
408
|
});
|
|
389
409
|
// A single library root can contain several nested manifest.json files (the library manifest
|
|
390
410
|
// plus per-component manifests), each of which getReuseLibs resolves back to the same libRoot.
|
|
391
|
-
//
|
|
392
|
-
|
|
411
|
+
// The emitted entry is keyed on libRoot (root: lib.value.libRoot), so deduplicate on libRoot —
|
|
412
|
+
// not on lib.value.path, which is distinct per nested manifest and would let the same library
|
|
413
|
+
// through multiple times. Keep the first occurrence so libRoot/libPath stay paired (PR #39527).
|
|
414
|
+
const seenLibRoots = [];
|
|
393
415
|
const reuseLibsUnique = reuseLibsRoots
|
|
394
416
|
.filter((lib) => {
|
|
395
|
-
if (
|
|
417
|
+
if (seenLibRoots.some((libRoot) => isSamePath(libRoot, lib.value.libRoot))) {
|
|
396
418
|
return false;
|
|
397
419
|
}
|
|
398
|
-
|
|
420
|
+
seenLibRoots.push(lib.value.libRoot);
|
|
399
421
|
return true;
|
|
400
422
|
})
|
|
401
423
|
.map((lib) => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import type { Editor } from 'mem-fs-editor';
|
|
1
2
|
import type { MigrationTypes } from './constants.js';
|
|
2
|
-
export declare const readMigrationSettingsFile: () => Promise<any>;
|
|
3
|
-
export declare const readMigrationSettingsFileIgnoreProjects: () => Promise<string[]>;
|
|
4
|
-
export declare const checkForMigration: (projectRoot: string, type: MigrationTypes, libPath?: string) => Promise<boolean>;
|
|
3
|
+
export declare const readMigrationSettingsFile: (fsEditor?: Editor) => Promise<any>;
|
|
4
|
+
export declare const readMigrationSettingsFileIgnoreProjects: (fsEditor?: Editor) => Promise<string[]>;
|
|
5
|
+
export declare const checkForMigration: (projectRoot: string, type: MigrationTypes, libPath?: string, fsEditor?: Editor) => Promise<boolean>;
|
|
5
6
|
//# sourceMappingURL=checkForMigration.d.ts.map
|
|
@@ -2,23 +2,26 @@ import { ProjectAccess } from './Project.js';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { getFioriToolsDirectory } from '@sap-ux/store';
|
|
4
4
|
import { FileName, FioriToolsSettings } from '@sap-ux/project-access';
|
|
5
|
+
import { createMemFsEditor } from './fs-adapter.js';
|
|
5
6
|
import { hasDependency, readJSON, findProjectRoot } from './index.js';
|
|
6
|
-
export const readMigrationSettingsFile = async () => {
|
|
7
|
+
export const readMigrationSettingsFile = async (fsEditor) => {
|
|
8
|
+
const fs = fsEditor ?? createMemFsEditor();
|
|
7
9
|
let migrationSettingsFile;
|
|
8
10
|
try {
|
|
9
|
-
migrationSettingsFile = await readJSON(join(getFioriToolsDirectory(), FioriToolsSettings.migrationSettingsFile));
|
|
11
|
+
migrationSettingsFile = await readJSON(fs, join(getFioriToolsDirectory(), FioriToolsSettings.migrationSettingsFile));
|
|
10
12
|
}
|
|
11
13
|
catch (error) {
|
|
12
14
|
migrationSettingsFile = {};
|
|
13
15
|
}
|
|
14
16
|
return migrationSettingsFile;
|
|
15
17
|
};
|
|
16
|
-
export const readMigrationSettingsFileIgnoreProjects = async () => {
|
|
17
|
-
const migrationSettingsFile = await readMigrationSettingsFile();
|
|
18
|
+
export const readMigrationSettingsFileIgnoreProjects = async (fsEditor) => {
|
|
19
|
+
const migrationSettingsFile = await readMigrationSettingsFile(fsEditor);
|
|
18
20
|
migrationSettingsFile.ignoreProjects = migrationSettingsFile?.ignoreProjects ?? [];
|
|
19
21
|
return migrationSettingsFile?.ignoreProjects;
|
|
20
22
|
};
|
|
21
|
-
export const checkForMigration = async (projectRoot, type, libPath) => {
|
|
23
|
+
export const checkForMigration = async (projectRoot, type, libPath, fsEditor) => {
|
|
24
|
+
const fs = fsEditor ?? createMemFsEditor();
|
|
22
25
|
let project = {
|
|
23
26
|
projectInfo: {},
|
|
24
27
|
messages: []
|
|
@@ -26,8 +29,8 @@ export const checkForMigration = async (projectRoot, type, libPath) => {
|
|
|
26
29
|
let packageJson;
|
|
27
30
|
let hasUi5Tooling = false;
|
|
28
31
|
try {
|
|
29
|
-
project = await ProjectAccess.getProjectInfo(projectRoot, type, undefined, libPath);
|
|
30
|
-
packageJson = await readJSON(join(projectRoot, FileName.Package));
|
|
32
|
+
project = await ProjectAccess.getProjectInfo(projectRoot, type, undefined, libPath, fs);
|
|
33
|
+
packageJson = await readJSON(fs, join(projectRoot, FileName.Package));
|
|
31
34
|
hasUi5Tooling =
|
|
32
35
|
hasDependency(packageJson, '@sap-ux/ui5-tooling') || hasDependency(packageJson, '@sap/ux-ui5-tooling');
|
|
33
36
|
}
|
|
@@ -48,7 +51,7 @@ export const checkForMigration = async (projectRoot, type, libPath) => {
|
|
|
48
51
|
Array.isArray(project.projectInfo.sapux) ||
|
|
49
52
|
project.messages.length > 0 ||
|
|
50
53
|
hasUi5Tooling === true ||
|
|
51
|
-
(await readMigrationSettingsFileIgnoreProjects()).includes(projectRoot) ||
|
|
54
|
+
(await readMigrationSettingsFileIgnoreProjects(fs)).includes(projectRoot) ||
|
|
52
55
|
sapUXProjectRoot !== projectRoot);
|
|
53
56
|
return migratable;
|
|
54
57
|
};
|
|
@@ -1,58 +1,60 @@
|
|
|
1
1
|
import type { Editor } from 'mem-fs-editor';
|
|
2
2
|
/**
|
|
3
|
-
* Read a text file
|
|
3
|
+
* Read a text file.
|
|
4
4
|
*
|
|
5
|
-
* @param
|
|
6
|
-
* @param path - Path to file
|
|
5
|
+
* @param fs - mem-fs editor
|
|
6
|
+
* @param path - Path to file
|
|
7
7
|
* @returns File contents as string
|
|
8
8
|
*/
|
|
9
|
-
export declare function readFile(
|
|
9
|
+
export declare function readFile(fs: Editor, path: string): string;
|
|
10
10
|
/**
|
|
11
|
-
* Read a JSON file
|
|
11
|
+
* Read and parse a JSON file, preserving indentation metadata (Symbol(indent))
|
|
12
|
+
* so that a later updateJSON can keep the original formatting.
|
|
12
13
|
*
|
|
13
|
-
* @param
|
|
14
|
-
* @param path - Path to file
|
|
14
|
+
* @param fs - mem-fs editor
|
|
15
|
+
* @param path - Path to file
|
|
15
16
|
* @returns Parsed JSON object
|
|
16
17
|
*/
|
|
17
|
-
export declare function readJSON<T = any>(
|
|
18
|
+
export declare function readJSON<T = any>(fs: Editor, path: string): T;
|
|
18
19
|
/**
|
|
19
|
-
* Check if a file exists
|
|
20
|
+
* Check if a file or directory exists (staged in mem-fs or present on the real filesystem).
|
|
20
21
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
22
|
+
* Unlike mem-fs's `editor.exists()`, this also reports directories as present — many migration
|
|
23
|
+
* checks test for folders (e.g. the webapp directory) — and reads through to the real filesystem
|
|
24
|
+
* so files not yet staged in mem-fs are still seen.
|
|
25
|
+
*
|
|
26
|
+
* @param fs - mem-fs editor
|
|
27
|
+
* @param path - Path to file or directory
|
|
28
|
+
* @returns true if the path exists
|
|
24
29
|
*/
|
|
25
|
-
export declare function fileExists(
|
|
30
|
+
export declare function fileExists(fs: Editor, path: string): boolean;
|
|
26
31
|
/**
|
|
27
|
-
* Write a text file
|
|
32
|
+
* Write a text file.
|
|
28
33
|
*
|
|
29
|
-
* @param
|
|
30
|
-
* @param
|
|
31
|
-
* @param content - Content to write
|
|
34
|
+
* @param fs - mem-fs editor
|
|
35
|
+
* @param path - Path to file
|
|
36
|
+
* @param content - Content to write
|
|
32
37
|
*/
|
|
33
|
-
export declare function writeFile(
|
|
38
|
+
export declare function writeFile(fs: Editor, path: string, content: string): void;
|
|
34
39
|
/**
|
|
35
|
-
* Update a text file
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* @param pathOrFs - Path to file, or Editor instance
|
|
39
|
-
* @param contentOrPath - Content to write, or path (if first param is Editor)
|
|
40
|
-
* @param content - Content to write (if first param is Editor)
|
|
40
|
+
* Update a text file. Alias of writeFile; kept as a distinct name for call-site clarity
|
|
41
|
+
* (updating an existing file vs. creating a new one).
|
|
41
42
|
*/
|
|
42
|
-
export declare
|
|
43
|
+
export declare const updateFile: typeof writeFile;
|
|
43
44
|
/**
|
|
44
|
-
* Update a JSON file while preserving indentation
|
|
45
|
+
* Update a JSON file while preserving the indentation of the existing file.
|
|
46
|
+
* New files are written with 4-space indentation and a trailing newline.
|
|
45
47
|
*
|
|
46
|
-
* @param
|
|
47
|
-
* @param
|
|
48
|
-
* @param
|
|
48
|
+
* @param fs - mem-fs editor
|
|
49
|
+
* @param path - Path to file
|
|
50
|
+
* @param content - Object to serialize
|
|
49
51
|
*/
|
|
50
|
-
export declare function updateJSON(
|
|
52
|
+
export declare function updateJSON(fs: Editor, path: string, content: object): void;
|
|
51
53
|
/**
|
|
52
|
-
* Delete a file
|
|
54
|
+
* Delete a file.
|
|
53
55
|
*
|
|
54
|
-
* @param
|
|
55
|
-
* @param path - Path to file
|
|
56
|
+
* @param fs - mem-fs editor
|
|
57
|
+
* @param path - Path to file
|
|
56
58
|
*/
|
|
57
|
-
export declare function deleteFile(
|
|
59
|
+
export declare function deleteFile(fs: Editor, path: string): void;
|
|
58
60
|
//# sourceMappingURL=file-access.d.ts.map
|