@@ -617,7 +617,9 @@ export class RegistryClient {
617
617
const metadata = await this . getComposerPackageMetadata ( pkg . name )
618
618
619
619
// Find multiple update paths: patch, minor, and major
620
- const currentVersion = pkg . version
620
+ // Extract the base version from the constraint (e.g., "^3.0" -> "3.0.0")
621
+ const constraintBaseVersion = this . extractConstraintBaseVersion ( constraint )
622
+ const currentVersion = constraintBaseVersion || pkg . version
621
623
const latestVersion = pkg . latest
622
624
623
625
// Get all available versions by querying composer show
@@ -633,8 +635,8 @@ export class RegistryClient {
633
635
availableVersions = [ latestVersion ]
634
636
}
635
637
636
- // Find the best update for each type (patch, minor, major )
637
- const updateCandidates = await this . findBestUpdates ( currentVersion , availableVersions , constraint )
638
+ // Find the best constraint updates (e.g., ^3.0 -> ^3.9.0 )
639
+ const updateCandidates = await this . findBestConstraintUpdates ( constraint , availableVersions , currentVersion )
638
640
639
641
for ( const candidate of updateCandidates ) {
640
642
const updateType = getUpdateType ( currentVersion , candidate . version )
@@ -917,4 +919,81 @@ export class RegistryClient {
917
919
918
920
return undefined
919
921
}
922
+
923
+ /**
924
+ * Extract the base version from a version constraint (e.g., "^3.0" -> "3.0.0")
925
+ */
926
+ private extractConstraintBaseVersion ( constraint : string ) : string | null {
927
+ const match = constraint . match ( / ^ [ \^ ~ > = < ] * ( [ \d . ] + ) / )
928
+ if ( match ) {
929
+ return match [ 1 ]
930
+ }
931
+ return null
932
+ }
933
+
934
+ /**
935
+ * Find the best constraint updates (e.g., ^3.0 -> ^3.9.0)
936
+ */
937
+ private async findBestConstraintUpdates ( constraint : string , availableVersions : string [ ] , currentVersion : string ) : Promise < { version : string , type : 'patch' | 'minor' | 'major' } [ ] > {
938
+ const { getUpdateType } = await import ( '../utils/helpers' )
939
+ const candidates : { version : string , type : 'patch' | 'minor' | 'major' } [ ] = [ ]
940
+
941
+ // Parse current version
942
+ const currentParts = this . parseVersion ( currentVersion )
943
+ if ( ! currentParts ) {
944
+ return [ ]
945
+ }
946
+
947
+ let bestPatch : string | null = null
948
+ let bestMinor : string | null = null
949
+ let bestMajor : string | null = null
950
+
951
+ for ( const version of availableVersions ) {
952
+ // Skip dev/alpha/beta versions for now (could be enhanced later)
953
+ if ( version . includes ( 'dev' ) || version . includes ( 'alpha' ) || version . includes ( 'beta' ) || version . includes ( 'RC' ) ) {
954
+ continue
955
+ }
956
+
957
+ const versionParts = this . parseVersion ( version )
958
+ if ( ! versionParts ) {
959
+ continue
960
+ }
961
+
962
+ // Skip versions that are not newer
963
+ const comparison = this . compareVersions ( version , currentVersion )
964
+ if ( comparison <= 0 ) {
965
+ continue
966
+ }
967
+
968
+ const updateType = getUpdateType ( currentVersion , version )
969
+
970
+ // Find best update for each type
971
+ if ( updateType === 'patch' && versionParts . major === currentParts . major && versionParts . minor === currentParts . minor ) {
972
+ if ( ! bestPatch || this . compareVersions ( version , bestPatch ) > 0 ) {
973
+ bestPatch = version
974
+ }
975
+ } else if ( updateType === 'minor' && versionParts . major === currentParts . major ) {
976
+ if ( ! bestMinor || this . compareVersions ( version , bestMinor ) > 0 ) {
977
+ bestMinor = version
978
+ }
979
+ } else if ( updateType === 'major' ) {
980
+ if ( ! bestMajor || this . compareVersions ( version , bestMajor ) > 0 ) {
981
+ bestMajor = version
982
+ }
983
+ }
984
+ }
985
+
986
+ // Add the best candidates
987
+ if ( bestPatch ) {
988
+ candidates . push ( { version : bestPatch , type : 'patch' } )
989
+ }
990
+ if ( bestMinor ) {
991
+ candidates . push ( { version : bestMinor , type : 'minor' } )
992
+ }
993
+ if ( bestMajor ) {
994
+ candidates . push ( { version : bestMajor , type : 'major' } )
995
+ }
996
+
997
+ return candidates
998
+ }
920
999
}
0 commit comments