@@ -47,3 +47,71 @@ export function resolveVersion(requested: string, available: string[]): string {
4747 // final fallback
4848 return uniq [ 0 ] ;
4949}
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