Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@npmcli/arborist

Package Overview
Dependencies
Maintainers
5
Versions
193
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@npmcli/arborist - npm Package Compare versions

Comparing version 1.0.1 to 1.0.2

140

lib/arborist/build-ideal-tree.js

@@ -1026,2 +1026,3 @@ // mixin implementing the buildIdealTree method

strictPeerDeps: this[_strictPeerDeps],
force: this[_force],
}

@@ -1044,3 +1045,3 @@ }

// of functionality that ought to have its own unit tests more conveniently.
[_placeDep] (dep, node, edge, peerEntryEdge = null) {
[_placeDep] (dep, node, edge, peerEntryEdge = null, peerPath = []) {
if (edge.to &&

@@ -1062,3 +1063,3 @@ !edge.error &&

for (let check = start; check; check = check.resolveParent) {
const cp = this[_canPlaceDep](dep, check, edge, peerEntryEdge)
const cp = this[_canPlaceDep](dep, check, edge, peerEntryEdge, peerPath)

@@ -1101,3 +1102,6 @@ // anything other than a conflict is fine to proceed with

if (canPlace === KEEP) {
dep.parent = null
if (edge.peer && !target.children.get(edge.name).satisfies(edge)) {
// this is an overridden peer dep
this[_warnPeerConflict](edge)
}
return []

@@ -1109,3 +1113,15 @@ }

const placed = [dep]
const newDep = new dep.constructor({
name: dep.name,
pkg: dep.package,
resolved: dep.resolved,
integrity: dep.integrity,
legacyPeerDeps: this.legacyPeerDeps,
error: dep.errors[0],
...(dep.target ? { target: dep.target } : {}),
})
if (this[_loadFailures].has(dep))
this[_loadFailures].add(newDep)
const placed = [newDep]
const oldChild = target.children.get(edge.name)

@@ -1121,19 +1137,24 @@ if (oldChild) {

for (const [name, edge] of oldChild.edgesOut.entries()) {
if (!dep.edgesOut.has(name) && edge.to)
if (!newDep.edgesOut.has(name) && edge.to)
oldDeps.push(edge.to)
}
dep.replace(oldChild)
this[_pruneForReplacement](dep, oldDeps)
newDep.replace(oldChild)
this[_pruneForReplacement](newDep, oldDeps)
// this may also create some invalid edges, for example if we're
// intentionally causing something to get nested which was previously
// placed in this location.
for (const edge of dep.edgesIn) {
if (edge.invalid) {
this[_depsQueue].push(edge.from)
this[_depsSeen].delete(edge.from)
for (const edgeIn of newDep.edgesIn) {
if (edgeIn.invalid && edgeIn !== edge) {
this[_depsQueue].push(edgeIn.from)
this[_depsSeen].delete(edgeIn.from)
}
}
} else
dep.parent = target
newDep.parent = target
if (edge.peer && !newDep.satisfies(edge)) {
// this is an overridden peer dep
this[_warnPeerConflict](edge)
}
// If the edge is not an error, then we're updating something, and

@@ -1143,3 +1164,3 @@ // MAY end up putting a better/identical node further up the tree in

// now-unnecessary node.
if (edge.valid && edge.to.parent !== target && dep.canReplace(edge.to))
if (edge.valid && edge.to.parent !== target && newDep.canReplace(edge.to))
edge.to.parent = null

@@ -1150,3 +1171,3 @@

// skip over it!
for (const edgeIn of dep.edgesIn) {
for (const edgeIn of newDep.edgesIn) {
if (edgeIn !== edge && !edgeIn.valid && !this[_depsSeen].has(edge.from)) {

@@ -1161,8 +1182,8 @@ this.addTracker('idealTree', edgeIn.from.name, edgeIn.from.location)

if (this.idealTree) {
for (const node of this.idealTree.inventory.query('name', dep.name)) {
if (node !== dep &&
for (const node of this.idealTree.inventory.query('name', newDep.name)) {
if (node !== newDep &&
node.isDescendantOf(target) &&
!node.inShrinkwrap &&
!node.inBundle &&
node.canReplaceWith(dep)) {
node.canReplaceWith(newDep)) {
// don't prune if the dupe is necessary!

@@ -1180,5 +1201,5 @@ // root (a, d)

node.parent.parent !== target &&
node.parent.parent.resolve(dep.name)
node.parent.parent.resolve(newDep.name)
if (!mask || mask === dep || node.canReplaceWith(mask))
if (!mask || mask === newDep || node.canReplaceWith(mask))
node.parent = null

@@ -1190,22 +1211,15 @@ }

// also place its unmet or invalid peer deps at this location
// note that dep has now been removed from the virtualRoot set
// note that newDep has now been removed from the virtualRoot set
// by virtue of being placed in the target's node_modules.
const peers = []
// double loop so that we don't yank things out and then fail to find
// them in the virtualRoot's children.
for (const peerEdge of dep.edgesOut.values()) {
// loop through any peer deps from the thing we just placed, and place
// those ones as well. it's safe to do this with the virtual nodes,
// because we're copying rather than moving them out of the virtual root,
// otherwise they'd be gone and the peer set would change throughout
// this loop.
for (const peerEdge of newDep.edgesOut.values()) {
if (!peerEdge.peer || peerEdge.valid)
continue
const peer = virtualRoot.children.get(peerEdge.name)
// since we re-use virtualRoots, it's possible that the node was
// already placed somewhere in the tree, and thus plucked off the
// virtual root. however, in that case, it should have been no
// longer a missing/invalid peer dep, so something is messed up.
if (peer)
peers.push([peer, peerEdge])
}
for (const [peer, peerEdge] of peers) {
const peerPlaced = this[_placeDep](
peer, dep, peerEdge, peerEntryEdge || edge)
peer, newDep, peerEdge, peerEntryEdge || edge)
placed.push(...peerPlaced)

@@ -1259,7 +1273,5 @@ }

// original edge that caused us to load the family of peer dependencies.
[_canPlaceDep] (dep, target, edge, peerEntryEdge = null) {
[_canPlaceDep] (dep, target, edge, peerEntryEdge = null, peerPath = []) {
const entryEdge = peerEntryEdge || edge
const source = this[_peerSetSource].get(dep)
const virtualRoot = dep.parent
const vrEdge = virtualRoot.edgesOut.get(edge.name)

@@ -1281,3 +1293,3 @@ const isSource = target === source

if (tryReplace && dep.canReplace(current)) {
const res = this[_canPlacePeers](dep, target, edge, REPLACE, peerEntryEdge)
const res = this[_canPlacePeers](dep, target, edge, REPLACE, peerEntryEdge, peerPath)
/* istanbul ignore else - It's extremely rare that a replaceable

@@ -1292,2 +1304,4 @@ * node would be a conflict, if the current one wasn't a conflict,

// ok, can't replace the current with new one, but maybe current is ok?
// no need to check if it's a peer that's valid to be here, because
// peers are always placed along with their entry source
if (edge.satisfiedBy(current))

@@ -1298,3 +1312,3 @@ return KEEP

if (this[_preferDedupe] && !tryReplace && dep.canReplace(current)) {
const res = this[_canPlacePeers](dep, target, edge, REPLACE, peerEntryEdge)
const res = this[_canPlacePeers](dep, target, edge, REPLACE, peerEntryEdge, peerPath)
/* istanbul ignore else - It's extremely rare that a replaceable

@@ -1351,3 +1365,3 @@ * node would be a conflict, if the current one wasn't a conflict,

if (canReplace) {
const ret = this[_canPlacePeers](dep, target, edge, REPLACE, peerEntryEdge)
const ret = this[_canPlacePeers](dep, target, edge, REPLACE, peerEntryEdge, peerPath)
/* istanbul ignore else - extremely rare that the peer set would

@@ -1371,14 +1385,2 @@ * conflict if we can replace the node in question, but theoretically

if (vrEdge && vrEdge.satisfiedBy(current)) {
/* istanbul ignore else - If the virtual root was satisfied, in
* such a way that it was an override, and it's NOT forced, and is
* ours, or is in strict mode, then it would have crashed during
* the creation of the peerSet. Nevertheless, this is a good check
* to ensure we're not warning when we should be conflicting. */
if (this[_force] || !isMine && !this[_strictPeerDeps]) {
this[_warnPeerConflict](edge)
return KEEP
}
}
// no justification for overriding, and no agreement possible.

@@ -1406,17 +1408,4 @@ return CONFLICT

// is unbounded in its dependency list.
if (!targetEdge.satisfiedBy(dep)) {
if (isSource) {
// conflicted peer dep. accept what's there, if overriding
/* istanbul ignore else - If it's the source, and the source's edge
* is not valid, then either we crashed when creating the peer set,
* or it's forced, or it's not ours and not strict. Keep this check
* to avoid relying on action at a distance, however. */
if (this[_force] || !isMine && !this[_strictPeerDeps]) {
this[_warnPeerConflict](edge)
return KEEP
}
}
if (!targetEdge.satisfiedBy(dep))
return CONFLICT
}
}

@@ -1440,3 +1429,3 @@

// no objections! ok to place here
return this[_canPlacePeers](dep, target, edge, OK, peerEntryEdge)
return this[_canPlacePeers](dep, target, edge, OK, peerEntryEdge, peerPath)
}

@@ -1448,6 +1437,8 @@

// the tree.
[_canPlacePeers] (dep, target, edge, ret, peerEntryEdge) {
if (!dep.parent || peerEntryEdge)
[_canPlacePeers] (dep, target, edge, ret, peerEntryEdge, peerPath) {
// do not go in cycles when we're resolving a peer group
if (!dep.parent || peerEntryEdge && peerPath.includes(dep))
return ret
peerPath = [...peerPath, dep]
for (const peer of dep.parent.children.values()) {

@@ -1457,11 +1448,9 @@ if (peer === dep)

const peerEdge = dep.edgesOut.get(peer.name) ||
[...peer.edgesIn].find(e => e.peer)
/* istanbul ignore if - pretty sure this is impossible, but just
being cautious */
// we only have to pick the first one, because ALL peer edgesIn will
// be checked before we decide to accept an existing dep in the tree
const peerEdge = [...peer.edgesIn].find(e => e.peer && e !== edge)
if (!peerEdge)
continue
const canPlacePeer = this[_canPlaceDep](peer, target, peerEdge, edge)
const canPlacePeer = this[_canPlaceDep](peer, target, peerEdge, edge, peerPath)
if (canPlacePeer !== CONFLICT)

@@ -1588,2 +1577,3 @@ continue

throw node.errors[0]
const set = optionalSet(node)

@@ -1590,0 +1580,0 @@ for (const node of set)

@@ -403,3 +403,3 @@ // mixin implementing the reify method

// entirely, since we can't possibly reify it.
const res = node.resolved ? this[_registryResolved](node.resolved)
const res = node.resolved ? `${node.name}@${this[_registryResolved](node.resolved)}`
: node.package.name && node.version

@@ -406,0 +406,0 @@ ? `${node.package.name}@${node.version}`

{
"name": "@npmcli/arborist",
"version": "1.0.1",
"version": "1.0.2",
"description": "Manage node_modules trees",

@@ -5,0 +5,0 @@ "dependencies": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc