@@ -6,26 +6,32 @@ import {
66 ERROR_NPM_FETCH_FAILED ,
77} from '#shared/utils/constants'
88
9+ /** Standard README filenames to try when fetching from jsdelivr (case-sensitive CDN) */
10+ const standardReadmeFilenames = [
11+ 'README.md' ,
12+ 'readme.md' ,
13+ 'Readme.md' ,
14+ 'README' ,
15+ 'readme' ,
16+ 'README.markdown' ,
17+ 'readme.markdown' ,
18+ ]
19+
20+ /** Matches standard README filenames (case-insensitive, for checking registry metadata) */
21+ const standardReadmePattern = / ^ r e a d m e ( \. m d | \. m a r k d o w n ) ? $ / i
22+
923/**
1024 * Fetch README from jsdelivr CDN for a specific package version.
1125 * Falls back through common README filenames.
1226 */
1327async function fetchReadmeFromJsdelivr (
1428 packageName : string ,
29+ readmeFilenames : string [ ] ,
1530 version ?: string ,
1631) : Promise < string | null > {
17- const filenames = [
18- 'README.md' ,
19- 'readme.md' ,
20- 'Readme.md' ,
21- 'README' ,
22- 'readme' ,
23- 'README.markdown' ,
24- 'readme.markdown' ,
25- ]
2632 const versionSuffix = version ? `@${ version } ` : ''
2733
28- for ( const filename of filenames ) {
34+ for ( const filename of readmeFilenames ) {
2935 try {
3036 const url = `https://cdn.jsdelivr.net/npm/${ packageName } ${ versionSuffix } /${ filename } `
3137 const response = await fetch ( url )
@@ -67,24 +73,40 @@ export default defineCachedEventHandler(
6773 const packageData = await fetchNpmPackage ( packageName )
6874
6975 let readmeContent : string | undefined
76+ let readmeFilename : string | undefined
7077
7178 // If a specific version is requested, get README from that version
7279 if ( version ) {
7380 const versionData = packageData . versions [ version ]
7481 if ( versionData ) {
7582 readmeContent = versionData . readme
83+ readmeFilename = versionData . readmeFilename
7684 }
7785 } else {
7886 // Use the packument-level readme (from latest version)
7987 readmeContent = packageData . readme
88+ readmeFilename = packageData . readmeFilename
8089 }
8190
82- // If no README in packument, try fetching from jsdelivr (package tarball)
83- if ( ! readmeContent || readmeContent === NPM_MISSING_README_SENTINEL ) {
84- readmeContent = ( await fetchReadmeFromJsdelivr ( packageName , version ) ) ?? undefined
91+ const hasValidNpmReadme = readmeContent && readmeContent !== NPM_MISSING_README_SENTINEL
92+
93+ // If no README in packument, or if readmeFilename is non-standard (e.g., README.zh-TW.md),
94+ // try fetching a standard README from jsdelivr (package tarball).
95+ // Note: When readmeFilename is missing, we defensively fetch from jsdelivr to ensure
96+ // we get a standard English README if one exists.
97+ if ( ! hasValidNpmReadme || ! isStandardReadme ( readmeFilename ) ) {
98+ const jsdelivrReadme = await fetchReadmeFromJsdelivr (
99+ packageName ,
100+ standardReadmeFilenames ,
101+ version ,
102+ )
103+ // Only replace npm content if jsdelivr returned something
104+ if ( jsdelivrReadme ) {
105+ readmeContent = jsdelivrReadme
106+ }
85107 }
86108
87- if ( ! readmeContent ) {
109+ if ( ! readmeContent || readmeContent === NPM_MISSING_README_SENTINEL ) {
88110 return { html : '' , playgroundLinks : [ ] }
89111 }
90112
@@ -108,3 +130,7 @@ export default defineCachedEventHandler(
108130 } ,
109131 } ,
110132)
133+
134+ function isStandardReadme ( filename : string | undefined ) : boolean {
135+ return ! ! filename && standardReadmePattern . test ( filename )
136+ }
0 commit comments