Skip to content

Commit a58326f

Browse files
committed
feat: update
1 parent 9923d48 commit a58326f

File tree

2 files changed

+61
-5
lines changed

2 files changed

+61
-5
lines changed

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const { data: npmWebsiteVersions } = useLazyFetch<NpmWebsiteVersionsResponse>(
7171
)
7272
7373
const numberFormatter = useNumberFormatter()
74+
const { t } = useI18n()
7475
const versionDownloadsMap = computed(
7576
() =>
7677
new Map(
@@ -99,6 +100,10 @@ function getGroupDownloads(versions: string[]): number | undefined {
99100
return hasValue ? total : undefined
100101
}
101102
103+
function getDownloadsAriaLabel(downloads: number): string {
104+
return `${numberFormatter.value.format(downloads)} ${t('package.downloads.title')}`
105+
}
106+
102107
// ─── Phase 2: full metadata (loaded on first group expand) ────────────────────
103108
// Fetches deprecated status, provenance, and exact times needed for version rows.
104109
@@ -294,7 +299,7 @@ const flatItems = computed<FlatItem[]>(() => {
294299
<div
295300
v-if="getVersionDownloads(latestTagRow!.version) !== undefined"
296301
class="text-sm font-medium text-fg tabular-nums shrink-0"
297-
:aria-label="$t('package.downloads.title')"
302+
:aria-label="getDownloadsAriaLabel(getVersionDownloads(latestTagRow!.version)!)"
298303
dir="ltr"
299304
>
300305
{{ numberFormatter.format(getVersionDownloads(latestTagRow!.version)!) }}
@@ -351,7 +356,7 @@ const flatItems = computed<FlatItem[]>(() => {
351356
<span
352357
v-if="getVersionDownloads(row.version) !== undefined"
353358
class="text-xs text-fg-muted shrink-0 tabular-nums w-24 text-end"
354-
:aria-label="$t('package.downloads.title')"
359+
:aria-label="getDownloadsAriaLabel(getVersionDownloads(row.version)!)"
355360
dir="ltr"
356361
>
357362
{{ numberFormatter.format(getVersionDownloads(row.version)!) }}
@@ -445,7 +450,7 @@ const flatItems = computed<FlatItem[]>(() => {
445450
<span
446451
v-if="getGroupDownloads(item.versions) !== undefined"
447452
class="ms-auto text-xs text-fg-muted tabular-nums w-24 text-end"
448-
:aria-label="$t('package.downloads.title')"
453+
:aria-label="getDownloadsAriaLabel(getGroupDownloads(item.versions)!)"
449454
dir="ltr"
450455
>
451456
{{ numberFormatter.format(getGroupDownloads(item.versions)!) }}
@@ -518,7 +523,7 @@ const flatItems = computed<FlatItem[]>(() => {
518523
<span
519524
v-if="getVersionDownloads(item.version) !== undefined"
520525
class="text-xs text-fg-muted tabular-nums w-24 text-end shrink-0"
521-
:aria-label="$t('package.downloads.title')"
526+
:aria-label="getDownloadsAriaLabel(getVersionDownloads(item.version)!)"
522527
dir="ltr"
523528
>
524529
{{ numberFormatter.format(getVersionDownloads(item.version)!) }}
@@ -564,7 +569,7 @@ const flatItems = computed<FlatItem[]>(() => {
564569
<span
565570
v-if="getGroupDownloads(item.versions) !== undefined"
566571
class="ms-auto text-xs text-fg-muted tabular-nums w-24 text-end"
567-
:aria-label="$t('package.downloads.title')"
572+
:aria-label="getDownloadsAriaLabel(getGroupDownloads(item.versions)!)"
568573
dir="ltr"
569574
>
570575
{{ numberFormatter.format(getGroupDownloads(item.versions)!) }}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { afterEach, describe, expect, it, vi } from 'vitest'
2+
import { createError } from 'h3'
3+
4+
vi.stubGlobal('encodePackageName', (name: string) => {
5+
if (name.startsWith('@')) return `@${encodeURIComponent(name.slice(1))}`
6+
return encodeURIComponent(name)
7+
})
8+
vi.stubGlobal('createError', createError)
9+
10+
const { fetchNpmVersionDownloadsFromApi } = await import('#server/utils/npm-website-versions')
11+
12+
afterEach(() => {
13+
vi.restoreAllMocks()
14+
})
15+
16+
describe('fetchNpmVersionDownloadsFromApi', () => {
17+
it('encodes scoped package names in npm API request URL', async () => {
18+
const fetchMock = vi.fn().mockResolvedValue({
19+
ok: true,
20+
json: async () => ({
21+
downloads: {
22+
'1.0.0': 123,
23+
},
24+
}),
25+
})
26+
vi.stubGlobal('fetch', fetchMock)
27+
28+
const result = await fetchNpmVersionDownloadsFromApi('@nuxt/kit')
29+
30+
expect(fetchMock).toHaveBeenCalledWith('https://api.npmjs.org/versions/@nuxt%2Fkit/last-week')
31+
expect(result).toEqual([
32+
{
33+
version: '1.0.0',
34+
downloads: 123,
35+
},
36+
])
37+
})
38+
39+
it('throws a not-found error when npm API returns 404', async () => {
40+
const fetchMock = vi.fn().mockResolvedValue({
41+
ok: false,
42+
status: 404,
43+
})
44+
vi.stubGlobal('fetch', fetchMock)
45+
46+
await expect(fetchNpmVersionDownloadsFromApi('missing-package')).rejects.toMatchObject({
47+
statusCode: 404,
48+
message: 'Package not found',
49+
})
50+
})
51+
})

0 commit comments

Comments
 (0)