Skip to content

Commit 6a4aa00

Browse files
authored
fix: use jsdelivr when npm has a truncated readme (#1459)
1 parent bb0fd6f commit 6a4aa00

File tree

3 files changed

+37
-3
lines changed

3 files changed

+37
-3
lines changed

server/utils/readme-loaders.ts

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import * as v from 'valibot'
22
import { PackageRouteParamsSchema } from '#shared/schemas/package'
3-
import { CACHE_MAX_AGE_ONE_HOUR, NPM_MISSING_README_SENTINEL } from '#shared/utils/constants'
3+
import {
4+
CACHE_MAX_AGE_ONE_HOUR,
5+
NPM_MISSING_README_SENTINEL,
6+
NPM_README_TRUNCATION_THRESHOLD,
7+
} from '#shared/utils/constants'
48

59
/** Standard README filenames to try when fetching from jsdelivr (case-sensitive CDN) */
610
const standardReadmeFilenames = [
@@ -75,11 +79,16 @@ export const resolvePackageReadmeSource = defineCachedFunction(
7579

7680
const hasValidNpmReadme = readmeContent && readmeContent !== NPM_MISSING_README_SENTINEL
7781

78-
if (!hasValidNpmReadme || !isStandardReadme(readmeFilename)) {
82+
if (
83+
!hasValidNpmReadme ||
84+
!isStandardReadme(readmeFilename) ||
85+
readmeContent!.length >= NPM_README_TRUNCATION_THRESHOLD
86+
) {
87+
const resolvedVersion = version ?? packageData['dist-tags']?.latest
7988
const jsdelivrReadme = await fetchReadmeFromJsdelivr(
8089
packageName,
8190
standardReadmeFilenames,
82-
version,
91+
resolvedVersion,
8392
)
8493
if (jsdelivrReadme) {
8594
readmeContent = jsdelivrReadme

shared/utils/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export const ERROR_PACKAGE_REQUIREMENTS_FAILED =
2121
export const ERROR_FILE_LIST_FETCH_FAILED = 'Failed to fetch file list.'
2222
export const ERROR_CALC_INSTALL_SIZE_FAILED = 'Failed to calculate install size.'
2323
export const NPM_MISSING_README_SENTINEL = 'ERROR: No README data found!'
24+
/** The npm registry truncates the packument readme field at 65,536 characters (2^16) */
25+
export const NPM_README_TRUNCATION_THRESHOLD = 64_000
2426
export const ERROR_JSR_FETCH_FAILED = 'Failed to fetch package from JSR registry.'
2527
export const ERROR_NPM_FETCH_FAILED = 'Failed to fetch package from npm registry.'
2628
export const ERROR_PROVENANCE_FETCH_FAILED = 'Failed to fetch provenance.'

test/unit/server/utils/readme-loaders.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,29 @@ describe('resolvePackageReadmeSource', () => {
214214
})
215215
})
216216

217+
it('fetches from jsdelivr when packument readme exceeds truncation threshold', async () => {
218+
const truncatedReadme = 'x'.repeat(64_000)
219+
const fullReadme = 'x'.repeat(80_000)
220+
fetchNpmPackageMock.mockResolvedValue({
221+
'readme': truncatedReadme,
222+
'readmeFilename': 'README.md',
223+
'repository': undefined,
224+
'versions': {},
225+
'dist-tags': { latest: '1.0.0' },
226+
})
227+
parseRepositoryInfoMock.mockReturnValue(undefined)
228+
const fetchMock = vi.fn().mockResolvedValue({
229+
ok: true,
230+
text: async () => fullReadme,
231+
})
232+
vi.stubGlobal('fetch', fetchMock)
233+
234+
const result = await resolvePackageReadmeSource('pkg')
235+
236+
expect(result).toMatchObject({ markdown: fullReadme })
237+
expect(fetchMock).toHaveBeenCalled()
238+
})
239+
217240
it('uses package repository for repoInfo when markdown is present', async () => {
218241
fetchNpmPackageMock.mockResolvedValue({
219242
readme: '# Hi',

0 commit comments

Comments
 (0)