import { StartInstanceOptions } from './createStart.js';
import { AnyServerFn, ConstrainValidator, CustomFetch, Method } from './createServerFn.js';
import { ClientFnMeta, ServerFnMeta } from './constants.js';
import { AnyContext, Assign, Constrain, Expand, IntersectAssign, Register, ResolveValidatorInput, ResolveValidatorOutput, ValidateSerializableInput } from '@tanstack/router-core';
export type CreateMiddlewareFn<TRegister> = <TType extends MiddlewareType>(options?: {
    type?: TType;
}, __opts?: FunctionMiddlewareOptions<TRegister, unknown, undefined, undefined, undefined>) => CreateMiddlewareResult<TRegister, TType>;
export declare const createMiddleware: CreateMiddlewareFn<{}>;
export type MiddlewareType = 'request' | 'function';
export type CreateMiddlewareResult<TRegister, TType extends MiddlewareType> = 'request' extends TType ? RequestMiddleware<TRegister> : FunctionMiddleware<TRegister>;
export interface FunctionMiddleware<TRegister> extends FunctionMiddlewareAfterMiddleware<TRegister, unknown> {
    middleware: <const TNewMiddlewares = undefined>(middlewares: Constrain<TNewMiddlewares, ReadonlyArray<AnyRequestMiddleware | AnyFunctionMiddleware>>) => FunctionMiddlewareAfterMiddleware<TRegister, TNewMiddlewares>;
}
export interface FunctionMiddlewareAfterMiddleware<TRegister, TMiddlewares> extends FunctionMiddlewareWithTypes<TRegister, TMiddlewares, undefined, undefined, undefined, undefined, undefined>, FunctionMiddlewareServer<TRegister, TMiddlewares, undefined, undefined, undefined>, FunctionMiddlewareClient<TRegister, TMiddlewares, undefined>, FunctionMiddlewareValidator<TRegister, TMiddlewares> {
}
export interface FunctionMiddlewareWithTypes<TRegister, TMiddlewares, TInputValidator, TServerContext, TServerSendContext, TClientContext, TClientSendContext> {
    '~types': FunctionMiddlewareTypes<TRegister, TMiddlewares, TInputValidator, TServerContext, TServerSendContext, TClientContext, TClientSendContext>;
    options: FunctionMiddlewareOptions<TRegister, TMiddlewares, TInputValidator, TServerContext, TClientContext>;
}
export interface FunctionMiddlewareTypes<in out TRegister, in out TMiddlewares, in out TInputValidator, in out TServerContext, in out TServerSendContext, in out TClientContext, in out TClientSendContext> {
    type: 'function';
    middlewares: TMiddlewares;
    input: ResolveValidatorInput<TInputValidator>;
    allInput: IntersectAllValidatorInputs<TMiddlewares, TInputValidator>;
    output: ResolveValidatorOutput<TInputValidator>;
    allOutput: IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>;
    clientContext: TClientContext;
    allClientContextBeforeNext: AssignAllClientContextBeforeNext<TMiddlewares, TClientContext>;
    allClientContextAfterNext: AssignAllClientContextAfterNext<TMiddlewares, TClientContext, TClientSendContext>;
    serverContext: TServerContext;
    serverSendContext: TServerSendContext;
    allServerSendContext: AssignAllServerSendContext<TMiddlewares, TServerSendContext>;
    allServerContext: AssignAllServerFnContext<TRegister, TMiddlewares, TServerSendContext, TServerContext>;
    clientSendContext: TClientSendContext;
    allClientSendContext: AssignAllClientSendContext<TMiddlewares, TClientSendContext>;
    inputValidator: TInputValidator;
}
/**
 * Recursively resolve the input type produced by a sequence of middleware
 */
