Skip to content

Commit 7206fa9

Browse files
committed
Update npm overrides patch based on npm/cli#8089
1 parent e0c97e0 commit 7206fa9

6 files changed

Lines changed: 120 additions & 136 deletions

File tree

src/commands/optimize/apply-optimization.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export async function applyOptimization(
130130

131131
if (agent === NPM || pkgJsonChanged) {
132132
// Always update package-lock.json until the npm overrides PR lands:
133-
// https://github.com/npm/cli/pull/7025
133+
// https://github.com/npm/cli/pull/8089
134134
await updatePackageLockJson(lockName, agentExecPath, agent, spinner)
135135
}
136136
}

src/commands/optimize/update-package-lock-json.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import type { Agent } from '../../utils/package-manager-detector'
1010
const { NPM, SOCKET_CLI_SAFE_WRAPPER, abortSignal } = constants
1111

1212
const COMMAND_TITLE = 'Socket Optimize'
13-
const NPM_OVERRIDE_PR_URL = 'https://github.com/npm/cli/pull/7025'
13+
const NPM_OVERRIDE_PR_URL = 'https://github.com/npm/cli/pull/8089'
1414

1515
export async function updatePackageLockJson(
1616
lockName: string,

src/shadow/arborist/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111

1212
export function installSafeArborist() {
1313
// Override '@npmcli/arborist' module exports with patched variants based on
14-
// https://github.com/npm/cli/pull/7025.
14+
// https://github.com/npm/cli/pull/8089.
1515
const cache: { [key: string]: any } = require.cache
1616
cache[getArboristClassPath()] = { exports: SafeArborist }
1717
cache[getArboristEdgeClassPath()] = { exports: SafeEdge }

src/shadow/arborist/lib/edge.ts

Lines changed: 42 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export const Edge: EdgeClass = require(getArboristEdgeClassPath())
6161
// The Edge class makes heavy use of private properties which subclasses do NOT
6262
// have access to. So we have to recreate any functionality that relies on those
6363
// private properties and use our own "safe" prefixed non-conflicting private
64-
// properties. Implementation code not related to patch https://github.com/npm/cli/pull/7025
64+
// properties. Implementation code not related to patch https://github.com/npm/cli/pull/8089
6565
// is based on https://github.com/npm/cli/blob/v11.0.0/workspaces/arborist/lib/edge.js.
6666
//
6767
// The npm application
@@ -70,39 +70,26 @@ export const Edge: EdgeClass = require(getArboristEdgeClassPath())
7070
//
7171
// An edge in the dependency graph.
7272
// Represents a dependency relationship of some kind.
73-
const initializedSafeEdges = new WeakSet()
74-
7573
export class SafeEdge extends Edge {
76-
#safeAccept: string | undefined
7774
#safeError: ErrorStatus | null
7875
#safeExplanation: Explanation | undefined
7976
#safeFrom: SafeNode | null
80-
#safeName: string
8177
#safeTo: SafeNode | null
8278

8379
constructor(options: EdgeOptions) {
84-
const { accept, from, name } = options
80+
const { from } = options
8581
// Defer to supper to validate options and assign non-private values.
8682
super(options)
87-
if (accept !== undefined) {
88-
this.#safeAccept = accept || '*'
89-
}
9083
if (from.constructor !== SafeNode) {
9184
Reflect.setPrototypeOf(from, SafeNode.prototype)
9285
}
9386
this.#safeError = null
9487
this.#safeExplanation = null
9588
this.#safeFrom = from
96-
this.#safeName = name
9789
this.#safeTo = null
98-
initializedSafeEdges.add(this)
9990
this.reload(true)
10091
}
10192

102-
override get accept() {
103-
return this.#safeAccept
104-
}
105-
10693
override get bundled() {
10794
return !!this.#safeFrom?.package?.bundleDependencies?.includes(this.name)
10895
}
@@ -118,14 +105,16 @@ export class SafeEdge extends Edge {
118105
} else if (
119106
this.peer &&
120107
this.#safeFrom === this.#safeTo.parent &&
108+
// Patch adding "?." use based on
109+
// https://github.com/npm/cli/pull/8089.
121110
!this.#safeFrom?.isTop
122111
) {
123112
this.#safeError = 'PEER LOCAL'
124113
} else if (!this.satisfiedBy(this.#safeTo)) {
125114
this.#safeError = 'INVALID'
126115
}
127116
// Patch adding "else if" condition is based on
128-
// https://github.com/npm/cli/pull/7025.
117+
// https://github.com/npm/cli/pull/8089.
129118
else if (
130119
this.overrides &&
131120
this.#safeTo.edgesOut.size &&
@@ -162,21 +151,15 @@ export class SafeEdge extends Edge {
162151
this.overrides.value !== '*' &&
163152
this.overrides.name === this.name
164153
) {
165-
// Patch adding "if" condition is based on
166-
// https://github.com/npm/cli/pull/7025.
167-
//
168-
// If this edge has the same overrides field as the source, then we're not
169-
// applying an override for this edge.
170-
if (this.overrides === this.#safeFrom?.overrides) {
171-
// The Edge rawSpec getter will retrieve the private Edge #spec property.
172-
return this.rawSpec
173-
}
174154
if (this.overrides.value.startsWith('$')) {
175155
const ref = this.overrides.value.slice(1)
176156
// We may be a virtual root, if we are we want to resolve reference
177157
// overrides from the real root, not the virtual one.
158+
//
159+
// Patch adding "?." use based on
160+
// https://github.com/npm/cli/pull/8089.
178161
const pkg = this.#safeFrom?.sourceReference
179-
? this.#safeFrom.sourceReference.root.package
162+
? this.#safeFrom?.sourceReference.root.package
180163
: this.#safeFrom?.root?.package
181164
if (pkg?.devDependencies?.[ref]) {
182165
return <string>pkg.devDependencies[ref]
@@ -205,10 +188,11 @@ export class SafeEdge extends Edge {
205188
override detach() {
206189
this.#safeExplanation = null
207190
// Patch replacing
208-
// if (this.#safeTo) {
209-
// this.#safeTo.edgesIn.delete(this)
191+
// if (this.#to) {
192+
// this.#to.edgesIn.delete(this)
210193
// }
211-
// is based on https://github.com/npm/cli/pull/7025.
194+
// this.#from.edgesOut.delete(this.#name)
195+
// is based on https://github.com/npm/cli/pull/8089.
212196
this.#safeTo?.deleteEdgeIn(this)
213197
this.#safeFrom?.edgesOut.delete(this.name)
214198
this.#safeTo = null
@@ -249,38 +233,34 @@ export class SafeEdge extends Edge {
249233
}
250234

251235
override reload(hard = false) {
252-
if (!initializedSafeEdges.has(this)) {
253-
// Skip if called during super constructor.
254-
return
255-
}
256236
this.#safeExplanation = null
257-
// Patch adding newOverrideSet and oldOverrideSet is based on
258-
// https://github.com/npm/cli/pull/7025.
237+
// Patch replacing
238+
// if (this.#from.overrides) {
239+
// is based on https://github.com/npm/cli/pull/8089.
240+
let needToUpdateOverrideSet = false
259241
let newOverrideSet
260242
let oldOverrideSet
261243
if (this.#safeFrom?.overrides) {
262-
// Patch replacing
263-
// this.overrides = this.#safeFrom.overrides.getEdgeRule(this)
264-
// is based on https://github.com/npm/cli/pull/7025.
265-
const newOverrideSet = this.#safeFrom.overrides.getEdgeRule(this)
244+
newOverrideSet = this.#safeFrom.overrides.getEdgeRule(this)
266245
if (newOverrideSet && !newOverrideSet.isEqual(this.overrides)) {
267246
// If there's a new different override set we need to propagate it to
268247
// the nodes. If we're deleting the override set then there's no point
269248
// propagating it right now since it will be filled with another value
270249
// later.
250+
needToUpdateOverrideSet = true
271251
oldOverrideSet = this.overrides
272252
this.overrides = newOverrideSet
273253
}
274254
} else {
275255
this.overrides = undefined
276256
}
257+
// Patch adding "?." use based on
258+
// https://github.com/npm/cli/pull/8089.
277259
const newTo = this.#safeFrom?.resolve(this.name)
278260
if (newTo !== this.#safeTo) {
279261
// Patch replacing
280-
// if (this.#safeTo) {
281-
// this.#safeTo.edgesIn.delete(this)
282-
// }
283-
// is based on https://github.com/npm/cli/pull/7025.
262+
// this.#to.edgesIn.delete(this)
263+
// is based on https://github.com/npm/cli/pull/8089.
284264
this.#safeTo?.deleteEdgeIn(this)
285265
this.#safeTo = <SafeNode>newTo ?? null
286266
this.#safeError = null
@@ -289,10 +269,10 @@ export class SafeEdge extends Edge {
289269
this.#safeError = null
290270
}
291271
// Patch adding "else if" condition based on
292-
// https://github.com/npm/cli/pull/7025.
293-
else if (oldOverrideSet) {
272+
// https://github.com/npm/cli/pull/8089.
273+
else if (needToUpdateOverrideSet && this.#safeTo) {
294274
// Propagate the new override set to the target node.
295-
this.#safeTo.updateOverridesEdgeInRemoved(oldOverrideSet)
275+
this.#safeTo.updateOverridesEdgeInRemoved(oldOverrideSet!)
296276
this.#safeTo.updateOverridesEdgeInAdded(newOverrideSet)
297277
}
298278
}
@@ -302,46 +282,42 @@ export class SafeEdge extends Edge {
302282
// if (node.name !== this.#name) {
303283
// return false
304284
// }
305-
// is based on https://github.com/npm/cli/pull/7025.
306-
if (node.name !== this.#safeName || !this.#safeFrom) {
285+
// is based on https://github.com/npm/cli/pull/8089.
286+
if (node.name !== this.name || !this.#safeFrom) {
307287
return false
308288
}
309289
// NOTE: this condition means we explicitly do not support overriding
310290
// bundled or shrinkwrapped dependencies
311291
if (node.hasShrinkwrap || node.inShrinkwrap || node.inBundle) {
312-
return depValid(node, this.rawSpec, this.#safeAccept, this.#safeFrom)
292+
return depValid(node, this.rawSpec, this.accept, this.#safeFrom)
313293
}
314294
// Patch replacing
315295
// return depValid(node, this.spec, this.#accept, this.#from)
316-
// is based on https://github.com/npm/cli/pull/7025.
296+
// is based on https://github.com/npm/cli/pull/8089.
317297
//
318298
// If there's no override we just use the spec.
319299
if (!this.overrides?.keySpec) {
320-
return depValid(node, this.spec, this.#safeAccept, this.#safeFrom)
300+
return depValid(node, this.spec, this.accept, this.#safeFrom)
321301
}
322302
// There's some override. If the target node satisfies the overriding spec
323303
// then it's okay.
324-
if (depValid(node, this.spec, this.#safeAccept, this.#safeFrom)) {
304+
if (depValid(node, this.spec, this.accept, this.#safeFrom)) {
325305
return true
326306
}
327307
// If it doesn't, then it should at least satisfy the original spec.
328-
if (!depValid(node, this.rawSpec, this.#safeAccept, this.#safeFrom)) {
308+
if (!depValid(node, this.rawSpec, this.accept, this.#safeFrom)) {
329309
return false
330310
}
331311
// It satisfies the original spec, not the overriding spec. We need to make
332312
// sure it doesn't use the overridden spec.
333-
// For example, we might have an ^8.0.0 rawSpec, and an override that makes
334-
// keySpec=8.23.0 and the override value spec=9.0.0.
335-
// If the node is 9.0.0, then it's okay because it's consistent with spec.
336-
// If the node is 8.24.0, then it's okay because it's consistent with the rawSpec.
337-
// If the node is 8.23.0, then it's not okay because even though it's consistent
338-
// with the rawSpec, it's also consistent with the keySpec.
339-
// So we're looking for ^8.0.0 or 9.0.0 and not 8.23.0.
340-
return !depValid(
341-
node,
342-
this.overrides.keySpec,
343-
this.#safeAccept,
344-
this.#safeFrom
345-
)
313+
// For example:
314+
// we might have an ^8.0.0 rawSpec, and an override that makes
315+
// keySpec=8.23.0 and the override value spec=9.0.0.
316+
// If the node is 9.0.0, then it's okay because it's consistent with spec.
317+
// If the node is 8.24.0, then it's okay because it's consistent with the rawSpec.
318+
// If the node is 8.23.0, then it's not okay because even though it's consistent
319+
// with the rawSpec, it's also consistent with the keySpec.
320+
// So we're looking for ^8.0.0 or 9.0.0 and not 8.23.0.
321+
return !depValid(node, this.overrides.keySpec, this.accept, this.#safeFrom)
346322
}
347323
}

0 commit comments

Comments
 (0)