@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.
Files changed (49) hide show
  1. package/bin/actual.js +4 -2
  2. package/bin/audit.js +12 -6
  3. package/bin/dedupe.js +6 -3
  4. package/bin/funding.js +4 -2
  5. package/bin/ideal.js +2 -1
  6. package/bin/lib/logging.js +4 -3
  7. package/bin/lib/options.js +14 -12
  8. package/bin/lib/timers.js +6 -3
  9. package/bin/license.js +9 -5
  10. package/bin/prune.js +6 -3
  11. package/bin/reify.js +6 -3
  12. package/bin/virtual.js +4 -2
  13. package/lib/add-rm-pkg-deps.js +25 -14
  14. package/lib/arborist/audit.js +2 -1
  15. package/lib/arborist/build-ideal-tree.js +129 -68
  16. package/lib/arborist/deduper.js +2 -1
  17. package/lib/arborist/index.js +8 -4
  18. package/lib/arborist/load-actual.js +28 -13
  19. package/lib/arborist/load-virtual.js +34 -18
  20. package/lib/arborist/load-workspaces.js +4 -2
  21. package/lib/arborist/rebuild.js +31 -16
  22. package/lib/arborist/reify.js +153 -76
  23. package/lib/audit-report.js +42 -22
  24. package/lib/calc-dep-flags.js +18 -9
  25. package/lib/can-place-dep.js +56 -28
  26. package/lib/case-insensitive-map.js +4 -2
  27. package/lib/consistent-resolve.js +2 -1
  28. package/lib/deepest-nesting-target.js +4 -2
  29. package/lib/dep-valid.js +8 -4
  30. package/lib/diff.js +74 -22
  31. package/lib/edge.js +26 -13
  32. package/lib/gather-dep-set.js +2 -1
  33. package/lib/inventory.js +12 -6
  34. package/lib/link.js +14 -9
  35. package/lib/node.js +216 -113
  36. package/lib/optional-set.js +4 -2
  37. package/lib/peer-entry-sets.js +10 -5
  38. package/lib/place-dep.js +56 -29
  39. package/lib/printable.js +41 -21
  40. package/lib/realpath.js +12 -6
  41. package/lib/shrinkwrap.js +162 -89
  42. package/lib/signal-handling.js +6 -3
  43. package/lib/spec-from-lock.js +7 -4
  44. package/lib/tracker.js +24 -18
  45. package/lib/tree-check.js +12 -6
  46. package/lib/version-from-tgz.js +4 -2
  47. package/lib/vuln.js +28 -16
  48. package/lib/yarn-lock.js +27 -15
  49. 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
- if (!isScope && !isNM && !data.packages[rel])
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
- if (node.dev)
296
+ }
297
+ if (node.dev) {
283
298
  meta.dev = true
284
- if (node.optional)
299
+ }
300
+ if (node.optional) {
285
301
  meta.optional = true
286
- if (node.devOptional && !node.dev && !node.optional)
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
- if (lock.dev)
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
- lock.requires = [...depender.edgesOut.entries()].reduce((set, [k, v]) => {
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
@@ -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
  }
@@ -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)