@zimic/fetch
Version:
Next-gen TypeScript-first Fetch client
406 lines (394 loc) • 30 kB
TypeScript
import { HttpSchema, HttpSchemaMethod, HttpSchemaPath, HttpMethodSchema, HttpHeadersSchema, HttpHeadersInit, HttpRequestHeadersSchema, HttpSearchParamsSchema, HttpSearchParamsInit, HttpRequestSearchParamsSchema, HttpBody, HttpRequestSchema, HttpSearchParams, HttpFormData, HttpHeadersSerialized, HttpRequest, HttpRequestBodySchema, AllowAnyStringInPathParams, HttpMethod, LiteralHttpSchemaPathFromNonLiteral, HttpStatusCode, HttpResponseSchemaStatusCode, HttpResponseSchema, HttpResponseHeadersSchema, HttpResponse, HttpResponseBodySchema } from '@zimic/http';
type JSON = {
[key: string]: JSON;
} | JSON[] | string | number | boolean | null | undefined;
declare namespace JSON {
type Loose = Record<string, any> | Loose[] | string | number | boolean | null | undefined;
}
/**
* Represents or validates a type that is compatible with JSON.
*
* **IMPORTANT**: the input of `JSONValue` and all of its internal types must be declared inline or as a type aliases
* (`type`). They cannot be interfaces.
*
* @example
* import { type JSONValue } from '@zimic/http';
*
* // Can be used as a standalone type:
* const value: JSONValue = {
* name: 'example',
* tags: ['one', 'two'],
* };
*
* @example
* import { type JSONValue } from '@zimic/http';
*
* // Can be used with a type argument to validate a JSON value:
* type ValidJSON = JSONValue<{
* id: string;
* email: string;
* createdAt: string;
* }>;
*
* // This results in a type error:
* type InvalidJSON = JSONValue<{
* id: string;
* email: string;
* createdAt: Date; // `Date` is not a valid JSON value.
* save: () => Promise<void>; // Functions are not valid JSON values.
* }>;
*/
type JSONValue<Type extends JSON = JSON> = Type;
declare namespace JSONValue {
/** A loose version of the JSON value type. JSON objects are not strictly typed. */
type Loose<Type extends JSON.Loose = JSON.Loose> = Type;
}
/**
* Recursively converts a type to its JSON-serialized version. Dates are converted to strings and keys with non-JSON
* values are excluded.
*
* @example
* import { type JSONSerialized } from '@zimic/http';
*
* type SerializedUser = JSONSerialized<{
* id: string;
* email: string;
* createdAt: Date;
* save: () => Promise<void>;
* }>;
* // {
* // id: string;
* // email: string;
* // createdAt: string;
* // }
*/
type JSONSerialized<Type> = Type extends JSONValue ? Type : Type extends Date ? string : Type extends (...parameters: never[]) => unknown ? never : Type extends symbol ? never : Type extends Map<infer _Key, infer _Value> ? Record<string, never> : Type extends Set<infer _Value> ? Record<string, never> : Type extends (infer ArrayItem)[] ? JSONSerialized<ArrayItem>[] : Type extends object ? {
[Key in keyof Type as [JSONSerialized<Type[Key]>] extends [never] ? never : Key]: JSONSerialized<Type[Key]>;
} : never;
declare global {
interface JSON {
readonly value: unique symbol;
stringify<Value>(value: Value, replacer?: ((this: any, key: string, value: Value) => any) | (number | string)[] | null, space?: string | number): JSONStringified<Value>;
parse<Value>(text: JSONStringified<Value>, reviver?: (this: any, key: string, value: any) => any): JSONSerialized<Value>;
}
}
type JSONStringified<Value> = string & {
[JSON.value]: JSONSerialized<Value>;
};
type Default<Type, IfEmpty = never> = [undefined | void] extends [Type] ? IfEmpty : Exclude<Type, undefined | void>;
type PossiblePromise<Type> = Type | PromiseLike<Type>;
/** Converts a union type to an intersection type. For example, `A | B` becomes `A & B`. */
type UnionToIntersection<Union> = (Union extends unknown ? (union: Union) => void : never) extends (intersectedUnion: infer IntersectedUnion) => void ? IntersectedUnion : never;
/**
* Extracts the values of a specific key from a union of types. If the key does not exist in a type within the union, it
* evaluates to `never` for that type.
*/
type IndexUnion<Union, Key> = Union extends Union ? (Key extends keyof Union ? Union[Key] : never) : never;
type RequiredByKey<Type, Key extends keyof Type> = Omit<Type, Key> & Required<Pick<Type, Key>>;
type FetchRequestInitWithHeaders<HeadersSchema extends HttpHeadersSchema | undefined> = [HeadersSchema] extends [
never
] ? {
headers?: undefined;
} : undefined extends HeadersSchema ? {
headers?: HttpHeadersInit<Default<HeadersSchema>>;
} : {
headers: HttpHeadersInit<Default<HeadersSchema>>;
};
type FetchRequestInitWithSearchParams<SearchParamsSchema extends HttpSearchParamsSchema | undefined> = [
SearchParamsSchema
] extends [never] ? {
searchParams?: undefined;
} : undefined extends SearchParamsSchema ? {
searchParams?: HttpSearchParamsInit<Default<SearchParamsSchema>>;
} : {
searchParams: HttpSearchParamsInit<Default<SearchParamsSchema>>;
};
type FetchRequestBodySchema<RequestSchema extends HttpRequestSchema> = 'body' extends keyof RequestSchema ? [RequestSchema['body']] extends [never] ? null | undefined : [Extract<RequestSchema['body'], BodyInit | HttpSearchParams | HttpFormData>] extends [never] ? undefined extends RequestSchema['body'] ? JSONStringified<Exclude<RequestSchema['body'], null | undefined>> | null | undefined : JSONStringified<Exclude<RequestSchema['body'], null>> | Extract<RequestSchema['body'], null> : undefined extends RequestSchema['body'] ? RequestSchema['body'] : RequestSchema['body'] : null | undefined;
type FetchRequestInitWithBody<BodySchema extends HttpBody> = [BodySchema] extends [never] ? {
body?: BodySchema;
} : undefined extends BodySchema ? {
body?: BodySchema;
} : {
body: BodySchema;
};
type FetchRequestInitPerPath<MethodSchema extends HttpMethodSchema> = FetchRequestInitWithHeaders<HttpRequestHeadersSchema<MethodSchema>> & FetchRequestInitWithSearchParams<HttpRequestSearchParamsSchema<MethodSchema>> & FetchRequestInitWithBody<FetchRequestBodySchema<Default<MethodSchema['request']>>>;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch `fetch` API reference} */
type FetchRequestInit<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath<Schema, Method>, Redirect extends RequestRedirect = 'follow'> = Omit<RequestInit, 'method' | 'headers' | 'body'> & {
method: Method;
baseURL?: string;
redirect?: Redirect;
duplex?: 'half';
} & (Path extends Path ? FetchRequestInitPerPath<Default<Schema[Path][Method]>> : never);
declare namespace FetchRequestInit {
type DefaultHeadersSchema<Schema extends HttpSchema> = {
[Path in HttpSchemaPath.Literal<Schema>]: {
[Method in keyof Schema[Path]]: HttpRequestHeadersSchema<Default<Schema[Path][Method]>>;
}[keyof Schema[Path]];
}[HttpSchemaPath.Literal<Schema>];
export type DefaultHeaders<Schema extends HttpSchema> = {
[HeaderName in keyof UnionToIntersection<Default<DefaultHeadersSchema<Schema>>>]?: IndexUnion<DefaultHeadersSchema<Schema>, HeaderName>;
};
type DefaultSearchParamsSchema<Schema extends HttpSchema> = {
[Path in HttpSchemaPath.Literal<Schema>]: {
[Method in keyof Schema[Path]]: HttpRequestSearchParamsSchema<Default<Schema[Path][Method]>>;
}[keyof Schema[Path]];
}[HttpSchemaPath.Literal<Schema>];
export type DefaultSearchParams<Schema extends HttpSchema> = {
[SearchParamName in keyof UnionToIntersection<Default<DefaultSearchParamsSchema<Schema>>>]?: IndexUnion<DefaultSearchParamsSchema<Schema>, SearchParamName>;
};
export type DefaultBody<Schema extends HttpSchema> = {
[Path in HttpSchemaPath.Literal<Schema>]: {
[Method in keyof Schema[Path]]: FetchRequestBodySchema<Default<Schema[Path][Method]> extends HttpMethodSchema ? Default<Default<Schema[Path][Method]>['request']> : never>;
}[keyof Schema[Path]];
}[HttpSchemaPath.Literal<Schema>];
/** @see {@link https://zimic.dev/docs/fetch/api/fetch#fetch-defaults `fetch` defaults API reference} */
export interface Defaults<Schema extends HttpSchema = HttpSchema> extends Omit<RequestInit, 'headers' | 'body'> {
baseURL: string;
headers?: DefaultHeaders<Schema>;
searchParams?: DefaultSearchParams<Schema>;
body?: DefaultBody<Schema>;
duplex?: 'half';
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch `fetch` API reference} */
export type Loose = Partial<Defaults>;
export { };
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-request#requesttoobject `request.toObject()` API reference} */
interface FetchRequestObjectOptions {
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-request#requesttoobject `request.toObject()` API reference} */
includeBody?: boolean;
}
declare namespace FetchRequestObjectOptions {
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-request#requesttoobject `request.toObject()` API reference} */
interface WithBody {
includeBody: true;
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-request#requesttoobject `request.toObject()` API reference} */
interface WithoutBody {
includeBody?: false;
}
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-request#requesttoobject `request.toObject()`} */
type FetchRequestObject = Pick<FetchRequest.Loose, 'url' | 'path' | 'method' | 'cache' | 'destination' | 'credentials' | 'integrity' | 'keepalive' | 'mode' | 'redirect' | 'referrer' | 'referrerPolicy'> & {
headers: HttpHeadersSerialized<HttpHeadersSchema>;
body?: HttpBody | null;
};
interface FetchRequestClass {
new <Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>>(fetch: Fetch<Schema>, input: FetchInput<Schema, Method, Path>, init?: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>): FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
prototype: Request;
[Symbol.hasInstance]: (instance: unknown) => instance is FetchRequest<any, any, any>;
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-request `FetchRequest` API reference} */
interface FetchRequest<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>> extends HttpRequest<HttpRequestBodySchema<Default<Schema[Path][Method]>>, Default<HttpRequestHeadersSchema<Default<Schema[Path][Method]>>>> {
raw: Request;
path: AllowAnyStringInPathParams<Path>;
method: Method;
clone: () => FetchRequest<Schema, Method, Path>;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-request#requesttoobject `request.toObject()` API reference} */
toObject: ((options: FetchRequestObjectOptions.WithBody) => Promise<FetchRequestObject>) & ((options?: FetchRequestObjectOptions.WithoutBody) => FetchRequestObject) & ((options?: FetchRequestObjectOptions) => PossiblePromise<FetchRequestObject>);
}
declare namespace FetchRequest {
/** A loosely typed version of a {@link FetchRequest `FetchRequest`}. */
interface Loose extends Request {
raw: Request;
path: string;
method: HttpMethod;
clone: () => Loose;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-request#requesttoobject `request.toObject()` API reference} */
toObject: ((options: FetchRequestObjectOptions.WithBody) => Promise<FetchRequestObject>) & ((options?: FetchRequestObjectOptions.WithoutBody) => FetchRequestObject) & ((options?: FetchRequestObjectOptions) => PossiblePromise<FetchRequestObject>);
}
}
declare const FetchRequest: FetchRequestClass;
type AllFetchResponseStatusCode<MethodSchema extends HttpMethodSchema> = HttpResponseSchemaStatusCode<Default<MethodSchema['response']>>;
type FilterFetchResponseStatusCodeByError<StatusCode extends HttpStatusCode, ErrorOnly extends boolean> = ErrorOnly extends true ? Extract<StatusCode, HttpStatusCode.ClientError | HttpStatusCode.ServerError> : StatusCode;
type FilterFetchResponseStatusCodeByRedirect<StatusCode extends HttpStatusCode, Redirect extends RequestRedirect> = Redirect extends 'error' ? FilterFetchResponseStatusCodeByRedirect<StatusCode, 'follow'> : Redirect extends 'follow' ? Exclude<StatusCode, Exclude<HttpStatusCode.Redirection, 304>> : StatusCode;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response `FetchResponse` API reference} */
type FetchResponseStatusCode<MethodSchema extends HttpMethodSchema, ErrorOnly extends boolean, Redirect extends RequestRedirect> = FilterFetchResponseStatusCodeByRedirect<FilterFetchResponseStatusCodeByError<AllFetchResponseStatusCode<MethodSchema>, ErrorOnly>, Redirect>;
type FetchResponseInitWithHeaders<HeadersSchema extends HttpHeadersSchema | undefined> = FetchRequestInitWithHeaders<HeadersSchema>;
type FetchResponseBodySchema<ResponseSchema extends HttpResponseSchema> = FetchRequestBodySchema<ResponseSchema>;
type FetchResponseInitPerStatusCode<MethodSchema extends HttpMethodSchema, StatusCode extends AllFetchResponseStatusCode<MethodSchema>> = {
status: StatusCode;
} & FetchResponseInitWithHeaders<HttpResponseHeadersSchema<MethodSchema, StatusCode>>;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response `FetchResponse` API reference} */
type FetchResponseInit<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath<Schema, Method>,
/** @deprecated The type parameter `ErrorOnly` will be removed in the next major version. */
ErrorOnly extends boolean = false, Redirect extends RequestRedirect = 'follow', StatusCode extends FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect> = FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect>> = Omit<ResponseInit, 'headers' | 'status'> & (StatusCode extends StatusCode ? FetchResponseInitPerStatusCode<Default<Schema[Path][Method]>, StatusCode> : never);
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response `FetchResponse` API reference} */
interface FetchResponseConstructor {
new <Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>,
/** @deprecated The type parameter `ErrorOnly` will be removed in the next major version. */
ErrorOnly extends boolean = false, Redirect extends RequestRedirect = 'follow', StatusCode extends FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect> = FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect>>(fetchRequest: FetchRequest<Schema, Method, Path>, response?: Response): FetchResponse<Schema, Method, Path, ErrorOnly, Redirect, StatusCode>;
new <Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>,
/** @deprecated The type parameter `ErrorOnly` will be removed in the next major version. */
ErrorOnly extends boolean = false, Redirect extends RequestRedirect = 'follow', StatusCode extends FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect> = FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect>>(fetchRequest: FetchRequest<Schema, Method, Path>, body?: FetchResponseBodySchema<Default<Default<Default<Schema[Path][Method]>['response']>[StatusCode]>>, init?: FetchResponseInit<Schema, Method, Path, ErrorOnly, Redirect, StatusCode>): FetchResponse<Schema, Method, Path, ErrorOnly, Redirect, StatusCode>;
[Symbol.hasInstance]: (instance: unknown) => boolean;
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response#responsetoobject `response.toObject()` API reference} */
interface FetchResponseObjectOptions {
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response#responsetoobject `response.toObject()` API reference} */
includeBody?: boolean;
}
declare namespace FetchResponseObjectOptions {
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response#responsetoobject `response.toObject()` API reference} */
interface WithBody {
includeBody: true;
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response#responsetoobject `response.toObject()` API reference} */
interface WithoutBody {
includeBody?: false;
}
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response#responsetoobject `response.toObject()`} */
type FetchResponseObject = Pick<FetchResponse.Loose, 'url' | 'type' | 'status' | 'statusText' | 'ok' | 'redirected'> & {
headers: HttpHeadersSerialized<HttpHeadersSchema>;
body?: HttpBody | null;
};
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response `FetchResponse` API reference} */
interface FetchResponsePerStatusCode<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>, StatusCode extends HttpStatusCode = HttpStatusCode> extends HttpResponse<HttpResponseBodySchema<Default<Schema[Path][Method]>, StatusCode>, Default<HttpResponseHeadersSchema<Default<Schema[Path][Method]>, StatusCode>>, StatusCode> {
raw: Response;
request: FetchRequest<Schema, Method, Path>;
error: FetchResponseError<Schema, Method, Path>;
clone: () => FetchResponsePerStatusCode<Schema, Method, Path, StatusCode>;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response#responsetoobject `response.toObject()` API reference} */
toObject: ((options: FetchResponseObjectOptions.WithBody) => Promise<FetchResponseObject>) & ((options?: FetchResponseObjectOptions.WithoutBody) => FetchResponseObject) & ((options?: FetchResponseObjectOptions) => PossiblePromise<FetchResponseObject>);
}
interface FetchResponseClass {
new <Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>,
/** @deprecated The type parameter `ErrorOnly` will be removed in the next major version. */
ErrorOnly extends boolean = false, Redirect extends RequestRedirect = 'follow', StatusCode extends FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect> = FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect>>(fetchRequest: FetchRequest<Schema, Method, Path>, response?: Response): FetchResponse<Schema, Method, Path, ErrorOnly, Redirect, StatusCode>;
new <Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>,
/** @deprecated The type parameter `ErrorOnly` will be removed in the next major version. */
ErrorOnly extends boolean = false, Redirect extends RequestRedirect = 'follow', StatusCode extends FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect> = FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect>>(fetchRequest: FetchRequest<Schema, Method, Path>, body?: FetchResponseBodySchema<Default<Default<Default<Schema[Path][Method]>['response']>[StatusCode]>>, init?: FetchResponseInit<Schema, Method, Path, ErrorOnly, Redirect, StatusCode>): FetchResponse<Schema, Method, Path, ErrorOnly, Redirect, StatusCode>;
prototype: Response;
[Symbol.hasInstance]: (instance: unknown) => instance is FetchResponse<any, any, any, any, any, any>;
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response `FetchResponse` API reference} */
type FetchResponse<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>,
/** @deprecated The type parameter `ErrorOnly` will be removed in the next major version. */
ErrorOnly extends boolean = false, Redirect extends RequestRedirect = 'follow', StatusCode extends FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect> = FetchResponseStatusCode<Default<Schema[Path][Method]>, ErrorOnly, Redirect>> = StatusCode extends StatusCode ? FetchResponsePerStatusCode<Schema, Method, Path, StatusCode> : never;
declare namespace FetchResponse {
/** A loosely typed version of a {@link FetchResponse}. */
interface Loose extends Response {
raw: Response;
request: FetchRequest.Loose;
error: FetchResponseError<any, any, any>;
clone: () => Loose;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response#responsetoobject `response.toObject()` API reference} */
toObject: ((options: FetchResponseObjectOptions.WithBody) => Promise<FetchResponseObject>) & ((options?: FetchResponseObjectOptions.WithoutBody) => FetchResponseObject) & ((options?: FetchResponseObjectOptions) => PossiblePromise<FetchResponseObject>);
}
}
declare const FetchResponse: FetchResponseClass;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `response.error.toObject()` API reference} */
interface FetchResponseErrorObjectOptions {
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `response.error.toObject()` API reference} */
includeRequestBody?: boolean;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `response.error.toObject()` API reference} */
includeResponseBody?: boolean;
}
declare namespace FetchResponseErrorObjectOptions {
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `response.error.toObject()` API reference} */
type WithBody = FetchResponseErrorObjectOptions & ({
includeRequestBody: true;
} | {
includeResponseBody: true;
});
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `response.error.toObject()` API reference} */
type WithoutBody = FetchResponseErrorObjectOptions & ({
includeRequestBody?: false;
} | {
includeResponseBody?: false;
});
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `response.error.toObject()` API reference} */
interface FetchResponseErrorObject {
name: string;
message: string;
request: FetchRequestObject;
response: FetchResponseObject;
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error `FetchResponseError` API reference} */
declare class FetchResponseError<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>> extends Error {
request: FetchRequest<Schema, Method, Path>;
response: FetchResponse<Schema, Method, Path>;
constructor(request: FetchRequest<Schema, Method, Path>, response: FetchResponse<Schema, Method, Path>);
/** @see {@link https://zimic.dev/docs/fetch/api/fetch-response-error#errortoobject `response.error.toObject()` API reference} */
toObject(options: FetchResponseErrorObjectOptions.WithBody): Promise<FetchResponseErrorObject>;
toObject(options?: FetchResponseErrorObjectOptions.WithoutBody): FetchResponseErrorObject;
toObject(options?: FetchResponseErrorObjectOptions): PossiblePromise<FetchResponseErrorObject>;
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch#fetchrequest `fetch.Request` API reference} */
interface FetchRequestConstructor<Schema extends HttpSchema> {
new <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>, Redirect extends RequestRedirect = 'follow'>(input: Path | URL, init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>): FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
new <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>, Redirect extends RequestRedirect = 'follow'>(input: FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>, init?: Omit<FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>, 'baseURL' | 'searchParams'>): FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
new <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>, Redirect extends RequestRedirect = 'follow'>(input: FetchInput<Schema, Method, Path>, init?: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>): FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
}
/** @see {@link https://zimic.dev/docs/fetch/api/fetch `fetch` API reference} */
type FetchInput<Schema extends HttpSchema, Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath<Schema, Method>> = Path | URL | FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch `fetch` API reference} */
interface Fetch<Schema extends HttpSchema> extends Pick<FetchOptions<Schema>, 'onRequest' | 'onResponse'>, FetchDefaults<Schema> {
<Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>, Redirect extends RequestRedirect = 'follow'>(input: Path | URL, init: FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>): Promise<FetchResponse<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, false, Redirect>>;
<Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.NonLiteral<Schema, Method>, Redirect extends RequestRedirect = 'follow'>(input: FetchRequest<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>>, init?: Omit<FetchRequestInit<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, Redirect>, 'baseURL' | 'searchParams'>): Promise<FetchResponse<Schema, Method, LiteralHttpSchemaPathFromNonLiteral<Schema, Method, Path>, false, Redirect>>;
/**
* @deprecated Consider accessing the default options directly from the fetch instance.
* @see {@link https://zimic.dev/docs/fetch/api/fetch#fetch-defaults `fetch` defaults}
*/
defaults: FetchDefaults<Schema>;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch#fetchloose `fetch.loose`} */
loose: Fetch.Loose;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch#fetchrequest `fetch.Request`} */
Request: FetchRequestConstructor<Schema>;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch#fetchisrequest `fetch.isRequest`} */
isRequest: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(request: unknown, method: Method, path: Path) => request is FetchRequest<Schema, Method, Path>;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch#fetchisresponse `fetch.isResponse`} */
isResponse: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(response: unknown, method: Method, path: Path) => response is FetchResponse<Schema, Method, Path>;
/** @see {@link https://zimic.dev/docs/fetch/api/fetch#fetchisresponseerror `fetch.isResponseError`} */
isResponseError: <Method extends HttpSchemaMethod<Schema>, Path extends HttpSchemaPath.Literal<Schema, Method>>(error: unknown, method: Method, path: Path) => error is FetchResponseError<Schema, Method, Path>;
}
declare namespace Fetch {
/** A loosely-typed version of {@link Fetch `fetch`}. This can be useful to make requests with fewer type constraints, */
type Loose = (input: string | URL | FetchRequest.Loose, init?: FetchRequestInit.Loose) => Promise<FetchResponse.Loose>;
}
/** @see {@link https://zimic.dev/docs/fetch/api/create-fetch `createFetch` API reference} */
interface FetchOptions<Schema extends HttpSchema> extends Omit<FetchRequestInit.Defaults<Schema>, 'method'> {
/** @see {@link https://zimic.dev/docs/fetch/api/create-fetch#onrequest `createFetch.onRequest`} API reference */
onRequest?: (this: Fetch<Schema>, request: FetchRequest.Loose) => PossiblePromise<Request>;
/** @see {@link https://zimic.dev/docs/fetch/api/create-fetch#onresponse `createFetch.onResponse`} API reference */
onResponse?: (this: Fetch<Schema>, response: FetchResponse.Loose) => PossiblePromise<Response>;
}
/**
* The default options to send with each request.
*
* @see {@link https://zimic.dev/docs/fetch/api/fetch `fetch` API reference}
*/
type FetchDefaults<Schema extends HttpSchema = HttpSchema> = RequiredByKey<FetchRequestInit.Defaults<Schema>, 'headers' | 'searchParams'>;
/**
* Infers the schema of a {@link https://zimic.dev/docs/fetch/api/fetch fetch instance}.
*
* @example
* import { type HttpSchema } from '@zimic/http';
* import { createFetch, InferFetchSchema } from '@zimic/fetch';
*
* const fetch = createFetch<{
* '/users': {
* GET: {
* response: { 200: { body: User[] } };
* };
* };
* }>({
* baseURL: 'http://localhost:3000',
* });
*
* type Schema = InferFetchSchema<typeof fetch>;
* // {
* // '/users': {
* // GET: {
* // response: { 200: { body: User[] } };
* // };
* // };
*
* @see {@link https://zimic.dev/docs/fetch/api/fetch `fetch` API reference}
*/
type InferFetchSchema<FetchInstance> = FetchInstance extends Fetch<infer Schema> ? Schema : never;
/** @see {@link https://zimic.dev/docs/fetch/api/create-fetch `createFetch` API reference} */
declare function createFetch<Schema extends HttpSchema>(options: FetchOptions<Schema>): Fetch<Schema>;
export { Fetch, type FetchDefaults, type FetchInput, type FetchOptions, FetchRequest, type FetchRequestConstructor, FetchRequestInit, type FetchRequestObject, FetchRequestObjectOptions, FetchResponse, type FetchResponseConstructor, FetchResponseError, type FetchResponseErrorObject, FetchResponseErrorObjectOptions, type FetchResponseInit, type FetchResponseObject, FetchResponseObjectOptions, type FetchResponsePerStatusCode, type FetchResponseStatusCode, type InferFetchSchema, type JSONStringified, createFetch };