From d9b67fda8c38f45f832891938c437adc2f5b1a88 Mon Sep 17 00:00:00 2001 From: fraxken Date: Fri, 9 May 2025 16:46:23 +0200 Subject: [PATCH] feat(mama): implement getEntryFiles() --- workspaces/mama/README.md | 3 ++ workspaces/mama/src/ManifestManager.class.ts | 39 +++++++++++++++- workspaces/mama/test/ManifestManager.spec.ts | 48 ++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/workspaces/mama/README.md b/workspaces/mama/README.md index 44ab7714..32f0ac0a 100644 --- a/workspaces/mama/README.md +++ b/workspaces/mama/README.md @@ -62,6 +62,9 @@ Default values are injected if they are not present in the document. This behavi > [!NOTE] > document is deep cloned (there will no longer be any reference to the object supplied as an argument) +### getEntryFiles(): IterableIterator< string > +Deeply extract entry files from package `main` and Node.js `exports` fields. + ### spec Return the NPM specification (which is the combinaison of `name@version`). diff --git a/workspaces/mama/src/ManifestManager.class.ts b/workspaces/mama/src/ManifestManager.class.ts index bbedd49a..4131f812 100644 --- a/workspaces/mama/src/ManifestManager.class.ts +++ b/workspaces/mama/src/ManifestManager.class.ts @@ -5,7 +5,10 @@ import path from "node:path"; // Import Third-party Dependencies import { parseAuthor } from "@nodesecure/utils"; import type { - PackumentVersion, PackageJSON, WorkspacesPackageJSON, Contact + PackumentVersion, + PackageJSON, + WorkspacesPackageJSON, + Contact } from "@nodesecure/npm-types"; // Import Internal Dependencies @@ -123,6 +126,40 @@ export class ManifestManager< return packageJSONIntegrityHash(this.document); } + * getEntryFiles(): IterableIterator { + if (this.document.main) { + yield this.document.main; + } + + if (!this.document.exports) { + return; + } + + if (typeof this.document.exports === "string") { + yield this.document.exports; + } + else { + yield* this.extractNodejsExport(this.document.exports); + } + } + + private* extractNodejsExport( + exports: Record> + ): IterableIterator { + for (const node of Object.values(exports)) { + if (node === null) { + continue; + } + + if (typeof node === "string") { + yield node; + } + else { + yield* this.extractNodejsExport(node); + } + } + } + static async fromPackageJSON( location: string ): Promise { diff --git a/workspaces/mama/test/ManifestManager.spec.ts b/workspaces/mama/test/ManifestManager.spec.ts index b082bbda..c1b3b694 100644 --- a/workspaces/mama/test/ManifestManager.spec.ts +++ b/workspaces/mama/test/ManifestManager.spec.ts @@ -552,4 +552,52 @@ describe("ManifestManager", () => { }); }); }); + + describe("getEntryFiles", () => { + it("should return PackageJSON main entry files", () => { + const packageJSON: PackageJSON = { + ...kMinimalPackageJSON, + main: "./dist/index.js", + exports: "./dist/foobar.js" + }; + + const mama = new ManifestManager(packageJSON); + const files = new Set(mama.getEntryFiles()); + + assert.deepEqual( + [...files], + [ + "./dist/index.js", + "./dist/foobar.js" + ] + ); + }); + + it("should deep extract Node.js export fields in PackageJSON", () => { + const packageJSON: PackageJSON = { + ...kMinimalPackageJSON, + exports: { + ".": { + import: "./index.js" + }, + "./web": { + import: "./src/web.js" + }, + "./package.json": "./package.json" + } + }; + + const mama = new ManifestManager(packageJSON); + const files = new Set(mama.getEntryFiles()); + + assert.deepEqual( + [...files], + [ + "./index.js", + "./src/web.js", + "./package.json" + ] + ); + }); + }); });