type HTTPStatusCode = 
/** CONTINUE */
100
/** SWITCHING_PROTOCOLS */
 | 101
/** PROCESSING */
 | 102
/** EARLY_HINTS */
 | 103
/** OK */
 | 200
/** CREATED */
 | 201
/** ACCEPTED */
 | 202
/** NON_AUTHORITATIVE_INFORMATION */
 | 203
/** NO_CONTENT */
 | 204
/** RESET_CONTENT */
 | 205
/** PARTIAL_CONTENT */
 | 206
/** MULTI_STATUS */
 | 207
/** MULTIPLE_CHOICES */
 | 300
/** MOVED_PERMANENTLY */
 | 301
/** MOVED_TEMPORARILY */
 | 302
/** SEE_OTHER */
 | 303
/** NOT_MODIFIED */
 | 304
/** USE_PROXY */
 | 305
/** TEMPORARY_REDIRECT */
 | 307
/** PERMANENT_REDIRECT */
 | 308
/** BAD_REQUEST */
 | 400
/** UNAUTHORIZED */
 | 401
/** PAYMENT_REQUIRED */
 | 402
/** FORBIDDEN */
 | 403
/** NOT_FOUND */
 | 404
/** METHOD_NOT_ALLOWED */
 | 405
/** NOT_ACCEPTABLE */
 | 406
/** PROXY_AUTHENTICATION_REQUIRED */
 | 407
/** REQUEST_TIMEOUT */
 | 408
/** CONFLICT */
 | 409
/** GONE */
 | 410
/** LENGTH_REQUIRED */
 | 411
/** PRECONDITION_FAILED */
 | 412
/** REQUEST_TOO_LONG */
 | 413
/** REQUEST_URI_TOO_LONG */
 | 414
/** UNSUPPORTED_MEDIA_TYPE */
 | 415
/** REQUESTED_RANGE_NOT_SATISFIABLE */
 | 416
/** EXPECTATION_FAILED */
 | 417
/** IM_A_TEAPOT */
 | 418
/** INSUFFICIENT_SPACE_ON_RESOURCE */
 | 419
/** METHOD_FAILURE */
 | 420
/** MISDIRECTED_REQUEST */
 | 421
/** UNPROCESSABLE_ENTITY */
 | 422
/** LOCKED */
 | 423
/** FAILED_DEPENDENCY */
 | 424
/** UPGRADE_REQUIRED */
 | 426
/** PRECONDITION_REQUIRED */
 | 428
/** TOO_MANY_REQUESTS */
 | 429
/** REQUEST_HEADER_FIELDS_TOO_LARGE */
 | 431
/** UNAVAILABLE_FOR_LEGAL_REASONS */
 | 451
/** INTERNAL_SERVER_ERROR */
 | 500
/** NOT_IMPLEMENTED */
 | 501
/** BAD_GATEWAY */
 | 502
/** SERVICE_UNAVAILABLE */
 | 503
/** GATEWAY_TIMEOUT */
 | 504
/** HTTP_VERSION_NOT_SUPPORTED */
 | 505
/** INSUFFICIENT_STORAGE */
 | 507
/** NETWORK_AUTHENTICATION_REQUIRED */
 | 511;

type HTTPMethod = "get" | "put" | "post" | "delete" | "options" | "head" | "patch" | "trace";
type RouteFor<TPaths, TPath extends keyof TPaths, TMethod extends HTTPMethod> = TMethod extends keyof TPaths[TPath] ? Extract<NonNullable<TPaths[TPath][TMethod]>, AnyRoute> : never;
type EmptyParameters = {
    query?: never;
    header?: never;
    path?: never;
    cookie?: never;
};
type RouteParameters<TParameters> = [Extract<TParameters, AnyParameters>] extends [
    never
] ? EmptyParameters : Extract<TParameters, AnyParameters>;
type PathMethods<TPaths, TPath extends keyof TPaths> = {
    [TMethod in HTTPMethod]: [RouteFor<TPaths, TPath, TMethod>] extends [never] ? never : TMethod;
}[HTTPMethod];
type AnyRequestBody = {
    content: Record<string, any>;
};
type AnyResponses = Record<number, {
    content?: Record<string, any>;
    headers?: Record<string, any>;
}>;
type AnyParameters = {
    query?: Record<string, any>;
    header?: Record<string, any>;
    path?: Record<string, any>;
    cookie?: Record<string, any>;
};
type AnyRoute = {
    responses: AnyResponses;
    requestBody?: AnyRequestBody;
    parameters?: AnyParameters;
};
type Prettify<T> = {
    [K in keyof T]: T[K];
} & {};
/**
 * ApiResponse is a utility type that infers the possible response shapes for an OpenAPI route.
 *
 * Given a set of possible HTTP responses (TResponses), it produces a union type representing
 * all possible response objects, including status, content type, data, and headers.
 *
 * For each status code (TStatus) in TResponses:
 *   - If TResponses[TStatus]['content'] is undefined (i.e., no content for this status):
 *       - The response object has:
 *           - status: the status code
 *           - contentType: never
 *           - data: never
 *           - headers: either a Map of header keys/values (if headers are a record), or the headers as-is
 *   - If TResponses[TStatus]['content'] is defined:
 *       - For each content type K in the content object:
 *           - The response object has:
 *               - status: the status code
 *               - contentType: K (the MIME type)
 *               - data: the data for that content type
 *               - headers: either a Map of header keys/values (if headers are a record), or the headers as-is
 *
 * The final type is a union of all possible response objects for all status codes and content types.
 */
