@npmcli/arborist 6.2.8 → 6.2.10
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/lib/arborist/build-ideal-tree.js +271 -269
- package/lib/arborist/index.js +1 -1
- package/lib/arborist/load-actual.js +104 -107
- package/lib/arborist/load-virtual.js +58 -78
- package/lib/arborist/reify.js +23 -11
- package/lib/arborist/{load-workspaces.js → set-workspaces.js} +2 -2
- package/lib/calc-dep-flags.js +14 -10
- package/lib/dep-valid.js +15 -9
- package/lib/edge.js +168 -161
- package/lib/from-path.js +21 -15
- package/lib/inventory.js +68 -55
- package/lib/node.js +72 -75
- package/lib/query-selector-all.js +1 -1
- package/package.json +5 -12
package/lib/node.js
CHANGED
|
@@ -47,21 +47,15 @@ const _package = Symbol('_package')
|
|
|
47
47
|
const _parent = Symbol('_parent')
|
|
48
48
|
const _target = Symbol.for('_target')
|
|
49
49
|
const _fsParent = Symbol('_fsParent')
|
|
50
|
-
const _loadDepType = Symbol('_loadDepType')
|
|
51
|
-
const _loadWorkspaces = Symbol('_loadWorkspaces')
|
|
52
50
|
const _reloadNamedEdges = Symbol('_reloadNamedEdges')
|
|
53
51
|
// overridden by Link class
|
|
54
52
|
const _loadDeps = Symbol.for('Arborist.Node._loadDeps')
|
|
55
|
-
const _root = Symbol('_root')
|
|
56
53
|
const _refreshLocation = Symbol.for('_refreshLocation')
|
|
57
54
|
const _changePath = Symbol.for('_changePath')
|
|
58
55
|
// used by Link class as well
|
|
59
56
|
const _delistFromMeta = Symbol.for('_delistFromMeta')
|
|
60
|
-
const _global = Symbol.for('global')
|
|
61
|
-
const _workspaces = Symbol('_workspaces')
|
|
62
57
|
const _explain = Symbol('_explain')
|
|
63
58
|
const _explanation = Symbol('_explanation')
|
|
64
|
-
const _meta = Symbol('_meta')
|
|
65
59
|
|
|
66
60
|
const relpath = require('./relpath.js')
|
|
67
61
|
const consistentResolve = require('./consistent-resolve.js')
|
|
@@ -72,6 +66,11 @@ const CaseInsensitiveMap = require('./case-insensitive-map.js')
|
|
|
72
66
|
const querySelectorAll = require('./query-selector-all.js')
|
|
73
67
|
|
|
74
68
|
class Node {
|
|
69
|
+
#global
|
|
70
|
+
#meta
|
|
71
|
+
#root
|
|
72
|
+
#workspaces
|
|
73
|
+
|
|
75
74
|
constructor (options) {
|
|
76
75
|
// NB: path can be null if it's a link target
|
|
77
76
|
const {
|
|
@@ -109,9 +108,9 @@ class Node {
|
|
|
109
108
|
this.queryContext = {}
|
|
110
109
|
|
|
111
110
|
// true if part of a global install
|
|
112
|
-
this
|
|
111
|
+
this.#global = global
|
|
113
112
|
|
|
114
|
-
this
|
|
113
|
+
this.#workspaces = null
|
|
115
114
|
|
|
116
115
|
this.errors = error ? [error] : []
|
|
117
116
|
this.isInStore = isInStore
|
|
@@ -165,7 +164,7 @@ class Node {
|
|
|
165
164
|
|
|
166
165
|
this.children = new CaseInsensitiveMap()
|
|
167
166
|
this.fsChildren = new Set()
|
|
168
|
-
this.inventory = new Inventory(
|
|
167
|
+
this.inventory = new Inventory()
|
|
169
168
|
this.tops = new Set()
|
|
170
169
|
this.linksIn = new Set(linksIn || [])
|
|
171
170
|
|
|
@@ -262,18 +261,21 @@ class Node {
|
|
|
262
261
|
}
|
|
263
262
|
|
|
264
263
|
get meta () {
|
|
265
|
-
return this
|
|
264
|
+
return this.#meta
|
|
266
265
|
}
|
|
267
266
|
|
|
268
267
|
set meta (meta) {
|
|
269
|
-
this
|
|
268
|
+
this.#meta = meta
|
|
270
269
|
if (meta) {
|
|
271
270
|
meta.add(this)
|
|
272
271
|
}
|
|
273
272
|
}
|
|
274
273
|
|
|
275
274
|
get global () {
|
|
276
|
-
|
|
275
|
+
if (this.#root === this) {
|
|
276
|
+
return this.#global
|
|
277
|
+
}
|
|
278
|
+
return this.#root.global
|
|
277
279
|
}
|
|
278
280
|
|
|
279
281
|
// true for packages installed directly in the global node_modules folder
|
|
@@ -282,21 +284,21 @@ class Node {
|
|
|
282
284
|
}
|
|
283
285
|
|
|
284
286
|
get workspaces () {
|
|
285
|
-
return this
|
|
287
|
+
return this.#workspaces
|
|
286
288
|
}
|
|
287
289
|
|
|
288
290
|
set workspaces (workspaces) {
|
|
289
291
|
// deletes edges if they already exists
|
|
290
|
-
if (this
|
|
291
|
-
for (const name of this
|
|
292
|
+
if (this.#workspaces) {
|
|
293
|
+
for (const name of this.#workspaces.keys()) {
|
|
292
294
|
if (!workspaces.has(name)) {
|
|
293
295
|
this.edgesOut.get(name).detach()
|
|
294
296
|
}
|
|
295
297
|
}
|
|
296
298
|
}
|
|
297
299
|
|
|
298
|
-
this
|
|
299
|
-
this
|
|
300
|
+
this.#workspaces = workspaces
|
|
301
|
+
this.#loadWorkspaces()
|
|
300
302
|
this[_loadDeps]()
|
|
301
303
|
}
|
|
302
304
|
|
|
@@ -367,7 +369,7 @@ class Node {
|
|
|
367
369
|
pkg = {}
|
|
368
370
|
}
|
|
369
371
|
this[_package] = pkg
|
|
370
|
-
this
|
|
372
|
+
this.#loadWorkspaces()
|
|
371
373
|
this[_loadDeps]()
|
|
372
374
|
// do a hard reload, since the dependents may now be valid or invalid
|
|
373
375
|
// as a result of the package change.
|
|
@@ -569,12 +571,12 @@ class Node {
|
|
|
569
571
|
// this allows us to do new Node({...}) and then set the root later.
|
|
570
572
|
// just make the assignment so we don't lose it, and move on.
|
|
571
573
|
if (!this.path || !root.realpath || !root.path) {
|
|
572
|
-
this
|
|
574
|
+
this.#root = root
|
|
573
575
|
return
|
|
574
576
|
}
|
|
575
577
|
|
|
576
578
|
// temporarily become a root node
|
|
577
|
-
this
|
|
579
|
+
this.#root = this
|
|
578
580
|
|
|
579
581
|
// break all linksIn, we're going to re-set them if needed later
|
|
580
582
|
for (const link of this.linksIn) {
|
|
@@ -618,7 +620,7 @@ class Node {
|
|
|
618
620
|
current.root = null
|
|
619
621
|
}
|
|
620
622
|
|
|
621
|
-
this
|
|
623
|
+
this.#root = root
|
|
622
624
|
// set this.location and add to inventory
|
|
623
625
|
this[_refreshLocation]()
|
|
624
626
|
|
|
@@ -684,22 +686,22 @@ class Node {
|
|
|
684
686
|
// the node at nm/a, which might have the root node as a fsParent.
|
|
685
687
|
// we can't rely on the public setter here, because it calls into
|
|
686
688
|
// this function to set up these references!
|
|
687
|
-
const nmloc = `${this.location}${this.location ? '/' : ''}node_modules/`
|
|
688
|
-
const isChild = n => n.location === nmloc + n.name
|
|
689
689
|
// check dirname so that /foo isn't treated as the fsparent of /foo-bar
|
|
690
|
-
const
|
|
691
|
-
return dirname(n.path).startsWith(this.path) &&
|
|
692
|
-
n !== this &&
|
|
693
|
-
!n.parent &&
|
|
694
|
-
(!n.fsParent ||
|
|
695
|
-
n.fsParent === this ||
|
|
696
|
-
dirname(this.path).startsWith(n.fsParent.path))
|
|
697
|
-
}
|
|
698
|
-
const isKid = n => isChild(n) || isFsChild(n)
|
|
699
|
-
|
|
690
|
+
const nmloc = `${this.location}${this.location ? '/' : ''}node_modules/`
|
|
700
691
|
// only walk top nodes, since anything else already has a parent.
|
|
701
692
|
for (const child of root.tops) {
|
|
702
|
-
|
|
693
|
+
const isChild = child.location === nmloc + child.name
|
|
694
|
+
const isFsChild =
|
|
695
|
+
dirname(child.path).startsWith(this.path) &&
|
|
696
|
+
child !== this &&
|
|
697
|
+
!child.parent &&
|
|
698
|
+
(
|
|
699
|
+
!child.fsParent ||
|
|
700
|
+
child.fsParent === this ||
|
|
701
|
+
dirname(this.path).startsWith(child.fsParent.path)
|
|
702
|
+
)
|
|
703
|
+
|
|
704
|
+
if (!isChild && !isFsChild) {
|
|
703
705
|
continue
|
|
704
706
|
}
|
|
705
707
|
|
|
@@ -712,7 +714,7 @@ class Node {
|
|
|
712
714
|
child.fsParent.fsChildren.delete(child)
|
|
713
715
|
}
|
|
714
716
|
child[_fsParent] = null
|
|
715
|
-
if (isChild
|
|
717
|
+
if (isChild) {
|
|
716
718
|
this.children.set(child.name, child)
|
|
717
719
|
child[_parent] = this
|
|
718
720
|
root.tops.delete(child)
|
|
@@ -823,19 +825,21 @@ class Node {
|
|
|
823
825
|
}
|
|
824
826
|
// tree should always be valid upon root setter completion.
|
|
825
827
|
treeCheck(this)
|
|
826
|
-
|
|
828
|
+
if (this !== root) {
|
|
829
|
+
treeCheck(root)
|
|
830
|
+
}
|
|
827
831
|
}
|
|
828
832
|
|
|
829
833
|
get root () {
|
|
830
|
-
return this
|
|
834
|
+
return this.#root || this
|
|
831
835
|
}
|
|
832
836
|
|
|
833
|
-
|
|
834
|
-
if (!this
|
|
837
|
+
#loadWorkspaces () {
|
|
838
|
+
if (!this.#workspaces) {
|
|
835
839
|
return
|
|
836
840
|
}
|
|
837
841
|
|
|
838
|
-
for (const [name, path] of this
|
|
842
|
+
for (const [name, path] of this.#workspaces.entries()) {
|
|
839
843
|
new Edge({ from: this, name, spec: `file:${path.replace(/#/g, '%23')}`, type: 'workspace' })
|
|
840
844
|
}
|
|
841
845
|
}
|
|
@@ -851,23 +855,24 @@ class Node {
|
|
|
851
855
|
// but don't have a 'path' field, only a 'realpath', because we
|
|
852
856
|
// don't know their canonical location. We don't need their devDeps.
|
|
853
857
|
const pd = this.package.peerDependencies
|
|
858
|
+
const ad = this.package.acceptDependencies || {}
|
|
854
859
|
if (pd && typeof pd === 'object' && !this.legacyPeerDeps) {
|
|
855
860
|
const pm = this.package.peerDependenciesMeta || {}
|
|
856
861
|
const peerDependencies = {}
|
|
857
862
|
const peerOptional = {}
|
|
858
863
|
for (const [name, dep] of Object.entries(pd)) {
|
|
859
|
-
if (pm[name]
|
|
864
|
+
if (pm[name]?.optional) {
|
|
860
865
|
peerOptional[name] = dep
|
|
861
866
|
} else {
|
|
862
867
|
peerDependencies[name] = dep
|
|
863
868
|
}
|
|
864
869
|
}
|
|
865
|
-
this
|
|
866
|
-
this
|
|
870
|
+
this.#loadDepType(peerDependencies, 'peer', ad)
|
|
871
|
+
this.#loadDepType(peerOptional, 'peerOptional', ad)
|
|
867
872
|
}
|
|
868
873
|
|
|
869
|
-
this
|
|
870
|
-
this
|
|
874
|
+
this.#loadDepType(this.package.dependencies, 'prod', ad)
|
|
875
|
+
this.#loadDepType(this.package.optionalDependencies, 'optional', ad)
|
|
871
876
|
|
|
872
877
|
const { globalTop, isTop, path, sourceReference } = this
|
|
873
878
|
const {
|
|
@@ -878,12 +883,11 @@ class Node {
|
|
|
878
883
|
const thisDev = isTop && !globalTop && path
|
|
879
884
|
const srcDev = !sourceReference || srcTop && !srcGlobalTop && srcPath
|
|
880
885
|
if (thisDev && srcDev) {
|
|
881
|
-
this
|
|
886
|
+
this.#loadDepType(this.package.devDependencies, 'dev', ad)
|
|
882
887
|
}
|
|
883
888
|
}
|
|
884
889
|
|
|
885
|
-
|
|
886
|
-
const ad = this.package.acceptDependencies || {}
|
|
890
|
+
#loadDepType (deps, type, ad) {
|
|
887
891
|
// Because of the order in which _loadDeps runs, we always want to
|
|
888
892
|
// prioritize a new edge over an existing one
|
|
889
893
|
for (const [name, spec] of Object.entries(deps || {})) {
|
|
@@ -895,14 +899,8 @@ class Node {
|
|
|
895
899
|
}
|
|
896
900
|
|
|
897
901
|
get fsParent () {
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
debug(() => {
|
|
901
|
-
if (parent === this) {
|
|
902
|
-
throw new Error('node set to its own fsParent')
|
|
903
|
-
}
|
|
904
|
-
})
|
|
905
|
-
return parent
|
|
902
|
+
// in debug setter prevents fsParent from being this
|
|
903
|
+
return this[_fsParent]
|
|
906
904
|
}
|
|
907
905
|
|
|
908
906
|
set fsParent (fsParent) {
|
|
@@ -997,7 +995,7 @@ class Node {
|
|
|
997
995
|
// root dependency brings peer deps along with it. In that case, we
|
|
998
996
|
// will go ahead and create the invalid state, and then try to resolve
|
|
999
997
|
// it with more tree construction, because it's a user request.
|
|
1000
|
-
canReplaceWith (node, ignorePeers
|
|
998
|
+
canReplaceWith (node, ignorePeers) {
|
|
1001
999
|
if (node.name !== this.name) {
|
|
1002
1000
|
return false
|
|
1003
1001
|
}
|
|
@@ -1010,7 +1008,6 @@ class Node {
|
|
|
1010
1008
|
if (node.overrides !== this.overrides) {
|
|
1011
1009
|
return false
|
|
1012
1010
|
}
|
|
1013
|
-
|
|
1014
1011
|
ignorePeers = new Set(ignorePeers)
|
|
1015
1012
|
|
|
1016
1013
|
// gather up all the deps of this node and that are only depended
|
|
@@ -1022,11 +1019,10 @@ class Node {
|
|
|
1022
1019
|
// when replacing peer sets, we need to be able to replace the entire
|
|
1023
1020
|
// peer group, which means we ignore incoming edges from other peers
|
|
1024
1021
|
// within the replacement set.
|
|
1025
|
-
|
|
1022
|
+
if (!this.isTop &&
|
|
1026
1023
|
edge.from.parent === this.parent &&
|
|
1027
1024
|
edge.peer &&
|
|
1028
|
-
ignorePeers.has(edge.from.name)
|
|
1029
|
-
if (ignored) {
|
|
1025
|
+
ignorePeers.has(edge.from.name)) {
|
|
1030
1026
|
continue
|
|
1031
1027
|
}
|
|
1032
1028
|
|
|
@@ -1156,9 +1152,7 @@ class Node {
|
|
|
1156
1152
|
// something case-insensitively, so merely setting name and path won't
|
|
1157
1153
|
// have the desired effect. just set the path so it'll collide in the
|
|
1158
1154
|
// parent's children map, and leave it at that.
|
|
1159
|
-
|
|
1160
|
-
node.parent.children.get(this.name) === node
|
|
1161
|
-
if (nameMatch) {
|
|
1155
|
+
if (node.parent?.children.get(this.name) === node) {
|
|
1162
1156
|
this.path = resolve(node.parent.path, 'node_modules', this.name)
|
|
1163
1157
|
} else {
|
|
1164
1158
|
this.path = node.path
|
|
@@ -1193,14 +1187,8 @@ class Node {
|
|
|
1193
1187
|
}
|
|
1194
1188
|
|
|
1195
1189
|
get parent () {
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
debug(() => {
|
|
1199
|
-
if (parent === this) {
|
|
1200
|
-
throw new Error('node set to its own parent')
|
|
1201
|
-
}
|
|
1202
|
-
})
|
|
1203
|
-
return parent
|
|
1190
|
+
// setter prevents _parent from being this
|
|
1191
|
+
return this[_parent]
|
|
1204
1192
|
}
|
|
1205
1193
|
|
|
1206
1194
|
// This setter keeps everything in order when we move a node from
|
|
@@ -1405,7 +1393,10 @@ class Node {
|
|
|
1405
1393
|
}
|
|
1406
1394
|
|
|
1407
1395
|
get depth () {
|
|
1408
|
-
|
|
1396
|
+
if (this.isTop) {
|
|
1397
|
+
return 0
|
|
1398
|
+
}
|
|
1399
|
+
return this.parent.depth + 1
|
|
1409
1400
|
}
|
|
1410
1401
|
|
|
1411
1402
|
get isTop () {
|
|
@@ -1413,7 +1404,10 @@ class Node {
|
|
|
1413
1404
|
}
|
|
1414
1405
|
|
|
1415
1406
|
get top () {
|
|
1416
|
-
|
|
1407
|
+
if (this.isTop) {
|
|
1408
|
+
return this
|
|
1409
|
+
}
|
|
1410
|
+
return this.parent.top
|
|
1417
1411
|
}
|
|
1418
1412
|
|
|
1419
1413
|
get isFsTop () {
|
|
@@ -1421,7 +1415,10 @@ class Node {
|
|
|
1421
1415
|
}
|
|
1422
1416
|
|
|
1423
1417
|
get fsTop () {
|
|
1424
|
-
|
|
1418
|
+
if (this.isFsTop) {
|
|
1419
|
+
return this
|
|
1420
|
+
}
|
|
1421
|
+
return this.fsParent.fsTop
|
|
1425
1422
|
}
|
|
1426
1423
|
|
|
1427
1424
|
get resolveParent () {
|
|
@@ -4,7 +4,7 @@ const { resolve } = require('path')
|
|
|
4
4
|
const { parser, arrayDelimiter } = require('@npmcli/query')
|
|
5
5
|
const localeCompare = require('@isaacs/string-locale-compare')('en')
|
|
6
6
|
const log = require('proc-log')
|
|
7
|
-
const minimatch = require('minimatch')
|
|
7
|
+
const { minimatch } = require('minimatch')
|
|
8
8
|
const npa = require('npm-package-arg')
|
|
9
9
|
const pacote = require('pacote')
|
|
10
10
|
const semver = require('semver')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/arborist",
|
|
3
|
-
"version": "6.2.
|
|
3
|
+
"version": "6.2.10",
|
|
4
4
|
"description": "Manage node_modules trees",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@isaacs/string-locale-compare": "^1.1.0",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"hosted-git-info": "^6.1.1",
|
|
20
20
|
"json-parse-even-better-errors": "^3.0.0",
|
|
21
21
|
"json-stringify-nice": "^1.1.4",
|
|
22
|
-
"minimatch": "^
|
|
22
|
+
"minimatch": "^9.0.0",
|
|
23
23
|
"nopt": "^7.0.0",
|
|
24
24
|
"npm-install-checks": "^6.0.0",
|
|
25
25
|
"npm-package-arg": "^10.1.0",
|
|
@@ -39,9 +39,8 @@
|
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@npmcli/eslint-config": "^4.0.0",
|
|
42
|
-
"@npmcli/template-oss": "4.
|
|
42
|
+
"@npmcli/template-oss": "4.14.1",
|
|
43
43
|
"benchmark": "^2.1.4",
|
|
44
|
-
"chalk": "^4.1.0",
|
|
45
44
|
"minify-registry-metadata": "^3.0.0",
|
|
46
45
|
"nock": "^13.3.0",
|
|
47
46
|
"tap": "^16.3.4",
|
|
@@ -75,18 +74,12 @@
|
|
|
75
74
|
"bin": {
|
|
76
75
|
"arborist": "bin/index.js"
|
|
77
76
|
},
|
|
78
|
-
"//": "sk test-env locale to catch locale-specific sorting",
|
|
79
77
|
"tap": {
|
|
80
|
-
"color": true,
|
|
81
78
|
"after": "test/fixtures/cleanup.js",
|
|
82
79
|
"test-env": [
|
|
83
|
-
"NODE_OPTIONS=--no-warnings",
|
|
84
80
|
"LC_ALL=sk"
|
|
85
81
|
],
|
|
86
|
-
"
|
|
87
|
-
"--no-warnings",
|
|
88
|
-
"--no-deprecation"
|
|
89
|
-
],
|
|
82
|
+
"color": 1,
|
|
90
83
|
"timeout": "360",
|
|
91
84
|
"nyc-arg": [
|
|
92
85
|
"--exclude",
|
|
@@ -98,7 +91,7 @@
|
|
|
98
91
|
},
|
|
99
92
|
"templateOSS": {
|
|
100
93
|
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
|
101
|
-
"version": "4.
|
|
94
|
+
"version": "4.14.1",
|
|
102
95
|
"content": "../../scripts/template-oss/index.js"
|
|
103
96
|
}
|
|
104
97
|
}
|