diff --git a/lib/graph/providers/NodePackageDependencies.js b/lib/graph/providers/NodePackageDependencies.js index ecf79c5ef..ada50f406 100644 --- a/lib/graph/providers/NodePackageDependencies.js +++ b/lib/graph/providers/NodePackageDependencies.js @@ -64,7 +64,7 @@ class NodePackageDependencies { } return Promise.all(node._dependencies.map(async ({name, optional}) => { const modulePath = await this._resolveModulePath(node.path, name, workspace); - return this._getNode(modulePath, optional); + return this._getNode(modulePath, optional, name); })); } @@ -99,7 +99,17 @@ class NodePackageDependencies { } } - async _getNode(modulePath, optional) { + /** + * Resolves a Node module by reading its package.json + * + * @param {string} modulePath Path to the module. + * @param {boolean} optional Whether this dependency is optional. + * @param {string} [nameAlias] The name of the module. It's usually the same as the name definfed + * in package.json and could easily be skipped. Useful when defining dependency as an alias: + * {@link https://github.com/npm/rfcs/blob/main/implemented/0001-package-aliases.md} + * @returns {Promise} + */ + async _getNode(modulePath, optional, nameAlias) { log.verbose(`Reading package.json in directory ${modulePath}...`); const packageJson = await readPackage({ cwd: modulePath, @@ -107,7 +117,7 @@ class NodePackageDependencies { }); return { - id: packageJson.name, + id: nameAlias || packageJson.name, version: packageJson.version, path: modulePath, optional, diff --git a/test/fixtures/application.a.aliases/node_modules/extension.a.esm.alias/lib/extensionModule.js b/test/fixtures/application.a.aliases/node_modules/extension.a.esm.alias/lib/extensionModule.js new file mode 100644 index 000000000..c7a5c0758 --- /dev/null +++ b/test/fixtures/application.a.aliases/node_modules/extension.a.esm.alias/lib/extensionModule.js @@ -0,0 +1,2 @@ +export default () => "extension module"; +export function determineRequiredDependencies () { return "required dependencies function" }; diff --git a/test/fixtures/application.a.aliases/node_modules/extension.a.esm.alias/package.json b/test/fixtures/application.a.aliases/node_modules/extension.a.esm.alias/package.json new file mode 100644 index 000000000..97c63b166 --- /dev/null +++ b/test/fixtures/application.a.aliases/node_modules/extension.a.esm.alias/package.json @@ -0,0 +1,5 @@ +{ + "name": "extension.a", + "type": "module", + "version": "1.0.0" +} diff --git a/test/fixtures/application.a.aliases/package.json b/test/fixtures/application.a.aliases/package.json new file mode 100644 index 000000000..b15c70dfe --- /dev/null +++ b/test/fixtures/application.a.aliases/package.json @@ -0,0 +1,12 @@ +{ + "name": "application.a.aliases", + "version": "1.0.0", + "description": "Simple SAPUI5 based application", + "main": "index.html", + "dependencies": { + "extension.a.esm.alias": "file:../extension.a.esm" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + } +} diff --git a/test/fixtures/application.a.aliases/ui5.yaml b/test/fixtures/application.a.aliases/ui5.yaml new file mode 100644 index 000000000..bdc9a31f8 --- /dev/null +++ b/test/fixtures/application.a.aliases/ui5.yaml @@ -0,0 +1,23 @@ +--- +specVersion: "3.0" +type: application +metadata: + name: application.a.aliases + +--- # Everything below this line could also be put into the ui5.yaml of a standalone extension module +specVersion: "3.0" +kind: extension +type: project-shim +metadata: + name: my.application.thirdparty +shims: + configurations: + extension.a.esm.alias: # name as defined in package.json + specVersion: "3.0" + type: module # Use module type + metadata: + name: extension.a.esm.alias + resources: + configuration: + paths: + /resources/my/application/thirdparty/: "" # map root directory of lodash module diff --git a/test/fixtures/application.a.aliases/webapp/index.html b/test/fixtures/application.a.aliases/webapp/index.html new file mode 100644 index 000000000..1b8755901 --- /dev/null +++ b/test/fixtures/application.a.aliases/webapp/index.html @@ -0,0 +1,9 @@ + + + + Application A + + + + + diff --git a/test/fixtures/application.a.aliases/webapp/manifest.json b/test/fixtures/application.a.aliases/webapp/manifest.json new file mode 100644 index 000000000..d33902df7 --- /dev/null +++ b/test/fixtures/application.a.aliases/webapp/manifest.json @@ -0,0 +1,13 @@ +{ + "_version": "1.1.0", + "sap.app": { + "_version": "1.1.0", + "id": "id1", + "type": "application", + "applicationVersion": { + "version": "1.2.2" + }, + "embeds": ["embedded"], + "title": "{{title}}" + } +} diff --git a/test/fixtures/application.a.aliases/webapp/test.js b/test/fixtures/application.a.aliases/webapp/test.js new file mode 100644 index 000000000..a3df410c3 --- /dev/null +++ b/test/fixtures/application.a.aliases/webapp/test.js @@ -0,0 +1,5 @@ +function test(paramA) { + var variableA = paramA; + console.log(variableA); +} +test(); diff --git a/test/lib/graph/providers/NodePackageDependencies.integration.js b/test/lib/graph/providers/NodePackageDependencies.integration.js index 842442cb1..19657aa41 100644 --- a/test/lib/graph/providers/NodePackageDependencies.integration.js +++ b/test/lib/graph/providers/NodePackageDependencies.integration.js @@ -6,6 +6,7 @@ import sinonGlobal from "sinon"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const applicationAPath = path.join(__dirname, "..", "..", "..", "fixtures", "application.a"); +const applicationAAliasesPath = path.join(__dirname, "..", "..", "..", "fixtures", "application.a.aliases"); const applicationCPath = path.join(__dirname, "..", "..", "..", "fixtures", "application.c"); const applicationC2Path = path.join(__dirname, "..", "..", "..", "fixtures", "application.c2"); const applicationC3Path = path.join(__dirname, "..", "..", "..", "fixtures", "application.c3"); @@ -68,6 +69,23 @@ test("AppA: project with collection dependency", async (t) => { ]); }); +test("AppA: project with an alias dependency", async (t) => { + const workspace = { + getName: () => "workspace name", + getModuleByNodeId: t.context.sinon.stub().resolves(undefined).onFirstCall().resolves({ + getPath: () => path.join(applicationAAliasesPath, "node_modules", "extension.a.esm.alias"), + getVersion: () => "1.0.0", + }) + }; + const npmProvider = new NodePackageDependenciesProvider({ + cwd: applicationAAliasesPath + }); + await testGraphCreationDfs(t, npmProvider, [ + "extension.a.esm.alias", + "application.a.aliases", + ], workspace); +}); + test("AppA: project with workspace overrides", async (t) => { const workspace = { getName: () => "workspace name",