@npmcli/arborist 2.2.9 → 2.4.2

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.
@@ -20,13 +20,21 @@ const levelMap = new Map(levels.reduce((set, level, index) => {
20
20
  }, []))
21
21
 
22
22
  const { inspect, format } = require('util')
23
+ const colors = process.stderr.isTTY
24
+ const magenta = colors ? msg => `\x1B[35m${msg}\x1B[39m` : m => m
23
25
  if (loglevel !== 'silent') {
24
26
  process.on('log', (level, ...args) => {
25
27
  if (levelMap.get(level) < levelMap.get(loglevel))
26
28
  return
27
- const pref = `${process.pid} ${level} `
29
+ const pref = `${process.pid} ${magenta(level)} `
28
30
  if (level === 'warn' && args[0] === 'ERESOLVE')
29
- args[2] = inspect(args[2], { depth: 10 })
31
+ args[2] = inspect(args[2], { depth: 10, colors })
32
+ else {
33
+ args = args.map(a => {
34
+ return typeof a === 'string' ? a
35
+ : inspect(a, { depth: 10, colors })
36
+ })
37
+ }
30
38
  const msg = pref + format(...args).trim().split('\n').join(`\n${pref}`)
31
39
  console.error(msg)
32
40
  })
@@ -33,7 +33,13 @@ for (const arg of process.argv.slice(2)) {
33
33
  options.omit.push(arg.substr('--omit='.length))
34
34
  } else if (/^--before=/.test(arg))
35
35
  options.before = new Date(arg.substr('--before='.length))
36
- else if (/^--[^=]+=/.test(arg)) {
36
+ else if (/^-w.+/.test(arg)) {
37
+ options.workspaces = options.workspaces || []
38
+ options.workspaces.push(arg.replace(/^-w/, ''))
39
+ } else if (/^--workspace=/.test(arg)) {
40
+ options.workspaces = options.workspaces || []
41
+ options.workspaces.push(arg.replace(/^--workspace=/, ''))
42
+ } else if (/^--[^=]+=/.test(arg)) {
37
43
  const [key, ...v] = arg.replace(/^--/, '').split('=')
38
44
  const val = v.join('=')
39
45
  options[key] = val === 'false' ? false : val === 'true' ? true : val
package/bin/lib/timers.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const timers = Object.create(null)
2
+ const { format } = require('util')
2
3
 
3
4
  process.on('time', name => {
4
5
  if (timers[name])
@@ -6,17 +7,20 @@ process.on('time', name => {
6
7
  timers[name] = process.hrtime()
7
8
  })
8
9
 
10
+ const dim = process.stderr.isTTY ? msg => `\x1B[2m${msg}\x1B[22m` : m => m
11
+ const red = process.stderr.isTTY ? msg => `\x1B[31m${msg}\x1B[39m` : m => m
9
12
  process.on('timeEnd', name => {
10
13
  if (!timers[name])
11
14
  throw new Error('timer not started! ' + name)
12
15
  const res = process.hrtime(timers[name])
13
16
  delete timers[name]
14
- console.error(`${process.pid} ${name}`, res[0] * 1e3 + res[1] / 1e6)
17
+ const msg = format(`${process.pid} ${name}`, res[0] * 1e3 + res[1] / 1e6)
18
+ console.error(dim(msg))
15
19
  })
16
20
 
17
21
  process.on('exit', () => {
18
22
  for (const name of Object.keys(timers)) {
19
- console.error('Dangling timer: ', name)
23
+ console.error(red('Dangling timer:'), name)
20
24
  process.exitCode = 1
21
25
  }
22
26
  })
package/bin/virtual.js CHANGED
@@ -8,7 +8,8 @@ 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
- print(tree)
11
+ if (!options.quiet)
12
+ print(tree)
12
13
  if (options.save)
13
14
  tree.meta.save()
14
15
  console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`)
@@ -1,60 +1,60 @@
1
1
  // add and remove dependency specs to/from pkg manifest
2
2
 
3
- const removeFromOthers = (name, type, pkg) => {
4
- const others = new Set([
5
- 'dependencies',
6
- 'optionalDependencies',
7
- 'devDependencies',
8
- 'peerDependenciesMeta',
9
- 'peerDependencies',
10
- ])
11
-
12
- switch (type) {
13
- case 'prod':
14
- others.delete('dependencies')
15
- break
16
- case 'dev':
17
- others.delete('devDependencies')
18
- others.delete('peerDependencies')
19
- others.delete('peerDependenciesMeta')
20
- break
21
- case 'optional':
22
- others.delete('optionalDependencies')
23
- break
24
- case 'peer':
25
- case 'peerOptional':
26
- others.delete('devDependencies')
27
- others.delete('peerDependencies')
28
- others.delete('peerDependenciesMeta')
29
- break
30
- }
31
-
32
- for (const other of others)
33
- deleteSubKey(pkg, other, name)
34
- }
35
-
36
- const add = ({pkg, add, saveBundle, saveType}) => {
3
+ const add = ({pkg, add, saveBundle, saveType, log}) => {
37
4
  for (const spec of add)
38
- addSingle({pkg, spec, saveBundle, saveType})
5
+ addSingle({pkg, spec, saveBundle, saveType, log})
39
6
 
40
7
  return pkg
41
8
  }
42
9
 
43
- const addSingle = ({pkg, spec, saveBundle, saveType}) => {
44
- if (!saveType)
45
- saveType = getSaveType(pkg, spec)
10
+ // Canonical source of both the map between saveType and where it correlates to
11
+ // in the package, and the names of all our dependencies attributes
12
+ const saveTypeMap = new Map([
13
+ ['dev', 'devDependencies'],
14
+ ['optional', 'optionalDependencies'],
15
+ ['prod', 'dependencies'],
16
+ ['peerOptional', 'peerDependencies'],
17
+ ['peer', 'peerDependencies'],
18
+ ])
46
19
 
20
+ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => {
47
21
  const { name, rawSpec } = spec
48
- removeFromOthers(name, saveType, pkg)
49
- const type = saveType === 'prod' ? 'dependencies'
50
- : saveType === 'optional' ? 'optionalDependencies'
51
- : saveType === 'peer' || saveType === 'peerOptional' ? 'peerDependencies'
52
- : saveType === 'dev' ? 'devDependencies'
53
- : /* istanbul ignore next */ null
54
22
 
55
- pkg[type] = pkg[type] || {}
56
- if (rawSpec !== '' || pkg[type][name] === undefined)
57
- pkg[type][name] = rawSpec || '*'
23
+ // if the user does not give us a type, we infer which type(s)
24
+ // to keep based on the same order of priority we do when
25
+ // building the tree as defined in the _loadDeps method of
26
+ // the node class.
27
+ if (!saveType)
28
+ saveType = inferSaveType(pkg, spec.name)
29
+
30
+ if (saveType === 'prod') {
31
+ // a production dependency can only exist as production (rpj ensures it
32
+ // doesn't coexist w/ optional)
33
+ deleteSubKey(pkg, 'devDependencies', name, 'dependencies', log)
34
+ deleteSubKey(pkg, 'peerDependencies', name, 'dependencies', log)
35
+ } else if (saveType === 'dev') {
36
+ // a dev dependency may co-exist as peer, or optional, but not production
37
+ deleteSubKey(pkg, 'dependencies', name, 'devDependencies', log)
38
+ } else if (saveType === 'optional') {
39
+ // an optional dependency may co-exist as dev (rpj ensures it doesn't
40
+ // coexist w/ prod)
41
+ deleteSubKey(pkg, 'peerDependencies', name, 'optionalDependencies', log)
42
+ } else { // peer or peerOptional is all that's left
43
+ // a peer dependency may coexist as dev
44
+ deleteSubKey(pkg, 'dependencies', name, 'peerDependencies', log)
45
+ deleteSubKey(pkg, 'optionalDependencies', name, 'peerDependencies', log)
46
+ }
47
+
48
+ const depType = saveTypeMap.get(saveType)
49
+
50
+ pkg[depType] = pkg[depType] || {}
51
+ if (rawSpec !== '' || pkg[depType][name] === undefined)
52
+ pkg[depType][name] = rawSpec || '*'
53
+ if (saveType === 'optional') {
54
+ // Affordance for previous npm versions that require this behaviour
55
+ pkg.dependencies = pkg.dependencies || {}
56
+ pkg.dependencies[name] = pkg.optionalDependencies[name]
57
+ }
58
58
 
59
59
  if (saveType === 'peer' || saveType === 'peerOptional') {
60
60
  const pdm = pkg.peerDependenciesMeta || {}
@@ -79,47 +79,49 @@ const addSingle = ({pkg, spec, saveBundle, saveType}) => {
79
79
  }
80
80
  }
81
81
 
82
- const getSaveType = (pkg, spec) => {
83
- const {name} = spec
84
- const {
85
- // these names are so lonnnnngggg
86
- devDependencies: devDeps,
87
- optionalDependencies: optDeps,
88
- peerDependencies: peerDeps,
89
- peerDependenciesMeta: peerDepsMeta,
90
- } = pkg
91
-
92
- if (peerDeps && peerDeps[name] !== undefined) {
93
- if (peerDepsMeta && peerDepsMeta[name] && peerDepsMeta[name].optional)
94
- return 'peerOptional'
95
- else
96
- return 'peer'
97
- } else if (devDeps && devDeps[name] !== undefined)
98
- return 'dev'
99
- else if (optDeps && optDeps[name] !== undefined)
100
- return 'optional'
101
- else
102
- return 'prod'
82
+ // Finds where the package is already in the spec and infers saveType from that
83
+ const inferSaveType = (pkg, name) => {
84
+ for (const saveType of saveTypeMap.keys()) {
85
+ if (hasSubKey(pkg, saveTypeMap.get(saveType), name)) {
86
+ if (
87
+ saveType === 'peerOptional' &&
88
+ (!hasSubKey(pkg, 'peerDependenciesMeta', name) ||
89
+ !pkg.peerDependenciesMeta[name].optional)
90
+ )
91
+ return 'peer'
92
+ return saveType
93
+ }
94
+ }
95
+ return 'prod'
103
96
  }
104
97
 
105
- const deleteSubKey = (obj, k, sk) => {
106
- if (obj[k]) {
107
- delete obj[k][sk]
108
- if (!Object.keys(obj[k]).length)
109
- delete obj[k]
98
+ const hasSubKey = (pkg, depType, name) => {
99
+ return pkg[depType] && Object.prototype.hasOwnProperty.call(pkg[depType], name)
100
+ }
101
+
102
+ // Removes a subkey and warns about it if it's being replaced
103
+ const deleteSubKey = (pkg, depType, name, replacedBy, log) => {
104
+ if (hasSubKey(pkg, depType, name)) {
105
+ if (replacedBy && log)
106
+ log.warn('idealTree', `Removing ${depType}.${name} in favor of ${replacedBy}.${name}`)
107
+ delete pkg[depType][name]
108
+
109
+ // clean up peerDependenciesMeta if we are removing something from peerDependencies
110
+ if (depType === 'peerDependencies' && pkg.peerDependenciesMeta) {
111
+ delete pkg.peerDependenciesMeta[name]
112
+ if (!Object.keys(pkg.peerDependenciesMeta).length)
113
+ delete pkg.peerDependenciesMeta
114
+ }
115
+
116
+ if (!Object.keys(pkg[depType]).length)
117
+ delete pkg[depType]
110
118
  }
111
119
  }
112
120
 
113
121
  const rm = (pkg, rm) => {
114
- for (const type of [
115
- 'dependencies',
116
- 'optionalDependencies',
117
- 'peerDependencies',
118
- 'peerDependenciesMeta',
119
- 'devDependencies',
120
- ]) {
122
+ for (const depType of new Set(saveTypeMap.values())) {
121
123
  for (const name of rm)
122
- deleteSubKey(pkg, type, name)
124
+ deleteSubKey(pkg, depType, name)
123
125
  }
124
126
  if (pkg.bundleDependencies) {
125
127
  pkg.bundleDependencies = pkg.bundleDependencies
@@ -130,4 +132,4 @@ const rm = (pkg, rm) => {
130
132
  return pkg
131
133
  }
132
134
 
133
- module.exports = { add, rm }
135
+ module.exports = { add, rm, saveTypeMap, hasSubKey }