@@ -189,25 +189,42 @@ async function addOverrides(
189
189
if ( overridesData ) {
190
190
overridesDataObjects . push ( overridesData )
191
191
}
192
+ const aliasMap = new Map < string , string > ( )
192
193
for ( const { 1 : data } of availableOverrides ) {
193
194
const { name : regPkgName , package : origPkgName , version } = data
194
195
for ( const { 1 : depObj } of depEntries ) {
195
- const pkgSpec = depObj [ origPkgName ]
196
+ let pkgSpec = depObj [ origPkgName ]
196
197
if ( pkgSpec ) {
197
- if ( ! pkgSpec . startsWith ( `npm:${ regPkgName } @` ) ) {
198
+ // Add package aliases for direct dependencies to avoid npm EOVERRIDE errors.
199
+ // https://docs.npmjs.com/cli/v8/using-npm/package-spec#aliases
200
+ const overrideSpecPrefix = `npm:${ regPkgName } @`
201
+ if ( ! pkgSpec . startsWith ( overrideSpecPrefix ) ) {
202
+ aliasMap . set ( regPkgName , pkgSpec )
203
+ } else {
198
204
packageNames . add ( regPkgName )
199
- depObj [ origPkgName ] = `npm:${ regPkgName } @^${ version } `
205
+ pkgSpec = `${ overrideSpecPrefix } ^${ version } `
206
+ depObj [ origPkgName ] = pkgSpec
200
207
}
208
+ aliasMap . set ( origPkgName , pkgSpec )
201
209
}
202
210
}
203
- for ( const { overrides } of overridesDataObjects ) {
211
+ for ( const { type , overrides } of overridesDataObjects ) {
204
212
if (
205
213
overrides &&
206
214
! hasOwn ( overrides , origPkgName ) &&
207
215
lockIncludes ( lockSrc , origPkgName )
208
216
) {
209
217
packageNames . add ( regPkgName )
210
- overrides [ origPkgName ] = `npm:${ regPkgName } @^${ semver . major ( version ) } `
218
+ overrides [ origPkgName ] =
219
+ // With npm you may not set an override for a package that you directly
220
+ // depend on unless both the dependency and the override itself share
221
+ // the exact same spec. To make this limitation easier to deal with,
222
+ // overrides may also be defined as a reference to a spec for a direct
223
+ // dependency by prefixing the name of the package you wish the version
224
+ // to match with a $.
225
+ // https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides
226
+ ( type === 'npm' && aliasMap . has ( origPkgName ) && `$${ origPkgName } ` ) ||
227
+ `npm:${ regPkgName } @^${ semver . major ( version ) } `
211
228
}
212
229
}
213
230
}
@@ -252,7 +269,9 @@ export const optimize: CliSubcommand = {
252
269
}
253
270
} )
254
271
if ( ! supported ) {
255
- console . log ( `✘ ${ COMMAND_TITLE } : Package engines.node range is not supported` )
272
+ console . log (
273
+ `✘ ${ COMMAND_TITLE } : Package engines.node range is not supported`
274
+ )
256
275
return
257
276
}
258
277
const lockName = lockPath ? path . basename ( lockPath ) : 'lock file'
@@ -265,7 +284,9 @@ export const optimize: CliSubcommand = {
265
284
return
266
285
}
267
286
if ( lockPath && path . relative ( cwd , lockPath ) . startsWith ( '.' ) ) {
268
- console . log ( `⚠️ ${ COMMAND_TITLE } : Package ${ lockName } found at ${ lockPath } ` )
287
+ console . log (
288
+ `⚠️ ${ COMMAND_TITLE } : Package ${ lockName } found at ${ lockPath } `
289
+ )
269
290
}
270
291
271
292
const aoState : AddOverridesState = {
@@ -326,7 +347,9 @@ export const optimize: CliSubcommand = {
326
347
}
327
348
} catch {
328
349
spinner . stop ( )
329
- console . log ( `✘ ${ COMMAND_TITLE } : ${ agent } install failed to update ${ lockName } ` )
350
+ console . log (
351
+ `✘ ${ COMMAND_TITLE } : ${ agent } install failed to update ${ lockName } `
352
+ )
330
353
}
331
354
}
332
355
}
0 commit comments