@npmcli/arborist 2.8.2 → 2.9.0
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 +28 -15
- package/lib/arborist/audit.js +2 -1
- package/lib/arborist/build-ideal-tree.js +139 -72
- 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 +37 -20
- package/lib/arborist/load-workspaces.js +4 -2
- package/lib/arborist/rebuild.js +34 -17
- package/lib/arborist/reify.js +153 -76
- package/lib/audit-report.js +44 -23
- package/lib/calc-dep-flags.js +18 -9
- package/lib/can-place-dep.js +59 -30
- 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 +111 -37
- package/lib/printable.js +46 -25
- package/lib/realpath.js +12 -6
- package/lib/shrinkwrap.js +164 -90
- 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 +44 -22
- package/lib/yarn-lock.js +34 -21
- package/package.json +8 -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
|
-
|
|
44
|
+
}
|
|
45
|
+
if (!options.quiet) {
|
|
43
46
|
printReport(arb.auditReport)
|
|
44
|
-
|
|
47
|
+
}
|
|
48
|
+
if (options.fix) {
|
|
45
49
|
console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`)
|
|
46
|
-
|
|
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)
|
package/bin/lib/logging.js
CHANGED
|
@@ -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 })
|
package/bin/lib/options.js
CHANGED
|
@@ -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
|
-
|
|
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))
|
package/lib/add-rm-pkg-deps.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
// add and remove dependency specs to/from pkg manifest
|
|
2
2
|
|
|
3
|
+
const localeCompare = require('@isaacs/string-locale-compare')('en')
|
|
4
|
+
|
|
3
5
|
const add = ({pkg, add, saveBundle, saveType, log}) => {
|
|
4
|
-
for (const spec of add)
|
|
6
|
+
for (const spec of add) {
|
|
5
7
|
addSingle({pkg, spec, saveBundle, saveType, log})
|
|
8
|
+
}
|
|
6
9
|
|
|
7
10
|
return pkg
|
|
8
11
|
}
|
|
@@ -24,8 +27,9 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => {
|
|
|
24
27
|
// to keep based on the same order of priority we do when
|
|
25
28
|
// building the tree as defined in the _loadDeps method of
|
|
26
29
|
// the node class.
|
|
27
|
-
if (!saveType)
|
|
30
|
+
if (!saveType) {
|
|
28
31
|
saveType = inferSaveType(pkg, spec.name)
|
|
32
|
+
}
|
|
29
33
|
|
|
30
34
|
if (saveType === 'prod') {
|
|
31
35
|
// a production dependency can only exist as production (rpj ensures it
|
|
@@ -48,8 +52,9 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => {
|
|
|
48
52
|
const depType = saveTypeMap.get(saveType)
|
|
49
53
|
|
|
50
54
|
pkg[depType] = pkg[depType] || {}
|
|
51
|
-
if (rawSpec !== '' || pkg[depType][name] === undefined)
|
|
55
|
+
if (rawSpec !== '' || pkg[depType][name] === undefined) {
|
|
52
56
|
pkg[depType][name] = rawSpec || '*'
|
|
57
|
+
}
|
|
53
58
|
if (saveType === 'optional') {
|
|
54
59
|
// Affordance for previous npm versions that require this behaviour
|
|
55
60
|
pkg.dependencies = pkg.dependencies || {}
|
|
@@ -58,24 +63,25 @@ const addSingle = ({pkg, spec, saveBundle, saveType, log}) => {
|
|
|
58
63
|
|
|
59
64
|
if (saveType === 'peer' || saveType === 'peerOptional') {
|
|
60
65
|
const pdm = pkg.peerDependenciesMeta || {}
|
|
61
|
-
if (saveType === 'peer' && pdm[name] && pdm[name].optional)
|
|
66
|
+
if (saveType === 'peer' && pdm[name] && pdm[name].optional) {
|
|
62
67
|
pdm[name].optional = false
|
|
63
|
-
else if (saveType === 'peerOptional') {
|
|
68
|
+
} else if (saveType === 'peerOptional') {
|
|
64
69
|
pdm[name] = pdm[name] || {}
|
|
65
70
|
pdm[name].optional = true
|
|
66
71
|
pkg.peerDependenciesMeta = pdm
|
|
67
72
|
}
|
|
68
73
|
// peerDeps are often also a devDep, so that they can be tested when
|
|
69
74
|
// using package managers that don't auto-install peer deps
|
|
70
|
-
if (pkg.devDependencies && pkg.devDependencies[name] !== undefined)
|
|
75
|
+
if (pkg.devDependencies && pkg.devDependencies[name] !== undefined) {
|
|
71
76
|
pkg.devDependencies[name] = pkg.peerDependencies[name]
|
|
77
|
+
}
|
|
72
78
|
}
|
|
73
79
|
|
|
74
80
|
if (saveBundle && saveType !== 'peer' && saveType !== 'peerOptional') {
|
|
75
81
|
// keep it sorted, keep it unique
|
|
76
82
|
const bd = new Set(pkg.bundleDependencies || [])
|
|
77
83
|
bd.add(spec.name)
|
|
78
|
-
pkg.bundleDependencies = [...bd].sort(
|
|
84
|
+
pkg.bundleDependencies = [...bd].sort(localeCompare)
|
|
79
85
|
}
|
|
80
86
|
}
|
|
81
87
|
|
|
@@ -87,47 +93,54 @@ const inferSaveType = (pkg, name) => {
|
|
|
87
93
|
saveType === 'peerOptional' &&
|
|
88
94
|
(!hasSubKey(pkg, 'peerDependenciesMeta', name) ||
|
|
89
95
|
!pkg.peerDependenciesMeta[name].optional)
|
|
90
|
-
)
|
|
96
|
+
) {
|
|
91
97
|
return 'peer'
|
|
98
|
+
}
|
|
92
99
|
return saveType
|
|
93
100
|
}
|
|
94
101
|
}
|
|
95
102
|
return 'prod'
|
|
96
103
|
}
|
|
97
104
|
|
|
105
|
+
const { hasOwnProperty } = Object.prototype
|
|
98
106
|
const hasSubKey = (pkg, depType, name) => {
|
|
99
|
-
return pkg[depType] &&
|
|
107
|
+
return pkg[depType] && hasOwnProperty.call(pkg[depType], name)
|
|
100
108
|
}
|
|
101
109
|
|
|
102
110
|
// Removes a subkey and warns about it if it's being replaced
|
|
103
111
|
const deleteSubKey = (pkg, depType, name, replacedBy, log) => {
|
|
104
112
|
if (hasSubKey(pkg, depType, name)) {
|
|
105
|
-
if (replacedBy && log)
|
|
113
|
+
if (replacedBy && log) {
|
|
106
114
|
log.warn('idealTree', `Removing ${depType}.${name} in favor of ${replacedBy}.${name}`)
|
|
115
|
+
}
|
|
107
116
|
delete pkg[depType][name]
|
|
108
117
|
|
|
109
|
-
// clean up
|
|
118
|
+
// clean up peerDepsMeta if we are removing something from peerDependencies
|
|
110
119
|
if (depType === 'peerDependencies' && pkg.peerDependenciesMeta) {
|
|
111
120
|
delete pkg.peerDependenciesMeta[name]
|
|
112
|
-
if (!Object.keys(pkg.peerDependenciesMeta).length)
|
|
121
|
+
if (!Object.keys(pkg.peerDependenciesMeta).length) {
|
|
113
122
|
delete pkg.peerDependenciesMeta
|
|
123
|
+
}
|
|
114
124
|
}
|
|
115
125
|
|
|
116
|
-
if (!Object.keys(pkg[depType]).length)
|
|
126
|
+
if (!Object.keys(pkg[depType]).length) {
|
|
117
127
|
delete pkg[depType]
|
|
128
|
+
}
|
|
118
129
|
}
|
|
119
130
|
}
|
|
120
131
|
|
|
121
132
|
const rm = (pkg, rm) => {
|
|
122
133
|
for (const depType of new Set(saveTypeMap.values())) {
|
|
123
|
-
for (const name of rm)
|
|
134
|
+
for (const name of rm) {
|
|
124
135
|
deleteSubKey(pkg, depType, name)
|
|
136
|
+
}
|
|
125
137
|
}
|
|
126
138
|
if (pkg.bundleDependencies) {
|
|
127
139
|
pkg.bundleDependencies = pkg.bundleDependencies
|
|
128
140
|
.filter(name => !rm.includes(name))
|
|
129
|
-
if (!pkg.bundleDependencies.length)
|
|
141
|
+
if (!pkg.bundleDependencies.length) {
|
|
130
142
|
delete pkg.bundleDependencies
|
|
143
|
+
}
|
|
131
144
|
}
|
|
132
145
|
return pkg
|
|
133
146
|
}
|
package/lib/arborist/audit.js
CHANGED
|
@@ -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')
|