-
-
Notifications
You must be signed in to change notification settings - Fork 400
Expand file tree
/
Copy path[...pkg].get.ts
More file actions
93 lines (83 loc) · 2.93 KB
/
[...pkg].get.ts
File metadata and controls
93 lines (83 loc) · 2.93 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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import type { DocsResponse } from '#shared/types'
import { assertValidPackageName } from '#shared/utils/npm'
import { parsePackageParam } from '#shared/utils/parse-package-param'
import { generateDocsWithDeno, getEntrypoints } from '#server/utils/docs'
export default defineCachedEventHandler(
async event => {
const pkgParam = getRouterParam(event, 'pkg')
if (!pkgParam) {
// TODO: throwing 404 rather than 400 as it's cacheable
throw createError({ statusCode: 404, message: 'Package name is required' })
}
const { packageName, version, rest } = parsePackageParam(pkgParam)
if (!packageName) {
// TODO: throwing 404 rather than 400 as it's cacheable
throw createError({ statusCode: 404, message: 'Package name is required' })
}
assertValidPackageName(packageName)
if (!version) {
// TODO: throwing 404 rather than 400 as it's cacheable
throw createError({ statusCode: 404, message: 'Package version is required' })
}
// Extract entrypoint from remaining path segments (e.g., ["router.js"] -> "router.js")
const entrypoint = rest.length > 0 ? rest.join('/') : undefined
// Discover available entrypoints (null for single-entrypoint packages)
const entrypoints = await getEntrypoints(packageName, version)
// If multi-entrypoint but no specific entrypoint requested, return early
// with the entrypoints list so the client can redirect to the first one
if (entrypoints && !entrypoint) {
return {
package: packageName,
version,
html: '',
toc: null,
status: 'ok',
entrypoints,
entrypoint: entrypoints[0],
} satisfies DocsResponse
}
let generated
try {
generated = await generateDocsWithDeno(packageName, version, entrypoint)
} catch (error) {
// eslint-disable-next-line no-console
console.error(`Doc generation failed for ${packageName}@${version}:`, error)
return {
package: packageName,
version,
html: '',
toc: null,
status: 'error',
message: 'Failed to generate documentation. Please try again later.',
...(entrypoints && { entrypoints, entrypoint }),
} satisfies DocsResponse
}
if (!generated) {
return {
package: packageName,
version,
html: '',
toc: null,
status: 'missing',
message: 'Docs are not available for this package. It may not have TypeScript types.',
...(entrypoints && { entrypoints, entrypoint }),
} satisfies DocsResponse
}
return {
package: packageName,
version,
html: generated.html,
toc: generated.toc,
status: 'ok',
...(entrypoints && { entrypoints, entrypoint }),
} satisfies DocsResponse
},
{
maxAge: 60 * 60, // 1 hour cache
swr: true,
getKey: event => {
const pkg = getRouterParam(event, 'pkg') ?? ''
return `docs:v3:${pkg}`
},
},
)