diff --git a/packages/nx/src/plugins/js/lock-file/pnpm-parser.spec.ts b/packages/nx/src/plugins/js/lock-file/pnpm-parser.spec.ts index bdc43d6927940c..49bcbf0dea77c6 100644 --- a/packages/nx/src/plugins/js/lock-file/pnpm-parser.spec.ts +++ b/packages/nx/src/plugins/js/lock-file/pnpm-parser.spec.ts @@ -12,11 +12,6 @@ import { RawProjectGraphDependency, } from '../../../project-graph/project-graph-builder'; import { CreateDependenciesContext } from '../../../project-graph/plugins'; -import { - getYarnLockfileDependencies, - getYarnLockfileNodes, - stringifyYarnLockfile, -} from 'nx/src/plugins/js/lock-file/yarn-parser'; jest.mock('fs', () => { const memFs = require('memfs').fs; diff --git a/packages/nx/src/plugins/js/lock-file/pnpm-parser.ts b/packages/nx/src/plugins/js/lock-file/pnpm-parser.ts index de701e6988d956..f2bb56022a8c2a 100644 --- a/packages/nx/src/plugins/js/lock-file/pnpm-parser.ts +++ b/packages/nx/src/plugins/js/lock-file/pnpm-parser.ts @@ -98,6 +98,15 @@ function matchedDependencyName( ); } +function createHashFromSnapshot(snapshot: PackageSnapshot) { + return ( + snapshot.resolution?.['integrity'] || + (snapshot.resolution?.['tarball'] + ? hashArray([snapshot.resolution['tarball']]) + : undefined) + ); +} + function getNodes( data: Lockfile, keyMap: Map, @@ -105,16 +114,25 @@ function getNodes( ): Record { const nodes: Map> = new Map(); + const maybeAliasedPackageVersions = new Map(); // + + const packageNames = new Set<{ + key: string; + packageName: string; + hash?: string; + }>(); for (const [key, snapshot] of Object.entries(data.packages)) { const originalPackageName = extractNameFromKey(key); if (!originalPackageName) { continue; } - const packageNames = new Set(); - // snapshot already has a name if (snapshot.name) { - packageNames.add(snapshot.name); + packageNames.add({ + key, + packageName: snapshot.name, + hash: createHashFromSnapshot(snapshot), + }); } const rootDependencyName = matchedDependencyName(data.importers['.'], key, originalPackageName) || @@ -125,62 +143,87 @@ function getNodes( originalPackageName ); if (rootDependencyName) { - packageNames.add(rootDependencyName); + packageNames.add({ + key, + packageName: rootDependencyName, + hash: createHashFromSnapshot(snapshot), + }); } - if (packageNames.size === 0) { - packageNames.add(originalPackageName); + if (!snapshot.name && !rootDependencyName) { + packageNames.add({ + key, + packageName: originalPackageName, + hash: createHashFromSnapshot(snapshot), + }); } - const snapshots = Object.values(data.packages); - for (const snapshot of snapshots) { - const dependencyName = matchedDependencyName( - snapshot, - key, - originalPackageName - ); - if (dependencyName) { - packageNames.add(dependencyName); + if (snapshot.dependencies) { + for (const [depName, depVersion] of Object.entries( + snapshot.dependencies + )) { + if (depVersion.startsWith('/')) { + maybeAliasedPackageVersions.set(depVersion, depName); + } } } - - for (const packageName of packageNames) { - const rawVersion = findVersion(key, packageName); - if (!rawVersion) { - continue; + if (snapshot.optionalDependencies) { + for (const [depName, depVersion] of Object.entries( + snapshot.optionalDependencies + )) { + if (depVersion.startsWith('/')) { + maybeAliasedPackageVersions.set(depVersion, depName); + } } - const version = parseBaseVersion(rawVersion, isV6); - if (!version) { - continue; + } + if (snapshot.peerDependencies) { + for (const [depName, depVersion] of Object.entries( + snapshot.peerDependencies + )) { + if (depVersion.startsWith('/')) { + maybeAliasedPackageVersions.set(depVersion, depName); + } } + } - if (!nodes.has(packageName)) { - nodes.set(packageName, new Map()); - } + const aliasedDep = maybeAliasedPackageVersions.get(key); + if (aliasedDep) { + packageNames.add({ + key, + packageName: aliasedDep, + hash: createHashFromSnapshot(snapshot), + }); + } + } - if (!nodes.get(packageName).has(version)) { - const node: ProjectGraphExternalNode = { - type: 'npm', - name: version - ? `npm:${packageName}@${version}` - : `npm:${packageName}`, - data: { - version, - packageName, - hash: - snapshot.resolution?.['integrity'] || - hashArray( - snapshot.resolution?.['tarball'] - ? [snapshot.resolution['tarball']] - : [packageName, version] - ), - }, - }; - nodes.get(packageName).set(version, node); - keyMap.set(key, node); - } else { - keyMap.set(key, nodes.get(packageName).get(version)); - } + for (const { key, packageName, hash } of packageNames) { + const rawVersion = findVersion(key, packageName); + if (!rawVersion) { + continue; + } + const version = parseBaseVersion(rawVersion, isV6); + if (!version) { + continue; + } + + if (!nodes.has(packageName)) { + nodes.set(packageName, new Map()); + } + + if (!nodes.get(packageName).has(version)) { + const node: ProjectGraphExternalNode = { + type: 'npm', + name: version ? `npm:${packageName}@${version}` : `npm:${packageName}`, + data: { + version, + packageName, + hash: hash ?? hashArray([packageName, version]), + }, + }; + nodes.get(packageName).set(version, node); + keyMap.set(key, node); + } else { + keyMap.set(key, nodes.get(packageName).get(version)); } }