UNPKG

@lokalise/api-contracts

Version:
83 lines (82 loc) 4.45 kB
import type { z } from 'zod/v4'; import type { HttpStatusCode, WildcardStatusCodeKey } from '../HttpStatusCodes.ts'; import { ContractNoBody } from './constants.ts'; export type ResponseOptions = { readonly description?: string; }; export type TypedTextResponse = { readonly _tag: 'TextResponse'; readonly contentType: string; readonly description?: string; }; export declare const textResponse: (contentType: string, options?: ResponseOptions) => TypedTextResponse; export declare const isTextResponse: (value: ApiContractResponse) => value is TypedTextResponse; export type TypedBlobResponse = { readonly _tag: 'BlobResponse'; readonly contentType: string; readonly description?: string; }; export declare const blobResponse: (contentType: string, options?: ResponseOptions) => TypedBlobResponse; export declare const isBlobResponse: (value: ApiContractResponse) => value is TypedBlobResponse; export type SseSchemaByEventName = Record<string, z.ZodType>; export type TypedSseResponse<T extends SseSchemaByEventName = SseSchemaByEventName> = { readonly _tag: 'SseResponse'; readonly schemaByEventName: T; readonly description?: string; }; export declare const sseResponse: <T extends SseSchemaByEventName>(schemaByEventName: T, options?: ResponseOptions) => TypedSseResponse<T>; export declare const isSseResponse: (value: ApiContractResponse) => value is TypedSseResponse; export type TypedJsonResponse = z.ZodType; export declare const isJsonResponse: (value: ApiContractResponse) => value is TypedJsonResponse; export type TypedApiContractResponse = TypedJsonResponse | TypedTextResponse | TypedBlobResponse | TypedSseResponse; export type AnyOfResponses<T extends TypedApiContractResponse = TypedApiContractResponse> = { readonly _tag: 'AnyOfResponses'; readonly responses: T[]; readonly description?: string; }; export declare const anyOfResponses: <T extends TypedApiContractResponse>(responses: T[], options?: ResponseOptions) => AnyOfResponses<T>; export declare const isAnyOfResponses: (value: ApiContractResponse) => value is AnyOfResponses; export type NoBodyResponse = { readonly _tag: 'NoBodyResponse'; readonly description?: string; }; export declare const noBodyResponse: (options?: ResponseOptions) => NoBodyResponse; export declare const isNoBodyResponse: (value: ApiContractResponse) => value is NoBodyResponse; export type ApiContractResponse = typeof ContractNoBody | NoBodyResponse | TypedApiContractResponse | AnyOfResponses; export type ResponsesByStatusCode = Partial<Record<HttpStatusCode | WildcardStatusCodeKey, ApiContractResponse>>; export type ResponseKind = { kind: 'noContent'; } | { kind: 'text'; } | { kind: 'blob'; } | { kind: 'json'; schema: z.ZodType; } | { kind: 'sse'; schemaByEventName: SseSchemaByEventName; }; /** * Resolves a contract's response entry for a given status code into a concrete `ResponseKind`, * taking the response `content-type` into account. * * Returns `null` when the content-type cannot be matched to any entry in the contract, * indicating the response is unexpected and should be treated as an error by the caller. * * @param schemaEntry - The contract entry for the matched status code (`ContractNoBody`, * a Zod schema, `textResponse`, `blobResponse`, `sseResponse`, or `anyOfResponses`). * @param contentType - The `content-type` header value from the actual HTTP response, * or `undefined` when the header is absent. * @param strict - When `true` (default), returns `null` if the `content-type` is absent or does * not match the contract entry. When `false`, falls back to the entry's declared kind instead of * returning `null` — only applies to single-entry responses; `anyOfResponses` always requires a * content-type to disambiguate regardless of this flag. */ export declare const resolveContractResponse: (schemaEntry: ApiContractResponse, contentType: string | undefined, strict?: boolean) => ResponseKind | null; /** * Combines status-code lookup and content-type resolution into a single call. * Lookup precedence: exact code → range key (e.g. `'4xx'`) → `'default'`. * Returns `null` when no entry matches or the content-type cannot be matched. */ export declare function resolveResponseEntry(responsesByStatusCode: ResponsesByStatusCode, statusCode: number, contentType: string | undefined, strictContentType: boolean): ResponseKind | null;