@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/bin/actual.js CHANGED
@@ -7,12 +7,14 @@ require('./lib/timers.js')
7
7
  const start = process.hrtime()
8
8
  new Arborist(options).loadActual(options).then(tree => {
9
9
  const end = process.hrtime(start)
10
- if (!process.argv.includes('--quiet'))
10
+ if (!process.argv.includes('--quiet')) {
11
11
  print(tree)
12
+ }
12
13
 
13
14
  console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`)
14
- if (options.save)
15
+ if (options.save) {
15
16
  tree.meta.save()
17
+ }
16
18
  if (options.saveHidden) {
17
19
  tree.meta.hiddenLockfile = true
18
20
  tree.meta.filename = options.path + '/node_modules/.package-lock.json'
package/bin/audit.js CHANGED
@@ -7,12 +7,14 @@ require('./lib/logging.js')
7
7
 
8
8
  const Vuln = require('../lib/vuln.js')
9
9
  const printReport = report => {
10
- for (const vuln of report.values())
10
+ for (const vuln of report.values()) {
11
11
  console.log(printVuln(vuln))
12
+ }
12
13
  if (report.topVulns.size) {
13
14
  console.log('\n# top-level vulnerabilities')
14
- for (const vuln of report.topVulns.values())
15
+ for (const vuln of report.topVulns.values()) {
15
16
  console.log(printVuln(vuln))
17
+ }
16
18
  }
17
19
  }
18
20
 
@@ -37,12 +39,16 @@ const arb = new Arborist(options)
37
39
  arb.audit(options).then(tree => {
38
40
  process.emit('timeEnd', 'audit script')
39
41
  const end = process.hrtime(start)
40
- if (options.fix)
42
+ if (options.fix) {
41
43
  print(tree)
42
- if (!options.quiet)
44
+ }
45
+ if (!options.quiet) {
43
46
  printReport(arb.auditReport)
44
- if (options.fix)
47
+ }
48
+ if (options.fix) {
45
49
  console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`)
46
- if (tree.meta && options.save)
50
+ }
51
+ if (tree.meta && options.save) {
47
52
  tree.meta.save()
53
+ }
48
54
  }).catch(er => console.error(er))
