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