@npmcli/arborist 4.1.2 → 4.3.1
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/lib/arborist/build-ideal-tree.js +59 -22
- package/lib/arborist/load-actual.js +7 -2
- package/lib/arborist/reify.js +105 -19
- package/lib/shrinkwrap.js +35 -15
- package/package.json +8 -6
|
@@ -41,7 +41,7 @@ const _complete = Symbol('complete')
|
|
|
41
41
|
const _depsSeen = Symbol('depsSeen')
|
|
42
42
|
const _depsQueue = Symbol('depsQueue')
|
|
43
43
|
const _currentDep = Symbol('currentDep')
|
|
44
|
-
const _updateAll = Symbol('updateAll')
|
|
44
|
+
const _updateAll = Symbol.for('updateAll')
|
|
45
45
|
const _mutateTree = Symbol('mutateTree')
|
|
46
46
|
const _flagsSuspect = Symbol.for('flagsSuspect')
|
|
47
47
|
const _workspaces = Symbol.for('workspaces')
|
|
@@ -176,7 +176,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
176
176
|
// public method
|
|
177
177
|
async buildIdealTree (options = {}) {
|
|
178
178
|
if (this.idealTree) {
|
|
179
|
-
return
|
|
179
|
+
return this.idealTree
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
// allow the user to set reify options on the ctor as well.
|
|
@@ -194,8 +194,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
194
194
|
process.emit('time', 'idealTree')
|
|
195
195
|
|
|
196
196
|
if (!options.add && !options.rm && !options.update && this[_global]) {
|
|
197
|
-
|
|
198
|
-
return Promise.reject(er)
|
|
197
|
+
throw new Error('global requires add, rm, or update option')
|
|
199
198
|
}
|
|
200
199
|
|
|
201
200
|
// first get the virtual tree, if possible. If there's a lockfile, then
|
|
@@ -270,6 +269,22 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
270
269
|
this[_complete] = !!options.complete
|
|
271
270
|
this[_preferDedupe] = !!options.preferDedupe
|
|
272
271
|
this[_legacyBundling] = !!options.legacyBundling
|
|
272
|
+
|
|
273
|
+
// validates list of update names, they must
|
|
274
|
+
// be dep names only, no semver ranges are supported
|
|
275
|
+
for (const name of update.names) {
|
|
276
|
+
const spec = npa(name)
|
|
277
|
+
const validationError =
|
|
278
|
+
new TypeError(`Update arguments must not contain package version specifiers
|
|
279
|
+
|
|
280
|
+
Try using the package name instead, e.g:
|
|
281
|
+
npm update ${spec.name}`)
|
|
282
|
+
validationError.code = 'EUPDATEARGS'
|
|
283
|
+
|
|
284
|
+
if (spec.fetchSpec !== 'latest') {
|
|
285
|
+
throw validationError
|
|
286
|
+
}
|
|
287
|
+
}
|
|
273
288
|
this[_updateNames] = update.names
|
|
274
289
|
|
|
275
290
|
this[_updateAll] = update.all
|
|
@@ -321,7 +336,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
321
336
|
// Load on a new Arborist object, so the Nodes aren't the same,
|
|
322
337
|
// or else it'll get super confusing when we change them!
|
|
323
338
|
.then(async root => {
|
|
324
|
-
if (!this[_updateAll] && !this[_global] && !root.meta.loadedFromDisk) {
|
|
339
|
+
if ((!this[_updateAll] && !this[_global] && !root.meta.loadedFromDisk) || (this[_global] && this[_updateNames].length)) {
|
|
325
340
|
await new this.constructor(this.options).loadActual({ root })
|
|
326
341
|
const tree = root.target
|
|
327
342
|
// even though we didn't load it from a package-lock.json FILE,
|
|
@@ -334,6 +349,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
334
349
|
root.meta.lockfileVersion = defaultLockfileVersion
|
|
335
350
|
}
|
|
336
351
|
}
|
|
352
|
+
root.meta.inferFormattingOptions(root.package)
|
|
337
353
|
return root
|
|
338
354
|
})
|
|
339
355
|
|
|
@@ -1180,6 +1196,11 @@ This is a one-time fix-up, please be patient...
|
|
|
1180
1196
|
return true
|
|
1181
1197
|
}
|
|
1182
1198
|
|
|
1199
|
+
// If the edge is a workspace, and it's valid, leave it alone
|
|
1200
|
+
if (edge.to.isWorkspace) {
|
|
1201
|
+
return false
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1183
1204
|
// user explicitly asked to update this package by name, problem
|
|
1184
1205
|
if (this[_updateNames].includes(edge.name)) {
|
|
1185
1206
|
return true
|
|
@@ -1229,24 +1250,40 @@ This is a one-time fix-up, please be patient...
|
|
|
1229
1250
|
// Don't bother to load the manifest for link deps, because the target
|
|
1230
1251
|
// might be within another package that doesn't exist yet.
|
|
1231
1252
|
const { legacyPeerDeps } = this
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1253
|
+
|
|
1254
|
+
// spec is a directory, link it
|
|
1255
|
+
if (spec.type === 'directory') {
|
|
1256
|
+
return this[_linkFromSpec](name, spec, parent, edge)
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
// if the spec matches a workspace name, then see if the workspace node will
|
|
1260
|
+
// satisfy the edge. if it does, we return the workspace node to make sure it
|
|
1261
|
+
// takes priority.
|
|
1262
|
+
if (this.idealTree.workspaces && this.idealTree.workspaces.has(spec.name)) {
|
|
1263
|
+
const existingNode = this.idealTree.edgesOut.get(spec.name).to
|
|
1264
|
+
if (existingNode && existingNode.isWorkspace && existingNode.satisfies(edge)) {
|
|
1265
|
+
return edge.to
|
|
1266
|
+
}
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
// spec isn't a directory, and either isn't a workspace or the workspace we have
|
|
1270
|
+
// doesn't satisfy the edge. try to fetch a manifest and build a node from that.
|
|
1271
|
+
return this[_fetchManifest](spec)
|
|
1272
|
+
.then(pkg => new Node({ name, pkg, parent, legacyPeerDeps }), error => {
|
|
1273
|
+
error.requiredBy = edge.from.location || '.'
|
|
1274
|
+
|
|
1275
|
+
// failed to load the spec, either because of enotarget or
|
|
1276
|
+
// fetch failure of some other sort. save it so we can verify
|
|
1277
|
+
// later that it's optional, otherwise the error is fatal.
|
|
1278
|
+
const n = new Node({
|
|
1279
|
+
name,
|
|
1280
|
+
parent,
|
|
1281
|
+
error,
|
|
1282
|
+
legacyPeerDeps,
|
|
1249
1283
|
})
|
|
1284
|
+
this[_loadFailures].add(n)
|
|
1285
|
+
return n
|
|
1286
|
+
})
|
|
1250
1287
|
}
|
|
1251
1288
|
|
|
1252
1289
|
[_linkFromSpec] (name, spec, parent, edge) {
|
|
@@ -212,7 +212,8 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
212
212
|
const promises = []
|
|
213
213
|
for (const path of tree.workspaces.values()) {
|
|
214
214
|
if (!this[_cache].has(path)) {
|
|
215
|
-
|
|
215
|
+
// workspace overrides use the root overrides
|
|
216
|
+
const p = this[_loadFSNode]({ path, root: this[_actualTree], useRootOverrides: true })
|
|
216
217
|
.then(node => this[_loadFSTree](node))
|
|
217
218
|
promises.push(p)
|
|
218
219
|
}
|
|
@@ -240,7 +241,7 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
240
241
|
this[_actualTree] = root
|
|
241
242
|
}
|
|
242
243
|
|
|
243
|
-
[_loadFSNode] ({ path, parent, real, root, loadOverrides }) {
|
|
244
|
+
[_loadFSNode] ({ path, parent, real, root, loadOverrides, useRootOverrides }) {
|
|
244
245
|
if (!real) {
|
|
245
246
|
return realpath(path, this[_rpcache], this[_stcache])
|
|
246
247
|
.then(
|
|
@@ -250,6 +251,7 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
250
251
|
real,
|
|
251
252
|
root,
|
|
252
253
|
loadOverrides,
|
|
254
|
+
useRootOverrides,
|
|
253
255
|
}),
|
|
254
256
|
// if realpath fails, just provide a dummy error node
|
|
255
257
|
error => new Node({
|
|
@@ -289,6 +291,9 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
289
291
|
parent,
|
|
290
292
|
root,
|
|
291
293
|
loadOverrides,
|
|
294
|
+
...(useRootOverrides && root.overrides
|
|
295
|
+
? { overrides: root.overrides.getNodeRule({ name: pkg.name, version: pkg.version }) }
|
|
296
|
+
: {}),
|
|
292
297
|
})
|
|
293
298
|
})
|
|
294
299
|
.then(node => {
|
package/lib/arborist/reify.js
CHANGED
|
@@ -5,6 +5,7 @@ const pacote = require('pacote')
|
|
|
5
5
|
const AuditReport = require('../audit-report.js')
|
|
6
6
|
const { subset, intersects } = require('semver')
|
|
7
7
|
const npa = require('npm-package-arg')
|
|
8
|
+
const semver = require('semver')
|
|
8
9
|
const debug = require('../debug.js')
|
|
9
10
|
const walkUp = require('walk-up-path')
|
|
10
11
|
|
|
@@ -58,6 +59,8 @@ const _bundleUnpacked = Symbol('bundleUnpacked')
|
|
|
58
59
|
const _bundleMissing = Symbol('bundleMissing')
|
|
59
60
|
const _reifyNode = Symbol.for('reifyNode')
|
|
60
61
|
const _extractOrLink = Symbol('extractOrLink')
|
|
62
|
+
const _updateAll = Symbol.for('updateAll')
|
|
63
|
+
const _updateNames = Symbol.for('updateNames')
|
|
61
64
|
// defined by rebuild mixin
|
|
62
65
|
const _checkBins = Symbol.for('checkBins')
|
|
63
66
|
const _symlink = Symbol('symlink')
|
|
@@ -1140,21 +1143,33 @@ module.exports = cls => class Reifier extends cls {
|
|
|
1140
1143
|
// for install failures. Those still end up in the shrinkwrap, so we
|
|
1141
1144
|
// save it first, then prune out the optional trash, and then return it.
|
|
1142
1145
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1146
|
+
const save = !(options.save === false)
|
|
1147
|
+
|
|
1148
|
+
// we check for updates in order to make sure we run save ideal tree
|
|
1149
|
+
// even though save=false since we want `npm update` to be able to
|
|
1150
|
+
// write to package-lock files by default
|
|
1151
|
+
const hasUpdates = this[_updateAll] || this[_updateNames].length
|
|
1152
|
+
|
|
1153
|
+
// we're going to completely skip save ideal tree in case of a global or
|
|
1154
|
+
// dry-run install and also if the save option is set to false, EXCEPT for
|
|
1155
|
+
// update since the expected behavior for npm7+ is for update to
|
|
1156
|
+
// NOT save to package.json, we make that exception since we still want
|
|
1157
|
+
// saveIdealTree to be able to write the lockfile by default.
|
|
1158
|
+
const saveIdealTree = !(
|
|
1159
|
+
(!save && !hasUpdates)
|
|
1160
|
+
|| this[_global]
|
|
1161
|
+
|| this[_dryRun]
|
|
1162
|
+
)
|
|
1163
|
+
|
|
1164
|
+
if (!saveIdealTree) {
|
|
1145
1165
|
return false
|
|
1146
1166
|
}
|
|
1147
1167
|
|
|
1148
1168
|
process.emit('time', 'reify:save')
|
|
1149
1169
|
|
|
1150
1170
|
const updatedTrees = new Set()
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
// to things like git repos and tarball file/urls. However, if the
|
|
1154
|
-
// user requested 'foo@', and we have a foo@file:../foo, then we should
|
|
1155
|
-
// end up saving the spec we actually used, not whatever they gave us.
|
|
1156
|
-
if (this[_resolvedAdd].length) {
|
|
1157
|
-
for (const { name, tree: addTree } of this[_resolvedAdd]) {
|
|
1171
|
+
const updateNodes = nodes => {
|
|
1172
|
+
for (const { name, tree: addTree } of nodes) {
|
|
1158
1173
|
// addTree either the root, or a workspace
|
|
1159
1174
|
const edge = addTree.edgesOut.get(name)
|
|
1160
1175
|
const pkg = addTree.package
|
|
@@ -1168,7 +1183,7 @@ module.exports = cls => class Reifier extends cls {
|
|
|
1168
1183
|
// that we couldn't resolve, this MAY be missing. if we haven't
|
|
1169
1184
|
// blown up by now, it's because it was not a problem, though, so
|
|
1170
1185
|
// just move on.
|
|
1171
|
-
if (!child) {
|
|
1186
|
+
if (!child || !addTree.isTop) {
|
|
1172
1187
|
continue
|
|
1173
1188
|
}
|
|
1174
1189
|
|
|
@@ -1259,6 +1274,80 @@ module.exports = cls => class Reifier extends cls {
|
|
|
1259
1274
|
}
|
|
1260
1275
|
}
|
|
1261
1276
|
|
|
1277
|
+
// Returns true if any of the edges from this node has a semver
|
|
1278
|
+
// range definition that is an exact match to the version installed
|
|
1279
|
+
// e.g: should return true if for a given an installed version 1.0.0,
|
|
1280
|
+
// range is either =1.0.0 or 1.0.0
|
|
1281
|
+
const exactVersion = node => {
|
|
1282
|
+
for (const edge of node.edgesIn) {
|
|
1283
|
+
try {
|
|
1284
|
+
if (semver.subset(edge.spec, node.version)) {
|
|
1285
|
+
return false
|
|
1286
|
+
}
|
|
1287
|
+
} catch {}
|
|
1288
|
+
}
|
|
1289
|
+
return true
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
// helper that retrieves an array of nodes that were
|
|
1293
|
+
// potentially updated during the reify process, in order
|
|
1294
|
+
// to limit the number of nodes to check and update, only
|
|
1295
|
+
// select nodes from the inventory that are direct deps
|
|
1296
|
+
// of a given package.json (project root or a workspace)
|
|
1297
|
+
// and in ase of using a list of `names`, restrict nodes
|
|
1298
|
+
// to only names that are found in this list
|
|
1299
|
+
const retrieveUpdatedNodes = names => {
|
|
1300
|
+
const filterDirectDependencies = node =>
|
|
1301
|
+
!node.isRoot && node.resolveParent.isRoot
|
|
1302
|
+
&& (!names || names.includes(node.name))
|
|
1303
|
+
&& exactVersion(node) // skip update for exact ranges
|
|
1304
|
+
|
|
1305
|
+
const directDeps = this.idealTree.inventory
|
|
1306
|
+
.filter(filterDirectDependencies)
|
|
1307
|
+
|
|
1308
|
+
// traverses the list of direct dependencies and collect all nodes
|
|
1309
|
+
// to be updated, since any of them might have changed during reify
|
|
1310
|
+
const nodes = []
|
|
1311
|
+
for (const node of directDeps) {
|
|
1312
|
+
for (const edgeIn of node.edgesIn) {
|
|
1313
|
+
nodes.push({
|
|
1314
|
+
name: node.name,
|
|
1315
|
+
tree: edgeIn.from.target,
|
|
1316
|
+
})
|
|
1317
|
+
}
|
|
1318
|
+
}
|
|
1319
|
+
return nodes
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
if (save) {
|
|
1323
|
+
// when using update all alongside with save, we'll make
|
|
1324
|
+
// sure to refresh every dependency of the root idealTree
|
|
1325
|
+
if (this[_updateAll]) {
|
|
1326
|
+
const nodes = retrieveUpdatedNodes()
|
|
1327
|
+
updateNodes(nodes)
|
|
1328
|
+
} else {
|
|
1329
|
+
// resolvedAdd is the list of user add requests, but with names added
|
|
1330
|
+
// to things like git repos and tarball file/urls. However, if the
|
|
1331
|
+
// user requested 'foo@', and we have a foo@file:../foo, then we should
|
|
1332
|
+
// end up saving the spec we actually used, not whatever they gave us.
|
|
1333
|
+
if (this[_resolvedAdd].length) {
|
|
1334
|
+
updateNodes(this[_resolvedAdd])
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
// if updating given dependencies by name, restrict the list of
|
|
1338
|
+
// nodes to check to only those currently in _updateNames
|
|
1339
|
+
if (this[_updateNames].length) {
|
|
1340
|
+
const nodes = retrieveUpdatedNodes(this[_updateNames])
|
|
1341
|
+
updateNodes(nodes)
|
|
1342
|
+
}
|
|
1343
|
+
|
|
1344
|
+
// grab any from explicitRequests that had deps removed
|
|
1345
|
+
for (const { from: tree } of this.explicitRequests) {
|
|
1346
|
+
updatedTrees.add(tree)
|
|
1347
|
+
}
|
|
1348
|
+
}
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1262
1351
|
// preserve indentation, if possible
|
|
1263
1352
|
const {
|
|
1264
1353
|
[Symbol.for('indent')]: indent,
|
|
@@ -1291,15 +1380,12 @@ module.exports = cls => class Reifier extends cls {
|
|
|
1291
1380
|
await pkgJson.save()
|
|
1292
1381
|
}
|
|
1293
1382
|
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
// refresh the edges so they have the correct specs
|
|
1301
|
-
tree.package = tree.package
|
|
1302
|
-
promises.push(updatePackageJson(tree))
|
|
1383
|
+
if (save) {
|
|
1384
|
+
for (const tree of updatedTrees) {
|
|
1385
|
+
// refresh the edges so they have the correct specs
|
|
1386
|
+
tree.package = tree.package
|
|
1387
|
+
promises.push(updatePackageJson(tree))
|
|
1388
|
+
}
|
|
1303
1389
|
}
|
|
1304
1390
|
|
|
1305
1391
|
await Promise.all(promises)
|
package/lib/shrinkwrap.js
CHANGED
|
@@ -424,6 +424,18 @@ class Shrinkwrap {
|
|
|
424
424
|
.map(fn => fn && maybeStatFile(fn)))
|
|
425
425
|
}
|
|
426
426
|
|
|
427
|
+
inferFormattingOptions (packageJSONData) {
|
|
428
|
+
// don't use detect-indent, just pick the first line.
|
|
429
|
+
// if the file starts with {" then we have an indent of '', ie, none
|
|
430
|
+
// which will default to 2 at save time.
|
|
431
|
+
const {
|
|
432
|
+
[Symbol.for('indent')]: indent,
|
|
433
|
+
[Symbol.for('newline')]: newline,
|
|
434
|
+
} = packageJSONData
|
|
435
|
+
this.indent = indent !== undefined ? indent : this.indent
|
|
436
|
+
this.newline = newline !== undefined ? newline : this.newline
|
|
437
|
+
}
|
|
438
|
+
|
|
427
439
|
load () {
|
|
428
440
|
// we don't need to load package-lock.json except for top of tree nodes,
|
|
429
441
|
// only npm-shrinkwrap.json.
|
|
@@ -451,15 +463,7 @@ class Shrinkwrap {
|
|
|
451
463
|
|
|
452
464
|
return data ? parseJSON(data) : {}
|
|
453
465
|
}).then(async data => {
|
|
454
|
-
|
|
455
|
-
// if the file starts with {" then we have an indent of '', ie, none
|
|
456
|
-
// which will default to 2 at save time.
|
|
457
|
-
const {
|
|
458
|
-
[Symbol.for('indent')]: indent,
|
|
459
|
-
[Symbol.for('newline')]: newline,
|
|
460
|
-
} = data
|
|
461
|
-
this.indent = indent !== undefined ? indent : this.indent
|
|
462
|
-
this.newline = newline !== undefined ? newline : this.newline
|
|
466
|
+
this.inferFormattingOptions(data)
|
|
463
467
|
|
|
464
468
|
if (!this.hiddenLockfile || !data.packages) {
|
|
465
469
|
return data
|
|
@@ -472,8 +476,13 @@ class Shrinkwrap {
|
|
|
472
476
|
// all good! hidden lockfile is the newest thing in here.
|
|
473
477
|
return data
|
|
474
478
|
}).catch(er => {
|
|
475
|
-
|
|
476
|
-
this.
|
|
479
|
+
/* istanbul ignore else */
|
|
480
|
+
if (typeof this.filename === 'string') {
|
|
481
|
+
const rel = relpath(this.path, this.filename)
|
|
482
|
+
this.log.verbose('shrinkwrap', `failed to load ${rel}`, er)
|
|
483
|
+
} else {
|
|
484
|
+
this.log.verbose('shrinkwrap', `failed to load ${this.path}`, er)
|
|
485
|
+
}
|
|
477
486
|
this.loadingError = er
|
|
478
487
|
this.loadedFromDisk = false
|
|
479
488
|
this.ancientLockfile = false
|
|
@@ -1085,18 +1094,29 @@ class Shrinkwrap {
|
|
|
1085
1094
|
return lock
|
|
1086
1095
|
}
|
|
1087
1096
|
|
|
1088
|
-
|
|
1097
|
+
toJSON () {
|
|
1089
1098
|
if (!this.data) {
|
|
1090
|
-
throw new Error('run load() before
|
|
1099
|
+
throw new Error('run load() before getting or setting data')
|
|
1091
1100
|
}
|
|
1092
1101
|
|
|
1102
|
+
return this.commit()
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
toString (options = {}) {
|
|
1106
|
+
const data = this.toJSON()
|
|
1093
1107
|
const { format = true } = options
|
|
1094
1108
|
const defaultIndent = this.indent || 2
|
|
1095
1109
|
const indent = format === true ? defaultIndent
|
|
1096
1110
|
: format || 0
|
|
1097
1111
|
const eol = format ? this.newline || '\n' : ''
|
|
1098
|
-
|
|
1099
|
-
|
|
1112
|
+
return stringify(data, swKeyOrder, indent).replace(/\n/g, eol)
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
save (options = {}) {
|
|
1116
|
+
if (!this.data) {
|
|
1117
|
+
throw new Error('run load() before saving data')
|
|
1118
|
+
}
|
|
1119
|
+
const json = this.toString(options)
|
|
1100
1120
|
return Promise.all([
|
|
1101
1121
|
writeFile(this.filename, json).catch(er => {
|
|
1102
1122
|
if (this.hiddenLockfile) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/arborist",
|
|
3
|
-
"version": "4.1
|
|
3
|
+
"version": "4.3.1",
|
|
4
4
|
"description": "Manage node_modules trees",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@isaacs/string-locale-compare": "^1.1.0",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"@npmcli/node-gyp": "^1.0.3",
|
|
13
13
|
"@npmcli/package-json": "^1.0.1",
|
|
14
14
|
"@npmcli/run-script": "^2.0.0",
|
|
15
|
-
"bin-links": "^
|
|
15
|
+
"bin-links": "^3.0.0",
|
|
16
16
|
"cacache": "^15.0.3",
|
|
17
17
|
"common-ancestor-path": "^1.0.1",
|
|
18
18
|
"json-parse-even-better-errors": "^2.3.1",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"npm-install-checks": "^4.0.0",
|
|
23
23
|
"npm-package-arg": "^8.1.5",
|
|
24
24
|
"npm-pick-manifest": "^6.1.0",
|
|
25
|
-
"npm-registry-fetch": "^
|
|
25
|
+
"npm-registry-fetch": "^12.0.1",
|
|
26
26
|
"pacote": "^12.0.2",
|
|
27
27
|
"parse-conflict-json": "^2.0.1",
|
|
28
28
|
"proc-log": "^1.0.0",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"walk-up-path": "^1.0.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@npmcli/template-oss": "^2.
|
|
40
|
+
"@npmcli/template-oss": "^2.4.2",
|
|
41
41
|
"benchmark": "^2.1.4",
|
|
42
42
|
"chalk": "^4.1.0",
|
|
43
43
|
"minify-registry-metadata": "^2.1.0",
|
|
@@ -94,9 +94,11 @@
|
|
|
94
94
|
"engines": {
|
|
95
95
|
"node": "^12.13.0 || ^14.15.0 || >=16"
|
|
96
96
|
},
|
|
97
|
-
"templateVersion": "2.3.1",
|
|
98
97
|
"eslintIgnore": [
|
|
99
98
|
"test/fixtures/",
|
|
100
99
|
"!test/fixtures/*.js"
|
|
101
|
-
]
|
|
100
|
+
],
|
|
101
|
+
"templateOSS": {
|
|
102
|
+
"version": "2.4.3"
|
|
103
|
+
}
|
|
102
104
|
}
|