← Public packages
@kody/integrations-sh
Client for the public integrations.sh registry: search, detect, cached surface, and live discover.
src/client.ts
68 lines · 1.6 KB · TypeScriptimport {
BoundedBodyTooLargeError,
readBoundedBody,
} from './bounded-body.ts'
import { getErrorMessage } from './error-message.ts'
const DEFAULT_MAX_BODY_BYTES = 500_000
export type RegistryFetchResult =
| { outcome: 'success'; status: number; json: unknown }
| { outcome: 'not-found'; status: 404 }
| { outcome: 'failure'; status: number | null; message: string }
export async function fetchRegistryJson(
url: string,
timeoutMs: number,
maxBytes = DEFAULT_MAX_BODY_BYTES,
): Promise<RegistryFetchResult> {
let response: Response
try {
response = await fetch(url, {
headers: { Accept: 'application/json' },
redirect: 'follow',
signal: AbortSignal.timeout(timeoutMs),
})
} catch (cause) {
return { outcome: 'failure', status: null, message: getErrorMessage(cause) }
}
if (response.status === 404) {
return { outcome: 'not-found', status: 404 }
}
let body: string
try {
body = await readBoundedBody(response, maxBytes)
} catch (cause) {
if (cause instanceof BoundedBodyTooLargeError) {
return { outcome: 'failure', status: response.status, message: cause.message }
}
return {
outcome: 'failure',
status: response.status,
message: getErrorMessage(cause),
}
}
let parsed: unknown
try {
parsed = JSON.parse(body)
} catch (cause) {
return {
outcome: 'failure',
status: response.status,
message: `invalid JSON (${getErrorMessage(cause)})`,
}
}
if (!response.ok) {
return {
outcome: 'failure',
status: response.status,
message: `HTTP ${response.status} for ${url}`,
}
}
return { outcome: 'success', status: response.status, json: parsed }
}