@@ -886,6 +886,62 @@ function isStablePatchDrift(generatedVersion, currentVersion) {
886886 ) ;
887887}
888888
889+ function compareStableVersions ( leftVersion , rightVersion ) {
890+ const left = stableVersionParts ( leftVersion ) ;
891+ const right = stableVersionParts ( rightVersion ) ;
892+ if ( ! left || ! right ) {
893+ return null ;
894+ }
895+ return left . major - right . major || left . minor - right . minor || left . patch - right . patch ;
896+ }
897+
898+ function versionSatisfiesSimpleSpec ( version , spec ) {
899+ const normalized = typeof spec === "string" ? spec . trim ( ) : "" ;
900+ if ( normalized === "" || normalized === "*" ) {
901+ return true ;
902+ }
903+ const match = normalized . match ( / ^ (?< operator > \^ | ~ | > = ) ? (?< version > \d + \. \d + \. \d + ) $ / u) ;
904+ if ( ! match ?. groups ) {
905+ return normalized === version ;
906+ }
907+ const minimumVersion = match . groups . version ;
908+ const comparison = compareStableVersions ( version , minimumVersion ) ;
909+ if ( comparison === null || comparison < 0 ) {
910+ return false ;
911+ }
912+ const candidate = stableVersionParts ( version ) ;
913+ const minimum = stableVersionParts ( minimumVersion ) ;
914+ if ( ! candidate || ! minimum ) {
915+ return false ;
916+ }
917+ switch ( match . groups . operator ) {
918+ case "^" :
919+ return minimum . major > 0
920+ ? candidate . major === minimum . major
921+ : minimum . minor > 0
922+ ? candidate . major === 0 && candidate . minor === minimum . minor
923+ : candidate . major === 0 && candidate . minor === 0 && candidate . patch === minimum . patch ;
924+ case "~" :
925+ return candidate . major === minimum . major && candidate . minor === minimum . minor ;
926+ case ">=" :
927+ return true ;
928+ default :
929+ return comparison === 0 ;
930+ }
931+ }
932+
933+ function dependencySpecForLockPath ( packages , lockPath , dependencyName ) {
934+ const packagePath = parseLockPackagePath ( lockPath ) ;
935+ const parentPath = packagePath . at ( - 2 ) ?. path ?? "" ;
936+ const parent = packages [ parentPath ] ;
937+ return (
938+ parent ?. dependencies ?. [ dependencyName ] ??
939+ parent ?. optionalDependencies ?. [ dependencyName ] ??
940+ parent ?. peerDependencies ?. [ dependencyName ] ??
941+ null
942+ ) ;
943+ }
944+
889945function restoreCurrentPnpmLockedPackages (
890946 generated ,
891947 current ,
@@ -922,6 +978,10 @@ function restoreCurrentPnpmLockedPackages(
922978 ! currentMetadata . version ||
923979 currentPackageName !== packageName ||
924980 ! isStablePatchDrift ( metadata . version , currentMetadata . version ) ||
981+ ! versionSatisfiesSimpleSpec (
982+ currentMetadata . version ,
983+ dependencySpecForLockPath ( generatedPackages , lockPath , packageName ) ,
984+ ) ||
925985 ! pnpmLockPackages . has ( `${ packageName } @${ currentMetadata . version } ` )
926986 ) {
927987 continue ;
0 commit comments