import { Context } from '@getcronit/pylon';
type Primitive = string | number | boolean | symbol | bigint | undefined | null | Date;
/**
 * Recursively maps a GraphQL return type to a selection map for the `needs` object.
 * Allows boolean flags for selection and a special `__args` property for nested arguments.
 */
export type NeedsMap<T> = T extends Primitive ? boolean : T extends (...args: any[]) => infer Ret ? NeedsMap<Awaited<Ret>> : T extends Array<infer U> ? NeedsMap<U> : {
    [K in keyof T]?: NeedsMap<T[K]> | boolean;
} & {
    __args?: Record<string, any>;
};
/**
 * Maps over the properties of the resolved type within the registry.
 * Intercepting the lookup at the property level mitigates TS2589
 * (Type instantiation is excessively deep and possibly infinite) during recursive type inference.
 */
type MapValue<V, P, R> = V extends Primitive ? V : V extends Array<infer U> ? Array<PatchSchema<U, P, R>> : V extends {
    __typename: infer Name;
} ? Name extends keyof P ? P[Name & keyof P] extends (...args: any) => infer Res ? {
    [Prop in keyof Res]: PatchSchema<Res[Prop], P, R>;
} : never : {
    [Prop in keyof V]: PatchSchema<V[Prop], P, R>;
} : {
    [Prop in keyof V]: PatchSchema<V[Prop], P, R>;
};
type MappedRegistry<R, P> = {
    [K in keyof R]: MapValue<R[K], P, R>;
};
type PatchSchema<T, P, R> = T extends Primitive ? T : T extends (...args: infer Args) => infer Ret ? (...args: Args) => Ret extends Promise<any> ? Promise<PatchSchema<Awaited<Ret>, P, R>> : PatchSchema<Awaited<Ret>, P, R> : T extends Array<infer U> ? Array<PatchSchema<U, P, R>> : T extends {
    __typename: infer Name;
} ? Name extends keyof R ? MappedRegistry<R, P>[Name & keyof R] : {
    [K in keyof T]: PatchSchema<T[K], P, R>;
} : T extends object ? {
    [K in keyof T]: PatchSchema<T[K], P, R>;
} : T;
export interface GatewayContext<TRegistry extends {
    delegate: any;
    types: any;
}> {
    delegate: <K extends keyof TRegistry['delegate'], TNeeds extends NeedsMap<TRegistry['delegate'][K]['return']> = NeedsMap<TRegistry['delegate'][K]['return']>>(key: K, ...opts: {} extends TRegistry['delegate'][K]['args'] ? [options?: {
        args?: TRegistry['delegate'][K]['args'];
        needs?: TNeeds;
    }] : [options: {
        args: TRegistry['delegate'][K]['args'];
        needs?: TNeeds;
    }]) => Promise<TRegistry['delegate'][K]['return']>;
}
declare class PylonGateway<TRegistry extends {
    delegate: any;
    types: any;
}, TPatch extends Record<string, (data: any, api: any) => any>> {
    private config;
    private apiContext;
    constructor(config: {
        url: string;
        headers?: (ctx: any) => Record<string, string>;
        patches: TPatch;
    });
    delegate<K extends keyof TRegistry['delegate'], TNeeds extends NeedsMap<TRegistry['delegate'][K]['return']> = NeedsMap<TRegistry['delegate'][K]['return']>>(key: K, ...opts: {} extends TRegistry['delegate'][K]['args'] ? [options?: {
        args?: TRegistry['delegate'][K]['args'];
        needs?: TNeeds;
    }] : [options: {
        args: TRegistry['delegate'][K]['args'];
        needs?: TNeeds;
    }]): Promise<PatchSchema<TRegistry['delegate'][K]['return'], TPatch, TRegistry['types']>>;
}
/**
 * Instantiates a factory for configuring a strongly-typed PylonGateway.
 *
 * Utilizes a generated type registry (`TRegistry`) mapping remote GraphQL typenames
 * to TypeScript interfaces, guaranteeing end-to-end type safety for configurations,
 * schema patches, and delegated execution payloads.
 *
 * @template TRegistry - Type map correlating GraphQL typenames to local TypeScript definitions.
 * @returns Gateway configuration interface.
 *
 * @example
 *
 * // Provision remote schema via CLI: pylon pull <url> -n <name>
 *
 * ```typescript
 * import { createGateway } from '@getcronit/pylon';
 * import { RemoteRegistry } from './generated/remote';
 *
 * const gateway = createGateway<RemoteRegistry>().configure({
 * url: '[https://api.example.com/graphql](https://api.example.com/graphql)',
 * headers: (ctx) => ({ Authorization: ctx.token }),
 * patches: {
 * User: (data, api) => ({ ...data, fullName: `${data.firstName} ${data.lastName}` })
 * }
 * });
 * ```
 */
export declare function createGateway<TRegistry extends {
    delegate: any;
    types: any;
}>(): {
    configure: <TPatch extends { [K in keyof TPatch]: K extends keyof TRegistry["types"] ? (data: TRegistry["types"][K], api: GatewayContext<TRegistry>) => any : never; }>(config: {
        url: string;
        headers?: (ctx: Context) => Record<string, string>;
        patches: TPatch;
    }) => PylonGateway<TRegistry, TPatch>;
};
export {};
