From ff57463040e681355a7a0f31995ec8c44ae2395c Mon Sep 17 00:00:00 2001 From: cgombauld Date: Fri, 6 Mar 2026 12:17:57 +0100 Subject: [PATCH] fix(tarball): unused dependency false positive --- .changeset/fluffy-frogs-shop.md | 5 +++ .../class/DependencyCollectableSet.class.ts | 18 ++++++-- .../test/DependencyCollectableSet.spec.ts | 45 +++++++++++++++++++ 3 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 .changeset/fluffy-frogs-shop.md diff --git a/.changeset/fluffy-frogs-shop.md b/.changeset/fluffy-frogs-shop.md new file mode 100644 index 00000000..4883433e --- /dev/null +++ b/.changeset/fluffy-frogs-shop.md @@ -0,0 +1,5 @@ +--- +"@nodesecure/tarball": patch +--- + +fix(tarball): unused dependency false positive diff --git a/workspaces/tarball/src/class/DependencyCollectableSet.class.ts b/workspaces/tarball/src/class/DependencyCollectableSet.class.ts index a94fc172..ce4b5b39 100644 --- a/workspaces/tarball/src/class/DependencyCollectableSet.class.ts +++ b/workspaces/tarball/src/class/DependencyCollectableSet.class.ts @@ -217,9 +217,7 @@ export class DependencyCollectableSet implements CollectableSet { } } - const name = dependencies.includes(sourceDependency) ? - sourceDependency : - parseNpmSpec(sourceDependency)?.name ?? sourceDependency; + const name = this.#extractDependencyName(sourceDependency, dependencies); let thirdPartyDependency: string | undefined; @@ -253,6 +251,20 @@ export class DependencyCollectableSet implements CollectableSet { } } + #extractDependencyName(sourceDependency: string, dependencies: string[]) { + for (const dependency of dependencies) { + if (dependency === sourceDependency) { + return sourceDependency; + } + + if (sourceDependency.startsWith(dependency)) { + return dependency; + } + } + + return parseNpmSpec(sourceDependency)?.name ?? sourceDependency; + } + #isMissingDependency(thirdPartyDependency: string, thirdPartyAliasedDependency: string | undefined) { const { dependencies, nodejsImports = {} } = this.#mama; diff --git a/workspaces/tarball/test/DependencyCollectableSet.spec.ts b/workspaces/tarball/test/DependencyCollectableSet.spec.ts index fb1f4792..901130e5 100644 --- a/workspaces/tarball/test/DependencyCollectableSet.spec.ts +++ b/workspaces/tarball/test/DependencyCollectableSet.spec.ts @@ -263,6 +263,51 @@ describe("DependencyCollectableSet", () => { }); }); + test("should not detect unused dependencies on deep import", () => { + const mama = { + dependencies: ["koa", "kleur"], + devDependencies: ["mocha"] + }; + const dependencyCollectableSet = new DependencyCollectableSet(mama); + + dependencyCollectableSet.add("mocha", { + file: process.cwd(), location: [[0, 0], [0, 0]], metadata: { + unsafe: false, + inTry: false, + relativeFile: process.cwd() + } + }); + + dependencyCollectableSet.add("kleur", { + file: process.cwd(), location: [[0, 0], [0, 0]], metadata: { + unsafe: false, + inTry: false, + relativeFile: process.cwd() + } + }); + + dependencyCollectableSet.add("koa/dist/index.js", { + file: process.cwd(), location: [[0, 0], [0, 0]], metadata: { + unsafe: false, + inTry: false, + relativeFile: process.cwd() + } + }); + + assert.deepEqual(dependencyCollectableSet.extract(), { + files: new Set([]), + dependenciesInTryBlock: [], + flags: { hasExternalCapacity: false, hasMissingOrUnusedDependency: false }, + dependencies: { + nodeJs: [], + thirdparty: ["kleur", "koa"], + subpathImports: {}, + unused: [], + missing: [] + } + }); + }); + test("should be capable of detecting missing dependency 'kleur'", () => { const mama = { dependencies: ["mocha"],