@@ -49,7 +49,52 @@ export function parseVersion(rawVersion: string): ParsedVersion | null {
4949 return { protocol, prefix, semver }
5050}
5151
52+ /** related to: https://semver.org/spec/v2.0.0-rc.2.html */
53+ const CORE_VERSION_PATTERN = / ^ ( 0 | [ 1 - 9 ] \d * ) \. ( 0 | [ 1 - 9 ] \d * ) \. ( 0 | [ 1 - 9 ] \d * ) /
54+ type CoreVersion = [ major : number , minor : number , patch : number ]
55+
56+ function stripBuildMetadata ( version : string ) : string {
57+ const idx = version . indexOf ( '+' )
58+ return idx === - 1 ? version : version . slice ( 0 , idx )
59+ }
60+
61+ function parseCoreVersion ( version : string ) : CoreVersion | null {
62+ const match = version . match ( CORE_VERSION_PATTERN )
63+ if ( ! match )
64+ return null
65+
66+ return [ Number ( match [ 1 ] ) , Number ( match [ 2 ] ) , Number ( match [ 3 ] ) ]
67+ }
68+
69+ export type UpdateType = 'major' | 'minor' | 'patch' | 'prerelease' | 'none'
70+
71+ export function getUpdateType ( current : string , latest : string ) : UpdateType {
72+ current = stripBuildMetadata ( current )
73+ latest = stripBuildMetadata ( latest )
74+
75+ const cur = parseCoreVersion ( current )
76+ const lat = parseCoreVersion ( latest )
77+
78+ if ( ! cur || ! lat )
79+ return 'none'
80+
81+ if ( lat [ 0 ] !== cur [ 0 ] )
82+ return lat [ 0 ] > cur [ 0 ] ? 'major' : 'none'
83+
84+ if ( lat [ 1 ] !== cur [ 1 ] )
85+ return lat [ 1 ] > cur [ 1 ] ? 'minor' : 'none'
86+
87+ if ( lat [ 2 ] !== cur [ 2 ] )
88+ return lat [ 2 ] > cur [ 2 ] ? 'patch' : 'none'
89+
90+ if ( current !== latest && current . includes ( '-' ) && ! latest . includes ( '-' ) )
91+ return 'prerelease'
92+
93+ return 'none'
94+ }
95+
5296export function getPrereleaseId ( version : string ) : string | null {
97+ version = stripBuildMetadata ( version )
5398 const idx = version . indexOf ( '-' )
5499 if ( idx === - 1 )
55100 return null
@@ -75,8 +120,14 @@ function comparePrereleasePrecedence(a: string, b: string): number {
75120
76121 const numA = Number ( partsA [ i ] )
77122 const numB = Number ( partsB [ i ] )
78- if ( ! Number . isNaN ( numA ) && ! Number . isNaN ( numB ) ) {
79- return numA - numB
123+ const isNumA = ! Number . isNaN ( numA )
124+ const isNumB = ! Number . isNaN ( numB )
125+
126+ if ( isNumA && isNumB ) {
127+ if ( numA !== numB )
128+ return numA - numB
129+ } else if ( isNumA !== isNumB ) {
130+ return isNumA ? - 1 : 1
80131 } else if ( partsA [ i ] !== partsB [ i ] ) {
81132 return partsA [ i ] < partsB [ i ] ? - 1 : 1
82133 }
@@ -86,10 +137,14 @@ function comparePrereleasePrecedence(a: string, b: string): number {
86137}
87138
88139export function lt ( a : string , b : string ) : boolean {
89- const [ coreA , preA ] = a . split ( '-' , 2 )
90- const [ coreB , preB ] = b . split ( '-' , 2 )
91- const partsA = coreA . split ( '.' ) . map ( Number )
92- const partsB = coreB . split ( '.' ) . map ( Number )
140+ a = stripBuildMetadata ( a )
141+ b = stripBuildMetadata ( b )
142+
143+ const [ coreA , preA ] = a . split ( '-' )
144+ const [ coreB , preB ] = b . split ( '-' )
145+
146+ const partsA = parseCoreVersion ( coreA ) !
147+ const partsB = parseCoreVersion ( coreB ) !
93148 for ( let i = 0 ; i < 3 ; i ++ ) {
94149 const diff = ( partsA [ i ] || 0 ) - ( partsB [ i ] || 0 )
95150 if ( diff !== 0 )
0 commit comments