/** * The envelope every endpoint answers with, the error codes it carries, the * shape of a paginated list, and {@link Wire}, which maps a type to what JSON * makes of it. * * @module */ /** The error codes an {@link APIError} carries, by name. */ export const APIErrorCode = { /** The request is malformed or not allowed in the current state. */ BAD_REQUEST: "BAD_REQUEST", /** What the request names doesn't exist, or the caller may not see it. */ NOT_FOUND: "NOT_FOUND", /** The server failed. */ SERVER_ERROR: "SERVER_ERROR", /** A remote site took too long to answer. */ TIMEOUT: "TIMEOUT", /** The caller isn't signed in, or may not do this. */ UNAUTHORIZED: "UNAUTHORIZED", /** The request body failed validation. */ VALIDATION_ERROR: "VALIDATION_ERROR", } as const; /** One of the {@link APIErrorCode} values. */ export type APIErrorCode = typeof APIErrorCode[keyof typeof APIErrorCode]; /** What went wrong, in a failed response. */ export interface APIError { /** The kind of failure. */ code: APIErrorCode; /** A human-readable explanation. */ message: string; } /** A successful response, carrying its payload. */ export interface APISuccess { /** Always true. */ success: true; /** The payload. */ data: T; /** Never set on success. */ error?: never; } /** A failed response, carrying its error. */ export interface APIFailure { /** Always false. */ success: false; /** Never set on failure. */ data?: never; /** What went wrong. */ error: APIError; } /** What every endpoint answers with, narrowed by `success`. */ export type APIResponse = APISuccess | APIFailure; /** One page of a list. */ export interface PaginatedData { /** The page's items. */ items: T[]; /** Whether another page follows. */ hasMore: boolean; /** The whole list's size — only where it's shown (search results). */ total?: number; } /** * `T` as it arrives over JSON (HTTP, the socket, localStorage): every Date is * an ISO string. */ export type Wire = T extends Date ? string : T extends readonly (infer U)[] ? Wire[] : T extends object ? { [K in keyof T]: Wire } : T;