export type IntersectAllValidatorInputs<TMiddlewares, TInputValidator> = unknown extends TInputValidator ? TInputValidator : TInputValidator extends undefined ? IntersectAllMiddleware<TMiddlewares, 'allInput'> : IntersectAssign<IntersectAllMiddleware<TMiddlewares, 'allInput'>, ResolveValidatorInput<TInputValidator>>;
export type IntersectAllMiddleware<TMiddlewares, TType extends keyof AnyFunctionMiddleware['~types'] | keyof AnyRequestMiddleware['~types'] | keyof AnyServerFn['~types'], TAcc = undefined> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest] ? TMiddleware extends AnyFunctionMiddleware | AnyRequestMiddleware | AnyServerFn ? IntersectAllMiddleware<TRest, TType, IntersectAssign<TAcc, TMiddleware['~types'][TType & keyof TMiddleware['~types']]>> : TAcc : TAcc;
export type AnyFunctionMiddleware = FunctionMiddlewareWithTypes<any, any, any, any, any, any, any>;
/**
 * Recursively merge the output type produced by a sequence of middleware
 */
export type IntersectAllValidatorOutputs<TMiddlewares, TInputValidator> = unknown extends TInputValidator ? TInputValidator : TInputValidator extends undefined ? IntersectAllMiddleware<TMiddlewares, 'allOutput'> : IntersectAssign<IntersectAllMiddleware<TMiddlewares, 'allOutput'>, Awaited<ResolveValidatorOutput<TInputValidator>>>;
/**
 * Recursively resolve the client context type produced by a sequence of middleware
 */
