Skip to content

Commit a51d1e7

Browse files
committed
fix: fetch org packages via existing server route
Org packages are fetched from the npm registry api (`/-/org/{org}/package`) in two places: 1. Server route `/api/registry/org/[org]/packages.get.ts`: - calls `$fetch('https://registry.npmjs.org/-/org/{org}/package')` 2. Client composable `useOrgPackages()`: calls `$npmRegistry('/-/org/{org}/package')` The composable bypasses the server route, duplicating the registry call, org name encoding, and error handling, and bypassing the important server-side caching. But most importantly, calls to the registry from the client fail with a CORS error, since the registry doesn't allow cross-origin requests from browsers.
1 parent 188e887 commit a51d1e7

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

app/composables/npm/useOrgPackages.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ export function useOrgPackages(orgName: MaybeRefOrGetter<string>) {
9292
// Get all package names in the org
9393
let packageNames: string[]
9494
try {
95-
const { data } = await $npmRegistry<Record<string, string>>(
96-
`/-/org/${encodeURIComponent(org)}/package`,
95+
const { packages } = await $fetch<{ packages: string[]; count: number }>(
96+
`/api/registry/org/${encodeURIComponent(org)}/packages`,
9797
{ signal },
9898
)
99-
packageNames = Object.keys(data)
99+
packageNames = packages
100100
} catch (err) {
101101
// Check if this is a 404 (org not found)
102102
if (err && typeof err === 'object' && 'statusCode' in err && err.statusCode === 404) {

server/api/registry/org/[org]/packages.get.ts

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { CACHE_MAX_AGE_ONE_HOUR } from '#shared/utils/constants'
2-
3-
const NPM_REGISTRY = 'https://registry.npmjs.org'
1+
import { CACHE_MAX_AGE_ONE_HOUR, NPM_REGISTRY } from '#shared/utils/constants'
2+
import { FetchError } from 'ofetch'
43

54
// Validation pattern for npm org names (alphanumeric with hyphens)
65
const NPM_ORG_NAME_RE = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i
@@ -37,8 +36,12 @@ export default defineCachedEventHandler(
3736
packages: Object.keys(data),
3837
count: Object.keys(data).length,
3938
}
40-
} catch {
41-
// Org doesn't exist or has no packages
39+
} catch (error) {
40+
// Let 404s propagate (org not found) so consumers can distinguish from empty
41+
if (error instanceof FetchError && error.statusCode === 404) {
42+
throw createError({ statusCode: 404, message: `Organization not found: ${org}` })
43+
}
44+
// For other errors (network, etc.), return empty
4245
return {
4346
packages: [],
4447
count: 0,

0 commit comments

Comments
 (0)