[READ-ONLY] a fast, modern browser for the npm registry
at main 66 lines 2.0 kB view raw
1import type { JsrPackageMeta, JsrPackageInfo } from '#shared/types/jsr' 2 3const JSR_REGISTRY = 'https://jsr.io' 4 5/** 6 * Check if a scoped npm package exists on JSR with the same name. 7 * 8 * This only works for scoped packages (@scope/name) since: 9 * 1. JSR only has scoped packages 10 * 2. We can only authoritatively match when names are identical 11 * 12 * Unscoped npm packages (e.g., "hono") may exist on JSR under a different 13 * name (e.g., "@hono/hono"), but we don't attempt to guess these mappings. 14 * 15 * @param npmPackageName - The npm package name (e.g., "@hono/hono") 16 * @returns JsrPackageInfo with existence status and metadata 17 */ 18export const fetchJsrPackageInfo = defineCachedFunction( 19 async (npmPackageName: string): Promise<JsrPackageInfo> => { 20 // Only check scoped packages - we can't authoritatively map unscoped names 21 if (!npmPackageName.startsWith('@')) { 22 return { exists: false } 23 } 24 25 // Parse scope and name from @scope/name format 26 const match = npmPackageName.match(/^@([^/]+)\/(.+)$/) 27 if (!match) { 28 return { exists: false } 29 } 30 31 const [, scope, name] = match 32 33 try { 34 // Fetch JSR package metadata 35 const meta = await $fetch<JsrPackageMeta>(`${JSR_REGISTRY}/@${scope}/${name}/meta.json`, { 36 // Short timeout since this is a nice-to-have feature 37 timeout: 3000, 38 }) 39 40 // Find latest non-yanked version 41 const versions = Object.entries(meta.versions) 42 .filter(([, v]) => !v.yanked) 43 .map(([version]) => version) 44 45 versions.sort() 46 const latestVersion = versions[versions.length - 1] 47 48 return { 49 exists: true, 50 scope: meta.scope, 51 name: meta.name, 52 url: `${JSR_REGISTRY}/@${meta.scope}/${meta.name}`, 53 latestVersion, 54 } 55 } catch { 56 // Package doesn't exist on JSR or API error 57 return { exists: false } 58 } 59 }, 60 { 61 maxAge: 60 * 60 * 24, // 1 day 62 swr: true, 63 name: 'jsr-package-info', 64 getKey: (name: string) => name, 65 }, 66)