export type AssignAllClientContextBeforeNext<TMiddlewares, TClientContext = undefined> = unknown extends TClientContext ? TClientContext : Assign<AssignAllMiddleware<TMiddlewares, 'allClientContextBeforeNext'>, TClientContext>;
export type AssignAllMiddleware<TMiddlewares, TType extends keyof AnyFunctionMiddleware['~types'] | keyof AnyRequestMiddleware['~types'] | keyof AnyServerFn['~types'], TAcc = undefined> = TMiddlewares extends readonly [infer TMiddleware, ...infer TRest] ? TMiddleware extends AnyFunctionMiddleware | AnyRequestMiddleware | AnyServerFn ? AssignAllMiddleware<TRest, TType, Assign<TAcc, TMiddleware['~types'][TType & keyof TMiddleware['~types']]>> : TAcc : TAcc;
export type AssignAllClientContextAfterNext<TMiddlewares, TClientContext = undefined, TSendContext = undefined> = unknown extends TClientContext ? Assign<TClientContext, TSendContext> : Assign<AssignAllMiddleware<TMiddlewares, 'allClientContextAfterNext'>, Assign<TClientContext, TSendContext>>;
export type AssignAllServerSendContext<TMiddlewares, TSendContext = undefined> = unknown extends TSendContext ? TSendContext : Assign<AssignAllMiddleware<TMiddlewares, 'allServerSendContext'>, TSendContext>;
export type AssignAllServerRequestContext<TRegister, TMiddlewares, TSendContext = undefined, TServerContext = undefined> = Assign<GlobalFetchRequestContext, Assign<GlobalServerRequestContext<TRegister>, __AssignAllServerRequestContext<TMiddlewares, TSendContext, TServerContext>>>;
export type GlobalFetchRequestContext = Register extends {
    server: {
        requestContext: infer TRequestContext;
    };
} ? TRequestContext : AnyContext;
export type GlobalServerRequestContext<TRegister> = TRegister extends {
    config: StartInstanceOptions<any, any, infer TRequestMiddlewares, any>;
} ? AssignAllMiddleware<TRequestMiddlewares, 'allServerContext'> : AnyContext;
type __AssignAllServerRequestContext<TMiddlewares, TSendContext = undefined, TServerContext = undefined> = unknown extends TSendContext ? Assign<TSendContext, TServerContext> : Assign<AssignAllMiddleware<TMiddlewares, 'allServerContext'>, Assign<TSendContext, TServerContext>>;
export type AssignAllServerFnContext<TRegister, TMiddlewares, TSendContext = undefined, TServerContext = undefined> = Assign<GlobalFetchRequestContext, Assign<GlobalServerRequestContext<TRegister>, // TODO: This enabled global middleware
Assign<GlobalServerFnContext<TRegister>, // TODO: This enabled global middleware
__AssignAllServerFnContext<TMiddlewares, TSendContext, TServerContext>>>>;
type GlobalServerFnContext<TRegister> = TRegister extends {
    config: StartInstanceOptions<any, any, any, infer TFunctionMiddlewares>;
} ? AssignAllMiddleware<TFunctionMiddlewares, 'allServerContext'> : AnyContext;
type __AssignAllServerFnContext<TMiddlewares, TSendContext = undefined, TServerContext = undefined> = unknown extends TSendContext ? Assign<TSendContext, TServerContext> : Assign<AssignAllMiddleware<TMiddlewares, 'allServerContext'>, Assign<TSendContext, TServerContext>>;
export type AssignAllClientSendContext<TMiddlewares, TSendContext = undefined> = unknown extends TSendContext ? TSendContext : Assign<AssignAllMiddleware<TMiddlewares, 'allClientSendContext'>, TSendContext>;
export interface FunctionMiddlewareOptions<in out TRegister, in out TMiddlewares, in out TInputValidator, in out TServerContext, in out TClientContext> {
    middleware?: TMiddlewares;
    inputValidator?: ConstrainValidator<TRegister, 'GET', TInputValidator>;
    client?: FunctionMiddlewareClientFn<TRegister, TMiddlewares, TInputValidator, TServerContext, TClientContext>;
    server?: FunctionMiddlewareServerFn<TRegister, TMiddlewares, TInputValidator, TServerContext, unknown, unknown>;
}
export type FunctionMiddlewareClientNextFn<TRegister, TMiddlewares> = <TSendContext = undefined, TNewClientContext = undefined>(ctx?: {
    context?: TNewClientContext;
    sendContext?: ValidateSerializableInput<TRegister, TSendContext>;
    headers?: HeadersInit;
    fetch?: CustomFetch;
}) => Promise<FunctionClientResultWithContext<TMiddlewares, TSendContext, TNewClientContext>>;
export interface FunctionMiddlewareServer<TRegister, TMiddlewares, TInputValidator, TServerSendContext, TClientContext> {
    server: <TNewServerContext = undefined, TSendContext = undefined>(server: FunctionMiddlewareServerFn<TRegister, TMiddlewares, TInputValidator, TServerSendContext, TNewServerContext, TSendContext>) => FunctionMiddlewareAfterServer<TRegister, TMiddlewares, TInputValidator, TNewServerContext, TServerSendContext, TClientContext, TSendContext>;
}
export type FunctionMiddlewareServerFn<TRegister, TMiddlewares, TInputValidator, TServerSendContext, TNewServerContext, TSendContext> = (options: FunctionMiddlewareServerFnOptions<TRegister, TMiddlewares, TInputValidator, TServerSendContext>) => FunctionMiddlewareServerFnResult<TRegister, TMiddlewares, TServerSendContext, TNewServerContext, TSendContext>;
export type FunctionMiddlewareServerNextFn<TRegister, TMiddlewares, TServerSendContext> = <TNewServerContext = undefined, TSendContext = undefined>(ctx?: {
    context?: TNewServerContext;
    sendContext?: ValidateSerializableInput<TRegister, TSendContext>;
}) => Promise<FunctionServerResultWithContext<TRegister, TMiddlewares, TServerSendContext, TNewServerContext, TSendContext>>;
export type FunctionServerResultWithContext<in out TRegister, in out TMiddlewares, in out TServerSendContext, in out TServerContext, in out TSendContext> = {
    'use functions must return the result of next()': true;
    '~types': {
        context: TServerContext;
        sendContext: TSendContext;
    };
    context: Expand<AssignAllServerFnContext<TRegister, TMiddlewares, TServerSendContext, TServerContext>>;
    sendContext: Expand<AssignAllClientSendContext<TMiddlewares, TSendContext>>;
};
export interface FunctionMiddlewareServerFnOptions<in out TRegister, in out TMiddlewares, in out TInputValidator, in out TServerSendContext> {
    data: Expand<IntersectAllValidatorOutputs<TMiddlewares, TInputValidator>>;
    context: Expand<AssignAllServerFnContext<TRegister, TMiddlewares, TServerSendContext>>;
    next: FunctionMiddlewareServerNextFn<TRegister, TMiddlewares, TServerSendContext>;
    method: Method;
    serverFnMeta: ServerFnMeta;
    signal: AbortSignal;
}
export type FunctionMiddlewareServerFnResult<TRegister, TMiddlewares, TServerSendContext, TServerContext, TSendContext> = Promise<FunctionServerResultWithContext<TRegister, TMiddlewares, TServerSendContext, TServerContext, TSendContext>> | FunctionServerResultWithContext<TRegister, TMiddlewares, TServerSendContext, TServerContext, TSendContext>;
export interface FunctionMiddlewareAfterServer<TRegister, TMiddlewares, TInputValidator, TServerContext, TServerSendContext, TClientContext, TClientSendContext> extends FunctionMiddlewareWithTypes<TRegister, TMiddlewares, TInputValidator, TServerContext, TServerSendContext, TClientContext, TClientSendContext> {
}
export interface FunctionMiddlewareClient<TRegister, TMiddlewares, TInputValidator> {
    client: <TSendServerContext = undefined, TNewClientContext = undefined>(client: FunctionMiddlewareClientFn<TRegister, TMiddlewares, TInputValidator, TSendServerContext, TNewClientContext>) => FunctionMiddlewareAfterClient<TRegister, TMiddlewares, TInputValidator, TSendServerContext, TNewClientContext>;
}
export type FunctionMiddlewareClientFn<TRegister, TMiddlewares, TInputValidator, TSendContext, TClientContext> = (options: FunctionMiddlewareClientFnOptions<TRegister, TMiddlewares, TInputValidator>) => FunctionMiddlewareClientFnResult<TMiddlewares, TSendContext, TClientContext>;
export interface FunctionMiddlewareClientFnOptions<in out TRegister, in out TMiddlewares, in out TInputValidator> {
    data: Expand<IntersectAllValidatorInputs<TMiddlewares, TInputValidator>>;
    context: Expand<AssignAllClientContextBeforeNext<TMiddlewares>>;
    sendContext: Expand<AssignAllServerSendContext<TMiddlewares>>;
    method: Method;
    signal: AbortSignal;
    serverFnMeta: ClientFnMeta;
    next: FunctionMiddlewareClientNextFn<TRegister, TMiddlewares>;
    filename: string;
    fetch?: CustomFetch;
}
export type FunctionMiddlewareClientFnResult<TMiddlewares, TSendContext, TClientContext> = Promise<FunctionClientResultWithContext<TMiddlewares, TSendContext, TClientContext>> | FunctionClientResultWithContext<TMiddlewares, TSendContext, TClientContext>;
export type FunctionClientResultWithContext<in out TMiddlewares, in out TSendContext, in out TClientContext> = {
    'use functions must return the result of next()': true;
    context: Expand<AssignAllClientContextAfterNext<TMiddlewares, TClientContext>>;
    sendContext: Expand<AssignAllServerSendContext<TMiddlewares, TSendContext>>;
    headers: HeadersInit;
    fetch?: CustomFetch;
};
export interface FunctionMiddlewareAfterClient<TRegister, TMiddlewares, TInputValidator, TServerSendContext, TClientContext> extends FunctionMiddlewareWithTypes<TRegister, TMiddlewares, TInputValidator, undefined, TServerSendContext, TClientContext, undefined>, FunctionMiddlewareServer<TRegister, TMiddlewares, TInputValidator, TServerSendContext, TClientContext> {
}
export interface FunctionMiddlewareValidator<TRegister, TMiddlewares> {
    inputValidator: <TNewValidator>(inputValidator: ConstrainValidator<TRegister, 'GET', TNewValidator>) => FunctionMiddlewareAfterValidator<TRegister, TMiddlewares, TNewValidator>;
}
export interface FunctionMiddlewareAfterValidator<TRegister, TMiddlewares, TInputValidator> extends FunctionMiddlewareWithTypes<TRegister, TMiddlewares, TInputValidator, undefined, undefined, undefined, undefined>, FunctionMiddlewareServer<TRegister, TMiddlewares, TInputValidator, undefined, undefined>, FunctionMiddlewareClient<TRegister, TMiddlewares, TInputValidator> {
}
export interface RequestMiddleware<TRegister> extends RequestMiddlewareAfterMiddleware<TRegister, undefined> {
    middleware: <const TMiddlewares = undefined>(middlewares: Constrain<TMiddlewares, ReadonlyArray<AnyRequestMiddleware>>) => RequestMiddlewareAfterMiddleware<TRegister, TMiddlewares>;
}
export type AnyRequestMiddleware = RequestMiddlewareWithTypes<any, any, any>;
export interface RequestMiddlewareWithTypes<TRegister, TMiddlewares, TServerContext> {
    '~types': RequestMiddlewareTypes<TRegister, TMiddlewares, TServerContext>;
    options: RequestMiddlewareOptions<TRegister, TMiddlewares, TServerContext>;
}
export interface RequestMiddlewareOptions<in out TRegister, in out TMiddlewares, in out TServerContext> {
    middleware?: TMiddlewares;
    server?: RequestServerFn<TRegister, TMiddlewares, TServerContext>;
}
export interface RequestMiddlewareTypes<TRegister, TMiddlewares, TServerContext> {
    type: 'request';
    allInput: undefined;
    allOutput: undefined;
    middlewares: TMiddlewares;
    serverContext: TServerContext;
    allServerContext: AssignAllServerRequestContext<TRegister, TMiddlewares, undefined, TServerContext>;
}
export interface RequestMiddlewareAfterMiddleware<TRegister, TMiddlewares> extends RequestMiddlewareWithTypes<TRegister, TMiddlewares, undefined>, RequestMiddlewareServer<TRegister, TMiddlewares> {
}
export interface RequestMiddlewareServer<TRegister, TMiddlewares> {
    server: <TServerContext = undefined>(fn: RequestServerFn<TRegister, TMiddlewares, TServerContext>) => RequestMiddlewareAfterServer<TRegister, TMiddlewares, TServerContext>;
}
export type RequestServerFn<TRegister, TMiddlewares, TServerContext> = (options: RequestServerOptions<TRegister, TMiddlewares>) => RequestMiddlewareServerFnResult<TRegister, TMiddlewares, TServerContext>;
export interface RequestServerOptions<TRegister, TMiddlewares> {
    request: Request;
    pathname: string;
    context: Expand<AssignAllServerRequestContext<TRegister, TMiddlewares>>;
    next: RequestServerNextFn<TRegister, TMiddlewares>;
    /**
     * Metadata about the server function being invoked.
     * This is only present when the request is handling a server function call.
     * For regular page requests, this will be undefined.
     */
    serverFnMeta?: ServerFnMeta;
}
export type RequestServerNextFn<TRegister, TMiddlewares> = <TServerContext = undefined>(options?: RequestServerNextFnOptions<TServerContext>) => RequestServerNextFnResult<TRegister, TMiddlewares, TServerContext>;
export interface RequestServerNextFnOptions<TServerContext> {
    context?: TServerContext;
}
export type RequestServerNextFnResult<TRegister, TMiddlewares, TServerContext> = Promise<RequestServerResult<TRegister, TMiddlewares, TServerContext>> | RequestServerResult<TRegister, TMiddlewares, TServerContext>;
export type RequestMiddlewareServerFnResult<TRegister, TMiddlewares, TServerContext> = Promise<RequestServerResult<TRegister, TMiddlewares, TServerContext> | Response> | RequestServerResult<TRegister, TMiddlewares, TServerContext> | Response;
export interface RequestServerResult<TRegister, TMiddlewares, TServerContext> {
    request: Request;
    pathname: string;
    context: Expand<AssignAllServerRequestContext<TRegister, TMiddlewares, undefined, TServerContext>>;
    response: Response;
}
export interface RequestMiddlewareAfterServer<TRegister, TMiddlewares, TServerContext> extends RequestMiddlewareWithTypes<TRegister, TMiddlewares, TServerContext> {
}
export {};
