@npmcli/arborist 4.0.2 → 4.1.0
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/LICENSE.md +20 -0
- package/README.md +3 -3
- package/bin/prune.js +1 -1
- package/bin/reify.js +1 -1
- package/lib/add-rm-pkg-deps.js +3 -3
- package/lib/arborist/build-ideal-tree.js +12 -6
- package/lib/arborist/index.js +34 -22
- package/lib/arborist/load-actual.js +25 -7
- package/lib/arborist/load-virtual.js +5 -4
- package/lib/arborist/rebuild.js +7 -7
- package/lib/arborist/reify.js +15 -11
- package/lib/audit-report.js +3 -3
- package/lib/calc-dep-flags.js +1 -1
- package/lib/can-place-dep.js +2 -2
- package/lib/dep-valid.js +1 -1
- package/lib/diff.js +7 -7
- package/lib/edge.js +38 -3
- package/lib/from-path.js +1 -1
- package/lib/link.js +1 -1
- package/lib/node.js +51 -6
- package/lib/override-set.js +123 -0
- package/lib/place-dep.js +5 -3
- package/lib/printable.js +13 -4
- package/lib/relpath.js +1 -1
- package/lib/retire-path.js +1 -1
- package/lib/shrinkwrap.js +27 -16
- package/lib/version-from-tgz.js +2 -2
- package/lib/vuln.js +1 -1
- package/lib/yarn-lock.js +2 -2
- package/package.json +23 -17
- package/LICENSE +0 -22
package/lib/edge.js
CHANGED
|
@@ -29,6 +29,7 @@ class ArboristEdge {}
|
|
|
29
29
|
const printableEdge = (edge) => {
|
|
30
30
|
const edgeFrom = edge.from && edge.from.location
|
|
31
31
|
const edgeTo = edge.to && edge.to.location
|
|
32
|
+
const override = edge.overrides && edge.overrides.value
|
|
32
33
|
|
|
33
34
|
return Object.assign(new ArboristEdge(), {
|
|
34
35
|
name: edge.name,
|
|
@@ -38,12 +39,13 @@ const printableEdge = (edge) => {
|
|
|
38
39
|
...(edgeTo ? { to: edgeTo } : {}),
|
|
39
40
|
...(edge.error ? { error: edge.error } : {}),
|
|
40
41
|
...(edge.peerConflicted ? { peerConflicted: true } : {}),
|
|
42
|
+
...(override ? { overridden: override } : {}),
|
|
41
43
|
})
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
class Edge {
|
|
45
47
|
constructor (options) {
|
|
46
|
-
const { type, name, spec, accept, from } = options
|
|
48
|
+
const { type, name, spec, accept, from, overrides } = options
|
|
47
49
|
|
|
48
50
|
if (typeof spec !== 'string') {
|
|
49
51
|
throw new TypeError('must provide string spec')
|
|
@@ -55,6 +57,10 @@ class Edge {
|
|
|
55
57
|
|
|
56
58
|
this[_spec] = spec
|
|
57
59
|
|
|
60
|
+
if (overrides !== undefined) {
|
|
61
|
+
this.overrides = overrides
|
|
62
|
+
}
|
|
63
|
+
|
|
58
64
|
if (accept !== undefined) {
|
|
59
65
|
if (typeof accept !== 'string') {
|
|
60
66
|
throw new TypeError('accept field must be a string if provided')
|
|
@@ -82,8 +88,11 @@ class Edge {
|
|
|
82
88
|
}
|
|
83
89
|
|
|
84
90
|
satisfiedBy (node) {
|
|
85
|
-
|
|
86
|
-
|
|
91
|
+
if (node.name !== this.name) {
|
|
92
|
+
return false
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return depValid(node, this.spec, this.accept, this.from)
|
|
87
96
|
}
|
|
88
97
|
|
|
89
98
|
explain (seen = []) {
|
|
@@ -101,6 +110,10 @@ class Edge {
|
|
|
101
110
|
type: this.type,
|
|
102
111
|
name: this.name,
|
|
103
112
|
spec: this.spec,
|
|
113
|
+
...(this.rawSpec !== this.spec ? {
|
|
114
|
+
rawSpec: this.rawSpec,
|
|
115
|
+
overridden: true,
|
|
116
|
+
} : {}),
|
|
104
117
|
...(bundled ? { bundled } : {}),
|
|
105
118
|
...(error ? { error } : {}),
|
|
106
119
|
...(from ? { from: from.explain(null, seen) } : {}),
|
|
@@ -143,7 +156,28 @@ class Edge {
|
|
|
143
156
|
return this[_name]
|
|
144
157
|
}
|
|
145
158
|
|
|
159
|
+
get rawSpec () {
|
|
160
|
+
return this[_spec]
|
|
161
|
+
}
|
|
162
|
+
|
|
146
163
|
get spec () {
|
|
164
|
+
if (this.overrides && this.overrides.value && this.overrides.name === this.name) {
|
|
165
|
+
if (this.overrides.value.startsWith('$')) {
|
|
166
|
+
const ref = this.overrides.value.slice(1)
|
|
167
|
+
const pkg = this.from.root.package
|
|
168
|
+
const overrideSpec = (pkg.devDependencies && pkg.devDependencies[ref]) ||
|
|
169
|
+
(pkg.optionalDependencies && pkg.optionalDependencies[ref]) ||
|
|
170
|
+
(pkg.dependencies && pkg.dependencies[ref]) ||
|
|
171
|
+
(pkg.peerDependencies && pkg.peerDependencies[ref])
|
|
172
|
+
|
|
173
|
+
if (overrideSpec) {
|
|
174
|
+
return overrideSpec
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
throw new Error(`Unable to resolve reference ${this.overrides.value}`)
|
|
178
|
+
}
|
|
179
|
+
return this.overrides.value
|
|
180
|
+
}
|
|
147
181
|
return this[_spec]
|
|
148
182
|
}
|
|
149
183
|
|
|
@@ -213,6 +247,7 @@ class Edge {
|
|
|
213
247
|
if (node.edgesOut.has(this.name)) {
|
|
214
248
|
node.edgesOut.get(this.name).detach()
|
|
215
249
|
}
|
|
250
|
+
|
|
216
251
|
node.addEdgeOut(this)
|
|
217
252
|
this.reload()
|
|
218
253
|
}
|
package/lib/from-path.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// end up getting installed. directory (ie, symlink) deps also need
|
|
4
4
|
// to be resolved based on their targets, but that's what realpath is
|
|
5
5
|
|
|
6
|
-
const {dirname} = require('path')
|
|
6
|
+
const { dirname } = require('path')
|
|
7
7
|
const npa = require('npm-package-arg')
|
|
8
8
|
|
|
9
9
|
const fromPath = (node, spec) =>
|
package/lib/link.js
CHANGED
|
@@ -3,7 +3,7 @@ const relpath = require('./relpath.js')
|
|
|
3
3
|
const Node = require('./node.js')
|
|
4
4
|
const _loadDeps = Symbol.for('Arborist.Node._loadDeps')
|
|
5
5
|
const _target = Symbol.for('_target')
|
|
6
|
-
const {dirname} = require('path')
|
|
6
|
+
const { dirname } = require('path')
|
|
7
7
|
// defined by Node class
|
|
8
8
|
const _delistFromMeta = Symbol.for('_delistFromMeta')
|
|
9
9
|
const _refreshLocation = Symbol.for('_refreshLocation')
|
package/lib/node.js
CHANGED
|
@@ -32,15 +32,16 @@ const semver = require('semver')
|
|
|
32
32
|
const nameFromFolder = require('@npmcli/name-from-folder')
|
|
33
33
|
const Edge = require('./edge.js')
|
|
34
34
|
const Inventory = require('./inventory.js')
|
|
35
|
-
const
|
|
36
|
-
const {
|
|
35
|
+
const OverrideSet = require('./override-set.js')
|
|
36
|
+
const { normalize } = require('read-package-json-fast')
|
|
37
|
+
const { getPaths: getBinPaths } = require('bin-links')
|
|
37
38
|
const npa = require('npm-package-arg')
|
|
38
39
|
const debug = require('./debug.js')
|
|
39
40
|
const gatherDepSet = require('./gather-dep-set.js')
|
|
40
41
|
const treeCheck = require('./tree-check.js')
|
|
41
42
|
const walkUp = require('walk-up-path')
|
|
42
43
|
|
|
43
|
-
const {resolve, relative, dirname, basename} = require('path')
|
|
44
|
+
const { resolve, relative, dirname, basename } = require('path')
|
|
44
45
|
const util = require('util')
|
|
45
46
|
const _package = Symbol('_package')
|
|
46
47
|
const _parent = Symbol('_parent')
|
|
@@ -88,6 +89,8 @@ class Node {
|
|
|
88
89
|
legacyPeerDeps = false,
|
|
89
90
|
linksIn,
|
|
90
91
|
hasShrinkwrap,
|
|
92
|
+
overrides,
|
|
93
|
+
loadOverrides = false,
|
|
91
94
|
extraneous = true,
|
|
92
95
|
dev = true,
|
|
93
96
|
optional = true,
|
|
@@ -190,6 +193,17 @@ class Node {
|
|
|
190
193
|
// because this.package is read when adding to inventory
|
|
191
194
|
this[_package] = pkg && typeof pkg === 'object' ? pkg : {}
|
|
192
195
|
|
|
196
|
+
if (overrides) {
|
|
197
|
+
this.overrides = overrides
|
|
198
|
+
} else if (loadOverrides) {
|
|
199
|
+
const overrides = this[_package].overrides || {}
|
|
200
|
+
if (Object.keys(overrides).length > 0) {
|
|
201
|
+
this.overrides = new OverrideSet({
|
|
202
|
+
overrides: this[_package].overrides,
|
|
203
|
+
})
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
193
207
|
// only relevant for the root and top nodes
|
|
194
208
|
this.meta = meta
|
|
195
209
|
|
|
@@ -291,8 +305,8 @@ class Node {
|
|
|
291
305
|
}
|
|
292
306
|
|
|
293
307
|
get hasInstallScript () {
|
|
294
|
-
const {hasInstallScript, scripts} = this.package
|
|
295
|
-
const {install, preinstall, postinstall} = scripts || {}
|
|
308
|
+
const { hasInstallScript, scripts } = this.package
|
|
309
|
+
const { install, preinstall, postinstall } = scripts || {}
|
|
296
310
|
return !!(hasInstallScript || install || preinstall || postinstall)
|
|
297
311
|
}
|
|
298
312
|
|
|
@@ -376,7 +390,7 @@ class Node {
|
|
|
376
390
|
}
|
|
377
391
|
|
|
378
392
|
if (this.root.sourceReference) {
|
|
379
|
-
const {name, version} = this.root.package
|
|
393
|
+
const { name, version } = this.root.package
|
|
380
394
|
why.whileInstalling = {
|
|
381
395
|
name,
|
|
382
396
|
version,
|
|
@@ -963,6 +977,11 @@ class Node {
|
|
|
963
977
|
return false
|
|
964
978
|
}
|
|
965
979
|
|
|
980
|
+
// XXX need to check for two root nodes?
|
|
981
|
+
if (node.overrides !== this.overrides) {
|
|
982
|
+
return false
|
|
983
|
+
}
|
|
984
|
+
|
|
966
985
|
ignorePeers = new Set(ignorePeers)
|
|
967
986
|
|
|
968
987
|
// gather up all the deps of this node and that are only depended
|
|
@@ -1208,6 +1227,10 @@ class Node {
|
|
|
1208
1227
|
this[_changePath](newPath)
|
|
1209
1228
|
}
|
|
1210
1229
|
|
|
1230
|
+
if (parent.overrides) {
|
|
1231
|
+
this.overrides = parent.overrides.getNodeRule(this)
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1211
1234
|
// clobbers anything at that path, resets all appropriate references
|
|
1212
1235
|
this.root = parent.root
|
|
1213
1236
|
}
|
|
@@ -1279,11 +1302,33 @@ class Node {
|
|
|
1279
1302
|
}
|
|
1280
1303
|
}
|
|
1281
1304
|
|
|
1305
|
+
assertRootOverrides () {
|
|
1306
|
+
if (!this.isProjectRoot || !this.overrides) {
|
|
1307
|
+
return
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
for (const edge of this.edgesOut.values()) {
|
|
1311
|
+
// if these differ an override has been applied, those are not allowed
|
|
1312
|
+
// for top level dependencies so throw an error
|
|
1313
|
+
if (edge.spec !== edge.rawSpec && !edge.spec.startsWith('$')) {
|
|
1314
|
+
throw Object.assign(new Error(`Override for ${edge.name}@${edge.rawSpec} conflicts with direct dependency`), { code: 'EOVERRIDE' })
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1318
|
+
|
|
1282
1319
|
addEdgeOut (edge) {
|
|
1320
|
+
if (this.overrides) {
|
|
1321
|
+
edge.overrides = this.overrides.getEdgeRule(edge)
|
|
1322
|
+
}
|
|
1323
|
+
|
|
1283
1324
|
this.edgesOut.set(edge.name, edge)
|
|
1284
1325
|
}
|
|
1285
1326
|
|
|
1286
1327
|
addEdgeIn (edge) {
|
|
1328
|
+
if (edge.overrides) {
|
|
1329
|
+
this.overrides = edge.overrides
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1287
1332
|
this.edgesIn.add(edge)
|
|
1288
1333
|
|
|
1289
1334
|
// try to get metadata from the yarn.lock file
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const npa = require('npm-package-arg')
|
|
2
|
+
const semver = require('semver')
|
|
3
|
+
|
|
4
|
+
class OverrideSet {
|
|
5
|
+
constructor ({ overrides, key, parent }) {
|
|
6
|
+
this.parent = parent
|
|
7
|
+
this.children = new Map()
|
|
8
|
+
|
|
9
|
+
if (typeof overrides === 'string') {
|
|
10
|
+
overrides = { '.': overrides }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// change a literal empty string to * so we can use truthiness checks on
|
|
14
|
+
// the value property later
|
|
15
|
+
if (overrides['.'] === '') {
|
|
16
|
+
overrides['.'] = '*'
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (parent) {
|
|
20
|
+
const spec = npa(key)
|
|
21
|
+
if (!spec.name) {
|
|
22
|
+
throw new Error(`Override without name: ${key}`)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
this.name = spec.name
|
|
26
|
+
spec.name = ''
|
|
27
|
+
this.key = key
|
|
28
|
+
this.keySpec = spec.rawSpec === '' ? '' : spec.toString()
|
|
29
|
+
this.value = overrides['.'] || this.keySpec
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
for (const [key, childOverrides] of Object.entries(overrides)) {
|
|
33
|
+
if (key === '.') {
|
|
34
|
+
continue
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const child = new OverrideSet({
|
|
38
|
+
parent: this,
|
|
39
|
+
key,
|
|
40
|
+
overrides: childOverrides,
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
this.children.set(child.key, child)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
getEdgeRule (edge) {
|
|
48
|
+
for (const rule of this.ruleset.values()) {
|
|
49
|
+
if (rule.name !== edge.name) {
|
|
50
|
+
continue
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (rule.keySpec === '' ||
|
|
54
|
+
semver.intersects(edge.spec, rule.keySpec)) {
|
|
55
|
+
return rule
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return this
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getNodeRule (node) {
|
|
63
|
+
for (const rule of this.ruleset.values()) {
|
|
64
|
+
if (rule.name !== node.name) {
|
|
65
|
+
continue
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (rule.keySpec === '' ||
|
|
69
|
+
semver.satisfies(node.version, rule.keySpec) ||
|
|
70
|
+
semver.satisfies(node.version, rule.value)) {
|
|
71
|
+
return rule
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return this
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
getMatchingRule (node) {
|
|
79
|
+
for (const rule of this.ruleset.values()) {
|
|
80
|
+
if (rule.name !== node.name) {
|
|
81
|
+
continue
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (rule.keySpec === '' ||
|
|
85
|
+
semver.satisfies(node.version, rule.keySpec) ||
|
|
86
|
+
semver.satisfies(node.version, rule.value)) {
|
|
87
|
+
return rule
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return null
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
* ancestry () {
|
|
95
|
+
for (let ancestor = this; ancestor; ancestor = ancestor.parent) {
|
|
96
|
+
yield ancestor
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get isRoot () {
|
|
101
|
+
return !this.parent
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
get ruleset () {
|
|
105
|
+
const ruleset = new Map()
|
|
106
|
+
|
|
107
|
+
for (const override of this.ancestry()) {
|
|
108
|
+
for (const kid of override.children.values()) {
|
|
109
|
+
if (!ruleset.has(kid.key)) {
|
|
110
|
+
ruleset.set(kid.key, kid)
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!override.isRoot && !ruleset.has(override.key)) {
|
|
115
|
+
ruleset.set(override.key, override)
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return ruleset
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
module.exports = OverrideSet
|
package/lib/place-dep.js
CHANGED
|
@@ -295,6 +295,7 @@ class PlaceDep {
|
|
|
295
295
|
integrity: dep.integrity,
|
|
296
296
|
legacyPeerDeps: this.legacyPeerDeps,
|
|
297
297
|
error: dep.errors[0],
|
|
298
|
+
...(dep.overrides ? { overrides: dep.overrides } : {}),
|
|
298
299
|
...(dep.isLink ? { target: dep.target, realpath: dep.realpath } : {}),
|
|
299
300
|
})
|
|
300
301
|
|
|
@@ -407,11 +408,12 @@ class PlaceDep {
|
|
|
407
408
|
for (const entryEdge of peerEntrySets(edge.from).keys()) {
|
|
408
409
|
// either this one needs to be pruned and re-evaluated, or marked
|
|
409
410
|
// as peerConflicted and warned about. If the entryEdge comes in from
|
|
410
|
-
// the root, then we have to leave it alone, and in that
|
|
411
|
-
// will have already warned or crashed by getting to this point
|
|
411
|
+
// the root or a workspace, then we have to leave it alone, and in that
|
|
412
|
+
// case, it will have already warned or crashed by getting to this point
|
|
412
413
|
const entryNode = entryEdge.to
|
|
413
414
|
const deepestTarget = deepestNestingTarget(entryNode)
|
|
414
|
-
if (deepestTarget !== target &&
|
|
415
|
+
if (deepestTarget !== target &&
|
|
416
|
+
!(entryEdge.from.isProjectRoot || entryEdge.from.isWorkspace)) {
|
|
415
417
|
prunePeerSets.push(...gatherDepSet([entryNode], e => {
|
|
416
418
|
return e.to !== entryNode && !e.peerConflicted
|
|
417
419
|
}))
|
package/lib/printable.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// helper function to output a clearer visualization
|
|
2
2
|
// of the current node and its descendents
|
|
3
|
-
|
|
4
3
|
const localeCompare = require('@isaacs/string-locale-compare')('en')
|
|
5
4
|
const util = require('util')
|
|
6
5
|
const relpath = require('./relpath.js')
|
|
@@ -65,6 +64,11 @@ class ArboristNode {
|
|
|
65
64
|
this.errors = tree.errors.map(treeError)
|
|
66
65
|
}
|
|
67
66
|
|
|
67
|
+
if (tree.overrides) {
|
|
68
|
+
this.overrides = new Map([...tree.overrides.ruleset.values()]
|
|
69
|
+
.map((override) => [override.key, override.value]))
|
|
70
|
+
}
|
|
71
|
+
|
|
68
72
|
// edgesOut sorted by name
|
|
69
73
|
if (tree.edgesOut.size) {
|
|
70
74
|
this.edgesOut = new Map([...tree.edgesOut.entries()]
|
|
@@ -87,7 +91,7 @@ class ArboristNode {
|
|
|
87
91
|
// fsChildren sorted by path
|
|
88
92
|
if (tree.fsChildren.size) {
|
|
89
93
|
this.fsChildren = new Set([...tree.fsChildren]
|
|
90
|
-
.sort(({path: a}, {path: b}) => localeCompare(a, b))
|
|
94
|
+
.sort(({ path: a }, { path: b }) => localeCompare(a, b))
|
|
91
95
|
.map(tree => printableTree(tree, path)))
|
|
92
96
|
}
|
|
93
97
|
|
|
@@ -114,7 +118,7 @@ class ArboristLink extends ArboristNode {
|
|
|
114
118
|
}
|
|
115
119
|
}
|
|
116
120
|
|
|
117
|
-
const treeError = ({code, path}) => ({
|
|
121
|
+
const treeError = ({ code, path }) => ({
|
|
118
122
|
code,
|
|
119
123
|
...(path ? { path } : {}),
|
|
120
124
|
})
|
|
@@ -126,7 +130,10 @@ class Edge {
|
|
|
126
130
|
constructor (edge) {
|
|
127
131
|
this.type = edge.type
|
|
128
132
|
this.name = edge.name
|
|
129
|
-
this.spec = edge.
|
|
133
|
+
this.spec = edge.rawSpec || '*'
|
|
134
|
+
if (edge.rawSpec !== edge.spec) {
|
|
135
|
+
this.override = edge.spec
|
|
136
|
+
}
|
|
130
137
|
if (edge.error) {
|
|
131
138
|
this.error = edge.error
|
|
132
139
|
}
|
|
@@ -145,6 +152,8 @@ class EdgeOut extends Edge {
|
|
|
145
152
|
|
|
146
153
|
[util.inspect.custom] () {
|
|
147
154
|
return `{ ${this.type} ${this.name}@${this.spec}${
|
|
155
|
+
this.override ? ` overridden:${this.override}` : ''
|
|
156
|
+
}${
|
|
148
157
|
this.to ? ' -> ' + this.to : ''
|
|
149
158
|
}${
|
|
150
159
|
this.error ? ' ' + this.error : ''
|
package/lib/relpath.js
CHANGED
package/lib/retire-path.js
CHANGED
package/lib/shrinkwrap.js
CHANGED
|
@@ -35,7 +35,7 @@ const mismatch = (a, b) => a && b && a !== b
|
|
|
35
35
|
|
|
36
36
|
const procLog = require('proc-log')
|
|
37
37
|
const YarnLock = require('./yarn-lock.js')
|
|
38
|
-
const {promisify} = require('util')
|
|
38
|
+
const { promisify } = require('util')
|
|
39
39
|
const rimraf = promisify(require('rimraf'))
|
|
40
40
|
const fs = require('fs')
|
|
41
41
|
const readFile = promisify(fs.readFile)
|
|
@@ -180,7 +180,7 @@ const assertNoNewer = async (path, data, lockTime, dir = path, seen = null) => {
|
|
|
180
180
|
|
|
181
181
|
const parent = isParent ? dir : resolve(dir, 'node_modules')
|
|
182
182
|
const children = dir === path
|
|
183
|
-
? Promise.resolve([{name: 'node_modules', isDirectory: () => true }])
|
|
183
|
+
? Promise.resolve([{ name: 'node_modules', isDirectory: () => true }])
|
|
184
184
|
: readdir(parent, { withFileTypes: true })
|
|
185
185
|
|
|
186
186
|
return children.catch(() => [])
|
|
@@ -238,21 +238,31 @@ class Shrinkwrap {
|
|
|
238
238
|
return swKeyOrder
|
|
239
239
|
}
|
|
240
240
|
|
|
241
|
-
static reset (options) {
|
|
241
|
+
static async reset (options) {
|
|
242
242
|
// still need to know if it was loaded from the disk, but don't
|
|
243
243
|
// bother reading it if we're gonna just throw it away.
|
|
244
244
|
const s = new Shrinkwrap(options)
|
|
245
245
|
s.reset()
|
|
246
246
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
247
|
+
const [sw, lock] = await s[_maybeStat]()
|
|
248
|
+
|
|
249
|
+
s.filename = resolve(s.path,
|
|
250
|
+
(s.hiddenLockfile ? 'node_modules/.package-lock'
|
|
251
|
+
: s.shrinkwrapOnly || sw ? 'npm-shrinkwrap'
|
|
252
|
+
: 'package-lock') + '.json')
|
|
253
|
+
s.loadedFromDisk = !!(sw || lock)
|
|
254
|
+
s.type = basename(s.filename)
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
if (s.loadedFromDisk && !s.lockfileVersion) {
|
|
258
|
+
const json = parseJSON(await maybeReadFile(s.filename))
|
|
259
|
+
if (json.lockfileVersion > defaultLockfileVersion) {
|
|
260
|
+
s.lockfileVersion = json.lockfileVersion
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
} catch (e) {}
|
|
264
|
+
|
|
265
|
+
return s
|
|
256
266
|
}
|
|
257
267
|
|
|
258
268
|
static metaFromNode (node, path) {
|
|
@@ -356,7 +366,7 @@ class Shrinkwrap {
|
|
|
356
366
|
if (fromYarn && fromYarn.version) {
|
|
357
367
|
// if it's the yarn or npm default registry, use the version as
|
|
358
368
|
// our effective spec. if it's any other kind of thing, use that.
|
|
359
|
-
const {resolved, version, integrity} = fromYarn
|
|
369
|
+
const { resolved, version, integrity } = fromYarn
|
|
360
370
|
const isYarnReg = spec.registry && yarnRegRe.test(resolved)
|
|
361
371
|
const isnpmReg = spec.registry && !isYarnReg && npmRegRe.test(resolved)
|
|
362
372
|
const isReg = isnpmReg || isYarnReg
|
|
@@ -380,9 +390,10 @@ class Shrinkwrap {
|
|
|
380
390
|
reset () {
|
|
381
391
|
this.tree = null
|
|
382
392
|
this[_awaitingUpdate] = new Map()
|
|
383
|
-
|
|
393
|
+
const lockfileVersion = this.lockfileVersion || defaultLockfileVersion
|
|
394
|
+
this.originalLockfileVersion = lockfileVersion
|
|
384
395
|
this.data = {
|
|
385
|
-
lockfileVersion
|
|
396
|
+
lockfileVersion,
|
|
386
397
|
requires: true,
|
|
387
398
|
packages: {},
|
|
388
399
|
dependencies: {},
|
|
@@ -1051,7 +1062,7 @@ class Shrinkwrap {
|
|
|
1051
1062
|
}
|
|
1052
1063
|
|
|
1053
1064
|
// now we walk the children, putting them in the 'dependencies' object
|
|
1054
|
-
const {children} = node.target
|
|
1065
|
+
const { children } = node.target
|
|
1055
1066
|
if (!children.size) {
|
|
1056
1067
|
delete lock.dependencies
|
|
1057
1068
|
} else {
|
package/lib/version-from-tgz.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint node/no-deprecated-api: "off" */
|
|
2
2
|
const semver = require('semver')
|
|
3
|
-
const {basename} = require('path')
|
|
4
|
-
const {parse} = require('url')
|
|
3
|
+
const { basename } = require('path')
|
|
4
|
+
const { parse } = require('url')
|
|
5
5
|
module.exports = (name, tgz) => {
|
|
6
6
|
const base = basename(tgz)
|
|
7
7
|
if (!base.endsWith('.tgz')) {
|
package/lib/vuln.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// @npmcli/metavuln-calculator
|
|
12
12
|
// - via: dependency vulns which cause this one
|
|
13
13
|
|
|
14
|
-
const {satisfies, simplifyRange} = require('semver')
|
|
14
|
+
const { satisfies, simplifyRange } = require('semver')
|
|
15
15
|
const semverOpt = { loose: true, includePrerelease: true }
|
|
16
16
|
|
|
17
17
|
const localeCompare = require('@isaacs/string-locale-compare')('en')
|
package/lib/yarn-lock.js
CHANGED
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
|
|
31
31
|
const localeCompare = require('@isaacs/string-locale-compare')('en')
|
|
32
32
|
const consistentResolve = require('./consistent-resolve.js')
|
|
33
|
-
const {dirname} = require('path')
|
|
34
|
-
const {breadth} = require('treeverse')
|
|
33
|
+
const { dirname } = require('path')
|
|
34
|
+
const { breadth } = require('treeverse')
|
|
35
35
|
|
|
36
36
|
// sort a key/value object into a string of JSON stringified keys and vals
|
|
37
37
|
const sortKV = obj => Object.keys(obj)
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/arborist",
|
|
3
|
-
"version": "4.0
|
|
3
|
+
"version": "4.1.0",
|
|
4
4
|
"description": "Manage node_modules trees",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@isaacs/string-locale-compare": "^1.0
|
|
6
|
+
"@isaacs/string-locale-compare": "^1.1.0",
|
|
7
7
|
"@npmcli/installed-package-contents": "^1.0.7",
|
|
8
8
|
"@npmcli/map-workspaces": "^2.0.0",
|
|
9
9
|
"@npmcli/metavuln-calculator": "^2.0.0",
|
|
10
10
|
"@npmcli/move-file": "^1.1.0",
|
|
11
11
|
"@npmcli/name-from-folder": "^1.0.1",
|
|
12
|
-
"@npmcli/node-gyp": "^1.0.
|
|
12
|
+
"@npmcli/node-gyp": "^1.0.3",
|
|
13
13
|
"@npmcli/package-json": "^1.0.1",
|
|
14
14
|
"@npmcli/run-script": "^2.0.0",
|
|
15
15
|
"bin-links": "^2.3.0",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"npm-package-arg": "^8.1.5",
|
|
24
24
|
"npm-pick-manifest": "^6.1.0",
|
|
25
25
|
"npm-registry-fetch": "^11.0.0",
|
|
26
|
-
"pacote": "^12.0.
|
|
26
|
+
"pacote": "^12.0.2",
|
|
27
27
|
"parse-conflict-json": "^1.1.1",
|
|
28
28
|
"proc-log": "^1.0.0",
|
|
29
29
|
"promise-all-reject-late": "^1.0.0",
|
|
@@ -37,39 +37,40 @@
|
|
|
37
37
|
"walk-up-path": "^1.0.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@npmcli/
|
|
40
|
+
"@npmcli/template-oss": "^2.3.1",
|
|
41
41
|
"benchmark": "^2.1.4",
|
|
42
42
|
"chalk": "^4.1.0",
|
|
43
43
|
"minify-registry-metadata": "^2.1.0",
|
|
44
|
-
"
|
|
44
|
+
"nock": "^13.2.0",
|
|
45
|
+
"tap": "^15.1.2",
|
|
45
46
|
"tcompare": "^5.0.6"
|
|
46
47
|
},
|
|
47
48
|
"scripts": {
|
|
48
|
-
"test": "
|
|
49
|
-
"
|
|
50
|
-
"posttest": "npm run lint --",
|
|
49
|
+
"test": "tap",
|
|
50
|
+
"posttest": "npm run lint",
|
|
51
51
|
"snap": "tap",
|
|
52
|
-
"postsnap": "npm run lintfix
|
|
52
|
+
"postsnap": "npm run lintfix",
|
|
53
53
|
"test-proxy": "ARBORIST_TEST_PROXY=1 tap --snapshot",
|
|
54
54
|
"preversion": "npm test",
|
|
55
55
|
"postversion": "npm publish",
|
|
56
56
|
"prepublishOnly": "git push origin --follow-tags",
|
|
57
57
|
"eslint": "eslint",
|
|
58
|
-
"lint": "
|
|
58
|
+
"lint": "eslint '**/*.js'",
|
|
59
59
|
"lintfix": "npm run lint -- --fix",
|
|
60
60
|
"benchmark": "node scripts/benchmark.js",
|
|
61
61
|
"benchclean": "rm -rf scripts/benchmark/*/",
|
|
62
|
-
"npmclilint": "npmcli-lint"
|
|
62
|
+
"npmclilint": "npmcli-lint",
|
|
63
|
+
"postlint": "npm-template-check"
|
|
63
64
|
},
|
|
64
65
|
"repository": {
|
|
65
66
|
"type": "git",
|
|
66
67
|
"url": "https://github.com/npm/arborist"
|
|
67
68
|
},
|
|
68
|
-
"author": "
|
|
69
|
+
"author": "GitHub Inc.",
|
|
69
70
|
"license": "ISC",
|
|
70
71
|
"files": [
|
|
71
|
-
"
|
|
72
|
-
"
|
|
72
|
+
"bin",
|
|
73
|
+
"lib"
|
|
73
74
|
],
|
|
74
75
|
"main": "lib/index.js",
|
|
75
76
|
"bin": {
|
|
@@ -88,9 +89,14 @@
|
|
|
88
89
|
"--no-warnings",
|
|
89
90
|
"--no-deprecation"
|
|
90
91
|
],
|
|
91
|
-
"timeout": "
|
|
92
|
+
"timeout": "360"
|
|
92
93
|
},
|
|
93
94
|
"engines": {
|
|
94
95
|
"node": "^12.13.0 || ^14.15.0 || >=16"
|
|
95
|
-
}
|
|
96
|
+
},
|
|
97
|
+
"templateVersion": "2.3.1",
|
|
98
|
+
"eslintIgnore": [
|
|
99
|
+
"test/fixtures/",
|
|
100
|
+
"!test/fixtures/*.js"
|
|
101
|
+
]
|
|
96
102
|
}
|