@npmcli/arborist 6.0.0-pre.3 → 6.0.0-pre.5
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/lib/logging.js +1 -2
- package/lib/add-rm-pkg-deps.js +2 -2
- package/lib/arborist/build-ideal-tree.js +12 -18
- package/lib/arborist/index.js +1 -0
- package/lib/arborist/reify.js +29 -21
- package/lib/consistent-resolve.js +17 -11
- package/lib/edge.js +1 -1
- package/lib/override-set.js +4 -7
- package/lib/place-dep.js +6 -9
- package/lib/query-selector-all.js +4 -4
- package/lib/realpath.js +1 -4
- package/lib/shrinkwrap.js +34 -41
- package/package.json +26 -29
package/bin/lib/logging.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const log = require('proc-log')
|
|
2
|
-
const mkdirp = require('mkdirp')
|
|
3
2
|
const fs = require('fs')
|
|
4
3
|
const { dirname } = require('path')
|
|
5
4
|
const os = require('os')
|
|
@@ -70,7 +69,7 @@ if (options.loglevel !== 'silent') {
|
|
|
70
69
|
|
|
71
70
|
if (options.logfile) {
|
|
72
71
|
log.silly('logfile', options.logfile)
|
|
73
|
-
|
|
72
|
+
fs.mkdirSync(dirname(options.logfile), { recursive: true })
|
|
74
73
|
const fd = fs.openSync(options.logfile, 'a')
|
|
75
74
|
addLogListener((str) => fs.writeSync(fd, str))
|
|
76
75
|
}
|
package/lib/add-rm-pkg-deps.js
CHANGED
|
@@ -35,8 +35,8 @@ const add = ({ pkg, add, saveBundle, saveType }) => {
|
|
|
35
35
|
const depType = saveTypeMap.get(addSaveType)
|
|
36
36
|
|
|
37
37
|
pkg[depType] = pkg[depType] || {}
|
|
38
|
-
if (rawSpec !== '' || pkg[depType][name] === undefined) {
|
|
39
|
-
pkg[depType][name] = rawSpec
|
|
38
|
+
if (rawSpec !== '*' || pkg[depType][name] === undefined) {
|
|
39
|
+
pkg[depType][name] = rawSpec
|
|
40
40
|
}
|
|
41
41
|
if (addSaveType === 'optional') {
|
|
42
42
|
// Affordance for previous npm versions that require this behaviour
|
|
@@ -10,9 +10,7 @@ const { resolve, dirname } = require('path')
|
|
|
10
10
|
const { promisify } = require('util')
|
|
11
11
|
const treeCheck = require('../tree-check.js')
|
|
12
12
|
const readdir = promisify(require('readdir-scoped-modules'))
|
|
13
|
-
const
|
|
14
|
-
const lstat = promisify(fs.lstat)
|
|
15
|
-
const readlink = promisify(fs.readlink)
|
|
13
|
+
const { lstat, readlink } = require('fs/promises')
|
|
16
14
|
const { depth } = require('treeverse')
|
|
17
15
|
const log = require('proc-log')
|
|
18
16
|
|
|
@@ -48,7 +46,6 @@ const _flagsSuspect = Symbol.for('flagsSuspect')
|
|
|
48
46
|
const _workspaces = Symbol.for('workspaces')
|
|
49
47
|
const _prune = Symbol('prune')
|
|
50
48
|
const _preferDedupe = Symbol('preferDedupe')
|
|
51
|
-
const _legacyBundling = Symbol('legacyBundling')
|
|
52
49
|
const _parseSettings = Symbol('parseSettings')
|
|
53
50
|
const _initTree = Symbol('initTree')
|
|
54
51
|
const _applyUserRequests = Symbol('applyUserRequests')
|
|
@@ -79,7 +76,7 @@ const _loadFailures = Symbol('loadFailures')
|
|
|
79
76
|
const _pruneFailedOptional = Symbol('pruneFailedOptional')
|
|
80
77
|
const _linkNodes = Symbol('linkNodes')
|
|
81
78
|
const _follow = Symbol('follow')
|
|
82
|
-
const
|
|
79
|
+
const _installStrategy = Symbol('installStrategy')
|
|
83
80
|
const _globalRootNode = Symbol('globalRootNode')
|
|
84
81
|
const _usePackageLock = Symbol.for('usePackageLock')
|
|
85
82
|
const _rpcache = Symbol.for('realpathCache')
|
|
@@ -114,7 +111,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
114
111
|
follow = false,
|
|
115
112
|
force = false,
|
|
116
113
|
global = false,
|
|
117
|
-
|
|
114
|
+
installStrategy = 'hoisted',
|
|
118
115
|
idealTree = null,
|
|
119
116
|
includeWorkspaceRoot = false,
|
|
120
117
|
installLinks = false,
|
|
@@ -134,7 +131,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
134
131
|
|
|
135
132
|
this[_usePackageLock] = packageLock
|
|
136
133
|
this[_global] = !!global
|
|
137
|
-
this[
|
|
134
|
+
this[_installStrategy] = global ? 'shallow' : installStrategy
|
|
138
135
|
this[_follow] = !!follow
|
|
139
136
|
|
|
140
137
|
if (this[_workspaces].length && this[_global]) {
|
|
@@ -143,7 +140,6 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
143
140
|
|
|
144
141
|
this[_explicitRequests] = new Set()
|
|
145
142
|
this[_preferDedupe] = false
|
|
146
|
-
this[_legacyBundling] = false
|
|
147
143
|
this[_depsSeen] = new Set()
|
|
148
144
|
this[_depsQueue] = []
|
|
149
145
|
this[_currentDep] = null
|
|
@@ -252,20 +248,18 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
252
248
|
|
|
253
249
|
this[_complete] = !!options.complete
|
|
254
250
|
this[_preferDedupe] = !!options.preferDedupe
|
|
255
|
-
this[_legacyBundling] = !!options.legacyBundling
|
|
256
251
|
|
|
257
252
|
// validates list of update names, they must
|
|
258
253
|
// be dep names only, no semver ranges are supported
|
|
259
254
|
for (const name of update.names) {
|
|
260
255
|
const spec = npa(name)
|
|
261
256
|
const validationError =
|
|
262
|
-
new TypeError(`Update arguments must
|
|
263
|
-
|
|
264
|
-
Try using the package name instead, e.g:
|
|
257
|
+
new TypeError(`Update arguments must only contain package names, eg:
|
|
265
258
|
npm update ${spec.name}`)
|
|
266
259
|
validationError.code = 'EUPDATEARGS'
|
|
267
260
|
|
|
268
|
-
|
|
261
|
+
// If they gave us anything other than a bare package name
|
|
262
|
+
if (spec.raw !== spec.name) {
|
|
269
263
|
throw validationError
|
|
270
264
|
}
|
|
271
265
|
}
|
|
@@ -330,8 +324,7 @@ Try using the package name instead, e.g:
|
|
|
330
324
|
if (tree.children.size) {
|
|
331
325
|
root.meta.loadedFromDisk = true
|
|
332
326
|
// set these so that we don't try to ancient lockfile reload it
|
|
333
|
-
root.meta.originalLockfileVersion = defaultLockfileVersion
|
|
334
|
-
root.meta.lockfileVersion = defaultLockfileVersion
|
|
327
|
+
root.meta.originalLockfileVersion = root.meta.lockfileVersion = this.options.lockfileVersion || defaultLockfileVersion
|
|
335
328
|
}
|
|
336
329
|
}
|
|
337
330
|
root.meta.inferFormattingOptions(root.package)
|
|
@@ -758,7 +751,9 @@ This is a one-time fix-up, please be patient...
|
|
|
758
751
|
// yes, yes, this isn't the "original" version, but now that it's been
|
|
759
752
|
// upgraded, we need to make sure we don't do the work to upgrade it
|
|
760
753
|
// again, since it's now as new as can be.
|
|
761
|
-
meta.
|
|
754
|
+
if (!this.options.lockfileVersion && !meta.hiddenLockfile) {
|
|
755
|
+
meta.originalLockfileVersion = defaultLockfileVersion
|
|
756
|
+
}
|
|
762
757
|
this.finishTracker('idealTree:inflate')
|
|
763
758
|
process.emit('timeEnd', 'idealTree:inflate')
|
|
764
759
|
}
|
|
@@ -951,11 +946,10 @@ This is a one-time fix-up, please be patient...
|
|
|
951
946
|
auditReport: this.auditReport,
|
|
952
947
|
force: this[_force],
|
|
953
948
|
preferDedupe: this[_preferDedupe],
|
|
954
|
-
legacyBundling: this[_legacyBundling],
|
|
955
949
|
strictPeerDeps: this[_strictPeerDeps],
|
|
956
950
|
installLinks: this.installLinks,
|
|
957
951
|
legacyPeerDeps: this.legacyPeerDeps,
|
|
958
|
-
|
|
952
|
+
installStrategy: this[_installStrategy],
|
|
959
953
|
}))
|
|
960
954
|
|
|
961
955
|
const promises = []
|
package/lib/arborist/index.js
CHANGED
|
@@ -76,6 +76,7 @@ class Arborist extends Base {
|
|
|
76
76
|
workspacesEnabled: options.workspacesEnabled !== false,
|
|
77
77
|
replaceRegistryHost: options.replaceRegistryHost,
|
|
78
78
|
lockfileVersion: lockfileVersion(options.lockfileVersion),
|
|
79
|
+
installStrategy: options.global ? 'shallow' : (options.installStrategy ? options.installStrategy : 'hoisted'),
|
|
79
80
|
}
|
|
80
81
|
this.replaceRegistryHost = this.options.replaceRegistryHost =
|
|
81
82
|
(!this.options.replaceRegistryHost || this.options.replaceRegistryHost === 'npmjs') ?
|
package/lib/arborist/reify.js
CHANGED
|
@@ -12,14 +12,13 @@ const log = require('proc-log')
|
|
|
12
12
|
|
|
13
13
|
const { dirname, resolve, relative } = require('path')
|
|
14
14
|
const { depth: dfwalk } = require('treeverse')
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
const {
|
|
16
|
+
lstat,
|
|
17
|
+
mkdir,
|
|
18
|
+
rm,
|
|
19
|
+
symlink,
|
|
20
|
+
} = require('fs/promises')
|
|
21
21
|
const moveFile = require('@npmcli/move-file')
|
|
22
|
-
const rimraf = promisify(require('rimraf'))
|
|
23
22
|
const PackageJson = require('@npmcli/package-json')
|
|
24
23
|
const packageContents = require('@npmcli/installed-package-contents')
|
|
25
24
|
const runScript = require('@npmcli/run-script')
|
|
@@ -35,6 +34,9 @@ const optionalSet = require('../optional-set.js')
|
|
|
35
34
|
const calcDepFlags = require('../calc-dep-flags.js')
|
|
36
35
|
const { saveTypeMap, hasSubKey } = require('../add-rm-pkg-deps.js')
|
|
37
36
|
|
|
37
|
+
const Shrinkwrap = require('../shrinkwrap.js')
|
|
38
|
+
const { defaultLockfileVersion } = Shrinkwrap
|
|
39
|
+
|
|
38
40
|
const _retiredPaths = Symbol('retiredPaths')
|
|
39
41
|
const _retiredUnchanged = Symbol('retiredUnchanged')
|
|
40
42
|
const _sparseTreeDirs = Symbol('sparseTreeDirs')
|
|
@@ -172,7 +174,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
172
174
|
// we do NOT want to set ownership on this folder, especially
|
|
173
175
|
// recursively, because it can have other side effects to do that
|
|
174
176
|
// in a project directory. We just want to make it if it's missing.
|
|
175
|
-
await
|
|
177
|
+
await mkdir(resolve(this.path), { recursive: true })
|
|
176
178
|
|
|
177
179
|
// do not allow the top-level node_modules to be a symlink
|
|
178
180
|
await this[_validateNodeModules](resolve(this.path, 'node_modules'))
|
|
@@ -430,10 +432,10 @@ module.exports = cls => class Reifier extends cls {
|
|
|
430
432
|
// handled the most common cause of ENOENT (dir doesn't exist yet),
|
|
431
433
|
// then just ignore any ENOENT.
|
|
432
434
|
if (er.code === 'ENOENT') {
|
|
433
|
-
return didMkdirp ? null :
|
|
435
|
+
return didMkdirp ? null : mkdir(dirname(to), { recursive: true }).then(() =>
|
|
434
436
|
this[_renamePath](from, to, true))
|
|
435
437
|
} else if (er.code === 'EEXIST') {
|
|
436
|
-
return
|
|
438
|
+
return rm(to, { recursive: true, force: true }).then(() => moveFile(from, to))
|
|
437
439
|
} else {
|
|
438
440
|
throw er
|
|
439
441
|
}
|
|
@@ -515,7 +517,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
515
517
|
await this[_renamePath](d, retired)
|
|
516
518
|
}
|
|
517
519
|
}
|
|
518
|
-
const made = await
|
|
520
|
+
const made = await mkdir(node.path, { recursive: true })
|
|
519
521
|
this[_sparseTreeDirs].add(node.path)
|
|
520
522
|
this[_sparseTreeRoots].add(made)
|
|
521
523
|
}))
|
|
@@ -530,7 +532,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
530
532
|
const failures = []
|
|
531
533
|
const targets = [...roots, ...Object.keys(this[_retiredPaths])]
|
|
532
534
|
const unlinks = targets
|
|
533
|
-
.map(path =>
|
|
535
|
+
.map(path => rm(path, { recursive: true, force: true }).catch(er => failures.push([path, er])))
|
|
534
536
|
return promiseAllRejectLate(unlinks).then(() => {
|
|
535
537
|
// eslint-disable-next-line promise/always-return
|
|
536
538
|
if (failures.length) {
|
|
@@ -627,7 +629,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
627
629
|
return
|
|
628
630
|
}
|
|
629
631
|
log.warn('reify', 'Removing non-directory', nm)
|
|
630
|
-
await
|
|
632
|
+
await rm(nm, { recursive: true, force: true })
|
|
631
633
|
}
|
|
632
634
|
|
|
633
635
|
async [_extractOrLink] (node) {
|
|
@@ -661,7 +663,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
661
663
|
await this[_validateNodeModules](nm)
|
|
662
664
|
|
|
663
665
|
if (node.isLink) {
|
|
664
|
-
await
|
|
666
|
+
await rm(node.path, { recursive: true, force: true })
|
|
665
667
|
await this[_symlink](node)
|
|
666
668
|
} else {
|
|
667
669
|
await debug(async () => {
|
|
@@ -687,7 +689,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
687
689
|
const dir = dirname(node.path)
|
|
688
690
|
const target = node.realpath
|
|
689
691
|
const rel = relative(dir, target)
|
|
690
|
-
await
|
|
692
|
+
await mkdir(dir, { recursive: true })
|
|
691
693
|
return symlink(rel, node.path, 'junction')
|
|
692
694
|
}
|
|
693
695
|
|
|
@@ -950,7 +952,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
950
952
|
|
|
951
953
|
// ok! actually unpack stuff into their target locations!
|
|
952
954
|
// The sparse tree has already been created, so we walk the diff
|
|
953
|
-
// kicking off each unpack job. If any fail, we
|
|
955
|
+
// kicking off each unpack job. If any fail, we rm the sparse
|
|
954
956
|
// tree entirely and try to put everything back where it was.
|
|
955
957
|
[_unpackNewModules] () {
|
|
956
958
|
process.emit('time', 'reify:unpack')
|
|
@@ -1031,7 +1033,8 @@ module.exports = cls => class Reifier extends cls {
|
|
|
1031
1033
|
return promiseAllRejectLate(diff.unchanged.map(node => {
|
|
1032
1034
|
// no need to roll back links, since we'll just delete them anyway
|
|
1033
1035
|
if (node.isLink) {
|
|
1034
|
-
return
|
|
1036
|
+
return mkdir(dirname(node.path), { recursive: true, force: true })
|
|
1037
|
+
.then(() => this[_reifyNode](node))
|
|
1035
1038
|
}
|
|
1036
1039
|
|
|
1037
1040
|
// will have been moved/unpacked along with bundler
|
|
@@ -1047,7 +1050,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
1047
1050
|
// skip it.
|
|
1048
1051
|
const bd = node.package.bundleDependencies
|
|
1049
1052
|
const dir = bd && bd.length ? node.path + '/node_modules' : node.path
|
|
1050
|
-
return
|
|
1053
|
+
return mkdir(dir, { recursive: true }).then(() => this[_moveContents](node, fromPath))
|
|
1051
1054
|
}))
|
|
1052
1055
|
}))
|
|
1053
1056
|
.then(() => process.emit('timeEnd', 'reify:unretire'))
|
|
@@ -1121,15 +1124,15 @@ module.exports = cls => class Reifier extends cls {
|
|
|
1121
1124
|
// the tree is pretty much built now, so it's cleanup time.
|
|
1122
1125
|
// remove the retired folders, and any deleted nodes
|
|
1123
1126
|
// If this fails, there isn't much we can do but tell the user about it.
|
|
1124
|
-
// Thankfully, it's pretty unlikely that it'll fail, since
|
|
1127
|
+
// Thankfully, it's pretty unlikely that it'll fail, since rm is a node builtin.
|
|
1125
1128
|
async [_removeTrash] () {
|
|
1126
1129
|
process.emit('time', 'reify:trash')
|
|
1127
1130
|
const promises = []
|
|
1128
1131
|
const failures = []
|
|
1129
|
-
const
|
|
1132
|
+
const _rm = path => rm(path, { recursive: true, force: true }).catch(er => failures.push([path, er]))
|
|
1130
1133
|
|
|
1131
1134
|
for (const path of this[_trashList]) {
|
|
1132
|
-
promises.push(
|
|
1135
|
+
promises.push(_rm(path))
|
|
1133
1136
|
}
|
|
1134
1137
|
|
|
1135
1138
|
await promiseAllRejectLate(promises)
|
|
@@ -1514,11 +1517,16 @@ module.exports = cls => class Reifier extends cls {
|
|
|
1514
1517
|
this.idealTree.meta.filename =
|
|
1515
1518
|
this.idealTree.realpath + '/node_modules/.package-lock.json'
|
|
1516
1519
|
this.idealTree.meta.hiddenLockfile = true
|
|
1520
|
+
const resetMeta = this.idealTree.meta && this.idealTree.meta.lockfileVersion !== defaultLockfileVersion
|
|
1521
|
+
this.idealTree.meta.lockfileVersion = defaultLockfileVersion
|
|
1517
1522
|
|
|
1518
1523
|
this.actualTree = this.idealTree
|
|
1519
1524
|
this.idealTree = null
|
|
1520
1525
|
|
|
1521
1526
|
if (!this[_global]) {
|
|
1527
|
+
if (resetMeta) {
|
|
1528
|
+
await this.actualTree.meta.reset()
|
|
1529
|
+
}
|
|
1522
1530
|
await this.actualTree.meta.save()
|
|
1523
1531
|
const ignoreScripts = !!this.options.ignoreScripts
|
|
1524
1532
|
// if we aren't doing a dry run or ignoring scripts and we actually made changes to the dep
|
|
@@ -19,17 +19,23 @@ const consistentResolve = (resolved, fromPath, toPath, relPaths = false) => {
|
|
|
19
19
|
rawSpec,
|
|
20
20
|
raw,
|
|
21
21
|
} = npa(resolved, fromPath)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}`
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
22
|
+
if (type === 'file' || type === 'directory') {
|
|
23
|
+
const cleanFetchSpec = fetchSpec.replace(/#/g, '%23')
|
|
24
|
+
if (relPaths && toPath) {
|
|
25
|
+
return `file:${relpath(toPath, cleanFetchSpec)}`
|
|
26
|
+
}
|
|
27
|
+
return `file:${cleanFetchSpec}`
|
|
28
|
+
}
|
|
29
|
+
if (hosted) {
|
|
30
|
+
return `git+${hosted.auth ? hosted.https(hostedOpt) : hosted.sshurl(hostedOpt)}`
|
|
31
|
+
}
|
|
32
|
+
if (type === 'git') {
|
|
33
|
+
return saveSpec
|
|
34
|
+
}
|
|
35
|
+
if (rawSpec === '*') {
|
|
36
|
+
return raw
|
|
37
|
+
}
|
|
38
|
+
return rawSpec
|
|
33
39
|
} catch (_) {
|
|
34
40
|
// whatever we passed in was not acceptable to npa.
|
|
35
41
|
// leave it 100% untouched.
|
package/lib/edge.js
CHANGED
|
@@ -166,7 +166,7 @@ class Edge {
|
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
get spec () {
|
|
169
|
-
if (this.overrides && this.overrides.value && this.overrides.name === this.name) {
|
|
169
|
+
if (this.overrides?.value && this.overrides.value !== '*' && this.overrides.name === this.name) {
|
|
170
170
|
if (this.overrides.value.startsWith('$')) {
|
|
171
171
|
const ref = this.overrides.value.slice(1)
|
|
172
172
|
// we may be a virtual root, if we are we want to resolve reference overrides
|
package/lib/override-set.js
CHANGED
|
@@ -25,7 +25,7 @@ class OverrideSet {
|
|
|
25
25
|
this.name = spec.name
|
|
26
26
|
spec.name = ''
|
|
27
27
|
this.key = key
|
|
28
|
-
this.keySpec = spec.
|
|
28
|
+
this.keySpec = spec.toString()
|
|
29
29
|
this.value = overrides['.'] || this.keySpec
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -50,8 +50,7 @@ class OverrideSet {
|
|
|
50
50
|
continue
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
if (rule.keySpec
|
|
54
|
-
semver.intersects(edge.spec, rule.keySpec)) {
|
|
53
|
+
if (semver.intersects(edge.spec, rule.keySpec)) {
|
|
55
54
|
return rule
|
|
56
55
|
}
|
|
57
56
|
}
|
|
@@ -65,8 +64,7 @@ class OverrideSet {
|
|
|
65
64
|
continue
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
if (rule.keySpec
|
|
69
|
-
semver.satisfies(node.version, rule.keySpec) ||
|
|
67
|
+
if (semver.satisfies(node.version, rule.keySpec) ||
|
|
70
68
|
semver.satisfies(node.version, rule.value)) {
|
|
71
69
|
return rule
|
|
72
70
|
}
|
|
@@ -81,8 +79,7 @@ class OverrideSet {
|
|
|
81
79
|
continue
|
|
82
80
|
}
|
|
83
81
|
|
|
84
|
-
if (rule.keySpec
|
|
85
|
-
semver.satisfies(node.version, rule.keySpec) ||
|
|
82
|
+
if (semver.satisfies(node.version, rule.keySpec) ||
|
|
86
83
|
semver.satisfies(node.version, rule.value)) {
|
|
87
84
|
return rule
|
|
88
85
|
}
|
package/lib/place-dep.js
CHANGED
|
@@ -43,11 +43,10 @@ class PlaceDep {
|
|
|
43
43
|
explicitRequest,
|
|
44
44
|
updateNames,
|
|
45
45
|
auditReport,
|
|
46
|
-
legacyBundling,
|
|
47
46
|
strictPeerDeps,
|
|
48
47
|
installLinks,
|
|
49
48
|
legacyPeerDeps,
|
|
50
|
-
|
|
49
|
+
installStrategy,
|
|
51
50
|
} = parent || options
|
|
52
51
|
Object.assign(this, {
|
|
53
52
|
preferDedupe,
|
|
@@ -55,11 +54,10 @@ class PlaceDep {
|
|
|
55
54
|
explicitRequest,
|
|
56
55
|
updateNames,
|
|
57
56
|
auditReport,
|
|
58
|
-
legacyBundling,
|
|
59
57
|
strictPeerDeps,
|
|
60
58
|
installLinks,
|
|
59
|
+
installStrategy,
|
|
61
60
|
legacyPeerDeps,
|
|
62
|
-
globalStyle,
|
|
63
61
|
})
|
|
64
62
|
|
|
65
63
|
this.children = []
|
|
@@ -78,10 +76,9 @@ class PlaceDep {
|
|
|
78
76
|
edge,
|
|
79
77
|
dep,
|
|
80
78
|
preferDedupe,
|
|
81
|
-
globalStyle,
|
|
82
|
-
legacyBundling,
|
|
83
79
|
explicitRequest,
|
|
84
80
|
updateNames,
|
|
81
|
+
installStrategy,
|
|
85
82
|
checks,
|
|
86
83
|
} = this
|
|
87
84
|
|
|
@@ -170,13 +167,13 @@ class PlaceDep {
|
|
|
170
167
|
|
|
171
168
|
// nest packages like npm v1 and v2
|
|
172
169
|
// very disk-inefficient
|
|
173
|
-
if (
|
|
170
|
+
if (installStrategy === 'nested') {
|
|
174
171
|
break
|
|
175
172
|
}
|
|
176
173
|
|
|
177
174
|
// when installing globally, or just in global style, we never place
|
|
178
175
|
// deps above the first level.
|
|
179
|
-
if (
|
|
176
|
+
if (installStrategy === 'shallow') {
|
|
180
177
|
const rp = target.resolveParent
|
|
181
178
|
if (rp && rp.isProjectRoot) {
|
|
182
179
|
break
|
|
@@ -463,7 +460,7 @@ class PlaceDep {
|
|
|
463
460
|
// prune all the nodes in a branch of the tree that can be safely removed
|
|
464
461
|
// This is only the most basic duplication detection; it finds if there
|
|
465
462
|
// is another satisfying node further up the tree, and if so, dedupes.
|
|
466
|
-
// Even in
|
|
463
|
+
// Even in installStategy is nested, we do this amount of deduplication.
|
|
467
464
|
pruneDedupable (node, descend = true) {
|
|
468
465
|
if (node.canDedupe(this.preferDedupe)) {
|
|
469
466
|
// gather up all deps that have no valid edges in from outside
|
|
@@ -120,13 +120,13 @@ class Results {
|
|
|
120
120
|
this.#pendingCombinator = combinators[String(this.currentAstNode)]
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
// name selectors (i.e. #foo
|
|
123
|
+
// name selectors (i.e. #foo)
|
|
124
124
|
// css calls this id, we interpret it as name
|
|
125
125
|
idType () {
|
|
126
|
-
const
|
|
126
|
+
const name = this.currentAstNode.value
|
|
127
127
|
const nextResults = this.initialItems.filter(node =>
|
|
128
|
-
(
|
|
129
|
-
|
|
128
|
+
(name === node.name) || (name === node.package.name)
|
|
129
|
+
)
|
|
130
130
|
this.processPendingCombinator(nextResults)
|
|
131
131
|
}
|
|
132
132
|
|
package/lib/realpath.js
CHANGED
|
@@ -5,10 +5,7 @@
|
|
|
5
5
|
// built-in fs.realpath, because we only care about symbolic links,
|
|
6
6
|
// so we can handle many fewer edge cases.
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
const promisify = require('util').promisify
|
|
10
|
-
const readlink = promisify(fs.readlink)
|
|
11
|
-
const lstat = promisify(fs.lstat)
|
|
8
|
+
const { lstat, readlink } = require('fs/promises')
|
|
12
9
|
const { resolve, basename, dirname } = require('path')
|
|
13
10
|
|
|
14
11
|
const realpathCached = (path, rpcache, stcache, depth) => {
|
package/lib/shrinkwrap.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
// definitely not before npm v8.
|
|
11
11
|
|
|
12
12
|
const localeCompare = require('@isaacs/string-locale-compare')('en')
|
|
13
|
-
const defaultLockfileVersion =
|
|
13
|
+
const defaultLockfileVersion = 3
|
|
14
14
|
|
|
15
15
|
// for comparing nodes to yarn.lock entries
|
|
16
16
|
const mismatch = (a, b) => a && b && a !== b
|
|
@@ -35,32 +35,16 @@ const mismatch = (a, b) => a && b && a !== b
|
|
|
35
35
|
|
|
36
36
|
const log = require('proc-log')
|
|
37
37
|
const YarnLock = require('./yarn-lock.js')
|
|
38
|
-
const {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const lstat = promisify(fs.lstat)
|
|
49
|
-
/* istanbul ignore next - version specific polyfill */
|
|
50
|
-
const readdir = async (path, opt) => {
|
|
51
|
-
if (!opt || !opt.withFileTypes) {
|
|
52
|
-
return readdir_(path, opt)
|
|
53
|
-
}
|
|
54
|
-
const ents = await readdir_(path, opt)
|
|
55
|
-
if (typeof ents[0] === 'string') {
|
|
56
|
-
return Promise.all(ents.map(async ent => {
|
|
57
|
-
return Object.assign(await lstat(path + '/' + ent), { name: ent })
|
|
58
|
-
}))
|
|
59
|
-
}
|
|
60
|
-
return ents
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const { resolve, basename } = require('path')
|
|
38
|
+
const {
|
|
39
|
+
readFile,
|
|
40
|
+
readdir,
|
|
41
|
+
readlink,
|
|
42
|
+
rm,
|
|
43
|
+
stat,
|
|
44
|
+
writeFile,
|
|
45
|
+
} = require('fs/promises')
|
|
46
|
+
|
|
47
|
+
const { resolve, basename, relative } = require('path')
|
|
64
48
|
const specFromLock = require('./spec-from-lock.js')
|
|
65
49
|
const versionFromTgz = require('./version-from-tgz.js')
|
|
66
50
|
const npa = require('npm-package-arg')
|
|
@@ -224,6 +208,7 @@ const _buildLegacyLockfile = Symbol('_buildLegacyLockfile')
|
|
|
224
208
|
const _filenameSet = Symbol('_filenameSet')
|
|
225
209
|
const _maybeRead = Symbol('_maybeRead')
|
|
226
210
|
const _maybeStat = Symbol('_maybeStat')
|
|
211
|
+
|
|
227
212
|
class Shrinkwrap {
|
|
228
213
|
static get defaultLockfileVersion () {
|
|
229
214
|
return defaultLockfileVersion
|
|
@@ -252,17 +237,6 @@ class Shrinkwrap {
|
|
|
252
237
|
s.loadedFromDisk = !!(sw || lock)
|
|
253
238
|
s.type = basename(s.filename)
|
|
254
239
|
|
|
255
|
-
try {
|
|
256
|
-
if (s.loadedFromDisk && !s.lockfileVersion) {
|
|
257
|
-
const json = parseJSON(await maybeReadFile(s.filename))
|
|
258
|
-
if (json.lockfileVersion > defaultLockfileVersion) {
|
|
259
|
-
s.lockfileVersion = json.lockfileVersion
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
} catch {
|
|
263
|
-
// ignore errors
|
|
264
|
-
}
|
|
265
|
-
|
|
266
240
|
return s
|
|
267
241
|
}
|
|
268
242
|
|
|
@@ -342,6 +316,7 @@ class Shrinkwrap {
|
|
|
342
316
|
this.lockfileVersion = hiddenLockfile ? 3
|
|
343
317
|
: lockfileVersion ? parseInt(lockfileVersion, 10)
|
|
344
318
|
: null
|
|
319
|
+
|
|
345
320
|
this[_awaitingUpdate] = new Map()
|
|
346
321
|
this.tree = null
|
|
347
322
|
this.path = resolve(path || '.')
|
|
@@ -398,6 +373,7 @@ class Shrinkwrap {
|
|
|
398
373
|
this[_awaitingUpdate] = new Map()
|
|
399
374
|
const lockfileVersion = this.lockfileVersion || defaultLockfileVersion
|
|
400
375
|
this.originalLockfileVersion = lockfileVersion
|
|
376
|
+
|
|
401
377
|
this.data = {
|
|
402
378
|
lockfileVersion,
|
|
403
379
|
requires: true,
|
|
@@ -496,8 +472,14 @@ class Shrinkwrap {
|
|
|
496
472
|
this.ancientLockfile = false
|
|
497
473
|
return {}
|
|
498
474
|
}).then(lock => {
|
|
499
|
-
|
|
500
|
-
|
|
475
|
+
// auto convert v1 lockfiles to v3
|
|
476
|
+
// leave v2 in place unless configured
|
|
477
|
+
// v3 by default
|
|
478
|
+
const lockfileVersion =
|
|
479
|
+
this.lockfileVersion ? this.lockfileVersion
|
|
480
|
+
: lock.lockfileVersion === 1 ? defaultLockfileVersion
|
|
481
|
+
: lock.lockfileVersion || defaultLockfileVersion
|
|
482
|
+
|
|
501
483
|
this.data = {
|
|
502
484
|
...lock,
|
|
503
485
|
lockfileVersion: lockfileVersion,
|
|
@@ -507,6 +489,7 @@ class Shrinkwrap {
|
|
|
507
489
|
}
|
|
508
490
|
|
|
509
491
|
this.originalLockfileVersion = lock.lockfileVersion
|
|
492
|
+
|
|
510
493
|
// use default if it wasn't explicitly set, and the current file is
|
|
511
494
|
// less than our default. otherwise, keep whatever is in the file,
|
|
512
495
|
// unless we had an explicit setting already.
|
|
@@ -1135,7 +1118,17 @@ class Shrinkwrap {
|
|
|
1135
1118
|
if (!this.data) {
|
|
1136
1119
|
throw new Error('run load() before saving data')
|
|
1137
1120
|
}
|
|
1121
|
+
|
|
1138
1122
|
const json = this.toString(options)
|
|
1123
|
+
if (
|
|
1124
|
+
!this.hiddenLockfile
|
|
1125
|
+
&& this.originalLockfileVersion !== undefined
|
|
1126
|
+
&& this.originalLockfileVersion !== this.lockfileVersion
|
|
1127
|
+
) {
|
|
1128
|
+
log.warn(
|
|
1129
|
+
`Converting lock file (${relative(process.cwd(), this.filename)}) from v${this.originalLockfileVersion} -> v${this.lockfileVersion}`
|
|
1130
|
+
)
|
|
1131
|
+
}
|
|
1139
1132
|
return Promise.all([
|
|
1140
1133
|
writeFile(this.filename, json).catch(er => {
|
|
1141
1134
|
if (this.hiddenLockfile) {
|
|
@@ -1144,7 +1137,7 @@ class Shrinkwrap {
|
|
|
1144
1137
|
// a node_modules folder, but then the lockfile is not important.
|
|
1145
1138
|
// Remove the file, so that in case there WERE deps, but we just
|
|
1146
1139
|
// failed to update the file for some reason, it's not out of sync.
|
|
1147
|
-
return
|
|
1140
|
+
return rm(this.filename, { recursive: true, force: true })
|
|
1148
1141
|
}
|
|
1149
1142
|
throw er
|
|
1150
1143
|
}),
|
package/package.json
CHANGED
|
@@ -1,48 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/arborist",
|
|
3
|
-
"version": "6.0.0-pre.
|
|
3
|
+
"version": "6.0.0-pre.5",
|
|
4
4
|
"description": "Manage node_modules trees",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@isaacs/string-locale-compare": "^1.1.0",
|
|
7
|
-
"@npmcli/installed-package-contents": "^
|
|
8
|
-
"@npmcli/map-workspaces": "^
|
|
9
|
-
"@npmcli/metavuln-calculator": "^
|
|
10
|
-
"@npmcli/move-file": "^
|
|
7
|
+
"@npmcli/installed-package-contents": "^2.0.0",
|
|
8
|
+
"@npmcli/map-workspaces": "^3.0.0",
|
|
9
|
+
"@npmcli/metavuln-calculator": "^5.0.0",
|
|
10
|
+
"@npmcli/move-file": "^3.0.0",
|
|
11
11
|
"@npmcli/name-from-folder": "^1.0.1",
|
|
12
|
-
"@npmcli/node-gyp": "^
|
|
13
|
-
"@npmcli/package-json": "^
|
|
14
|
-
"@npmcli/query": "^
|
|
15
|
-
"@npmcli/run-script": "^
|
|
16
|
-
"bin-links": "^
|
|
17
|
-
"cacache": "^
|
|
12
|
+
"@npmcli/node-gyp": "^3.0.0",
|
|
13
|
+
"@npmcli/package-json": "^3.0.0",
|
|
14
|
+
"@npmcli/query": "^3.0.0",
|
|
15
|
+
"@npmcli/run-script": "^5.0.0",
|
|
16
|
+
"bin-links": "^4.0.1",
|
|
17
|
+
"cacache": "^17.0.1",
|
|
18
18
|
"common-ancestor-path": "^1.0.1",
|
|
19
|
-
"json-parse-even-better-errors": "^
|
|
19
|
+
"json-parse-even-better-errors": "^3.0.0",
|
|
20
20
|
"json-stringify-nice": "^1.1.4",
|
|
21
21
|
"minimatch": "^5.1.0",
|
|
22
|
-
"mkdirp": "^1.0.4",
|
|
23
|
-
"mkdirp-infer-owner": "^2.0.0",
|
|
24
22
|
"nopt": "^6.0.0",
|
|
25
|
-
"npm-install-checks": "^
|
|
26
|
-
"npm-package-arg": "^
|
|
27
|
-
"npm-pick-manifest": "^
|
|
28
|
-
"npm-registry-fetch": "^
|
|
29
|
-
"npmlog": "^
|
|
30
|
-
"pacote": "^
|
|
31
|
-
"parse-conflict-json": "^
|
|
32
|
-
"proc-log": "^
|
|
23
|
+
"npm-install-checks": "^6.0.0",
|
|
24
|
+
"npm-package-arg": "^10.0.0",
|
|
25
|
+
"npm-pick-manifest": "^8.0.1",
|
|
26
|
+
"npm-registry-fetch": "^14.0.2",
|
|
27
|
+
"npmlog": "^7.0.1",
|
|
28
|
+
"pacote": "^15.0.2",
|
|
29
|
+
"parse-conflict-json": "^3.0.0",
|
|
30
|
+
"proc-log": "^3.0.0",
|
|
33
31
|
"promise-all-reject-late": "^1.0.0",
|
|
34
32
|
"promise-call-limit": "^1.0.1",
|
|
35
|
-
"read-package-json-fast": "^
|
|
33
|
+
"read-package-json-fast": "^3.0.1",
|
|
36
34
|
"readdir-scoped-modules": "^1.1.0",
|
|
37
|
-
"rimraf": "^3.0.2",
|
|
38
35
|
"semver": "^7.3.7",
|
|
39
|
-
"ssri": "^
|
|
40
|
-
"treeverse": "^
|
|
36
|
+
"ssri": "^10.0.0",
|
|
37
|
+
"treeverse": "^3.0.0",
|
|
41
38
|
"walk-up-path": "^1.0.0"
|
|
42
39
|
},
|
|
43
40
|
"devDependencies": {
|
|
44
|
-
"@npmcli/eslint-config": "^
|
|
45
|
-
"@npmcli/template-oss": "4.
|
|
41
|
+
"@npmcli/eslint-config": "^4.0.0",
|
|
42
|
+
"@npmcli/template-oss": "4.6.2",
|
|
46
43
|
"benchmark": "^2.1.4",
|
|
47
44
|
"chalk": "^4.1.0",
|
|
48
45
|
"minify-registry-metadata": "^2.1.0",
|
|
@@ -104,7 +101,7 @@
|
|
|
104
101
|
},
|
|
105
102
|
"templateOSS": {
|
|
106
103
|
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
|
107
|
-
"version": "4.
|
|
104
|
+
"version": "4.6.2",
|
|
108
105
|
"content": "../../scripts/template-oss/index.js"
|
|
109
106
|
}
|
|
110
107
|
}
|