import type { Auth } from '../core/auth'; import type { ServerSentEventsOptions, ServerSentEventsResult, } from '../core/serverSentEvents'; import type { Client as CoreClient, Config as CoreConfig, } from '../core/types'; import type { Middleware } from './utils'; export interface Config extends Omit, CoreConfig { /** * Base URL for all requests made by this client. */ baseUrl?: T['baseUrl']; /** * Fetch API implementation. You can use this option to provide a custom * fetch instance. * * @default globalThis.fetch */ fetch?: typeof fetch; /** * Return the response data parsed in a specified format. By default, `auto` * will infer the appropriate method from the `Content-Type` response header. * You can override this behavior with any of the {@link Body} methods. * Select `stream` if you don't want to parse response data at all. * * @default 'auto' */ parseAs?: | 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text'; /** * Throw an error instead of returning it in the response? * * @default false */ throwOnError?: T['throwOnError']; } export interface RequestOptions< TData = unknown, ThrowOnError extends boolean = boolean, Url extends string = string, > extends Config<{ throwOnError: ThrowOnError; }>, Pick< ServerSentEventsOptions, | 'onSseError' | 'onSseEvent' | 'sseDefaultRetryDelay' | 'sseMaxRetryAttempts' | 'sseMaxRetryDelay' > { /** * Any body that you want to add to your request. * * {@link https://developer.mozilla.org/docs/Web/API/fetch#body} */ body?: unknown; path?: Record; query?: Record; /** * Security mechanism(s) to use for the request. */ security?: ReadonlyArray; url: Url; } export interface ResolvedRequestOptions< ThrowOnError extends boolean = boolean, Url extends string = string, > extends RequestOptions { serializedBody?: string; } export type RequestResult< TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, > = ThrowOnError extends true ? Promise<{ data: TData extends Record ? TData[keyof TData] : TData; response: Response; }> : Promise< ( | { data: TData extends Record ? TData[keyof TData] : TData; error: undefined; } | { data: undefined; error: TError extends Record ? TError[keyof TError] : TError; } ) & { response: Response; } >; export interface ClientOptions { baseUrl?: string; throwOnError?: boolean; } type MethodFn = < TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'>, ) => RequestResult; type SseFn = < TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'>, ) => Promise>; type RequestFn = < TData = unknown, TError = unknown, ThrowOnError extends boolean = false, >( options: Omit, 'method'> & Pick>, 'method'>, ) => RequestResult; type BuildUrlFn = < TData extends { body?: unknown; path?: Record; query?: Record; url: string; }, >( options: TData & Options, ) => string; export type Client = CoreClient< RequestFn, Config, MethodFn, BuildUrlFn, SseFn > & { interceptors: Middleware; }; /** * The `createClientConfig()` function will be called on client initialization * and the returned object will become the client's initial configuration. * * You may want to initialize your client this way instead of calling * `setConfig()`. This is useful for example if you're using Next.js * to ensure your client always has the correct values. */ export type CreateClientConfig = ( override?: Config, ) => Config & T>; export interface TDataShape { body?: unknown; headers?: unknown; path?: unknown; query?: unknown; url: string; } type OmitKeys = Pick>; export type Options< TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown, > = OmitKeys< RequestOptions, 'body' | 'path' | 'query' | 'url' > & ([TData] extends [never] ? unknown : Omit);