@npmcli/arborist
Advanced tools
@@ -953,3 +953,3 @@ // mixin implementing the buildIdealTree method | ||
| visit: pd => { | ||
| const { placed, edge, canPlace: cpd } = pd | ||
| const { placed, edge, canPlace: cpd, parent } = pd | ||
| // if we didn't place anything, nothing to do here | ||
@@ -1015,4 +1015,3 @@ if (!placed) { | ||
| // lastly, also check for the missing deps of the node we placed, | ||
| // and any holes created by pruning out conflicted peer sets. | ||
| // lastly, also check for the missing deps of the node we placed, and any holes created by pruning out conflicted peer sets. | ||
| this.#depsQueue.push(placed) | ||
@@ -1025,12 +1024,10 @@ for (const dep of pd.needEvaluation) { | ||
| // pre-fetch any problem edges, since we'll need these soon | ||
| // if it fails at this point, though, don't worry because it | ||
| // may well be an optional dep that has gone missing. it'll | ||
| // fail later anyway. | ||
| // if it fails at this point, though, don't worry because it may well be an optional dep that has gone missing | ||
| // it'll fail later anyway | ||
| for (const e of this.#problemEdges(placed)) { | ||
| // XXX This is somehow load bearing. This makes tests that print | ||
| // the ideal tree of a tree with tarball dependencies fail. This | ||
| // can't be changed or removed till we figure out why | ||
| // XXX This is somehow load bearing. This makes tests that print the ideal tree of a tree with tarball dependencies fail | ||
| // This can't be changed or removed till we figure out why | ||
| // The test is named "tarball deps with transitive tarball deps" | ||
| promises.push(() => | ||
| this.#fetchManifest(npa.resolve(e.name, e.spec, fromPath(placed, e))) | ||
| this.#fetchManifest(npa.resolve(e.name, e.spec, fromPath(placed, e)), parent) | ||
| .catch(() => null) | ||
@@ -1053,10 +1050,6 @@ ) | ||
| // loads a node from an edge, and then loads its peer deps (and their | ||
| // peer deps, on down the line) into a virtual root parent. | ||
| // loads a node from an edge, and then loads its peer deps (and their peer deps, on down the line) into a virtual root parent. | ||
| async #nodeFromEdge (edge, parent_, secondEdge, required) { | ||
| // create a virtual root node with the same deps as the node that | ||
| // is requesting this one, so that we can get all the peer deps in | ||
| // a context where they're likely to be resolvable. | ||
| // Note that the virtual root will also have virtual copies of the | ||
| // targets of any child Links, so that they resolve appropriately. | ||
| // create a virtual root node with the same deps as the node that is requesting this one, so that we can get all the peer deps in a context where they're likely to be resolvable. | ||
| // Note that the virtual root will also have virtual copies of the targets of any child Links, so that they resolve appropriately. | ||
| const parent = parent_ || this.#virtualRoot(edge.from) | ||
@@ -1067,9 +1060,5 @@ | ||
| // we might have a case where the parent has a peer dependency on | ||
| // `foo@*` which resolves to v2, but another dep in the set has a | ||
| // peerDependency on `foo@1`. In that case, if we force it to be v2, | ||
| // we're unnecessarily triggering an ERESOLVE. | ||
| // If we have a second edge to worry about, and it's not satisfied | ||
| // by the first node, try a second and see if that satisfies the | ||
| // original edge here. | ||
| // we might have a case where the parent has a peer dependency on `foo@*` which resolves to v2, but another dep in the set has a peerDependency on `foo@1`. | ||
| // In that case, if we force it to be v2, we're unnecessarily triggering an ERESOLVE. | ||
| // If we have a second edge to worry about, and it's not satisfied by the first node, try a second and see if that satisfies the original edge here. | ||
| const spec2 = secondEdge && npa.resolve( | ||
@@ -1218,3 +1207,3 @@ edge.name, | ||
| async #fetchManifest (spec) { | ||
| async #fetchManifest (spec, parent) { | ||
| const options = { | ||
@@ -1224,2 +1213,3 @@ ...this.options, | ||
| fullMetadata: true, | ||
| _isRoot: parent?.isProjectRoot || parent?.isWorkspace, | ||
| } | ||
@@ -1241,6 +1231,4 @@ // get the intended spec and stored metadata from yarn.lock file, | ||
| async #nodeFromSpec (name, spec, parent, edge) { | ||
| // pacote will slap integrity on its options, so we have to clone | ||
| // the object so it doesn't get mutated. | ||
| // Don't bother to load the manifest for link deps, because the target | ||
| // might be within another package that doesn't exist yet. | ||
| // pacote will slap integrity on its options, so we have to clone the object so it doesn't get mutated. | ||
| // Don't bother to load the manifest for link deps, because the target might be within another package that doesn't exist yet. | ||
| const { installLinks, legacyPeerDeps } = this | ||
@@ -1298,3 +1286,3 @@ const isWorkspace = this.idealTree.workspaces && this.idealTree.workspaces.has(spec.name) | ||
| // doesn't satisfy the edge. try to fetch a manifest and build a node from that. | ||
| return this.#fetchManifest(spec) | ||
| return this.#fetchManifest(spec, parent) | ||
| .then(pkg => new Node({ name, pkg, parent, installLinks, legacyPeerDeps }), error => { | ||
@@ -1301,0 +1289,0 @@ error.requiredBy = edge.from.location || '.' |
@@ -116,3 +116,7 @@ const { mkdirSync } = require('node:fs') | ||
| // they are already handled as workspace-like proxies above and should not go through the external/store extraction path. | ||
| if (!next.isProjectRoot && !next.isWorkspace && !next.inert && !idealTree.fsChildren.has(next) && !idealTree.fsChildren.has(next.target)) { | ||
| // Links with file: resolved paths (from `npm link`) should also be treated as local dependencies and symlinked directly instead of being extracted into the store. | ||
| const isLocalFileDep = next.isLink && next.resolved?.startsWith('file:') | ||
| if (isLocalFileDep && !idealTree.fsChildren.has(next) && !idealTree.fsChildren.has(next.target)) { | ||
| this.idealGraph.workspaces.push(await this.#workspaceProxy(next.target)) | ||
| } else if (!next.isProjectRoot && !next.isWorkspace && !next.inert && !idealTree.fsChildren.has(next) && !idealTree.fsChildren.has(next.target)) { | ||
| this.idealGraph.external.push(await this.#externalProxy(next)) | ||
@@ -161,2 +165,3 @@ } | ||
| integrity: node.integrity, | ||
| // TODO _isRoot | ||
| }) | ||
@@ -163,0 +168,0 @@ const Arborist = this.constructor |
@@ -740,2 +740,3 @@ // mixin implementing the reify method | ||
| integrity: node.integrity, | ||
| _isRoot: node.parent?.isProjectRoot || node.parent?.isWorkspace, | ||
| }) | ||
@@ -742,0 +743,0 @@ // store nodes don't use Node class so node.package doesn't get updated |
@@ -29,5 +29,5 @@ // when an optional dep fails to install, we need to remove the branch of the | ||
| // the optional section that don't have dependents outside the set. | ||
| return gatherDepSet(set, edge => !set.has(edge.to)) | ||
| return gatherDepSet(set, edge => !set.has(edge.to) && !edge.from?.inert) | ||
| } | ||
| module.exports = optionalSet |
+1
-1
| { | ||
| "name": "@npmcli/arborist", | ||
| "version": "9.4.2", | ||
| "version": "9.4.3", | ||
| "description": "Manage node_modules trees", | ||
@@ -5,0 +5,0 @@ "dependencies": { |
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
487954
0.11%12833
-0.05%