forked from npmx-dev/npmx.dev
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathreadme-loaders.ts
More file actions
120 lines (102 loc) · 3.25 KB
/
readme-loaders.ts
File metadata and controls
120 lines (102 loc) · 3.25 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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import * as v from 'valibot'
import { PackageRouteParamsSchema } from '#shared/schemas/package'
import {
CACHE_MAX_AGE_ONE_HOUR,
NPM_MISSING_README_SENTINEL,
NPM_README_TRUNCATION_THRESHOLD,
} from '#shared/utils/constants'
/** Standard README filenames to try when fetching from jsdelivr (case-sensitive CDN) */
const standardReadmeFilenames = [
'README.md',
'readme.md',
'Readme.md',
'README',
'readme',
'README.markdown',
'readme.markdown',
]
/** Matches standard README filenames (case-insensitive, for checking registry metadata) */
const standardReadmePattern = /^readme(?:\.md|\.markdown)?$/i
export function isStandardReadme(filename: string | undefined): boolean {
return !!filename && standardReadmePattern.test(filename)
}
/**
* Fetch README from jsdelivr CDN for a specific package version.
* Falls back through common README filenames.
*/
export async function fetchReadmeFromJsdelivr(
packageName: string,
readmeFilenames: string[],
version?: string,
): Promise<string | null> {
const versionSuffix = version ? `@${version}` : ''
for (const filename of readmeFilenames) {
try {
const url = `https://cdn.jsdelivr.net/npm/${packageName}${versionSuffix}/${filename}`
const response = await fetch(url)
if (response.ok) {
return await response.text()
}
} catch {
// Try next filename
}
}
return null
}
export const resolvePackageReadmeSource = defineCachedFunction(
async (packagePath: string) => {
const pkgParamSegments = packagePath.split('/')
const { rawPackageName, rawVersion } = parsePackageParams(pkgParamSegments)
const { packageName, version } = v.parse(PackageRouteParamsSchema, {
packageName: rawPackageName,
version: rawVersion,
})
const packageData = await fetchNpmPackage(packageName)
let readmeContent: string | undefined
let readmeFilename: string | undefined
if (version) {
const versionData = packageData.versions[version]
if (versionData) {
readmeContent = versionData.readme
readmeFilename = versionData.readmeFilename
}
} else {
readmeContent = packageData.readme
readmeFilename = packageData.readmeFilename
}
const hasValidNpmReadme = readmeContent && readmeContent !== NPM_MISSING_README_SENTINEL
const isLikelyTruncated =
hasValidNpmReadme && readmeContent!.length >= NPM_README_TRUNCATION_THRESHOLD
if (!hasValidNpmReadme || !isStandardReadme(readmeFilename) || isLikelyTruncated) {
const resolvedVersion = version ?? packageData['dist-tags']?.latest
const jsdelivrReadme = await fetchReadmeFromJsdelivr(
packageName,
standardReadmeFilenames,
resolvedVersion,
)
if (jsdelivrReadme) {
readmeContent = jsdelivrReadme
}
}
if (!readmeContent || readmeContent === NPM_MISSING_README_SENTINEL) {
return {
packageName,
version,
markdown: undefined,
repoInfo: undefined,
}
}
const repoInfo = parseRepositoryInfo(packageData.repository)
return {
packageName,
version,
markdown: readmeContent,
repoInfo,
}
},
{
maxAge: CACHE_MAX_AGE_ONE_HOUR,
swr: true,
getKey: (packagePath: string) => packagePath,
},
)