package/bin/dedupe.js CHANGED
@@ -10,8 +10,9 @@ const printDiff = diff => {
10
10
  depth({
11
11
  tree: diff,
12
12
  visit: d => {
13
- if (d.location === '')
13
+ if (d.location === '') {
14
14
  return
15
+ }
15
16
  switch (d.action) {
16
17
  case 'REMOVE':
17
18
  console.error('REMOVE', d.actual.location)
@@ -38,9 +39,11 @@ arb.dedupe(options).then(tree => {
38
39
  process.emit('timeEnd', 'install')
39
40
  const end = process.hrtime(start)
40
41
  print(tree)
41
- if (options.dryRun)
42
+ if (options.dryRun) {
42
43
  printDiff(arb.diff)
44
+ }
43
45
  console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`)
44
- if (tree.meta && options.save)
46
+ if (tree.meta && options.save) {
45
47
  tree.meta.save()
48
+ }
46
49
  }).catch(er => console.error(require('util').inspect(er, { depth: Infinity })))
package/bin/funding.js CHANGED
@@ -19,13 +19,15 @@ a.loadVirtual().then(tree => {
19
19
  const end = process.hrtime(start)
20
20
  if (!query) {
21
21
  for (const node of tree.inventory.values()) {
22
- if (node.package.funding)
22
+ if (node.package.funding) {
23
23
  console.log(node.name, node.location, node.package.funding)
24
+ }
24
25
  }
25
26
  } else {
26
27
  for (const node of tree.inventory.query('name', query)) {
27
- if (node.package.funding)
28
+ if (node.package.funding) {
28
29
  console.log(node.name, node.location, node.package.funding)
30
+ }
29
31
  }
30
32
  }
31
33
  console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`)
package/bin/ideal.js CHANGED
@@ -11,8 +11,9 @@ new Arborist(options).buildIdealTree(options).then(tree => {
11
11
  const end = process.hrtime(start)
12
12
  print(tree)
13
13
  console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 10e9}s`)
14
- if (tree.meta && options.save)
14
+ if (tree.meta && options.save) {
15
15
  tree.meta.save()
16
+ }
16
17
  }).catch(er => {
17
18
  const opt = { depth: Infinity, color: true }
18
19
  console.error(er.code === 'ERESOLVE' ? inspect(er, opt) : er)
@@ -24,12 +24,13 @@ const colors = process.stderr.isTTY
24
24
  const magenta = colors ? msg => `\x1B[35m${msg}\x1B[39m` : m => m
25
25
  if (loglevel !== 'silent') {
26
26
  process.on('log', (level, ...args) => {
27
- if (levelMap.get(level) < levelMap.get(loglevel))
27
+ if (levelMap.get(level) < levelMap.get(loglevel)) {
28
28
  return
29
+ }
29
30
  const pref = `${process.pid} ${magenta(level)} `
30
- if (level === 'warn' && args[0] === 'ERESOLVE')
31
+ if (level === 'warn' && args[0] === 'ERESOLVE') {
31
32
  args[2] = inspect(args[2], { depth: 10, colors })
32
- else {
33
+ } else {
33
34
  args = args.map(a => {
34
35
  return typeof a === 'string' ? a
35
36
  : inspect(a, { depth: 10, colors })
@@ -11,17 +11,17 @@ for (const arg of process.argv.slice(2)) {
11
11
  } else if (/^--rm=/.test(arg)) {
12
12
  options.rm = options.rm || []
13
13
  options.rm.push(arg.substr('--rm='.length))
14
- } else if (arg === '--global')
14
+ } else if (arg === '--global') {
15
15
  options.global = true
16
- else if (arg === '--global-style')
16
+ } else if (arg === '--global-style') {
17
17
  options.globalStyle = true
18
- else if (arg === '--prefer-dedupe')
18
+ } else if (arg === '--prefer-dedupe') {
19
19
  options.preferDedupe = true
20
- else if (arg === '--legacy-peer-deps')
20
+ } else if (arg === '--legacy-peer-deps') {
21
21
  options.legacyPeerDeps = true
22
- else if (arg === '--force')
22
+ } else if (arg === '--force') {
23
23
  options.force = true
24
- else if (arg === '--update-all') {
24
+ } else if (arg === '--update-all') {
25
25
  options.update = options.update || {}
26
26
  options.update.all = true
27
27
  } else if (/^--update=/.test(arg)) {
@@ -31,9 +31,9 @@ for (const arg of process.argv.slice(2)) {
31
31
  } else if (/^--omit=/.test(arg)) {
32
32
  options.omit = options.omit || []
33
33
  options.omit.push(arg.substr('--omit='.length))
34
- } else if (/^--before=/.test(arg))
34
+ } else if (/^--before=/.test(arg)) {
35
35
  options.before = new Date(arg.substr('--before='.length))
36
- else if (/^-w.+/.test(arg)) {
36
+ } else if (/^-w.+/.test(arg)) {
37
37
  options.workspaces = options.workspaces || []
38
38
  options.workspaces.push(arg.replace(/^-w/, ''))
39
39
  } else if (/^--workspace=/.test(arg)) {
@@ -43,15 +43,17 @@ for (const arg of process.argv.slice(2)) {
43
43
  const [key, ...v] = arg.replace(/^--/, '').split('=')
44
44
  const val = v.join('=')
45
45
  options[key] = val === 'false' ? false : val === 'true' ? true : val
46
- } else if (/^--.+/.test(arg))
46
+ } else if (/^--.+/.test(arg)) {
47
47
  options[arg.replace(/^--/, '')] = true
48
- else if (options.path === undefined)
48
+ } else if (options.path === undefined) {
49
49
  options.path = arg
50
- else
50
+ } else {
51
51
  options._.push(arg)
52
+ }
52
53
  }
53
54
 
54
- if (options.path === undefined)
55
+ if (options.path === undefined) {
55
56
  options.path = '.'
57
+ }
56
58
 
57
59
  console.error(options)
package/bin/lib/timers.js CHANGED
@@ -3,21 +3,24 @@ const { format } = require('util')
3
3
  const options = require('./options.js')
4
4
 
5
5
  process.on('time', name => {
6
- if (timers[name])
6
+ if (timers[name]) {
7
7
  throw new Error('conflicting timer! ' + name)
8
+ }
8
9
  timers[name] = process.hrtime()
9
10
  })
10
11
 
11
12
  const dim = process.stderr.isTTY ? msg => `\x1B[2m${msg}\x1B[22m` : m => m
12
13
  const red = process.stderr.isTTY ? msg => `\x1B[31m${msg}\x1B[39m` : m => m
13
14
  process.on('timeEnd', name => {
14
- if (!timers[name])
15
+ if (!timers[name]) {
15
16
  throw new Error('timer not started! ' + name)
17
+ }
16
18
  const res = process.hrtime(timers[name])
17
19
  delete timers[name]
18
20
  const msg = format(`${process.pid} ${name}`, res[0] * 1e3 + res[1] / 1e6)
19
- if (options.timers !== false)
21
+ if (options.timers !== false) {
20
22
  console.error(dim(msg))
23
+ }
21
24
  })
22
25
 
23
26
  process.on('exit', () => {
package/bin/license.js CHANGED
@@ -8,27 +8,31 @@ const query = options._.shift()
8
8
 
9
9
  a.loadVirtual().then(tree => {
10
10
  // only load the actual tree if the virtual one doesn't have modern metadata
11
- if (!tree.meta || !(tree.meta.originalLockfileVersion >= 2))
11
+ if (!tree.meta || !(tree.meta.originalLockfileVersion >= 2)) {
12
12
  throw 'load actual'
13
- else
13
+ } else {
14
14
  return tree
15
+ }
15
16
  }).catch((er) => {
16
17
  console.error('loading actual tree', er)
17
18
  return a.loadActual()
18
19
  }).then(tree => {
19
20
  if (!query) {
20
21
  const set = []
21
- for (const license of tree.inventory.query('license'))
22
+ for (const license of tree.inventory.query('license')) {
22
23
  set.push([tree.inventory.query('license', license).size, license])
24
+ }
23
25
 
24
26
  for (const [count, license] of set.sort((a, b) =>
25
27
  a[1] && b[1] ? b[0] - a[0] || a[1].localeCompare(b[1], 'en')
26
28
  : a[1] ? -1
27
29
  : b[1] ? 1
28
- : 0))
30
+ : 0)) {
29
31
  console.log(count, license)
32
+ }
30
33
  } else {
31
- for (const node of tree.inventory.query('license', query === 'undefined' ? undefined : query))
34
+ for (const node of tree.inventory.query('license', query === 'undefined' ? undefined : query)) {
32
35
  console.log(`${node.name} ${node.location} ${node.package.description || ''}`)
36
+ }
33
37
  }
34
38
  })
package/bin/prune.js CHANGED
@@ -10,8 +10,9 @@ const printDiff = diff => {
10
10
  depth({
11
11
  tree: diff,
12
12
  visit: d => {
13
- if (d.location === '')
13
+ if (d.location === '') {
14
14
  return
15
+ }
15
16
  switch (d.action) {
16
17
  case 'REMOVE':
17
18
  console.error('REMOVE', d.actual.location)
@@ -38,9 +39,11 @@ arb.prune(options).then(tree => {
38
39
  process.emit('timeEnd', 'install')
39
40
  const end = process.hrtime(start)
40
41
  print(tree)
41
- if (options.dryRun)
42
+ if (options.dryRun) {
42
43
  printDiff(arb.diff)
44
+ }
43
45
  console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`)
44
- if (tree.meta && options.save)
46
+ if (tree.meta && options.save) {
45
47
  tree.meta.save()
48
+ }
46
49
  }).catch(er => console.error(require('util').inspect(er, { depth: Infinity })))
package/bin/reify.js CHANGED
@@ -10,8 +10,9 @@ const printDiff = diff => {
10
10
  depth({
11
11
  tree: diff,
12
12
  visit: d => {
13
- if (d.location === '')
13
+ if (d.location === '') {
14
14
  return
15
+ }
15
16
  switch (d.action) {
16
17
  case 'REMOVE':
17
18
  console.error('REMOVE', d.actual.location)
@@ -38,9 +39,11 @@ arb.reify(options).then(tree => {
38
39
  process.emit('timeEnd', 'install')
39
40
  const end = process.hrtime(start)
40
41
  print(tree)
41
- if (options.dryRun)
42
+ if (options.dryRun) {
42
43
  printDiff(arb.diff)
44
+ }
43
45
  console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`)
44
- if (tree.meta && options.save)
46
+ if (tree.meta && options.save) {
45
47
  tree.meta.save()
48
+ }
46
49
  }).catch(er => console.error(require('util').inspect(er, { depth: Infinity })))
package/bin/virtual.js CHANGED
@@ -8,9 +8,11 @@ require('./lib/timers.js')
8
8
  const start = process.hrtime()
9
9
  new Arborist(options).loadVirtual().then(tree => {
10
10
  const end = process.hrtime(start)
11
- if (!options.quiet)
11
+ if (!options.quiet) {
12
12
  print(tree)
13
- if (options.save)
13
+ }
14
+ if (options.save) {
14
15
  tree.meta.save()
16
+ }
15
17
  console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`)
16
18
  }).catch(er => console.error(er))
@@ -1,8 +1,9 @@
1
1
  // add and remove dependency specs to/from pkg manifest
2
2
 
3
3
  const add = ({pkg, add, saveBundle, saveType, log}) => {
4
- for (const spec of add)
4
+ for (const spec of add) {
5
5
  addSingle({pkg, spec, saveBundle, saveType, log})
6
+ }
6
7
 
7
8
  return pkg
8
9
  }
@@ -24,8 +25,9 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => {
24
25
  // to keep based on the same order of priority we do when
25
26
  // building the tree as defined in the _loadDeps method of
26
27
  // the node class.
27
- if (!saveType)
28
+ if (!saveType) {
28
29
  saveType = inferSaveType(pkg, spec.name)
30
+ }
29
31
 
30
32
  if (saveType === 'prod') {
31
33
  // a production dependency can only exist as production (rpj ensures it
@@ -48,8 +50,9 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => {
48
50
  const depType = saveTypeMap.get(saveType)
49
51
 
50
52
  pkg[depType] = pkg[depType] || {}
51
- if (rawSpec !== '' || pkg[depType][name] === undefined)
53
+ if (rawSpec !== '' || pkg[depType][name] === undefined) {
52
54
  pkg[depType][name] = rawSpec || '*'
55
+ }
53
56
  if (saveType === 'optional') {
54
57
  // Affordance for previous npm versions that require this behaviour
55
58
  pkg.dependencies = pkg.dependencies || {}
@@ -58,17 +61,18 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => {
58
61
 
59
62
  if (saveType === 'peer' || saveType === 'peerOptional') {
60
63
  const pdm = pkg.peerDependenciesMeta || {}
61
- if (saveType === 'peer' && pdm[name] && pdm[name].optional)
64
+ if (saveType === 'peer' && pdm[name] && pdm[name].optional) {
62
65
  pdm[name].optional = false
63
- else if (saveType === 'peerOptional') {
66
+ } else if (saveType === 'peerOptional') {
64
67
  pdm[name] = pdm[name] || {}
65
68
  pdm[name].optional = true
66
69
  pkg.peerDependenciesMeta = pdm
67
70
  }
68
71
  // peerDeps are often also a devDep, so that they can be tested when
69
72
  // using package managers that don't auto-install peer deps
70
- if (pkg.devDependencies && pkg.devDependencies[name] !== undefined)
73
+ if (pkg.devDependencies && pkg.devDependencies[name] !== undefined) {
71
74
  pkg.devDependencies[name] = pkg.peerDependencies[name]
75
+ }
72
76
  }
73
77
 
74
78
  if (saveBundle && saveType !== 'peer' && saveType !== 'peerOptional') {
@@ -87,47 +91,54 @@ const inferSaveType = (pkg, name) => {
87
91
  saveType === 'peerOptional' &&
88
92
  (!hasSubKey(pkg, 'peerDependenciesMeta', name) ||
89
93
  !pkg.peerDependenciesMeta[name].optional)
90
- )
94
+ ) {
91
95
  return 'peer'
96
+ }
92
97
  return saveType
93
98
  }
94
99
  }
95
100
  return 'prod'
96
101
  }
97
102
 
103
+ const { hasOwnProperty } = Object.prototype
98
104
  const hasSubKey = (pkg, depType, name) => {
99
- return pkg[depType] && Object.prototype.hasOwnProperty.call(pkg[depType], name)
105
+ return pkg[depType] && hasOwnProperty.call(pkg[depType], name)
100
106
  }
101
107
 
102
108
  // Removes a subkey and warns about it if it's being replaced
103
109
  const deleteSubKey = (pkg, depType, name, replacedBy, log) => {
104
110
  if (hasSubKey(pkg, depType, name)) {
105
- if (replacedBy && log)
111
+ if (replacedBy && log) {
106
112
  log.warn('idealTree', `Removing ${depType}.${name} in favor of ${replacedBy}.${name}`)
113
+ }
107
114
  delete pkg[depType][name]
108
115
 
109
- // clean up peerDependenciesMeta if we are removing something from peerDependencies
116
+ // clean up peerDepsMeta if we are removing something from peerDependencies
110
117
  if (depType === 'peerDependencies' && pkg.peerDependenciesMeta) {
111
118
  delete pkg.peerDependenciesMeta[name]
112
- if (!Object.keys(pkg.peerDependenciesMeta).length)
119
+ if (!Object.keys(pkg.peerDependenciesMeta).length) {
113
120
  delete pkg.peerDependenciesMeta
121
+ }
114
122
  }
115
123
 
116
- if (!Object.keys(pkg[depType]).length)
124
+ if (!Object.keys(pkg[depType]).length) {
117
125
  delete pkg[depType]
126
+ }
118
127
  }
119
128
  }
120
129
 
121
130
  const rm = (pkg, rm) => {
122
131
  for (const depType of new Set(saveTypeMap.values())) {
123
- for (const name of rm)
132
+ for (const name of rm) {
124
133
  deleteSubKey(pkg, depType, name)
134
+ }
125
135
  }
126
136
  if (pkg.bundleDependencies) {
127
137
  pkg.bundleDependencies = pkg.bundleDependencies
128
138
  .filter(name => !rm.includes(name))
129
- if (!pkg.bundleDependencies.length)
139
+ if (!pkg.bundleDependencies.length) {
130
140
  delete pkg.bundleDependencies
141
+ }
131
142
  }
132
143
  return pkg
133
144
  }
@@ -22,8 +22,9 @@ module.exports = cls => class Auditor extends cls {
22
22
 
23
23
  process.emit('time', 'audit')
24
24
  const tree = await this.loadVirtual()
25
- if (this[_workspaces] && this[_workspaces].length)
25
+ if (this[_workspaces] && this[_workspaces].length) {
26
26
  options.filterSet = this.workspaceDependencySet(tree, this[_workspaces])
27
+ }
27
28
  this.auditReport = await AuditReport.load(tree, options)
28
29
  const ret = options.fix ? this.reify(options) : this.auditReport
29
30
  process.emit('timeEnd', 'audit')