@sap-ux/project-access 1.38.1 → 2.0.1
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/command/index.d.ts +1 -1
- package/dist/command/index.js +1 -5
- package/dist/command/npm-command.js +3 -6
- package/dist/constants.js +10 -13
- package/dist/file/file-access.d.ts +1 -1
- package/dist/file/file-access.js +18 -32
- package/dist/file/file-search.js +25 -35
- package/dist/file/index.d.ts +2 -2
- package/dist/file/index.js +2 -19
- package/dist/index.d.ts +10 -10
- package/dist/index.js +9 -102
- package/dist/library/constants.js +1 -4
- package/dist/library/helpers.d.ts +1 -1
- package/dist/library/helpers.js +36 -44
- package/dist/library/index.d.ts +1 -1
- package/dist/library/index.js +1 -6
- package/dist/odata/index.d.ts +1 -1
- package/dist/odata/index.js +1 -6
- package/dist/odata/metadata.js +2 -6
- package/dist/path/index.d.ts +1 -1
- package/dist/path/index.js +1 -5
- package/dist/path/normalize.js +3 -6
- package/dist/project/access.d.ts +1 -1
- package/dist/project/access.js +30 -34
- package/dist/project/cap.d.ts +1 -1
- package/dist/project/cap.js +75 -102
- package/dist/project/dependencies.d.ts +1 -1
- package/dist/project/dependencies.js +16 -22
- package/dist/project/flex-changes.js +7 -10
- package/dist/project/i18n/i18n.d.ts +1 -1
- package/dist/project/i18n/i18n.js +22 -22
- package/dist/project/i18n/index.d.ts +3 -3
- package/dist/project/i18n/index.js +3 -13
- package/dist/project/i18n/read.d.ts +1 -1
- package/dist/project/i18n/read.js +11 -15
- package/dist/project/i18n/write.d.ts +1 -1
- package/dist/project/i18n/write.js +22 -28
- package/dist/project/index.d.ts +15 -15
- package/dist/project/index.js +14 -79
- package/dist/project/info.d.ts +1 -1
- package/dist/project/info.js +45 -54
- package/dist/project/module-loader.js +28 -64
- package/dist/project/mta.d.ts +1 -1
- package/dist/project/mta.js +6 -9
- package/dist/project/script.js +11 -18
- package/dist/project/search.d.ts +1 -1
- package/dist/project/search.js +77 -86
- package/dist/project/service.d.ts +1 -1
- package/dist/project/service.js +10 -16
- package/dist/project/specification.js +38 -44
- package/dist/project/ui5-config.js +21 -29
- package/dist/project/ui5-xml-id-validator.js +3 -6
- package/dist/types/access/index.d.ts +4 -4
- package/dist/types/access/index.js +1 -2
- package/dist/types/cap/index.js +1 -2
- package/dist/types/find/index.d.ts +1 -1
- package/dist/types/find/index.js +1 -2
- package/dist/types/i18n/index.js +1 -2
- package/dist/types/index.d.ts +9 -9
- package/dist/types/index.js +9 -25
- package/dist/types/info/index.d.ts +2 -2
- package/dist/types/info/index.js +1 -2
- package/dist/types/library/index.js +5 -2
- package/dist/types/mta/index.js +1 -2
- package/dist/types/package/basic.js +1 -2
- package/dist/types/package/index.d.ts +1 -1
- package/dist/types/package/index.js +1 -2
- package/dist/types/package/literal-union.d.ts +1 -1
- package/dist/types/package/literal-union.js +1 -2
- package/dist/types/package/package-json.d.ts +2 -2
- package/dist/types/package/package-json.js +1 -2
- package/dist/types/package/primitive.js +1 -2
- package/dist/types/vscode/index.js +1 -2
- package/dist/types/webapp/index.d.ts +2 -3
- package/dist/types/webapp/index.js +1 -2
- package/package.json +7 -5
package/dist/project/cap.js
CHANGED
|
@@ -1,45 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
exports.getCdsFiles = getCdsFiles;
|
|
12
|
-
exports.getCdsRoots = getCdsRoots;
|
|
13
|
-
exports.getCdsServices = getCdsServices;
|
|
14
|
-
exports.readCapServiceMetadataEdmx = readCapServiceMetadataEdmx;
|
|
15
|
-
exports.isMatchingServiceUri = isMatchingServiceUri;
|
|
16
|
-
exports.getCapEnvironment = getCapEnvironment;
|
|
17
|
-
exports.clearCdsModuleCache = clearCdsModuleCache;
|
|
18
|
-
exports.clearGlobalCdsModulePromiseCache = clearGlobalCdsModulePromiseCache;
|
|
19
|
-
exports.getGlobalCdsHomePath = getGlobalCdsHomePath;
|
|
20
|
-
exports.getCapServiceName = getCapServiceName;
|
|
21
|
-
exports.deleteCapApp = deleteCapApp;
|
|
22
|
-
exports.checkCdsUi5PluginEnabled = checkCdsUi5PluginEnabled;
|
|
23
|
-
exports.getWorkspaceInfo = getWorkspaceInfo;
|
|
24
|
-
exports.satisfiesMinCdsVersion = satisfiesMinCdsVersion;
|
|
25
|
-
exports.hasMinCdsVersion = hasMinCdsVersion;
|
|
26
|
-
const node_child_process_1 = require("node:child_process");
|
|
27
|
-
const node_path_1 = require("node:path");
|
|
28
|
-
const constants_1 = require("../constants");
|
|
29
|
-
const file_1 = require("../file");
|
|
30
|
-
const module_loader_1 = require("./module-loader");
|
|
31
|
-
const search_1 = require("./search");
|
|
32
|
-
const semver_1 = require("semver");
|
|
33
|
-
const mem_fs_1 = require("mem-fs");
|
|
34
|
-
const mem_fs_editor_1 = require("mem-fs-editor");
|
|
35
|
-
const dependencies_1 = require("./dependencies");
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { basename, dirname, join, normalize, relative, sep } from 'node:path';
|
|
3
|
+
import { FileName, MinCdsVersion } from '../constants.js';
|
|
4
|
+
import { deleteDirectory, deleteFile, fileExists, findBy, readDirectory, readFile, readJSON, updatePackageJSON, writeFile } from '../file/index.js';
|
|
5
|
+
import { loadModuleFromProject } from './module-loader.js';
|
|
6
|
+
import { findCapProjectRoot } from './search.js';
|
|
7
|
+
import { coerce, gte, satisfies } from 'semver';
|
|
8
|
+
import { create as createStorage } from 'mem-fs';
|
|
9
|
+
import { create } from 'mem-fs-editor';
|
|
10
|
+
import { hasDependency } from './dependencies.js';
|
|
36
11
|
/**
|
|
37
12
|
* Returns true if the project is a CAP Node.js project.
|
|
38
13
|
*
|
|
39
14
|
* @param packageJson - the parsed package.json object
|
|
40
15
|
* @returns - true if the project is a CAP Node.js project
|
|
41
16
|
*/
|
|
42
|
-
function isCapNodeJsProject(packageJson) {
|
|
17
|
+
export function isCapNodeJsProject(packageJson) {
|
|
43
18
|
return !!(packageJson.cds ?? packageJson.dependencies?.['@sap/cds']);
|
|
44
19
|
}
|
|
45
20
|
/**
|
|
@@ -50,9 +25,9 @@ function isCapNodeJsProject(packageJson) {
|
|
|
50
25
|
* @param memFs - optional mem-fs-editor instance
|
|
51
26
|
* @returns - true if the project is a CAP project
|
|
52
27
|
*/
|
|
53
|
-
async function isCapJavaProject(projectRoot, capCustomPaths, memFs) {
|
|
28
|
+
export async function isCapJavaProject(projectRoot, capCustomPaths, memFs) {
|
|
54
29
|
const srv = capCustomPaths?.srv ?? (await getCapCustomPaths(projectRoot)).srv;
|
|
55
|
-
return
|
|
30
|
+
return fileExists(join(projectRoot, srv, 'src', 'main', 'resources', FileName.CapJavaApplicationYaml), memFs);
|
|
56
31
|
}
|
|
57
32
|
/**
|
|
58
33
|
* Checks if there are files in the `srv` folder, using node fs or mem-fs.
|
|
@@ -63,7 +38,7 @@ async function isCapJavaProject(projectRoot, capCustomPaths, memFs) {
|
|
|
63
38
|
*/
|
|
64
39
|
async function checkFilesInSrvFolder(srvFolderPath, memFs) {
|
|
65
40
|
try {
|
|
66
|
-
return (await
|
|
41
|
+
return (await findBy({ root: srvFolderPath, memFs })).length > 0;
|
|
67
42
|
}
|
|
68
43
|
catch (error) {
|
|
69
44
|
return false;
|
|
@@ -76,9 +51,9 @@ async function checkFilesInSrvFolder(srvFolderPath, memFs) {
|
|
|
76
51
|
* @param memFs - optional mem-fs-editor instance
|
|
77
52
|
* @returns - CAPJava for Java based CAP projects; CAPNodejs for node.js based CAP projects; undefined if it is no CAP project
|
|
78
53
|
*/
|
|
79
|
-
async function getCapProjectType(projectRoot, memFs) {
|
|
54
|
+
export async function getCapProjectType(projectRoot, memFs) {
|
|
80
55
|
const capCustomPaths = await getCapCustomPaths(projectRoot);
|
|
81
|
-
if (!(await checkFilesInSrvFolder(
|
|
56
|
+
if (!(await checkFilesInSrvFolder(join(projectRoot, capCustomPaths.srv), memFs))) {
|
|
82
57
|
return undefined;
|
|
83
58
|
}
|
|
84
59
|
if (await isCapJavaProject(projectRoot, capCustomPaths, memFs)) {
|
|
@@ -86,7 +61,7 @@ async function getCapProjectType(projectRoot, memFs) {
|
|
|
86
61
|
}
|
|
87
62
|
let packageJson;
|
|
88
63
|
try {
|
|
89
|
-
packageJson = await
|
|
64
|
+
packageJson = await readJSON(join(projectRoot, FileName.Package), memFs);
|
|
90
65
|
}
|
|
91
66
|
catch {
|
|
92
67
|
// Ignore errors while reading the package.json file
|
|
@@ -102,7 +77,7 @@ async function getCapProjectType(projectRoot, memFs) {
|
|
|
102
77
|
* @param projectRoot - the root path of the project
|
|
103
78
|
* @returns - true if the project is a CAP project
|
|
104
79
|
*/
|
|
105
|
-
async function isCapProject(projectRoot) {
|
|
80
|
+
export async function isCapProject(projectRoot) {
|
|
106
81
|
return !!(await getCapProjectType(projectRoot));
|
|
107
82
|
}
|
|
108
83
|
/**
|
|
@@ -111,7 +86,7 @@ async function isCapProject(projectRoot) {
|
|
|
111
86
|
* @param capProjectPath - project root of cap project
|
|
112
87
|
* @returns - paths to app, db, and srv for CAP project
|
|
113
88
|
*/
|
|
114
|
-
async function getCapCustomPaths(capProjectPath) {
|
|
89
|
+
export async function getCapCustomPaths(capProjectPath) {
|
|
115
90
|
const result = {
|
|
116
91
|
app: 'app/',
|
|
117
92
|
db: 'db/',
|
|
@@ -146,7 +121,7 @@ function filterCapServiceEndpoints(endpoint) {
|
|
|
146
121
|
* @param projectRoot - CAP project root where package.json resides or object specifying project root and optional logger to log additional info
|
|
147
122
|
* @returns {Promise<{ model: csn; services: ServiceInfo[]; cdsVersionInfo: CdsVersionInfo }>} - CAP Model and Services
|
|
148
123
|
*/
|
|
149
|
-
async function getCapModelAndServices(projectRoot) {
|
|
124
|
+
export async function getCapModelAndServices(projectRoot) {
|
|
150
125
|
let _projectRoot;
|
|
151
126
|
let _logger;
|
|
152
127
|
let _pathSelection;
|
|
@@ -164,7 +139,7 @@ async function getCapModelAndServices(projectRoot) {
|
|
|
164
139
|
const capProjectPaths = await getCapCustomPaths(_projectRoot);
|
|
165
140
|
const modelPaths = [];
|
|
166
141
|
_pathSelection?.forEach((path) => {
|
|
167
|
-
modelPaths.push(
|
|
142
|
+
modelPaths.push(join(_projectRoot, capProjectPaths[path]));
|
|
168
143
|
});
|
|
169
144
|
const model = await cds.load(modelPaths, { root: _projectRoot });
|
|
170
145
|
_logger?.info(`@sap-ux/project-access:getCapModelAndServices - Using 'cds.home': ${cds.home}`);
|
|
@@ -189,7 +164,7 @@ async function getCapModelAndServices(projectRoot) {
|
|
|
189
164
|
* @param services - list of services from cds.compile.to['serviceinfo'](model)
|
|
190
165
|
* @returns list of normalized service info
|
|
191
166
|
*/
|
|
192
|
-
function processServices(services) {
|
|
167
|
+
export function processServices(services) {
|
|
193
168
|
// filter services that have ( urlPath defined AND no endpoints) OR have endpoints with kind 'odata'
|
|
194
169
|
// i.e. ignore services for websockets and other unsupported protocols
|
|
195
170
|
if (services && Array.isArray(services)) {
|
|
@@ -217,7 +192,7 @@ function processServices(services) {
|
|
|
217
192
|
* @param [envRoot] - optionally, the root folder or CDS file to get the layer files
|
|
218
193
|
* @returns - array of strings containing cds file paths
|
|
219
194
|
*/
|
|
220
|
-
async function getCdsFiles(projectRoot, ignoreErrors = false, envRoot) {
|
|
195
|
+
export async function getCdsFiles(projectRoot, ignoreErrors = false, envRoot) {
|
|
221
196
|
let cdsFiles = [];
|
|
222
197
|
try {
|
|
223
198
|
let csn;
|
|
@@ -248,7 +223,7 @@ async function getCdsFiles(projectRoot, ignoreErrors = false, envRoot) {
|
|
|
248
223
|
* @param [clearCache] - optionally, clear the cache, default false
|
|
249
224
|
* @returns - array of root paths
|
|
250
225
|
*/
|
|
251
|
-
async function getCdsRoots(projectRoot, clearCache = false) {
|
|
226
|
+
export async function getCdsRoots(projectRoot, clearCache = false) {
|
|
252
227
|
const roots = [];
|
|
253
228
|
const capCustomPaths = await getCapCustomPaths(projectRoot);
|
|
254
229
|
const cdsEnvRoots = [capCustomPaths.db, capCustomPaths.srv, capCustomPaths.app, 'schema', 'services'];
|
|
@@ -258,7 +233,7 @@ async function getCdsRoots(projectRoot, clearCache = false) {
|
|
|
258
233
|
clearCdsResolveCache(cds);
|
|
259
234
|
}
|
|
260
235
|
for (const cdsEnvRoot of cdsEnvRoots) {
|
|
261
|
-
const resolvedRoots = cds.resolve(
|
|
236
|
+
const resolvedRoots = cds.resolve(join(projectRoot, cdsEnvRoot), {
|
|
262
237
|
skipModelCache: true
|
|
263
238
|
}) || [];
|
|
264
239
|
for (const resolvedRoot of resolvedRoots) {
|
|
@@ -274,7 +249,7 @@ async function getCdsRoots(projectRoot, clearCache = false) {
|
|
|
274
249
|
* @param ignoreErrors - in case loading the cds model throws an error, try to use the model from the exception object
|
|
275
250
|
* @returns - array of service definitions
|
|
276
251
|
*/
|
|
277
|
-
async function getCdsServices(projectRoot, ignoreErrors = true) {
|
|
252
|
+
export async function getCdsServices(projectRoot, ignoreErrors = true) {
|
|
278
253
|
let cdsServices = [];
|
|
279
254
|
try {
|
|
280
255
|
const cds = await loadCdsModuleFromProject(projectRoot);
|
|
@@ -317,8 +292,8 @@ function extractCdsFilesFromMessage(sources) {
|
|
|
317
292
|
const cdsFiles = [];
|
|
318
293
|
for (const source in sources) {
|
|
319
294
|
let filename = sources[source].filename;
|
|
320
|
-
if (typeof filename === 'string' && !filename.startsWith(
|
|
321
|
-
filename =
|
|
295
|
+
if (typeof filename === 'string' && !filename.startsWith(sep)) {
|
|
296
|
+
filename = join(sep, filename);
|
|
322
297
|
}
|
|
323
298
|
if (filename) {
|
|
324
299
|
cdsFiles.push(filename);
|
|
@@ -350,7 +325,7 @@ function uniformUrl(url) {
|
|
|
350
325
|
* @param version - optional OData version v2 or v4
|
|
351
326
|
* @returns - string containing the edmx
|
|
352
327
|
*/
|
|
353
|
-
async function readCapServiceMetadataEdmx(root, uri, version = 'v4') {
|
|
328
|
+
export async function readCapServiceMetadataEdmx(root, uri, version = 'v4') {
|
|
354
329
|
try {
|
|
355
330
|
const { model, services } = await getCapModelAndServices(root);
|
|
356
331
|
const service = findServiceByUri(services, uri);
|
|
@@ -388,7 +363,7 @@ function normalizeServiceUrlPath(urlPath) {
|
|
|
388
363
|
* @param expectedSuffixPath - The expected service path (e.g. `odata/v4/myService`).
|
|
389
364
|
* @returns `true` if the path matches one of the supported patterns and ends with the expected suffix.
|
|
390
365
|
*/
|
|
391
|
-
function isMatchingServiceUri(path, expectedSuffixPath) {
|
|
366
|
+
export function isMatchingServiceUri(path, expectedSuffixPath) {
|
|
392
367
|
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
|
393
368
|
// Escapes special regex characters in a string so it can be embedded into regular expression
|
|
394
369
|
const escapedSuffix = expectedSuffixPath.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw `\$&`);
|
|
@@ -424,7 +399,7 @@ function findServiceByUri(services, uri) {
|
|
|
424
399
|
* @param capProjectPath - project root of a CAP project
|
|
425
400
|
* @returns - environment config for a CAP project
|
|
426
401
|
*/
|
|
427
|
-
async function getCapEnvironment(capProjectPath) {
|
|
402
|
+
export async function getCapEnvironment(capProjectPath) {
|
|
428
403
|
const cds = await loadCdsModuleFromProject(capProjectPath);
|
|
429
404
|
return cds.env.for('cds', capProjectPath);
|
|
430
405
|
}
|
|
@@ -443,7 +418,7 @@ async function loadCdsModuleFromProject(capProjectPath, strict = false) {
|
|
|
443
418
|
let loadError;
|
|
444
419
|
try {
|
|
445
420
|
// First approach, load @sap/cds from project
|
|
446
|
-
module = await
|
|
421
|
+
module = await loadModuleFromProject(capProjectPath, '@sap/cds');
|
|
447
422
|
}
|
|
448
423
|
catch (error) {
|
|
449
424
|
loadProjectError = error;
|
|
@@ -463,7 +438,7 @@ async function loadCdsModuleFromProject(capProjectPath, strict = false) {
|
|
|
463
438
|
const cds = 'default' in module ? module.default : module;
|
|
464
439
|
// In case strict is true and there was a fallback to global cds installation for a project that has a cds dependency, check if major versions match
|
|
465
440
|
if (strict && loadProjectError) {
|
|
466
|
-
const cdsDependencyVersion = await getCdsVersionFromPackageJson(
|
|
441
|
+
const cdsDependencyVersion = await getCdsVersionFromPackageJson(join(capProjectPath, FileName.Package));
|
|
467
442
|
if (typeof cdsDependencyVersion === 'string') {
|
|
468
443
|
const globalCdsVersion = cds.version;
|
|
469
444
|
if (getMajorVersion(cdsDependencyVersion) !== getMajorVersion(globalCdsVersion)) {
|
|
@@ -487,7 +462,7 @@ async function loadCdsModuleFromProject(capProjectPath, strict = false) {
|
|
|
487
462
|
* @param projectRoot root of a CAP project.
|
|
488
463
|
* @returns True if cache cleared successfully.
|
|
489
464
|
*/
|
|
490
|
-
async function clearCdsModuleCache(projectRoot) {
|
|
465
|
+
export async function clearCdsModuleCache(projectRoot) {
|
|
491
466
|
let result = false;
|
|
492
467
|
try {
|
|
493
468
|
const cds = await loadCdsModuleFromProject(projectRoot);
|
|
@@ -516,8 +491,7 @@ function clearCdsResolveCache(cds) {
|
|
|
516
491
|
* @param relativeUri - relative resource path.
|
|
517
492
|
* @returns {string} - absolute path.
|
|
518
493
|
*/
|
|
519
|
-
const toAbsoluteUri = (projectRoot, relativeUri) =>
|
|
520
|
-
exports.toAbsoluteUri = toAbsoluteUri;
|
|
494
|
+
export const toAbsoluteUri = (projectRoot, relativeUri) => join(projectRoot, relativeUri);
|
|
521
495
|
/**
|
|
522
496
|
* Converts to referenced uri to be used in using statements.
|
|
523
497
|
*
|
|
@@ -526,7 +500,7 @@ exports.toAbsoluteUri = toAbsoluteUri;
|
|
|
526
500
|
* @param relativeUriTo - relative uri of to directory
|
|
527
501
|
* @returns {Promise<string>} - reference uri
|
|
528
502
|
*/
|
|
529
|
-
const toReferenceUri = async (projectRoot, relativeUriFrom, relativeUriTo) => {
|
|
503
|
+
export const toReferenceUri = async (projectRoot, relativeUriFrom, relativeUriTo) => {
|
|
530
504
|
let relativeUri = '';
|
|
531
505
|
const indexNodeModules = relativeUriTo.lastIndexOf('node_modules');
|
|
532
506
|
if (indexNodeModules >= 0) {
|
|
@@ -548,8 +522,8 @@ const toReferenceUri = async (projectRoot, relativeUriFrom, relativeUriTo) => {
|
|
|
548
522
|
}
|
|
549
523
|
if (!relativeUri) {
|
|
550
524
|
// build relative path
|
|
551
|
-
const fromDir =
|
|
552
|
-
relativeUri =
|
|
525
|
+
const fromDir = dirname(toAbsoluteUri(projectRoot, relativeUriFrom));
|
|
526
|
+
relativeUri = relative(fromDir, toAbsoluteUri(projectRoot, relativeUriTo));
|
|
553
527
|
if (!relativeUri.startsWith('.')) {
|
|
554
528
|
relativeUri = './' + relativeUri;
|
|
555
529
|
}
|
|
@@ -560,9 +534,8 @@ const toReferenceUri = async (projectRoot, relativeUriFrom, relativeUriTo) => {
|
|
|
560
534
|
relativeUri = relativeUri.slice(0, relativeUri.length - fileExtension.length - 1);
|
|
561
535
|
}
|
|
562
536
|
// always use '/' instead of platform specific separator
|
|
563
|
-
return relativeUri.split(
|
|
537
|
+
return relativeUri.split(sep).join('/');
|
|
564
538
|
};
|
|
565
|
-
exports.toReferenceUri = toReferenceUri;
|
|
566
539
|
/**
|
|
567
540
|
* Gets package name from the folder.
|
|
568
541
|
*
|
|
@@ -571,10 +544,10 @@ exports.toReferenceUri = toReferenceUri;
|
|
|
571
544
|
* @returns {Promise<{ packageName: string; packageFolder: string }>} - package name and folder
|
|
572
545
|
*/
|
|
573
546
|
async function getPackageNameInFolder(baseUri, relativeUri) {
|
|
574
|
-
const refUriParts = relativeUri.split(
|
|
547
|
+
const refUriParts = relativeUri.split(sep);
|
|
575
548
|
const result = { packageName: '', packageFolder: relativeUri };
|
|
576
549
|
for (let i = refUriParts.length - 1; i >= 0 && !result.packageName; i--) {
|
|
577
|
-
const currentFolder = refUriParts.slice(0, i).join(
|
|
550
|
+
const currentFolder = refUriParts.slice(0, i).join(sep);
|
|
578
551
|
result.packageName = await readPackageNameForFolder(baseUri, currentFolder);
|
|
579
552
|
if (result.packageName) {
|
|
580
553
|
result.packageFolder = currentFolder;
|
|
@@ -592,8 +565,8 @@ async function getPackageNameInFolder(baseUri, relativeUri) {
|
|
|
592
565
|
async function readPackageNameForFolder(baseUri, relativeUri) {
|
|
593
566
|
let packageName = '';
|
|
594
567
|
try {
|
|
595
|
-
const path =
|
|
596
|
-
const content = await
|
|
568
|
+
const path = normalize(baseUri + '/' + relativeUri + '/' + FileName.Package);
|
|
569
|
+
const content = await readJSON(path);
|
|
597
570
|
if (typeof content?.name === 'string') {
|
|
598
571
|
packageName = content.name;
|
|
599
572
|
}
|
|
@@ -617,7 +590,7 @@ async function loadGlobalCdsModule() {
|
|
|
617
590
|
return getGlobalCdsHomePath().then((home) => {
|
|
618
591
|
if (home) {
|
|
619
592
|
// "@sap/cds" module is inside node_modules of "@sap/cds-dk"
|
|
620
|
-
resolve(
|
|
593
|
+
resolve(loadModuleFromProject(join(home, 'node_modules', '@sap', 'cds'), '@sap/cds'));
|
|
621
594
|
}
|
|
622
595
|
else {
|
|
623
596
|
reject(new Error('Can not find global installation of module @sap/cds, which should be part of @sap/cds-dk'));
|
|
@@ -629,7 +602,7 @@ async function loadGlobalCdsModule() {
|
|
|
629
602
|
/**
|
|
630
603
|
* Clear cache of request to load global cds module.
|
|
631
604
|
*/
|
|
632
|
-
function clearGlobalCdsModulePromiseCache() {
|
|
605
|
+
export function clearGlobalCdsModulePromiseCache() {
|
|
633
606
|
globalCdsModulePromise = undefined;
|
|
634
607
|
}
|
|
635
608
|
/**
|
|
@@ -642,7 +615,7 @@ async function getCdsEnvData(cwd) {
|
|
|
642
615
|
return new Promise((resolve, reject) => {
|
|
643
616
|
let out = '';
|
|
644
617
|
// call 'cds env --json'
|
|
645
|
-
const cdsVersionInfo =
|
|
618
|
+
const cdsVersionInfo = spawn('cds', ['env', '--json'], { cwd, shell: true });
|
|
646
619
|
cdsVersionInfo.stdout.on('data', (data) => {
|
|
647
620
|
out += data.toString();
|
|
648
621
|
});
|
|
@@ -671,7 +644,7 @@ async function getCdsEnvData(cwd) {
|
|
|
671
644
|
*
|
|
672
645
|
* @returns {Promise<string | undefined>} The absolute path to the global CDS home directory, or undefined if not found.
|
|
673
646
|
*/
|
|
674
|
-
async function getGlobalCdsHomePath() {
|
|
647
|
+
export async function getGlobalCdsHomePath() {
|
|
675
648
|
const cdsEnvData = await getCdsEnvData();
|
|
676
649
|
// Handle output of `cds env --json`
|
|
677
650
|
return cdsEnvData['_home_cds-dk'];
|
|
@@ -685,8 +658,8 @@ async function getGlobalCdsHomePath() {
|
|
|
685
658
|
async function getCdsVersionFromPackageJson(packageJsonPath) {
|
|
686
659
|
let version;
|
|
687
660
|
try {
|
|
688
|
-
if (await
|
|
689
|
-
const packageJson = await
|
|
661
|
+
if (await fileExists(packageJsonPath)) {
|
|
662
|
+
const packageJson = await readJSON(packageJsonPath);
|
|
690
663
|
version = packageJson?.dependencies?.['@sap/cds'];
|
|
691
664
|
}
|
|
692
665
|
}
|
|
@@ -711,7 +684,7 @@ function getMajorVersion(versionString) {
|
|
|
711
684
|
* @param datasourceUri - service uri
|
|
712
685
|
* @returns - found cap service name
|
|
713
686
|
*/
|
|
714
|
-
async function getCapServiceName(projectRoot, datasourceUri) {
|
|
687
|
+
export async function getCapServiceName(projectRoot, datasourceUri) {
|
|
715
688
|
const services = (await getCapModelAndServices(projectRoot)).services;
|
|
716
689
|
const service = findServiceByUri(services, datasourceUri);
|
|
717
690
|
if (!service?.name) {
|
|
@@ -731,18 +704,18 @@ async function getCapServiceName(projectRoot, datasourceUri) {
|
|
|
731
704
|
async function cleanupCdsFiles(cdsFilePaths, appName, memFs, logger) {
|
|
732
705
|
const usingEntry = `using from './${appName}/annotations';`;
|
|
733
706
|
for (const cdsFilePath of cdsFilePaths) {
|
|
734
|
-
if (await
|
|
707
|
+
if (await fileExists(cdsFilePath, memFs)) {
|
|
735
708
|
try {
|
|
736
|
-
let cdsFile = await
|
|
709
|
+
let cdsFile = await readFile(cdsFilePath, memFs);
|
|
737
710
|
if (cdsFile.indexOf(usingEntry) !== -1) {
|
|
738
711
|
logger?.info(`Removing using statement for './${appName}/annotations' from '${cdsFilePath}'.`);
|
|
739
712
|
cdsFile = cdsFile.replace(usingEntry, '');
|
|
740
713
|
if (cdsFile.replace(/\n/g, '').trim() === '') {
|
|
741
714
|
logger?.info(`File '${cdsFilePath}' is now empty, removing it.`);
|
|
742
|
-
await
|
|
715
|
+
await deleteFile(cdsFilePath, memFs);
|
|
743
716
|
}
|
|
744
717
|
else {
|
|
745
|
-
await
|
|
718
|
+
await writeFile(cdsFilePath, cdsFile, memFs);
|
|
746
719
|
}
|
|
747
720
|
}
|
|
748
721
|
}
|
|
@@ -759,17 +732,17 @@ async function cleanupCdsFiles(cdsFilePaths, appName, memFs, logger) {
|
|
|
759
732
|
* @param [memFs] - optional mem-fs-editor instance
|
|
760
733
|
* @param [logger] - function to log messages (optional)
|
|
761
734
|
*/
|
|
762
|
-
async function deleteCapApp(appPath, memFs, logger) {
|
|
763
|
-
const appName =
|
|
764
|
-
const projectRoot = await
|
|
735
|
+
export async function deleteCapApp(appPath, memFs, logger) {
|
|
736
|
+
const appName = basename(appPath);
|
|
737
|
+
const projectRoot = await findCapProjectRoot(appPath);
|
|
765
738
|
if (!projectRoot) {
|
|
766
739
|
const message = `Project root was not found for CAP application with path '${appPath}'`;
|
|
767
740
|
logger?.error(message);
|
|
768
741
|
throw Error(message);
|
|
769
742
|
}
|
|
770
|
-
const packageJsonPath =
|
|
771
|
-
const packageJson = await
|
|
772
|
-
const cdsFilePaths = [
|
|
743
|
+
const packageJsonPath = join(projectRoot, FileName.Package);
|
|
744
|
+
const packageJson = await readJSON(packageJsonPath, memFs);
|
|
745
|
+
const cdsFilePaths = [join(dirname(appPath), FileName.ServiceCds), join(dirname(appPath), FileName.IndexCds)];
|
|
773
746
|
logger?.info(`Deleting app '${appName}' from CAP project '${projectRoot}'.`);
|
|
774
747
|
// Update `sapux` array if presented in package.json
|
|
775
748
|
if (Array.isArray(packageJson.sapux)) {
|
|
@@ -783,16 +756,16 @@ async function deleteCapApp(appPath, memFs, logger) {
|
|
|
783
756
|
if (packageJson.scripts?.[`watch-${appName}`]) {
|
|
784
757
|
delete packageJson.scripts[`watch-${appName}`];
|
|
785
758
|
}
|
|
786
|
-
await
|
|
759
|
+
await updatePackageJSON(packageJsonPath, packageJson, memFs);
|
|
787
760
|
logger?.info(`File '${packageJsonPath}' updated.`);
|
|
788
|
-
await
|
|
761
|
+
await deleteDirectory(appPath, memFs);
|
|
789
762
|
logger?.info(`Directory '${appPath}' deleted.`);
|
|
790
763
|
// Cleanup app/service.cds and app/index.cds files
|
|
791
764
|
await cleanupCdsFiles(cdsFilePaths, appName, memFs, logger);
|
|
792
765
|
// Check if app folder is now empty
|
|
793
|
-
if ((await
|
|
794
|
-
logger?.info(`Directory '${
|
|
795
|
-
await
|
|
766
|
+
if ((await readDirectory(dirname(appPath))).length === 0) {
|
|
767
|
+
logger?.info(`Directory '${dirname(appPath)}' is now empty. Deleting it.`);
|
|
768
|
+
await deleteDirectory(dirname(appPath), memFs);
|
|
796
769
|
}
|
|
797
770
|
}
|
|
798
771
|
/**
|
|
@@ -806,11 +779,11 @@ async function deleteCapApp(appPath, memFs, logger) {
|
|
|
806
779
|
* @returns false if package.json is not found at specified path or {@link CdsUi5PluginInfo} with additional info or true if
|
|
807
780
|
* cds-plugin-ui5 and all prerequisites are fulfilled
|
|
808
781
|
*/
|
|
809
|
-
async function checkCdsUi5PluginEnabled(basePath, fs, moreInfo, cdsVersionInfo) {
|
|
782
|
+
export async function checkCdsUi5PluginEnabled(basePath, fs, moreInfo, cdsVersionInfo) {
|
|
810
783
|
if (!fs) {
|
|
811
|
-
fs =
|
|
784
|
+
fs = create(createStorage());
|
|
812
785
|
}
|
|
813
|
-
const packageJsonPath =
|
|
786
|
+
const packageJsonPath = join(basePath, 'package.json');
|
|
814
787
|
if (!fs.exists(packageJsonPath)) {
|
|
815
788
|
return false;
|
|
816
789
|
}
|
|
@@ -821,10 +794,10 @@ async function checkCdsUi5PluginEnabled(basePath, fs, moreInfo, cdsVersionInfo)
|
|
|
821
794
|
// If it does, it uses that version information to determine if it satisfies the minimum CDS version required.
|
|
822
795
|
// If 'cdsVersionInfo' is not available or does not contain version information,it falls back to check the version specified in the package.json file.
|
|
823
796
|
hasMinCdsVersion: cdsVersionInfo?.version
|
|
824
|
-
?
|
|
797
|
+
? satisfies(cdsVersionInfo?.version, `>=${MinCdsVersion}`)
|
|
825
798
|
: satisfiesMinCdsVersion(packageJson),
|
|
826
799
|
isWorkspaceEnabled: workspaceEnabled,
|
|
827
|
-
hasCdsUi5Plugin:
|
|
800
|
+
hasCdsUi5Plugin: hasDependency(packageJson, 'cds-plugin-ui5'),
|
|
828
801
|
isCdsUi5PluginEnabled: false
|
|
829
802
|
};
|
|
830
803
|
cdsInfo.isCdsUi5PluginEnabled = cdsInfo.hasMinCdsVersion && cdsInfo.isWorkspaceEnabled && cdsInfo.hasCdsUi5Plugin;
|
|
@@ -837,7 +810,7 @@ async function checkCdsUi5PluginEnabled(basePath, fs, moreInfo, cdsVersionInfo)
|
|
|
837
810
|
* @param packageJson - the parsed package.json
|
|
838
811
|
* @returns - appWorkspace containing the path to the appWorkspace including wildcard; workspaceEnabled: boolean that states whether workspace for apps are enabled
|
|
839
812
|
*/
|
|
840
|
-
async function getWorkspaceInfo(basePath, packageJson) {
|
|
813
|
+
export async function getWorkspaceInfo(basePath, packageJson) {
|
|
841
814
|
const capPaths = await getCapCustomPaths(basePath);
|
|
842
815
|
const appWorkspace = capPaths.app.endsWith('/') ? `${capPaths.app}*` : `${capPaths.app}/*`;
|
|
843
816
|
const workspacePackages = getWorkspacePackages(packageJson) ?? [];
|
|
@@ -868,8 +841,8 @@ function getWorkspacePackages(packageJson) {
|
|
|
868
841
|
* @param packageJson - the parsed package.json
|
|
869
842
|
* @returns - true: cds version satisfies the min cds version; false: cds version does not satisfy min cds version
|
|
870
843
|
*/
|
|
871
|
-
function satisfiesMinCdsVersion(packageJson) {
|
|
872
|
-
return hasMinCdsVersion(packageJson) ||
|
|
844
|
+
export function satisfiesMinCdsVersion(packageJson) {
|
|
845
|
+
return hasMinCdsVersion(packageJson) || satisfies(MinCdsVersion, packageJson.dependencies?.['@sap/cds'] ?? '0.0.0');
|
|
873
846
|
}
|
|
874
847
|
/**
|
|
875
848
|
* Check if package.json has dependency to the minimum min version of @sap/cds,
|
|
@@ -878,7 +851,7 @@ function satisfiesMinCdsVersion(packageJson) {
|
|
|
878
851
|
* @param packageJson - the parsed package.json
|
|
879
852
|
* @returns - true: min cds version is present; false: cds version needs update
|
|
880
853
|
*/
|
|
881
|
-
function hasMinCdsVersion(packageJson) {
|
|
882
|
-
return
|
|
854
|
+
export function hasMinCdsVersion(packageJson) {
|
|
855
|
+
return gte(coerce(packageJson.dependencies?.['@sap/cds']) ?? '0.0.0', MinCdsVersion);
|
|
883
856
|
}
|
|
884
857
|
//# sourceMappingURL=cap.js.map
|
|
@@ -1,12 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
exports.addPackageDevDependency = addPackageDevDependency;
|
|
6
|
-
const node_fs_1 = require("node:fs");
|
|
7
|
-
const node_path_1 = require("node:path");
|
|
8
|
-
const constants_1 = require("../constants");
|
|
9
|
-
const file_1 = require("../file");
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { dirname, isAbsolute, join, parse } from 'node:path';
|
|
3
|
+
import { FileName } from '../constants.js';
|
|
4
|
+
import { readJSON, updatePackageJSON } from '../file/index.js';
|
|
10
5
|
/**
|
|
11
6
|
* Helper to check for dependency/devDependency.
|
|
12
7
|
*
|
|
@@ -14,8 +9,7 @@ const file_1 = require("../file");
|
|
|
14
9
|
* @param dependency - name of the dependency
|
|
15
10
|
* @returns - true: has dependency; false: no dependency
|
|
16
11
|
*/
|
|
17
|
-
const hasDependency = (packageJson, dependency) => !!(packageJson.dependencies?.[dependency] ?? packageJson.devDependencies?.[dependency]);
|
|
18
|
-
exports.hasDependency = hasDependency;
|
|
12
|
+
export const hasDependency = (packageJson, dependency) => !!(packageJson.dependencies?.[dependency] ?? packageJson.devDependencies?.[dependency]);
|
|
19
13
|
/**
|
|
20
14
|
* Returns path to folder that hosts 'node_modules' used by project.
|
|
21
15
|
* Optionally, a module name can be passed to check for. This is
|
|
@@ -25,23 +19,23 @@ exports.hasDependency = hasDependency;
|
|
|
25
19
|
* @param [module] - optional module name to find in node_modules
|
|
26
20
|
* @returns - parent path of node_modules used by project or undefined if node module path was not found
|
|
27
21
|
*/
|
|
28
|
-
function getNodeModulesPath(projectRoot, module) {
|
|
29
|
-
if (!
|
|
22
|
+
export function getNodeModulesPath(projectRoot, module) {
|
|
23
|
+
if (!isAbsolute(projectRoot)) {
|
|
30
24
|
return undefined;
|
|
31
25
|
}
|
|
32
|
-
const { root } =
|
|
26
|
+
const { root } = parse(projectRoot);
|
|
33
27
|
let currentDir = projectRoot;
|
|
34
28
|
let modulesPath;
|
|
35
29
|
while (currentDir !== root) {
|
|
36
|
-
let checkPath =
|
|
30
|
+
let checkPath = join(currentDir, 'node_modules');
|
|
37
31
|
if (module) {
|
|
38
|
-
checkPath =
|
|
32
|
+
checkPath = join(checkPath, module, FileName.Package);
|
|
39
33
|
}
|
|
40
|
-
if (
|
|
34
|
+
if (existsSync(checkPath)) {
|
|
41
35
|
modulesPath = currentDir;
|
|
42
36
|
break;
|
|
43
37
|
}
|
|
44
|
-
currentDir =
|
|
38
|
+
currentDir = dirname(currentDir);
|
|
45
39
|
}
|
|
46
40
|
return modulesPath;
|
|
47
41
|
}
|
|
@@ -53,13 +47,13 @@ function getNodeModulesPath(projectRoot, module) {
|
|
|
53
47
|
* @param depVersion - the dependency version
|
|
54
48
|
* @param fs - optional memfs editor instance
|
|
55
49
|
*/
|
|
56
|
-
async function addPackageDevDependency(basePath, depName, depVersion, fs) {
|
|
57
|
-
const filePath =
|
|
58
|
-
const packageJson = await
|
|
50
|
+
export async function addPackageDevDependency(basePath, depName, depVersion, fs) {
|
|
51
|
+
const filePath = join(basePath, FileName.Package);
|
|
52
|
+
const packageJson = await readJSON(filePath, fs);
|
|
59
53
|
packageJson.devDependencies = packageJson.devDependencies ?? {};
|
|
60
54
|
if (!packageJson.devDependencies[depName]) {
|
|
61
55
|
packageJson.devDependencies[depName] = depVersion;
|
|
62
56
|
}
|
|
63
|
-
await
|
|
57
|
+
await updatePackageJSON(filePath, packageJson, fs);
|
|
64
58
|
}
|
|
65
59
|
//# sourceMappingURL=dependencies.js.map
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const node_path_1 = require("node:path");
|
|
5
|
-
const file_1 = require("../file");
|
|
6
|
-
const node_fs_1 = require("node:fs");
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { readDirectory, readFile } from '../file/index.js';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
7
4
|
/**
|
|
8
5
|
* Reads all flex change files from the changes directory.
|
|
9
6
|
*
|
|
@@ -11,12 +8,12 @@ const node_fs_1 = require("node:fs");
|
|
|
11
8
|
* @param memFs - optional mem-fs-editor instance.
|
|
12
9
|
* @returns A promise that resolves to an array of flex change files.
|
|
13
10
|
*/
|
|
14
|
-
async function readFlexChanges(changesPath, memFs) {
|
|
11
|
+
export async function readFlexChanges(changesPath, memFs) {
|
|
15
12
|
const changes = {};
|
|
16
|
-
if (
|
|
17
|
-
const files = await
|
|
13
|
+
if (existsSync(changesPath)) {
|
|
14
|
+
const files = await readDirectory(changesPath);
|
|
18
15
|
for (const file of files) {
|
|
19
|
-
changes[file] = await
|
|
16
|
+
changes[file] = await readFile(join(changesPath, file), memFs);
|
|
20
17
|
}
|
|
21
18
|
}
|
|
22
19
|
return changes;
|