@npmcli/arborist 9.2.0 → 9.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.
@@ -339,7 +339,8 @@ module.exports = cls => class IdealTreeBuilder extends cls {
339
339
  filter: node => node,
340
340
  visit: node => {
341
341
  for (const edge of node.edgesOut.values()) {
342
- if ((!edge.to && edge.type !== 'peerOptional') || !edge.valid) {
342
+ const skipPeerOptional = edge.type === 'peerOptional' && this.options.save === false
343
+ if (!skipPeerOptional && (!edge.to || !edge.valid)) {
343
344
  this.#depsQueue.push(node)
344
345
  break // no need to continue the loop after the first hit
345
346
  }
@@ -966,9 +967,17 @@ This is a one-time fix-up, please be patient...
966
967
  continue
967
968
  }
968
969
  const { from, valid, peerConflicted } = edgeIn
969
- if (!peerConflicted && !valid && !this.#depsSeen.has(from)) {
970
- this.addTracker('idealTree', from.name, from.location)
971
- this.#depsQueue.push(edgeIn.from)
970
+ if (!peerConflicted && !valid) {
971
+ if (this.#depsSeen.has(from) && this.options.save) {
972
+ // Re-queue already-processed nodes when a newly placed dep creates an invalid edge during npm install (save=true).
973
+ // This handles the case where a peerOptional dep was valid (missing) when the node was first processed, but becomes invalid when the dep is later placed by another path with a version that doesn't satisfy the peer spec.
974
+ // See npm/cli#8726.
975
+ this.#depsSeen.delete(from)
976
+ this.#depsQueue.push(from)
977
+ } else if (!this.#depsSeen.has(from)) {
978
+ this.addTracker('idealTree', from.name, from.location)
979
+ this.#depsQueue.push(from)
980
+ }
972
981
  }
973
982
  }
974
983
  } else {
@@ -1165,9 +1174,13 @@ This is a one-time fix-up, please be patient...
1165
1174
  continue
1166
1175
  }
1167
1176
 
1168
- // If the edge has an error, there's a problem.
1177
+ // If the edge has an error, there's a problem, unless it's peerOptional and we're not saving (e.g. npm ci), in which case we trust the lockfile and skip re-resolution.
1178
+ // When saving (npm install), peerOptional invalid edges ARE treated as problems so the lockfile gets fixed.
1179
+ // See npm/cli#8726.
1169
1180
  if (!edge.valid) {
1170
- problems.push(edge)
1181
+ if (edge.type !== 'peerOptional' || this.options.save !== false) {
1182
+ problems.push(edge)
1183
+ }
1171
1184
  continue
1172
1185
  }
1173
1186
 
package/lib/dep-valid.js CHANGED
@@ -82,7 +82,7 @@ const depValid = (child, requested, requestor) => {
82
82
  const resRepo = npa(child.resolved || '')
83
83
  const resHost = resRepo.hosted
84
84
  const reqHost = requested.hosted
85
- const reqCommit = /^[a-fA-F0-9]{40}$/.test(requested.gitCommittish || '')
85
+ const reqCommit = /^[a-fA-F0-9]{40,64}$/.test(requested.gitCommittish || '')
86
86
  const nc = { noCommittish: !reqCommit }
87
87
  if (!resHost) {
88
88
  if (resRepo.fetchSpec !== requested.fetchSpec) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npmcli/arborist",
3
- "version": "9.2.0",
3
+ "version": "9.3.1",
4
4
  "description": "Manage node_modules trees",
5
5
  "dependencies": {
6
6
  "@isaacs/string-locale-compare": "^1.1.0",
@@ -40,7 +40,7 @@
40
40
  "devDependencies": {
41
41
  "@npmcli/eslint-config": "^5.0.1",
42
42
  "@npmcli/mock-registry": "^1.0.0",
43
- "@npmcli/template-oss": "4.25.1",
43
+ "@npmcli/template-oss": "4.29.0",
44
44
  "benchmark": "^2.1.4",
45
45
  "minify-registry-metadata": "^4.0.0",
46
46
  "nock": "^13.3.3",
@@ -92,7 +92,7 @@
92
92
  },
93
93
  "templateOSS": {
94
94
  "//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
95
- "version": "4.25.1",
95
+ "version": "4.29.0",
96
96
  "content": "../../scripts/template-oss/index.js"
97
97
  }
98
98
  }