@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/edge.js
CHANGED
|
@@ -4,194 +4,210 @@
|
|
|
4
4
|
const util = require('util')
|
|
5
5
|
const npa = require('npm-package-arg')
|
|
6
6
|
const depValid = require('./dep-valid.js')
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return Object.assign(new ArboristEdge(), {
|
|
35
|
-
name: edge.name,
|
|
36
|
-
spec: edge.spec,
|
|
37
|
-
type: edge.type,
|
|
38
|
-
...(edgeFrom != null ? { from: edgeFrom } : {}),
|
|
39
|
-
...(edgeTo ? { to: edgeTo } : {}),
|
|
40
|
-
...(edge.error ? { error: edge.error } : {}),
|
|
41
|
-
...(edge.peerConflicted ? { peerConflicted: true } : {}),
|
|
42
|
-
...(override ? { overridden: override } : {}),
|
|
43
|
-
})
|
|
7
|
+
|
|
8
|
+
class ArboristEdge {
|
|
9
|
+
constructor (edge) {
|
|
10
|
+
this.name = edge.name
|
|
11
|
+
this.spec = edge.spec
|
|
12
|
+
this.type = edge.type
|
|
13
|
+
|
|
14
|
+
const edgeFrom = edge.from?.location
|
|
15
|
+
const edgeTo = edge.to?.location
|
|
16
|
+
const override = edge.overrides?.value
|
|
17
|
+
|
|
18
|
+
if (edgeFrom != null) {
|
|
19
|
+
this.from = edgeFrom
|
|
20
|
+
}
|
|
21
|
+
if (edgeTo) {
|
|
22
|
+
this.to = edgeTo
|
|
23
|
+
}
|
|
24
|
+
if (edge.error) {
|
|
25
|
+
this.error = edge.error
|
|
26
|
+
}
|
|
27
|
+
if (edge.peerConflicted) {
|
|
28
|
+
this.peerConflicted = true
|
|
29
|
+
}
|
|
30
|
+
if (override) {
|
|
31
|
+
this.overridden = override
|
|
32
|
+
}
|
|
33
|
+
}
|
|
44
34
|
}
|
|
45
35
|
|
|
46
36
|
class Edge {
|
|
37
|
+
#accept
|
|
38
|
+
#error
|
|
39
|
+
#explanation
|
|
40
|
+
#from
|
|
41
|
+
#name
|
|
42
|
+
#spec
|
|
43
|
+
#to
|
|
44
|
+
#type
|
|
45
|
+
|
|
46
|
+
static types = Object.freeze([
|
|
47
|
+
'prod',
|
|
48
|
+
'dev',
|
|
49
|
+
'optional',
|
|
50
|
+
'peer',
|
|
51
|
+
'peerOptional',
|
|
52
|
+
'workspace',
|
|
53
|
+
])
|
|
54
|
+
|
|
55
|
+
// XXX where is this used?
|
|
56
|
+
static errors = Object.freeze([
|
|
57
|
+
'DETACHED',
|
|
58
|
+
'MISSING',
|
|
59
|
+
'PEER LOCAL',
|
|
60
|
+
'INVALID',
|
|
61
|
+
])
|
|
62
|
+
|
|
47
63
|
constructor (options) {
|
|
48
64
|
const { type, name, spec, accept, from, overrides } = options
|
|
49
65
|
|
|
66
|
+
// XXX are all of these error states even possible?
|
|
50
67
|
if (typeof spec !== 'string') {
|
|
51
68
|
throw new TypeError('must provide string spec')
|
|
52
69
|
}
|
|
53
|
-
|
|
70
|
+
if (!Edge.types.includes(type)) {
|
|
71
|
+
throw new TypeError(`invalid type: ${type}\n(valid types are: ${Edge.types.join(', ')})`)
|
|
72
|
+
}
|
|
54
73
|
if (type === 'workspace' && npa(spec).type !== 'directory') {
|
|
55
74
|
throw new TypeError('workspace edges must be a symlink')
|
|
56
75
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
|
|
76
|
+
if (typeof name !== 'string') {
|
|
77
|
+
throw new TypeError('must provide dependency name')
|
|
78
|
+
}
|
|
79
|
+
if (!from) {
|
|
80
|
+
throw new TypeError('must provide "from" node')
|
|
62
81
|
}
|
|
63
|
-
|
|
64
82
|
if (accept !== undefined) {
|
|
65
83
|
if (typeof accept !== 'string') {
|
|
66
84
|
throw new TypeError('accept field must be a string if provided')
|
|
67
85
|
}
|
|
68
|
-
this
|
|
86
|
+
this.#accept = accept || '*'
|
|
69
87
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
throw new TypeError('must provide dependency name')
|
|
88
|
+
if (overrides !== undefined) {
|
|
89
|
+
this.overrides = overrides
|
|
73
90
|
}
|
|
74
|
-
this[_name] = name
|
|
75
91
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
this
|
|
86
|
-
this[_error] = this[_loadError]()
|
|
92
|
+
this.#name = name
|
|
93
|
+
this.#type = type
|
|
94
|
+
this.#spec = spec
|
|
95
|
+
this.#explanation = null
|
|
96
|
+
this.#from = from
|
|
97
|
+
|
|
98
|
+
from.edgesOut.get(this.#name)?.detach()
|
|
99
|
+
from.addEdgeOut(this)
|
|
100
|
+
|
|
101
|
+
this.reload(true)
|
|
87
102
|
this.peerConflicted = false
|
|
88
103
|
}
|
|
89
104
|
|
|
90
105
|
satisfiedBy (node) {
|
|
91
|
-
if (node.name !== this
|
|
106
|
+
if (node.name !== this.#name) {
|
|
92
107
|
return false
|
|
93
108
|
}
|
|
94
109
|
|
|
95
110
|
// NOTE: this condition means we explicitly do not support overriding
|
|
96
111
|
// bundled or shrinkwrapped dependencies
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
: this.spec
|
|
100
|
-
return depValid(node, spec, this.accept, this.from)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
explain (seen = []) {
|
|
104
|
-
if (this[_explanation]) {
|
|
105
|
-
return this[_explanation]
|
|
112
|
+
if (node.hasShrinkwrap || node.inShrinkwrap || node.inBundle) {
|
|
113
|
+
return depValid(node, this.rawSpec, this.#accept, this.#from)
|
|
106
114
|
}
|
|
107
|
-
|
|
108
|
-
return this[_explanation] = this[_explain](seen)
|
|
115
|
+
return depValid(node, this.spec, this.#accept, this.#from)
|
|
109
116
|
}
|
|
110
117
|
|
|
111
118
|
// return the edge data, and an explanation of how that edge came to be here
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
explain (seen = []) {
|
|
120
|
+
if (!this.#explanation) {
|
|
121
|
+
const explanation = {
|
|
122
|
+
type: this.#type,
|
|
123
|
+
name: this.#name,
|
|
124
|
+
spec: this.spec,
|
|
125
|
+
}
|
|
126
|
+
if (this.rawSpec !== this.spec) {
|
|
127
|
+
explanation.rawSpec = this.rawSpec
|
|
128
|
+
explanation.overridden = true
|
|
129
|
+
}
|
|
130
|
+
if (this.bundled) {
|
|
131
|
+
explanation.bundled = this.bundled
|
|
132
|
+
}
|
|
133
|
+
if (this.error) {
|
|
134
|
+
explanation.error = this.error
|
|
135
|
+
}
|
|
136
|
+
if (this.#from) {
|
|
137
|
+
explanation.from = this.#from.explain(null, seen)
|
|
138
|
+
}
|
|
139
|
+
this.#explanation = explanation
|
|
125
140
|
}
|
|
141
|
+
return this.#explanation
|
|
126
142
|
}
|
|
127
143
|
|
|
128
144
|
get bundled () {
|
|
129
|
-
|
|
130
|
-
return false
|
|
131
|
-
}
|
|
132
|
-
const { package: { bundleDependencies = [] } } = this.from
|
|
133
|
-
return bundleDependencies.includes(this.name)
|
|
145
|
+
return !!this.#from?.package?.bundleDependencies?.includes(this.#name)
|
|
134
146
|
}
|
|
135
147
|
|
|
136
148
|
get workspace () {
|
|
137
|
-
return this
|
|
149
|
+
return this.#type === 'workspace'
|
|
138
150
|
}
|
|
139
151
|
|
|
140
152
|
get prod () {
|
|
141
|
-
return this
|
|
153
|
+
return this.#type === 'prod'
|
|
142
154
|
}
|
|
143
155
|
|
|
144
156
|
get dev () {
|
|
145
|
-
return this
|
|
157
|
+
return this.#type === 'dev'
|
|
146
158
|
}
|
|
147
159
|
|
|
148
160
|
get optional () {
|
|
149
|
-
return this
|
|
161
|
+
return this.#type === 'optional' || this.#type === 'peerOptional'
|
|
150
162
|
}
|
|
151
163
|
|
|
152
164
|
get peer () {
|
|
153
|
-
return this
|
|
165
|
+
return this.#type === 'peer' || this.#type === 'peerOptional'
|
|
154
166
|
}
|
|
155
167
|
|
|
156
168
|
get type () {
|
|
157
|
-
return this
|
|
169
|
+
return this.#type
|
|
158
170
|
}
|
|
159
171
|
|
|
160
172
|
get name () {
|
|
161
|
-
return this
|
|
173
|
+
return this.#name
|
|
162
174
|
}
|
|
163
175
|
|
|
164
176
|
get rawSpec () {
|
|
165
|
-
return this
|
|
177
|
+
return this.#spec
|
|
166
178
|
}
|
|
167
179
|
|
|
168
180
|
get spec () {
|
|
169
|
-
if (this.overrides?.value && this.overrides.value !== '*' && this.overrides.name === this
|
|
181
|
+
if (this.overrides?.value && this.overrides.value !== '*' && this.overrides.name === this.#name) {
|
|
170
182
|
if (this.overrides.value.startsWith('$')) {
|
|
171
183
|
const ref = this.overrides.value.slice(1)
|
|
172
184
|
// we may be a virtual root, if we are we want to resolve reference overrides
|
|
173
185
|
// from the real root, not the virtual one
|
|
174
|
-
const pkg = this
|
|
175
|
-
? this
|
|
176
|
-
: this
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
186
|
+
const pkg = this.#from.sourceReference
|
|
187
|
+
? this.#from.sourceReference.root.package
|
|
188
|
+
: this.#from.root.package
|
|
189
|
+
if (pkg.devDependencies?.[ref]) {
|
|
190
|
+
return pkg.devDependencies[ref]
|
|
191
|
+
}
|
|
192
|
+
if (pkg.optionalDependencies?.[ref]) {
|
|
193
|
+
return pkg.optionalDependencies[ref]
|
|
194
|
+
}
|
|
195
|
+
if (pkg.dependencies?.[ref]) {
|
|
196
|
+
return pkg.dependencies[ref]
|
|
197
|
+
}
|
|
198
|
+
if (pkg.peerDependencies?.[ref]) {
|
|
199
|
+
return pkg.peerDependencies[ref]
|
|
184
200
|
}
|
|
185
201
|
|
|
186
202
|
throw new Error(`Unable to resolve reference ${this.overrides.value}`)
|
|
187
203
|
}
|
|
188
204
|
return this.overrides.value
|
|
189
205
|
}
|
|
190
|
-
return this
|
|
206
|
+
return this.#spec
|
|
191
207
|
}
|
|
192
208
|
|
|
193
209
|
get accept () {
|
|
194
|
-
return this
|
|
210
|
+
return this.#accept
|
|
195
211
|
}
|
|
196
212
|
|
|
197
213
|
get valid () {
|
|
@@ -211,71 +227,70 @@ class Edge {
|
|
|
211
227
|
}
|
|
212
228
|
|
|
213
229
|
get error () {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
230
|
+
if (!this.#error) {
|
|
231
|
+
if (!this.#to) {
|
|
232
|
+
if (this.optional) {
|
|
233
|
+
this.#error = null
|
|
234
|
+
} else {
|
|
235
|
+
this.#error = 'MISSING'
|
|
236
|
+
}
|
|
237
|
+
} else if (this.peer && this.#from === this.#to.parent && !this.#from.isTop) {
|
|
238
|
+
this.#error = 'PEER LOCAL'
|
|
239
|
+
} else if (!this.satisfiedBy(this.#to)) {
|
|
240
|
+
this.#error = 'INVALID'
|
|
241
|
+
} else {
|
|
242
|
+
this.#error = 'OK'
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (this.#error === 'OK') {
|
|
246
|
+
return null
|
|
247
|
+
}
|
|
248
|
+
return this.#error
|
|
223
249
|
}
|
|
224
250
|
|
|
225
251
|
reload (hard = false) {
|
|
226
|
-
this
|
|
227
|
-
if (this
|
|
228
|
-
this.overrides = this
|
|
252
|
+
this.#explanation = null
|
|
253
|
+
if (this.#from.overrides) {
|
|
254
|
+
this.overrides = this.#from.overrides.getEdgeRule(this)
|
|
229
255
|
} else {
|
|
230
256
|
delete this.overrides
|
|
231
257
|
}
|
|
232
|
-
const newTo = this
|
|
233
|
-
if (newTo !== this
|
|
234
|
-
if (this
|
|
235
|
-
this
|
|
258
|
+
const newTo = this.#from.resolve(this.#name)
|
|
259
|
+
if (newTo !== this.#to) {
|
|
260
|
+
if (this.#to) {
|
|
261
|
+
this.#to.edgesIn.delete(this)
|
|
236
262
|
}
|
|
237
|
-
this
|
|
238
|
-
this
|
|
239
|
-
if (this
|
|
240
|
-
this
|
|
263
|
+
this.#to = newTo
|
|
264
|
+
this.#error = null
|
|
265
|
+
if (this.#to) {
|
|
266
|
+
this.#to.addEdgeIn(this)
|
|
241
267
|
}
|
|
242
268
|
} else if (hard) {
|
|
243
|
-
this
|
|
269
|
+
this.#error = null
|
|
244
270
|
}
|
|
245
271
|
}
|
|
246
272
|
|
|
247
273
|
detach () {
|
|
248
|
-
this
|
|
249
|
-
if (this
|
|
250
|
-
this
|
|
274
|
+
this.#explanation = null
|
|
275
|
+
if (this.#to) {
|
|
276
|
+
this.#to.edgesIn.delete(this)
|
|
251
277
|
}
|
|
252
|
-
this
|
|
253
|
-
this
|
|
254
|
-
this
|
|
255
|
-
this
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
[_setFrom] (node) {
|
|
259
|
-
this[_explanation] = null
|
|
260
|
-
this[_from] = node
|
|
261
|
-
if (node.edgesOut.has(this.name)) {
|
|
262
|
-
node.edgesOut.get(this.name).detach()
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
node.addEdgeOut(this)
|
|
266
|
-
this.reload()
|
|
278
|
+
this.#from.edgesOut.delete(this.#name)
|
|
279
|
+
this.#to = null
|
|
280
|
+
this.#error = 'DETACHED'
|
|
281
|
+
this.#from = null
|
|
267
282
|
}
|
|
268
283
|
|
|
269
284
|
get from () {
|
|
270
|
-
return this
|
|
285
|
+
return this.#from
|
|
271
286
|
}
|
|
272
287
|
|
|
273
288
|
get to () {
|
|
274
|
-
return this
|
|
289
|
+
return this.#to
|
|
275
290
|
}
|
|
276
291
|
|
|
277
292
|
toJSON () {
|
|
278
|
-
return
|
|
293
|
+
return new ArboristEdge(this)
|
|
279
294
|
}
|
|
280
295
|
|
|
281
296
|
[util.inspect.custom] () {
|
|
@@ -283,12 +298,4 @@ class Edge {
|
|
|
283
298
|
}
|
|
284
299
|
}
|
|
285
300
|
|
|
286
|
-
Edge.types = [...types]
|
|
287
|
-
Edge.errors = [
|
|
288
|
-
'DETACHED',
|
|
289
|
-
'MISSING',
|
|
290
|
-
'PEER LOCAL',
|
|
291
|
-
'INVALID',
|
|
292
|
-
]
|
|
293
|
-
|
|
294
301
|
module.exports = Edge
|
package/lib/from-path.js
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
|
-
// file dependencies need their dependencies resolved based on the
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
1
|
+
// file dependencies need their dependencies resolved based on the location
|
|
2
|
+
// where the tarball was found, not the location where they end up getting
|
|
3
|
+
// installed. directory (ie, symlink) deps also need to be resolved based on
|
|
4
|
+
// their targets, but that's what realpath is
|
|
5
5
|
|
|
6
6
|
const { dirname } = require('path')
|
|
7
7
|
const npa = require('npm-package-arg')
|
|
8
8
|
|
|
9
|
-
const fromPath = (node,
|
|
9
|
+
const fromPath = (node, edge) => {
|
|
10
10
|
if (edge && edge.overrides && edge.overrides.name === edge.name && edge.overrides.value) {
|
|
11
|
-
// fromPath could be called with a node that has a virtual root, if that
|
|
12
|
-
// we want to make sure we get the real root node when overrides
|
|
13
|
-
// is to allow things like overriding a dependency with a
|
|
14
|
-
// relative path from the project root
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
// fromPath could be called with a node that has a virtual root, if that
|
|
12
|
+
// happens we want to make sure we get the real root node when overrides
|
|
13
|
+
// are in use. this is to allow things like overriding a dependency with a
|
|
14
|
+
// tarball file that's a relative path from the project root
|
|
15
|
+
if (node.sourceReference) {
|
|
16
|
+
return node.sourceReference.root.realpath
|
|
17
|
+
}
|
|
18
|
+
return node.root.realpath
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
if (node.resolved) {
|
|
22
|
+
const spec = npa(node.resolved)
|
|
23
|
+
if (spec?.type === 'file') {
|
|
24
|
+
return dirname(spec.fetchSpec)
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return node.realpath
|
|
22
28
|
}
|
|
23
29
|
|
|
24
|
-
module.exports =
|
|
30
|
+
module.exports = fromPath
|
package/lib/inventory.js
CHANGED
|
@@ -1,45 +1,28 @@
|
|
|
1
|
-
// a class to manage an inventory and set of indexes of
|
|
2
|
-
//
|
|
3
|
-
// primary is the primary index key.
|
|
4
|
-
// keys is the set of fields to be able to query.
|
|
5
|
-
const _primaryKey = Symbol('_primaryKey')
|
|
6
|
-
const _index = Symbol('_index')
|
|
7
|
-
const defaultKeys = ['name', 'license', 'funding', 'realpath', 'packageName']
|
|
1
|
+
// a class to manage an inventory and set of indexes of a set of objects based
|
|
2
|
+
// on specific fields.
|
|
8
3
|
const { hasOwnProperty } = Object.prototype
|
|
9
4
|
const debug = require('./debug.js')
|
|
10
5
|
|
|
11
|
-
|
|
12
|
-
// also support the alternative spelling "licence"
|
|
13
|
-
const getLicense = pkg => {
|
|
14
|
-
if (pkg) {
|
|
15
|
-
const lic = pkg.license || pkg.licence
|
|
16
|
-
if (lic) {
|
|
17
|
-
return lic
|
|
18
|
-
}
|
|
19
|
-
const lics = pkg.licenses || pkg.licences
|
|
20
|
-
if (Array.isArray(lics)) {
|
|
21
|
-
return lics[0]
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
6
|
+
const keys = ['name', 'license', 'funding', 'realpath', 'packageName']
|
|
26
7
|
class Inventory extends Map {
|
|
27
|
-
|
|
28
|
-
|
|
8
|
+
#index
|
|
9
|
+
|
|
10
|
+
constructor () {
|
|
29
11
|
super()
|
|
30
|
-
this
|
|
31
|
-
|
|
32
|
-
index.set(
|
|
33
|
-
|
|
34
|
-
}, new Map())
|
|
12
|
+
this.#index = new Map()
|
|
13
|
+
for (const key of keys) {
|
|
14
|
+
this.#index.set(key, new Map())
|
|
15
|
+
}
|
|
35
16
|
}
|
|
36
17
|
|
|
18
|
+
// XXX where is this used?
|
|
37
19
|
get primaryKey () {
|
|
38
|
-
return
|
|
20
|
+
return 'location'
|
|
39
21
|
}
|
|
40
22
|
|
|
23
|
+
// XXX where is this used?
|
|
41
24
|
get indexes () {
|
|
42
|
-
return [...
|
|
25
|
+
return [...keys]
|
|
43
26
|
}
|
|
44
27
|
|
|
45
28
|
* filter (fn) {
|
|
@@ -63,28 +46,49 @@ class Inventory extends Map {
|
|
|
63
46
|
return
|
|
64
47
|
}
|
|
65
48
|
|
|
66
|
-
const current = super.get(node
|
|
49
|
+
const current = super.get(node.location)
|
|
67
50
|
if (current) {
|
|
68
51
|
if (current === node) {
|
|
69
52
|
return
|
|
70
53
|
}
|
|
71
54
|
this.delete(current)
|
|
72
55
|
}
|
|
73
|
-
super.set(node
|
|
74
|
-
for (const [key, map] of this
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
56
|
+
super.set(node.location, node)
|
|
57
|
+
for (const [key, map] of this.#index.entries()) {
|
|
58
|
+
let val
|
|
59
|
+
if (hasOwnProperty.call(node, key)) {
|
|
60
|
+
// if the node has the value, use it even if it's false
|
|
61
|
+
val = node[key]
|
|
62
|
+
} else if (key === 'license' && node.package) {
|
|
63
|
+
// handling for the outdated "licenses" array, just pick the first one
|
|
64
|
+
// also support the alternative spelling "licence"
|
|
65
|
+
if (node.package.license) {
|
|
66
|
+
val = node.package.license
|
|
67
|
+
} else if (node.package.licence) {
|
|
68
|
+
val = node.package.licence
|
|
69
|
+
} else if (Array.isArray(node.package.licenses)) {
|
|
70
|
+
val = node.package.licenses[0]
|
|
71
|
+
} else if (Array.isArray(node.package.licences)) {
|
|
72
|
+
val = node.package.licences[0]
|
|
73
|
+
}
|
|
74
|
+
} else if (node[key]) {
|
|
75
|
+
val = node[key]
|
|
76
|
+
} else {
|
|
77
|
+
val = node.package?.[key]
|
|
78
|
+
}
|
|
79
|
+
if (val && typeof val === 'object') {
|
|
80
|
+
// We currently only use license and funding
|
|
81
|
+
/* istanbul ignore next - not used */
|
|
82
|
+
if (key === 'license') {
|
|
83
|
+
val = val.type
|
|
84
|
+
} else if (key === 'funding') {
|
|
85
|
+
val = val.url
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (!map.has(val)) {
|
|
89
|
+
map.set(val, new Set())
|
|
90
|
+
}
|
|
91
|
+
map.get(val).add(node)
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
|
|
@@ -93,10 +97,14 @@ class Inventory extends Map {
|
|
|
93
97
|
return
|
|
94
98
|
}
|
|
95
99
|
|
|
96
|
-
super.delete(node
|
|
97
|
-
for (const [key, map] of this
|
|
98
|
-
|
|
99
|
-
|
|
100
|
+
super.delete(node.location)
|
|
101
|
+
for (const [key, map] of this.#index.entries()) {
|
|
102
|
+
let val
|
|
103
|
+
if (node[key] !== undefined) {
|
|
104
|
+
val = node[key]
|
|
105
|
+
} else {
|
|
106
|
+
val = node.package?.[key]
|
|
107
|
+
}
|
|
100
108
|
const set = map.get(val)
|
|
101
109
|
if (set) {
|
|
102
110
|
set.delete(node)
|
|
@@ -108,13 +116,18 @@ class Inventory extends Map {
|
|
|
108
116
|
}
|
|
109
117
|
|
|
110
118
|
query (key, val) {
|
|
111
|
-
const map = this
|
|
112
|
-
|
|
113
|
-
|
|
119
|
+
const map = this.#index.get(key)
|
|
120
|
+
if (arguments.length === 2) {
|
|
121
|
+
if (map.has(val)) {
|
|
122
|
+
return map.get(val)
|
|
123
|
+
}
|
|
124
|
+
return new Set()
|
|
125
|
+
}
|
|
126
|
+
return map.keys()
|
|
114
127
|
}
|
|
115
128
|
|
|
116
129
|
has (node) {
|
|
117
|
-
return super.get(node
|
|
130
|
+
return super.get(node.location) === node
|
|
118
131
|
}
|
|
119
132
|
|
|
120
133
|
set (k, v) {
|