@luukgoossen/elysia-procedures
Version:
tRPC style procedures and actions with TypeBox validation
319 lines (315 loc) • 14.3 kB
TypeScript
// 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;
/**
* A utility type that merges the context of a procedure with an optional next context.
* The next context can be an object or void.
*/
export type MergedContext<Ctx extends Context, Next extends object | void = void> = Simplify<Context & Merge<Ctx, Next extends object ? Next : unknown>>;
/**
* Configuration arguments for creating a procedure.
*/
export type ProcedureArgs<Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined> = {
/** TypeBox schema for route parameters */
params: Params;
/** TypeBox schema for query parameters */
query: Query;
/** TypeBox schema for request body */
body: Body;
/** Chain of middleware to execute before the main action handler */
middlewares: AnyMiddleware[];
/** Name of the procedure for identification */
name: string;
};
/**
* 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>;
/**
* Middleware class representing a function to run during request processing.
* A middleware processes requests before they reach the main action handler.
*/
export 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>;
}
/**
* Builder class for creating procedures with a type-safe API.
* Enables chaining methods to require parameters, query, body, and handlers.
*/
export declare class ProcedureBuilder<Ctx extends Context, Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined> {
private _state;
constructor(base: ProcedureArgs<Params, Query, Body>);
/**
* Creates a new builder with applied changes.
* @param changes - Partial procedure configuration to apply
* @returns A new ProcedureBuilder with updated configuration
* @private
*/
private _apply;
/**
* Adds or merges route parameter definitions to the procedure.
* @param params - The TypeBox schema defining the route parameters
*/
params: <T extends TObject>(params: SafeTObject<T, Params>) => ProcedureBuilder<Ctx, MergedObject<SafeTObject<T, Params>, Params>, Query, Body>;
/**
* Adds or merges query parameter definitions to the procedure.
* @param query - The TypeBox schema defining the query parameters
*/
query: <T extends TObject>(query: SafeTObject<T, Query>) => ProcedureBuilder<Ctx, Params, MergedObject<SafeTObject<T, Query>, Query>, Body>;
/**
* Adds or merges request body definitions to the procedure.
* @param body - The TypeBox schema defining the request body
*/
body: <T extends TObject>(body: SafeTObject<T, Body>) => ProcedureBuilder<Ctx, Params, Query, MergedObject<SafeTObject<T, Body>, Body>>;
/**
* Adds cache keys to the procedure.
* @param keys - The function to compute the cache keys
*/
cache: (keys: ProcedureFn<Ctx, Params, Query, Body, string[]>) => ProcedureBuilder<Ctx, Params, Query, Body>;
/**
* Builds this procedure with the given handler function.
* @param handler - The function to execute when this procedure is called
* @returns A built procedure with the given handler
*/
build: <Next extends object | void>(handler?: ProcedureFn<Ctx, Params, Query, Body, Next>) => Procedure<MergedContext<Ctx, Next>, Params, Query, Body>;
}
/**
* A procedure acts as a base for creating actions.
* It predefines and handles parameters, query, body, and middlewares.
* The procedure can be extended to create more specific procedures
* or used to create actions directly.
*/
export declare class Procedure<Ctx extends Context, Params extends TObject | undefined, Query extends TObject | undefined, Body extends TObject | undefined> {
/** TypeBox schema for route parameters */
params: Params;
/** TypeBox schema for query parameters */
query: Query;
/** TypeBox schema for request body */
body: Body;
/** Chain of middleware to execute before the main action handler */
middlewares: AnyMiddleware[];
constructor(base: ProcedureArgs<Params, Query, Body>);
/**
* Creates a new action from this procedure.
* @param name - Name of the action for identification
* @param details - API documentation details for the action
* @returns A new ActionBuilder instance
*/
createAction: (name: string, details?: DocumentDecoration) => ActionBuilder<Ctx, Params, Query, Body, undefined>;
}
/**
* Creates a new procedure builder with typed params, query, and body.
*
* @param name - Descriptive name for the procedure (used in logs and debugging)
* @param base - Optional base procedure to inherit from
* @param role - Optional role for authorization purposes
*
* @example
* ```ts
* const userProcedure = createProcedure('User Authentication')
* .params(Type.Object({
* id: Type.String()
* }))
* .handler(({ params }) => ({
* user: {
* id: params.id,
* name: "John Doe"
* }
* }))
* ```
*/
export declare const createProcedure: <Ctx extends Context, Params extends TObject | undefined = undefined, Query extends TObject | undefined = undefined, Body extends TObject | undefined = undefined>(name: string, base?: Procedure<Ctx, Params, Query, Body>) => ProcedureBuilder<Ctx, Params, Query, Body>;
/**
* 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>;
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>;
}
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 {};