···11+import { getLatestVersion } from 'fast-npm-meta'
12import { createError } from 'h3'
23import validatePackageName from 'validate-npm-package-name'
44+55+/**
66+ * Encode package name for URL usage.
77+ * Scoped packages need special handling (@scope/name → @scope%2Fname)
88+ */
99+export function encodePackageName(name: string): string {
1010+ if (name.startsWith('@')) {
1111+ return `@${encodeURIComponent(name.slice(1))}`
1212+ }
1313+ return encodeURIComponent(name)
1414+}
1515+1616+/**
1717+ * Fetch the latest version of a package using fast-npm-meta API.
1818+ * This is a lightweight alternative to fetching the full packument.
1919+ *
2020+ * @param name Package name
2121+ * @returns Latest version string or null if not found
2222+ * @see https://github.com/antfu/fast-npm-meta
2323+ */
2424+export async function fetchLatestVersion(name: string): Promise<string | null> {
2525+ try {
2626+ const meta = await getLatestVersion(name)
2727+ return meta.version
2828+ } catch {
2929+ return null
3030+ }
3131+}
332433/**
534 * Validate an npm package name and throw an HTTP error if invalid.
+1-1
test/e2e/vulnerabilities.spec.ts
···7373 )
7474 const response = await page.request.get(url)
75757676- expect(response.status()).toBe(502) // Based on handleApiError fallback
7676+ expect(response.status()).toBe(404) // Package not found returns 404
7777 })
7878})