Skip to content

Commit 205c634

Browse files
committed
fix: last week version nitpicks
1 parent e65bf62 commit 205c634

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

server/api/registry/downloads/[...slug].get.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as v from 'valibot'
33
import { hash } from 'ohash'
44
import type { VersionDistributionResponse } from '#shared/types'
55
import { CACHE_MAX_AGE_ONE_HOUR } from '#shared/utils/constants'
6+
import { encodePackageName } from '#shared/utils/npm'
67
import { groupVersionDownloads } from '#server/utils/version-downloads'
78

89
/**
@@ -19,7 +20,13 @@ interface NpmVersionDownloadsResponse {
1920
*/
2021
const QuerySchema = v.object({
2122
mode: v.optional(v.picklist(['major', 'minor'] as const), 'major'),
22-
filterThreshold: v.optional(v.pipe(v.string(), v.transform(Number)), '1'),
23+
filterThreshold: v.optional(
24+
v.pipe(
25+
v.string(),
26+
v.toNumber(), // Fails validation on invalid conversion (e.g., "abc") instead of producing NaN
27+
v.minValue(0), // Ensure non-negative values
28+
),
29+
),
2330
filterOldVersions: v.optional(v.picklist(['true', 'false'] as const), 'false'),
2431
})
2532

@@ -40,7 +47,8 @@ export default defineCachedEventHandler(
4047
const slugParam = getRouterParam(event, 'slug')
4148
const pkgParamSegments = slugParam?.split('/') ?? []
4249

43-
if (pkgParamSegments[pkgParamSegments.length - 1] !== 'versions') {
50+
const lastSegment = pkgParamSegments.at(-1)
51+
if (!lastSegment || lastSegment !== 'versions') {
4452
throw createError({
4553
statusCode: 404,
4654
message: 'Invalid endpoint. Expected /versions',
@@ -59,11 +67,15 @@ export default defineCachedEventHandler(
5967
}
6068

6169
const query = getQuery(event)
62-
const { mode, filterThreshold, filterOldVersions } = v.parse(QuerySchema, query)
63-
const filterOldVersionsBool = filterOldVersions === 'true'
70+
const parsed = v.parse(QuerySchema, query)
71+
const mode = parsed.mode
72+
const filterThreshold = parsed.filterThreshold ?? 1
73+
const filterOldVersionsBool = parsed.filterOldVersions === 'true'
6474

6575
try {
66-
const url = `https://api.npmjs.org/versions/${rawPackageName}/last-week`
76+
// URL-encode package name for scoped packages (e.g., @types/node -> @types%2Fnode)
77+
const encodedPackageName = encodePackageName(rawPackageName)
78+
const url = `https://api.npmjs.org/versions/${encodedPackageName}/last-week`
6779
const npmResponse = await fetch(url)
6880

6981
if (!npmResponse.ok) {

0 commit comments

Comments
 (0)