// Generated by dts-bundle-generator v9.5.1

import { Static, TObject, TSchema } from '@sinclair/typebox';
import { Cookie, DocumentDecoration } from 'elysia';
import { Merge, Promisable, Simplify } from 'type-fest';

/**
 * Base context available in all procedures.
 */
export type Context = {
	/** The received HTTP request */
	request: Request;
	cookie: Record<string, Cookie<string | undefined>>;
};
/**
 * A utlity type that ensures a TObject (Next) does not have any overlapping properties with an opional reference TObject (Prev).
 */
export type SafeTObject<Next extends TObject, Prev extends TObject | undefined = undefined> = Prev extends TObject ? (Extract<keyof Prev["properties"], keyof Next["properties"]> extends never ? Next : never) : Next;
/**
 * A utility type that checks the properties of a TypeBox object schema.
 */
export type CheckProperties<T extends TObject | undefined> = T extends TObject ? T["properties"] : unknown;
/**
 * A utility type that merges the properties of two TypeBox object schemas.
 * The second schema is optional and can be undefined.
 */
export type MergedProperties<Next extends TObject, Prev extends TObject | undefined = undefined> = Merge<Next["properties"], CheckProperties<Prev>>;
/**
 * A utility type that merges two TypeBox objects into one.
 * The next schema's properties will override the previous schema's properties.
 */
export type MergedObject<Next extends TObject | never, Prev extends TObject | undefined = undefined> = Next extends TObject ? TObject<Simplify<MergedProperties<Next, Prev>>> : Prev;
/**
 * Arguments passed to procedure handler functions.
 */
export type ProcedureFnArgs<Ctx extends Context, Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined> = {
	/** Context object with request data and middleware results */
	ctx: Simplify<Ctx>;
	/** Parsed and validated route parameters */
	params: Params extends TObject ? Static<Params> : undefined;
	/** Parsed and validated query parameters */
	query: Query extends TObject ? Static<Query> : undefined;
	/** Parsed and validated request body */
	body: Body extends TObject ? Static<Body> : undefined;
};
/**
 * Function type for procedure middleware functions.
 */
export type ProcedureFn<Ctx extends Context, Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined, Next = object | void> = (input: ProcedureFnArgs<Ctx, Params, Query, Body>) => Promisable<Next>;
/**
 * Type alias for any middleware type.
 */
export type AnyMiddleware = Middleware<any, any, any, any>;
declare class Middleware<Ctx extends Context, Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined, Next = object | void> {
	private _id;
	private _handler;
	private _keys?;
	/** Name of the middleware for identification */
	name: string;
	constructor(handler: ProcedureFn<Ctx, Params, Query, Body, Next>, name: string, keys?: ProcedureFn<Ctx, Params, Query, Body, string[]>);
	/**
	 * Executes this middleware with the provided input
	 * @param input - The current procedure arguments
	 * @returns - The additional context created by the middleware to be merged into the procedure
	 */
	execute: (input: ProcedureFnArgs<Ctx, Params, Query, Body>) => Promise<any>;
}
/**
 * Configuration arguments for creating an action builder.
 */
export type ActionBuilderArgs<Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined, Output extends TSchema | undefined> = {
	/** TypeBox schema for route parameters */
	params: Params;
	/** TypeBox schema for query parameters */
	query: Query;
	/** TypeBox schema for request body */
	body: Body;
	/** TypeBox schema for response output */
	output: Output;
	/** Chain of middleware to execute before the action's main handler function */
	middlewares: AnyMiddleware[];
	/** Name of the action for identification */
	name: string;
	/** API documentation details for the action */
	details?: DocumentDecoration;
};
/**
 * Configuration arguments for creating an action.
 */
export type ActionArgs<Ctx extends Context, Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined, Output extends TSchema | undefined> = ActionBuilderArgs<Params, Query, Body, Output> & {
	/** The main handler function of the action */
	handler: ActionFn<Ctx, Params, Query, Body, Output>;
};
/**
 * Function type for action's main handler functions.
 */
export type ActionFn<Ctx extends Context, Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined, Output extends TSchema | undefined, Out = Output extends TSchema ? Static<Output> : any> = (input: ProcedureFnArgs<Ctx, Params, Query, Body>) => Promisable<Out>;
/**
 * Builder class for creating actions with a type-safe API.
 * Enables chaining methods to require parameters, query, body, output and handlers.
 */
