@pnpm/installing.linking.real-hoist 1100.1.20 → 1100.1.22
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 +21 -0
- package/lib/index.js +138 -107
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @pnpm/real-hoist
|
|
2
2
|
|
|
3
|
+
## 1100.1.22
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies:
|
|
8
|
+
- @pnpm/deps.path@1101.0.6
|
|
9
|
+
- @pnpm/error@1100.2.2
|
|
10
|
+
- @pnpm/lockfile.utils@1102.1.6
|
|
11
|
+
|
|
12
|
+
## 1100.1.21
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- `pnpm install` no longer fails when a package from the registry declares a `file:` dependency on a directory inside itself, such as `"@types/css-tree": "file:./typings/css-tree"`. pnpm links that dependency to the directory inside the package, as npm and Yarn do. The lockfile records it as `link:<root>/typings/css-tree` [#9141](https://github.com/pnpm/pnpm/issues/9141).
|
|
17
|
+
|
|
18
|
+
- Updated dependencies:
|
|
19
|
+
- @pnpm/deps.path@1101.0.5
|
|
20
|
+
- @pnpm/error@1100.2.1
|
|
21
|
+
- @pnpm/lockfile.types@1100.1.4
|
|
22
|
+
- @pnpm/lockfile.utils@1102.1.5
|
|
23
|
+
|
|
3
24
|
## 1100.1.20
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/lib/index.js
CHANGED
|
@@ -53,137 +53,168 @@ export function getHoistingLimits(lockfile, mode) {
|
|
|
53
53
|
const hoistingLimits = new Map();
|
|
54
54
|
const rootHoistingLimit = new Set();
|
|
55
55
|
for (const [importerId, importer] of Object.entries(lockfile.importers)) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
// per-importer border.
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
const reference = isWorkspaceRoot ? '' : `workspace:${importerId}`;
|
|
68
|
-
const hoistingLimit = isWorkspaceRoot ? rootHoistingLimit : new Set();
|
|
69
|
-
hoistingLimits.set(`${encodedId}@${reference}`, hoistingLimit);
|
|
70
|
-
for (const deps of [importer.dependencies, importer.devDependencies, importer.optionalDependencies]) {
|
|
71
|
-
if (!deps)
|
|
72
|
-
continue;
|
|
73
|
-
for (const dep of Object.keys(deps)) {
|
|
74
|
-
hoistingLimit.add(dep);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
56
|
+
addImporterHoistingLimits({
|
|
57
|
+
hoistingLimits,
|
|
58
|
+
importer,
|
|
59
|
+
importerId,
|
|
60
|
+
mode,
|
|
61
|
+
rootHoistingLimit,
|
|
62
|
+
});
|
|
77
63
|
}
|
|
78
64
|
if (!hoistingLimits.has('.@')) {
|
|
79
65
|
hoistingLimits.set('.@', rootHoistingLimit);
|
|
80
66
|
}
|
|
81
67
|
return hoistingLimits;
|
|
82
68
|
}
|
|
69
|
+
function addImporterHoistingLimits(opts) {
|
|
70
|
+
const { hoistingLimits, importer, importerId, mode, rootHoistingLimit } = opts;
|
|
71
|
+
const isWorkspaceRoot = importerId === '.';
|
|
72
|
+
const encodedId = encodeURIComponent(importerId);
|
|
73
|
+
if (!isWorkspaceRoot) {
|
|
74
|
+
rootHoistingLimit.add(encodedId);
|
|
75
|
+
if (mode !== 'dependencies') {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const reference = isWorkspaceRoot ? '' : `workspace:${importerId}`;
|
|
80
|
+
const hoistingLimit = isWorkspaceRoot ? rootHoistingLimit : new Set();
|
|
81
|
+
hoistingLimits.set(`${encodedId}@${reference}`, hoistingLimit);
|
|
82
|
+
collectDirectDeps(importer, hoistingLimit);
|
|
83
|
+
}
|
|
84
|
+
function collectDirectDeps(importer, targetSet) {
|
|
85
|
+
const depGroups = [importer.dependencies, importer.devDependencies, importer.optionalDependencies];
|
|
86
|
+
for (const deps of depGroups) {
|
|
87
|
+
if (!deps)
|
|
88
|
+
continue;
|
|
89
|
+
for (const dep of Object.keys(deps)) {
|
|
90
|
+
targetSet.add(dep);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
83
94
|
export function hoist(lockfile, opts) {
|
|
84
|
-
const nodes = new Map();
|
|
85
95
|
const ctx = {
|
|
86
96
|
autoInstallPeers: opts?.autoInstallPeers,
|
|
87
|
-
nodes,
|
|
88
|
-
lockfile,
|
|
89
97
|
depPathByPkgId: new Map(),
|
|
98
|
+
lockfile,
|
|
99
|
+
nodes: new Map(),
|
|
90
100
|
};
|
|
91
|
-
const
|
|
92
|
-
const node = {
|
|
93
|
-
name: '.',
|
|
94
|
-
identName: '.',
|
|
95
|
-
reference: '',
|
|
96
|
-
peerNames: new Set([]),
|
|
97
|
-
dependencyKind: HoisterDependencyKind.WORKSPACE,
|
|
98
|
-
dependencies: _toTree({
|
|
99
|
-
...lockfile.importers['.']?.dependencies,
|
|
100
|
-
...lockfile.importers['.']?.devDependencies,
|
|
101
|
-
...lockfile.importers['.']?.optionalDependencies,
|
|
102
|
-
...(Array.from(opts?.externalDependencies ?? [])).reduce((acc, dep) => {
|
|
103
|
-
// It doesn't matter what version spec is used here.
|
|
104
|
-
// This dependency will be removed from the tree anyway.
|
|
105
|
-
// It is only needed to prevent the hoister from hoisting deps with this name to the root of node_modules.
|
|
106
|
-
acc[dep] = 'link:';
|
|
107
|
-
return acc;
|
|
108
|
-
}, {}),
|
|
109
|
-
}),
|
|
110
|
-
};
|
|
101
|
+
const rootNode = buildRootHoisterTree(lockfile, ctx, opts?.externalDependencies);
|
|
111
102
|
for (const [importerId, importer] of Object.entries(lockfile.importers)) {
|
|
112
103
|
if (importerId === '.')
|
|
113
104
|
continue;
|
|
114
|
-
|
|
115
|
-
name: encodeURIComponent(importerId),
|
|
116
|
-
identName: encodeURIComponent(importerId),
|
|
117
|
-
reference: `workspace:${importerId}`,
|
|
118
|
-
peerNames: new Set([]),
|
|
119
|
-
dependencyKind: HoisterDependencyKind.WORKSPACE,
|
|
120
|
-
dependencies: _toTree({
|
|
121
|
-
...importer.dependencies,
|
|
122
|
-
...importer.devDependencies,
|
|
123
|
-
...importer.optionalDependencies,
|
|
124
|
-
}),
|
|
125
|
-
};
|
|
126
|
-
node.dependencies.add(importerNode);
|
|
105
|
+
rootNode.dependencies.add(buildImporterHoisterTree(importerId, importer, ctx));
|
|
127
106
|
}
|
|
128
107
|
const hoistingLimits = getHoistingLimits(lockfile, opts?.hoistingLimits);
|
|
129
|
-
const hoisterResult = _hoist(
|
|
108
|
+
const hoisterResult = _hoist(rootNode, { ...opts, hoistingLimits });
|
|
130
109
|
if (opts?.externalDependencies) {
|
|
131
|
-
|
|
132
|
-
if (opts.externalDependencies.has(hoistedDep.name)) {
|
|
133
|
-
hoisterResult.dependencies.delete(hoistedDep);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
110
|
+
filterExternalDependencies(hoisterResult, opts.externalDependencies);
|
|
136
111
|
}
|
|
137
112
|
return hoisterResult;
|
|
138
113
|
}
|
|
139
|
-
function
|
|
114
|
+
function buildRootHoisterTree(lockfile, ctx, externalDependencies) {
|
|
115
|
+
const rootImporter = lockfile.importers['.'];
|
|
116
|
+
const externalDepsMap = {};
|
|
117
|
+
for (const dep of externalDependencies ?? []) {
|
|
118
|
+
externalDepsMap[dep] = 'link:';
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
dependencies: toTree(ctx, {
|
|
122
|
+
...rootImporter?.dependencies,
|
|
123
|
+
...rootImporter?.devDependencies,
|
|
124
|
+
...rootImporter?.optionalDependencies,
|
|
125
|
+
...externalDepsMap,
|
|
126
|
+
}),
|
|
127
|
+
dependencyKind: HoisterDependencyKind.WORKSPACE,
|
|
128
|
+
identName: '.',
|
|
129
|
+
name: '.',
|
|
130
|
+
peerNames: new Set([]),
|
|
131
|
+
reference: '',
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
function buildImporterHoisterTree(importerId, importer, ctx) {
|
|
135
|
+
return {
|
|
136
|
+
dependencies: toTree(ctx, {
|
|
137
|
+
...importer.dependencies,
|
|
138
|
+
...importer.devDependencies,
|
|
139
|
+
...importer.optionalDependencies,
|
|
140
|
+
}),
|
|
141
|
+
dependencyKind: HoisterDependencyKind.WORKSPACE,
|
|
142
|
+
identName: encodeURIComponent(importerId),
|
|
143
|
+
name: encodeURIComponent(importerId),
|
|
144
|
+
peerNames: new Set([]),
|
|
145
|
+
reference: `workspace:${importerId}`,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function filterExternalDependencies(result, externalDependencies) {
|
|
149
|
+
for (const hoistedDep of result.dependencies.values()) {
|
|
150
|
+
if (externalDependencies.has(hoistedDep.name)) {
|
|
151
|
+
result.dependencies.delete(hoistedDep);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
function toTree(ctx, deps) {
|
|
140
156
|
return new Set(Object.entries(deps).map(([alias, ref]) => {
|
|
141
157
|
const depPath = dp.refToRelative(ref, alias);
|
|
142
158
|
if (!depPath) {
|
|
143
|
-
|
|
144
|
-
let node = nodes.get(key);
|
|
145
|
-
if (!node) {
|
|
146
|
-
node = {
|
|
147
|
-
name: alias,
|
|
148
|
-
identName: alias,
|
|
149
|
-
reference: ref,
|
|
150
|
-
dependencyKind: HoisterDependencyKind.REGULAR,
|
|
151
|
-
dependencies: new Set(),
|
|
152
|
-
peerNames: new Set(),
|
|
153
|
-
};
|
|
154
|
-
nodes.set(key, node);
|
|
155
|
-
}
|
|
156
|
-
return node;
|
|
157
|
-
}
|
|
158
|
-
const key = `${alias}:${depPath}`;
|
|
159
|
-
let node = nodes.get(key);
|
|
160
|
-
if (!node) {
|
|
161
|
-
const pkgSnapshot = lockfile.packages[depPath];
|
|
162
|
-
if (!pkgSnapshot) {
|
|
163
|
-
throw new LockfileMissingDependencyError(depPath);
|
|
164
|
-
}
|
|
165
|
-
const { name: pkgName } = nameVerFromPkgSnapshot(depPath, pkgSnapshot);
|
|
166
|
-
const id = getHoisterPkgId(depPath, pkgSnapshot);
|
|
167
|
-
if (!depPathByPkgId.has(id)) {
|
|
168
|
-
depPathByPkgId.set(id, depPath);
|
|
169
|
-
}
|
|
170
|
-
node = {
|
|
171
|
-
name: alias,
|
|
172
|
-
identName: pkgName,
|
|
173
|
-
reference: depPathByPkgId.get(id),
|
|
174
|
-
dependencyKind: HoisterDependencyKind.REGULAR,
|
|
175
|
-
dependencies: new Set(),
|
|
176
|
-
peerNames: new Set(autoInstallPeers
|
|
177
|
-
? []
|
|
178
|
-
: [
|
|
179
|
-
...Object.keys(pkgSnapshot.peerDependencies ?? {}),
|
|
180
|
-
...(pkgSnapshot.transitivePeerDependencies ?? []),
|
|
181
|
-
]),
|
|
182
|
-
};
|
|
183
|
-
nodes.set(key, node);
|
|
184
|
-
node.dependencies = toTree({ nodes, lockfile, depPathByPkgId, autoInstallPeers }, { ...pkgSnapshot.dependencies, ...pkgSnapshot.optionalDependencies });
|
|
159
|
+
return getOrCreateWorkspaceNode(ctx.nodes, alias, ref);
|
|
185
160
|
}
|
|
186
|
-
return
|
|
161
|
+
return getOrCreatePackageNode(ctx, alias, depPath);
|
|
187
162
|
}));
|
|
188
163
|
}
|
|
164
|
+
function getOrCreateWorkspaceNode(nodes, alias, ref) {
|
|
165
|
+
const key = `${alias}:${ref}`;
|
|
166
|
+
let node = nodes.get(key);
|
|
167
|
+
if (!node) {
|
|
168
|
+
node = {
|
|
169
|
+
dependencies: new Set(),
|
|
170
|
+
dependencyKind: dp.packageRootLinkTarget(ref) != null
|
|
171
|
+
? HoisterDependencyKind.WORKSPACE
|
|
172
|
+
: HoisterDependencyKind.REGULAR,
|
|
173
|
+
identName: alias,
|
|
174
|
+
name: alias,
|
|
175
|
+
peerNames: new Set(),
|
|
176
|
+
reference: ref,
|
|
177
|
+
};
|
|
178
|
+
nodes.set(key, node);
|
|
179
|
+
}
|
|
180
|
+
return node;
|
|
181
|
+
}
|
|
182
|
+
function getOrCreatePackageNode(ctx, alias, depPath) {
|
|
183
|
+
const key = `${alias}:${depPath}`;
|
|
184
|
+
let node = ctx.nodes.get(key);
|
|
185
|
+
if (!node) {
|
|
186
|
+
const pkgSnapshot = ctx.lockfile.packages?.[depPath];
|
|
187
|
+
if (!pkgSnapshot) {
|
|
188
|
+
throw new LockfileMissingDependencyError(depPath);
|
|
189
|
+
}
|
|
190
|
+
const { name: pkgName } = nameVerFromPkgSnapshot(depPath, pkgSnapshot);
|
|
191
|
+
const id = getHoisterPkgId(depPath, pkgSnapshot);
|
|
192
|
+
if (!ctx.depPathByPkgId.has(id)) {
|
|
193
|
+
ctx.depPathByPkgId.set(id, depPath);
|
|
194
|
+
}
|
|
195
|
+
node = {
|
|
196
|
+
dependencies: new Set(),
|
|
197
|
+
dependencyKind: HoisterDependencyKind.REGULAR,
|
|
198
|
+
identName: pkgName,
|
|
199
|
+
name: alias,
|
|
200
|
+
peerNames: resolvePeerNames(pkgSnapshot, ctx.autoInstallPeers),
|
|
201
|
+
reference: ctx.depPathByPkgId.get(id),
|
|
202
|
+
};
|
|
203
|
+
ctx.nodes.set(key, node);
|
|
204
|
+
node.dependencies = toTree(ctx, {
|
|
205
|
+
...pkgSnapshot.dependencies,
|
|
206
|
+
...pkgSnapshot.optionalDependencies,
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return node;
|
|
210
|
+
}
|
|
211
|
+
function resolvePeerNames(pkgSnapshot, autoInstallPeers) {
|
|
212
|
+
if (autoInstallPeers) {
|
|
213
|
+
return new Set();
|
|
214
|
+
}
|
|
215
|
+
return new Set([
|
|
216
|
+
...Object.keys(pkgSnapshot.peerDependencies ?? {}),
|
|
217
|
+
...(pkgSnapshot.transitivePeerDependencies ?? []),
|
|
218
|
+
]);
|
|
219
|
+
}
|
|
189
220
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/installing.linking.real-hoist",
|
|
3
|
-
"version": "1100.1.
|
|
3
|
+
"version": "1100.1.22",
|
|
4
4
|
"description": "Hoists dependencies in a node_modules created by pnpm",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -27,16 +27,16 @@
|
|
|
27
27
|
"!*.map"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@pnpm/deps.path": "1101.0.
|
|
31
|
-
"@pnpm/error": "1100.2.
|
|
32
|
-
"@pnpm/lockfile.types": "1100.1.
|
|
33
|
-
"@pnpm/lockfile.utils": "1102.1.
|
|
30
|
+
"@pnpm/deps.path": "1101.0.6",
|
|
31
|
+
"@pnpm/error": "1100.2.2",
|
|
32
|
+
"@pnpm/lockfile.types": "1100.1.4",
|
|
33
|
+
"@pnpm/lockfile.utils": "1102.1.6",
|
|
34
34
|
"@yarnpkg/nm": "4.1.1"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@jest/globals": "30.4.1",
|
|
38
|
-
"@pnpm/installing.linking.real-hoist": "1100.1.
|
|
39
|
-
"@pnpm/lockfile.fs": "1100.2.
|
|
38
|
+
"@pnpm/installing.linking.real-hoist": "1100.1.22",
|
|
39
|
+
"@pnpm/lockfile.fs": "1100.2.13",
|
|
40
40
|
"@pnpm/test-fixtures": "1100.0.1",
|
|
41
41
|
"@pnpm/types": "1102.1.1"
|
|
42
42
|
},
|