@sap-ux/project-access 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +22 -0
  3. package/dist/constants.d.ts +8 -0
  4. package/dist/constants.js +11 -0
  5. package/dist/file/file-access.d.ts +26 -0
  6. package/dist/file/file-access.js +74 -0
  7. package/dist/file/file-search.d.ts +40 -0
  8. package/dist/file/file-search.js +105 -0
  9. package/dist/file/index.d.ts +3 -0
  10. package/dist/file/index.js +11 -0
  11. package/dist/index.d.ts +4 -0
  12. package/dist/index.js +27 -0
  13. package/dist/project/cap.d.ts +42 -0
  14. package/dist/project/cap.js +118 -0
  15. package/dist/project/dependencies.d.ts +10 -0
  16. package/dist/project/dependencies.js +13 -0
  17. package/dist/project/index.d.ts +5 -0
  18. package/dist/project/index.js +17 -0
  19. package/dist/project/module-loader.d.ts +9 -0
  20. package/dist/project/module-loader.js +53 -0
  21. package/dist/project/search.d.ts +23 -0
  22. package/dist/project/search.js +238 -0
  23. package/dist/project/ui5-config.d.ts +8 -0
  24. package/dist/project/ui5-config.js +40 -0
  25. package/dist/types/cap/index.d.ts +136 -0
  26. package/dist/types/cap/index.js +3 -0
  27. package/dist/types/find/index.d.ts +8 -0
  28. package/dist/types/find/index.js +3 -0
  29. package/dist/types/index.d.ts +6 -0
  30. package/dist/types/index.js +18 -0
  31. package/dist/types/package/basic.d.ts +47 -0
  32. package/dist/types/package/basic.js +3 -0
  33. package/dist/types/package/index.d.ts +12 -0
  34. package/dist/types/package/index.js +3 -0
  35. package/dist/types/package/literal-union.d.ts +32 -0
  36. package/dist/types/package/literal-union.js +3 -0
  37. package/dist/types/package/package-json.d.ts +510 -0
  38. package/dist/types/package/package-json.js +3 -0
  39. package/dist/types/package/primitive.d.ts +7 -0
  40. package/dist/types/package/primitive.js +3 -0
  41. package/dist/types/vscode/index.d.ts +10 -0
  42. package/dist/types/vscode/index.js +3 -0
  43. package/dist/types/webapp/index.d.ts +4 -0
  44. package/dist/types/webapp/index.js +3 -0
  45. package/dist/types/webapp/manifest.d.ts +2823 -0
  46. package/dist/types/webapp/manifest.js +4 -0
  47. package/package.json +46 -0
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getCapModelAndServices = exports.getCapCustomPaths = exports.getCapProjectType = exports.isCapJavaProject = exports.isCapNodeJsProject = void 0;
13
+ const path_1 = require("path");
14
+ const constants_1 = require("../constants");
15
+ const file_1 = require("../file");
16
+ const module_loader_1 = require("./module-loader");
17
+ /**
18
+ * Returns true if the project is a CAP Node.js project.
19
+ *
20
+ * @param packageJson - the parsed package.json object
21
+ * @returns - true if the project is a CAP Node.js project
22
+ */
23
+ function isCapNodeJsProject(packageJson) {
24
+ var _a;
25
+ return !!(packageJson.cds || ((_a = packageJson.dependencies) === null || _a === void 0 ? void 0 : _a['@sap/cds']));
26
+ }
27
+ exports.isCapNodeJsProject = isCapNodeJsProject;
28
+ /**
29
+ * Returns true if the project is a CAP Java project.
30
+ *
31
+ * @param projectRoot - the root path of the project
32
+ * @returns - true if the project is a CAP project
33
+ */
34
+ function isCapJavaProject(projectRoot) {
35
+ return __awaiter(this, void 0, void 0, function* () {
36
+ const { srv } = yield getCapCustomPaths(projectRoot);
37
+ return file_1.fileExists(path_1.join(projectRoot, srv, 'src', 'main', 'resources', 'application.yaml'));
38
+ });
39
+ }
40
+ exports.isCapJavaProject = isCapJavaProject;
41
+ /**
42
+ * Returns the CAP project type, undefined if it is not a CAP project.
43
+ *
44
+ * @param projectRoot - root of the project, where the package.json resides.
45
+ * @returns - CAPJava for Java based CAP projects; CAPNodejs for node.js based CAP projects; undefined if it is no CAP project
46
+ */
47
+ function getCapProjectType(projectRoot) {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ if (yield isCapJavaProject(projectRoot)) {
50
+ return 'CAPJava';
51
+ }
52
+ let packageJson;
53
+ try {
54
+ packageJson = yield file_1.readJSON(path_1.join(projectRoot, constants_1.FileName.Package));
55
+ }
56
+ catch (_a) {
57
+ // Ignore errors while reading the package.json file
58
+ }
59
+ if (packageJson && isCapNodeJsProject(packageJson)) {
60
+ return 'CAPNodejs';
61
+ }
62
+ return undefined;
63
+ });
64
+ }
65
+ exports.getCapProjectType = getCapProjectType;
66
+ /**
67
+ * Get CAP CDS project custom paths for project root.
68
+ *
69
+ * @param capProjectPath - project root of cap project
70
+ * @returns - paths to app, db, and srv for CAP project
71
+ */
72
+ function getCapCustomPaths(capProjectPath) {
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ const result = {
75
+ app: 'app/',
76
+ db: 'db/',
77
+ srv: 'srv/'
78
+ };
79
+ try {
80
+ const cds = yield module_loader_1.loadModuleFromProject(capProjectPath, '@sap/cds');
81
+ const cdsCustomPaths = cds.env.for('cds', capProjectPath);
82
+ if (cdsCustomPaths.folders) {
83
+ result.app = cdsCustomPaths.folders.app;
84
+ result.db = cdsCustomPaths.folders.db;
85
+ result.srv = cdsCustomPaths.folders.srv;
86
+ }
87
+ }
88
+ catch (error) {
89
+ // In case of issues, fall back to the defaults
90
+ }
91
+ return result;
92
+ });
93
+ }
94
+ exports.getCapCustomPaths = getCapCustomPaths;
95
+ /**
96
+ * Return the CAP model and all services.
97
+ *
98
+ * @param projectRoot - CAP project root where package.json resides
99
+ */
100
+ function getCapModelAndServices(projectRoot) {
101
+ return __awaiter(this, void 0, void 0, function* () {
102
+ const cds = yield module_loader_1.loadModuleFromProject(projectRoot, '@sap/cds');
103
+ const capProjectPaths = yield getCapCustomPaths(projectRoot);
104
+ const modelPaths = [
105
+ path_1.join(projectRoot, capProjectPaths.app),
106
+ path_1.join(projectRoot, capProjectPaths.srv),
107
+ path_1.join(projectRoot, capProjectPaths.db)
108
+ ];
109
+ const model = yield cds.load(modelPaths);
110
+ const services = cds.compile.to['serviceinfo'](model, { root: projectRoot });
111
+ return {
112
+ model,
113
+ services
114
+ };
115
+ });
116
+ }
117
+ exports.getCapModelAndServices = getCapModelAndServices;
118
+ //# sourceMappingURL=cap.js.map
@@ -0,0 +1,10 @@
1
+ import type { Package } from '../types';
2
+ /**
3
+ * Helper to check for dependency/devDependency.
4
+ *
5
+ * @param packageJson - content of package.json to check
6
+ * @param dependency - name of the dependency
7
+ * @returns - true: has dependency; false: no dependency
8
+ */
9
+ export declare const hasDependency: (packageJson: Package, dependency: string) => boolean;
10
+ //# sourceMappingURL=dependencies.d.ts.map
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.hasDependency = void 0;
4
+ /**
5
+ * Helper to check for dependency/devDependency.
6
+ *
7
+ * @param packageJson - content of package.json to check
8
+ * @param dependency - name of the dependency
9
+ * @returns - true: has dependency; false: no dependency
10
+ */
11
+ const hasDependency = (packageJson, dependency) => { var _a, _b; return !!(((_a = packageJson.dependencies) === null || _a === void 0 ? void 0 : _a[dependency]) || ((_b = packageJson.devDependencies) === null || _b === void 0 ? void 0 : _b[dependency])); };
12
+ exports.hasDependency = hasDependency;
13
+ //# sourceMappingURL=dependencies.js.map
@@ -0,0 +1,5 @@
1
+ export { getCapModelAndServices, getCapProjectType, isCapJavaProject, isCapNodeJsProject } from './cap';
2
+ export { loadModuleFromProject } from './module-loader';
3
+ export { findAllApps, findProjectRoot, getAppRootFromWebappPath } from './search';
4
+ export { getWebappPath } from './ui5-config';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getWebappPath = exports.getAppRootFromWebappPath = exports.findProjectRoot = exports.findAllApps = exports.loadModuleFromProject = exports.isCapNodeJsProject = exports.isCapJavaProject = exports.getCapProjectType = exports.getCapModelAndServices = void 0;
4
+ var cap_1 = require("./cap");
5
+ Object.defineProperty(exports, "getCapModelAndServices", { enumerable: true, get: function () { return cap_1.getCapModelAndServices; } });
6
+ Object.defineProperty(exports, "getCapProjectType", { enumerable: true, get: function () { return cap_1.getCapProjectType; } });
7
+ Object.defineProperty(exports, "isCapJavaProject", { enumerable: true, get: function () { return cap_1.isCapJavaProject; } });
8
+ Object.defineProperty(exports, "isCapNodeJsProject", { enumerable: true, get: function () { return cap_1.isCapNodeJsProject; } });
9
+ var module_loader_1 = require("./module-loader");
10
+ Object.defineProperty(exports, "loadModuleFromProject", { enumerable: true, get: function () { return module_loader_1.loadModuleFromProject; } });
11
+ var search_1 = require("./search");
12
+ Object.defineProperty(exports, "findAllApps", { enumerable: true, get: function () { return search_1.findAllApps; } });
13
+ Object.defineProperty(exports, "findProjectRoot", { enumerable: true, get: function () { return search_1.findProjectRoot; } });
14
+ Object.defineProperty(exports, "getAppRootFromWebappPath", { enumerable: true, get: function () { return search_1.getAppRootFromWebappPath; } });
15
+ var ui5_config_1 = require("./ui5-config");
16
+ Object.defineProperty(exports, "getWebappPath", { enumerable: true, get: function () { return ui5_config_1.getWebappPath; } });
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Load module from project or app. Throws error if module is not installed.
3
+ *
4
+ * @param projectRoot - root path of the project/app.
5
+ * @param moduleName - name of the npm module.
6
+ * @returns - loaded module.
7
+ */
8
+ export declare function loadModuleFromProject<T>(projectRoot: string, moduleName: string): Promise<T>;
9
+ //# sourceMappingURL=module-loader.d.ts.map
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.loadModuleFromProject = void 0;
32
+ /**
33
+ * Load module from project or app. Throws error if module is not installed.
34
+ *
35
+ * @param projectRoot - root path of the project/app.
36
+ * @param moduleName - name of the npm module.
37
+ * @returns - loaded module.
38
+ */
39
+ function loadModuleFromProject(projectRoot, moduleName) {
40
+ return __awaiter(this, void 0, void 0, function* () {
41
+ let module;
42
+ try {
43
+ const modulePath = require.resolve(moduleName, { paths: [projectRoot] });
44
+ module = (yield Promise.resolve().then(() => __importStar(require(modulePath))));
45
+ }
46
+ catch (error) {
47
+ throw Error(`Module '${moduleName}' not installed in project '${projectRoot}'`);
48
+ }
49
+ return module;
50
+ });
51
+ }
52
+ exports.loadModuleFromProject = loadModuleFromProject;
53
+ //# sourceMappingURL=module-loader.js.map
@@ -0,0 +1,23 @@
1
+ import type { AllAppResults, WorkspaceFolder } from '../types';
2
+ /**
3
+ * Find root folder of the project containing the given file.
4
+ *
5
+ * @param path path of a project file
6
+ * @param sapuxRequired if true, only find sapux projects
7
+ */
8
+ export declare function findProjectRoot(path: string, sapuxRequired?: boolean): Promise<string>;
9
+ /**
10
+ * Get the application root for a given webapp path.
11
+ *
12
+ * @param webappPath - path to webapp folder, where manifest.json is
13
+ * @returns - root path of the application, where usually ui5.yaml and package.json are
14
+ */
15
+ export declare function getAppRootFromWebappPath(webappPath: string): Promise<string | null>;
16
+ /**
17
+ * Find all app that are supported by Fiori tools for a given list of roots (workspace folders).
18
+ *
19
+ * @param wsFolders - list of roots, either as vscode WorkspaceFolder[] or array of paths
20
+ * @returns - results as path to apps plus files already parsed, e.g. manifest.json
21
+ */
22
+ export declare function findAllApps(wsFolders: WorkspaceFolder[] | string[] | undefined): Promise<AllAppResults[]>;
23
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1,238 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.findAllApps = exports.getAppRootFromWebappPath = exports.findProjectRoot = void 0;
13
+ const path_1 = require("path");
14
+ const constants_1 = require("../constants");
15
+ const file_1 = require("../file");
16
+ const dependencies_1 = require("./dependencies");
17
+ const cap_1 = require("./cap");
18
+ const ui5_config_1 = require("./ui5-config");
19
+ /**
20
+ * WorkspaceFolder type guard.
21
+ *
22
+ * @param value - value to type check
23
+ * @returns - true: is a vscode workspace array; no: not a vscode workspace array
24
+ */
25
+ function isWorkspaceFolder(value) {
26
+ return value && value.length > 0 && value[0].uri !== undefined;
27
+ }
28
+ /**
29
+ * Search all manifest.json files in given workspaces. This is used as starting point to find all tools
30
+ * supported apps.
31
+ *
32
+ * @param wsFolders - workspace folders
33
+ * @returns - array of path to manifest.json files
34
+ */
35
+ function findAllManifest(wsFolders) {
36
+ return __awaiter(this, void 0, void 0, function* () {
37
+ // extract root path if provided as VSCode folder
38
+ let wsRoots;
39
+ if (wsFolders && isWorkspaceFolder(wsFolders)) {
40
+ wsRoots = [];
41
+ wsFolders
42
+ .filter((each) => each.uri.scheme === 'file')
43
+ .forEach((folder) => {
44
+ wsRoots.push(folder.uri.fsPath);
45
+ });
46
+ }
47
+ else {
48
+ wsRoots = wsFolders || [];
49
+ }
50
+ // find all manifest files
51
+ const manifests = [];
52
+ for (const root of wsRoots) {
53
+ try {
54
+ manifests.push(...(yield file_1.findFiles(constants_1.FileName.Manifest, root, ['.git', 'node_modules', 'dist'])));
55
+ }
56
+ catch (_a) {
57
+ // ignore exceptions during find
58
+ }
59
+ }
60
+ return manifests;
61
+ });
62
+ }
63
+ /**
64
+ * Find root folder of the project containing the given file.
65
+ *
66
+ * @param path path of a project file
67
+ * @param sapuxRequired if true, only find sapux projects
68
+ */
69
+ function findProjectRoot(path, sapuxRequired = true) {
70
+ return __awaiter(this, void 0, void 0, function* () {
71
+ const packageJson = yield file_1.findFileUp(constants_1.FileName.Package, path);
72
+ if (!packageJson) {
73
+ throw new Error(`Could not find any project root for '${path}'. Search was done for ${sapuxRequired ? 'Fiori elements' : 'All'} projects.`);
74
+ }
75
+ let root = path_1.dirname(packageJson);
76
+ if (sapuxRequired) {
77
+ const sapux = (yield file_1.readJSON(packageJson)).sapux;
78
+ if (!sapux) {
79
+ root = yield findProjectRoot(path_1.dirname(root), sapuxRequired);
80
+ }
81
+ }
82
+ return root;
83
+ });
84
+ }
85
+ exports.findProjectRoot = findProjectRoot;
86
+ /**
87
+ * Find app root and project root from given paths and sapux entry.
88
+ *
89
+ *
90
+ * @param sapux - value of sapux in package.json, either boolean or string array
91
+ * @param path - path where the search started from
92
+ * @param root - root of the app or project, where package.json is located
93
+ * @returns - appRoot and projectRoot or null
94
+ */
95
+ function findRootsWithSapux(sapux, path, root) {
96
+ if (typeof sapux === 'boolean' && sapux === true) {
97
+ return {
98
+ appRoot: root,
99
+ projectRoot: root
100
+ };
101
+ }
102
+ else if (Array.isArray(sapux)) {
103
+ // Backward compatibility for FE apps in CAP projects that have no app package.json,
104
+ // but are listed in CAP root sapux array
105
+ const pathWithSep = path.endsWith(path_1.sep) ? path : path + path_1.sep;
106
+ const relAppPaths = sapux.map((a) => path_1.join(...a.split(/[\\/]/)));
107
+ const relApp = relAppPaths.find((app) => pathWithSep.startsWith(path_1.join(root, app) + path_1.sep));
108
+ if (relApp) {
109
+ return {
110
+ appRoot: path_1.join(root, relApp),
111
+ projectRoot: root
112
+ };
113
+ }
114
+ }
115
+ // The first package.json we found when searching up contains sapux, but not true -> not supported
116
+ return null;
117
+ }
118
+ /**
119
+ * Get the application root for a given webapp path.
120
+ *
121
+ * @param webappPath - path to webapp folder, where manifest.json is
122
+ * @returns - root path of the application, where usually ui5.yaml and package.json are
123
+ */
124
+ function getAppRootFromWebappPath(webappPath) {
125
+ return __awaiter(this, void 0, void 0, function* () {
126
+ const ui5YamlPath = yield file_1.findFileUp(constants_1.FileName.Ui5Yaml, webappPath);
127
+ let appRoot = path_1.dirname(webappPath);
128
+ if (ui5YamlPath) {
129
+ const candidate = path_1.dirname(ui5YamlPath);
130
+ const webapp = yield ui5_config_1.getWebappPath(candidate);
131
+ if (webapp === webappPath) {
132
+ appRoot = candidate;
133
+ }
134
+ }
135
+ return appRoot;
136
+ });
137
+ }
138
+ exports.getAppRootFromWebappPath = getAppRootFromWebappPath;
139
+ /**
140
+ * Find the app root and project root folder for a given path. In case of apps in non CAP projects they are the same.
141
+ * This function also validates if an app is supported by tools considering Fiori elements apps and SAPUI5
142
+ * freestyle apps. Only if project root and app root can be determined, they are returned, otherwise null is returned.
143
+ * This function is used e.g. to get a filtered list of all manifest.json files in a workspace for tools
144
+ * supported apps and retrieve the respective root paths.
145
+ *
146
+ * This function makes following assumptions:
147
+ * - All applications have a package.json in root folder.
148
+ * - If sapux=true in package.json the app is NOT inside a CAP project.
149
+ * - Freestyle application (non CAP) has in package.json dependency to @sap/ux-ui5-tooling and <appRoot>/ui5-local.yaml.
150
+ *
151
+ * @param path - path to check, e.g. to the manifest.json
152
+ * @returns - in case a supported app is found this function returns the appRoot and projectRoot path
153
+ */
154
+ function findRootsForPath(path) {
155
+ return __awaiter(this, void 0, void 0, function* () {
156
+ try {
157
+ // Get the root of the app, that is where the package.json is, otherwise not supported
158
+ const appRoot = yield findProjectRoot(path, false);
159
+ if (!appRoot) {
160
+ return null;
161
+ }
162
+ const appPckJson = yield file_1.readJSON(path_1.join(appRoot, constants_1.FileName.Package));
163
+ // Check for most common app, Fiori elements with sapux=true in package.json
164
+ if (appPckJson.sapux) {
165
+ return findRootsWithSapux(appPckJson.sapux, path, appRoot);
166
+ }
167
+ if (cap_1.isCapNodeJsProject(appPckJson) || (yield cap_1.isCapJavaProject(appRoot))) {
168
+ // App is part of a CAP project, but doesn't have own package.json and is not mentioned in sapux array
169
+ // in root -> not supported
170
+ return null;
171
+ }
172
+ // Now we have the app root folder. Check for freestyle non CAP
173
+ if ((yield file_1.fileExists(path_1.join(appRoot, constants_1.FileName.Ui5LocalYaml))) &&
174
+ dependencies_1.hasDependency(appPckJson, '@sap/ux-ui5-tooling')) {
175
+ return {
176
+ appRoot,
177
+ projectRoot: appRoot
178
+ };
179
+ }
180
+ // Project must be CAP, find project root
181
+ try {
182
+ const { root } = path_1.parse(appRoot);
183
+ let projectRoot = path_1.dirname(appRoot);
184
+ while (projectRoot !== root) {
185
+ if (yield cap_1.getCapProjectType(projectRoot)) {
186
+ // We have found a CAP project as root. Check if the found app is not directly in CAP's 'app/' folder.
187
+ // Sometime there is a <CAP_ROOT>/app/package.json file that is used for app router (not an app)
188
+ if (path_1.join(projectRoot, 'app') !== appRoot) {
189
+ return {
190
+ appRoot,
191
+ projectRoot
192
+ };
193
+ }
194
+ }
195
+ projectRoot = path_1.dirname(projectRoot);
196
+ }
197
+ }
198
+ catch (_a) {
199
+ // No project root can be found at parent folder.
200
+ }
201
+ }
202
+ catch (_b) {
203
+ // Finding root should not throw error. Return null instead.
204
+ }
205
+ return null;
206
+ });
207
+ }
208
+ /**
209
+ * Find all app that are supported by Fiori tools for a given list of roots (workspace folders).
210
+ *
211
+ * @param wsFolders - list of roots, either as vscode WorkspaceFolder[] or array of paths
212
+ * @returns - results as path to apps plus files already parsed, e.g. manifest.json
213
+ */
214
+ function findAllApps(wsFolders) {
215
+ return __awaiter(this, void 0, void 0, function* () {
216
+ const result = [];
217
+ const manifestPaths = yield findAllManifest(wsFolders);
218
+ for (const manifestPath of manifestPaths) {
219
+ try {
220
+ // All UI5 apps have at least sap.app: { id: <ID>, type: "application" } in manifest.json
221
+ const manifest = yield file_1.readJSON(path_1.join(manifestPath, constants_1.FileName.Manifest));
222
+ if (!manifest['sap.app'] || !manifest['sap.app'].id || manifest['sap.app'].type !== 'application') {
223
+ continue;
224
+ }
225
+ const roots = yield findRootsForPath(manifestPath);
226
+ if (roots) {
227
+ result.push({ appRoot: roots.appRoot, projectRoot: roots.projectRoot, manifest, manifestPath });
228
+ }
229
+ }
230
+ catch (_a) {
231
+ // ignore exceptions for invalid manifests
232
+ }
233
+ }
234
+ return result;
235
+ });
236
+ }
237
+ exports.findAllApps = findAllApps;
238
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Get path to webapp.
3
+ *
4
+ * @param projectRoot - root path, where package.json or ui5.yaml is
5
+ * @returns - path to webapp folder
6
+ */
7
+ export declare function getWebappPath(projectRoot: string): Promise<string>;
8
+ //# sourceMappingURL=ui5-config.d.ts.map
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getWebappPath = void 0;
13
+ const path_1 = require("path");
14
+ const ui5_config_1 = require("@sap-ux/ui5-config");
15
+ const constants_1 = require("../constants");
16
+ const file_1 = require("../file");
17
+ /**
18
+ * Get path to webapp.
19
+ *
20
+ * @param projectRoot - root path, where package.json or ui5.yaml is
21
+ * @returns - path to webapp folder
22
+ */
23
+ function getWebappPath(projectRoot) {
24
+ var _a, _b;
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ let webappPath = path_1.join(projectRoot, 'webapp');
27
+ const ui5YamlPath = path_1.join(projectRoot, constants_1.FileName.Ui5Yaml);
28
+ if (yield file_1.fileExists(ui5YamlPath)) {
29
+ const yamlString = yield file_1.readFile(ui5YamlPath);
30
+ const ui5Config = yield ui5_config_1.UI5Config.newInstance(yamlString);
31
+ const relativeWebappPath = (_b = (_a = ui5Config.getConfiguration()) === null || _a === void 0 ? void 0 : _a.paths) === null || _b === void 0 ? void 0 : _b.webapp;
32
+ if (relativeWebappPath) {
33
+ webappPath = path_1.join(projectRoot, relativeWebappPath);
34
+ }
35
+ }
36
+ return webappPath;
37
+ });
38
+ }
39
+ exports.getWebappPath = getWebappPath;
40
+ //# sourceMappingURL=ui5-config.js.map