type ApiResponse<TResponses extends AnyResponses> = {
    [TStatus in keyof TResponses]: TStatus extends number ? TResponses[TStatus]["content"] extends undefined ? {
        status: TStatus;
        contentType: never;
        data: never;
        headers: TResponses[TStatus]["headers"] extends Record<string, unknown> ? Map<keyof TResponses[TStatus]["headers"], TResponses[TStatus]["headers"][keyof TResponses[TStatus]["headers"]]> : TResponses[TStatus]["headers"];
    } : {
        [K in keyof TResponses[TStatus]["content"]]: {
            status: TStatus;
            contentType: K;
            data: TResponses[TStatus]["content"][K];
            headers: TResponses[TStatus]["headers"] extends Record<string, unknown> ? Map<keyof TResponses[TStatus]["headers"], TResponses[TStatus]["headers"][keyof TResponses[TStatus]["headers"]]> : TResponses[TStatus]["headers"];
        };
    }[keyof TResponses[TStatus]["content"]] : never;
}[keyof TResponses] | UnknownApiResponse<keyof TResponses>;
type ExcludedStatusCodes<TStatus> = Exclude<HTTPStatusCode, TStatus> & {};
type UnknownApiResponse<TStatus> = {
    status: ExcludedStatusCodes<TStatus>;
    contentType?: string;
    data?: unknown;
    headers?: Headers;
};
type AnyApiResponse = {
    status: number;
    contentType?: string;
    data?: unknown;
    headers?: Headers;
};
type NoRequestBody = {
    contentType?: undefined;
    data?: undefined;
};
type RequestBodyContentType<TBody extends AnyRequestBody | undefined> = Extract<keyof Extract<TBody, AnyRequestBody>["content"], string>;
type ApiRequestBody<TBody extends AnyRequestBody | undefined> = [
    Extract<TBody, AnyRequestBody>
] extends [never] ? NoRequestBody : {
    [K in RequestBodyContentType<TBody>]: {
        contentType: K;
        data: Extract<TBody, AnyRequestBody>["content"][K];
    };
}[RequestBodyContentType<TBody>];
type HeaderObject = Record<string, string>;
type HeaderPredicate = () => PromiseLike<HeaderObject>;
type OpenApiHookOptions = {
    baseUrl: URL | string;
    headers?: HeaderObject | HeaderPredicate;
    onError?: (error: ApiError) => void;
    fetch?: typeof fetch;
    decodeResponse?: (response: Response, responseContentType: string | null) => Promise<AnyApiResponse>;
    encodeBody?: (data: any, contentType: string | undefined) => BodyInit | undefined;
};
/**
 * FetchOptions is a type that represents the options for the fetch function.
 * It can be a RequestInit object or a function that takes a base RequestInit object and returns a RequestInit object.
 * The function is useful for adding additional headers or other properties to the request or modifying properties.
 */
type FetchOptions = RequestInit | ((base: Pick<RequestInit, "body" | "headers" | "method" | "mode">) => RequestInit);
declare class ApiError extends Error {
    status: number;
    response?: Response | undefined;
    data?: unknown | undefined;
    constructor(message: string, status: number, response?: Response | undefined, data?: unknown | undefined);
    static fromResponse(response: Response, data?: unknown): ApiError;
    static fromNetworkError(error: Error): ApiError;
}
type OptionsFor<TRoute extends AnyRoute> = RouteParameters<TRoute["parameters"]> & ApiRequestBody<TRoute["requestBody"]> & {
    fetchOptions?: FetchOptions;
};
declare const createFetch: <paths extends object>(options?: OpenApiHookOptions) => <TPath extends keyof paths & string, TMethod extends PathMethods<paths, TPath>, TRoute extends AnyRoute = RouteFor<paths, TPath, TMethod>, TOptions extends OptionsFor<TRoute> = OptionsFor<TRoute>>(path: TPath, method: TMethod, options: TOptions) => Promise<Prettify<ApiResponse<TRoute["responses"]>>>;

export { type AnyApiResponse, ApiError, type ApiRequestBody, type ApiResponse, type FetchOptions, type HeaderObject, type HeaderPredicate, type OpenApiHookOptions, type OptionsFor, type PathMethods, createFetch };
