@@ -189,25 +189,42 @@ async function addOverrides(
189189 if ( overridesData ) {
190190 overridesDataObjects . push ( overridesData )
191191 }
192+ const aliasMap = new Map < string , string > ( )
192193 for ( const { 1 : data } of availableOverrides ) {
193194 const { name : regPkgName , package : origPkgName , version } = data
194195 for ( const { 1 : depObj } of depEntries ) {
195- const pkgSpec = depObj [ origPkgName ]
196+ let pkgSpec = depObj [ origPkgName ]
196197 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 {
198204 packageNames . add ( regPkgName )
199- depObj [ origPkgName ] = `npm:${ regPkgName } @^${ version } `
205+ pkgSpec = `${ overrideSpecPrefix } ^${ version } `
206+ depObj [ origPkgName ] = pkgSpec
200207 }
208+ aliasMap . set ( origPkgName , pkgSpec )
201209 }
202210 }
203- for ( const { overrides } of overridesDataObjects ) {
211+ for ( const { type , overrides } of overridesDataObjects ) {
204212 if (
205213 overrides &&
206214 ! hasOwn ( overrides , origPkgName ) &&
207215 lockIncludes ( lockSrc , origPkgName )
208216 ) {
209217 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 ) } `
211228 }
212229 }
213230 }
@@ -252,7 +269,9 @@ export const optimize: CliSubcommand = {
252269 }
253270 } )
254271 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+ )
256275 return
257276 }
258277 const lockName = lockPath ? path . basename ( lockPath ) : 'lock file'
@@ -265,7 +284,9 @@ export const optimize: CliSubcommand = {
265284 return
266285 }
267286 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+ )
269290 }
270291
271292 const aoState : AddOverridesState = {
@@ -326,7 +347,9 @@ export const optimize: CliSubcommand = {
326347 }
327348 } catch {
328349 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+ )
330353 }
331354 }
332355 }
0 commit comments