@npmcli/arborist 9.1.5 → 9.1.6

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/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  Inspect and manage `node_modules` trees.
8
8
 
9
- ![a tree with the word ARBORIST superimposed on it](https://raw.githubusercontent.com/npm/arborist/main/docs/logo.svg?sanitize=true)
9
+ ![a tree with the word ARBORIST superimposed on it](https://raw.githubusercontent.com/npm/cli/latest/workspaces/arborist/docs/logo.svg?sanitize=true)
10
10
 
11
11
  There's more documentation [in the docs
12
12
  folder](https://github.com/npm/cli/tree/latest/workspaces/arborist/docs).
package/bin/index.js CHANGED
@@ -37,7 +37,7 @@ ${message && '\n' + message + '\n'}
37
37
 
38
38
  Additionally:
39
39
 
40
- * --loglevel=warn|--quiet will supppress the printing of package trees
40
+ * --loglevel=warn|--quiet will suppress the printing of package trees
41
41
  * --logfile <file|bool> will output logs to a file
42
42
  * --timing will show timing information
43
43
  * Instead of 'npm install <pkg>', use 'arborist reify --add=<pkg>'.
@@ -192,7 +192,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
192
192
  }
193
193
 
194
194
  async #checkEngineAndPlatform () {
195
- const { engineStrict, npmVersion, nodeVersion, omit = [] } = this.options
195
+ const { engineStrict, npmVersion, nodeVersion, omit = [], cpu, os, libc } = this.options
196
196
  const omitSet = new Set(omit)
197
197
 
198
198
  for (const node of this.idealTree.inventory.values()) {
@@ -214,6 +214,19 @@ module.exports = cls => class IdealTreeBuilder extends cls {
214
214
  }
215
215
  checkPlatform(node.package, this.options.force)
216
216
  }
217
+ if (node.optional && !node.inert) {
218
+ // Mark any optional packages we can't install as inert.
219
+ // We ignore the --force and --engine-strict flags.
220
+ try {
221
+ checkEngine(node.package, npmVersion, nodeVersion, false)
222
+ checkPlatform(node.package, false, { cpu, os, libc })
223
+ } catch (error) {
224
+ const set = optionalSet(node)
225
+ for (const node of set) {
226
+ node.inert = true
227
+ }
228
+ }
229
+ }
217
230
  }
218
231
  }
219
232
 
@@ -324,7 +337,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
324
337
  })
325
338
 
