@sap-ux/fiori-migration-writer 0.0.2 → 0.0.3
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.js +4 -1
- package/dist/adapters/ui5-config-adapter.js +39 -48
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/migration-process/legacy-helpers.js +33 -66
- package/dist/migration-process/setup.d.ts +5 -5
- package/dist/migration-process/setup.js +8 -17
- package/dist/template/details.js +1 -1
- package/dist/utils/common.d.ts +1 -1
- package/dist/utils/common.js +1 -1
- package/dist/utils/file-access.d.ts +1 -1
- package/dist/utils/file-access.js +19 -26
- package/dist/utils/file-discovery.js +3 -2
- package/dist/utils/file-system-utils.d.ts +8 -15
- package/dist/utils/file-system-utils.js +8 -22
- package/dist/utils/fs-adapter.d.ts +17 -3
- package/dist/utils/fs-adapter.js +38 -9
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/index.js +0 -2
- package/dist/utils/migration-utils.js +6 -10
- package/package.json +14 -14
package/dist/ProjectMigrator.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { FioriElementsVersion, FileName } from './project-spec-types.js';
|
|
2
2
|
import { determineMessage, readFile, updateFile } from './utils/index.js';
|
|
3
|
-
import { createMemFsEditor, getCurrentEditor, runWithEditor, exists } from './utils/fs-adapter.js';
|
|
3
|
+
import { createMemFsEditor, getCurrentEditor, runWithEditor, exists, loadProjectIntoEditor } from './utils/fs-adapter.js';
|
|
4
4
|
import { commitFileSystemChanges } from './files/file-system.js';
|
|
5
5
|
import { ui5VersionRequestInfo } from '@sap-ux/ui5-info';
|
|
6
6
|
import { getAppProgrammingLanguage } from '@sap-ux/project-access';
|
|
@@ -50,6 +50,9 @@ export class ProjectMigrator {
|
|
|
50
50
|
let messages = [];
|
|
51
51
|
let result = false;
|
|
52
52
|
try {
|
|
53
|
+
// Load the project tree into mem-fs so existence checks see untracked files
|
|
54
|
+
// on disk and migration writes never silently overwrite them.
|
|
55
|
+
await loadProjectIntoEditor(editor, projectRoot);
|
|
53
56
|
// Load or fetch project information
|
|
54
57
|
const { projectInfo, messages: projectInfoMessages } = await loadOrFetchProjectInfo(projectRoot, importProjectInfoOpt);
|
|
55
58
|
messages = messages.concat(projectInfoMessages);
|
|
@@ -47,6 +47,40 @@ function addMockserverMiddleware(orderedYaml, templateData) {
|
|
|
47
47
|
orderedYaml.server.customMiddleware.unshift(mockserverMiddleware);
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Create a new UI5Config instance with metadata and type pre-configured.
|
|
52
|
+
*
|
|
53
|
+
* @param templateData - Template data providing the config name
|
|
54
|
+
* @returns Configured UI5Config instance
|
|
55
|
+
*/
|
|
56
|
+
async function createBaseConfig(templateData) {
|
|
57
|
+
const config = await UI5Config.newInstance('', { validateSchema: false });
|
|
58
|
+
config.setMetadata({
|
|
59
|
+
name: templateData.ui5Yaml?.name?.toLowerCase() || templateData.project.name?.toLowerCase() || 'app'
|
|
60
|
+
});
|
|
61
|
+
config.setType('application');
|
|
62
|
+
return config;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Post-process a UI5Config YAML string: add specVersion 4.0 at the top and
|
|
66
|
+
* optionally set webapp and appreload paths.
|
|
67
|
+
*
|
|
68
|
+
* @param yamlContent - Raw YAML string from UI5Config.toString()
|
|
69
|
+
* @param webappPath - Optional webapp path to inject
|
|
70
|
+
* @returns Final YAML string with specVersion and optional paths applied
|
|
71
|
+
*/
|
|
72
|
+
function postProcessYaml(yamlContent, webappPath) {
|
|
73
|
+
const yamlJson = parse(yamlContent);
|
|
74
|
+
const orderedYaml = { specVersion: '4.0' };
|
|
75
|
+
Object.keys(yamlJson).forEach((key) => {
|
|
76
|
+
orderedYaml[key] = yamlJson[key];
|
|
77
|
+
});
|
|
78
|
+
if (webappPath) {
|
|
79
|
+
setWebappPath(orderedYaml, webappPath);
|
|
80
|
+
setAppreloadPath(orderedYaml, webappPath);
|
|
81
|
+
}
|
|
82
|
+
return stringify(orderedYaml);
|
|
83
|
+
}
|
|
50
84
|
/**
|
|
51
85
|
* Build backend configuration from template data and neo-app destinations
|
|
52
86
|
*
|
|
@@ -86,12 +120,7 @@ function buildBackendConfigs(templateData, neoappDestinations, messages, destina
|
|
|
86
120
|
*/
|
|
87
121
|
export async function generateUI5YamlContent(options) {
|
|
88
122
|
const { templateData, neoappDestinations, messages, destination, firstNeoAppDestination, webappPath, setUI5Version, strict = false } = options;
|
|
89
|
-
const config = await
|
|
90
|
-
// Set metadata and type
|
|
91
|
-
config.setMetadata({
|
|
92
|
-
name: templateData.ui5Yaml?.name?.toLowerCase() || templateData.project.name?.toLowerCase() || 'app'
|
|
93
|
-
});
|
|
94
|
-
config.setType('application');
|
|
123
|
+
const config = await createBaseConfig(templateData);
|
|
95
124
|
// Build backend configuration using helpers
|
|
96
125
|
const backends = buildBackendConfigs(templateData, neoappDestinations, messages, destination, firstNeoAppDestination, strict);
|
|
97
126
|
// Add fiori-tools-proxy middleware with all backends
|
|
@@ -104,20 +133,7 @@ export async function generateUI5YamlContent(options) {
|
|
|
104
133
|
if (previewMiddleware) {
|
|
105
134
|
config.addCustomMiddleware(previewMiddleware);
|
|
106
135
|
}
|
|
107
|
-
|
|
108
|
-
// Post-process: Add specVersion 4.0 (UI5Config doesn't set this)
|
|
109
|
-
const yamlJson = parse(yamlContent);
|
|
110
|
-
// Add specVersion at the top
|
|
111
|
-
const orderedYaml = { specVersion: '4.0' };
|
|
112
|
-
Object.keys(yamlJson).forEach((key) => {
|
|
113
|
-
orderedYaml[key] = yamlJson[key];
|
|
114
|
-
});
|
|
115
|
-
// Apply webappPath if provided
|
|
116
|
-
if (webappPath) {
|
|
117
|
-
setWebappPath(orderedYaml, webappPath);
|
|
118
|
-
setAppreloadPath(orderedYaml, webappPath);
|
|
119
|
-
}
|
|
120
|
-
return stringify(orderedYaml);
|
|
136
|
+
return postProcessYaml(config.toString(), webappPath);
|
|
121
137
|
}
|
|
122
138
|
/**
|
|
123
139
|
* Generate ui5-local.yaml content using @sap-ux/ui5-config builder
|
|
@@ -135,12 +151,7 @@ export async function generateUI5YamlContent(options) {
|
|
|
135
151
|
*/
|
|
136
152
|
export async function generateUI5LocalYamlContent(options) {
|
|
137
153
|
const { templateData, neoappDestinations, messages, destination, firstNeoAppDestination, webappPath, strict = false } = options;
|
|
138
|
-
const config = await
|
|
139
|
-
// Set metadata and type
|
|
140
|
-
config.setMetadata({
|
|
141
|
-
name: templateData.ui5Yaml?.name?.toLowerCase() || templateData.project.name?.toLowerCase() || 'app'
|
|
142
|
-
});
|
|
143
|
-
config.setType('application');
|
|
154
|
+
const config = await createBaseConfig(templateData);
|
|
144
155
|
// Add framework section with SAPUI5 libraries (ui5-local.yaml specific)
|
|
145
156
|
if (templateData.project.localUI5Version && templateData.ui5Yaml?.sapUiLibs) {
|
|
146
157
|
const libraries = [...templateData.ui5Yaml.sapUiLibs];
|
|
@@ -165,9 +176,7 @@ export async function generateUI5LocalYamlContent(options) {
|
|
|
165
176
|
config.addCustomMiddleware(previewMiddleware);
|
|
166
177
|
}
|
|
167
178
|
const yamlContent = config.toString();
|
|
168
|
-
// Parse and post-process
|
|
169
179
|
const yamlJson = parse(yamlContent);
|
|
170
|
-
// Add specVersion at the top
|
|
171
180
|
const orderedYaml = { specVersion: '4.0' };
|
|
172
181
|
Object.keys(yamlJson).forEach((key) => {
|
|
173
182
|
orderedYaml[key] = yamlJson[key];
|
|
@@ -192,12 +201,7 @@ export async function generateUI5LocalYamlContent(options) {
|
|
|
192
201
|
* @returns Promise resolving to ui5-mock.yaml content as string
|
|
193
202
|
*/
|
|
194
203
|
export async function generateUI5MockYamlContent(templateData, webappPath, setUI5Version) {
|
|
195
|
-
const config = await
|
|
196
|
-
// Set metadata and type
|
|
197
|
-
config.setMetadata({
|
|
198
|
-
name: templateData.ui5Yaml?.name?.toLowerCase() || templateData.project.name?.toLowerCase() || 'app'
|
|
199
|
-
});
|
|
200
|
-
config.setType('application');
|
|
204
|
+
const config = await createBaseConfig(templateData);
|
|
201
205
|
// Add fiori-tools-proxy middleware with UI5 version if provided
|
|
202
206
|
const proxyConfig = {
|
|
203
207
|
ignoreCertErrors: false,
|
|
@@ -214,19 +218,6 @@ export async function generateUI5MockYamlContent(templateData, webappPath, setUI
|
|
|
214
218
|
config.addFioriToolsProxyMiddleware(proxyConfig);
|
|
215
219
|
// Add fiori-tools-appreload middleware
|
|
216
220
|
config.addFioriToolsAppReloadMiddleware();
|
|
217
|
-
|
|
218
|
-
// Post-process: Add specVersion and webappPath
|
|
219
|
-
const yamlJson = parse(yamlContent);
|
|
220
|
-
// Add specVersion at the top
|
|
221
|
-
const orderedYaml = { specVersion: '4.0' };
|
|
222
|
-
Object.keys(yamlJson).forEach((key) => {
|
|
223
|
-
orderedYaml[key] = yamlJson[key];
|
|
224
|
-
});
|
|
225
|
-
// Apply webappPath if provided
|
|
226
|
-
if (webappPath) {
|
|
227
|
-
setWebappPath(orderedYaml, webappPath);
|
|
228
|
-
setAppreloadPath(orderedYaml, webappPath);
|
|
229
|
-
}
|
|
230
|
-
return stringify(orderedYaml);
|
|
221
|
+
return postProcessYaml(config.toString(), webappPath);
|
|
231
222
|
}
|
|
232
223
|
//# sourceMappingURL=ui5-config-adapter.js.map
|
package/dist/index.d.ts
CHANGED
|
@@ -45,12 +45,12 @@ export { BulkProjectMigrator } from './BulkProjectMigrator.js';
|
|
|
45
45
|
export { createMemFsEditor } from './utils/fs-adapter.js';
|
|
46
46
|
export * from './types.js';
|
|
47
47
|
export * from './i18n.js';
|
|
48
|
-
export { findProjectRoot, getProjectType, getMainService, hasDependency, getMinUI5VersionAsArray, type CdsUi5PluginInfo, readFile, readJSON, fileExists, writeFile, updateFile, updateJSON, deleteFile, findAllManifest, isFioriToolsProject, determineMessage
|
|
48
|
+
export { findProjectRoot, getProjectType, getMainService, hasDependency, getMinUI5VersionAsArray, type CdsUi5PluginInfo, readFile, readJSON, fileExists, writeFile, updateFile, updateJSON, deleteFile, findAllManifest, isFioriToolsProject, determineMessage } from './utils/index.js';
|
|
49
49
|
export { buildMainBackend, buildProxyConfig, buildPreviewMiddleware } from './adapters/ui5-config-helpers.js';
|
|
50
50
|
export { generateUI5YamlContent, generateUI5LocalYamlContent, generateUI5MockYamlContent } from './adapters/ui5-config-adapter.js';
|
|
51
51
|
export type { UI5YamlOptions } from './adapters/ui5-config-adapter.js';
|
|
52
52
|
export { readManifest, getUI5Version } from './utils/manifest-and-version-utils.js';
|
|
53
|
-
export {
|
|
53
|
+
export { stripSpaces, escapeSingleQuotes, escapeDoubleQuotes, doesDirectoryExists } from './utils/file-system-utils.js';
|
|
54
54
|
export { generateSapLibsStr, getSourceTemplate } from './utils/migration-utils.js';
|
|
55
55
|
export { getWebIDEProjectPathsAsLabels } from './utils/project-discovery.js';
|
|
56
56
|
export { handleGitIgnoreFile, handlePackageJsonFile, handleLocateReuseLibsFile } from './utils/template-generators/index.js';
|
package/dist/index.js
CHANGED
|
@@ -56,13 +56,13 @@ export * from './i18n.js';
|
|
|
56
56
|
// Public API - Utilities (re-export selective functions for backward compatibility)
|
|
57
57
|
export { findProjectRoot, getProjectType, getMainService, hasDependency, getMinUI5VersionAsArray, readFile, readJSON, fileExists, writeFile, updateFile, updateJSON, deleteFile, findAllManifest, isFioriToolsProject,
|
|
58
58
|
// Additional exports for test compatibility
|
|
59
|
-
determineMessage
|
|
59
|
+
determineMessage } from './utils/index.js';
|
|
60
60
|
// Additional exports from adapters for test compatibility
|
|
61
61
|
export { buildMainBackend, buildProxyConfig, buildPreviewMiddleware } from './adapters/ui5-config-helpers.js';
|
|
62
62
|
export { generateUI5YamlContent, generateUI5LocalYamlContent, generateUI5MockYamlContent } from './adapters/ui5-config-adapter.js';
|
|
63
63
|
// Additional exports from utils for test compatibility
|
|
64
64
|
export { readManifest, getUI5Version } from './utils/manifest-and-version-utils.js';
|
|
65
|
-
export {
|
|
65
|
+
export { stripSpaces, escapeSingleQuotes, escapeDoubleQuotes, doesDirectoryExists } from './utils/file-system-utils.js';
|
|
66
66
|
export { generateSapLibsStr, getSourceTemplate } from './utils/migration-utils.js';
|
|
67
67
|
export { getWebIDEProjectPathsAsLabels } from './utils/project-discovery.js';
|
|
68
68
|
export { handleGitIgnoreFile, handlePackageJsonFile, handleLocateReuseLibsFile } from './utils/template-generators/index.js';
|
|
@@ -31,81 +31,48 @@ export function buildLegacyPaths(rootPath, legacyPath) {
|
|
|
31
31
|
* @param rootPath - Project root path
|
|
32
32
|
* @param paths - Legacy paths object
|
|
33
33
|
*/
|
|
34
|
+
/**
|
|
35
|
+
* Move all mem-fs files rooted at `fromPath` to be rooted at `toPath`.
|
|
36
|
+
* Iterates the store after collecting to avoid modifying during iteration.
|
|
37
|
+
*
|
|
38
|
+
* mem-fs keys use the OS-native separator, so comparisons use `sep`.
|
|
39
|
+
*
|
|
40
|
+
* @param fs
|
|
41
|
+
* @param fromPath
|
|
42
|
+
* @param toPath
|
|
43
|
+
*/
|
|
44
|
+
function moveMemFsDirectory(fs, fromPath, toPath) {
|
|
45
|
+
const filesToMove = [];
|
|
46
|
+
fs.store.each((file) => {
|
|
47
|
+
const filePath = file.path;
|
|
48
|
+
if (filePath === fromPath || filePath.startsWith(fromPath + sep)) {
|
|
49
|
+
const relativePath = filePath === fromPath ? '' : filePath.substring(fromPath.length + 1);
|
|
50
|
+
const newPath = relativePath ? join(toPath, relativePath) : toPath;
|
|
51
|
+
filesToMove.push({ oldPath: filePath, newPath });
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
for (const { oldPath, newPath } of filesToMove) {
|
|
55
|
+
const fileContent = fs.read(oldPath);
|
|
56
|
+
fs.write(newPath, fileContent);
|
|
57
|
+
fs.delete(oldPath);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
34
60
|
async function memFsMove(rootPath, paths) {
|
|
35
|
-
const
|
|
36
|
-
if (!
|
|
61
|
+
const editor = getCurrentEditor();
|
|
62
|
+
if (!editor || !hasStore(editor)) {
|
|
37
63
|
return;
|
|
38
64
|
}
|
|
39
65
|
// Move webapp files from src/main/webapp to webapp
|
|
40
66
|
if (await exists(paths.ffLegacyWebappPath)) {
|
|
41
|
-
|
|
42
|
-
// mem-fs stores files with absolute paths as keys
|
|
43
|
-
const filesToMove = [];
|
|
44
|
-
fs.store.each((file) => {
|
|
45
|
-
const filePath = file.path;
|
|
46
|
-
// Check if this file is under the legacy webapp path.
|
|
47
|
-
// mem-fs keys use the OS-native separator, so compare with `sep` (not a hardcoded '/')
|
|
48
|
-
// or the match fails on Windows and no files are moved.
|
|
49
|
-
if (filePath === paths.ffLegacyWebappPath || filePath.startsWith(paths.ffLegacyWebappPath + sep)) {
|
|
50
|
-
// Calculate relative path from legacy webapp
|
|
51
|
-
const relativePath = filePath === paths.ffLegacyWebappPath
|
|
52
|
-
? ''
|
|
53
|
-
: filePath.substring(paths.ffLegacyWebappPath.length + 1);
|
|
54
|
-
const newPath = relativePath
|
|
55
|
-
? join(rootPath, DirName.Webapp, relativePath)
|
|
56
|
-
: join(rootPath, DirName.Webapp);
|
|
57
|
-
filesToMove.push({ oldPath: filePath, newPath });
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
// Move files (do this after iteration to avoid modifying during iteration)
|
|
61
|
-
for (const { oldPath, newPath } of filesToMove) {
|
|
62
|
-
const fileContent = fs.read(oldPath);
|
|
63
|
-
fs.write(newPath, fileContent);
|
|
64
|
-
fs.delete(oldPath);
|
|
65
|
-
}
|
|
67
|
+
moveMemFsDirectory(editor, paths.ffLegacyWebappPath, join(rootPath, DirName.Webapp));
|
|
66
68
|
}
|
|
67
|
-
// Move test/qunit to webapp/test
|
|
69
|
+
// Move test/qunit to webapp/test/qunit
|
|
68
70
|
if (await exists(paths.ffLegacyTestQunitPath)) {
|
|
69
|
-
|
|
70
|
-
fs.store.each((file) => {
|
|
71
|
-
const filePath = file.path;
|
|
72
|
-
if (filePath === paths.ffLegacyTestQunitPath || filePath.startsWith(paths.ffLegacyTestQunitPath + sep)) {
|
|
73
|
-
const relativePath = filePath === paths.ffLegacyTestQunitPath
|
|
74
|
-
? ''
|
|
75
|
-
: filePath.substring(paths.ffLegacyTestQunitPath.length + 1);
|
|
76
|
-
const newPath = relativePath
|
|
77
|
-
? join(paths.ffNewTestPath, 'qunit', relativePath)
|
|
78
|
-
: join(paths.ffNewTestPath, 'qunit');
|
|
79
|
-
filesToMove.push({ oldPath: filePath, newPath });
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
for (const { oldPath, newPath } of filesToMove) {
|
|
83
|
-
const fileContent = fs.read(oldPath);
|
|
84
|
-
fs.write(newPath, fileContent);
|
|
85
|
-
fs.delete(oldPath);
|
|
86
|
-
}
|
|
71
|
+
moveMemFsDirectory(editor, paths.ffLegacyTestQunitPath, join(paths.ffNewTestPath, 'qunit'));
|
|
87
72
|
}
|
|
88
|
-
// Move test/uiveri5 to webapp/test
|
|
73
|
+
// Move test/uiveri5 to webapp/test/uiveri5
|
|
89
74
|
if (await exists(paths.ffLegacyTestuiveri5Path)) {
|
|
90
|
-
|
|
91
|
-
fs.store.each((file) => {
|
|
92
|
-
const filePath = file.path;
|
|
93
|
-
if (filePath === paths.ffLegacyTestuiveri5Path ||
|
|
94
|
-
filePath.startsWith(paths.ffLegacyTestuiveri5Path + sep)) {
|
|
95
|
-
const relativePath = filePath === paths.ffLegacyTestuiveri5Path
|
|
96
|
-
? ''
|
|
97
|
-
: filePath.substring(paths.ffLegacyTestuiveri5Path.length + 1);
|
|
98
|
-
const newPath = relativePath
|
|
99
|
-
? join(paths.ffNewTestPath, 'uiveri5', relativePath)
|
|
100
|
-
: join(paths.ffNewTestPath, 'uiveri5');
|
|
101
|
-
filesToMove.push({ oldPath: filePath, newPath });
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
for (const { oldPath, newPath } of filesToMove) {
|
|
105
|
-
const fileContent = fs.read(oldPath);
|
|
106
|
-
fs.write(newPath, fileContent);
|
|
107
|
-
fs.delete(oldPath);
|
|
108
|
-
}
|
|
75
|
+
moveMemFsDirectory(editor, paths.ffLegacyTestuiveri5Path, join(paths.ffNewTestPath, 'uiveri5'));
|
|
109
76
|
}
|
|
110
77
|
}
|
|
111
78
|
/**
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type { ImportProjectInfo } from '../types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Sets up necessary directories for migration
|
|
4
|
-
*
|
|
4
|
+
* Note: mem-fs handles directory creation implicitly when files are written
|
|
5
5
|
*
|
|
6
|
-
* @param
|
|
7
|
-
* @param
|
|
8
|
-
* @param
|
|
6
|
+
* @param _projectInfo - Project information (unused - kept for API compatibility)
|
|
7
|
+
* @param _rootPath - Root path of the project (unused - kept for API compatibility)
|
|
8
|
+
* @param _hasDataSource - Whether project has a data source (unused - kept for API compatibility)
|
|
9
9
|
*/
|
|
10
|
-
export declare function setupMigrationDirectories(
|
|
10
|
+
export declare function setupMigrationDirectories(_projectInfo: ImportProjectInfo, _rootPath: string, _hasDataSource: boolean): Promise<void>;
|
|
11
11
|
/**
|
|
12
12
|
* Removes package-lock.json if it exists
|
|
13
13
|
* Package-lock is regenerated during installation
|
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
|
-
import {
|
|
3
|
-
import { TemplateFileName } from '../index.js';
|
|
4
|
-
import { createDirectory, fileExists, deleteFile } from '../utils/index.js';
|
|
2
|
+
import { fileExists, deleteFile } from '../utils/index.js';
|
|
5
3
|
/**
|
|
6
4
|
* Sets up necessary directories for migration
|
|
7
|
-
*
|
|
5
|
+
* Note: mem-fs handles directory creation implicitly when files are written
|
|
8
6
|
*
|
|
9
|
-
* @param
|
|
10
|
-
* @param
|
|
11
|
-
* @param
|
|
7
|
+
* @param _projectInfo - Project information (unused - kept for API compatibility)
|
|
8
|
+
* @param _rootPath - Root path of the project (unused - kept for API compatibility)
|
|
9
|
+
* @param _hasDataSource - Whether project has a data source (unused - kept for API compatibility)
|
|
12
10
|
*/
|
|
13
|
-
export async function setupMigrationDirectories(
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
createDirectory(join(rootPath, projectInfo.webappPath, DirName.LocalService));
|
|
17
|
-
}
|
|
18
|
-
// Create test directory if webapp exists
|
|
19
|
-
const webAppPath = join(rootPath, projectInfo.webappPath);
|
|
20
|
-
if (await fileExists(webAppPath)) {
|
|
21
|
-
createDirectory(join(rootPath, projectInfo.webappPath, TemplateFileName.Test));
|
|
22
|
-
}
|
|
11
|
+
export async function setupMigrationDirectories(_projectInfo, _rootPath, _hasDataSource) {
|
|
12
|
+
// mem-fs handles directory creation implicitly when files are written to paths
|
|
13
|
+
// No explicit directory creation needed
|
|
23
14
|
}
|
|
24
15
|
/**
|
|
25
16
|
* Removes package-lock.json if it exists
|
package/dist/template/details.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { TemplateFileName } from '../index.js';
|
|
6
|
-
import {
|
|
6
|
+
import { readFile, fileExists } from '../utils/index.js';
|
|
7
7
|
import { xmlToJson } from '../utils/service.js';
|
|
8
8
|
import { isAppFreestyle } from '../utils/common.js';
|
|
9
9
|
/**
|
package/dist/utils/common.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare const v4MockServerDep: {
|
|
|
11
11
|
};
|
|
12
12
|
export { packageJsonTmplName, propertyEditorTaskProjectTypes, getBaseTemplatesMap, getFLPSandboxTemplatesMap, getFLPSandboxMockServerTemplatesMap, getCommonV4TemplatesMap, getSapTemplatesMap, getFeTemplatesMap, getAdaptationTemplatesMap, getLibraryTemplatesMap, getFFTestSuiteMap } from './template-maps.js';
|
|
13
13
|
export { findAllWebIDEProjectFolders, getWebIDEProjectPathsAsLabels, findProjectsByManifest } from './project-discovery.js';
|
|
14
|
-
export { stripSpaces, escapeSingleQuotes, escapeDoubleQuotes, doesDirectoryExists
|
|
14
|
+
export { normalizePath, stripSpaces, escapeSingleQuotes, escapeDoubleQuotes, doesDirectoryExists } from './file-system-utils.js';
|
|
15
15
|
export { getUI5Version, checkManifestUI5Version, readManifest, isAppFreestyle, isGenerateIndex } from './manifest-and-version-utils.js';
|
|
16
16
|
export { generateSapLibsStr, MigrationError, determineMessage, generateTemplate, getSourceTemplate, generateToolsId, determineSapUxLayer, buildUrlParam } from './migration-utils.js';
|
|
17
17
|
//# sourceMappingURL=common.d.ts.map
|
package/dist/utils/common.js
CHANGED
|
@@ -19,7 +19,7 @@ export { packageJsonTmplName, propertyEditorTaskProjectTypes, getBaseTemplatesMa
|
|
|
19
19
|
// Re-export from project-discovery
|
|
20
20
|
export { findAllWebIDEProjectFolders, getWebIDEProjectPathsAsLabels, findProjectsByManifest } from './project-discovery.js';
|
|
21
21
|
// Re-export from file-system-utils
|
|
22
|
-
export { stripSpaces, escapeSingleQuotes, escapeDoubleQuotes, doesDirectoryExists
|
|
22
|
+
export { normalizePath, stripSpaces, escapeSingleQuotes, escapeDoubleQuotes, doesDirectoryExists } from './file-system-utils.js';
|
|
23
23
|
// Re-export from manifest-and-version-utils
|
|
24
24
|
export { getUI5Version, checkManifestUI5Version, readManifest, isAppFreestyle, isGenerateIndex } from './manifest-and-version-utils.js';
|
|
25
25
|
// Re-export from migration-utils
|
|
@@ -12,7 +12,7 @@ export declare function readFile(pathOrFs: string | Editor, path?: string): stri
|
|
|
12
12
|
*
|
|
13
13
|
* @param pathOrFs - Path to file, or Editor instance
|
|
14
14
|
* @param path - Path to file (if first param is Editor)
|
|
15
|
-
* @returns Parsed JSON object
|
|
15
|
+
* @returns Parsed JSON object
|
|
16
16
|
*/
|
|
17
17
|
export declare function readJSON<T = any>(pathOrFs: string | Editor, path?: string): Promise<T>;
|
|
18
18
|
/**
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
// @ts-expect-error - no type definitions available
|
|
9
9
|
import parseJson from 'json-parse-even-better-errors';
|
|
10
|
-
import { readFile as fsReadFile } from 'node:fs/promises';
|
|
10
|
+
import { readFile as fsReadFile, access } from 'node:fs/promises';
|
|
11
11
|
import { editorHasPath, getCurrentEditor, exists as fsAdapterExists, getEditor } from './fs-adapter.js';
|
|
12
12
|
/**
|
|
13
13
|
* Read a text file
|
|
@@ -26,7 +26,7 @@ export function readFile(pathOrFs, path) {
|
|
|
26
26
|
*
|
|
27
27
|
* @param pathOrFs - Path to file, or Editor instance
|
|
28
28
|
* @param path - Path to file (if first param is Editor)
|
|
29
|
-
* @returns Parsed JSON object
|
|
29
|
+
* @returns Parsed JSON object
|
|
30
30
|
*/
|
|
31
31
|
export async function readJSON(pathOrFs, path) {
|
|
32
32
|
const filePath = typeof pathOrFs === 'string' ? pathOrFs : path;
|
|
@@ -40,23 +40,7 @@ export async function readJSON(pathOrFs, path) {
|
|
|
40
40
|
const fs = getEditor(pathOrFs);
|
|
41
41
|
content = fs.read(filePath);
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
const result = JSON.parse(content);
|
|
45
|
-
// Also parse with parseJson to extract indentation metadata
|
|
46
|
-
// This is needed for updateJSON to preserve formatting
|
|
47
|
-
try {
|
|
48
|
-
const resultWithIndent = parseJson(content);
|
|
49
|
-
// Copy indent metadata to the result object
|
|
50
|
-
const indent = Symbol.for('indent');
|
|
51
|
-
if (resultWithIndent[indent]) {
|
|
52
|
-
result[indent] = resultWithIndent[indent];
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
// If parseJson fails, we still have the result from JSON.parse
|
|
57
|
-
// updateJSON will use default 4-space indentation
|
|
58
|
-
}
|
|
59
|
-
return result;
|
|
43
|
+
return JSON.parse(content);
|
|
60
44
|
}
|
|
61
45
|
/**
|
|
62
46
|
* Check if a file exists
|
|
@@ -66,15 +50,24 @@ export async function readJSON(pathOrFs, path) {
|
|
|
66
50
|
* @returns true if file exists, false otherwise
|
|
67
51
|
*/
|
|
68
52
|
export async function fileExists(pathOrFs, path) {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
// When called with just a path string and no editor context, check filesystem directly
|
|
72
|
-
if (typeof pathOrFs === 'string' && !editor) {
|
|
53
|
+
// String path: delegate to the single shared existence check (mem-fs staged OR real fs).
|
|
54
|
+
if (typeof pathOrFs === 'string') {
|
|
73
55
|
return fsAdapterExists(pathOrFs);
|
|
74
56
|
}
|
|
75
|
-
//
|
|
76
|
-
|
|
77
|
-
|
|
57
|
+
// Explicit editor argument: check that editor's staged files, then fall back to real fs.
|
|
58
|
+
// The real-fs fallback prevents overwriting files not yet loaded into the given editor
|
|
59
|
+
// (e.g., the mockserver.js overwrite bug).
|
|
60
|
+
const filePath = path;
|
|
61
|
+
if (editorHasPath(pathOrFs, filePath)) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
await access(filePath);
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
78
71
|
}
|
|
79
72
|
/**
|
|
80
73
|
* Write a text file
|
|
@@ -8,6 +8,7 @@ import fastGlob from 'fast-glob';
|
|
|
8
8
|
import { dirname, basename, join, normalize } from 'node:path';
|
|
9
9
|
import { access } from 'node:fs/promises';
|
|
10
10
|
import { readJSON } from './file-access.js';
|
|
11
|
+
import { normalizePath } from './file-system-utils.js';
|
|
11
12
|
/**
|
|
12
13
|
* Reuse library type enum
|
|
13
14
|
* Matches @sap/ux-project-access ReuseLibType
|
|
@@ -92,8 +93,8 @@ export async function findAllProjectRoots(paths, sapuxRequired = false) {
|
|
|
92
93
|
async function findLibraryProjectRoot(manifestPath, workspaceBoundary) {
|
|
93
94
|
let current = dirname(manifestPath);
|
|
94
95
|
// Normalize paths for comparison
|
|
95
|
-
const normalizedBoundary = workspaceBoundary
|
|
96
|
-
const normalizedCurrent = (path) => path
|
|
96
|
+
const normalizedBoundary = normalizePath(workspaceBoundary);
|
|
97
|
+
const normalizedCurrent = (path) => normalizePath(path);
|
|
97
98
|
// Helper to check if a file/directory exists using Node.js fs API
|
|
98
99
|
// (not mem-fs, since project markers are real filesystem entries)
|
|
99
100
|
const pathExists = async (path) => {
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { Editor } from 'mem-fs-editor';
|
|
2
|
+
/**
|
|
3
|
+
* Normalize path separators to forward slashes for cross-platform compatibility
|
|
4
|
+
* mem-fs and many tools expect forward slashes regardless of OS
|
|
5
|
+
*
|
|
6
|
+
* @param path - Path to normalize
|
|
7
|
+
* @returns Path with forward slashes
|
|
8
|
+
*/
|
|
9
|
+
export declare const normalizePath: (path: string) => string;
|
|
2
10
|
/**
|
|
3
11
|
* stripSpaces
|
|
4
12
|
*
|
|
@@ -25,19 +33,4 @@ export declare const escapeDoubleQuotes: (s: string) => string;
|
|
|
25
33
|
* @param directory - Directory path (if first param is Editor)
|
|
26
34
|
*/
|
|
27
35
|
export declare function doesDirectoryExists(directoryOrFs: string | Editor, directory?: string): boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Check if property exists on object
|
|
30
|
-
*
|
|
31
|
-
* @param obj
|
|
32
|
-
* @param fieldName
|
|
33
|
-
*/
|
|
34
|
-
export declare function doesPropertyExist(obj: unknown, fieldName: string): boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Create directory if it doesn't exist
|
|
37
|
-
* Note: mem-fs handles directories implicitly, so this is a no-op
|
|
38
|
-
*
|
|
39
|
-
* @param directoryOrFs - Directory path or Editor instance
|
|
40
|
-
* @param directory - Directory path (if first param is Editor)
|
|
41
|
-
*/
|
|
42
|
-
export declare function createDirectory(directoryOrFs: string | Editor, directory?: string): boolean;
|
|
43
36
|
//# sourceMappingURL=file-system-utils.d.ts.map
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { editorHasPath, getEditor } from './fs-adapter.js';
|
|
2
|
+
/**
|
|
3
|
+
* Normalize path separators to forward slashes for cross-platform compatibility
|
|
4
|
+
* mem-fs and many tools expect forward slashes regardless of OS
|
|
5
|
+
*
|
|
6
|
+
* @param path - Path to normalize
|
|
7
|
+
* @returns Path with forward slashes
|
|
8
|
+
*/
|
|
9
|
+
export const normalizePath = (path) => path.replaceAll('\\', '/');
|
|
2
10
|
/**
|
|
3
11
|
* stripSpaces
|
|
4
12
|
*
|
|
@@ -30,26 +38,4 @@ export function doesDirectoryExists(directoryOrFs, directory) {
|
|
|
30
38
|
// Use editorHasPath instead of fs.exists() to avoid side effect of staging paths
|
|
31
39
|
return editorHasPath(fs, dir);
|
|
32
40
|
}
|
|
33
|
-
/**
|
|
34
|
-
* Check if property exists on object
|
|
35
|
-
*
|
|
36
|
-
* @param obj
|
|
37
|
-
* @param fieldName
|
|
38
|
-
*/
|
|
39
|
-
export function doesPropertyExist(obj, fieldName) {
|
|
40
|
-
return Object.hasOwn(obj, fieldName);
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Create directory if it doesn't exist
|
|
44
|
-
* Note: mem-fs handles directories implicitly, so this is a no-op
|
|
45
|
-
*
|
|
46
|
-
* @param directoryOrFs - Directory path or Editor instance
|
|
47
|
-
* @param directory - Directory path (if first param is Editor)
|
|
48
|
-
*/
|
|
49
|
-
export function createDirectory(directoryOrFs, directory) {
|
|
50
|
-
// mem-fs handles directories implicitly when writing files
|
|
51
|
-
// Check if it exists for consistency
|
|
52
|
-
const exists = doesDirectoryExists(directoryOrFs, directory);
|
|
53
|
-
return !exists; // Return true if it didn't exist (was "created")
|
|
54
|
-
}
|
|
55
41
|
//# sourceMappingURL=file-system-utils.js.map
|
|
@@ -28,6 +28,17 @@ export declare function createMemFsEditor(): Editor;
|
|
|
28
28
|
* @returns Result of the callback
|
|
29
29
|
*/
|
|
30
30
|
export declare function runWithEditor<T>(editor: Editor, callback: () => T | Promise<T>): T | Promise<T>;
|
|
31
|
+
/**
|
|
32
|
+
* Load every file under a project folder into the mem-fs store.
|
|
33
|
+
*
|
|
34
|
+
* Pulling files into the store makes existence checks that scan the store (editorHasPath)
|
|
35
|
+
* see the real project tree, so later writes do not overwrite untracked files. Loading via
|
|
36
|
+
* the store's get() does not mark files as modified, so commit() still skips them.
|
|
37
|
+
*
|
|
38
|
+
* @param editor - Mem-fs editor whose store should be populated
|
|
39
|
+
* @param projectRoot - Absolute path to the project folder to load
|
|
40
|
+
*/
|
|
41
|
+
export declare function loadProjectIntoEditor(editor: Editor, projectRoot: string): Promise<void>;
|
|
31
42
|
/**
|
|
32
43
|
* Get the current editor from context
|
|
33
44
|
*
|
|
@@ -51,11 +62,14 @@ export declare function isMemFsEnabled(): boolean;
|
|
|
51
62
|
*/
|
|
52
63
|
export declare function editorHasPath(editor: Editor, path: string): boolean;
|
|
53
64
|
/**
|
|
54
|
-
* Check if file/directory exists (async)
|
|
55
|
-
*
|
|
65
|
+
* Check if a file/directory exists (async).
|
|
66
|
+
*
|
|
67
|
+
* When an editor is in context, the migration tree is already loaded into mem-fs, so a staged
|
|
68
|
+
* path is authoritative. A real-filesystem check is still used as a fallback so files that were
|
|
69
|
+
* never loaded into mem-fs are not reported missing (and therefore not silently overwritten).
|
|
56
70
|
*
|
|
57
71
|
* @param path - Path to check
|
|
58
|
-
* @returns True if
|
|
72
|
+
* @returns True if staged in mem-fs OR present on the real filesystem
|
|
59
73
|
*/
|
|
60
74
|
export declare function exists(path: string): Promise<boolean>;
|
|
61
75
|
/**
|
package/dist/utils/fs-adapter.js
CHANGED
|
@@ -2,6 +2,8 @@ import { create as createMemFs } from 'mem-fs';
|
|
|
2
2
|
import { create as createEditor } from 'mem-fs-editor';
|
|
3
3
|
import { access } from 'node:fs/promises';
|
|
4
4
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
5
|
+
import fastGlob from 'fast-glob';
|
|
6
|
+
import { normalizePath } from './file-system-utils.js';
|
|
5
7
|
/**
|
|
6
8
|
* AsyncLocalStorage for tracking the current migration's editor
|
|
7
9
|
*/
|
|
@@ -42,6 +44,32 @@ export function createMemFsEditor() {
|
|
|
42
44
|
export function runWithEditor(editor, callback) {
|
|
43
45
|
return editorContext.run(editor, callback);
|
|
44
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Load every file under a project folder into the mem-fs store.
|
|
49
|
+
*
|
|
50
|
+
* Pulling files into the store makes existence checks that scan the store (editorHasPath)
|
|
51
|
+
* see the real project tree, so later writes do not overwrite untracked files. Loading via
|
|
52
|
+
* the store's get() does not mark files as modified, so commit() still skips them.
|
|
53
|
+
*
|
|
54
|
+
* @param editor - Mem-fs editor whose store should be populated
|
|
55
|
+
* @param projectRoot - Absolute path to the project folder to load
|
|
56
|
+
*/
|
|
57
|
+
export async function loadProjectIntoEditor(editor, projectRoot) {
|
|
58
|
+
const files = await fastGlob('**/*', {
|
|
59
|
+
cwd: projectRoot,
|
|
60
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/.git/**'],
|
|
61
|
+
absolute: true,
|
|
62
|
+
onlyFiles: true,
|
|
63
|
+
dot: true
|
|
64
|
+
});
|
|
65
|
+
const store = editor.store;
|
|
66
|
+
for (const file of files) {
|
|
67
|
+
// get() lazily reads the file into the store without marking it modified.
|
|
68
|
+
// The store resolves and keys the path itself; editorHasPath normalizes separators
|
|
69
|
+
// at comparison time, so both sides stay consistent cross-platform.
|
|
70
|
+
store.get(file);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
45
73
|
/**
|
|
46
74
|
* Get the current editor from context
|
|
47
75
|
*
|
|
@@ -70,7 +98,7 @@ export function isMemFsEnabled() {
|
|
|
70
98
|
export function editorHasPath(editor, path) {
|
|
71
99
|
// Normalize path separators to forward slashes for consistent comparison
|
|
72
100
|
// mem-fs stores all paths with forward slashes regardless of OS
|
|
73
|
-
const normalizedPath = path
|
|
101
|
+
const normalizedPath = normalizePath(path);
|
|
74
102
|
const directoryPrefix = normalizedPath.endsWith('/') ? normalizedPath : normalizedPath + '/';
|
|
75
103
|
let found = false;
|
|
76
104
|
editor.store.each((file) => {
|
|
@@ -78,7 +106,7 @@ export function editorHasPath(editor, path) {
|
|
|
78
106
|
return;
|
|
79
107
|
}
|
|
80
108
|
// Normalize file path as well for comparison
|
|
81
|
-
const normalizedFilePath = file.path
|
|
109
|
+
const normalizedFilePath = normalizePath(file.path);
|
|
82
110
|
// Check exact match OR files under this directory
|
|
83
111
|
if (normalizedFilePath === normalizedPath || normalizedFilePath.startsWith(directoryPrefix)) {
|
|
84
112
|
found = true;
|
|
@@ -87,19 +115,20 @@ export function editorHasPath(editor, path) {
|
|
|
87
115
|
return found;
|
|
88
116
|
}
|
|
89
117
|
/**
|
|
90
|
-
* Check if file/directory exists (async)
|
|
91
|
-
*
|
|
118
|
+
* Check if a file/directory exists (async).
|
|
119
|
+
*
|
|
120
|
+
* When an editor is in context, the migration tree is already loaded into mem-fs, so a staged
|
|
121
|
+
* path is authoritative. A real-filesystem check is still used as a fallback so files that were
|
|
122
|
+
* never loaded into mem-fs are not reported missing (and therefore not silently overwritten).
|
|
92
123
|
*
|
|
93
124
|
* @param path - Path to check
|
|
94
|
-
* @returns True if
|
|
125
|
+
* @returns True if staged in mem-fs OR present on the real filesystem
|
|
95
126
|
*/
|
|
96
127
|
export async function exists(path) {
|
|
97
128
|
const editor = getCurrentEditor();
|
|
98
|
-
if (editor) {
|
|
99
|
-
|
|
100
|
-
return editorHasPath(editor, path);
|
|
129
|
+
if (editor && editorHasPath(editor, path)) {
|
|
130
|
+
return true;
|
|
101
131
|
}
|
|
102
|
-
// No editor context - check real filesystem
|
|
103
132
|
try {
|
|
104
133
|
await access(path);
|
|
105
134
|
return true;
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ export * from './common.js';
|
|
|
2
2
|
export * from './UI5Theme.js';
|
|
3
3
|
export { validateMetadata } from './service.js';
|
|
4
4
|
export { determineMessage } from './migration-utils.js';
|
|
5
|
-
export { createDirectory } from './file-system-utils.js';
|
|
6
5
|
export { readFile, readJSON, fileExists, writeFile, updateFile, updateJSON, deleteFile } from './file-access.js';
|
|
7
6
|
export { findAllProjectRoots, getReuseLibs, ReuseLibType } from './file-discovery.js';
|
|
8
7
|
export { findProjectRoot, getProjectType, getMainService, hasDependency, getMinUI5VersionAsArray, type CdsUi5PluginInfo } from '@sap-ux/project-access';
|
package/dist/utils/index.js
CHANGED
|
@@ -8,8 +8,6 @@ export * from './UI5Theme.js';
|
|
|
8
8
|
export { validateMetadata } from './service.js';
|
|
9
9
|
// Migration utilities
|
|
10
10
|
export { determineMessage } from './migration-utils.js';
|
|
11
|
-
// File system utilities
|
|
12
|
-
export { createDirectory } from './file-system-utils.js';
|
|
13
11
|
// Re-export native file access to replace @sap/ux-project-access file I/O
|
|
14
12
|
export { readFile, readJSON, fileExists, writeFile, updateFile, updateJSON, deleteFile } from './file-access.js';
|
|
15
13
|
// Re-export native file discovery to replace @sap/ux-project-access
|
|
@@ -4,7 +4,7 @@ import { readPackageUpAsync } from './read-package-up-compat.js';
|
|
|
4
4
|
import { v4 as uuidV4 } from 'uuid';
|
|
5
5
|
import { i18nText } from '../i18n.js';
|
|
6
6
|
import { writeFile } from './file-access.js';
|
|
7
|
-
import
|
|
7
|
+
import uniq from 'lodash/uniq.js';
|
|
8
8
|
// Get current directory using import.meta.url (ESM)
|
|
9
9
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
// Matches strings starting with "sap" or containing ".sap" (e.g., "sap.m", "com.sap.ui")
|
|
@@ -17,14 +17,12 @@ const sapLibsRegexFilter = /(?:^sap|\.sap)/;
|
|
|
17
17
|
* @param libsStrInput
|
|
18
18
|
*/
|
|
19
19
|
export function generateSapLibsStr(manifestLibs, libsStrInput) {
|
|
20
|
-
let libStrOut = '';
|
|
21
20
|
const mlibs = Object.keys(manifestLibs || {});
|
|
22
21
|
// remove spaces and split at comma
|
|
23
22
|
const strlibs = libsStrInput?.replaceAll(' ', '').split(',') || [];
|
|
24
23
|
const libs = mlibs.concat(strlibs);
|
|
25
|
-
const uniquelibs = libs
|
|
26
|
-
|
|
27
|
-
return libStrOut;
|
|
24
|
+
const uniquelibs = uniq(libs);
|
|
25
|
+
return uniquelibs.filter((ele) => sapLibsRegexFilter.test(ele)).join(', ');
|
|
28
26
|
}
|
|
29
27
|
/**
|
|
30
28
|
* Custom error class for migration errors
|
|
@@ -82,14 +80,12 @@ export async function generateTemplate(templateData, projectRoot, templateRoot,
|
|
|
82
80
|
const { fullTemplateName, targetFile } = resolveTemplatePaths(projectRoot, templateRoot, templateName, templateProps);
|
|
83
81
|
// 2. Resolve template data
|
|
84
82
|
const resolvedData = resolveTemplateData(templateData, templateProps);
|
|
85
|
-
// 3.
|
|
86
|
-
createDirectory(dirname(targetFile));
|
|
87
|
-
// 4. Render template
|
|
83
|
+
// 3. Render template (mem-fs handles directory creation implicitly)
|
|
88
84
|
const { isRendered = true, opts = {} } = templateProps;
|
|
89
85
|
let content = renderTemplate(templateRoot, fullTemplateName, resolvedData, opts, isRendered);
|
|
90
|
-
//
|
|
86
|
+
// 4. Apply file-specific handlers
|
|
91
87
|
content = await applyFileSpecificHandlers(templateName, content, projectRoot, targetFile, templateData);
|
|
92
|
-
//
|
|
88
|
+
// 5. Write file (mem-fs handles directory creation implicitly)
|
|
93
89
|
// Do not catch - let errors propagate to caller for proper handling
|
|
94
90
|
writeFile(targetFile, content);
|
|
95
91
|
}
|
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"bugs": {
|
|
11
11
|
"url": "https://github.com/SAP/open-ux-tools/issues?q=is%3Aopen+is%3Aissue+label%3Abug+label%3Afiori-migration-writer"
|
|
12
12
|
},
|
|
13
|
-
"version": "0.0.
|
|
13
|
+
"version": "0.0.3",
|
|
14
14
|
"license": "Apache-2.0",
|
|
15
15
|
"main": "dist/index.js",
|
|
16
16
|
"files": [
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"ejs": "3.1.10",
|
|
26
26
|
"fast-glob": "3.3.3",
|
|
27
27
|
"fast-xml-parser": "5.10.1",
|
|
28
|
-
"fs-extra": "11.
|
|
28
|
+
"fs-extra": "11.4.1",
|
|
29
29
|
"i18next": "26.3.6",
|
|
30
30
|
"json-parse-even-better-errors": "5.0.0",
|
|
31
31
|
"lodash": "4.18.1",
|
|
@@ -37,17 +37,17 @@
|
|
|
37
37
|
"uuid": "11.1.1",
|
|
38
38
|
"vscode-uri": "3.1.0",
|
|
39
39
|
"yaml": "2.9.0",
|
|
40
|
-
"@sap-ux/
|
|
41
|
-
"@sap-ux/
|
|
42
|
-
"@sap-ux/i18n": "1.0.
|
|
43
|
-
"@sap-ux/
|
|
44
|
-
"@sap-ux/
|
|
45
|
-
"@sap-ux/
|
|
46
|
-
"@sap-ux/project-access": "2.3.0",
|
|
40
|
+
"@sap-ux/axios-extension": "2.1.2",
|
|
41
|
+
"@sap-ux/btp-utils": "2.0.7",
|
|
42
|
+
"@sap-ux/i18n": "1.0.6",
|
|
43
|
+
"@sap-ux/nodejs-utils": "1.0.11",
|
|
44
|
+
"@sap-ux/adp-tooling": "1.0.65",
|
|
45
|
+
"@sap-ux/project-access": "2.3.1",
|
|
47
46
|
"@sap-ux/store": "2.0.7",
|
|
48
|
-
"@sap-ux/ui5-application-writer": "2.1.
|
|
49
|
-
"@sap-ux/ui5-config": "1.0.
|
|
50
|
-
"@sap-ux/ui5-info": "1.0.
|
|
47
|
+
"@sap-ux/ui5-application-writer": "2.1.6",
|
|
48
|
+
"@sap-ux/ui5-config": "1.0.10",
|
|
49
|
+
"@sap-ux/ui5-info": "1.0.7",
|
|
50
|
+
"@sap-ux/launch-config": "1.0.25"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@jest/globals": "30.4.1",
|
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
"@types/lodash": "4.17.24",
|
|
57
57
|
"@types/mem-fs": "1.1.2",
|
|
58
58
|
"@types/mem-fs-editor": "7.0.1",
|
|
59
|
-
"@types/semver": "7.
|
|
59
|
+
"@types/semver": "7.8.0",
|
|
60
60
|
"jest-specific-snapshot": "^8.0.0",
|
|
61
61
|
"rimraf": "6.1.3",
|
|
62
|
-
"@sap-ux/eslint-plugin-fiori-tools": "10.17.
|
|
62
|
+
"@sap-ux/eslint-plugin-fiori-tools": "10.17.2"
|
|
63
63
|
},
|
|
64
64
|
"engines": {
|
|
65
65
|
"node": ">=22.x"
|