@sap-ux/project-access 1.10.2 → 1.11.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.
@@ -3,6 +3,7 @@ export declare const FileName: {
3
3
  readonly ExtConfigJson: ".extconfig.json";
4
4
  readonly Manifest: "manifest.json";
5
5
  readonly ManifestAppDescrVar: "manifest.appdescr_variant";
6
+ readonly MtaYaml: "mta.yaml";
6
7
  readonly Package: "package.json";
7
8
  readonly Tsconfig: "tsconfig.json";
8
9
  readonly Ui5Yaml: "ui5.yaml";
package/dist/constants.js CHANGED
@@ -6,6 +6,7 @@ exports.FileName = {
6
6
  ExtConfigJson: '.extconfig.json',
7
7
  Manifest: 'manifest.json',
8
8
  ManifestAppDescrVar: 'manifest.appdescr_variant',
9
+ MtaYaml: 'mta.yaml',
9
10
  Package: 'package.json',
10
11
  Tsconfig: 'tsconfig.json',
11
12
  Ui5Yaml: 'ui5.yaml',
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { FileName } from './constants';
2
- export { findAllApps, findFioriArtifacts, findProjectRoot, getAppRootFromWebappPath, getAppProgrammingLanguage, getCapCustomPaths, getCapEnvironment, getCapModelAndServices, getCapProjectType, getWebappPath, isCapJavaProject, isCapNodeJsProject, loadModuleFromProject, readCapServiceMetadataEdmx, readUi5Yaml } from './project';
2
+ export { findAllApps, findFioriArtifacts, findProjectRoot, getAppRootFromWebappPath, getAppProgrammingLanguage, getCapCustomPaths, getCapEnvironment, getCapModelAndServices, getCapProjectType, getMtaPath, getNodeModulesPath, getWebappPath, isCapJavaProject, isCapNodeJsProject, loadModuleFromProject, readCapServiceMetadataEdmx, readUi5Yaml } from './project';
3
3
  export { getFilePaths } from './file';
4
4
  export * from './types';
5
5
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.getFilePaths = exports.readUi5Yaml = exports.readCapServiceMetadataEdmx = exports.loadModuleFromProject = exports.isCapNodeJsProject = exports.isCapJavaProject = exports.getWebappPath = exports.getCapProjectType = exports.getCapModelAndServices = exports.getCapEnvironment = exports.getCapCustomPaths = exports.getAppProgrammingLanguage = exports.getAppRootFromWebappPath = exports.findProjectRoot = exports.findFioriArtifacts = exports.findAllApps = exports.FileName = void 0;
17
+ exports.getFilePaths = exports.readUi5Yaml = exports.readCapServiceMetadataEdmx = exports.loadModuleFromProject = exports.isCapNodeJsProject = exports.isCapJavaProject = exports.getWebappPath = exports.getNodeModulesPath = exports.getMtaPath = exports.getCapProjectType = exports.getCapModelAndServices = exports.getCapEnvironment = exports.getCapCustomPaths = exports.getAppProgrammingLanguage = exports.getAppRootFromWebappPath = exports.findProjectRoot = exports.findFioriArtifacts = exports.findAllApps = exports.FileName = void 0;
18
18
  var constants_1 = require("./constants");
19
19
  Object.defineProperty(exports, "FileName", { enumerable: true, get: function () { return constants_1.FileName; } });
20
20
  var project_1 = require("./project");
@@ -27,6 +27,8 @@ Object.defineProperty(exports, "getCapCustomPaths", { enumerable: true, get: fun
27
27
  Object.defineProperty(exports, "getCapEnvironment", { enumerable: true, get: function () { return project_1.getCapEnvironment; } });
28
28
  Object.defineProperty(exports, "getCapModelAndServices", { enumerable: true, get: function () { return project_1.getCapModelAndServices; } });
29
29
  Object.defineProperty(exports, "getCapProjectType", { enumerable: true, get: function () { return project_1.getCapProjectType; } });
30
+ Object.defineProperty(exports, "getMtaPath", { enumerable: true, get: function () { return project_1.getMtaPath; } });
31
+ Object.defineProperty(exports, "getNodeModulesPath", { enumerable: true, get: function () { return project_1.getNodeModulesPath; } });
30
32
  Object.defineProperty(exports, "getWebappPath", { enumerable: true, get: function () { return project_1.getWebappPath; } });
31
33
  Object.defineProperty(exports, "isCapJavaProject", { enumerable: true, get: function () { return project_1.isCapJavaProject; } });
32
34
  Object.defineProperty(exports, "isCapNodeJsProject", { enumerable: true, get: function () { return project_1.isCapNodeJsProject; } });
@@ -7,4 +7,14 @@ import type { Package } from '../types';
7
7
  * @returns - true: has dependency; false: no dependency
8
8
  */
9
9
  export declare const hasDependency: (packageJson: Package, dependency: string) => boolean;
10
+ /**
11
+ * Returns path to folder that hosts 'node_modules' used by project.
12
+ * Optionally, a module name can be passed to check for. This is
13
+ * useful to check if a module is hoisted in a mono repository.
14
+ *
15
+ * @param projectRoot - absolute path to root of the project/app.
16
+ * @param [module] - optional module name to find in node_modules
17
+ * @returns - parent path of node_modules used by project or undefined if node module path was not found
18
+ */
19
+ export declare function getNodeModulesPath(projectRoot: string, module?: string): string | undefined;
10
20
  //# sourceMappingURL=dependencies.d.ts.map
@@ -1,6 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasDependency = void 0;
3
+ exports.getNodeModulesPath = exports.hasDependency = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const constants_1 = require("../constants");
4
7
  /**
5
8
  * Helper to check for dependency/devDependency.
6
9
  *
@@ -10,4 +13,34 @@ exports.hasDependency = void 0;
10
13
  */
11
14
  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
15
  exports.hasDependency = hasDependency;
16
+ /**
17
+ * Returns path to folder that hosts 'node_modules' used by project.
18
+ * Optionally, a module name can be passed to check for. This is
19
+ * useful to check if a module is hoisted in a mono repository.
20
+ *
21
+ * @param projectRoot - absolute path to root of the project/app.
22
+ * @param [module] - optional module name to find in node_modules
23
+ * @returns - parent path of node_modules used by project or undefined if node module path was not found
24
+ */
25
+ function getNodeModulesPath(projectRoot, module) {
26
+ if (!(0, path_1.isAbsolute)(projectRoot)) {
27
+ return undefined;
28
+ }
29
+ const { root } = (0, path_1.parse)(projectRoot);
30
+ let currentDir = projectRoot;
31
+ let modulesPath;
32
+ while (currentDir !== root) {
33
+ let checkPath = (0, path_1.join)(currentDir, 'node_modules');
34
+ if (module) {
35
+ checkPath = (0, path_1.join)(checkPath, module, constants_1.FileName.Package);
36
+ }
37
+ if ((0, fs_1.existsSync)(checkPath)) {
38
+ modulesPath = currentDir;
39
+ break;
40
+ }
41
+ currentDir = (0, path_1.dirname)(currentDir);
42
+ }
43
+ return modulesPath;
44
+ }
45
+ exports.getNodeModulesPath = getNodeModulesPath;
13
46
  //# sourceMappingURL=dependencies.js.map
@@ -1,6 +1,8 @@
1
1
  export { getCapCustomPaths, getCapModelAndServices, getCapProjectType, isCapJavaProject, isCapNodeJsProject, getCapEnvironment, readCapServiceMetadataEdmx } from './cap';
2
+ export { getNodeModulesPath } from './dependencies';
2
3
  export { getAppProgrammingLanguage } from './info';
3
4
  export { loadModuleFromProject } from './module-loader';
4
5
  export { findAllApps, findFioriArtifacts, findProjectRoot, getAppRootFromWebappPath } from './search';
5
6
  export { getWebappPath, readUi5Yaml } from './ui5-config';
7
+ export { getMtaPath } from './mta';
6
8
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readUi5Yaml = exports.getWebappPath = exports.getAppRootFromWebappPath = exports.findProjectRoot = exports.findFioriArtifacts = exports.findAllApps = exports.loadModuleFromProject = exports.getAppProgrammingLanguage = exports.readCapServiceMetadataEdmx = exports.getCapEnvironment = exports.isCapNodeJsProject = exports.isCapJavaProject = exports.getCapProjectType = exports.getCapModelAndServices = exports.getCapCustomPaths = void 0;
3
+ exports.getMtaPath = exports.readUi5Yaml = exports.getWebappPath = exports.getAppRootFromWebappPath = exports.findProjectRoot = exports.findFioriArtifacts = exports.findAllApps = exports.loadModuleFromProject = exports.getAppProgrammingLanguage = exports.getNodeModulesPath = exports.readCapServiceMetadataEdmx = exports.getCapEnvironment = exports.isCapNodeJsProject = exports.isCapJavaProject = exports.getCapProjectType = exports.getCapModelAndServices = exports.getCapCustomPaths = void 0;
4
4
  var cap_1 = require("./cap");
5
5
  Object.defineProperty(exports, "getCapCustomPaths", { enumerable: true, get: function () { return cap_1.getCapCustomPaths; } });
6
6
  Object.defineProperty(exports, "getCapModelAndServices", { enumerable: true, get: function () { return cap_1.getCapModelAndServices; } });
@@ -9,6 +9,8 @@ Object.defineProperty(exports, "isCapJavaProject", { enumerable: true, get: func
9
9
  Object.defineProperty(exports, "isCapNodeJsProject", { enumerable: true, get: function () { return cap_1.isCapNodeJsProject; } });
10
10
  Object.defineProperty(exports, "getCapEnvironment", { enumerable: true, get: function () { return cap_1.getCapEnvironment; } });
11
11
  Object.defineProperty(exports, "readCapServiceMetadataEdmx", { enumerable: true, get: function () { return cap_1.readCapServiceMetadataEdmx; } });
12
+ var dependencies_1 = require("./dependencies");
13
+ Object.defineProperty(exports, "getNodeModulesPath", { enumerable: true, get: function () { return dependencies_1.getNodeModulesPath; } });
12
14
  var info_1 = require("./info");
13
15
  Object.defineProperty(exports, "getAppProgrammingLanguage", { enumerable: true, get: function () { return info_1.getAppProgrammingLanguage; } });
14
16
  var module_loader_1 = require("./module-loader");
@@ -21,4 +23,6 @@ Object.defineProperty(exports, "getAppRootFromWebappPath", { enumerable: true, g
21
23
  var ui5_config_1 = require("./ui5-config");
22
24
  Object.defineProperty(exports, "getWebappPath", { enumerable: true, get: function () { return ui5_config_1.getWebappPath; } });
23
25
  Object.defineProperty(exports, "readUi5Yaml", { enumerable: true, get: function () { return ui5_config_1.readUi5Yaml; } });
26
+ var mta_1 = require("./mta");
27
+ Object.defineProperty(exports, "getMtaPath", { enumerable: true, get: function () { return mta_1.getMtaPath; } });
24
28
  //# sourceMappingURL=index.js.map
@@ -1,8 +1,14 @@
1
1
  /**
2
2
  * Load module from project or app. Throws error if module is not installed.
3
3
  *
4
+ * Note: Node's require.resolve() caches file access results in internal statCache, see:
5
+ * (https://github.com/nodejs/node/blob/d150316a8ecad1a9c20615ae62fcaf4f8d060dcc/lib/internal/modules/cjs/loader.js#L155)
6
+ * This means, if a module is not installed and require.resolve() is executed, it will never resolve, even after the
7
+ * module is installed later on. To prevent filling cjs loader's statCache with entries for non existing files,
8
+ * we check if the module exists using getNodeModulesPath() before require.resolve().
9
+ *
4
10
  * @param projectRoot - root path of the project/app.
5
- * @param moduleName - name of the npm module.
11
+ * @param moduleName - name of the node module.
6
12
  * @returns - loaded module.
7
13
  */
8
14
  export declare function loadModuleFromProject<T>(projectRoot: string, moduleName: string): Promise<T>;
@@ -33,11 +33,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
33
33
  };
34
34
  Object.defineProperty(exports, "__esModule", { value: true });
35
35
  exports.loadModuleFromProject = void 0;
36
+ const dependencies_1 = require("./dependencies");
36
37
  /**
37
38
  * Load module from project or app. Throws error if module is not installed.
38
39
  *
40
+ * Note: Node's require.resolve() caches file access results in internal statCache, see:
41
+ * (https://github.com/nodejs/node/blob/d150316a8ecad1a9c20615ae62fcaf4f8d060dcc/lib/internal/modules/cjs/loader.js#L155)
42
+ * This means, if a module is not installed and require.resolve() is executed, it will never resolve, even after the
43
+ * module is installed later on. To prevent filling cjs loader's statCache with entries for non existing files,
44
+ * we check if the module exists using getNodeModulesPath() before require.resolve().
45
+ *
39
46
  * @param projectRoot - root path of the project/app.
40
- * @param moduleName - name of the npm module.
47
+ * @param moduleName - name of the node module.
41
48
  * @returns - loaded module.
42
49
  */
43
50
  function loadModuleFromProject(projectRoot, moduleName) {
@@ -45,11 +52,14 @@ function loadModuleFromProject(projectRoot, moduleName) {
45
52
  var _a;
46
53
  let module;
47
54
  try {
55
+ if (!(0, dependencies_1.getNodeModulesPath)(projectRoot, moduleName)) {
56
+ throw Error('Path to module not found.');
57
+ }
48
58
  const modulePath = require.resolve(moduleName, { paths: [projectRoot] });
49
59
  module = (yield (_a = modulePath, Promise.resolve().then(() => __importStar(require(_a)))));
50
60
  }
51
61
  catch (error) {
52
- throw Error(`Module '${moduleName}' not installed in project '${projectRoot}'`);
62
+ throw Error(`Module '${moduleName}' not installed in project '${projectRoot}'.\n${error.toString()}`);
53
63
  }
54
64
  return module;
55
65
  });
@@ -0,0 +1,15 @@
1
+ import type { Editor } from 'mem-fs-editor';
2
+ import type { MtaPath } from '../types/mta';
3
+ /**
4
+ * Searches `projectPath` and parent folders.
5
+ * If mta.yaml file is inside projectPath, this is a special type of MTA project
6
+ * that created in Fiori generator (Standalone App Router). E.g. Creating a new project that doesn't have
7
+ * a parent root folder for MTA project, and this project itself is configured
8
+ * to have deploy target CF and user answered yes to "add to Managed App Router" question.
9
+ *
10
+ * @param projectPath - Fiori app root folder
11
+ * @param fs - optional mem-fs-editor instance
12
+ * @returns - MtaPath
13
+ */
14
+ export declare function getMtaPath(projectPath: string, fs?: Editor): Promise<MtaPath | undefined>;
15
+ //# sourceMappingURL=mta.d.ts.map
@@ -0,0 +1,43 @@
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.getMtaPath = void 0;
13
+ const file_search_1 = require("../file/file-search");
14
+ const constants_1 = require("../constants");
15
+ const path_1 = require("path");
16
+ /**
17
+ * Searches `projectPath` and parent folders.
18
+ * If mta.yaml file is inside projectPath, this is a special type of MTA project
19
+ * that created in Fiori generator (Standalone App Router). E.g. Creating a new project that doesn't have
20
+ * a parent root folder for MTA project, and this project itself is configured
21
+ * to have deploy target CF and user answered yes to "add to Managed App Router" question.
22
+ *
23
+ * @param projectPath - Fiori app root folder
24
+ * @param fs - optional mem-fs-editor instance
25
+ * @returns - MtaPath
26
+ */
27
+ function getMtaPath(projectPath, fs) {
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ const mtaPath = yield (0, file_search_1.findFileUp)(constants_1.FileName.MtaYaml, projectPath, fs);
30
+ if (!mtaPath) {
31
+ return undefined;
32
+ }
33
+ else {
34
+ const mtaFolderPath = (0, path_1.dirname)(mtaPath);
35
+ return {
36
+ mtaPath,
37
+ hasRoot: mtaFolderPath !== projectPath
38
+ };
39
+ }
40
+ });
41
+ }
42
+ exports.getMtaPath = getMtaPath;
43
+ //# sourceMappingURL=mta.js.map
@@ -0,0 +1,5 @@
1
+ export interface MtaPath {
2
+ mtaPath: string;
3
+ hasRoot: boolean;
4
+ }
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap-ux/project-access",
3
- "version": "1.10.2",
3
+ "version": "1.11.1",
4
4
  "description": "Library to access SAP Fiori tools projects",
5
5
  "repository": {
6
6
  "type": "git",