Skip to content

src/rate-limit.ts

48 lines · 1.6 KB · TypeScript
Raw
import { originRequest } from './request.ts'
import { type OriginRateLimit } from './types.ts'

/**
 * Read Origin API rate-limit remaining using an app JWT (no installation token).
 *
 * Cheap smoke test that the Origin App private key and app id are configured.
 *
 * @returns `{ limit, remaining, used, reset }` from the Origin `rate_limit` resource.
 * @example
 * import getOriginRateLimit from 'kody:@kentcdodds/origin/rate-limit'
 * const rate = await getOriginRateLimit()
 * // => { limit: 5000, remaining: 4999, used: 1, reset: 1756400000 }
 */
export async function getOriginRateLimit(): Promise<OriginRateLimit> {
	const result = await originRequest({
		path: '/rate_limit',
		auth: 'app',
	})
	if (!result.ok) {
		const message =
			isRecord(result.body) && typeof result.body.message === 'string'
				? result.body.message
				: `HTTP ${String(result.status)}`
		throw new Error(`Origin rate_limit failed: ${message}`)
	}
	const payload = isRecord(result.body) ? result.body : {}
	const core = isRecord(payload.resources)
		? payload.resources.core
		: payload.rate
	const fields = isRecord(core) ? core : {}
	return {
		limit: numberField(fields.limit),
		remaining: numberField(fields.remaining),
		used: numberField(fields.used),
		reset: numberField(fields.reset),
	}
}

export default getOriginRateLimit

function isRecord(value: unknown): value is Record<string, unknown> {
	return value !== null && typeof value === 'object' && !Array.isArray(value)
}

function numberField(value: unknown): number | null {
	return typeof value === 'number' && Number.isFinite(value) ? value : null
}