@@ -13,6 +13,13 @@ interface NpmRegistryPackageMetadata {
1313 versions ?: Record < string , unknown > ;
1414}
1515
16+ interface ParsedVersion {
17+ major : number ;
18+ minor : number ;
19+ patch : number ;
20+ prerelease : string [ ] ;
21+ }
22+
1623export function isDeprecatedRspackVersion ( version : string ) {
1724 return deprecatedRspackVersions . includes ( version as ( typeof deprecatedRspackVersions ) [ number ] ) ;
1825}
@@ -24,12 +31,82 @@ function getEnabledRspackVersions(versions: string[]) {
2431}
2532
2633function compareVersionStrings ( a : string , b : string ) {
34+ const parsedA = parseVersion ( a ) ;
35+ const parsedB = parseVersion ( b ) ;
36+ if ( parsedA && parsedB ) {
37+ return compareParsedVersions ( parsedB , parsedA ) ;
38+ }
39+
40+ return compareVersionNames ( a , b ) ;
41+ }
42+
43+ function compareVersionNames ( a : string , b : string ) {
2744 return b . localeCompare ( a , undefined , {
2845 numeric : true ,
2946 sensitivity : "base" ,
3047 } ) ;
3148}
3249
50+ function parseVersion ( version : string ) : ParsedVersion | null {
51+ const match = version . match ( / ^ ( \d + ) \. ( \d + ) \. ( \d + ) (?: - ( [ ^ + ] + ) ) ? (?: \+ .* ) ? $ / ) ;
52+ if ( ! match ) {
53+ return null ;
54+ }
55+
56+ return {
57+ major : Number ( match [ 1 ] ) ,
58+ minor : Number ( match [ 2 ] ) ,
59+ patch : Number ( match [ 3 ] ) ,
60+ prerelease : match [ 4 ] ?. split ( "." ) ?? [ ] ,
61+ } ;
62+ }
63+
64+ function compareParsedVersions ( a : ParsedVersion , b : ParsedVersion ) {
65+ const releaseDiff = a . major - b . major || a . minor - b . minor || a . patch - b . patch ;
66+ if ( releaseDiff !== 0 ) {
67+ return releaseDiff ;
68+ }
69+
70+ if ( a . prerelease . length === 0 && b . prerelease . length === 0 ) {
71+ return 0 ;
72+ }
73+ if ( a . prerelease . length === 0 ) {
74+ return 1 ;
75+ }
76+ if ( b . prerelease . length === 0 ) {
77+ return - 1 ;
78+ }
79+
80+ const length = Math . max ( a . prerelease . length , b . prerelease . length ) ;
81+ for ( let i = 0 ; i < length ; i ++ ) {
82+ const itemA = a . prerelease [ i ] ;
83+ const itemB = b . prerelease [ i ] ;
84+ if ( itemA === undefined ) return - 1 ;
85+ if ( itemB === undefined ) return 1 ;
86+
87+ const numberA = getPrereleaseNumber ( itemA ) ;
88+ const numberB = getPrereleaseNumber ( itemB ) ;
89+ if ( numberA !== null && numberB !== null ) {
90+ const diff = numberA - numberB ;
91+ if ( diff !== 0 ) return diff ;
92+ continue ;
93+ }
94+ if ( numberA !== null ) return - 1 ;
95+ if ( numberB !== null ) return 1 ;
96+
97+ const diff = itemA . localeCompare ( itemB ) ;
98+ if ( diff !== 0 ) {
99+ return diff ;
100+ }
101+ }
102+
103+ return 0 ;
104+ }
105+
106+ function getPrereleaseNumber ( value : string ) {
107+ return / ^ \d + $ / . test ( value ) ? Number ( value ) : null ;
108+ }
109+
33110function sortVersionsByPublishedTime (
34111 versions : string [ ] ,
35112 publishedTime : Record < string , string > | undefined ,
0 commit comments