@@ -5,7 +5,7 @@ import spawn from '@npmcli/promise-spawn'
55import EditablePackageJson from '@npmcli/package-json'
66import { getManifestData } from '@socketsecurity/registry'
77import meow from 'meow'
8- import npmPackageArg from 'npm-package-arg'
8+ import npa from 'npm-package-arg'
99import ora from 'ora'
1010import pacote from 'pacote'
1111import semver from 'semver'
@@ -261,6 +261,7 @@ async function addOverrides(
261261 // Chunk package names to process them in parallel 3 at a time.
262262 await pEach ( manifestEntries , 3 , async ( { 1 : data } ) => {
263263 const { name : regPkgName , package : origPkgName , version } = data
264+ const major = semver . major ( version )
264265 for ( const { 1 : depObj } of depEntries ) {
265266 let pkgSpec = depObj [ origPkgName ]
266267 if ( pkgSpec ) {
@@ -269,7 +270,7 @@ async function addOverrides(
269270 // https://docs.npmjs.com/cli/v8/using-npm/package-spec#aliases
270271 const specStartsWith = `npm:${ regPkgName } @`
271272 const existingVersion = pkgSpec . startsWith ( specStartsWith )
272- ? ( semver . coerce ( npmPackageArg ( pkgSpec ) . rawSpec ) ?. version ?? '' )
273+ ? ( semver . coerce ( npa ( pkgSpec ) . rawSpec ) ?. version ?? '' )
273274 : ''
274275 if ( existingVersion ) {
275276 thisVersion = existingVersion
@@ -291,27 +292,30 @@ async function addOverrides(
291292 await pEach ( overridesDataObjects , 3 , async ( { overrides, type } ) => {
292293 const overrideExists = hasOwn ( overrides , origPkgName )
293294 if ( overrideExists || lockIncludes ( lockSrc , origPkgName ) ) {
294- // With npm one may not set an override for a package that one directly
295- // depends on unless both the dependency and the override itself share
296- // the exact same spec. To make this limitation easier to deal with,
297- // overrides may also be defined as a reference to a spec for a direct
298- // dependency by prefixing the name of the package to match the version
299- // of with a $.
300- // https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides
301- const oldSpec = overrides [ origPkgName ]
295+ const oldSpec = overrideExists ? overrides [ origPkgName ] : undefined
302296 const depAlias = depAliasMap . get ( origPkgName )
303- const thisVersion =
304- overrideExists && isNonEmptyString ( oldSpec )
305- ? ( (
306- await fetchPackageManifest (
307- oldSpec . startsWith ( '$' ) ? ( depAlias ?. id ?? oldSpec ) : oldSpec
308- )
309- ) ?. version ?? version )
310- : version
311- const newSpec =
312- depAlias && type === 'npm'
313- ? `$${ origPkgName } `
314- : `npm:${ regPkgName } @^${ pin ? thisVersion : semver . major ( thisVersion ) } `
297+ let newSpec = `npm:${ regPkgName } @^${ pin ? version : major } `
298+ let thisVersion = version
299+ if ( depAlias && type === 'npm' ) {
300+ // With npm one may not set an override for a package that one directly
301+ // depends on unless both the dependency and the override itself share
302+ // the exact same spec. To make this limitation easier to deal with,
303+ // overrides may also be defined as a reference to a spec for a direct
304+ // dependency by prefixing the name of the package to match the version
305+ // of with a $.
306+ // https://docs.npmjs.com/cli/v8/configuring-npm/package-json#overrides
307+ newSpec = `$${ origPkgName } `
308+ } else if ( overrideExists && pin ) {
309+ const thisSpec = oldSpec . startsWith ( '$' )
310+ ? ( depAlias ?. id ?? newSpec )
311+ : ( oldSpec ?? newSpec )
312+ thisVersion = semver . coerce ( npa ( thisSpec ) . rawSpec ) ?. version ?? version
313+ if ( semver . major ( thisVersion ) !== major ) {
314+ thisVersion =
315+ ( await fetchPackageManifest ( thisSpec ) ) ?. version ?? version
316+ }
317+ newSpec = `npm:${ regPkgName } @^${ pin ? thisVersion : semver . major ( thisVersion ) } `
318+ }
315319 if ( newSpec !== oldSpec ) {
316320 if ( overrideExists ) {
317321 state . updated . add ( regPkgName )
0 commit comments