UNPKG

@luukgoossen/elysia-procedures

Version:

tRPC style procedures and actions with TypeBox validation

319 lines (315 loc) 14.3 kB
// 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>; } 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>; } /** * 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 {};