export declare class ActionBuilder<Ctx extends Context, Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined, Output extends TSchema | undefined> {
	private _state;
	constructor(base: ActionBuilderArgs<Params, Query, Body, Output>);
	/**
	 * Creates a new builder with applied changes.
	 * @param changes - Partial action configuration to apply
	 * @returns A new ActionBuilder with updated configuration
	 * @private
	 */
	private _apply;
	/**
	 * Adds or merges route parameter definitions to the action.
	 * @param params - The TypeBox schema defining the route parameters
	 */
	params: <T extends TObject>(params: SafeTObject<T, Params>) => ActionBuilder<Ctx, MergedObject<SafeTObject<T, Params>, Params>, Query, Body, Output>;
	/**
	 * Adds or merges query parameter definitions to the action.
	 * @param query - The TypeBox schema defining the query parameters
	 */
	query: <T extends TObject>(query: SafeTObject<T, Query>) => ActionBuilder<Ctx, Params, MergedObject<SafeTObject<T, Query>, Query>, Body, Output>;
	/**
	 * Adds or merges request body definitions to the action.
	 * @param body - The TypeBox schema defining the request body
	 */
	body: <T extends TObject>(body: SafeTObject<T, Body>) => ActionBuilder<Ctx, Params, Query, MergedObject<SafeTObject<T, Body>, Body>, Output>;
	/**
	 * Adds response output definitions to the action.
	 * @param output - The TypeBox schema defining the reponse output
	 */
	output: <T extends TSchema>(output: T) => ActionBuilder<Ctx, Params, Query, Body, T>;
	/**
	 * Builds this action with the given handler function.
	 * @param handler - The function to execute when this action is called
	 * @returns A built action with the given handler
	 */
	build: <Out>(handler: ActionFn<Ctx, Params, Query, Body, Output, Output extends TSchema ? Static<Output> : Out>) => Action<Ctx, Params, Query, Body, Output, Output extends TSchema ? (Output & {
		params: [
		];
	})["static"] : Out>;
}
/**
 * An action is a common interface to query or mutate data.
 * It contains both the business logic and the API documentation.
 */
export declare class Action<Ctx extends Context, Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined, Output extends TSchema | undefined, Out> {
	private _handler;
	private _middlewares;
	/** Name of the action for identification */
	name: string;
	/** API documentation details for the action */
	details?: DocumentDecoration;
	/** TypeBox schema for route parameters */
	params: Params;
	/** TypeBox schema for query parameters */
	query: Query;
	/** TypeBox schema for request body */
	body: Body;
	/** TypeBox schema for response output */
	output: Output;
	constructor(input: ActionArgs<Ctx, Params, Query, Body, Output>);
	/**
	 * The API documentation for the action in Elysia route handler format.
	 */
	get docs(): {
		params: any;
		query: Query;
		body: Body;
		response: Output;
		detail: {
			tags?: string[];
			summary: string;
			description?: string;
			externalDocs?: import("openapi-types").OpenAPIV3.ExternalDocumentationObject;
			operationId: string;
			parameters?: (import("openapi-types").OpenAPIV3.ReferenceObject | import("openapi-types").OpenAPIV3.ParameterObject)[];
			requestBody?: import("openapi-types").OpenAPIV3.ReferenceObject | import("openapi-types").OpenAPIV3.RequestBodyObject;
			responses?: import("openapi-types").OpenAPIV3.ResponsesObject | undefined;
			callbacks?: {
				[callback: string]: import("openapi-types").OpenAPIV3.ReferenceObject | import("openapi-types").OpenAPIV3.CallbackObject;
			};
			deprecated?: boolean;
			security?: import("openapi-types").OpenAPIV3.SecurityRequirementObject[];
			servers?: import("openapi-types").OpenAPIV3.ServerObject[];
			hide?: boolean;
		};
	};
	/**
	 * Elysia handler for the action
	 *
	 * This method does not validate the inputs, as Elysia REST's handlers will do it for us with nicer errors.
	 * Do not use this method outside of Elysia's REST handlers.
	 * @param context The Elysia context
	 * @returns
	 */
	handle: (context: Context & {
		params: Params extends TObject ? Static<Params> : any;
		query: Query extends TObject ? Static<Query> : any;
		body: Body extends TObject ? Static<Body> : any;
	}) => Promise<Out>;
	/**
	 * General handler for the action
	 * @param request The HTTP request
	 * @param input The inputs for the action
	 * @returns
	 */
	run: (ctx: Context, input: {
		params: Params extends TObject ? Static<Params> : any;
		query: Query extends TObject ? Static<Query> : any;
		body: Body extends TObject ? Static<Body> : any;
	}) => Promise<Out>;
	private _execute;
}

export {};
