UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

69 lines (62 loc) 1.84 kB
import type { HttpContractConfig } from "./types.js"; type Digit = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; type ToNumber<S extends string> = S extends `${infer N extends number}` ? N : never; type Any2xxCode = ToNumber<`2${Digit}${Digit}`>; type NumericKey<K> = K extends number ? K : K extends `${infer N extends number}` ? N : never; type UnionToIntersection<T> = ( T extends unknown ? (value: T) => void : never ) extends (value: infer I) => void ? I : never; /** * All declared 2xx status codes from a contract `responses` record, as * numeric literal keys. */ export type Success2xxKeys<TResponses extends object> = { [K in keyof TResponses]: NumericKey<K> extends Any2xxCode ? NumericKey<K> : never; }[keyof TResponses]; /** * Whether a contract `responses` record declares exactly one 2xx status. */ export type IsSingle2xx<TResponses extends object> = [ Success2xxKeys<TResponses>, ] extends [never] ? false : [Success2xxKeys<TResponses>] extends [ UnionToIntersection<Success2xxKeys<TResponses>>, ] ? true : false; /** * List the declared 2xx statuses of a contract at runtime. */ export function getSuccess2xxStatuses( contract: Pick<HttpContractConfig, "responses">, ): number[] { return Object.keys(contract.responses) .map((status) => Number(status)) .filter( (status) => Number.isInteger(status) && status >= 200 && status < 300, ) .sort((a, b) => a - b); } /** * Resolve the sole declared 2xx status of a contract, or `undefined` when the * contract declares zero or multiple 2xx statuses. */ export function inferSoleSuccessStatus( contract: Pick<HttpContractConfig, "responses">, ): number | undefined { const statuses = getSuccess2xxStatuses(contract); return statuses.length === 1 ? statuses[0] : undefined; }