@pnpm/deps.graph-builder 1100.0.21 → 1100.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/package.json +14 -14
- package/lib/index.d.ts +0 -1
- package/lib/iteratePkgsForVirtualStore.d.ts +0 -16
- package/lib/iteratePkgsForVirtualStore.js +0 -65
- package/lib/lockfileToDepGraph.d.ts +0 -87
- package/lib/lockfileToDepGraph.js +0 -229
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
# @pnpm/deps.graph-builder
|
|
2
2
|
|
|
3
|
+
## 1100.0.23
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies:
|
|
8
|
+
- @pnpm/config.package-is-installable@1100.0.14
|
|
9
|
+
- @pnpm/core-loggers@1100.2.3
|
|
10
|
+
- @pnpm/fs.symlink-dependency@1100.0.12
|
|
11
|
+
|
|
12
|
+
## 1100.0.22
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies:
|
|
17
|
+
- @pnpm/config.package-is-installable@1100.0.13
|
|
18
|
+
- @pnpm/core-loggers@1100.2.2
|
|
19
|
+
- @pnpm/deps.graph-hasher@1100.2.10
|
|
20
|
+
- @pnpm/deps.path@1100.0.9
|
|
21
|
+
- @pnpm/fs.symlink-dependency@1100.0.11
|
|
22
|
+
- @pnpm/hooks.types@1100.2.1
|
|
23
|
+
- @pnpm/installing.modules-yaml@1100.0.10
|
|
24
|
+
- @pnpm/lockfile.fs@1100.1.11
|
|
25
|
+
- @pnpm/lockfile.utils@1100.1.3
|
|
26
|
+
- @pnpm/patching.config@1100.0.10
|
|
27
|
+
- @pnpm/store.controller-types@1100.1.8
|
|
28
|
+
- @pnpm/types@1101.4.0
|
|
29
|
+
|
|
3
30
|
## 1100.0.21
|
|
4
31
|
|
|
5
32
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/deps.graph-builder",
|
|
3
|
-
"version": "1100.0.
|
|
3
|
+
"version": "1100.0.23",
|
|
4
4
|
"description": "A package for building a dependency graph from a lockfile",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -27,20 +27,20 @@
|
|
|
27
27
|
"!*.map"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@pnpm/config.package-is-installable": "1100.0.
|
|
30
|
+
"@pnpm/config.package-is-installable": "1100.0.14",
|
|
31
31
|
"@pnpm/constants": "1100.0.0",
|
|
32
|
-
"@pnpm/core-loggers": "1100.2.
|
|
33
|
-
"@pnpm/deps.graph-hasher": "1100.2.
|
|
34
|
-
"@pnpm/deps.path": "1100.0.
|
|
35
|
-
"@pnpm/fs.symlink-dependency": "1100.0.
|
|
36
|
-
"@pnpm/hooks.types": "1100.2.
|
|
37
|
-
"@pnpm/installing.modules-yaml": "1100.0.
|
|
38
|
-
"@pnpm/lockfile.fs": "1100.1.
|
|
39
|
-
"@pnpm/lockfile.utils": "1100.1.
|
|
40
|
-
"@pnpm/patching.config": "1100.0.
|
|
32
|
+
"@pnpm/core-loggers": "1100.2.3",
|
|
33
|
+
"@pnpm/deps.graph-hasher": "1100.2.10",
|
|
34
|
+
"@pnpm/deps.path": "1100.0.9",
|
|
35
|
+
"@pnpm/fs.symlink-dependency": "1100.0.12",
|
|
36
|
+
"@pnpm/hooks.types": "1100.2.1",
|
|
37
|
+
"@pnpm/installing.modules-yaml": "1100.0.10",
|
|
38
|
+
"@pnpm/lockfile.fs": "1100.1.11",
|
|
39
|
+
"@pnpm/lockfile.utils": "1100.1.3",
|
|
40
|
+
"@pnpm/patching.config": "1100.0.10",
|
|
41
41
|
"@pnpm/patching.types": "1100.0.0",
|
|
42
|
-
"@pnpm/store.controller-types": "1100.1.
|
|
43
|
-
"@pnpm/types": "1101.
|
|
42
|
+
"@pnpm/store.controller-types": "1100.1.8",
|
|
43
|
+
"@pnpm/types": "1101.4.0",
|
|
44
44
|
"path-exists": "^5.0.0",
|
|
45
45
|
"ramda": "npm:@pnpm/ramda@0.28.1"
|
|
46
46
|
},
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"@jest/globals": "30.4.1",
|
|
52
|
-
"@pnpm/deps.graph-builder": "1100.0.
|
|
52
|
+
"@pnpm/deps.graph-builder": "1100.0.23",
|
|
53
53
|
"@pnpm/logger": "1100.0.0",
|
|
54
54
|
"@types/ramda": "0.31.1"
|
|
55
55
|
},
|
package/lib/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lockfileToDepGraph.js';
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { type PkgMetaAndSnapshot } from '@pnpm/deps.graph-hasher';
|
|
2
|
-
import type { LockfileObject } from '@pnpm/lockfile.fs';
|
|
3
|
-
import type { AllowBuild, SupportedArchitectures } from '@pnpm/types';
|
|
4
|
-
interface PkgSnapshotWithLocation {
|
|
5
|
-
pkgMeta: PkgMetaAndSnapshot;
|
|
6
|
-
dirInVirtualStore: string;
|
|
7
|
-
}
|
|
8
|
-
export declare function iteratePkgsForVirtualStore(lockfile: LockfileObject, opts: {
|
|
9
|
-
allowBuild?: AllowBuild;
|
|
10
|
-
enableGlobalVirtualStore?: boolean;
|
|
11
|
-
virtualStoreDirMaxLength: number;
|
|
12
|
-
virtualStoreDir: string;
|
|
13
|
-
globalVirtualStoreDir: string;
|
|
14
|
-
supportedArchitectures?: SupportedArchitectures;
|
|
15
|
-
}): IterableIterator<PkgSnapshotWithLocation>;
|
|
16
|
-
export {};
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import path from 'node:path';
|
|
2
|
-
import { calcGraphNodeHash, findRuntimeNodeVersion, iterateHashedGraphNodes, iteratePkgMeta, lockfileToDepGraph, } from '@pnpm/deps.graph-hasher';
|
|
3
|
-
import * as dp from '@pnpm/deps.path';
|
|
4
|
-
import { nameVerFromPkgSnapshot, } from '@pnpm/lockfile.utils';
|
|
5
|
-
export function* iteratePkgsForVirtualStore(lockfile, opts) {
|
|
6
|
-
// Resolve the project's pinned runtime Node version once per
|
|
7
|
-
// invocation — the result drives every snapshot's GVS hash (or
|
|
8
|
-
// the side-effects-cache key prefix in the non-GVS runtime
|
|
9
|
-
// branch). `undefined` when no `engines.runtime` / `devEngines.runtime`
|
|
10
|
-
// pin reached the lockfile, in which case the hasher falls through
|
|
11
|
-
// to the host-detected Node.
|
|
12
|
-
const nodeVersion = findRuntimeNodeVersion(Object.keys(lockfile.packages ?? {}));
|
|
13
|
-
if (opts.enableGlobalVirtualStore) {
|
|
14
|
-
for (const { hash, pkgMeta } of hashDependencyPaths(lockfile, {
|
|
15
|
-
allowBuild: opts.allowBuild,
|
|
16
|
-
supportedArchitectures: opts.supportedArchitectures,
|
|
17
|
-
nodeVersion,
|
|
18
|
-
})) {
|
|
19
|
-
yield {
|
|
20
|
-
dirInVirtualStore: path.join(opts.globalVirtualStoreDir, hash),
|
|
21
|
-
pkgMeta,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
else if (lockfile.packages) {
|
|
26
|
-
let graphNodeHashOpts;
|
|
27
|
-
for (const depPath in lockfile.packages) {
|
|
28
|
-
if (!Object.hasOwn(lockfile.packages, depPath)) {
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
const pkgSnapshot = lockfile.packages[depPath];
|
|
32
|
-
const { name, version } = nameVerFromPkgSnapshot(depPath, pkgSnapshot);
|
|
33
|
-
const pkgMeta = {
|
|
34
|
-
depPath: depPath,
|
|
35
|
-
pkgIdWithPatchHash: dp.getPkgIdWithPatchHash(depPath),
|
|
36
|
-
name,
|
|
37
|
-
version,
|
|
38
|
-
pkgSnapshot,
|
|
39
|
-
};
|
|
40
|
-
let dirInVirtualStore;
|
|
41
|
-
if (dp.isRuntimeDepPath(depPath)) {
|
|
42
|
-
graphNodeHashOpts ??= {
|
|
43
|
-
cache: {},
|
|
44
|
-
graph: lockfileToDepGraph(lockfile, opts.supportedArchitectures),
|
|
45
|
-
supportedArchitectures: opts.supportedArchitectures,
|
|
46
|
-
nodeVersion,
|
|
47
|
-
};
|
|
48
|
-
const hash = calcGraphNodeHash(graphNodeHashOpts, pkgMeta);
|
|
49
|
-
dirInVirtualStore = path.join(opts.globalVirtualStoreDir, hash);
|
|
50
|
-
}
|
|
51
|
-
else {
|
|
52
|
-
dirInVirtualStore = path.join(opts.virtualStoreDir, dp.depPathToFilename(depPath, opts.virtualStoreDirMaxLength));
|
|
53
|
-
}
|
|
54
|
-
yield {
|
|
55
|
-
dirInVirtualStore,
|
|
56
|
-
pkgMeta,
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
function hashDependencyPaths(lockfile, { allowBuild, supportedArchitectures, nodeVersion, }) {
|
|
62
|
-
const graph = lockfileToDepGraph(lockfile, supportedArchitectures);
|
|
63
|
-
return iterateHashedGraphNodes(graph, iteratePkgMeta(lockfile, graph), allowBuild, supportedArchitectures, nodeVersion);
|
|
64
|
-
}
|
|
65
|
-
//# sourceMappingURL=iteratePkgsForVirtualStore.js.map
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import type { IncludedDependencies } from '@pnpm/installing.modules-yaml';
|
|
2
|
-
import type { LockfileObject, LockfileResolution } from '@pnpm/lockfile.fs';
|
|
3
|
-
import { type PatchGroupRecord } from '@pnpm/patching.config';
|
|
4
|
-
import type { PatchInfo } from '@pnpm/patching.types';
|
|
5
|
-
import type { PkgRequestFetchResult, StoreController } from '@pnpm/store.controller-types';
|
|
6
|
-
import type { AllowBuild, DepPath, PkgIdWithPatchHash, ProjectId, Registries, SupportedArchitectures } from '@pnpm/types';
|
|
7
|
-
export interface DependenciesGraphNode {
|
|
8
|
-
alias?: string;
|
|
9
|
-
hasBundledDependencies: boolean;
|
|
10
|
-
modules: string;
|
|
11
|
-
name: string;
|
|
12
|
-
version: string;
|
|
13
|
-
fetching?: () => Promise<PkgRequestFetchResult>;
|
|
14
|
-
forceImportPackage?: boolean;
|
|
15
|
-
dir: string;
|
|
16
|
-
children: Record<string, string>;
|
|
17
|
-
optionalDependencies: Set<string>;
|
|
18
|
-
optional: boolean;
|
|
19
|
-
depPath: DepPath;
|
|
20
|
-
pkgIdWithPatchHash: PkgIdWithPatchHash;
|
|
21
|
-
isBuilt?: boolean;
|
|
22
|
-
requiresBuild?: boolean;
|
|
23
|
-
hasBin: boolean;
|
|
24
|
-
filesIndexFile?: string;
|
|
25
|
-
patch?: PatchInfo;
|
|
26
|
-
resolution: LockfileResolution;
|
|
27
|
-
}
|
|
28
|
-
export interface DependenciesGraph {
|
|
29
|
-
[depPath: string]: DependenciesGraphNode;
|
|
30
|
-
}
|
|
31
|
-
export interface LockfileToDepGraphOptions {
|
|
32
|
-
allowBuild?: AllowBuild;
|
|
33
|
-
autoInstallPeers: boolean;
|
|
34
|
-
enableGlobalVirtualStore?: boolean;
|
|
35
|
-
engineStrict: boolean;
|
|
36
|
-
force: boolean;
|
|
37
|
-
importerIds: ProjectId[];
|
|
38
|
-
include: IncludedDependencies;
|
|
39
|
-
includeUnchangedDeps?: boolean;
|
|
40
|
-
ignoreScripts: boolean;
|
|
41
|
-
/**
|
|
42
|
-
* When true, skip fetching local dependencies (file: protocol pointing to directories).
|
|
43
|
-
* This is useful for `pnpm fetch` which only downloads packages from the registry
|
|
44
|
-
* and doesn't need local packages that won't be available (e.g., in Docker builds).
|
|
45
|
-
*/
|
|
46
|
-
ignoreLocalPackages?: boolean;
|
|
47
|
-
lockfileDir: string;
|
|
48
|
-
nodeVersion: string;
|
|
49
|
-
pnpmVersion: string;
|
|
50
|
-
patchedDependencies?: PatchGroupRecord;
|
|
51
|
-
registries: Registries;
|
|
52
|
-
sideEffectsCacheRead: boolean;
|
|
53
|
-
skipped: Set<DepPath>;
|
|
54
|
-
storeController: StoreController;
|
|
55
|
-
storeDir: string;
|
|
56
|
-
globalVirtualStoreDir: string;
|
|
57
|
-
virtualStoreDir: string;
|
|
58
|
-
supportedArchitectures?: SupportedArchitectures;
|
|
59
|
-
virtualStoreDirMaxLength: number;
|
|
60
|
-
}
|
|
61
|
-
export interface DirectDependenciesByImporterId {
|
|
62
|
-
[importerId: string]: {
|
|
63
|
-
[alias: string]: string;
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
export interface DepHierarchy {
|
|
67
|
-
[depPath: string]: Record<string, DepHierarchy>;
|
|
68
|
-
}
|
|
69
|
-
export interface LockfileToDepGraphResult {
|
|
70
|
-
directDependenciesByImporterId: DirectDependenciesByImporterId;
|
|
71
|
-
graph: DependenciesGraph;
|
|
72
|
-
hierarchy?: DepHierarchy;
|
|
73
|
-
hoistedLocations?: Record<string, string[]>;
|
|
74
|
-
symlinkedDirectDependenciesByImporterId?: DirectDependenciesByImporterId;
|
|
75
|
-
prevGraph?: DependenciesGraph;
|
|
76
|
-
injectionTargetsByDepPath: Map<string, string[]>;
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Generate a dependency graph from lockfiles.
|
|
80
|
-
*
|
|
81
|
-
* If a current lockfile is provided, this function only includes new or changed
|
|
82
|
-
* packages in the graph. In other words, the graph returned will be a set
|
|
83
|
-
* subtraction of the packages in the wanted lockfile minus the current
|
|
84
|
-
* lockfile. This behavior can be configured with the `includeUnchangedDeps`
|
|
85
|
-
* option.
|
|
86
|
-
*/
|
|
87
|
-
export declare function lockfileToDepGraph(lockfile: LockfileObject, currentLockfile: LockfileObject | null, opts: LockfileToDepGraphOptions): Promise<LockfileToDepGraphResult>;
|
|
@@ -1,229 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { packageIsInstallable } from '@pnpm/config.package-is-installable';
|
|
4
|
-
import { WANTED_LOCKFILE } from '@pnpm/constants';
|
|
5
|
-
import { progressLogger, } from '@pnpm/core-loggers';
|
|
6
|
-
import * as dp from '@pnpm/deps.path';
|
|
7
|
-
import { safeJoinModulesDir } from '@pnpm/fs.symlink-dependency';
|
|
8
|
-
import { packageIdFromSnapshot, pkgSnapshotToResolution, } from '@pnpm/lockfile.utils';
|
|
9
|
-
import { logger } from '@pnpm/logger';
|
|
10
|
-
import { getPatchInfo } from '@pnpm/patching.config';
|
|
11
|
-
import { pathExists } from 'path-exists';
|
|
12
|
-
import { equals, isEmpty } from 'ramda';
|
|
13
|
-
import { iteratePkgsForVirtualStore } from './iteratePkgsForVirtualStore.js';
|
|
14
|
-
const brokenModulesLogger = logger('_broken_node_modules');
|
|
15
|
-
/**
|
|
16
|
-
* Generate a dependency graph from lockfiles.
|
|
17
|
-
*
|
|
18
|
-
* If a current lockfile is provided, this function only includes new or changed
|
|
19
|
-
* packages in the graph. In other words, the graph returned will be a set
|
|
20
|
-
* subtraction of the packages in the wanted lockfile minus the current
|
|
21
|
-
* lockfile. This behavior can be configured with the `includeUnchangedDeps`
|
|
22
|
-
* option.
|
|
23
|
-
*/
|
|
24
|
-
export async function lockfileToDepGraph(lockfile, currentLockfile, opts) {
|
|
25
|
-
const { graph, locationByDepPath, injectionTargetsByDepPath, } = await buildGraphFromPackages(lockfile, currentLockfile, opts);
|
|
26
|
-
const _getChildrenPaths = getChildrenPaths.bind(null, {
|
|
27
|
-
force: opts.force,
|
|
28
|
-
graph,
|
|
29
|
-
lockfileDir: opts.lockfileDir,
|
|
30
|
-
registries: opts.registries,
|
|
31
|
-
sideEffectsCacheRead: opts.sideEffectsCacheRead,
|
|
32
|
-
skipped: opts.skipped,
|
|
33
|
-
storeController: opts.storeController,
|
|
34
|
-
storeDir: opts.storeDir,
|
|
35
|
-
virtualStoreDir: opts.virtualStoreDir,
|
|
36
|
-
virtualStoreDirMaxLength: opts.virtualStoreDirMaxLength,
|
|
37
|
-
locationByDepPath,
|
|
38
|
-
});
|
|
39
|
-
for (const node of Object.values(graph)) {
|
|
40
|
-
const pkgSnapshot = lockfile.packages[node.depPath];
|
|
41
|
-
const allDeps = {
|
|
42
|
-
...pkgSnapshot.dependencies,
|
|
43
|
-
...(opts.include.optionalDependencies ? pkgSnapshot.optionalDependencies : {}),
|
|
44
|
-
};
|
|
45
|
-
const peerDeps = pkgSnapshot.peerDependencies ? new Set(Object.keys(pkgSnapshot.peerDependencies)) : null;
|
|
46
|
-
node.children = _getChildrenPaths(allDeps, peerDeps, '.');
|
|
47
|
-
}
|
|
48
|
-
const directDependenciesByImporterId = {};
|
|
49
|
-
for (const importerId of opts.importerIds) {
|
|
50
|
-
const projectSnapshot = lockfile.importers[importerId];
|
|
51
|
-
const rootDeps = {
|
|
52
|
-
...(opts.include.devDependencies ? projectSnapshot.devDependencies : {}),
|
|
53
|
-
...(opts.include.dependencies ? projectSnapshot.dependencies : {}),
|
|
54
|
-
...(opts.include.optionalDependencies ? projectSnapshot.optionalDependencies : {}),
|
|
55
|
-
};
|
|
56
|
-
directDependenciesByImporterId[importerId] = _getChildrenPaths(rootDeps, null, importerId);
|
|
57
|
-
}
|
|
58
|
-
return { graph, directDependenciesByImporterId, injectionTargetsByDepPath };
|
|
59
|
-
}
|
|
60
|
-
async function buildGraphFromPackages(lockfile, currentLockfile, opts) {
|
|
61
|
-
const currentPackages = currentLockfile?.packages ?? {};
|
|
62
|
-
const graph = {};
|
|
63
|
-
const locationByDepPath = {};
|
|
64
|
-
// Only populated for directory deps (injected workspace packages)
|
|
65
|
-
const injectionTargetsByDepPath = new Map();
|
|
66
|
-
const _getPatchInfo = getPatchInfo.bind(null, opts.patchedDependencies);
|
|
67
|
-
const promises = [];
|
|
68
|
-
const pkgSnapshotsWithLocations = iteratePkgsForVirtualStore(lockfile, opts);
|
|
69
|
-
for (const { dirInVirtualStore, pkgMeta } of pkgSnapshotsWithLocations) {
|
|
70
|
-
promises.push((async () => {
|
|
71
|
-
const { pkgIdWithPatchHash, name: pkgName, version: pkgVersion, depPath, pkgSnapshot } = pkgMeta;
|
|
72
|
-
if (opts.skipped.has(depPath))
|
|
73
|
-
return;
|
|
74
|
-
const pkg = {
|
|
75
|
-
name: pkgName,
|
|
76
|
-
version: pkgVersion,
|
|
77
|
-
engines: pkgSnapshot.engines,
|
|
78
|
-
cpu: pkgSnapshot.cpu,
|
|
79
|
-
os: pkgSnapshot.os,
|
|
80
|
-
libc: pkgSnapshot.libc,
|
|
81
|
-
};
|
|
82
|
-
const packageId = packageIdFromSnapshot(depPath, pkgSnapshot);
|
|
83
|
-
if (!opts.force && packageIsInstallable(packageId, pkg, {
|
|
84
|
-
engineStrict: opts.engineStrict,
|
|
85
|
-
lockfileDir: opts.lockfileDir,
|
|
86
|
-
nodeVersion: opts.nodeVersion,
|
|
87
|
-
optional: pkgSnapshot.optional === true,
|
|
88
|
-
supportedArchitectures: opts.supportedArchitectures,
|
|
89
|
-
}) === false) {
|
|
90
|
-
opts.skipped.add(depPath);
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
const isDirectoryDep = 'directory' in pkgSnapshot.resolution && pkgSnapshot.resolution.directory != null;
|
|
94
|
-
if (isDirectoryDep && opts.ignoreLocalPackages) {
|
|
95
|
-
logger.info({
|
|
96
|
-
message: `Skipping local dependency ${pkgName}@${pkgVersion} (file: protocol)`,
|
|
97
|
-
prefix: opts.lockfileDir,
|
|
98
|
-
});
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
const depIsPresent = !isDirectoryDep &&
|
|
102
|
-
currentPackages[depPath] &&
|
|
103
|
-
equals(currentPackages[depPath].dependencies, pkgSnapshot.dependencies);
|
|
104
|
-
const depIntegrityIsUnchanged = isIntegrityEqual(pkgSnapshot.resolution, currentPackages[depPath]?.resolution);
|
|
105
|
-
const modules = path.join(dirInVirtualStore, 'node_modules');
|
|
106
|
-
// `pkgName` is reconstructed from the (attacker-controllable) lockfile
|
|
107
|
-
// depPath key via `dp.parse`, which does no validation. Contain it here so
|
|
108
|
-
// a traversal name (e.g. `../../../tmp/x`) can't make the package import
|
|
109
|
-
// escape the virtual store. Mirrors the guard on the hoisted linker.
|
|
110
|
-
const dir = safeJoinModulesDir(modules, pkgName);
|
|
111
|
-
locationByDepPath[depPath] = dir;
|
|
112
|
-
// Track directory deps for injected workspace packages
|
|
113
|
-
if (isDirectoryDep) {
|
|
114
|
-
injectionTargetsByDepPath.set(depPath, [dir]);
|
|
115
|
-
}
|
|
116
|
-
// In GVS mode, packages that are allowed to build may have a .pnpm-needs-build
|
|
117
|
-
// marker indicating a previous build failed or was interrupted. When the
|
|
118
|
-
// marker is present, skip the fast path to force a re-fetch/re-import/re-build.
|
|
119
|
-
const mightNeedBuild = opts.enableGlobalVirtualStore &&
|
|
120
|
-
opts.allowBuild?.(depPath) === true;
|
|
121
|
-
let dirExists;
|
|
122
|
-
if (depIsPresent &&
|
|
123
|
-
depIntegrityIsUnchanged &&
|
|
124
|
-
isEmpty(currentPackages[depPath].optionalDependencies ?? {}) &&
|
|
125
|
-
isEmpty(pkgSnapshot.optionalDependencies ?? {}) &&
|
|
126
|
-
!opts.includeUnchangedDeps) {
|
|
127
|
-
dirExists = await pathExists(dir);
|
|
128
|
-
if (dirExists) {
|
|
129
|
-
if (!(mightNeedBuild && fs.existsSync(path.join(dir, '.pnpm-needs-build'))))
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
else {
|
|
133
|
-
brokenModulesLogger.debug({ missing: dir });
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
let fetchResponse;
|
|
137
|
-
if (depIsPresent && depIntegrityIsUnchanged && equals(currentPackages[depPath].optionalDependencies, pkgSnapshot.optionalDependencies)) {
|
|
138
|
-
if (dirExists ?? await pathExists(dir)) {
|
|
139
|
-
if (!(mightNeedBuild && fs.existsSync(path.join(dir, '.pnpm-needs-build')))) {
|
|
140
|
-
fetchResponse = {};
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
else {
|
|
144
|
-
brokenModulesLogger.debug({ missing: dir });
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
if (!fetchResponse && opts.enableGlobalVirtualStore && !isDirectoryDep
|
|
148
|
-
&& !opts.force) {
|
|
149
|
-
if (dirExists ?? await pathExists(dir)) {
|
|
150
|
-
if (!(mightNeedBuild && fs.existsSync(path.join(dir, '.pnpm-needs-build')))) {
|
|
151
|
-
fetchResponse = {};
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
if (!fetchResponse) {
|
|
156
|
-
const resolution = pkgSnapshotToResolution(depPath, pkgSnapshot, opts.registries);
|
|
157
|
-
progressLogger.debug({ packageId, requester: opts.lockfileDir, status: 'resolved' });
|
|
158
|
-
try {
|
|
159
|
-
fetchResponse = await opts.storeController.fetchPackage({
|
|
160
|
-
allowBuild: opts.allowBuild,
|
|
161
|
-
force: false,
|
|
162
|
-
lockfileDir: opts.lockfileDir,
|
|
163
|
-
ignoreScripts: opts.ignoreScripts,
|
|
164
|
-
pkg: { name: pkgName, version: pkgVersion, id: packageId, resolution },
|
|
165
|
-
supportedArchitectures: opts.supportedArchitectures,
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
catch (err) {
|
|
169
|
-
if (pkgSnapshot.optional)
|
|
170
|
-
return;
|
|
171
|
-
throw err;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
graph[dir] = {
|
|
175
|
-
children: {},
|
|
176
|
-
pkgIdWithPatchHash,
|
|
177
|
-
resolution: pkgSnapshot.resolution,
|
|
178
|
-
depPath,
|
|
179
|
-
dir,
|
|
180
|
-
fetching: fetchResponse.fetching,
|
|
181
|
-
filesIndexFile: fetchResponse.filesIndexFile,
|
|
182
|
-
forceImportPackage: !depIntegrityIsUnchanged,
|
|
183
|
-
hasBin: pkgSnapshot.hasBin === true,
|
|
184
|
-
hasBundledDependencies: pkgSnapshot.bundledDependencies != null,
|
|
185
|
-
modules,
|
|
186
|
-
name: pkgName,
|
|
187
|
-
version: pkgVersion,
|
|
188
|
-
optional: !!pkgSnapshot.optional,
|
|
189
|
-
optionalDependencies: new Set(Object.keys(pkgSnapshot.optionalDependencies ?? {})),
|
|
190
|
-
patch: _getPatchInfo(pkgName, pkgVersion),
|
|
191
|
-
};
|
|
192
|
-
})());
|
|
193
|
-
}
|
|
194
|
-
await Promise.all(promises);
|
|
195
|
-
return { graph, locationByDepPath, injectionTargetsByDepPath };
|
|
196
|
-
}
|
|
197
|
-
function getChildrenPaths(ctx, allDeps, peerDeps, importerId) {
|
|
198
|
-
const children = {};
|
|
199
|
-
for (const [alias, ref] of Object.entries(allDeps)) {
|
|
200
|
-
const childDepPath = dp.refToRelative(ref, alias);
|
|
201
|
-
if (childDepPath === null) {
|
|
202
|
-
children[alias] = path.resolve(ctx.lockfileDir, importerId, ref.slice(5));
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
const childRelDepPath = dp.refToRelative(ref, alias);
|
|
206
|
-
if (ctx.locationByDepPath[childRelDepPath]) {
|
|
207
|
-
children[alias] = ctx.locationByDepPath[childRelDepPath];
|
|
208
|
-
}
|
|
209
|
-
else if (ctx.graph[childRelDepPath]) {
|
|
210
|
-
children[alias] = ctx.graph[childRelDepPath].dir;
|
|
211
|
-
}
|
|
212
|
-
else if (ref.startsWith('file:')) {
|
|
213
|
-
children[alias] = path.resolve(ctx.lockfileDir, ref.slice(5));
|
|
214
|
-
}
|
|
215
|
-
else if (!ctx.skipped.has(childRelDepPath) && ((peerDeps == null) || !peerDeps.has(alias))) {
|
|
216
|
-
throw new Error(`${childRelDepPath} not found in ${WANTED_LOCKFILE}`);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
return children;
|
|
220
|
-
}
|
|
221
|
-
function isIntegrityEqual(resolutionA, resolutionB) {
|
|
222
|
-
// The LockfileResolution type is a union, but it doesn't have a "tag"
|
|
223
|
-
// field to perform a discriminant match on. Using a type assertion is
|
|
224
|
-
// required to get the integrity field.
|
|
225
|
-
const integrityA = resolutionA?.integrity;
|
|
226
|
-
const integrityB = resolutionB?.integrity;
|
|
227
|
-
return integrityA === integrityB;
|
|
228
|
-
}
|
|
229
|
-
//# sourceMappingURL=lockfileToDepGraph.js.map
|