@@ -47,3 +47,71 @@ export function resolveVersion(requested: string, available: string[]): string {
47
47
// final fallback
48
48
return uniq [ 0 ] ;
49
49
}
50
+
51
+ export function resolveVersionWithFuzzy (
52
+ requested : string ,
53
+ available : string [ ] ,
54
+ ) : string {
55
+ // strip duplicates & sort
56
+ const uniq = Array . from ( new Set ( available ) ) ;
57
+
58
+ // pick min/max
59
+ if ( requested === "latest" || requested === "oldest" ) {
60
+ // try numeric
61
+ const nums = uniq
62
+ . map ( ( v ) => ( { v, n : parseFloat ( v ) } ) )
63
+ . filter ( ( x ) => ! isNaN ( x . n ) )
64
+ . sort ( ( a , b ) => a . n - b . n ) ;
65
+ if ( nums . length ) {
66
+ return requested === "latest" ? nums [ nums . length - 1 ] . v : nums [ 0 ] . v ;
67
+ }
68
+ // fallback lex
69
+ const lex = uniq . slice ( ) . sort ( ) ;
70
+ return requested === "latest" ? lex [ lex . length - 1 ] : lex [ 0 ] ;
71
+ }
72
+
73
+ // exact match?
74
+ if ( uniq . includes ( requested ) ) {
75
+ return requested ;
76
+ }
77
+
78
+ // Try major version matching (e.g., "14" matches "14.0", "14.1", etc.)
79
+ const reqNum = parseFloat ( requested ) ;
80
+ if ( ! isNaN ( reqNum ) ) {
81
+ const majorVersionMatches = uniq . filter ( ( v ) => {
82
+ const vNum = parseFloat ( v ) ;
83
+ return ! isNaN ( vNum ) && Math . floor ( vNum ) === Math . floor ( reqNum ) ;
84
+ } ) ;
85
+
86
+ if ( majorVersionMatches . length > 0 ) {
87
+ // If multiple matches, prefer the most common format or latest
88
+ const exactMatch = majorVersionMatches . find (
89
+ ( v ) => v === `${ Math . floor ( reqNum ) } .0` ,
90
+ ) ;
91
+ if ( exactMatch ) {
92
+ return exactMatch ;
93
+ }
94
+ // Return the first match (usually the most common format)
95
+ return majorVersionMatches [ 0 ] ;
96
+ }
97
+ }
98
+
99
+ // Fuzzy matching: find the closest version
100
+ const reqNumForFuzzy = parseFloat ( requested ) ;
101
+ if ( ! isNaN ( reqNumForFuzzy ) ) {
102
+ const numericVersions = uniq
103
+ . map ( ( v ) => ( { v, n : parseFloat ( v ) } ) )
104
+ . filter ( ( x ) => ! isNaN ( x . n ) )
105
+ . sort (
106
+ ( a , b ) =>
107
+ Math . abs ( a . n - reqNumForFuzzy ) - Math . abs ( b . n - reqNumForFuzzy ) ,
108
+ ) ;
109
+
110
+ if ( numericVersions . length > 0 ) {
111
+ return numericVersions [ 0 ] . v ;
112
+ }
113
+ }
114
+
115
+ // Fallback: return the first available version
116
+ return uniq [ 0 ] ;
117
+ }
0 commit comments