forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1import type { ReleaseType } from 'semver'
2
3/** Information about an outdated dependency */
4export interface OutdatedDependencyInfo {
5 /** The resolved version that satisfies the constraint */
6 resolved: string
7 /** The latest available version */
8 latest: string
9 /** How many major versions behind */
10 majorsBehind: number
11 /** How many minor versions behind (when same major) */
12 minorsBehind: number
13 /** The type of version difference */
14 diffType: ReleaseType | null
15}
16
17/**
18 * Check if a version constraint explicitly includes a prerelease tag.
19 * e.g., "^1.0.0-alpha" or ">=2.0.0-beta.1" include prereleases
20 */
21export function constraintIncludesPrerelease(constraint: string): boolean {
22 return (
23 /-(?:alpha|beta|rc|next|canary|dev|preview|pre|experimental)/i.test(constraint) ||
24 /-\d/.test(constraint)
25 )
26}
27
28/**
29 * Check if a constraint is a non-semver value (git URL, file path, etc.)
30 */
31export function isNonSemverConstraint(constraint: string): boolean {
32 return (
33 constraint.startsWith('git') ||
34 constraint.startsWith('http') ||
35 constraint.startsWith('file:') ||
36 constraint.startsWith('npm:') ||
37 constraint.startsWith('link:') ||
38 constraint.startsWith('workspace:') ||
39 constraint.includes('/')
40 )
41}
42
43/**
44 * Get tooltip text for an outdated dependency
45 */
46export function getOutdatedTooltip(
47 info: OutdatedDependencyInfo,
48 t: (key: string, params?: Record<string, unknown>, plural?: number) => string,
49): string {
50 if (info.majorsBehind > 0) {
51 return t(
52 'package.dependencies.outdated_major',
53 { count: info.majorsBehind, latest: info.latest },
54 info.majorsBehind,
55 )
56 }
57 if (info.minorsBehind > 0) {
58 return t(
59 'package.dependencies.outdated_minor',
60 { count: info.minorsBehind, latest: info.latest },
61 info.minorsBehind,
62 )
63 }
64 return t('package.dependencies.outdated_patch', { latest: info.latest })
65}
66
67/**
68 * Get CSS class for a dependency version based on outdated status
69 */
70export function getVersionClass(info: OutdatedDependencyInfo | undefined): string {
71 if (!info) return 'text-fg-subtle'
72 // Green for up-to-date (e.g. "latest" constraint)
73 if (info.majorsBehind === 0 && info.minorsBehind === 0 && info.resolved === info.latest) {
74 return 'text-green-700 dark:text-green-500 cursor-help'
75 }
76 // Red for major versions behind
77 if (info.majorsBehind > 0) return 'text-red-700 dark:text-red-500 cursor-help'
78 // if (info.majorsBehind > 0) return 'text-#db0000 dark:text-red-500 cursor-help'
79 // Orange for minor versions behind
80 if (info.minorsBehind > 0) return 'text-orange-700 dark:text-orange-500 cursor-help'
81 // Yellow for patch versions behind
82 return 'text-yellow-700 dark:text-yellow-500 cursor-help'
83}