Skip to content

Commit 5b9f12f

Browse files
committed
fix: fix tag issue and sort tagged versions
1 parent 07a9ea9 commit 5b9f12f

2 files changed

Lines changed: 55 additions & 10 deletions

File tree

app/pages/package/[[org]]/[name]/versions.vue

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
filterVersions,
99
getVersionGroupKey,
1010
getVersionGroupLabel,
11+
getTagPriority,
1112
} from '~/utils/versions'
1213
import { fetchAllPackageVersions } from '~/utils/npm/api'
1314
@@ -65,6 +66,19 @@ async function ensureFullDataLoaded() {
6566
6667
const versionToTagsMap = computed(() => buildVersionToTagsMap(distTags.value))
6768
const tagRows = computed(() => buildTaggedVersionRows(distTags.value))
69+
const latestTagRow = computed(() => tagRows.value.find(r => r.tags.includes('latest')) ?? null)
70+
const otherTagRows = computed(() =>
71+
tagRows.value
72+
.filter(r => !r.tags.includes('latest'))
73+
.sort((a, b) => {
74+
const pa = getTagPriority(a.primaryTag)
75+
const pb = getTagPriority(b.primaryTag)
76+
if (pa !== pb) return pa - pb
77+
const ta = versionTimes.value[a.version] ?? ''
78+
const tb = versionTimes.value[b.version] ?? ''
79+
return tb.localeCompare(ta)
80+
}),
81+
)
6882
6983
function getVersionTime(version: string): string | undefined {
7084
return versionTimes.value[version]
@@ -215,39 +229,39 @@ const flatItems = computed<FlatItem[]>(() => {
215229

216230
<!-- Latest — featured card -->
217231
<div
218-
v-if="tagRows[0]"
232+
v-if="latestTagRow"
219233
class="border-y sm:rounded-lg sm:border border-accent/40 bg-accent/5 px-5 py-4 relative flex items-center justify-between gap-4 hover:bg-accent/8 transition-colors"
220234
>
221235
<!-- Left: tags + version -->
222236
<div>
223237
<div class="flex items-center gap-2 mb-1.5 flex-wrap">
224238
<span class="text-3xs font-bold uppercase tracking-widest text-accent">latest</span>
225239
<span
226-
v-for="tag in tagRows[0].tags.filter(t => t !== 'latest')"
240+
v-for="tag in latestTagRow!.tags.filter(t => t !== 'latest')"
227241
:key="tag"
228242
class="text-3xs font-semibold uppercase tracking-wide text-fg-subtle"
229243
>{{ tag }}</span
230244
>
231245
</div>
232246
<LinkBase
233-
:to="packageRoute(packageName, tagRows[0].version)"
247+
:to="packageRoute(packageName, latestTagRow!.version)"
234248
class="text-2xl font-semibold tracking-tight after:absolute after:inset-0 after:content-['']"
235249
dir="ltr"
236-
>{{ tagRows[0].version }}</LinkBase
250+
>{{ latestTagRow!.version }}</LinkBase
237251
>
238252
</div>
239253
<!-- Right: date + provenance -->
240254
<div class="flex flex-col items-end gap-1.5 shrink-0 relative z-10">
241255
<ProvenanceBadge
242-
v-if="fullVersionMap?.get(tagRows[0].version)?.hasProvenance"
256+
v-if="fullVersionMap?.get(latestTagRow!.version)?.hasProvenance"
243257
:package-name="packageName"
244-
:version="tagRows[0].version"
258+
:version="latestTagRow!.version"
245259
compact
246260
:linked="false"
247261
/>
248262
<DateTime
249-
v-if="getVersionTime(tagRows[0].version)"
250-
:datetime="getVersionTime(tagRows[0].version)!"
263+
v-if="getVersionTime(latestTagRow!.version)"
264+
:datetime="getVersionTime(latestTagRow!.version)!"
251265
class="text-xs text-fg-subtle"
252266
year="numeric"
253267
month="short"
@@ -258,11 +272,11 @@ const flatItems = computed<FlatItem[]>(() => {
258272

259273
<!-- Other tags — compact list (hidden when only latest exists) -->
260274
<div
261-
v-if="tagRows.length > 1"
275+
v-if="otherTagRows.length > 0"
262276
class="border-y sm:rounded-lg sm:border border-border sm:overflow-hidden"
263277
>
264278
<div
265-
v-for="row in tagRows.slice(1)"
279+
v-for="row in otherTagRows"
266280
:key="row.id"
267281
class="flex items-center gap-4 px-4 py-2.5 border-b border-border last:border-0 hover:bg-bg-subtle transition-colors relative"
268282
>

app/utils/versions.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,37 @@ export function getPrereleaseChannel(version: string): string {
5151
return match ? match[1]!.toLowerCase() : ''
5252
}
5353

54+
/**
55+
* Priority order for well-known dist-tags.
56+
* Lower number = higher priority in display order.
57+
* Unknown tags fall back to Infinity and are sorted by publish date descending.
58+
*/
59+
export const TAG_PRIORITY: Record<string, number> = {
60+
stable: 0,
61+
rc: 1,
62+
beta: 2,
63+
next: 3,
64+
alpha: 4,
65+
canary: 5,
66+
nightly: 6,
67+
experimental: 7,
68+
legacy: 8,
69+
}
70+
71+
/**
72+
* Get the display priority for a dist-tag.
73+
* Uses fuzzy matching so e.g. "v2-legacy" matches "legacy".
74+
* @param tag - The tag name (e.g., "beta", "v2-legacy")
75+
* @returns Numeric priority (lower = higher priority); Infinity for unknown tags
76+
*/
77+
export function getTagPriority(tag: string | undefined): number {
78+
if (!tag) return Infinity
79+
for (const [key, priority] of Object.entries(TAG_PRIORITY)) {
80+
if (tag.toLowerCase().includes(key)) return priority
81+
}
82+
return Infinity
83+
}
84+
5485
/**
5586
* Sort tags with 'latest' first, then alphabetically
5687
* @param tags - Array of tag names

0 commit comments

Comments
 (0)