@npmcli/arborist 2.8.2 → 2.8.3
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/bin/actual.js +4 -2
- package/bin/audit.js +12 -6
- package/bin/dedupe.js +6 -3
- package/bin/funding.js +4 -2
- package/bin/ideal.js +2 -1
- package/bin/lib/logging.js +4 -3
- package/bin/lib/options.js +14 -12
- package/bin/lib/timers.js +6 -3
- package/bin/license.js +9 -5
- package/bin/prune.js +6 -3
- package/bin/reify.js +6 -3
- package/bin/virtual.js +4 -2
- package/lib/add-rm-pkg-deps.js +25 -14
- package/lib/arborist/audit.js +2 -1
- package/lib/arborist/build-ideal-tree.js +129 -68
- package/lib/arborist/deduper.js +2 -1
- package/lib/arborist/index.js +8 -4
- package/lib/arborist/load-actual.js +28 -13
- package/lib/arborist/load-virtual.js +34 -18
- package/lib/arborist/load-workspaces.js +4 -2
- package/lib/arborist/rebuild.js +31 -16
- package/lib/arborist/reify.js +153 -76
- package/lib/audit-report.js +42 -22
- package/lib/calc-dep-flags.js +18 -9
- package/lib/can-place-dep.js +56 -28
- package/lib/case-insensitive-map.js +4 -2
- package/lib/consistent-resolve.js +2 -1
- package/lib/deepest-nesting-target.js +4 -2
- package/lib/dep-valid.js +8 -4
- package/lib/diff.js +74 -22
- package/lib/edge.js +26 -13
- package/lib/gather-dep-set.js +2 -1
- package/lib/inventory.js +12 -6
- package/lib/link.js +14 -9
- package/lib/node.js +216 -113
- package/lib/optional-set.js +4 -2
- package/lib/peer-entry-sets.js +10 -5
- package/lib/place-dep.js +56 -29
- package/lib/printable.js +41 -21
- package/lib/realpath.js +12 -6
- package/lib/shrinkwrap.js +162 -89
- package/lib/signal-handling.js +6 -3
- package/lib/spec-from-lock.js +7 -4
- package/lib/tracker.js +24 -18
- package/lib/tree-check.js +12 -6
- package/lib/version-from-tgz.js +4 -2
- package/lib/vuln.js +28 -16
- package/lib/yarn-lock.js +27 -15
- package/package.json +7 -10
|
@@ -137,8 +137,9 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
137
137
|
this[_globalStyle] = this[_global] || globalStyle
|
|
138
138
|
this[_follow] = !!follow
|
|
139
139
|
|
|
140
|
-
if (this[_workspaces].length && this[_global])
|
|
140
|
+
if (this[_workspaces].length && this[_global]) {
|
|
141
141
|
throw new Error('Cannot operate on workspaces in global mode')
|
|
142
|
+
}
|
|
142
143
|
|
|
143
144
|
this[_explicitRequests] = new Set()
|
|
144
145
|
this[_preferDedupe] = false
|
|
@@ -168,18 +169,21 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
168
169
|
|
|
169
170
|
// public method
|
|
170
171
|
async buildIdealTree (options = {}) {
|
|
171
|
-
if (this.idealTree)
|
|
172
|
+
if (this.idealTree) {
|
|
172
173
|
return Promise.resolve(this.idealTree)
|
|
174
|
+
}
|
|
173
175
|
|
|
174
176
|
// allow the user to set reify options on the ctor as well.
|
|
175
177
|
// XXX: deprecate separate reify() options object.
|
|
176
178
|
options = { ...this.options, ...options }
|
|
177
179
|
|
|
178
180
|
// an empty array or any falsey value is the same as null
|
|
179
|
-
if (!options.add || options.add.length === 0)
|
|
181
|
+
if (!options.add || options.add.length === 0) {
|
|
180
182
|
options.add = null
|
|
181
|
-
|
|
183
|
+
}
|
|
184
|
+
if (!options.rm || options.rm.length === 0) {
|
|
182
185
|
options.rm = null
|
|
186
|
+
}
|
|
183
187
|
|
|
184
188
|
process.emit('time', 'idealTree')
|
|
185
189
|
|
|
@@ -230,11 +234,12 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
230
234
|
|
|
231
235
|
[_checkEngine] (node) {
|
|
232
236
|
const { engineStrict, npmVersion, nodeVersion } = this.options
|
|
233
|
-
const c = () =>
|
|
237
|
+
const c = () =>
|
|
238
|
+
checkEngine(node.package, npmVersion, nodeVersion, this[_force])
|
|
234
239
|
|
|
235
|
-
if (engineStrict)
|
|
240
|
+
if (engineStrict) {
|
|
236
241
|
c()
|
|
237
|
-
else {
|
|
242
|
+
} else {
|
|
238
243
|
try {
|
|
239
244
|
c()
|
|
240
245
|
} catch (er) {
|
|
@@ -252,8 +257,9 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
252
257
|
: Array.isArray(options.update) ? { names: options.update }
|
|
253
258
|
: options.update || {}
|
|
254
259
|
|
|
255
|
-
if (update.all || !Array.isArray(update.names))
|
|
260
|
+
if (update.all || !Array.isArray(update.names)) {
|
|
256
261
|
update.names = []
|
|
262
|
+
}
|
|
257
263
|
|
|
258
264
|
this[_complete] = !!options.complete
|
|
259
265
|
this[_preferDedupe] = !!options.preferDedupe
|
|
@@ -283,8 +289,9 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
283
289
|
: rpj(this.path + '/package.json').then(
|
|
284
290
|
pkg => this[_rootNodeFromPackage](pkg),
|
|
285
291
|
er => {
|
|
286
|
-
if (er.code === 'EJSONPARSE')
|
|
292
|
+
if (er.code === 'EJSONPARSE') {
|
|
287
293
|
throw er
|
|
294
|
+
}
|
|
288
295
|
return this[_rootNodeFromPackage]({})
|
|
289
296
|
}
|
|
290
297
|
))
|
|
@@ -312,8 +319,9 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
312
319
|
// even though we didn't load it from a package-lock.json FILE,
|
|
313
320
|
// we still loaded it "from disk", meaning we have to reset
|
|
314
321
|
// dep flags before assuming that any mutations were reflected.
|
|
315
|
-
if (tree.children.size)
|
|
322
|
+
if (tree.children.size) {
|
|
316
323
|
root.meta.loadedFromDisk = true
|
|
324
|
+
}
|
|
317
325
|
}
|
|
318
326
|
return root
|
|
319
327
|
})
|
|
@@ -382,9 +390,9 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
382
390
|
process.emit('time', 'idealTree:userRequests')
|
|
383
391
|
const tree = this.idealTree.target
|
|
384
392
|
|
|
385
|
-
if (!this[_workspaces].length)
|
|
393
|
+
if (!this[_workspaces].length) {
|
|
386
394
|
await this[_applyUserRequestsToNode](tree, options)
|
|
387
|
-
else {
|
|
395
|
+
} else {
|
|
388
396
|
await Promise.all(this.workspaceNodes(tree, this[_workspaces])
|
|
389
397
|
.map(node => this[_applyUserRequestsToNode](node, options)))
|
|
390
398
|
}
|
|
@@ -396,8 +404,9 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
396
404
|
// If we have a list of package names to update, and we know it's
|
|
397
405
|
// going to update them wherever they are, add any paths into those
|
|
398
406
|
// named nodes to the buildIdealTree queue.
|
|
399
|
-
if (!this[_global] && this[_updateNames].length)
|
|
407
|
+
if (!this[_global] && this[_updateNames].length) {
|
|
400
408
|
this[_queueNamedUpdates]()
|
|
409
|
+
}
|
|
401
410
|
|
|
402
411
|
// global updates only update the globalTop nodes, but we need to know
|
|
403
412
|
// that they're there, and not reinstall the world unnecessarily.
|
|
@@ -408,46 +417,55 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
408
417
|
tree.package.dependencies = tree.package.dependencies || {}
|
|
409
418
|
const updateName = this[_updateNames].includes(name)
|
|
410
419
|
if (this[_updateAll] || updateName) {
|
|
411
|
-
if (updateName)
|
|
420
|
+
if (updateName) {
|
|
412
421
|
globalExplicitUpdateNames.push(name)
|
|
422
|
+
}
|
|
413
423
|
const dir = resolve(nm, name)
|
|
414
|
-
const st = await lstat(dir)
|
|
424
|
+
const st = await lstat(dir)
|
|
425
|
+
.catch(/* istanbul ignore next */ er => null)
|
|
415
426
|
if (st && st.isSymbolicLink()) {
|
|
416
427
|
const target = await readlink(dir)
|
|
417
428
|
const real = resolve(dirname(dir), target)
|
|
418
429
|
tree.package.dependencies[name] = `file:${real}`
|
|
419
|
-
} else
|
|
430
|
+
} else {
|
|
420
431
|
tree.package.dependencies[name] = '*'
|
|
432
|
+
}
|
|
421
433
|
}
|
|
422
434
|
}
|
|
423
435
|
}
|
|
424
436
|
|
|
425
|
-
if (this.auditReport && this.auditReport.size > 0)
|
|
437
|
+
if (this.auditReport && this.auditReport.size > 0) {
|
|
426
438
|
await this[_queueVulnDependents](options)
|
|
439
|
+
}
|
|
427
440
|
|
|
428
441
|
const { add, rm } = options
|
|
429
442
|
|
|
430
443
|
if (rm && rm.length) {
|
|
431
444
|
addRmPkgDeps.rm(tree.package, rm)
|
|
432
|
-
for (const name of rm)
|
|
445
|
+
for (const name of rm) {
|
|
433
446
|
this[_explicitRequests].add({ from: tree, name, action: 'DELETE' })
|
|
447
|
+
}
|
|
434
448
|
}
|
|
435
449
|
|
|
436
|
-
if (add && add.length)
|
|
450
|
+
if (add && add.length) {
|
|
437
451
|
await this[_add](tree, options)
|
|
452
|
+
}
|
|
438
453
|
|
|
439
454
|
// triggers a refresh of all edgesOut. this has to be done BEFORE
|
|
440
455
|
// adding the edges to explicitRequests, because the package setter
|
|
441
456
|
// resets all edgesOut.
|
|
442
|
-
if (add && add.length || rm && rm.length || this[_global])
|
|
457
|
+
if (add && add.length || rm && rm.length || this[_global]) {
|
|
443
458
|
tree.package = tree.package
|
|
459
|
+
}
|
|
444
460
|
|
|
445
461
|
for (const spec of this[_resolvedAdd]) {
|
|
446
|
-
if (spec.tree === tree)
|
|
462
|
+
if (spec.tree === tree) {
|
|
447
463
|
this[_explicitRequests].add(tree.edgesOut.get(spec.name))
|
|
464
|
+
}
|
|
448
465
|
}
|
|
449
|
-
for (const name of globalExplicitUpdateNames)
|
|
466
|
+
for (const name of globalExplicitUpdateNames) {
|
|
450
467
|
this[_explicitRequests].add(tree.edgesOut.get(name))
|
|
468
|
+
}
|
|
451
469
|
|
|
452
470
|
this[_depsQueue].push(tree)
|
|
453
471
|
}
|
|
@@ -487,21 +505,24 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
487
505
|
// if it's an explicit tag, we need to install that specific tag version
|
|
488
506
|
const isTag = spec.rawSpec && spec.type === 'tag'
|
|
489
507
|
|
|
490
|
-
if (spec.name && !isTag)
|
|
508
|
+
if (spec.name && !isTag) {
|
|
491
509
|
return spec
|
|
510
|
+
}
|
|
492
511
|
|
|
493
512
|
const mani = await pacote.manifest(spec, { ...this.options })
|
|
494
513
|
// if it's a tag type, then we need to run it down to an actual version
|
|
495
|
-
if (isTag)
|
|
514
|
+
if (isTag) {
|
|
496
515
|
return npa(`${mani.name}@${mani.version}`)
|
|
516
|
+
}
|
|
497
517
|
|
|
498
518
|
spec.name = mani.name
|
|
499
519
|
return spec
|
|
500
520
|
}
|
|
501
521
|
|
|
502
522
|
async [_updateFilePath] (spec) {
|
|
503
|
-
if (spec.type === 'file')
|
|
523
|
+
if (spec.type === 'file') {
|
|
504
524
|
return this[_getRelpathSpec](spec, spec.fetchSpec)
|
|
525
|
+
}
|
|
505
526
|
|
|
506
527
|
return spec
|
|
507
528
|
}
|
|
@@ -601,8 +622,9 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
601
622
|
nodesTouched.add(node)
|
|
602
623
|
}
|
|
603
624
|
}
|
|
604
|
-
for (const node of nodesTouched)
|
|
625
|
+
for (const node of nodesTouched) {
|
|
605
626
|
node.package = node.package
|
|
627
|
+
}
|
|
606
628
|
}
|
|
607
629
|
}
|
|
608
630
|
|
|
@@ -611,11 +633,13 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
611
633
|
}
|
|
612
634
|
|
|
613
635
|
[_avoidRange] (name) {
|
|
614
|
-
if (!this.auditReport)
|
|
636
|
+
if (!this.auditReport) {
|
|
615
637
|
return null
|
|
638
|
+
}
|
|
616
639
|
const vuln = this.auditReport.get(name)
|
|
617
|
-
if (!vuln)
|
|
640
|
+
if (!vuln) {
|
|
618
641
|
return null
|
|
642
|
+
}
|
|
619
643
|
return vuln.range
|
|
620
644
|
}
|
|
621
645
|
|
|
@@ -652,8 +676,9 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
652
676
|
const ancient = meta.ancientLockfile
|
|
653
677
|
const old = meta.loadedFromDisk && !(meta.originalLockfileVersion >= 2)
|
|
654
678
|
|
|
655
|
-
if (inventory.size === 0 || !ancient && !old)
|
|
679
|
+
if (inventory.size === 0 || !ancient && !old) {
|
|
656
680
|
return
|
|
681
|
+
}
|
|
657
682
|
|
|
658
683
|
// if the lockfile is from node v5 or earlier, then we'll have to reload
|
|
659
684
|
// all the manifests of everything we encounter. this is costly, but at
|
|
@@ -672,8 +697,9 @@ This is a one-time fix-up, please be patient...
|
|
|
672
697
|
this.addTracker('idealTree:inflate')
|
|
673
698
|
const queue = []
|
|
674
699
|
for (const node of inventory.values()) {
|
|
675
|
-
if (node.isProjectRoot)
|
|
700
|
+
if (node.isProjectRoot) {
|
|
676
701
|
continue
|
|
702
|
+
}
|
|
677
703
|
|
|
678
704
|
queue.push(async () => {
|
|
679
705
|
this.log.silly('inflate', node.location)
|
|
@@ -738,8 +764,9 @@ This is a one-time fix-up, please be patient...
|
|
|
738
764
|
this[_currentDep] = null
|
|
739
765
|
}
|
|
740
766
|
|
|
741
|
-
if (!this[_depsQueue].length)
|
|
767
|
+
if (!this[_depsQueue].length) {
|
|
742
768
|
return this[_resolveLinks]()
|
|
769
|
+
}
|
|
743
770
|
|
|
744
771
|
// sort physically shallower deps up to the front of the queue,
|
|
745
772
|
// because they'll affect things deeper in, then alphabetical
|
|
@@ -757,8 +784,9 @@ This is a one-time fix-up, please be patient...
|
|
|
757
784
|
// satisfied by whatever's in that file anyway.
|
|
758
785
|
if (this[_depsSeen].has(node) ||
|
|
759
786
|
node.root !== this.idealTree ||
|
|
760
|
-
hasShrinkwrap && !this[_complete])
|
|
787
|
+
hasShrinkwrap && !this[_complete]) {
|
|
761
788
|
return this[_buildDepStep]()
|
|
789
|
+
}
|
|
762
790
|
|
|
763
791
|
this[_depsSeen].add(node)
|
|
764
792
|
this[_currentDep] = node
|
|
@@ -841,8 +869,9 @@ This is a one-time fix-up, please be patient...
|
|
|
841
869
|
const tasks = []
|
|
842
870
|
const peerSource = this[_peerSetSource].get(node) || node
|
|
843
871
|
for (const edge of this[_problemEdges](node)) {
|
|
844
|
-
if (edge.overridden)
|
|
872
|
+
if (edge.overridden) {
|
|
845
873
|
continue
|
|
874
|
+
}
|
|
846
875
|
|
|
847
876
|
// peerSetSource is only relevant when we have a peerEntryEdge
|
|
848
877
|
// otherwise we're setting regular non-peer deps as if they have
|
|
@@ -878,8 +907,9 @@ This is a one-time fix-up, please be patient...
|
|
|
878
907
|
|
|
879
908
|
/* istanbul ignore next */
|
|
880
909
|
debug(() => {
|
|
881
|
-
if (!dep)
|
|
910
|
+
if (!dep) {
|
|
882
911
|
throw new Error('no dep??')
|
|
912
|
+
}
|
|
883
913
|
})
|
|
884
914
|
|
|
885
915
|
tasks.push({edge, dep})
|
|
@@ -912,17 +942,20 @@ This is a one-time fix-up, please be patient...
|
|
|
912
942
|
visit: pd => {
|
|
913
943
|
const { placed, edge, canPlace: cpd } = pd
|
|
914
944
|
// if we didn't place anything, nothing to do here
|
|
915
|
-
if (!placed)
|
|
945
|
+
if (!placed) {
|
|
916
946
|
return
|
|
947
|
+
}
|
|
917
948
|
|
|
918
949
|
// we placed something, that means we changed the tree
|
|
919
|
-
if (placed.errors.length)
|
|
950
|
+
if (placed.errors.length) {
|
|
920
951
|
this[_loadFailures].add(placed)
|
|
952
|
+
}
|
|
921
953
|
this[_mutateTree] = true
|
|
922
954
|
if (cpd.canPlaceSelf === OK) {
|
|
923
955
|
for (const edgeIn of placed.edgesIn) {
|
|
924
|
-
if (edgeIn === edge)
|
|
956
|
+
if (edgeIn === edge) {
|
|
925
957
|
continue
|
|
958
|
+
}
|
|
926
959
|
const { from, valid, overridden } = edgeIn
|
|
927
960
|
if (!overridden && !valid && !this[_depsSeen].has(from)) {
|
|
928
961
|
this.addTracker('idealTree', from.name, from.location)
|
|
@@ -936,8 +969,9 @@ This is a one-time fix-up, please be patient...
|
|
|
936
969
|
// intentionally causing something to get nested which was
|
|
937
970
|
// previously placed in this location.
|
|
938
971
|
for (const edgeIn of placed.edgesIn) {
|
|
939
|
-
if (edgeIn === edge)
|
|
972
|
+
if (edgeIn === edge) {
|
|
940
973
|
continue
|
|
974
|
+
}
|
|
941
975
|
|
|
942
976
|
const { valid, overridden } = edgeIn
|
|
943
977
|
if (!valid && !overridden) {
|
|
@@ -975,8 +1009,9 @@ This is a one-time fix-up, please be patient...
|
|
|
975
1009
|
}
|
|
976
1010
|
|
|
977
1011
|
for (const { to } of node.edgesOut.values()) {
|
|
978
|
-
if (to && to.isLink && to.target)
|
|
1012
|
+
if (to && to.isLink && to.target) {
|
|
979
1013
|
this[_linkNodes].add(to)
|
|
1014
|
+
}
|
|
980
1015
|
}
|
|
981
1016
|
|
|
982
1017
|
await Promise.all(promises)
|
|
@@ -1019,8 +1054,9 @@ This is a one-time fix-up, please be patient...
|
|
|
1019
1054
|
|
|
1020
1055
|
if (required.has(edge.from) && edge.type !== 'peerOptional' ||
|
|
1021
1056
|
secondEdge && (
|
|
1022
|
-
required.has(secondEdge.from) && secondEdge.type !== 'peerOptional'))
|
|
1057
|
+
required.has(secondEdge.from) && secondEdge.type !== 'peerOptional')) {
|
|
1023
1058
|
required.add(node)
|
|
1059
|
+
}
|
|
1024
1060
|
|
|
1025
1061
|
// keep track of the thing that caused this node to be included.
|
|
1026
1062
|
const src = parent.sourceReference
|
|
@@ -1030,16 +1066,18 @@ This is a one-time fix-up, please be patient...
|
|
|
1030
1066
|
// otherwise we'll be tempted to put peers as other top-level installed
|
|
1031
1067
|
// things, potentially clobbering what's there already, which is not
|
|
1032
1068
|
// what we want. the missing edges will be picked up on the next pass.
|
|
1033
|
-
if (this[_global] && edge.from.isProjectRoot)
|
|
1069
|
+
if (this[_global] && edge.from.isProjectRoot) {
|
|
1034
1070
|
return node
|
|
1071
|
+
}
|
|
1035
1072
|
|
|
1036
1073
|
// otherwise, we have to make sure that our peers can go along with us.
|
|
1037
1074
|
return this[_loadPeerSet](node, required)
|
|
1038
1075
|
}
|
|
1039
1076
|
|
|
1040
1077
|
[_virtualRoot] (node, reuse = false) {
|
|
1041
|
-
if (reuse && this[_virtualRoots].has(node))
|
|
1078
|
+
if (reuse && this[_virtualRoots].has(node)) {
|
|
1042
1079
|
return this[_virtualRoots].get(node)
|
|
1080
|
+
}
|
|
1043
1081
|
|
|
1044
1082
|
const vr = new Node({
|
|
1045
1083
|
path: node.realpath,
|
|
@@ -1081,16 +1119,19 @@ This is a one-time fix-up, please be patient...
|
|
|
1081
1119
|
return [...node.edgesOut.values()]
|
|
1082
1120
|
.filter(edge => {
|
|
1083
1121
|
// If it's included in a bundle, we take whatever is specified.
|
|
1084
|
-
if (bundled.has(edge.name))
|
|
1122
|
+
if (bundled.has(edge.name)) {
|
|
1085
1123
|
return false
|
|
1124
|
+
}
|
|
1086
1125
|
|
|
1087
1126
|
// If it's already been logged as a load failure, skip it.
|
|
1088
|
-
if (edge.to && this[_loadFailures].has(edge.to))
|
|
1127
|
+
if (edge.to && this[_loadFailures].has(edge.to)) {
|
|
1089
1128
|
return false
|
|
1129
|
+
}
|
|
1090
1130
|
|
|
1091
1131
|
// If it's shrinkwrapped, we use what the shrinkwap wants.
|
|
1092
|
-
if (edge.to && edge.to.inShrinkwrap)
|
|
1132
|
+
if (edge.to && edge.to.inShrinkwrap) {
|
|
1093
1133
|
return false
|
|
1134
|
+
}
|
|
1094
1135
|
|
|
1095
1136
|
// If the edge has no destination, that's a problem, unless
|
|
1096
1137
|
// if it's peerOptional and not explicitly requested.
|
|
@@ -1100,20 +1141,24 @@ This is a one-time fix-up, please be patient...
|
|
|
1100
1141
|
}
|
|
1101
1142
|
|
|
1102
1143
|
// If the edge has an error, there's a problem.
|
|
1103
|
-
if (!edge.valid)
|
|
1144
|
+
if (!edge.valid) {
|
|
1104
1145
|
return true
|
|
1146
|
+
}
|
|
1105
1147
|
|
|
1106
|
-
//
|
|
1107
|
-
if (this[_updateNames].includes(edge.name))
|
|
1148
|
+
// user explicitly asked to update this package by name, problem
|
|
1149
|
+
if (this[_updateNames].includes(edge.name)) {
|
|
1108
1150
|
return true
|
|
1151
|
+
}
|
|
1109
1152
|
|
|
1110
|
-
//
|
|
1111
|
-
if (this[_isVulnerable](edge.to))
|
|
1153
|
+
// fixing a security vulnerability with this package, problem
|
|
1154
|
+
if (this[_isVulnerable](edge.to)) {
|
|
1112
1155
|
return true
|
|
1156
|
+
}
|
|
1113
1157
|
|
|
1114
|
-
//
|
|
1115
|
-
if (this[_explicitRequests].has(edge))
|
|
1158
|
+
// user has explicitly asked to install this package, problem
|
|
1159
|
+
if (this[_explicitRequests].has(edge)) {
|
|
1116
1160
|
return true
|
|
1161
|
+
}
|
|
1117
1162
|
|
|
1118
1163
|
// No problems!
|
|
1119
1164
|
return false
|
|
@@ -1129,9 +1174,9 @@ This is a one-time fix-up, please be patient...
|
|
|
1129
1174
|
// if available and valid.
|
|
1130
1175
|
spec = this.idealTree.meta.checkYarnLock(spec, options)
|
|
1131
1176
|
|
|
1132
|
-
if (this[_manifests].has(spec.raw))
|
|
1177
|
+
if (this[_manifests].has(spec.raw)) {
|
|
1133
1178
|
return this[_manifests].get(spec.raw)
|
|
1134
|
-
else {
|
|
1179
|
+
} else {
|
|
1135
1180
|
this.log.silly('fetch manifest', spec.raw)
|
|
1136
1181
|
const p = pacote.manifest(spec, options)
|
|
1137
1182
|
.then(mani => {
|
|
@@ -1201,8 +1246,9 @@ This is a one-time fix-up, please be patient...
|
|
|
1201
1246
|
|
|
1202
1247
|
for (const edge of peerEdges) {
|
|
1203
1248
|
// already placed this one, and we're happy with it.
|
|
1204
|
-
if (edge.valid && edge.to)
|
|
1249
|
+
if (edge.valid && edge.to) {
|
|
1205
1250
|
continue
|
|
1251
|
+
}
|
|
1206
1252
|
|
|
1207
1253
|
const parentEdge = node.parent.edgesOut.get(edge.name)
|
|
1208
1254
|
const {isProjectRoot, isWorkspace} = node.parent.sourceReference
|
|
@@ -1223,11 +1269,17 @@ This is a one-time fix-up, please be patient...
|
|
|
1223
1269
|
// a conflict. this is always a problem in strict mode, never
|
|
1224
1270
|
// in force mode, and a problem in non-strict mode if this isn't
|
|
1225
1271
|
// on behalf of our project. in all such cases, we warn at least.
|
|
1226
|
-
const dep = await this[_nodeFromEdge](
|
|
1272
|
+
const dep = await this[_nodeFromEdge](
|
|
1273
|
+
parentEdge,
|
|
1274
|
+
node.parent,
|
|
1275
|
+
edge,
|
|
1276
|
+
required
|
|
1277
|
+
)
|
|
1227
1278
|
|
|
1228
1279
|
// hooray! that worked!
|
|
1229
|
-
if (edge.valid)
|
|
1280
|
+
if (edge.valid) {
|
|
1230
1281
|
continue
|
|
1282
|
+
}
|
|
1231
1283
|
|
|
1232
1284
|
// allow it. either we're overriding, or it's not something
|
|
1233
1285
|
// that will be installed by default anyway, and we'll fail when
|
|
@@ -1260,8 +1312,9 @@ This is a one-time fix-up, please be patient...
|
|
|
1260
1312
|
// isn't also required, then there's a good chance we won't need it,
|
|
1261
1313
|
// so allow it for now and let it conflict if it turns out to actually
|
|
1262
1314
|
// be necessary for the installation.
|
|
1263
|
-
if (conflictOK || !required.has(edge.from))
|
|
1315
|
+
if (conflictOK || !required.has(edge.from)) {
|
|
1264
1316
|
continue
|
|
1317
|
+
}
|
|
1265
1318
|
|
|
1266
1319
|
// ok, it's the root, or we're in unforced strict mode, so this is bad
|
|
1267
1320
|
this[_failPeerConflict](edge, parentEdge)
|
|
@@ -1304,15 +1357,17 @@ This is a one-time fix-up, please be patient...
|
|
|
1304
1357
|
this[_linkNodes].delete(link)
|
|
1305
1358
|
|
|
1306
1359
|
// link we never ended up placing, skip it
|
|
1307
|
-
if (link.root !== this.idealTree)
|
|
1360
|
+
if (link.root !== this.idealTree) {
|
|
1308
1361
|
continue
|
|
1362
|
+
}
|
|
1309
1363
|
|
|
1310
1364
|
const tree = this.idealTree.target
|
|
1311
1365
|
const external = !link.target.isDescendantOf(tree)
|
|
1312
1366
|
|
|
1313
1367
|
// outside the root, somebody else's problem, ignore it
|
|
1314
|
-
if (external && !this[_follow])
|
|
1368
|
+
if (external && !this[_follow]) {
|
|
1315
1369
|
continue
|
|
1370
|
+
}
|
|
1316
1371
|
|
|
1317
1372
|
// didn't find a parent for it or it has not been seen yet
|
|
1318
1373
|
// so go ahead and process it.
|
|
@@ -1328,8 +1383,9 @@ This is a one-time fix-up, please be patient...
|
|
|
1328
1383
|
}
|
|
1329
1384
|
}
|
|
1330
1385
|
|
|
1331
|
-
if (this[_depsQueue].length)
|
|
1386
|
+
if (this[_depsQueue].length) {
|
|
1332
1387
|
return this[_buildDepStep]()
|
|
1388
|
+
}
|
|
1333
1389
|
}
|
|
1334
1390
|
|
|
1335
1391
|
[_fixDepFlags] () {
|
|
@@ -1344,8 +1400,9 @@ This is a one-time fix-up, please be patient...
|
|
|
1344
1400
|
// all set to true, and there can be nothing extraneous, so there's
|
|
1345
1401
|
// nothing to prune, because we built it from scratch. if we didn't
|
|
1346
1402
|
// add or remove anything, then also nothing to do.
|
|
1347
|
-
if (metaFromDisk && mutateTree)
|
|
1403
|
+
if (metaFromDisk && mutateTree) {
|
|
1348
1404
|
resetDepFlags(this.idealTree)
|
|
1405
|
+
}
|
|
1349
1406
|
|
|
1350
1407
|
// update all the dev/optional/etc flags in the tree
|
|
1351
1408
|
// either we started with a fresh tree, or we
|
|
@@ -1353,9 +1410,9 @@ This is a one-time fix-up, please be patient...
|
|
|
1353
1410
|
//
|
|
1354
1411
|
// if we started from a blank slate, or changed something, then
|
|
1355
1412
|
// the dep flags will be all set to true.
|
|
1356
|
-
if (!metaFromDisk || mutateTree)
|
|
1413
|
+
if (!metaFromDisk || mutateTree) {
|
|
1357
1414
|
calcDepFlags(this.idealTree)
|
|
1358
|
-
else {
|
|
1415
|
+
} else {
|
|
1359
1416
|
// otherwise just unset all the flags on the root node
|
|
1360
1417
|
// since they will sometimes have the default value
|
|
1361
1418
|
this.idealTree.extraneous = false
|
|
@@ -1370,25 +1427,29 @@ This is a one-time fix-up, please be patient...
|
|
|
1370
1427
|
// then the tree is suspect. Prune what is marked as extraneous.
|
|
1371
1428
|
// otherwise, don't bother.
|
|
1372
1429
|
const needPrune = metaFromDisk && (mutateTree || flagsSuspect)
|
|
1373
|
-
if (this[_prune] && needPrune)
|
|
1430
|
+
if (this[_prune] && needPrune) {
|
|
1374
1431
|
this[_idealTreePrune]()
|
|
1432
|
+
}
|
|
1375
1433
|
|
|
1376
1434
|
process.emit('timeEnd', 'idealTree:fixDepFlags')
|
|
1377
1435
|
}
|
|
1378
1436
|
|
|
1379
1437
|
[_idealTreePrune] () {
|
|
1380
|
-
for (const node of this.idealTree.inventory.filter(n => n.extraneous))
|
|
1438
|
+
for (const node of this.idealTree.inventory.filter(n => n.extraneous)) {
|
|
1381
1439
|
node.parent = null
|
|
1440
|
+
}
|
|
1382
1441
|
}
|
|
1383
1442
|
|
|
1384
1443
|
[_pruneFailedOptional] () {
|
|
1385
1444
|
for (const node of this[_loadFailures]) {
|
|
1386
|
-
if (!node.optional)
|
|
1445
|
+
if (!node.optional) {
|
|
1387
1446
|
throw node.errors[0]
|
|
1447
|
+
}
|
|
1388
1448
|
|
|
1389
1449
|
const set = optionalSet(node)
|
|
1390
|
-
for (const node of set)
|
|
1450
|
+
for (const node of set) {
|
|
1391
1451
|
node.parent = null
|
|
1452
|
+
}
|
|
1392
1453
|
}
|
|
1393
1454
|
}
|
|
1394
1455
|
}
|
package/lib/arborist/deduper.js
CHANGED
|
@@ -6,8 +6,9 @@ module.exports = cls => class Deduper extends cls {
|
|
|
6
6
|
const tree = await this.loadVirtual().catch(() => this.loadActual())
|
|
7
7
|
const names = []
|
|
8
8
|
for (const name of tree.inventory.query('name')) {
|
|
9
|
-
if (tree.inventory.query('name', name).size > 1)
|
|
9
|
+
if (tree.inventory.query('name', name).size > 1) {
|
|
10
10
|
names.push(name)
|
|
11
|
+
}
|
|
11
12
|
}
|
|
12
13
|
return this.reify({
|
|
13
14
|
...options,
|
package/lib/arborist/index.js
CHANGED
|
@@ -59,8 +59,9 @@ class Arborist extends Base {
|
|
|
59
59
|
packumentCache: options.packumentCache || new Map(),
|
|
60
60
|
log: options.log || procLog,
|
|
61
61
|
}
|
|
62
|
-
if (options.saveType && !saveTypeMap.get(options.saveType))
|
|
62
|
+
if (options.saveType && !saveTypeMap.get(options.saveType)) {
|
|
63
63
|
throw new Error(`Invalid saveType ${options.saveType}`)
|
|
64
|
+
}
|
|
64
65
|
this.cache = resolve(this.options.cache)
|
|
65
66
|
this.path = resolve(this.options.path)
|
|
66
67
|
process.emit('timeEnd', 'arborist:ctor')
|
|
@@ -81,17 +82,20 @@ class Arborist extends Base {
|
|
|
81
82
|
const dep = edge.to
|
|
82
83
|
if (dep) {
|
|
83
84
|
set.add(dep)
|
|
84
|
-
if (dep.isLink)
|
|
85
|
+
if (dep.isLink) {
|
|
85
86
|
set.add(dep.target)
|
|
87
|
+
}
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
for (const child of node.children.values()) {
|
|
89
|
-
if (child.extraneous)
|
|
91
|
+
if (child.extraneous) {
|
|
90
92
|
extraneous.add(child)
|
|
93
|
+
}
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
|
-
for (const extra of extraneous)
|
|
96
|
+
for (const extra of extraneous) {
|
|
94
97
|
set.add(extra)
|
|
98
|
+
}
|
|
95
99
|
return set
|
|
96
100
|
}
|
|
97
101
|
}
|