@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
package/lib/shrinkwrap.js
CHANGED
|
@@ -47,8 +47,9 @@ const readlink = promisify(fs.readlink)
|
|
|
47
47
|
const lstat = promisify(fs.lstat)
|
|
48
48
|
/* istanbul ignore next - version specific polyfill */
|
|
49
49
|
const readdir = async (path, opt) => {
|
|
50
|
-
if (!opt || !opt.withFileTypes)
|
|
50
|
+
if (!opt || !opt.withFileTypes) {
|
|
51
51
|
return readdir_(path, opt)
|
|
52
|
+
}
|
|
52
53
|
const ents = await readdir_(path, opt)
|
|
53
54
|
if (typeof ents[0] === 'string') {
|
|
54
55
|
return Promise.all(ents.map(async ent => {
|
|
@@ -97,20 +98,22 @@ const consistentResolve = require('./consistent-resolve.js')
|
|
|
97
98
|
const maybeReadFile = file => {
|
|
98
99
|
return readFile(file, 'utf8').then(d => d, er => {
|
|
99
100
|
/* istanbul ignore else - can't test without breaking module itself */
|
|
100
|
-
if (er.code === 'ENOENT')
|
|
101
|
+
if (er.code === 'ENOENT') {
|
|
101
102
|
return ''
|
|
102
|
-
else
|
|
103
|
+
} else {
|
|
103
104
|
throw er
|
|
105
|
+
}
|
|
104
106
|
})
|
|
105
107
|
}
|
|
106
108
|
|
|
107
109
|
const maybeStatFile = file => {
|
|
108
110
|
return stat(file).then(st => st.isFile(), er => {
|
|
109
111
|
/* istanbul ignore else - can't test without breaking module itself */
|
|
110
|
-
if (er.code === 'ENOENT')
|
|
112
|
+
if (er.code === 'ENOENT') {
|
|
111
113
|
return null
|
|
112
|
-
else
|
|
114
|
+
} else {
|
|
113
115
|
throw er
|
|
116
|
+
}
|
|
114
117
|
})
|
|
115
118
|
}
|
|
116
119
|
|
|
@@ -163,13 +166,16 @@ const assertNoNewer = async (path, data, lockTime, dir = path, seen = null) => {
|
|
|
163
166
|
const rel = relpath(path, dir)
|
|
164
167
|
if (dir !== path) {
|
|
165
168
|
const dirTime = (await stat(dir)).mtime
|
|
166
|
-
if (dirTime > lockTime)
|
|
169
|
+
if (dirTime > lockTime) {
|
|
167
170
|
throw 'out of date, updated: ' + rel
|
|
168
|
-
|
|
171
|
+
}
|
|
172
|
+
if (!isScope && !isNM && !data.packages[rel]) {
|
|
169
173
|
throw 'missing from lockfile: ' + rel
|
|
174
|
+
}
|
|
170
175
|
seen.add(rel)
|
|
171
|
-
} else
|
|
176
|
+
} else {
|
|
172
177
|
seen = new Set([rel])
|
|
178
|
+
}
|
|
173
179
|
|
|
174
180
|
const parent = isParent ? dir : resolve(dir, 'node_modules')
|
|
175
181
|
const children = dir === path
|
|
@@ -179,26 +185,29 @@ const assertNoNewer = async (path, data, lockTime, dir = path, seen = null) => {
|
|
|
179
185
|
return children.catch(() => [])
|
|
180
186
|
.then(ents => Promise.all(ents.map(async ent => {
|
|
181
187
|
const child = resolve(parent, ent.name)
|
|
182
|
-
if (ent.isDirectory() && !/^\./.test(ent.name))
|
|
188
|
+
if (ent.isDirectory() && !/^\./.test(ent.name)) {
|
|
183
189
|
await assertNoNewer(path, data, lockTime, child, seen)
|
|
184
|
-
else if (ent.isSymbolicLink()) {
|
|
190
|
+
} else if (ent.isSymbolicLink()) {
|
|
185
191
|
const target = resolve(parent, await readlink(child))
|
|
186
192
|
const tstat = await stat(target).catch(
|
|
187
193
|
/* istanbul ignore next - windows */ () => null)
|
|
188
194
|
seen.add(relpath(path, child))
|
|
189
195
|
/* istanbul ignore next - windows cannot do this */
|
|
190
|
-
if (tstat && tstat.isDirectory() && !seen.has(relpath(path, target)))
|
|
196
|
+
if (tstat && tstat.isDirectory() && !seen.has(relpath(path, target))) {
|
|
191
197
|
await assertNoNewer(path, data, lockTime, target, seen)
|
|
198
|
+
}
|
|
192
199
|
}
|
|
193
200
|
})))
|
|
194
201
|
.then(() => {
|
|
195
|
-
if (dir !== path)
|
|
202
|
+
if (dir !== path) {
|
|
196
203
|
return
|
|
204
|
+
}
|
|
197
205
|
|
|
198
206
|
// assert that all the entries in the lockfile were seen
|
|
199
207
|
for (const loc of new Set(Object.keys(data.packages))) {
|
|
200
|
-
if (!seen.has(loc))
|
|
208
|
+
if (!seen.has(loc)) {
|
|
201
209
|
throw 'missing from node_modules: ' + loc
|
|
210
|
+
}
|
|
202
211
|
}
|
|
203
212
|
})
|
|
204
213
|
}
|
|
@@ -252,39 +261,48 @@ class Shrinkwrap {
|
|
|
252
261
|
const meta = {}
|
|
253
262
|
pkgMetaKeys.forEach(key => {
|
|
254
263
|
const val = metaFieldFromPkg(node.package, key)
|
|
255
|
-
if (val)
|
|
264
|
+
if (val) {
|
|
256
265
|
meta[key.replace(/^_/, '')] = val
|
|
266
|
+
}
|
|
257
267
|
})
|
|
258
268
|
// we only include name if different from the node path name, and for the
|
|
259
269
|
// root to help prevent churn based on the name of the directory the
|
|
260
270
|
// project is in
|
|
261
271
|
const pname = node.packageName
|
|
262
|
-
if (pname && (node === node.root || pname !== node.name))
|
|
272
|
+
if (pname && (node === node.root || pname !== node.name)) {
|
|
263
273
|
meta.name = pname
|
|
274
|
+
}
|
|
264
275
|
|
|
265
|
-
if (node.isTop && node.package.devDependencies)
|
|
276
|
+
if (node.isTop && node.package.devDependencies) {
|
|
266
277
|
meta.devDependencies = node.package.devDependencies
|
|
278
|
+
}
|
|
267
279
|
|
|
268
280
|
nodeMetaKeys.forEach(key => {
|
|
269
|
-
if (node[key])
|
|
281
|
+
if (node[key]) {
|
|
270
282
|
meta[key] = node[key]
|
|
283
|
+
}
|
|
271
284
|
})
|
|
272
285
|
|
|
273
286
|
const resolved = consistentResolve(node.resolved, node.path, path, true)
|
|
274
|
-
if (resolved)
|
|
287
|
+
if (resolved) {
|
|
275
288
|
meta.resolved = resolved
|
|
289
|
+
}
|
|
276
290
|
|
|
277
|
-
if (node.extraneous)
|
|
291
|
+
if (node.extraneous) {
|
|
278
292
|
meta.extraneous = true
|
|
279
|
-
else {
|
|
280
|
-
if (node.peer)
|
|
293
|
+
} else {
|
|
294
|
+
if (node.peer) {
|
|
281
295
|
meta.peer = true
|
|
282
|
-
|
|
296
|
+
}
|
|
297
|
+
if (node.dev) {
|
|
283
298
|
meta.dev = true
|
|
284
|
-
|
|
299
|
+
}
|
|
300
|
+
if (node.optional) {
|
|
285
301
|
meta.optional = true
|
|
286
|
-
|
|
302
|
+
}
|
|
303
|
+
if (node.devOptional && !node.dev && !node.optional) {
|
|
287
304
|
meta.devOptional = true
|
|
305
|
+
}
|
|
288
306
|
}
|
|
289
307
|
return meta
|
|
290
308
|
}
|
|
@@ -423,8 +441,9 @@ class Shrinkwrap {
|
|
|
423
441
|
this.indent = indent !== undefined ? indent : this.indent
|
|
424
442
|
this.newline = newline !== undefined ? newline : this.newline
|
|
425
443
|
|
|
426
|
-
if (!this.hiddenLockfile || !data.packages)
|
|
444
|
+
if (!this.hiddenLockfile || !data.packages) {
|
|
427
445
|
return data
|
|
446
|
+
}
|
|
428
447
|
|
|
429
448
|
// add a few ms just to account for jitter
|
|
430
449
|
const lockTime = +(await stat(this.filename)).mtime + 10
|
|
@@ -467,8 +486,9 @@ class Shrinkwrap {
|
|
|
467
486
|
// migrate a v1 package lock to the new format.
|
|
468
487
|
const meta = this[_metaFromLock](location, name, lock)
|
|
469
488
|
// dependencies nested under a link are actually under the link target
|
|
470
|
-
if (meta.link)
|
|
489
|
+
if (meta.link) {
|
|
471
490
|
location = meta.resolved
|
|
491
|
+
}
|
|
472
492
|
if (lock.dependencies) {
|
|
473
493
|
for (const [name, dep] of Object.entries(lock.dependencies)) {
|
|
474
494
|
const loc = location + (location ? '/' : '') + 'node_modules/' + name
|
|
@@ -488,13 +508,15 @@ class Shrinkwrap {
|
|
|
488
508
|
pkgMetaKeys.forEach(key => {
|
|
489
509
|
const val = metaFieldFromPkg(pkg, key)
|
|
490
510
|
const k = key.replace(/^_/, '')
|
|
491
|
-
if (val)
|
|
511
|
+
if (val) {
|
|
492
512
|
root[k] = val
|
|
513
|
+
}
|
|
493
514
|
})
|
|
494
515
|
|
|
495
516
|
for (const [loc, meta] of Object.entries(this.data.packages)) {
|
|
496
|
-
if (!meta.requires || !loc)
|
|
517
|
+
if (!meta.requires || !loc) {
|
|
497
518
|
continue
|
|
519
|
+
}
|
|
498
520
|
|
|
499
521
|
// resolve each require to a meta entry
|
|
500
522
|
// if this node isn't optional, but the dep is, then it's an optionalDep
|
|
@@ -523,27 +545,33 @@ class Shrinkwrap {
|
|
|
523
545
|
[_resolveMetaNode] (loc, name) {
|
|
524
546
|
for (let path = loc; true; path = path.replace(/(^|\/)[^/]*$/, '')) {
|
|
525
547
|
const check = `${path}${path ? '/' : ''}node_modules/${name}`
|
|
526
|
-
if (this.data.packages[check])
|
|
548
|
+
if (this.data.packages[check]) {
|
|
527
549
|
return this.data.packages[check]
|
|
550
|
+
}
|
|
528
551
|
|
|
529
|
-
if (!path)
|
|
552
|
+
if (!path) {
|
|
530
553
|
break
|
|
554
|
+
}
|
|
531
555
|
}
|
|
532
556
|
return null
|
|
533
557
|
}
|
|
534
558
|
|
|
535
559
|
[_lockFromLoc] (lock, path, i = 0) {
|
|
536
|
-
if (!lock)
|
|
560
|
+
if (!lock) {
|
|
537
561
|
return null
|
|
562
|
+
}
|
|
538
563
|
|
|
539
|
-
if (path[i] === '')
|
|
564
|
+
if (path[i] === '') {
|
|
540
565
|
i++
|
|
566
|
+
}
|
|
541
567
|
|
|
542
|
-
if (i >= path.length)
|
|
568
|
+
if (i >= path.length) {
|
|
543
569
|
return lock
|
|
570
|
+
}
|
|
544
571
|
|
|
545
|
-
if (!lock.dependencies)
|
|
572
|
+
if (!lock.dependencies) {
|
|
546
573
|
return null
|
|
574
|
+
}
|
|
547
575
|
|
|
548
576
|
return this[_lockFromLoc](lock.dependencies[path[i]], path, i + 1)
|
|
549
577
|
}
|
|
@@ -555,8 +583,9 @@ class Shrinkwrap {
|
|
|
555
583
|
}
|
|
556
584
|
|
|
557
585
|
delete (nodePath) {
|
|
558
|
-
if (!this.data)
|
|
586
|
+
if (!this.data) {
|
|
559
587
|
throw new Error('run load() before getting or setting data')
|
|
588
|
+
}
|
|
560
589
|
const location = this[_pathToLoc](nodePath)
|
|
561
590
|
this[_awaitingUpdate].delete(location)
|
|
562
591
|
|
|
@@ -564,22 +593,26 @@ class Shrinkwrap {
|
|
|
564
593
|
const path = location.split(/(?:^|\/)node_modules\//)
|
|
565
594
|
const name = path.pop()
|
|
566
595
|
const pLock = this[_lockFromLoc](this.data, path)
|
|
567
|
-
if (pLock && pLock.dependencies)
|
|
596
|
+
if (pLock && pLock.dependencies) {
|
|
568
597
|
delete pLock.dependencies[name]
|
|
598
|
+
}
|
|
569
599
|
}
|
|
570
600
|
|
|
571
601
|
get (nodePath) {
|
|
572
|
-
if (!this.data)
|
|
602
|
+
if (!this.data) {
|
|
573
603
|
throw new Error('run load() before getting or setting data')
|
|
604
|
+
}
|
|
574
605
|
|
|
575
606
|
const location = this[_pathToLoc](nodePath)
|
|
576
|
-
if (this[_awaitingUpdate].has(location))
|
|
607
|
+
if (this[_awaitingUpdate].has(location)) {
|
|
577
608
|
this[_updateWaitingNode](location)
|
|
609
|
+
}
|
|
578
610
|
|
|
579
611
|
// first try to get from the newer spot, which we know has
|
|
580
612
|
// all the things we need.
|
|
581
|
-
if (this.data.packages[location])
|
|
613
|
+
if (this.data.packages[location]) {
|
|
582
614
|
return this.data.packages[location]
|
|
615
|
+
}
|
|
583
616
|
|
|
584
617
|
// otherwise, fall back to the legacy metadata, and hope for the best
|
|
585
618
|
// get the node in the shrinkwrap corresponding to this spot
|
|
@@ -595,8 +628,9 @@ class Shrinkwrap {
|
|
|
595
628
|
// from a lockfile which may be outdated or incomplete. Since v1
|
|
596
629
|
// lockfiles used the "version" field to contain a variety of
|
|
597
630
|
// different possible types of data, this gets a little complicated.
|
|
598
|
-
if (!lock)
|
|
631
|
+
if (!lock) {
|
|
599
632
|
return {}
|
|
633
|
+
}
|
|
600
634
|
|
|
601
635
|
// try to figure out a npm-package-arg spec from the lockfile entry
|
|
602
636
|
// This will return null if we could not get anything valid out of it.
|
|
@@ -613,29 +647,35 @@ class Shrinkwrap {
|
|
|
613
647
|
}
|
|
614
648
|
// also save the link target, omitting version since we don't know
|
|
615
649
|
// what it is, but we know it isn't a link to itself!
|
|
616
|
-
if (!this.data.packages[target])
|
|
650
|
+
if (!this.data.packages[target]) {
|
|
617
651
|
this[_metaFromLock](target, name, { ...lock, version: null })
|
|
652
|
+
}
|
|
618
653
|
return this.data.packages[location]
|
|
619
654
|
}
|
|
620
655
|
|
|
621
656
|
const meta = {}
|
|
622
657
|
// when calling loadAll we'll change these into proper dep objects
|
|
623
|
-
if (lock.requires && typeof lock.requires === 'object')
|
|
658
|
+
if (lock.requires && typeof lock.requires === 'object') {
|
|
624
659
|
meta.requires = lock.requires
|
|
660
|
+
}
|
|
625
661
|
|
|
626
|
-
if (lock.optional)
|
|
662
|
+
if (lock.optional) {
|
|
627
663
|
meta.optional = true
|
|
628
|
-
|
|
664
|
+
}
|
|
665
|
+
if (lock.dev) {
|
|
629
666
|
meta.dev = true
|
|
667
|
+
}
|
|
630
668
|
|
|
631
669
|
// the root will typically have a name from the root project's
|
|
632
670
|
// package.json file.
|
|
633
|
-
if (location === '')
|
|
671
|
+
if (location === '') {
|
|
634
672
|
meta.name = lock.name
|
|
673
|
+
}
|
|
635
674
|
|
|
636
675
|
// if we have integrity, save it now.
|
|
637
|
-
if (lock.integrity)
|
|
676
|
+
if (lock.integrity) {
|
|
638
677
|
meta.integrity = lock.integrity
|
|
678
|
+
}
|
|
639
679
|
|
|
640
680
|
if (lock.version && !lock.integrity) {
|
|
641
681
|
// this is usually going to be a git url or symlink, but it could
|
|
@@ -668,12 +708,13 @@ class Shrinkwrap {
|
|
|
668
708
|
// have a fetchSpec equal to the fully resolved thing.
|
|
669
709
|
// Registry deps, we take what's in the lockfile.
|
|
670
710
|
if (lock.resolved || (spec.type && !spec.registry)) {
|
|
671
|
-
if (spec.registry)
|
|
711
|
+
if (spec.registry) {
|
|
672
712
|
meta.resolved = lock.resolved
|
|
673
|
-
else if (spec.type === 'file')
|
|
713
|
+
} else if (spec.type === 'file') {
|
|
674
714
|
meta.resolved = consistentResolve(spec, this.path, this.path, true)
|
|
675
|
-
else if (spec.fetchSpec)
|
|
715
|
+
} else if (spec.fetchSpec) {
|
|
676
716
|
meta.resolved = spec.fetchSpec
|
|
717
|
+
}
|
|
677
718
|
}
|
|
678
719
|
|
|
679
720
|
// at this point, if still we don't have a version, do our best to
|
|
@@ -685,32 +726,37 @@ class Shrinkwrap {
|
|
|
685
726
|
versionFromTgz(spec.name, meta.resolved)
|
|
686
727
|
if (fromTgz) {
|
|
687
728
|
meta.version = fromTgz.version
|
|
688
|
-
if (fromTgz.name !== name)
|
|
729
|
+
if (fromTgz.name !== name) {
|
|
689
730
|
meta.name = fromTgz.name
|
|
731
|
+
}
|
|
690
732
|
}
|
|
691
733
|
} else if (spec.type === 'alias') {
|
|
692
734
|
meta.name = spec.subSpec.name
|
|
693
735
|
meta.version = spec.subSpec.fetchSpec
|
|
694
|
-
} else if (spec.type === 'version')
|
|
736
|
+
} else if (spec.type === 'version') {
|
|
695
737
|
meta.version = spec.fetchSpec
|
|
738
|
+
}
|
|
696
739
|
// ok, I did my best! good luck!
|
|
697
740
|
}
|
|
698
741
|
|
|
699
|
-
if (lock.bundled)
|
|
742
|
+
if (lock.bundled) {
|
|
700
743
|
meta.inBundle = true
|
|
744
|
+
}
|
|
701
745
|
|
|
702
746
|
// save it for next time
|
|
703
747
|
return this.data.packages[location] = meta
|
|
704
748
|
}
|
|
705
749
|
|
|
706
750
|
add (node) {
|
|
707
|
-
if (!this.data)
|
|
751
|
+
if (!this.data) {
|
|
708
752
|
throw new Error('run load() before getting or setting data')
|
|
753
|
+
}
|
|
709
754
|
|
|
710
755
|
// will be actually updated on read
|
|
711
756
|
const loc = relpath(this.path, node.path)
|
|
712
|
-
if (node.path === this.path)
|
|
757
|
+
if (node.path === this.path) {
|
|
713
758
|
this.tree = node
|
|
759
|
+
}
|
|
714
760
|
|
|
715
761
|
// if we have metadata about this node, and it's a match, then
|
|
716
762
|
// try to decorate it.
|
|
@@ -758,18 +804,21 @@ class Shrinkwrap {
|
|
|
758
804
|
}
|
|
759
805
|
|
|
760
806
|
addEdge (edge) {
|
|
761
|
-
if (!this.yarnLock || !edge.valid)
|
|
807
|
+
if (!this.yarnLock || !edge.valid) {
|
|
762
808
|
return
|
|
809
|
+
}
|
|
763
810
|
|
|
764
811
|
const { to: node } = edge
|
|
765
812
|
|
|
766
813
|
// if it's already set up, nothing to do
|
|
767
|
-
if (node.resolved !== null && node.integrity !== null)
|
|
814
|
+
if (node.resolved !== null && node.integrity !== null) {
|
|
768
815
|
return
|
|
816
|
+
}
|
|
769
817
|
|
|
770
818
|
// if the yarn lock is empty, nothing to do
|
|
771
|
-
if (!this.yarnLock.entries || !this.yarnLock.entries.size)
|
|
819
|
+
if (!this.yarnLock.entries || !this.yarnLock.entries.size) {
|
|
772
820
|
return
|
|
821
|
+
}
|
|
773
822
|
|
|
774
823
|
// we relativize the path here because that's how it shows up in the lock
|
|
775
824
|
// XXX how is this different from pathFixed above??
|
|
@@ -783,11 +832,13 @@ class Shrinkwrap {
|
|
|
783
832
|
if (!entry ||
|
|
784
833
|
mismatch(node.version, entry.version) ||
|
|
785
834
|
mismatch(node.integrity, entry.integrity) ||
|
|
786
|
-
mismatch(pathFixed, entry.resolved))
|
|
835
|
+
mismatch(pathFixed, entry.resolved)) {
|
|
787
836
|
return
|
|
837
|
+
}
|
|
788
838
|
|
|
789
|
-
if (entry.resolved && yarnRegRe.test(entry.resolved) && spec.registry)
|
|
839
|
+
if (entry.resolved && yarnRegRe.test(entry.resolved) && spec.registry) {
|
|
790
840
|
entry.resolved = entry.resolved.replace(yarnRegRe, 'https://registry.npmjs.org/')
|
|
841
|
+
}
|
|
791
842
|
|
|
792
843
|
node.integrity = node.integrity || entry.integrity || null
|
|
793
844
|
node.resolved = node.resolved ||
|
|
@@ -804,30 +855,35 @@ class Shrinkwrap {
|
|
|
804
855
|
|
|
805
856
|
commit () {
|
|
806
857
|
if (this.tree) {
|
|
807
|
-
if (this.yarnLock)
|
|
858
|
+
if (this.yarnLock) {
|
|
808
859
|
this.yarnLock.fromTree(this.tree)
|
|
860
|
+
}
|
|
809
861
|
const root = Shrinkwrap.metaFromNode(this.tree.target, this.path)
|
|
810
862
|
this.data.packages = {}
|
|
811
|
-
if (Object.keys(root).length)
|
|
863
|
+
if (Object.keys(root).length) {
|
|
812
864
|
this.data.packages[''] = root
|
|
865
|
+
}
|
|
813
866
|
for (const node of this.tree.root.inventory.values()) {
|
|
814
867
|
// only way this.tree is not root is if the root is a link to it
|
|
815
|
-
if (node === this.tree || node.isRoot || node.location === '')
|
|
868
|
+
if (node === this.tree || node.isRoot || node.location === '') {
|
|
816
869
|
continue
|
|
870
|
+
}
|
|
817
871
|
const loc = relpath(this.path, node.path)
|
|
818
872
|
this.data.packages[loc] = Shrinkwrap.metaFromNode(node, this.path)
|
|
819
873
|
}
|
|
820
874
|
} else if (this[_awaitingUpdate].size > 0) {
|
|
821
|
-
for (const loc of this[_awaitingUpdate].keys())
|
|
875
|
+
for (const loc of this[_awaitingUpdate].keys()) {
|
|
822
876
|
this[_updateWaitingNode](loc)
|
|
877
|
+
}
|
|
823
878
|
}
|
|
824
879
|
|
|
825
880
|
// hidden lockfiles don't include legacy metadata or a root entry
|
|
826
881
|
if (this.hiddenLockfile) {
|
|
827
882
|
delete this.data.packages['']
|
|
828
883
|
delete this.data.dependencies
|
|
829
|
-
} else if (this.tree)
|
|
884
|
+
} else if (this.tree) {
|
|
830
885
|
this[_buildLegacyLockfile](this.tree, this.data)
|
|
886
|
+
}
|
|
831
887
|
|
|
832
888
|
return this.data
|
|
833
889
|
}
|
|
@@ -836,8 +892,9 @@ class Shrinkwrap {
|
|
|
836
892
|
if (node === this.tree) {
|
|
837
893
|
// the root node
|
|
838
894
|
lock.name = node.packageName || node.name
|
|
839
|
-
if (node.version)
|
|
895
|
+
if (node.version) {
|
|
840
896
|
lock.version = node.version
|
|
897
|
+
}
|
|
841
898
|
}
|
|
842
899
|
|
|
843
900
|
// npm v6 and before tracked 'from', meaning "the request that led
|
|
@@ -868,26 +925,29 @@ class Shrinkwrap {
|
|
|
868
925
|
const spec = !edge ? rSpec
|
|
869
926
|
: npa.resolve(node.name, edge.spec, edge.from.realpath)
|
|
870
927
|
|
|
871
|
-
if (node.isLink)
|
|
928
|
+
if (node.isLink) {
|
|
872
929
|
lock.version = `file:${relpath(this.path, node.realpath)}`
|
|
873
|
-
else if (spec && (spec.type === 'file' || spec.type === 'remote'))
|
|
930
|
+
} else if (spec && (spec.type === 'file' || spec.type === 'remote')) {
|
|
874
931
|
lock.version = spec.saveSpec
|
|
875
|
-
else if (spec && spec.type === 'git' || rSpec.type === 'git') {
|
|
932
|
+
} else if (spec && spec.type === 'git' || rSpec.type === 'git') {
|
|
876
933
|
lock.version = node.resolved
|
|
877
934
|
/* istanbul ignore else - don't think there are any cases where a git
|
|
878
935
|
* spec (or indeed, ANY npa spec) doesn't have a .raw member */
|
|
879
|
-
if (spec.raw)
|
|
936
|
+
if (spec.raw) {
|
|
880
937
|
lock.from = spec.raw
|
|
938
|
+
}
|
|
881
939
|
} else if (!node.isRoot &&
|
|
882
940
|
node.package &&
|
|
883
941
|
node.packageName &&
|
|
884
|
-
node.packageName !== node.name)
|
|
942
|
+
node.packageName !== node.name) {
|
|
885
943
|
lock.version = `npm:${node.packageName}@${node.version}`
|
|
886
|
-
else if (node.package && node.version)
|
|
944
|
+
} else if (node.package && node.version) {
|
|
887
945
|
lock.version = node.version
|
|
946
|
+
}
|
|
888
947
|
|
|
889
|
-
if (node.inDepBundle)
|
|
948
|
+
if (node.inDepBundle) {
|
|
890
949
|
lock.bundled = true
|
|
950
|
+
}
|
|
891
951
|
|
|
892
952
|
// when we didn't resolve to git, file, or dir, and didn't request
|
|
893
953
|
// git, file, dir, or remote, then the resolved value is necessary.
|
|
@@ -899,77 +959,90 @@ class Shrinkwrap {
|
|
|
899
959
|
spec.type !== 'directory' &&
|
|
900
960
|
spec.type !== 'git' &&
|
|
901
961
|
spec.type !== 'file' &&
|
|
902
|
-
spec.type !== 'remote')
|
|
962
|
+
spec.type !== 'remote') {
|
|
903
963
|
lock.resolved = node.resolved
|
|
964
|
+
}
|
|
904
965
|
|
|
905
|
-
if (node.integrity)
|
|
966
|
+
if (node.integrity) {
|
|
906
967
|
lock.integrity = node.integrity
|
|
968
|
+
}
|
|
907
969
|
|
|
908
|
-
if (node.extraneous)
|
|
970
|
+
if (node.extraneous) {
|
|
909
971
|
lock.extraneous = true
|
|
910
|
-
else if (!node.isLink) {
|
|
911
|
-
if (node.peer)
|
|
972
|
+
} else if (!node.isLink) {
|
|
973
|
+
if (node.peer) {
|
|
912
974
|
lock.peer = true
|
|
975
|
+
}
|
|
913
976
|
|
|
914
|
-
if (node.devOptional && !node.dev && !node.optional)
|
|
977
|
+
if (node.devOptional && !node.dev && !node.optional) {
|
|
915
978
|
lock.devOptional = true
|
|
979
|
+
}
|
|
916
980
|
|
|
917
|
-
if (node.dev)
|
|
981
|
+
if (node.dev) {
|
|
918
982
|
lock.dev = true
|
|
983
|
+
}
|
|
919
984
|
|
|
920
|
-
if (node.optional)
|
|
985
|
+
if (node.optional) {
|
|
921
986
|
lock.optional = true
|
|
987
|
+
}
|
|
922
988
|
}
|
|
923
989
|
|
|
924
990
|
const depender = node.target
|
|
925
991
|
if (depender.edgesOut.size > 0) {
|
|
926
992
|
if (node !== this.tree) {
|
|
927
|
-
|
|
993
|
+
const entries = [...depender.edgesOut.entries()]
|
|
994
|
+
lock.requires = entries.reduce((set, [k, v]) => {
|
|
928
995
|
// omit peer deps from legacy lockfile requires field, because
|
|
929
996
|
// npm v6 doesn't handle peer deps, and this triggers some bad
|
|
930
997
|
// behavior if the dep can't be found in the dependencies list.
|
|
931
998
|
const { spec, peer } = v
|
|
932
|
-
if (peer)
|
|
999
|
+
if (peer) {
|
|
933
1000
|
return set
|
|
1001
|
+
}
|
|
934
1002
|
if (spec.startsWith('file:')) {
|
|
935
1003
|
// turn absolute file: paths into relative paths from the node
|
|
936
1004
|
// this especially shows up with workspace edges when the root
|
|
937
1005
|
// node is also a workspace in the set.
|
|
938
1006
|
const p = resolve(node.realpath, spec.substr('file:'.length))
|
|
939
1007
|
set[k] = `file:${relpath(node.realpath, p)}`
|
|
940
|
-
} else
|
|
1008
|
+
} else {
|
|
941
1009
|
set[k] = spec
|
|
1010
|
+
}
|
|
942
1011
|
return set
|
|
943
1012
|
}, {})
|
|
944
|
-
} else
|
|
1013
|
+
} else {
|
|
945
1014
|
lock.requires = true
|
|
1015
|
+
}
|
|
946
1016
|
}
|
|
947
1017
|
|
|
948
1018
|
// now we walk the children, putting them in the 'dependencies' object
|
|
949
1019
|
const {children} = node.target
|
|
950
|
-
if (!children.size)
|
|
1020
|
+
if (!children.size) {
|
|
951
1021
|
delete lock.dependencies
|
|
952
|
-
else {
|
|
1022
|
+
} else {
|
|
953
1023
|
const kidPath = [...path, node.realpath]
|
|
954
1024
|
const dependencies = {}
|
|
955
1025
|
// skip any that are already in the descent path, so cyclical link
|
|
956
1026
|
// dependencies don't blow up with ELOOP.
|
|
957
1027
|
let found = false
|
|
958
1028
|
for (const [name, kid] of children.entries()) {
|
|
959
|
-
if (path.includes(kid.realpath))
|
|
1029
|
+
if (path.includes(kid.realpath)) {
|
|
960
1030
|
continue
|
|
1031
|
+
}
|
|
961
1032
|
dependencies[name] = this[_buildLegacyLockfile](kid, {}, kidPath)
|
|
962
1033
|
found = true
|
|
963
1034
|
}
|
|
964
|
-
if (found)
|
|
1035
|
+
if (found) {
|
|
965
1036
|
lock.dependencies = dependencies
|
|
1037
|
+
}
|
|
966
1038
|
}
|
|
967
1039
|
return lock
|
|
968
1040
|
}
|
|
969
1041
|
|
|
970
1042
|
save (options = {}) {
|
|
971
|
-
if (!this.data)
|
|
1043
|
+
if (!this.data) {
|
|
972
1044
|
throw new Error('run load() before saving data')
|
|
1045
|
+
}
|
|
973
1046
|
|
|
974
1047
|
const { format = true } = options
|
|
975
1048
|
const defaultIndent = this.indent || 2
|
package/lib/signal-handling.js
CHANGED
|
@@ -13,8 +13,9 @@ const setup = fn => {
|
|
|
13
13
|
const sigListeners = { loaded: false }
|
|
14
14
|
|
|
15
15
|
const unload = () => {
|
|
16
|
-
if (!sigListeners.loaded)
|
|
16
|
+
if (!sigListeners.loaded) {
|
|
17
17
|
return
|
|
18
|
+
}
|
|
18
19
|
for (const sig of signals) {
|
|
19
20
|
try {
|
|
20
21
|
process.removeListener(sig, sigListeners[sig])
|
|
@@ -43,8 +44,9 @@ const setup = fn => {
|
|
|
43
44
|
// if we exit normally, but caught a signal which would have been fatal,
|
|
44
45
|
// then re-send it once we're done with whatever cleanup we have to do.
|
|
45
46
|
unload()
|
|
46
|
-
if (process.listeners(sig).length < 1)
|
|
47
|
+
if (process.listeners(sig).length < 1) {
|
|
47
48
|
process.once('beforeExit', onBeforeExit)
|
|
49
|
+
}
|
|
48
50
|
|
|
49
51
|
fn({ signal: sig })
|
|
50
52
|
}
|
|
@@ -56,8 +58,9 @@ const setup = fn => {
|
|
|
56
58
|
try {
|
|
57
59
|
// if we call this a bunch of times, avoid triggering the warning
|
|
58
60
|
const { length } = process.listeners(sig)
|
|
59
|
-
if (length >= max)
|
|
61
|
+
if (length >= max) {
|
|
60
62
|
process.setMaxListeners(length + 1)
|
|
63
|
+
}
|
|
61
64
|
process.on(sig, sigListeners[sig])
|
|
62
65
|
} catch (er) {}
|
|
63
66
|
}
|
package/lib/spec-from-lock.js
CHANGED
|
@@ -5,19 +5,22 @@ const specFromLock = (name, lock, where) => {
|
|
|
5
5
|
try {
|
|
6
6
|
if (lock.version) {
|
|
7
7
|
const spec = npa.resolve(name, lock.version, where)
|
|
8
|
-
if (lock.integrity || spec.type === 'git')
|
|
8
|
+
if (lock.integrity || spec.type === 'git') {
|
|
9
9
|
return spec
|
|
10
|
+
}
|
|
10
11
|
}
|
|
11
12
|
if (lock.from) {
|
|
12
13
|
// legacy metadata includes "from", but not integrity
|
|
13
14
|
const spec = npa.resolve(name, lock.from, where)
|
|
14
|
-
if (spec.registry && lock.version)
|
|
15
|
+
if (spec.registry && lock.version) {
|
|
15
16
|
return npa.resolve(name, lock.version, where)
|
|
16
|
-
else if (!lock.resolved)
|
|
17
|
+
} else if (!lock.resolved) {
|
|
17
18
|
return spec
|
|
19
|
+
}
|
|
18
20
|
}
|
|
19
|
-
if (lock.resolved)
|
|
21
|
+
if (lock.resolved) {
|
|
20
22
|
return npa.resolve(name, lock.resolved, where)
|
|
23
|
+
}
|
|
21
24
|
} catch (_) { }
|
|
22
25
|
try {
|
|
23
26
|
return npa.resolve(name, lock.version, where)
|