import type { z } from 'zod/v4'; import type { SuccessfulHttpStatusCode } from '../HttpStatusCodes.ts'; import type { ValueOf } from '../typeUtils.ts'; import type { ContractNoBody } from './constants.ts'; import type { ResponsesByStatusCode } from './contractResponse.ts'; type ExtractSuccessResponses = ValueOf>; /** * Returns true if all success responses have no body (ContractNoBody or no success status codes defined). */ export type IsNoBodySuccessResponse = [ ExtractSuccessResponses ] extends [typeof ContractNoBody | undefined] ? true : false; type UnpackAnyOf = T extends { _tag: 'AnyOfResponses'; responses: Array; } ? Item : T; type FlatSuccessResponses = UnpackAnyOf>; type SseSchemaOf = T extends { _tag: 'SseResponse'; schemaByEventName: infer S; } ? S : never; /** * Extracts the merged SSE event schema map from a responsesByStatusCode map. * Returns the union of all `schemaByEventName` objects from TypedSseResponse entries, * including those nested inside AnyOfResponses. */ export type InferSseSuccessResponses = SseSchemaOf>; /** * Returns true if any success status code entry is a JSON Zod schema, * or an AnyOfResponses containing one. */ export type HasAnyJsonSuccessResponse = Extract, z.ZodType> extends never ? false : true; type JsonSchemaOf = T extends z.ZodType ? T : never; /** * Extracts the union of JSON Zod schemas from all success responses, * including those nested inside AnyOfResponses. Text, Blob, and SSE responses are excluded. */ export type InferJsonSuccessResponses = JsonSchemaOf>; type NonSseBodyOf = T extends { _tag: 'SseResponse'; } ? never : T extends { _tag: 'BlobResponse'; } ? Blob : T extends { _tag: 'TextResponse'; } ? string : T extends z.ZodType ? z.output : undefined; /** * Infers the TypeScript output type of all non-SSE success responses. * JSON schemas → z.output. TextResponse → string. BlobResponse → Blob. * ContractNoBody → undefined. SseResponse → never (excluded). * AnyOfResponses are unpacked before mapping. */ export type InferNonSseSuccessResponses = NonSseBodyOf>; /** * Discriminated union of SSE events inferred from a schemaByEventName map. * Aligns with the browser MessageEvent shape. */ export type SseEventOf = { [K in keyof S]: K extends string ? { type: K; data: S[K] extends z.ZodType ? z.output : never; lastEventId: string; retry: number | undefined; } : never; }[keyof S]; /** * Returns true if any success status code entry is TypedSseResponse, * or an AnyOfResponses containing a TypedSseResponse. */ export type HasAnySseSuccessResponse = Extract, { _tag: 'SseResponse'; }> extends never ? false : true; /** * Returns true if any success status code entry has a non-SSE response * (JSON, text, blob, or no-body). Mirrors HasAnySseSuccessResponse. */ export type HasAnyNonSseSuccessResponse = Exclude, { _tag: 'SseResponse'; }> extends never ? false : true; /** * Classifies a contract's response mode into one of three cases: * - 'dual' — SSE + non-SSE success responses; caller chooses via streaming param * - 'sse' — SSE-only success responses; always streams * - 'non-sse' — JSON / text / blob / no-body; never streams */ export type ContractResponseMode = HasAnySseSuccessResponse extends true ? HasAnyNonSseSuccessResponse extends true ? 'dual' : 'sse' : 'non-sse'; /** * Union of response mode literals available for a given responsesByStatusCode map. */ export type AvailableResponseModes = (HasAnyJsonSuccessResponse extends true ? 'json' : never) | (HasAnySseSuccessResponse extends true ? 'sse' : never) | (Extract, { _tag: 'BlobResponse'; }> extends never ? never : 'blob') | (Extract, { _tag: 'TextResponse'; }> extends never ? never : 'text') | (Extract, typeof ContractNoBody> extends never ? never : 'noContent'); export {};