|
1 | | -import type { Packument, PackumentVersion } from '@npm/types' |
2 | | -import { NPM_REGISTRY } from '#constants' |
| 1 | +import type { PackageVersionsInfoWithMetadata } from 'fast-npm-meta' |
3 | 2 | import { logger } from '#state' |
4 | | -import { encodePackageName } from '#utils/package' |
5 | | -import { ofetch } from 'ofetch' |
| 3 | +import { getVersions } from 'fast-npm-meta' |
6 | 4 | import { memoize } from '../memoize' |
7 | 5 |
|
8 | | -interface ResolvedPackumentVersion extends Pick<PackumentVersion, 'version'> { |
9 | | - tag?: string |
10 | | - hasProvenance: boolean |
11 | | - deprecated?: string |
| 6 | +export interface PackageInfo extends PackageVersionsInfoWithMetadata { |
| 7 | + versionToTag: Map<string, string> |
12 | 8 | } |
13 | 9 |
|
14 | | -export interface ResolvedPackument { |
15 | | - versions: Record<string, ResolvedPackumentVersion> |
16 | | -} |
17 | | - |
18 | | -export const getPackageInfo = memoize<string, Promise<ResolvedPackument>>(async (name) => { |
| 10 | +/** |
| 11 | + * Fetch npm package versions and build a version-to-tag lookup map. |
| 12 | + * |
| 13 | + * @see https://github.com/antfu/fast-npm-meta |
| 14 | + */ |
| 15 | +export const getPackageInfo = memoize<string, Promise<PackageInfo | null>>(async (name) => { |
19 | 16 | logger.info(`Fetching package info for ${name}`) |
20 | | - const encodedName = encodePackageName(name) |
21 | | - |
22 | | - const pkg = await ofetch<Packument>(`${NPM_REGISTRY}/${encodedName}`) |
23 | | - logger.info(`Fetched package info for ${name}`) |
24 | 17 |
|
25 | | - const resolvedVersions = Object.fromEntries( |
26 | | - Object.keys(pkg.versions) |
27 | | - .filter((v) => pkg.time[v]) |
28 | | - .map<[string, ResolvedPackumentVersion]>((v) => [ |
29 | | - v, |
30 | | - { |
31 | | - version: v, |
32 | | - // @ts-expect-error present if published with provenance |
33 | | - hasProvenance: !!pkg.versions[v].dist.attestations, |
34 | | - deprecated: pkg.versions[v].deprecated, |
35 | | - }, |
36 | | - ]), |
37 | | - ) |
38 | | - |
39 | | - Object.entries(pkg['dist-tags']).forEach(([tag, version]) => { |
40 | | - resolvedVersions[version].tag = tag |
| 18 | + const pkg = await getVersions(name, { |
| 19 | + metadata: true, |
| 20 | + throw: false, |
41 | 21 | }) |
42 | 22 |
|
43 | | - return { |
44 | | - versions: resolvedVersions, |
| 23 | + if ('error' in pkg) { |
| 24 | + logger.warn(`Fetching package info for ${name} error: ${JSON.stringify(pkg)}`) |
| 25 | + |
| 26 | + // Return null to trigger a cache hit |
| 27 | + if (pkg.status === 404) |
| 28 | + return null |
| 29 | + |
| 30 | + throw pkg |
45 | 31 | } |
| 32 | + |
| 33 | + logger.info(`Fetched package info for ${name}`) |
| 34 | + |
| 35 | + const versionToTag = new Map<string, string>() |
| 36 | + if (pkg.distTags) { |
| 37 | + for (const [tag, ver] of Object.entries(pkg.distTags)) { |
| 38 | + versionToTag.set(ver, tag) |
| 39 | + } |
| 40 | + } |
| 41 | + |
| 42 | + return { ...pkg, versionToTag } |
46 | 43 | }) |
0 commit comments