From 960e840e5d3b9c55d6b7ab7ebc3b3a6b148b80bb Mon Sep 17 00:00:00 2001 From: fraxken Date: Fri, 28 Nov 2025 22:32:51 +0100 Subject: [PATCH] refactor(scanner)!: move payload integrity into rootDependency --- .changeset/proud-planets-dance.md | 5 +++++ workspaces/scanner/src/depWalker.ts | 24 +++++++++++++++-------- workspaces/scanner/src/types.ts | 5 ++--- workspaces/scanner/test/depWalker.spec.ts | 12 +++++------- 4 files changed, 28 insertions(+), 18 deletions(-) create mode 100644 .changeset/proud-planets-dance.md diff --git a/.changeset/proud-planets-dance.md b/.changeset/proud-planets-dance.md new file mode 100644 index 00000000..0b7099f4 --- /dev/null +++ b/.changeset/proud-planets-dance.md @@ -0,0 +1,5 @@ +--- +"@nodesecure/scanner": major +--- + +Move payload integrity into rootDependency diff --git a/workspaces/scanner/src/depWalker.ts b/workspaces/scanner/src/depWalker.ts index c4965e01..865471b1 100644 --- a/workspaces/scanner/src/depWalker.ts +++ b/workspaces/scanner/src/depWalker.ts @@ -88,6 +88,13 @@ type WalkerOptions = Omit & { npmRcConfig?: Config; }; +type InitialPayload = + Partial & + { + rootDependency: Payload["rootDependency"]; + metadata: Payload["metadata"]; + }; + export async function depWalker( manifest: PackageJSON | WorkspacesPackageJSON | ManifestVersion, options: WalkerOptions, @@ -112,11 +119,12 @@ export async function depWalker( const dependencyConfusionWarnings: DependencyConfusionWarning[] = []; - const payload: Partial = { + const payload: InitialPayload = { id: tempDir.id, rootDependency: { name: manifest.name ?? "workspace", - version: manifest.version ?? "0.0.0" + version: manifest.version ?? "0.0.0", + integrity: null }, scannerVersion: packageVersion, vulnerabilityStrategy, @@ -189,12 +197,14 @@ export async function depWalker( const isRoot = current.id === kRootDependencyId; - if (isRoot && payload.integrity) { - payload.integrity = integrity; + if (isRoot && payload.rootDependency.integrity) { + payload.rootDependency.integrity = integrity; } else if (isRoot) { const isWorkspace = options.location && "workspaces" in manifest; - payload.integrity = isWorkspace ? null : fromData(JSON.stringify(manifest), { algorithms: ["sha512"] }).toString(); + payload.rootDependency.integrity = isWorkspace ? + null : + fromData(JSON.stringify(manifest), { algorithms: ["sha512"] }).toString(); } // If the dependency is a DevDependencies we ignore it. @@ -331,9 +341,7 @@ export async function depWalker( contacts: illuminated }; payload.dependencies = Object.fromEntries(dependencies); - - const metadata = payload.metadata!; - metadata.executionTime = Date.now() - startedAt; + payload.metadata.executionTime = Date.now() - startedAt; return payload as Payload; } diff --git a/workspaces/scanner/src/types.ts b/workspaces/scanner/src/types.ts index f673ba69..58e5bcda 100644 --- a/workspaces/scanner/src/types.ts +++ b/workspaces/scanner/src/types.ts @@ -191,6 +191,8 @@ export interface Payload { rootDependency: { name: string; version: string; + /** The integrity of the scanned package */ + integrity: string | null; }; /** Global warnings list */ warnings: GlobalWarning[]; @@ -204,9 +206,6 @@ export interface Payload { /** Vulnerability strategy name (npm, snyk, node) */ vulnerabilityStrategy: Vulnera.Kind; - /** The integrity of the scanned package */ - integrity: string | null; - metadata: { /** * UNIX Timestamp when the scan started diff --git a/workspaces/scanner/test/depWalker.spec.ts b/workspaces/scanner/test/depWalker.spec.ts index f5bbe0e8..8e65bd96 100644 --- a/workspaces/scanner/test/depWalker.spec.ts +++ b/workspaces/scanner/test/depWalker.spec.ts @@ -173,11 +173,10 @@ test("fetch payload of pacote on the npm registry", async() => { "vulnerabilityStrategy", "warnings", "metadata", - "integrity", "highlighted", "dependencies" ]); - assert.strictEqual(typeof result.integrity, "string"); + assert.strictEqual(typeof result.rootDependency.integrity, "string"); }); test("fetch payload of pacote on the gitlab registry", async() => { @@ -194,11 +193,10 @@ test("fetch payload of pacote on the gitlab registry", async() => { "vulnerabilityStrategy", "warnings", "metadata", - "integrity", "highlighted", "dependencies" ]); - assert.strictEqual(typeof result.integrity, "string"); + assert.strictEqual(typeof result.rootDependency.integrity, "string"); }); test("highlight contacts from a remote package", async() => { @@ -244,7 +242,7 @@ describe("scanner.cwd()", () => { name: "NodeSecure" }); assert.strictEqual(dep.metadata.homepage, "https://nodesecure.com"); - assert.strictEqual(typeof result.integrity, "string"); + assert.strictEqual(typeof result.rootDependency.integrity, "string"); }); test("should parse local manifest author field without throwing when attempting to highlight contacts", async() => { @@ -266,9 +264,9 @@ describe("scanner.cwd()", () => { assert.deepStrictEqual(result.rootDependency, { name: "workspace", - version: "0.0.0" + version: "0.0.0", + integrity: null }); - assert.strictEqual(result.integrity, null); }); });