@npmcli/arborist 4.2.1 → 5.0.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.
@@ -14,6 +14,7 @@ const fs = require('fs')
14
14
  const lstat = promisify(fs.lstat)
15
15
  const readlink = promisify(fs.readlink)
16
16
  const { depth } = require('treeverse')
17
+ const log = require('proc-log')
17
18
 
18
19
  const {
19
20
  OK,
@@ -248,7 +249,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
248
249
  try {
249
250
  c()
250
251
  } catch (er) {
251
- this.log.warn(er.code, er.message, {
252
+ log.warn(er.code, er.message, {
252
253
  package: er.pkgid,
253
254
  required: er.required,
254
255
  current: er.current,
@@ -269,6 +270,22 @@ module.exports = cls => class IdealTreeBuilder extends cls {
269
270
  this[_complete] = !!options.complete
270
271
  this[_preferDedupe] = !!options.preferDedupe
271
272
  this[_legacyBundling] = !!options.legacyBundling
273
+
274
+ // validates list of update names, they must
275
+ // be dep names only, no semver ranges are supported
276
+ for (const name of update.names) {
277
+ const spec = npa(name)
278
+ const validationError =
279
+ new TypeError(`Update arguments must not contain package version specifiers
280
+
281
+ Try using the package name instead, e.g:
282
+ npm update ${spec.name}`)
283
+ validationError.code = 'EUPDATEARGS'
284
+
285
+ if (spec.fetchSpec !== 'latest') {
286
+ throw validationError
287
+ }
288
+ }
272
289
  this[_updateNames] = update.names
273
290
 
274
291
  this[_updateAll] = update.all
@@ -320,7 +337,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
320
337
  // Load on a new Arborist object, so the Nodes aren't the same,
321
338
  // or else it'll get super confusing when we change them!
322
339
  .then(async root => {
323
- if (!this[_updateAll] && !this[_global] && !root.meta.loadedFromDisk) {
340
+ if ((!this[_updateAll] && !this[_global] && !root.meta.loadedFromDisk) || (this[_global] && this[_updateNames].length)) {
324
341
  await new this.constructor(this.options).loadActual({ root })
325
342
  const tree = root.target
326
343
  // even though we didn't load it from a package-lock.json FILE,
@@ -516,7 +533,6 @@ module.exports = cls => class IdealTreeBuilder extends cls {
516
533
  saveBundle,
517
534
  saveType,
518
535
  path: this.path,
519
- log: this.log,
520
536
  })
521
537
  })
522
538
  }
@@ -586,7 +602,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
586
602
  // be printed by npm-audit-report as if they can be fixed, because
587
603
  // they can't.
588
604
  if (bundler) {
589
- this.log.warn(`audit fix ${node.name}@${node.version}`,
605
+ log.warn(`audit fix ${node.name}@${node.version}`,
590
606
  `${node.location}\nis a bundled dependency of\n${
591
607
  bundler.name}@${bundler.version} at ${bundler.location}\n` +
592
608
  'It cannot be fixed automatically.\n' +
@@ -621,14 +637,14 @@ module.exports = cls => class IdealTreeBuilder extends cls {
621
637
  if (!node.isProjectRoot && !node.isWorkspace) {
622
638
  // not something we're going to fix, sorry. have to cd into
623
639
  // that directory and fix it yourself.
624
- this.log.warn('audit', 'Manual fix required in linked project ' +
640
+ log.warn('audit', 'Manual fix required in linked project ' +
625
641
  `at ./${node.location} for ${name}@${simpleRange}.\n` +
626
642
  `'cd ./${node.location}' and run 'npm audit' for details.`)
627
643
  continue
628
644
  }
629
645
 
630
646
  if (!fixAvailable) {
631
- this.log.warn('audit', `No fix available for ${name}@${simpleRange}`)
647
+ log.warn('audit', `No fix available for ${name}@${simpleRange}`)
632
648
  continue
633
649
  }
634
650
 
@@ -636,7 +652,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
636
652
  const breakingMessage = isSemVerMajor
637
653
  ? 'a SemVer major change'
638
654
  : 'outside your stated dependency range'
639
- this.log.warn('audit', `Updating ${name} to ${version},` +
655
+ log.warn('audit', `Updating ${name} to ${version},` +
640
656
  `which is ${breakingMessage}.`)
641
657
 
642
658
  await this[_add](node, { add: [`${name}@${version}`] })
@@ -711,7 +727,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
711
727
  const heading = ancient ? 'ancient lockfile' : 'old lockfile'
712
728
  if (ancient || !this.options.lockfileVersion ||
713
729
  this.options.lockfileVersion >= defaultLockfileVersion) {
714
- this.log.warn(heading,
730
+ log.warn(heading,
715
731
  `
716
732
  The ${meta.type} file was created with an old version of npm,
717
733
  so supplemental metadata must be fetched from the registry.
@@ -728,7 +744,7 @@ This is a one-time fix-up, please be patient...
728
744
  }
729
745
 
730
746
  queue.push(async () => {
731
- this.log.silly('inflate', node.location)
747
+ log.silly('inflate', node.location)
732
748
  const { resolved, version, path, name, location, integrity } = node
733
749
  // don't try to hit the registry for linked deps
734
750
  const useResolved = resolved && (
@@ -737,8 +753,7 @@ This is a one-time fix-up, please be patient...
737
753
  const id = useResolved ? resolved
738
754
  : version || `file:${node.path}`
739
755
  const spec = npa.resolve(name, id, dirname(path))
740
- const sloc = location.substr('node_modules/'.length)
741
- const t = `idealTree:inflate:${sloc}`
756
+ const t = `idealTree:inflate:${location}`
742
757
  this.addTracker(t)
743
758
  await pacote.manifest(spec, {
744
759
  ...this.options,
@@ -749,7 +764,7 @@ This is a one-time fix-up, please be patient...
749
764
  node.package = { ...mani, _id: `${mani.name}@${mani.version}` }
750
765
  }).catch((er) => {
751
766
  const warning = `Could not fetch metadata for ${name}@${id}`
752
- this.log.warn(heading, warning, er)
767
+ log.warn(heading, warning, er)
753
768
  })
754
769
  this.finishTracker(t)
755
770
  })
@@ -778,7 +793,7 @@ This is a one-time fix-up, please be patient...
778
793
  this[_depsQueue].push(tree)
779
794
  // XXX also push anything that depends on a node with a name
780
795
  // in the override list
781
- this.log.silly('idealTree', 'buildDeps')
796
+ log.silly('idealTree', 'buildDeps')
782
797
  this.addTracker('idealTree', tree.name, '')
783
798
  return this[_buildDepStep]()
784
799
  .then(() => process.emit('timeEnd', 'idealTree:buildDeps'))
@@ -1217,7 +1232,7 @@ This is a one-time fix-up, please be patient...
1217
1232
  if (this[_manifests].has(spec.raw)) {
1218
1233
  return this[_manifests].get(spec.raw)
1219
1234
  } else {
1220
- this.log.silly('fetch manifest', spec.raw)
1235
+ log.silly('fetch manifest', spec.raw)
1221
1236
  const p = pacote.manifest(spec, options)
1222
1237
  .then(mani => {
1223
1238
  this[_manifests].set(spec.raw, mani)
@@ -1234,24 +1249,40 @@ This is a one-time fix-up, please be patient...
1234
1249
  // Don't bother to load the manifest for link deps, because the target
1235
1250
  // might be within another package that doesn't exist yet.
1236
1251
  const { legacyPeerDeps } = this
1237
- return spec.type === 'directory'
1238
- ? this[_linkFromSpec](name, spec, parent, edge)
1239
- : this[_fetchManifest](spec)
1240
- .then(pkg => new Node({ name, pkg, parent, legacyPeerDeps }), error => {
1241
- error.requiredBy = edge.from.location || '.'
1242
-
1243
- // failed to load the spec, either because of enotarget or
1244
- // fetch failure of some other sort. save it so we can verify
1245
- // later that it's optional, otherwise the error is fatal.
1246
- const n = new Node({
1247
- name,
1248
- parent,
1249
- error,
1250
- legacyPeerDeps,
1251
- })
1252
- this[_loadFailures].add(n)
1253
- return n
1252
+
1253
+ // spec is a directory, link it
1254
+ if (spec.type === 'directory') {
1255
+ return this[_linkFromSpec](name, spec, parent, edge)
1256
+ }
1257
+
1258
+ // if the spec matches a workspace name, then see if the workspace node will
1259
+ // satisfy the edge. if it does, we return the workspace node to make sure it
1260
+ // takes priority.
1261
+ if (this.idealTree.workspaces && this.idealTree.workspaces.has(spec.name)) {
1262
+ const existingNode = this.idealTree.edgesOut.get(spec.name).to
1263
+ if (existingNode && existingNode.isWorkspace && existingNode.satisfies(edge)) {
1264
+ return edge.to
1265
+ }
1266
+ }
1267
+
1268
+ // spec isn't a directory, and either isn't a workspace or the workspace we have
1269
+ // doesn't satisfy the edge. try to fetch a manifest and build a node from that.
1270
+ return this[_fetchManifest](spec)
1271
+ .then(pkg => new Node({ name, pkg, parent, legacyPeerDeps }), error => {
1272
+ error.requiredBy = edge.from.location || '.'
1273
+
1274
+ // failed to load the spec, either because of enotarget or
1275
+ // fetch failure of some other sort. save it so we can verify
1276
+ // later that it's optional, otherwise the error is fatal.
1277
+ const n = new Node({
1278
+ name,
1279
+ parent,
1280
+ error,
1281
+ legacyPeerDeps,
1254
1282
  })
1283
+ this[_loadFailures].add(n)
1284
+ return n
1285
+ })
1255
1286
  }
1256
1287
 
1257
1288
  [_linkFromSpec] (name, spec, parent, edge) {
@@ -28,7 +28,6 @@
28
28
 
29
29
  const { resolve } = require('path')
30
30
  const { homedir } = require('os')
31
- const procLog = require('proc-log')
32
31
  const { depth } = require('treeverse')
33
32
  const { saveTypeMap } = require('../add-rm-pkg-deps.js')
34
33
 
@@ -74,7 +73,6 @@ class Arborist extends Base {
74
73
  path: options.path || '.',
75
74
  cache: options.cache || `${homedir()}/.npm/_cacache`,
76
75
  packumentCache: options.packumentCache || new Map(),
77
- log: options.log || procLog,
78
76
  workspacesEnabled: options.workspacesEnabled !== false,
79
77
  lockfileVersion: lockfileVersion(options.lockfileVersion),
80
78
  }
@@ -94,7 +92,7 @@ class Arborist extends Base {
94
92
 
95
93
  // returns an array of the actual nodes for all the workspaces
96
94
  workspaceNodes (tree, workspaces) {
97
- return getWorkspaceNodes(tree, workspaces, this.log)
95
+ return getWorkspaceNodes(tree, workspaces)
98
96
  }
99
97
 
100
98
  // returns a set of workspace nodes and all their deps
@@ -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
- const p = this[_loadFSNode]({ path, root: this[_actualTree] })
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 => {
@@ -13,6 +13,7 @@ const {
13
13
  isNodeGypPackage,
14
14
  defaultGypInstallScript,
15
15
  } = require('@npmcli/node-gyp')
16
+ const log = require('proc-log')
16
17
 
17
18
  const boolEnv = b => b ? '1' : ''
18
19
  const sortNodes = (a, b) =>
@@ -297,7 +298,7 @@ module.exports = cls => class Builder extends cls {
297
298
 
298
299
  const timer = `build:run:${event}:${location}`
299
300
  process.emit('time', timer)
300
- this.log.info('run', pkg._id, event, location, pkg.scripts[event])
301
+ log.info('run', pkg._id, event, location, pkg.scripts[event])
301
302
  const env = {
302
303
  npm_package_resolved: resolved,
303
304
  npm_package_integrity: integrity,
@@ -319,7 +320,7 @@ module.exports = cls => class Builder extends cls {
319
320
  }
320
321
  const p = runScript(runOpts).catch(er => {
321
322
  const { code, signal } = er
322
- this.log.info('run', pkg._id, event, { code, signal })
323
+ log.info('run', pkg._id, event, { code, signal })
323
324
  throw er
324
325
  }).then(({ args, code, signal, stdout, stderr }) => {
325
326
  this.scriptsRun.add({
@@ -333,7 +334,7 @@ module.exports = cls => class Builder extends cls {
333
334
  stdout,
334
335
  stderr,
335
336
  })
336
- this.log.info('run', pkg._id, event, { code, signal })
337
+ log.info('run', pkg._id, event, { code, signal })
337
338
  })
338
339
 
339
340
  await (this[_doHandleOptionalFailure]
@@ -5,8 +5,10 @@ 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')
11
+ const log = require('proc-log')
10
12
 
11
13
  const { dirname, resolve, relative } = require('path')
12
14
  const { depth: dfwalk } = require('treeverse')
@@ -389,7 +391,7 @@ module.exports = cls => class Reifier extends cls {
389
391
  [_addNodeToTrashList] (node, retire = false) {
390
392
  const paths = [node.path, ...node.binPaths]
391
393
  const moves = this[_retiredPaths]
392
- this.log.silly('reify', 'mark', retire ? 'retired' : 'deleted', paths)
394
+ log.silly('reify', 'mark', retire ? 'retired' : 'deleted', paths)
393
395
  for (const path of paths) {
394
396
  if (retire) {
395
397
  const retired = retirePath(path)
@@ -412,7 +414,7 @@ module.exports = cls => class Reifier extends cls {
412
414
  this[_addNodeToTrashList](diff.actual, true)
413
415
  }
414
416
  }
415
- this.log.silly('reify', 'moves', moves)
417
+ log.silly('reify', 'moves', moves)
416
418
  const movePromises = Object.entries(moves)
417
419
  .map(([from, to]) => this[_renamePath](from, to))
418
420
  return promiseAllRejectLate(movePromises)
@@ -531,7 +533,7 @@ module.exports = cls => class Reifier extends cls {
531
533
  return promiseAllRejectLate(unlinks)
532
534
  .then(() => {
533
535
  if (failures.length) {
534
- this.log.warn('cleanup', 'Failed to remove some directories', failures)
536
+ log.warn('cleanup', 'Failed to remove some directories', failures)
535
537
  }
536
538
  })
537
539
  .then(() => process.emit('timeEnd', 'reify:rollback:createSparse'))
@@ -623,7 +625,7 @@ module.exports = cls => class Reifier extends cls {
623
625
  this[_nmValidated].add(nm)
624
626
  return
625
627
  }
626
- this.log.warn('reify', 'Removing non-directory', nm)
628
+ log.warn('reify', 'Removing non-directory', nm)
627
629
  await rimraf(nm)
628
630
  }
629
631
 
@@ -646,8 +648,8 @@ module.exports = cls => class Reifier extends cls {
646
648
  'please re-try this operation once it completes\n' +
647
649
  'so that the damage can be corrected, or perform\n' +
648
650
  'a fresh install with no lockfile if the problem persists.'
649
- this.log.warn('reify', warning)
650
- this.log.verbose('reify', 'unrecognized node in tree', node.path)
651
+ log.warn('reify', warning)
652
+ log.verbose('reify', 'unrecognized node in tree', node.path)
651
653
  node.parent = null
652
654
  node.fsParent = null
653
655
  this[_addNodeToTrashList](node)
@@ -690,7 +692,7 @@ module.exports = cls => class Reifier extends cls {
690
692
  [_warnDeprecated] (node) {
691
693
  const { _id, deprecated } = node.package
692
694
  if (deprecated) {
693
- this.log.warn('deprecated', `${_id}: ${deprecated}`)
695
+ log.warn('deprecated', `${_id}: ${deprecated}`)
694
696
  }
695
697
  }
696
698
 
@@ -700,7 +702,7 @@ module.exports = cls => class Reifier extends cls {
700
702
  return (node.optional ? p.catch(er => {
701
703
  const set = optionalSet(node)
702
704
  for (node of set) {
703
- this.log.verbose('reify', 'failed optional dependency', node.path)
705
+ log.verbose('reify', 'failed optional dependency', node.path)
704
706
  this[_addNodeToTrashList](node)
705
707
  }
706
708
  }) : p).then(() => node)
@@ -715,7 +717,7 @@ module.exports = cls => class Reifier extends cls {
715
717
  // Shrinkwrap and Node classes carefully, so for now, just treat
716
718
  // the default reg as the magical animal that it has been.
717
719
  return resolved && resolved
718
- .replace(/^https?:\/\/registry.npmjs.org\//, this.registry)
720
+ .replace(/^https?:\/\/registry\.npmjs\.org\//, this.registry)
719
721
  }
720
722
 
721
723
  // bundles are *sort of* like shrinkwraps, in that the branch is defined
@@ -1128,7 +1130,7 @@ module.exports = cls => class Reifier extends cls {
1128
1130
 
1129
1131
  return promiseAllRejectLate(promises).then(() => {
1130
1132
  if (failures.length) {
1131
- this.log.warn('cleanup', 'Failed to remove some directories', failures)
1133
+ log.warn('cleanup', 'Failed to remove some directories', failures)
1132
1134
  }
1133
1135
  })
1134
1136
  .then(() => process.emit('timeEnd', 'reify:trash'))
@@ -1273,6 +1275,21 @@ module.exports = cls => class Reifier extends cls {
1273
1275
  }
1274
1276
  }
1275
1277
 
1278
+ // Returns true if any of the edges from this node has a semver
1279
+ // range definition that is an exact match to the version installed
1280
+ // e.g: should return true if for a given an installed version 1.0.0,
1281
+ // range is either =1.0.0 or 1.0.0
1282
+ const exactVersion = node => {
1283
+ for (const edge of node.edgesIn) {
1284
+ try {
1285
+ if (semver.subset(edge.spec, node.version)) {
1286
+ return false
1287
+ }
1288
+ } catch {}
1289
+ }
1290
+ return true
1291
+ }
1292
+
1276
1293
  // helper that retrieves an array of nodes that were
1277
1294
  // potentially updated during the reify process, in order
1278
1295
  // to limit the number of nodes to check and update, only
@@ -1284,6 +1301,8 @@ module.exports = cls => class Reifier extends cls {
1284
1301
  const filterDirectDependencies = node =>
1285
1302
  !node.isRoot && node.resolveParent.isRoot
1286
1303
  && (!names || names.includes(node.name))
1304
+ && exactVersion(node) // skip update for exact ranges
1305
+
1287
1306
  const directDeps = this.idealTree.inventory
1288
1307
  .filter(filterDirectDependencies)
1289
1308
 
@@ -1351,6 +1370,10 @@ module.exports = cls => class Reifier extends cls {
1351
1370
  devDependencies = {},
1352
1371
  optionalDependencies = {},
1353
1372
  peerDependencies = {},
1373
+ // bundleDependencies is not required by PackageJson like the other fields here
1374
+ // PackageJson also doesn't omit an empty array for this field so defaulting this
1375
+ // to an empty array would add that field to every package.json file.
1376
+ bundleDependencies,
1354
1377
  } = tree.package
1355
1378
 
1356
1379
  pkgJson.update({
@@ -1358,6 +1381,7 @@ module.exports = cls => class Reifier extends cls {
1358
1381
  devDependencies,
1359
1382
  optionalDependencies,
1360
1383
  peerDependencies,
1384
+ bundleDependencies,
1361
1385
  })
1362
1386
  await pkgJson.save()
1363
1387
  }
@@ -13,7 +13,7 @@ const _fixAvailable = Symbol('fixAvailable')
13
13
  const _checkTopNode = Symbol('checkTopNode')
14
14
  const _init = Symbol('init')
15
15
  const _omit = Symbol('omit')
16
- const procLog = require('proc-log')
16
+ const log = require('proc-log')
17
17
 
18
18
  const fetch = require('npm-registry-fetch')
19
19
 
@@ -98,14 +98,13 @@ class AuditReport extends Map {
98
98
  this.calculator = new Calculator(opts)
99
99
  this.error = null
100
100
  this.options = opts
101
- this.log = opts.log || procLog
102
101
  this.tree = tree
103
102
  this.filterSet = opts.filterSet
104
103
  }
105
104
 
106
105
  async run () {
107
106
  this.report = await this[_getReport]()
108
- this.log.silly('audit report', this.report)
107
+ log.silly('audit report', this.report)
109
108
  if (this.report) {
110
109
  await this[_init]()
111
110
  }
@@ -304,7 +303,7 @@ class AuditReport extends Map {
304
303
 
305
304
  async [_getReport] () {
306
305
  // if we're not auditing, just return false
307
- if (this.options.audit === false || this.tree.inventory.size === 1) {
306
+ if (this.options.audit === false || this.options.offline === true || this.tree.inventory.size === 1) {
308
307
  return null
309
308
  }
310
309
 
@@ -313,7 +312,7 @@ class AuditReport extends Map {
313
312
  try {
314
313
  // first try the super fast bulk advisory listing
315
314
  const body = prepareBulkData(this.tree, this[_omit], this.filterSet)
316
- this.log.silly('audit', 'bulk request', body)
315
+ log.silly('audit', 'bulk request', body)
317
316
 
318
317
  // no sense asking if we don't have anything to audit,
319
318
  // we know it'll be empty
@@ -331,7 +330,7 @@ class AuditReport extends Map {
331
330
 
332
331
  return await res.json()
333
332
  } catch (er) {
334
- this.log.silly('audit', 'bulk request failed', String(er.body))
333
+ log.silly('audit', 'bulk request failed', String(er.body))
335
334
  // that failed, try the quick audit endpoint
336
335
  const body = prepareData(this.tree, this.options)
337
336
  const res = await fetch('/-/npm/v1/security/audits/quick', {
@@ -344,8 +343,8 @@ class AuditReport extends Map {
344
343
  return AuditReport.auditToBulk(await res.json())
345
344
  }
346
345
  } catch (er) {
347
- this.log.verbose('audit error', er)
348
- this.log.silly('audit error', String(er.body))
346
+ log.verbose('audit error', er)
347
+ log.silly('audit error', String(er.body))
349
348
  this.error = er
350
349
  return null
351
350
  } finally {
@@ -1,7 +1,10 @@
1
1
  // Get the actual nodes corresponding to a root node's child workspaces,
2
2
  // given a list of workspace names.
3
+
4
+ const log = require('proc-log')
3
5
  const relpath = require('./relpath.js')
4
- const getWorkspaceNodes = (tree, workspaces, log) => {
6
+
7
+ const getWorkspaceNodes = (tree, workspaces) => {
5
8
  const wsMap = tree.workspaces
6
9
  if (!wsMap) {
7
10
  log.warn('workspaces', 'filter set, but no workspaces present')
package/lib/shrinkwrap.js CHANGED
@@ -33,7 +33,7 @@ const mismatch = (a, b) => a && b && a !== b
33
33
  // After calling this.commit(), any nodes not present in the tree will have
34
34
  // been removed from the shrinkwrap data as well.
35
35
 
36
- const procLog = require('proc-log')
36
+ const log = require('proc-log')
37
37
  const YarnLock = require('./yarn-lock.js')
38
38
  const { promisify } = require('util')
39
39
  const rimraf = promisify(require('rimraf'))
@@ -80,8 +80,8 @@ const swKeyOrder = [
80
80
  ]
81
81
 
82
82
  // used to rewrite from yarn registry to npm registry
83
- const yarnRegRe = /^https?:\/\/registry.yarnpkg.com\//
84
- const npmRegRe = /^https?:\/\/registry.npmjs.org\//
83
+ const yarnRegRe = /^https?:\/\/registry\.yarnpkg\.com\//
84
+ const npmRegRe = /^https?:\/\/registry\.npmjs\.org\//
85
85
 
86
86
  // sometimes resolved: is weird or broken, or something npa can't handle
87
87
  const specFromResolved = resolved => {
@@ -329,14 +329,12 @@ class Shrinkwrap {
329
329
  newline = '\n',
330
330
  shrinkwrapOnly = false,
331
331
  hiddenLockfile = false,
332
- log = procLog,
333
332
  lockfileVersion,
334
333
  } = options
335
334
 
336
335
  this.lockfileVersion = hiddenLockfile ? 3
337
336
  : lockfileVersion ? parseInt(lockfileVersion, 10)
338
337
  : null
339
- this.log = log
340
338
  this[_awaitingUpdate] = new Map()
341
339
  this.tree = null
342
340
  this.path = resolve(path || '.')
@@ -476,8 +474,13 @@ class Shrinkwrap {
476
474
  // all good! hidden lockfile is the newest thing in here.
477
475
  return data
478
476
  }).catch(er => {
479
- const rel = relpath(this.path, this.filename)
480
- this.log.verbose('shrinkwrap', `failed to load ${rel}`, er)
477
+ /* istanbul ignore else */
478
+ if (typeof this.filename === 'string') {
479
+ const rel = relpath(this.path, this.filename)
480
+ log.verbose('shrinkwrap', `failed to load ${rel}`, er)
481
+ } else {
482
+ log.verbose('shrinkwrap', `failed to load ${this.path}`, er)
483
+ }
481
484
  this.loadingError = er
482
485
  this.loadedFromDisk = false
483
486
  this.ancientLockfile = false
package/lib/tracker.js CHANGED
@@ -1,20 +1,14 @@
1
1
  const _progress = Symbol('_progress')
2
2
  const _onError = Symbol('_onError')
3
- const procLog = require('proc-log')
3
+ const npmlog = require('npmlog')
4
4
 
5
5
  module.exports = cls => class Tracker extends cls {
6
6
  constructor (options = {}) {
7
7
  super(options)
8
- this.log = options.log || procLog
9
8
  this[_progress] = new Map()
10
9
  }
11
10
 
12
11
  addTracker (section, subsection = null, key = null) {
13
- // TrackerGroup type object not found
14
- if (!this.log.newGroup) {
15
- return
16
- }
17
-
18
12
  if (section === null || section === undefined) {
19
13
  this[_onError](`Tracker can't be null or undefined`)
20
14
  }
@@ -31,13 +25,13 @@ module.exports = cls => class Tracker extends cls {
31
25
  this[_onError](`Tracker "${section}" already exists`)
32
26
  } else if (!hasTracker && subsection === null) {
33
27
  // 1. no existing tracker, no subsection
34
- // Create a new tracker from this.log
28
+ // Create a new tracker from npmlog
35
29
  // starts progress bar
36
30
  if (this[_progress].size === 0) {
37
- this.log.enableProgress()
31
+ npmlog.enableProgress()
38
32
  }
39
33
 
40
- this[_progress].set(section, this.log.newGroup(section))
34
+ this[_progress].set(section, npmlog.newGroup(section))
41
35
  } else if (!hasTracker && subsection !== null) {
42
36
  // 2. no parent tracker and subsection
43
37
  this[_onError](`Parent tracker "${section}" does not exist`)
@@ -53,11 +47,6 @@ module.exports = cls => class Tracker extends cls {
53
47
  }
54
48
 
55
49
  finishTracker (section, subsection = null, key = null) {
56
- // TrackerGroup type object not found
57
- if (!this.log.newGroup) {
58
- return
59
- }
60
-
61
50
  if (section === null || section === undefined) {
62
51
  this[_onError](`Tracker can't be null or undefined`)
63
52
  }
@@ -88,7 +77,7 @@ module.exports = cls => class Tracker extends cls {
88
77
  // remove progress bar if all
89
78
  // trackers are finished
90
79
  if (this[_progress].size === 0) {
91
- this.log.disableProgress()
80
+ npmlog.disableProgress()
92
81
  }
93
82
  } else if (!hasTracker && subsection === null) {
94
83
  // 1. no existing parent tracker, no subsection
@@ -103,7 +92,7 @@ module.exports = cls => class Tracker extends cls {
103
92
  }
104
93
 
105
94
  [_onError] (msg) {
106
- this.log.disableProgress()
95
+ npmlog.disableProgress()
107
96
  throw new Error(msg)
108
97
  }
109
98
  }
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@npmcli/arborist",
3
- "version": "4.2.1",
3
+ "version": "5.0.0",
4
4
  "description": "Manage node_modules trees",
5
5
  "dependencies": {
6
6
  "@isaacs/string-locale-compare": "^1.1.0",
7
7
  "@npmcli/installed-package-contents": "^1.0.7",
8
8
  "@npmcli/map-workspaces": "^2.0.0",
9
- "@npmcli/metavuln-calculator": "^2.0.0",
9
+ "@npmcli/metavuln-calculator": "^3.0.0",
10
10
  "@npmcli/move-file": "^1.1.0",
11
11
  "@npmcli/name-from-folder": "^1.0.1",
12
12
  "@npmcli/node-gyp": "^1.0.3",
13
13
  "@npmcli/package-json": "^1.0.1",
14
- "@npmcli/run-script": "^2.0.0",
14
+ "@npmcli/run-script": "^3.0.0",
15
15
  "bin-links": "^3.0.0",
16
16
  "cacache": "^15.0.3",
17
17
  "common-ancestor-path": "^1.0.1",
@@ -19,13 +19,15 @@
19
19
  "json-stringify-nice": "^1.1.4",
20
20
  "mkdirp": "^1.0.4",
21
21
  "mkdirp-infer-owner": "^2.0.0",
22
+ "nopt": "^5.0.0",
22
23
  "npm-install-checks": "^4.0.0",
23
- "npm-package-arg": "^8.1.5",
24
- "npm-pick-manifest": "^6.1.0",
25
- "npm-registry-fetch": "^11.0.0",
26
- "pacote": "^12.0.2",
24
+ "npm-package-arg": "^9.0.0",
25
+ "npm-pick-manifest": "^7.0.0",
26
+ "npm-registry-fetch": "^13.0.0",
27
+ "npmlog": "^6.0.1",
28
+ "pacote": "^13.0.2",
27
29
  "parse-conflict-json": "^2.0.1",
28
- "proc-log": "^1.0.0",
30
+ "proc-log": "^2.0.0",
29
31
  "promise-all-reject-late": "^1.0.0",
30
32
  "promise-call-limit": "^1.0.1",
31
33
  "read-package-json-fast": "^2.0.2",