import { AppRoute, AppRouteMutation, AppRouter } from './dsl';
import { AreAllPropertiesOptional, Prettify } from './type-utils';
import { ClientInferRequest, ClientInferResponses, PartialClientInferRequest } from './infer-types';
type RecursiveProxyObj<T extends AppRouter, TClientArgs extends ClientArgs> = {
    [TKey in keyof T]: T[TKey] extends AppRoute ? AppRouteFunction<T[TKey], TClientArgs> : T[TKey] extends AppRouter ? RecursiveProxyObj<T[TKey], TClientArgs> : never;
};
/**
 * @deprecated Only safe to use on the client-side. Use `ServerInferResponses`/`ClientInferResponses` instead.
 */
export type ApiResponseForRoute<T extends AppRoute> = ClientInferResponses<T>;
/**
 * @deprecated Only safe to use on the client-side. Use `ServerInferResponses`/`ClientInferResponses` instead.
 */
export declare function getRouteResponses<T extends AppRouter>(router: T): ClientInferResponses<T>;
/**
 * Returned from a mutation or query call
 */
export type AppRouteFunction<TRoute extends AppRoute, TClientArgs extends ClientArgs, TArgs = PartialClientInferRequest<TRoute, TClientArgs>> = AreAllPropertiesOptional<TArgs> extends true ? (args?: Prettify<TArgs>) => Promise<Prettify<ClientInferResponses<TRoute>>> : (args: Prettify<TArgs>) => Promise<Prettify<ClientInferResponses<TRoute>>>;
export type FetchOptions = typeof globalThis extends {
    Request: infer T extends typeof Request;
} ? Omit<NonNullable<ConstructorParameters<T>[1]>, 'method' | 'headers' | 'body'> : never;
export interface OverrideableClientArgs {
    baseUrl: string;
    credentials?: FetchOptions['credentials'];
    jsonQuery?: boolean;
    validateResponse?: boolean;
}
export interface ClientArgs extends OverrideableClientArgs {
    baseHeaders?: Record<string, string | ((options: FetchApiOptions) => string)>;
    api?: ApiFetcher;
}
export type ApiFetcherArgs<TFetchOptions extends FetchOptions = FetchOptions> = {
    route: AppRoute;
    path: string;
    method: string;
    headers: Record<string, string>;
    body: FormData | URLSearchParams | string | null | undefined;
    rawBody: unknown;
    rawQuery: unknown;
    contentType: AppRouteMutation['contentType'];
    fetchOptions?: FetchOptions;
    validateResponse?: boolean;
    /**
     * @deprecated Use `fetchOptions.credentials` instead
     */
    credentials?: TFetchOptions['credentials'];
    /**
     * @deprecated Use `fetchOptions.signal` instead
     */
    signal?: TFetchOptions['signal'];
    /**
     * @deprecated Use `fetchOptions.cache` instead
     */
    cache?: 'cache' extends keyof TFetchOptions ? TFetchOptions['cache'] : never;
    /**
     * @deprecated Use `fetchOptions.next` instead
     */
    next?: 'next' extends keyof TFetchOptions ? TFetchOptions['next'] : never;
};
export type ApiFetcher = (args: ApiFetcherArgs) => Promise<{
    status: number;
    body: unknown;
    headers: Headers;
}>;
/**
 * Default fetch api implementation:
 *
 * Can be used as a reference for implementing your own fetcher,
 * or used in the "api" field of ClientArgs to allow you to hook
 * into the request to run custom logic
 */
export declare const tsRestFetchApi: ApiFetcher;
export type FetchApiOptions = {
    path: string;
    clientArgs: ClientArgs;
    route: AppRoute;
    query: unknown;
    body: unknown;
    extraInputArgs: Record<string, unknown>;
    headers: Record<string, string | undefined>;
    fetchOptions?: FetchOptions;
};
export declare const fetchApi: (options: FetchApiOptions) => Promise<{
    status: number;
    body: unknown;
    headers: Headers;
}>;
export declare const evaluateFetchApiArgs: <TAppRoute extends AppRoute>(route: TAppRoute, clientArgs: InitClientArgs, inputArgs?: ClientInferRequest<AppRouteMutation, ClientArgs>) => FetchApiOptions;
/**
 * @hidden
 */
export declare const getCompleteUrl: (query: unknown, baseUrl: string, params: unknown, route: AppRoute, jsonQuery: boolean) => string;
export declare const getRouteQuery: <TAppRoute extends AppRoute>(route: TAppRoute, clientArgs: InitClientArgs) => (inputArgs?: ClientInferRequest<AppRouteMutation, ClientArgs>) => Promise<{
    status: number;
    body: unknown;
    headers: Headers;
}>;
export type InitClientReturn<T extends AppRouter, TClientArgs extends ClientArgs> = RecursiveProxyObj<T, TClientArgs>;
export type InitClientArgs = ClientArgs & {
    /**
     * Ensures that the responses from the server match those defined in the
     * contract.
     */
    throwOnUnknownStatus?: boolean;
};
export declare const initClient: <T extends AppRouter, TClientArgs extends InitClientArgs>(router: T, args: TClientArgs) => RecursiveProxyObj<T, TClientArgs>;
export {};
