forked from
npmx.dev/npmx.dev
[READ-ONLY]
a fast, modern browser for the npm registry
1import type { PackageVersionInfo } from '#shared/types'
2import { getVersions } from 'fast-npm-meta'
3import { compare } from 'semver'
4
5type NpmDownloadsRangeResponse = {
6 start: string
7 end: string
8 package: string
9 downloads: Array<{ day: string; downloads: number }>
10}
11
12/**
13 * Fetch download range data from npm API.
14 * Exported for external use (e.g., in components).
15 */
16export async function fetchNpmDownloadsRange(
17 packageName: string,
18 start: string,
19 end: string,
20): Promise<NpmDownloadsRangeResponse> {
21 const { $npmApi } = useNuxtApp()
22 const encodedName = encodePackageName(packageName)
23 return (
24 await $npmApi<NpmDownloadsRangeResponse>(`/downloads/range/${start}:${end}/${encodedName}`)
25 ).data
26}
27
28// ============================================================================
29// Package Versions
30// ============================================================================
31
32// Cache for full version lists (client-side only, for non-composable usage)
33const allVersionsCache = new Map<string, Promise<PackageVersionInfo[]>>()
34
35/**
36 * Fetch all versions of a package using fast-npm-meta API.
37 * Returns version info sorted by version (newest first).
38 * Results are cached to avoid duplicate requests.
39 *
40 * Note: This is a standalone async function for use in event handlers.
41 * For composable usage, use useAllPackageVersions instead.
42 *
43 * @see https://github.com/antfu/fast-npm-meta
44 */
45export async function fetchAllPackageVersions(packageName: string): Promise<PackageVersionInfo[]> {
46 const cached = allVersionsCache.get(packageName)
47 if (cached) return cached
48
49 const promise = (async () => {
50 const data = await getVersions(packageName, { metadata: true })
51
52 return Object.entries(data.versionsMeta)
53 .map(([version, meta]) => ({
54 version,
55 time: meta.time,
56 hasProvenance: meta.provenance === 'trustedPublisher' || meta.provenance === true,
57 deprecated: meta.deprecated,
58 }))
59 .sort((a, b) => compare(b.version, a.version))
60 })()
61
62 allVersionsCache.set(packageName, promise)
63 return promise
64}