326
339
  .then(tree => {
327
- // search the virtual tree for invalid edges, if any are found add their source to
340
+ // search the virtual tree for missing/invalid edges, if any are found add their source to
328
341
  // the depsQueue so that we'll fix it later
329
342
  depth({
330
343
  tree,
@@ -338,7 +351,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
338
351
  filter: node => node,
339
352
  visit: node => {
340
353
  for (const edge of node.edgesOut.values()) {
341
- if (!edge.valid) {
354
+ if (!edge.to || !edge.valid) {
342
355
  this.#depsQueue.push(node)
343
356
  break // no need to continue the loop after the first hit
344
357
  }
@@ -811,7 +824,7 @@ This is a one-time fix-up, please be patient...
811
824
  node !== this.idealTree &&
812
825
  node.resolved &&
813
826
  (hasBundle || hasShrinkwrap) &&
814
- !node.ideallyInert
827
+ !node.inert
815
828
  if (crackOpen) {
816
829
  const Arborist = this.constructor
817
830
  const opt = { ...this.options }
@@ -1011,7 +1024,7 @@ This is a one-time fix-up, please be patient...
1011
1024
  }
1012
1025
 
1013
1026
  // pre-fetch any problem edges, since we'll need these soon
1014
- // if it fails at this point, though, dont' worry because it
1027
+ // if it fails at this point, though, don't worry because it
1015
1028
  // may well be an optional dep that has gone missing. it'll
1016
1029
  // fail later anyway.
1017
1030
  for (const e of this.#problemEdges(placed)) {
@@ -1067,7 +1080,7 @@ This is a one-time fix-up, please be patient...
1067
1080
  ? await this.#nodeFromSpec(edge.name, spec2, parent, secondEdge)
1068
1081
  : null
1069
1082
 
1070
- // pick the second one if they're both happy with that, otherwise first
1083
+ // pick the second one if they're both happy with that; otherwise, first
1071
1084
  const node = second && edge.valid ? second : first
1072
1085
  // ensure the one we want is the one that's placed
1073
1086
  node.parent = parent
@@ -1274,7 +1287,7 @@ This is a one-time fix-up, please be patient...
1274
1287
 
1275
1288
  // failed to load the spec, either because of enotarget or
1276
1289
  // fetch failure of some other sort. save it so we can verify
1277
- // later that it's optional, otherwise the error is fatal.
1290
+ // later that it's optional; otherwise, the error is fatal.
1278
1291
  const n = new Node({
1279
1292
  name,
1280
1293
  parent,
@@ -1431,7 +1444,7 @@ This is a one-time fix-up, please be patient...
1431
1444
  // - if a path under an existing node, then assign that as the fsParent,
1432
1445
  // and add it to the _depsQueue
1433
1446
  //
1434
- // call buildDepStep if anything was added to the queue, otherwise we're done
1447
+ // call buildDepStep if anything was added to the queue; otherwise, we're done
1435
1448
  #resolveLinks () {
1436
1449
  for (const link of this.#linkNodes) {
1437
1450
  this.#linkNodes.delete(link)
@@ -1561,7 +1574,7 @@ This is a one-time fix-up, please be patient...
1561
1574
 
1562
1575
  const set = optionalSet(node)
1563
1576
  for (const node of set) {
1564
- node.ideallyInert = true
1577
+ node.inert = true
1565
1578
  }
1566
1579
  }
1567
1580
  }
@@ -1582,7 +1595,7 @@ This is a one-time fix-up, please be patient...
1582
1595
  node.parent !== null
1583
1596
  && !node.isProjectRoot
1584
1597
  && !excludeNodes.has(node)
1585
- && !node.ideallyInert
1598
+ && !node.inert
1586
1599
  ) {
1587
1600
  this[_addNodeToTrashList](node)
1588
1601
  }
@@ -81,7 +81,7 @@ module.exports = cls => class IsolatedReifier extends cls {
81
81
  }
82
82
  queue.push(e.to)
83
83
  })
84
- if (!next.isProjectRoot && !next.isWorkspace && !next.ideallyInert) {
84
+ if (!next.isProjectRoot && !next.isWorkspace && !next.inert) {
85
85
  root.external.push(await this.externalProxyMemo(next))
86
86
  }
87
87
  }
@@ -140,15 +140,15 @@ module.exports = cls => class IsolatedReifier extends cls {
140
140
 
141
141
  async assignCommonProperties (node, result) {
142
142
  function validEdgesOut (node) {
143
- return [...node.edgesOut.values()].filter(e => e.to && e.to.target && !(node.package.bundledDepenedencies || node.package.bundleDependencies || []).includes(e.to.name))
143
+ return [...node.edgesOut.values()].filter(e => e.to && e.to.target && !(node.package.bundledDependencies || node.package.bundleDependencies || []).includes(e.to.name))
144
144
  }
145
145
  const edges = validEdgesOut(node)
146
146
  const optionalDeps = edges.filter(e => e.optional).map(e => e.to.target)
147
147
  const nonOptionalDeps = edges.filter(e => !e.optional).map(e => e.to.target)
148
148
 
149
149
  result.localDependencies = await Promise.all(nonOptionalDeps.filter(n => n.isWorkspace).map(this.workspaceProxyMemo))
150
- result.externalDependencies = await Promise.all(nonOptionalDeps.filter(n => !n.isWorkspace && !n.ideallyInert).map(this.externalProxyMemo))
151
- result.externalOptionalDependencies = await Promise.all(optionalDeps.filter(n => !n.ideallyInert).map(this.externalProxyMemo))
150
+ result.externalDependencies = await Promise.all(nonOptionalDeps.filter(n => !n.isWorkspace && !n.inert).map(this.externalProxyMemo))
151
+ result.externalOptionalDependencies = await Promise.all(optionalDeps.filter(n => !n.inert).map(this.externalProxyMemo))
152
152
  result.dependencies = [
153
153
  ...result.externalDependencies,
154
154
  ...result.localDependencies,
@@ -36,7 +36,7 @@ module.exports = cls => class ActualLoader extends cls {
36
36
  // We don't do fsParent as a magic getter/setter, because it'd be too costly
37
37
  // to keep up to date along the walk.
38
38
  // And, we know that it can ONLY be relevant when the node is a target of a
39
- // link, otherwise it'd be in a node_modules folder, so take advantage of
39
+ // link; otherwise, it'd be in a node_modules folder, so take advantage of
40
40
  // that to limit the scans later.
41
41
  #topNodes = new Set()
42
42
  #transplantFilter
@@ -168,7 +168,7 @@ module.exports = cls => class VirtualLoader extends cls {
168
168
  }
169
169
  }
170
170
 
171
- // separate out link metadatas, and create Node objects for nodes
171
+ // separate out link metadata, and create Node objects for nodes
172
172
  #resolveNodes (s, root) {
173
173
  const links = new Map()
174
174
  const nodes = new Map([['', root]])
@@ -269,7 +269,6 @@ To fix:
269
269
  integrity: sw.integrity,
270
270
  resolved: consistentResolve(sw.resolved, this.path, path),
271
271
  pkg: sw,
272
- ideallyInert: sw.ideallyInert,
273
272
  hasShrinkwrap: sw.hasShrinkwrap,
274
273
  dev,
275
274
  optional,
@@ -7,7 +7,6 @@ const pacote = require('pacote')
7
7
  const promiseAllRejectLate = require('promise-all-reject-late')
8
8
  const runScript = require('@npmcli/run-script')
9
9
  const { callLimit: promiseCallLimit } = require('promise-call-limit')
10
- const { checkEngine, checkPlatform } = require('npm-install-checks')
11
10
  const { depth: dfwalk } = require('treeverse')
12
11
  const { dirname, resolve, relative, join } = require('node:path')
13
12
  const { log, time } = require('proc-log')
@@ -74,7 +73,6 @@ module.exports = cls => class Reifier extends cls {
74
73
  #dryRun
75
74
  #nmValidated = new Set()
76
75
  #omit
77
- #omitted
78
76
  #retiredPaths = {}
79
77
  #retiredUnchanged = {}
80
78
  #savePrefix
@@ -99,7 +97,6 @@ module.exports = cls => class Reifier extends cls {
99
97
  }
100
98
 
101
99
  this.#omit = new Set(options.omit)
102
- this.#omitted = new Set()
103
100
 
104
101
  // start tracker block
105
102
  this.addTracker('reify')
@@ -132,15 +129,17 @@ module.exports = cls => class Reifier extends cls {
132
129
  this.idealTree = oldTree
133
130
  }
134
131
  await this[_saveIdealTree](options)
135
- // clean omitted
136
- for (const node of this.#omitted) {
137
- node.parent = null
132
+ // clean inert
133
+ for (const node of this.idealTree.inventory.values()) {
134
+ if (node.inert) {
135
+ node.parent = null
136
+ }
138
137
  }
139
138
  // clean up any trash that is still in the tree
140
139
  for (const path of this[_trashList]) {
141
140
  const loc = relpath(this.idealTree.realpath, path)
142
141
  const node = this.idealTree.inventory.get(loc)
143
- if (node && node.root === this.idealTree && !node.ideallyInert) {
142
+ if (node && node.root === this.idealTree) {
144
143
  node.parent = null
145
144
  }
146
145
  }
@@ -228,18 +227,6 @@ module.exports = cls => class Reifier extends cls {
228
227
  this.idealTree.meta.hiddenLockfile = true
229
228
  this.idealTree.meta.lockfileVersion = defaultLockfileVersion
230
229
 
231
- // Preserve inertness for failed stuff.
232
- if (this.actualTree) {
233
- for (const [loc, actual] of this.actualTree.inventory.entries()) {
234
- if (actual.ideallyInert) {
235
- const ideal = this.idealTree.inventory.get(loc)
236
- if (ideal) {
237
- ideal.ideallyInert = true
238
- }
239
- }
240
- }
241
- }
242
-
243
230
  this.actualTree = this.idealTree
244
231
  this.idealTree = null
245
232
 
@@ -465,7 +452,6 @@ module.exports = cls => class Reifier extends cls {
465
452
  // and ideal trees.
466
453
  this.diff = Diff.calculate({
467
454
  omit: this.#omit,
468
- omitted: this.#omitted,
469
455
  shrinkwrapInflated: this.#shrinkwrapInflated,
470
456
  filterNodes,
471
457
  actual: this.actualTree,
@@ -566,9 +552,6 @@ module.exports = cls => class Reifier extends cls {
566
552
  // retire the same path at the same time.
567
553
  const dirsChecked = new Set()
568
554
  return promiseAllRejectLate(leaves.map(async node => {
569
- if (node.ideallyInert) {
570
- return
571
- }
572
555
  for (const d of walkUp(node.path)) {
573
556
  if (d === node.top.path) {
574
557
  break
@@ -662,18 +645,7 @@ module.exports = cls => class Reifier extends cls {
662
645
  const timeEnd = time.start(`reifyNode:${node.location}`)
663
646
  this.addTracker('reify', node.name, node.location)
664
647
 
665
- const { npmVersion, nodeVersion, cpu, os, libc } = this.options
666
648
  const p = Promise.resolve().then(async () => {
667
- // when we reify an optional node, check the engine and platform
668
- // first. be sure to ignore the --force and --engine-strict flags,
669
- // since we always want to skip any optional packages we can't install.
670
- // these checks throwing will result in a rollback and removal
671
- // of the mismatches
672
- // eslint-disable-next-line promise/always-return
673
- if (node.optional) {
674
- checkEngine(node.package, npmVersion, nodeVersion, false)
675
- checkPlatform(node.package, false, { cpu, os, libc })
676
- }
677
649
  await this[_checkBins](node)
678
650
  await this.#extractOrLink(node)
679
651
  const { _id, deprecated } = node.package
@@ -707,10 +679,6 @@ module.exports = cls => class Reifier extends cls {
707
679
  }
708
680
 
709
681
  async #extractOrLink (node) {
710
- if (node.ideallyInert) {
711
- return
712
- }
713
-
714
682
  const nm = resolve(node.parent.path, 'node_modules')
715
683
  await this.#validateNodeModules(nm)
716
684
 
@@ -791,9 +759,9 @@ module.exports = cls => class Reifier extends cls {
791
759
  [_handleOptionalFailure] (node, p) {
792
760
  return (node.optional ? p.catch(() => {
793
761
  const set = optionalSet(node)
794
- for (node of set) {
762
+ for (const node of set) {
795
763
  log.verbose('reify', 'failed optional dependency', node.path)
796
- node.ideallyInert = true
764
+ node.inert = true
797
765
  this[_addNodeToTrashList](node)
798
766
  }
799
767
  }) : p).then(() => node)
@@ -1165,9 +1133,6 @@ module.exports = cls => class Reifier extends cls {
1165
1133
 
1166
1134
  this.#retiredUnchanged[retireFolder] = []
1167
1135
  return promiseAllRejectLate(diff.unchanged.map(node => {
1168
- if (node.ideallyInert) {
1169
- return
1170
- }
1171
1136
  // no need to roll back links, since we'll just delete them anyway
1172
1137
  if (node.isLink) {
1173
1138
  return mkdir(dirname(node.path), { recursive: true, force: true })
@@ -1247,7 +1212,7 @@ module.exports = cls => class Reifier extends cls {
1247
1212
  // skip links that only live within node_modules as they are most
1248
1213
  // likely managed by packages we installed, we only want to rebuild
1249
1214
  // unchanged links we directly manage
1250
- const linkedFromRoot = (node.parent === tree && !node.ideallyInert) || node.target.fsTop === tree
1215
+ const linkedFromRoot = (node.parent === tree && !node.inert) || node.target.fsTop === tree
1251
1216
  if (node.isLink && linkedFromRoot) {
1252
1217
  nodes.push(node)
1253
1218
  }
@@ -1358,7 +1323,7 @@ module.exports = cls => class Reifier extends cls {
1358
1323
  const alias = name !== pname
1359
1324
  newSpec = alias ? `npm:${pname}@${range}` : range
1360
1325
  } else if (req.hosted) {
1361
- // save the git+https url if it has auth, otherwise shortcut
1326
+ // save the git+https url if it has auth; otherwise, shortcut
1362
1327
  const h = req.hosted
1363
1328
  const opt = { noCommittish: false }
1364
1329
  if (h.https && h.auth) {
@@ -1427,7 +1392,7 @@ module.exports = cls => class Reifier extends cls {
1427
1392
 
1428
1393
  // Returns true if any of the edges from this node has a semver
1429
1394
  // range definition that is an exact match to the version installed
1430
- // e.g: should return true if for a given an installed version 1.0.0,
1395
+ // e.g: should return true if for a given and installed version 1.0.0,
1431
1396
  // range is either =1.0.0 or 1.0.0
1432
1397
  const exactVersion = node => {
1433
1398
  for (const edge of node.edgesIn) {
package/lib/diff.js CHANGED
@@ -11,9 +11,8 @@ const { existsSync } = require('node:fs')
11
11
  const ssri = require('ssri')
12
12
 
13
13
  class Diff {
14
- constructor ({ actual, ideal, filterSet, shrinkwrapInflated, omit, omitted }) {
14
+ constructor ({ actual, ideal, filterSet, shrinkwrapInflated, omit }) {
15
15
  this.omit = omit
16
- this.omitted = omitted
17
16
  this.filterSet = filterSet
18
17
  this.shrinkwrapInflated = shrinkwrapInflated
19
18
  this.children = []
@@ -39,7 +38,6 @@ class Diff {
39
38
  filterNodes = [],
40
39
  shrinkwrapInflated = new Set(),
41
40
  omit = new Set(),
42
- omitted = new Set(),
43
41
  }) {
44
42
  // if there's a filterNode, then:
45
43
  // - get the path from the root to the filterNode. The root or
@@ -98,28 +96,18 @@ class Diff {
98
96
  }
99
97
 
100
98
  return depth({
101
- tree: new Diff({ actual, ideal, filterSet, shrinkwrapInflated, omit, omitted }),
99
+ tree: new Diff({ actual, ideal, filterSet, shrinkwrapInflated, omit }),
102
100
  getChildren,
103
101
  leave,
104
102
  })
105
103
  }
106
104
  }
107
105
 
108
- const getAction = ({ actual, ideal, omit, omitted }) => {
106
+ const getAction = ({ actual, ideal }) => {
109
107
  if (!ideal) {
110
108
  return 'REMOVE'
111
109
  }
112
110
 
113
- if (ideal.shouldOmit?.(omit)) {
114
- omitted.add(ideal)
115
-
116
- if (actual) {
117
- return 'REMOVE'
118
- }
119
-
120
- return null
121
- }
122
-
123
111
  // bundled meta-deps are copied over to the ideal tree when we visit it,
124
112
  // so they'll appear to be missing here. There's no need to handle them
125
113
  // in the diff, though, because they'll be replaced at reify time anyway
@@ -199,7 +187,6 @@ const getChildren = diff => {
199
187
  filterSet,
200
188
  shrinkwrapInflated,
201
189
  omit,
202
- omitted,
203
190
  } = diff
204
191
 
205
192
  // Note: we DON'T diff fsChildren themselves, because they are either
@@ -231,7 +218,6 @@ const getChildren = diff => {
231
218
  filterSet,
232
219
  shrinkwrapInflated,
233
220
  omit,
234
- omitted,
235
221
  })
236
222
  }
237
223
 
@@ -251,13 +237,24 @@ const diffNode = ({
251
237
  filterSet,
252
238
  shrinkwrapInflated,
253
239
  omit,
254
- omitted,
255
240
  }) => {
256
241
  if (filterSet.size && !(filterSet.has(ideal) || filterSet.has(actual))) {
257
242
  return
258
243
  }
259
244
 
260
- const action = getAction({ actual, ideal, omit, omitted })
245
+ if (ideal?.shouldOmit?.(omit)) {
246
+ ideal.inert = true
247
+ }
248
+
249
+ // Treat inert nodes as undefined for the purposes of diffing.
250
+ if (ideal?.inert) {
251
+ ideal = undefined
252
+ }
253
+ if (!actual && !ideal) {
254
+ return
255
+ }
256
+
257
+ const action = getAction({ actual, ideal })
261
258
 
262
259
  // if it's a match, then get its children
263
260
  // otherwise, this is the child diff node
@@ -265,7 +262,7 @@ const diffNode = ({
265
262
  if (action === 'REMOVE') {
266
263
  removed.push(actual)
267
264
  }
268
- children.push(new Diff({ actual, ideal, filterSet, shrinkwrapInflated, omit, omitted }))
265
+ children.push(new Diff({ actual, ideal, filterSet, shrinkwrapInflated, omit }))
269
266
  } else {
270
267
  unchanged.push(ideal)
271
268
  // !*! Weird dirty hack warning !*!
@@ -306,7 +303,6 @@ const diffNode = ({
306
303
  filterSet,
307
304
  shrinkwrapInflated,
308
305
  omit,
309
- omitted,
310
306
  }))
311
307
  }
312
308
  }
@@ -20,7 +20,7 @@ const gatherDepSet = (set, edgeFilter) => {
20
20
  }
21
21
  }
22
22
 
23
- // now remove all nodes in the set that have a dependant outside the set
23
+ // now remove all nodes in the set that have a dependent outside the set
24
24
  // if any change is made, then re-check
25
25
  // continue until no changes made, or deps set evaporates fully.
26
26
  let changed = true
package/lib/node.js CHANGED
@@ -101,7 +101,7 @@ class Node {
101
101
  global = false,
102
102
  dummy = false,
103
103
  sourceReference = null,
104
- ideallyInert = false,
104
+ inert = false,
105
105
  } = options
106
106
  // this object gives querySelectorAll somewhere to stash context about a node
107
107
  // while processing a query
@@ -207,7 +207,7 @@ class Node {
207
207
  this.extraneous = false
208
208
  }
209
209
 
210
- this.ideallyInert = ideallyInert
210
+ this.inert = inert
211
211
 
212
212
  this.edgesIn = new Set()
213
213
  this.edgesOut = new CaseInsensitiveMap()
@@ -248,7 +248,7 @@ class Node {
248
248
  this.fsParent = fsParent || null
249
249
 
250
250
  // see parent/root setters below.
251
- // root is set to parent's root if we have a parent, otherwise if it's
251
+ // root is set to parent's root if we have a parent; otherwise, if it's
252
252
  // null, then it's set to the node itself.
253
253
  if (!parent && !fsParent) {
254
254
  this.root = root || null
@@ -832,7 +832,7 @@ class Node {
832
832
  edge.reload()
833
833
  }
834
834
  }
835
- // reload all edgesOut where root doens't match, or is missing, since
835
+ // reload all edgesOut where root doesn't match, or is missing, since
836
836
  // it might not be missing in the new tree
837
837
  for (const edge of this.edgesOut.values()) {
838
838
  if (!edge.to || edge.to.root !== root) {
@@ -1268,7 +1268,7 @@ class Node {
1268
1268
  // with another by the same name (eg, to update or dedupe).
1269
1269
  // This does a couple of walks out on the node_modules tree, recursing
1270
1270
  // into child nodes. However, as setting the parent is typically done
1271
- // with nodes that don't have have many children, and (deduped) package
1271
+ // with nodes that don't have many children, and (deduped) package
1272
1272
  // trees tend to be broad rather than deep, it's not that bad.
1273
1273
  // The only walk that starts from the parent rather than this node is
1274
1274
  // limited by edge name.
@@ -1412,7 +1412,7 @@ class Node {
1412
1412
  }
1413
1413
 
1414
1414
  recalculateOutEdgesOverrides () {
1415
- // For each edge out propogate the new overrides through.
1415
+ // For each edge out propagate the new overrides through.
1416
1416
  for (const edge of this.edgesOut.values()) {
1417
1417
  edge.reload(true)
1418
1418
  if (edge.to) {
@@ -29,10 +29,8 @@ const optionalSet = node => {
29
29
  }
30
30
 
31
31
  // now that we've hit the boundary, gather the rest of the nodes in
32
- // the optional section. that's the set of dependencies that are only
33
- // depended upon by other nodes within the set, or optional dependencies
34
- // from outside the set.
35
- return gatherDepSet(set, edge => !edge.optional)
32
+ // the optional section that don't have dependents outside the set.
33
+ return gatherDepSet(set, edge => !set.has(edge.to))
36
34
  }
37
35
 
38
36
  module.exports = optionalSet
@@ -30,7 +30,7 @@ class PackumentCache extends LRUCache {
30
30
  maxSize,
31
31
  maxEntrySize,
32
32
  sizeCalculation: (p) => {
33
- // Don't cache if we dont know the size
33
+ // Don't cache if we don't know the size
34
34
  // Some versions of pacote set this to `0`, newer versions set it to `null`
35
35
  if (!p[sizeKey]) {
36
36
  return maxEntrySize + 1
package/lib/place-dep.js CHANGED
@@ -203,7 +203,7 @@ class PlaceDep {
203
203
  this.warnPeerConflict()
204
204
  }
205
205
 
206
- // if we get a KEEP in a update scenario, then we MAY have something
206
+ // if we get a KEEP in an update scenario, then we MAY have something
207
207
  // already duplicating this unnecessarily! For example:
208
208
  // ```
209
209
  // root (dep: y@1)
@@ -317,7 +317,7 @@ class PlaceDep {
317
317
  force: this.force,
318
318
  installLinks: this.installLinks,
319
319
  installStrategy: this.installStrategy,
320
- legacyPeerDeps: this.legaycPeerDeps,
320
+ legacyPeerDeps: this.legacyPeerDeps,
321
321
  preferDedupe: this.preferDedupe,
322
322
  strictPeerDeps: this.strictPeerDeps,
323
323
  updateNames: this.updateName,
@@ -421,7 +421,7 @@ class PlaceDep {
421
421
  // prune all the nodes in a branch of the tree that can be safely removed
422
422
  // This is only the most basic duplication detection; it finds if there
423
423
  // is another satisfying node further up the tree, and if so, dedupes.
424
- // Even in installStategy is nested, we do this amount of deduplication.
424
+ // Even if installStrategy is nested, we do this amount of deduplication.
425
425
  pruneDedupable (node, descend = true) {
426
426
  if (node.canDedupe(this.preferDedupe, this.explicitRequest)) {
427
427
  // gather up all deps that have no valid edges in from outside
@@ -785,7 +785,7 @@ const hasParent = (node, compareNodes) => {
785
785
  compareNode = compareNode.target
786
786
  }
787
787
 
788
- // follows logical parent for link anscestors
788
+ // follows logical parent for link ancestors
789
789
  if (node.isTop && (node.resolveParent === compareNode)) {
790
790
  return true
791
791
  }
package/lib/shrinkwrap.js CHANGED
@@ -109,7 +109,6 @@ const nodeMetaKeys = [
109
109
  'inBundle',
110
110
  'hasShrinkwrap',
111
111
  'hasInstallScript',
112
- 'ideallyInert',
113
112
  ]
114
113
 
115
114
  const metaFieldFromPkg = (pkg, key) => {
@@ -136,10 +135,6 @@ const assertNoNewer = async (path, data, lockTime, dir, seen) => {
136
135
 
137
136
  const parent = isParent ? dir : resolve(dir, 'node_modules')
138
137
  const rel = relpath(path, dir)
139
- const inert = data.packages[rel]?.ideallyInert
140
- if (inert) {
141
- return
142
- }
143
138
  seen.add(rel)
144
139
  let entries
145
140
  if (dir === path) {
@@ -178,7 +173,7 @@ const assertNoNewer = async (path, data, lockTime, dir, seen) => {
178
173
 
179
174
  // assert that all the entries in the lockfile were seen
180
175
  for (const loc in data.packages) {
181
- if (!seen.has(loc) && !data.packages[loc].ideallyInert) {
176
+ if (!seen.has(loc)) {
182
177
  throw new Error(`missing from node_modules: ${loc}`)
183
178
  }
184
179
  }
@@ -436,7 +431,7 @@ class Shrinkwrap {
436
431
  const [sw, lock, yarn] = await this.loadFiles
437
432
  data = sw || lock || '{}'
438
433
 
439
- // use shrinkwrap only for deps, otherwise prefer package-lock
434
+ // use shrinkwrap only for deps; otherwise, prefer package-lock
440
435
  // and ignore npm-shrinkwrap if both are present.
441
436
  // TODO: emit a warning here or something if both are present.
442
437
  if (this.hiddenLockfile) {
@@ -788,10 +783,6 @@ class Shrinkwrap {
788
783
  // ok, I did my best! good luck!
789
784
  }
790
785
 
791
- if (lock.ideallyInert) {
792
- meta.ideallyInert = true
793
- }
794
-
795
786
  if (lock.bundled) {
796
787
  meta.inBundle = true
797
788
  }
@@ -962,12 +953,6 @@ class Shrinkwrap {
962
953
  this.#buildLegacyLockfile(this.tree, this.data)
963
954
  }
964
955
 
965
- if (!this.hiddenLockfile) {
966
- for (const node of Object.values(this.data.packages)) {
967
- delete node.ideallyInert
968
- }
969
- }
970
-
971
956
  // lf version 1 = dependencies only
972
957
  // lf version 2 = dependencies and packages
973
958
  // lf version 3 = packages only
@@ -993,7 +978,7 @@ class Shrinkwrap {
993
978
 
994
979
  // npm v6 and before tracked 'from', meaning "the request that led
995
980
  // to this package being installed". However, that's inherently
996
- // racey and non-deterministic in a world where deps are deduped
981
+ // racy and non-deterministic in a world where deps are deduped
997
982
  // ahead of fetch time. In order to maintain backwards compatibility
998
983
  // with v6 in the lockfile, we do this trick where we pick a valid
999
984
  // dep link out of the edgesIn set. Choose the edge with the fewest
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npmcli/arborist",
3
- "version": "9.1.5",
3
+ "version": "9.1.6",
4
4
  "description": "Manage node_modules trees",
5
5
  "dependencies": {
6
6
  "@isaacs/string-locale-compare": "^1.1.0",