From 29dde9b42d3b1d56721dd55085968e2770797a86 Mon Sep 17 00:00:00 2001 From: Bret Comnes Date: Tue, 18 Jun 2024 18:59:56 -0700 Subject: [PATCH] Add support for npm workspaces --- src/PackageDetails.ts | 1 + src/getPackageResolution.ts | 28 +++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/PackageDetails.ts b/src/PackageDetails.ts index 259ac189..e43b9fdf 100644 --- a/src/PackageDetails.ts +++ b/src/PackageDetails.ts @@ -4,6 +4,7 @@ export interface PackageDetails { humanReadablePathSpecifier: string pathSpecifier: string path: string + workspacePath?: string name: string isNested: boolean packageNames: string[] diff --git a/src/getPackageResolution.ts b/src/getPackageResolution.ts index a046e7f9..764f3252 100644 --- a/src/getPackageResolution.ts +++ b/src/getPackageResolution.ts @@ -106,18 +106,40 @@ export function getPackageResolution({ lockFileStack.push(child[name]) } } + + // Handle Workspaces + const rootPackageName = `node_modules/${packageDetails.packageNames[0]}` + const packages = lockfile.packages + if (packages && rootPackageName in packages) { + if (packages[rootPackageName].link) { // It's a workspace + const resolved = packages[rootPackageName].resolved + if (resolved) { + packageDetails.workspacePath = packageDetails.path.replace(rootPackageName, resolved) + } + } + } + lockFileStack.reverse() const relevantStackEntry = lockFileStack.find((entry) => { if (entry.dependencies) { return entry.dependencies && packageDetails.name in entry.dependencies } else if (entry.packages) { - return entry.packages && packageDetails.path in entry.packages + return entry.packages && ( + packageDetails.path in entry.packages || + // @ts-ignore + packageDetails.workspacePath in entry.packages + ) } throw new Error("Cannot find dependencies or packages in lockfile") }) - const pkg = relevantStackEntry.dependencies + + const pkg = relevantStackEntry?.dependencies ? relevantStackEntry.dependencies[packageDetails.name] - : relevantStackEntry.packages[packageDetails.path] + : relevantStackEntry?.packages[packageDetails.path] + ? relevantStackEntry.packages[packageDetails.path] + // @ts-ignore + : relevantStackEntry.packages[packageDetails.workspacePath] + return pkg.resolved || pkg.version || pkg.from } }