@@ -253,8 +253,268 @@ function is_official(pkg: string): boolean {
253253 return false ;
254254}
255255
256+ function is_outdated ( iso : string ) : boolean {
257+ // 2 years
258+ return + new Date ( ) - + new Date ( iso ) > 2 * 365 * 24 * 60 * 60 * 1000 ;
259+ }
260+
261+ /**
262+ * Checks if a semver range supports Svelte versions 3.x, 4.x, and 5.x
263+ */
264+ function supports_svelte_versions ( version_range : string ) : {
265+ 3 : boolean ;
266+ 4 : boolean ;
267+ 5 : boolean ;
268+ } {
269+ if ( ! version_range ) return { 3 : false , 4 : false , 5 : false } ;
270+
271+ // Initialize result object
272+ const result = { 3 : false , 4 : false , 5 : false } ;
273+
274+ // Handle version range with OR operators first before any other processing
275+ if ( version_range . includes ( '||' ) ) {
276+ const ranges = version_range . split ( '||' ) . map ( ( r ) => r . trim ( ) ) ;
277+
278+ // Check each range and combine results with OR logic
279+ for ( const range of ranges ) {
280+ const range_result = supports_svelte_versions ( range ) ;
281+ result [ 3 ] = result [ 3 ] || range_result [ 3 ] ;
282+ result [ 4 ] = result [ 4 ] || range_result [ 4 ] ;
283+ result [ 5 ] = result [ 5 ] || range_result [ 5 ] ;
284+ }
285+
286+ return result ;
287+ }
288+
289+ // Handle exact version with equals sign
290+ if ( version_range . startsWith ( '=' ) ) {
291+ const exact_version = version_range . substring ( 1 ) ;
292+ return supports_svelte_versions ( exact_version ) ;
293+ }
294+
295+ // Handle hyphen ranges directly (not part of a complex expression)
296+ if ( version_range . includes ( ' - ' ) ) {
297+ // Split by hyphen and trim whitespace
298+ const parts = version_range . split ( '-' ) . map ( ( p ) => p . trim ( ) ) ;
299+ // Handle "x - y" format correctly
300+ if ( parts . length === 2 ) {
301+ const start = parseFloat ( parts [ 0 ] ) ;
302+ const end = parseFloat ( parts [ 1 ] ) ;
303+
304+ result [ 3 ] = start <= 3 && end >= 3 ;
305+ result [ 4 ] = start <= 4 && end >= 4 ;
306+ result [ 5 ] = start <= 5 && end >= 5 ;
307+
308+ return result ;
309+ }
310+ }
311+
312+ // Handle complex version ranges with both upper and lower bounds in the same expression
313+ // Examples: ">=1.0.0 <=4.9.9", ">=3.0.0 <6.0.0", ">3.0.0-rc.1 <3.1.0"
314+ if (
315+ version_range . includes ( ' ' ) &&
316+ ( version_range . includes ( '<' ) ||
317+ version_range . includes ( '<=' ) ||
318+ version_range . includes ( '>=' ) ||
319+ version_range . includes ( '>' ) )
320+ ) {
321+ // Process for complex range with multiple constraints
322+ let includes_version_3 = true ;
323+ let includes_version_4 = true ;
324+ let includes_version_5 = true ;
325+
326+ // Split by spaces to get individual constraints
327+ const constraints = version_range
328+ . split ( ' ' )
329+ . filter (
330+ ( c ) => c . startsWith ( '<' ) || c . startsWith ( '<=' ) || c . startsWith ( '>' ) || c . startsWith ( '>=' )
331+ ) ;
332+
333+ // If we couldn't parse any valid constraints, return false
334+ if ( constraints . length === 0 ) {
335+ return { 3 : false , 4 : false , 5 : false } ;
336+ }
337+
338+ // Special case handling for pre-release specific ranges (e.g., ">3.0.0-rc.1 <3.1.0")
339+ if ( constraints . some ( ( c ) => c . includes ( '-' ) ) ) {
340+ // Identify if this is a narrow range for a specific major version
341+ let major_version = null ;
342+
343+ for ( const constraint of constraints ) {
344+ const match = constraint . match ( / [ < > = ] + \s * ( \d + ) / ) ;
345+ if ( match ) {
346+ const version = parseInt ( match [ 1 ] ) ;
347+ if ( major_version === null ) {
348+ major_version = version ;
349+ } else if ( major_version !== version ) {
350+ major_version = null ; // Different major versions, not a narrow range
351+ break ;
352+ }
353+ }
354+ }
355+
356+ // If we identified a specific major version for this pre-release constraint
357+ if ( major_version !== null ) {
358+ result [ 3 ] = major_version === 3 ;
359+ result [ 4 ] = major_version === 4 ;
360+ result [ 5 ] = major_version === 5 ;
361+ return result ;
362+ }
363+ }
364+
365+ for ( const constraint of constraints ) {
366+ if ( constraint . startsWith ( '>=' ) ) {
367+ const version_number = parseFloat ( constraint . substring ( 2 ) ) ;
368+ // Check lower bounds for each version
369+ if ( version_number > 3 ) includes_version_3 = false ;
370+ if ( version_number > 4 ) includes_version_4 = false ;
371+ if ( version_number > 5 ) includes_version_5 = false ;
372+ } else if ( constraint . startsWith ( '>' ) ) {
373+ const version_number = parseFloat ( constraint . substring ( 1 ) ) ;
374+ // Check lower bounds for each version
375+ if ( version_number >= 3 ) includes_version_3 = false ;
376+ if ( version_number >= 4 ) includes_version_4 = false ;
377+ if ( version_number >= 5 ) includes_version_5 = false ;
378+ } else if ( constraint . startsWith ( '<=' ) ) {
379+ const version_number = parseFloat ( constraint . substring ( 2 ) ) ;
380+ // Check upper bounds for each version
381+ if ( version_number < 3 ) includes_version_3 = false ;
382+ if ( version_number < 4 ) includes_version_4 = false ;
383+ if ( version_number < 5 ) includes_version_5 = false ;
384+ } else if ( constraint . startsWith ( '<' ) ) {
385+ const version_number = parseFloat ( constraint . substring ( 1 ) ) ;
386+ // Check upper bounds for each version
387+ if ( version_number <= 3 ) includes_version_3 = false ;
388+ if ( version_number <= 4 ) includes_version_4 = false ;
389+ if ( version_number <= 5 ) includes_version_5 = false ;
390+ }
391+ }
392+
393+ result [ 3 ] = includes_version_3 ;
394+ result [ 4 ] = includes_version_4 ;
395+ result [ 5 ] = includes_version_5 ;
396+
397+ return result ;
398+ }
399+
400+ // Handle exact major version format
401+ if ( / ^ [ 0 - 9 ] + $ / . test ( version_range ) ) {
402+ const version = parseInt ( version_range ) ;
403+ result [ 3 ] = version === 3 ;
404+ result [ 4 ] = version === 4 ;
405+ result [ 5 ] = version === 5 ;
406+ return result ;
407+ }
408+
409+ // Handle caret ranges
410+ if ( version_range . startsWith ( '^' ) ) {
411+ const major_version = parseInt ( version_range . substring ( 1 ) . split ( '.' ) [ 0 ] ) ;
412+ result [ 3 ] = major_version === 3 ;
413+ result [ 4 ] = major_version === 4 ;
414+ result [ 5 ] = major_version === 5 ;
415+ return result ;
416+ }
417+
418+ // Handle pre-release versions directly (e.g., 5.0.0-next.42)
419+ if ( / ^ ( [ 0 - 9 ] + ) \. ( [ 0 - 9 ] + ) \. ( [ 0 - 9 ] + ) - / . test ( version_range ) ) {
420+ const match = version_range . match ( / ^ ( [ 0 - 9 ] + ) \. / ) ;
421+ if ( match ) {
422+ // Extract major version from the pre-release
423+ const major_version = parseInt ( match [ 1 ] ) ;
424+ result [ 3 ] = major_version === 3 ;
425+ result [ 4 ] = major_version === 4 ;
426+ result [ 5 ] = major_version === 5 ;
427+ return result ;
428+ }
429+ }
430+
431+ // Handle tilde ranges
432+ if ( version_range . startsWith ( '~' ) ) {
433+ const major_version = parseInt ( version_range . substring ( 1 ) . split ( '.' ) [ 0 ] ) ;
434+ result [ 3 ] = major_version === 3 ;
435+ result [ 4 ] = major_version === 4 ;
436+ result [ 5 ] = major_version === 5 ;
437+ return result ;
438+ }
439+
440+ // Handle wildcard (*) by itself, which means any version
441+ if ( version_range === '*' ) {
442+ return { 3 : true , 4 : true , 5 : true } ;
443+ }
444+
445+ // Handle * and x ranges (e.g., "3.x", "4.*")
446+ if ( / ^ ( [ 0 - 9 ] + ) \. ( x | \* ) / . test ( version_range ) ) {
447+ const match = version_range . match ( / ^ ( [ 0 - 9 ] + ) \. / ) ;
448+ if ( match ) {
449+ const major_version = parseInt ( match [ 1 ] ) ;
450+ result [ 3 ] = major_version === 3 ;
451+ result [ 4 ] = major_version === 4 ;
452+ result [ 5 ] = major_version === 5 ;
453+ return result ;
454+ }
455+ }
456+
457+ // Handle >= ranges
458+ if ( version_range . startsWith ( '>=' ) ) {
459+ const version_number = parseFloat ( version_range . substring ( 2 ) ) ;
460+ result [ 3 ] = version_number <= 3 ;
461+ result [ 4 ] = version_number <= 4 ;
462+ result [ 5 ] = version_number <= 5 ;
463+ return result ;
464+ }
465+
466+ // Handle > ranges
467+ if ( version_range . startsWith ( '>' ) ) {
468+ const version_number = parseFloat ( version_range . substring ( 1 ) ) ;
469+ result [ 3 ] = version_number < 3 ;
470+ result [ 4 ] = version_number < 4 ;
471+ result [ 5 ] = version_number < 5 ;
472+ return result ;
473+ }
474+
475+ // Handle <= ranges
476+ if ( version_range . startsWith ( '<=' ) ) {
477+ const version_number = parseFloat ( version_range . substring ( 2 ) ) ;
478+ result [ 3 ] = version_number >= 3 ;
479+ result [ 4 ] = version_number >= 4 ;
480+ result [ 5 ] = version_number >= 5 ;
481+ return result ;
482+ }
483+
484+ // Handle < ranges
485+ if ( version_range . startsWith ( '<' ) ) {
486+ const version_number = parseFloat ( version_range . substring ( 1 ) ) ;
487+ result [ 3 ] = version_number > 3 ;
488+ result [ 4 ] = version_number > 4 ;
489+ result [ 5 ] = version_number > 5 ;
490+ return result ;
491+ }
492+
493+ // Handle exact versions (like 3.0.0, 4.1.2, etc.)
494+ if ( / ^ [ 0 - 9 ] + \. [ 0 - 9 ] + \. [ 0 - 9 ] + $ / . test ( version_range ) ) {
495+ const major_version = parseInt ( version_range . split ( '.' ) [ 0 ] ) ;
496+ result [ 3 ] = major_version === 3 ;
497+ result [ 4 ] = major_version === 4 ;
498+ result [ 5 ] = major_version === 5 ;
499+ return result ;
500+ }
501+
502+ // Handle x-ranges (3.x.x, 4.x, etc.)
503+ if ( version_range . includes ( '.x' ) || version_range . includes ( '.*' ) ) {
504+ const major_version = parseInt ( version_range . split ( '.' ) [ 0 ] ) ;
505+ result [ 3 ] = major_version === 3 ;
506+ result [ 4 ] = major_version === 4 ;
507+ result [ 5 ] = major_version === 5 ;
508+ return result ;
509+ }
510+
511+ return result ;
512+ }
513+
256514export const PACKAGES_META = {
257515 is_official,
516+ is_outdated,
517+ supports_svelte_versions,
258518 FEATURED ,
259519 SV_ADD ,
260520 SV_ADD_CMD
0 commit comments