UNPKG

elysia

Version:

Ergonomic Framework for Human

1,125 lines 120 kB
import { type TObject, type TSchema, type TModule, type TRef, type TAnySchema } from '@sinclair/typebox'; import type { Context } from './context'; import { type Sucrose } from './sucrose'; import type { WSLocalHook } from './ws/types'; import type { ElysiaAdapter } from './adapter/types'; import type { ListenCallback, Serve, Server } from './universal/server'; import { PromiseGroup } from './utils'; import { ValidationError, type ParseError, type NotFoundError, type InternalServerError, type ElysiaCustomStatusResponse } from './error'; import type { TraceHandler } from './trace'; import type { ElysiaConfig, SingletonBase, DefinitionBase, Handler, InputSchema, LocalHook, MergeSchema, RouteSchema, UnwrapRoute, InternalRoute, HTTPMethod, PreHandler, BodyHandler, OptionalHandler, ErrorHandler, LifeCycleStore, MaybePromise, Prettify, AddPrefix, AddSuffix, AddPrefixCapitalize, AddSuffixCapitalize, MaybeArray, GracefulHandler, MapResponse, MacroToProperty, TransformHandler, MetadataBase, RouteBase, CreateEden, ComposeElysiaResponse, InlineHandler, HookContainer, LifeCycleType, EphemeralType, ExcludeElysiaResponse, ModelValidator, ContextAppendType, Reconcile, AfterResponseHandler, HigherOrderFunction, ResolvePath, JoinPath, ValidatorLayer, MergeElysiaInstances, Macro, MacroToContext, StandaloneValidator, GuardSchemaType, Or, DocumentDecoration, AfterHandler, NonResolvableMacroKey, StandardSchemaV1Like, ElysiaHandlerToResponseSchema, ElysiaHandlerToResponseSchemas, ExtractErrorFromHandle, ElysiaHandlerToResponseSchemaAmbiguous, GuardLocalHook, PickIfExists, SimplifyToSchema, UnionResponseStatus, CreateEdenResponse, MacroProperty, MaybeValueOrVoidFunction, IntersectIfObjectSchema, UnknownRouteSchema, MaybeFunction, InlineHandlerNonMacro, Router } from './types'; export type AnyElysia = Elysia<any, any, any, any, any, any, any>; /** * ### Elysia Server * Main instance to create web server using Elysia * * --- * @example * ```typescript * import { Elysia } from 'elysia' * * new Elysia() * .get("/", () => "Hello") * .listen(3000) * ``` */ export default class Elysia<const in out BasePath extends string = '', const in out Singleton extends SingletonBase = { decorator: {}; store: {}; derive: {}; resolve: {}; }, const in out Definitions extends DefinitionBase = { typebox: {}; error: {}; }, const in out Metadata extends MetadataBase = { schema: {}; standaloneSchema: {}; macro: {}; macroFn: {}; parser: {}; response: {}; }, const in out Routes extends RouteBase = {}, const in out Ephemeral extends EphemeralType = { derive: {}; resolve: {}; schema: {}; standaloneSchema: {}; response: {}; }, const in out Volatile extends EphemeralType = { derive: {}; resolve: {}; schema: {}; standaloneSchema: {}; response: {}; }> { config: ElysiaConfig<BasePath>; server: Server | null; private dependencies; '~Prefix': BasePath; '~Singleton': Singleton; '~Definitions': Definitions; '~Metadata': Metadata; '~Ephemeral': Ephemeral; '~Volatile': Volatile; '~Routes': Routes; protected singleton: SingletonBase; get store(): Singleton['store']; get decorator(): Singleton['decorator']; protected definitions: { typebox: TModule<{}, {}>; type: Record<string, TSchema | StandardSchemaV1Like>; error: Record<string, Error>; }; protected extender: { macro: Macro; higherOrderFunctions: HookContainer<HigherOrderFunction>[]; }; protected validator: ValidatorLayer; protected standaloneValidator: StandaloneValidator; event: Partial<LifeCycleStore>; protected telemetry: undefined | { stack: string | undefined; }; router: Router; protected routeTree: Record<string, number>; get routes(): InternalRoute[]; protected getGlobalRoutes(): InternalRoute[]; protected getGlobalDefinitions(): { typebox: TModule<{}, {}>; type: Record<string, TSchema | StandardSchemaV1Like>; error: Record<string, Error>; }; protected inference: Sucrose.Inference; private getServer; private getParent; '~parser': { [K: string]: BodyHandler<any, any>; }; private _promisedModules; private get promisedModules(); constructor(config?: ElysiaConfig<BasePath>); '~adapter': ElysiaAdapter; env(model: TObject<any>, _env?: NodeJS.ProcessEnv): this; /** * @private DO_NOT_USE_OR_YOU_WILL_BE_FIRED * @version 1.1.0 * * ! Do not use unless you know exactly what you are doing * ? Add Higher order function to Elysia.fetch */ wrap(fn: HigherOrderFunction): this; get models(): { [K in keyof Definitions['typebox']]: ModelValidator<Definitions['typebox'][K]>; } & { modules: TModule<Extract<Definitions['typebox'], TAnySchema>> | Extract<Definitions['typebox'], StandardSchemaV1Like>; }; private add; private setHeaders?; headers(header: Context['set']['headers'] | undefined): this; /** * ### start | Life cycle event * Called after server is ready for serving * * --- * @example * ```typescript * new Elysia() * .onStart(({ server }) => { * console.log("Running at ${server?.url}:${server?.port}") * }) * .listen(3000) * ``` */ onStart(handler: MaybeArray<GracefulHandler<this>>): this; /** * ### request | Life cycle event * Called on every new request is accepted * * --- * @example * ```typescript * new Elysia() * .onRequest(({ method, url }) => { * saveToAnalytic({ method, url }) * }) * ``` */ onRequest<const Schema extends RouteSchema, const Handler extends PreHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], { decorator: Singleton['decorator']; store: Singleton['store']; derive: {}; resolve: {}; }>>(handler: Handler): Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchema<Handler>>; }>; /** * ### request | Life cycle event * Called on every new request is accepted * * --- * @example * ```typescript * new Elysia() * .onRequest(({ method, url }) => { * saveToAnalytic({ method, url }) * }) * ``` */ onRequest<const Schema extends RouteSchema, const Handlers extends PreHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], { decorator: Singleton['decorator']; store: Singleton['store']; derive: {}; resolve: {}; }>[]>(handler: Handlers): Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchema<Handler>>; }>; /** * ### parse | Life cycle event * Callback function to handle body parsing * * If truthy value is returned, will be assigned to `context.body` * Otherwise will skip the callback and look for the next one. * * Equivalent to Express's body parser * * --- * @example * ```typescript * new Elysia() * .onParse((request, contentType) => { * if(contentType === "application/json") * return request.json() * }) * ``` */ onParse<const Schema extends RouteSchema>(parser: MaybeArray<BodyHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive'] & Ephemeral['derive'] & Volatile['derive']; resolve: {}; }>>): this; /** * ### parse | Life cycle event * Callback function to handle body parsing * * If truthy value is returned, will be assigned to `context.body` * Otherwise will skip the callback and look for the next one. * * Equivalent to Express's body parser * * --- * @example * ```typescript * new Elysia() * .onParse((request, contentType) => { * if(contentType === "application/json") * return request.json() * }) * ``` */ onParse<const Schema extends RouteSchema, const Type extends LifeCycleType>(options: { as: Type; }, parser: MaybeArray<BodyHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'] & 'global' extends Type ? { params: { [name: string]: string | undefined; }; } : 'scoped' extends Type ? { params: { [name: string]: string | undefined; }; } : {}, 'global' extends Type ? { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive'] & Partial<Ephemeral['derive'] & Volatile['derive']>; resolve: {}; } : 'scoped' extends Type ? { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive'] & Ephemeral['derive'] & Partial<Volatile['derive']>; resolve: {}; } : { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive'] & Ephemeral['derive'] & Volatile['derive']; resolve: {}; }>>): this; onParse<const Parsers extends keyof Metadata['parser']>(parser: Parsers): this; /** * ### parse | Life cycle event * Callback function to handle body parsing * * If truthy value is returned, will be assigned to `context.body` * Otherwise will skip the callback and look for the next one. * * Equivalent to Express's body parser * * --- * @example * ```typescript * new Elysia() * .onParse((request, contentType) => { * if(contentType === "application/json") * return request.json() * }) * ``` */ parser<const Parser extends string, const Schema extends RouteSchema, const Handler extends BodyHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive'] & Ephemeral['derive'] & Volatile['derive']; resolve: {}; }>>(name: Parser, parser: Handler): Elysia<BasePath, Singleton, Definitions, { schema: Metadata['schema']; standaloneSchema: Metadata['standaloneSchema']; macro: Metadata['macro']; macroFn: Metadata['macroFn']; parser: Metadata['parser'] & { [K in Parser]: Handler; }; response: Metadata['response']; }, Routes, Ephemeral, Volatile>; /** * ### transform | Life cycle event * Assign or transform anything related to context before validation. * * --- * @example * ```typescript * new Elysia() * .onTransform(({ params }) => { * if(params.id) * params.id = +params.id * }) * ``` */ onTransform<const Schema extends RouteSchema>(handler: MaybeArray<TransformHandler<UnknownRouteSchema<ResolvePath<BasePath>>, { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive'] & Ephemeral['derive'] & Volatile['derive']; resolve: {}; }>>): this; /** * ### transform | Life cycle event * Assign or transform anything related to context before validation. * * --- * @example * ```typescript * new Elysia() * .onTransform(({ params }) => { * if(params.id) * params.id = +params.id * }) * ``` */ onTransform<const Schema extends RouteSchema, const Type extends LifeCycleType>(options: { as: Type; }, handler: MaybeArray<TransformHandler<UnknownRouteSchema<'global' extends Type ? { [name: string]: string | undefined; } : 'scoped' extends Type ? { [name: string]: string | undefined; } : ResolvePath<BasePath>>, 'global' extends Type ? { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive'] & Ephemeral['derive'] & Volatile['derive']; resolve: {}; } : 'scoped' extends Type ? { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive'] & Ephemeral['derive'] & Partial<Volatile['derive']>; resolve: {}; } : { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive'] & Partial<Ephemeral['derive'] & Volatile['derive']>; resolve: {}; }>>): this; /** * Derive new property for each request with access to `Context`. * * If error is thrown, the scope will skip to handling error instead. * * --- * @example * new Elysia() * .state('counter', 1) * .derive(({ store }) => ({ * increase() { * store.counter++ * } * })) */ resolve<const Resolver extends Record<string, unknown> | ElysiaCustomStatusResponse<any, any, any>, const Type extends LifeCycleType>(options: { as: Type; }, resolver: (context: Context<MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'] & 'global' extends Type ? { params: { [name: string]: string | undefined; }; } : 'scoped' extends Type ? { params: { [name: string]: string | undefined; }; } : {}, Singleton & ('global' extends Type ? { derive: Partial<Ephemeral['derive'] & Volatile['derive']>; resolve: Partial<Ephemeral['resolve'] & Volatile['resolve']>; } : 'scoped' extends Type ? { derive: Ephemeral['derive'] & Partial<Volatile['derive']>; resolve: Ephemeral['resolve'] & Partial<Volatile['resolve']>; } : { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; })>) => MaybePromise<Resolver | void>): Type extends 'global' ? Elysia<BasePath, { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive']; resolve: Singleton['resolve'] & ExcludeElysiaResponse<Resolver>; }, Definitions, { schema: Metadata['schema']; standaloneSchema: Metadata['standaloneSchema']; macro: Metadata['macro']; macroFn: Metadata['macroFn']; parser: Metadata['parser']; response: UnionResponseStatus<Metadata['response'], ExtractErrorFromHandle<Resolver>>; }, Routes, Ephemeral, Volatile> : Type extends 'scoped' ? Elysia<BasePath, Singleton, Definitions, Metadata, Routes, { derive: Ephemeral['derive']; resolve: Ephemeral['resolve'] & ExcludeElysiaResponse<Resolver>; schema: Ephemeral['schema']; standaloneSchema: Ephemeral['standaloneSchema']; response: UnionResponseStatus<Ephemeral['response'], ExtractErrorFromHandle<Resolver>>; }, Volatile> : Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve'] & ExcludeElysiaResponse<Resolver>; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ExtractErrorFromHandle<Resolver>>; }>; /** * Derive new property for each request with access to `Context`. * * If error is thrown, the scope will skip to handling error instead. * * --- * @example * new Elysia() * .state('counter', 1) * .derive(({ store }) => ({ * increase() { * store.counter++ * } * })) */ resolve<const Resolver extends Record<string, unknown> | ElysiaCustomStatusResponse<any, any, any> | void>(resolver: (context: Context<MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton & { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; }, BasePath>) => MaybePromise<Resolver | void>): Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve'] & ExcludeElysiaResponse<Resolver>; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ExtractErrorFromHandle<Resolver>>; }>; mapResolve<const NewResolver extends Record<string, unknown> | ElysiaCustomStatusResponse<any, any, any>>(mapper: (context: Context<MergeSchema<Metadata['schema'], MergeSchema<Ephemeral['schema'], Volatile['schema']>> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton & { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; }, BasePath>) => MaybePromise<NewResolver | void>): Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: ExcludeElysiaResponse<NewResolver>; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ExtractErrorFromHandle<NewResolver>>; }>; mapResolve<const NewResolver extends Record<string, unknown> | ElysiaCustomStatusResponse<any, any, any>, const Type extends LifeCycleType>(options: { as: Type; }, mapper: (context: Context<MergeSchema<Metadata['schema'], MergeSchema<Ephemeral['schema'], Volatile['schema']>> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton & ('global' extends Type ? { derive: Partial<Ephemeral['derive'] & Volatile['derive']>; resolve: Partial<Ephemeral['resolve'] & Volatile['resolve']>; } : 'scoped' extends Type ? { derive: Ephemeral['derive'] & Partial<Volatile['derive']>; resolve: Ephemeral['resolve'] & Partial<Volatile['resolve']>; } : { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; })>) => MaybePromise<NewResolver | void>): Type extends 'global' ? Elysia<BasePath, { decorator: Singleton['decorator']; store: Singleton['store']; derive: Singleton['derive']; resolve: ExcludeElysiaResponse<NewResolver>; }, Definitions, { schema: Metadata['schema']; standaloneSchema: Metadata['standaloneSchema']; macro: Metadata['macro']; macroFn: Metadata['macroFn']; parser: Metadata['parser']; response: UnionResponseStatus<Metadata['response'], ExtractErrorFromHandle<NewResolver>>; }, Routes, Ephemeral, Volatile> : Type extends 'scoped' ? Elysia<BasePath, Singleton, Definitions, Metadata, Routes, { derive: Ephemeral['derive']; resolve: Ephemeral['resolve'] & ExcludeElysiaResponse<NewResolver>; schema: Ephemeral['schema']; standaloneSchema: Ephemeral['standaloneSchema']; response: UnionResponseStatus<Ephemeral['response'], ExtractErrorFromHandle<NewResolver>>; }, Volatile> : Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve'] & ExcludeElysiaResponse<NewResolver>; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ExtractErrorFromHandle<NewResolver>>; }>; /** * ### Before Handle | Life cycle event * Execute after validation and before the main route handler. * * If truthy value is returned, will be assigned as `Response` and skip the main handler * * --- * @example * ```typescript * new Elysia() * .onBeforeHandle(({ params: { id }, status }) => { * if(id && !isExisted(id)) { * status(401) * * return "Unauthorized" * } * }) * ``` */ onBeforeHandle<const Schema extends RouteSchema, const Handler extends OptionalHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton & { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; }>>(handler: Handler): Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchema<Handler>>; }>; /** * ### Before Handle | Life cycle event * Execute after validation and before the main route handler. * * If truthy value is returned, will be assigned as `Response` and skip the main handler * * --- * @example * ```typescript * new Elysia() * .onBeforeHandle(({ params: { id }, status }) => { * if(id && !isExisted(id)) { * status(401) * * return "Unauthorized" * } * }) * ``` */ onBeforeHandle<const Schema extends RouteSchema, const Handlers extends OptionalHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton & { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; }>[]>(handlers: Handlers): Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemas<Handlers>>; }>; /** * ### Before Handle | Life cycle event * Execute after validation and before the main route handler. * * If truthy value is returned, will be assigned as `Response` and skip the main handler * * --- * @example * ```typescript * new Elysia() * .onBeforeHandle(({ params: { id }, status }) => { * if(id && !isExisted(id)) { * status(401) * * return "Unauthorized" * } * }) * ``` */ onBeforeHandle<const Schema extends RouteSchema, const Type extends LifeCycleType, const Handler extends OptionalHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'] & 'global' extends Type ? { params: { [name: string]: string | undefined; }; } : 'scoped' extends Type ? { params: { [name: string]: string | undefined; }; } : {}, Singleton & ('global' extends Type ? { derive: Partial<Ephemeral['derive'] & Volatile['derive']>; resolve: Partial<Ephemeral['resolve'] & Volatile['resolve']>; } : 'scoped' extends Type ? { derive: Ephemeral['derive'] & Partial<Volatile['derive']>; resolve: Ephemeral['resolve'] & Partial<Volatile['resolve']>; } : { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; }), BasePath>>(options: { as: Type; }, handler: Handler): Type extends 'global' ? Elysia<BasePath, Singleton, Definitions, { schema: Metadata['schema']; standaloneSchema: Metadata['standaloneSchema']; macro: Metadata['macro']; macroFn: Metadata['macroFn']; parser: Metadata['parser']; response: UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchema<Handler>>; }, Routes, Ephemeral, Volatile> : Type extends 'scoped' ? Elysia<BasePath, Singleton, Definitions, Metadata, Routes, { derive: Ephemeral['derive']; resolve: Ephemeral['resolve']; schema: Ephemeral['schema']; standaloneSchema: Ephemeral['standaloneSchema']; response: UnionResponseStatus<Ephemeral['response'], ElysiaHandlerToResponseSchema<Handler>>; }, Volatile> : Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchema<Handler>>; }>; /** * ### Before Handle | Life cycle event * Execute after validation and before the main route handler. * * If truthy value is returned, will be assigned as `Response` and skip the main handler * * --- * @example * ```typescript * new Elysia() * .onBeforeHandle(({ params: { id }, status }) => { * if(id && !isExisted(id)) { * status(401) * * return "Unauthorized" * } * }) * ``` */ onBeforeHandle<const Schema extends RouteSchema, const Type extends LifeCycleType, const Handlers extends OptionalHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'] & 'global' extends Type ? { params: { [name: string]: string | undefined; }; } : 'scoped' extends Type ? { params: { [name: string]: string | undefined; }; } : {}, Singleton & ('global' extends Type ? { derive: Partial<Ephemeral['derive'] & Volatile['derive']>; resolve: Partial<Ephemeral['resolve'] & Volatile['resolve']>; } : 'scoped' extends Type ? { derive: Ephemeral['derive'] & Partial<Volatile['derive']>; resolve: Ephemeral['resolve'] & Partial<Volatile['resolve']>; } : { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; }), BasePath>[]>(options: { as: Type; }, handlers: Handlers): Type extends 'global' ? Elysia<BasePath, Singleton, Definitions, { schema: Metadata['schema']; standaloneSchema: Metadata['standaloneSchema']; macro: Metadata['macro']; macroFn: Metadata['macroFn']; parser: Metadata['parser']; response: UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemas<Handlers>>; }, Routes, Ephemeral, Volatile> : Type extends 'scoped' ? Elysia<BasePath, Singleton, Definitions, Metadata, Routes, { derive: Ephemeral['derive']; resolve: Ephemeral['resolve']; schema: Ephemeral['schema']; standaloneSchema: Ephemeral['standaloneSchema']; response: UnionResponseStatus<Ephemeral['response'], ElysiaHandlerToResponseSchemas<Handlers>>; }, Volatile> : Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemas<Handlers>>; }>; /** * ### After Handle | Life cycle event * Intercept request **after** main handler is called. * * If truthy value is returned, will be assigned as `Response` * * --- * @example * ```typescript * new Elysia() * .onAfterHandle((context, response) => { * if(typeof response === "object") * return JSON.stringify(response) * }) * ``` */ onAfterHandle<const Schema extends RouteSchema, const Handler extends AfterHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton & { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; }>>(handler: Handler): Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchema<Handler>>; }>; /** * ### After Handle | Life cycle event * Intercept request **after** main handler is called. * * If truthy value is returned, will be assigned as `Response` * * --- * @example * ```typescript * new Elysia() * .onAfterHandle((context, response) => { * if(typeof response === "object") * return JSON.stringify(response) * }) * ``` */ onAfterHandle<const Schema extends RouteSchema, const Handlers extends AfterHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton & { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; }>[]>(handlers: Handlers): Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemas<Handlers>>; }>; /** * ### After Handle | Life cycle event * Intercept request **after** main handler is called. * * If truthy value is returned, will be assigned as `Response` * * --- * @example * ```typescript * new Elysia() * .onAfterHandle((context, response) => { * if(typeof response === "object") * return JSON.stringify(response) * }) * ``` */ onAfterHandle<const Schema extends RouteSchema, const Type extends LifeCycleType, const Handler extends AfterHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'] & 'global' extends Type ? { params: { [name: string]: string | undefined; }; } : 'scoped' extends Type ? { params: { [name: string]: string | undefined; }; } : {}, Singleton & ('global' extends Type ? { derive: Partial<Ephemeral['derive'] & Volatile['derive']>; resolve: Partial<Ephemeral['resolve'] & Volatile['resolve']>; } : 'scoped' extends Type ? { derive: Ephemeral['derive'] & Partial<Volatile['derive']>; resolve: Ephemeral['resolve'] & Partial<Volatile['resolve']>; } : { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; })>>(options: { as: Type; }, handler: Handler): Type extends 'global' ? Elysia<BasePath, Singleton, Definitions, { schema: Metadata['schema']; standaloneSchema: Metadata['standaloneSchema']; macro: Metadata['macro']; macroFn: Metadata['macroFn']; parser: Metadata['parser']; response: UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchema<Handler>>; }, Routes, Ephemeral, Volatile> : Type extends 'scoped' ? Elysia<BasePath, Singleton, Definitions, Metadata, Routes, { derive: Ephemeral['derive']; resolve: Ephemeral['resolve']; schema: Ephemeral['schema']; standaloneSchema: Ephemeral['standaloneSchema']; response: UnionResponseStatus<Ephemeral['response'], ElysiaHandlerToResponseSchema<Handler>>; }, Volatile> : Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchema<Handler>>; }>; /** * ### After Handle | Life cycle event * Intercept request **after** main handler is called. * * If truthy value is returned, will be assigned as `Response` * * --- * @example * ```typescript * new Elysia() * .onAfterHandle((context, response) => { * if(typeof response === "object") * return JSON.stringify(response) * }) * ``` */ onAfterHandle<const Schema extends RouteSchema, const Type extends LifeCycleType, const Handlers extends AfterHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'] & 'global' extends Type ? { params: { [name: string]: string | undefined; }; } : 'scoped' extends Type ? { params: { [name: string]: string | undefined; }; } : {}, Singleton & ('global' extends Type ? { derive: Partial<Ephemeral['derive'] & Volatile['derive']>; resolve: Partial<Ephemeral['resolve'] & Volatile['resolve']>; } : 'scoped' extends Type ? { derive: Ephemeral['derive'] & Partial<Volatile['derive']>; resolve: Ephemeral['resolve'] & Partial<Volatile['resolve']>; } : { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; })>[]>(options: { as: Type; }, handler: Handlers): Type extends 'global' ? Elysia<BasePath, Singleton, Definitions, { schema: Metadata['schema']; standaloneSchema: Metadata['standaloneSchema']; macro: Metadata['macro']; macroFn: Metadata['macroFn']; parser: Metadata['parser']; response: UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemas<Handlers>>; }, Routes, Ephemeral, Volatile> : Type extends 'scoped' ? Elysia<BasePath, Singleton, Definitions, Metadata, Routes, { derive: Ephemeral['derive']; resolve: Ephemeral['resolve']; schema: Ephemeral['schema']; standaloneSchema: Ephemeral['standaloneSchema']; response: UnionResponseStatus<Ephemeral['response'], ElysiaHandlerToResponseSchemas<Handlers>>; }, Volatile> : Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemas<Handlers>>; }>; /** * ### After Handle | Life cycle event * Intercept request **after** main handler is called. * * If truthy value is returned, will be assigned as `Response` * * --- * @example * ```typescript * new Elysia() * .mapResponse((context, response) => { * if(typeof response === "object") * return JSON.stringify(response) * }) * ``` */ mapResponse<const Schema extends RouteSchema>(handler: MaybeArray<MapResponse<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton & { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; }>>): this; /** * ### After Handle | Life cycle event * Intercept request **after** main handler is called. * * If truthy value is returned, will be assigned as `Response` * * --- * @example * ```typescript * new Elysia() * .mapResponse((context, response) => { * if(typeof response === "object") * return JSON.stringify(response) * }) * ``` */ mapResponse<const Schema extends RouteSchema, Type extends LifeCycleType>(options: { as: Type; }, handler: MaybeArray<MapResponse<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'] & 'global' extends Type ? { params: { [name: string]: string | undefined; }; } : 'scoped' extends Type ? { params: { [name: string]: string | undefined; }; } : {}, Singleton & ('global' extends Type ? { derive: Partial<Ephemeral['derive'] & Volatile['derive']>; resolve: Partial<Ephemeral['resolve'] & Volatile['resolve']>; } : 'scoped' extends Type ? { derive: Ephemeral['derive'] & Partial<Volatile['derive']>; resolve: Ephemeral['resolve'] & Partial<Volatile['resolve']>; } : { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; })>>): this; /** * ### response | Life cycle event * Call AFTER main handler is executed * Good for analytic metrics * --- * @example * ```typescript * new Elysia() * .onAfterResponse(() => { * cleanup() * }) * ``` */ onAfterResponse<const Schema extends RouteSchema>(handler: MaybeArray<AfterResponseHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton & { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; }>>): this; /** * ### response | Life cycle event * Call AFTER main handler is executed * Good for analytic metrics * * --- * @example * ```typescript * new Elysia() * .onAfterResponse(() => { * cleanup() * }) * ``` */ onAfterResponse<const Schema extends RouteSchema, const Type extends LifeCycleType>(options: { as: Type; }, handler: MaybeArray<AfterResponseHandler<MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, BasePath> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'] & 'global' extends Type ? { params: { [name: string]: string | undefined; }; } : 'scoped' extends Type ? { params: { [name: string]: string | undefined; }; } : {}, Singleton & ('global' extends Type ? { derive: Partial<Ephemeral['derive'] & Volatile['derive']>; resolve: Partial<Ephemeral['resolve'] & Volatile['resolve']>; } : 'scoped' extends Type ? { derive: Ephemeral['derive'] & Partial<Volatile['derive']>; resolve: Ephemeral['resolve'] & Partial<Volatile['resolve']>; } : { derive: Ephemeral['derive'] & Volatile['derive']; resolve: Ephemeral['resolve'] & Volatile['resolve']; })>>): this; /** * ### After Handle | Life cycle event * Intercept request **after** main handler is called. * * If truthy value is returned, will be assigned as `Response` * * --- * @example * ```typescript * new Elysia() * .onAfterHandle((context, response) => { * if(typeof response === "object") * return JSON.stringify(response) * }) * ``` */ trace<const Schema extends RouteSchema>(handler: MaybeArray<TraceHandler<Schema, Singleton>>): this; /** * ### After Handle | Life cycle event * Intercept request **after** main handler is called. * * If truthy value is returned, will be assigned as `Response` * * --- * @example * ```typescript * new Elysia() * .onAfterHandle((context, response) => { * if(typeof response === "object") * return JSON.stringify(response) * }) * ``` */ trace<const Schema extends RouteSchema>(options: { as: LifeCycleType; }, handler: MaybeArray<TraceHandler<Schema, Singleton>>): this; /** * Register errors * * --- * @example * ```typescript * class CustomError extends Error { * constructor() { * super() * } * } * * new Elysia() * .error('CUSTOM_ERROR', CustomError) * ``` */ error<const Errors extends Record<string, { prototype: Error; }>>(errors: Errors): Elysia<BasePath, Singleton, { typebox: Definitions['typebox']; error: Definitions['error'] & { [K in keyof Errors]: Errors[K] extends { prototype: infer LiteralError extends Error; } ? LiteralError : Errors[K]; }; }, Metadata, Routes, Ephemeral, Volatile>; /** * Register errors * * --- * @example * ```typescript * class CustomError extends Error { * constructor() { * super() * } * } * * new Elysia() * .error({ * CUSTOM_ERROR: CustomError * }) * ``` */ error<Name extends string, const CustomError extends { prototype: Error; }>(name: Name, errors: CustomError): Elysia<BasePath, Singleton, { typebox: Definitions['typebox']; error: Definitions['error'] & { [name in Name]: CustomError extends { prototype: infer LiteralError extends Error; } ? LiteralError : CustomError; }; }, Metadata, Routes, Ephemeral, Volatile>; /** * Register errors * * --- * @example * ```typescript * class CustomError extends Error { * constructor() { * super() * } * } * * new Elysia() * .error('CUSTOM_ERROR', CustomError) * ``` */ error<const NewErrors extends Record<string, Error>>(mapper: (decorators: Definitions['error']) => NewErrors): Elysia<BasePath, Singleton, { typebox: Definitions['typebox']; error: { [K in keyof NewErrors]: NewErrors[K] extends { prototype: infer LiteralError extends Error; } ? LiteralError : never; }; }, Metadata, Routes, Ephemeral, Volatile>; /** * ### Error | Life cycle event * Called when error is thrown during processing request * * --- * @example * ```typescript * new Elysia() * .onError(({ code }) => { * if(code === "NOT_FOUND") * return "Path not found :(" * }) * ``` */ onError<const Schema extends RouteSchema, const Handler extends ErrorHandler<Definitions['error'], MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton, Ephemeral, Volatile>>(handler: Handler): Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchema<Handler>>; }>; /** * ### Error | Life cycle event * Called when error is thrown during processing request * * --- * @example * ```typescript * new Elysia() * .onError(({ code }) => { * if(code === "NOT_FOUND") * return "Path not found :(" * }) * ``` */ onError<const Schema extends RouteSchema, const Handlers extends ErrorHandler<Definitions['error'], MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Singleton, Ephemeral, Volatile>[]>(handler: Handlers): Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['derive']; resolve: Volatile['resolve']; schema: Volatile['schema']; standaloneSchema: Volatile['standaloneSchema']; response: UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemas<Handlers>>; }>; /** * ### Error | Life cycle event * Called when error is thrown during processing request * * --- * @example * ```typescript * new Elysia() * .onError(({ code }) => { * if(code === "NOT_FOUND") * return "Path not found :(" * }) * ``` */ onError<const Schema extends RouteSchema, const Type extends LifeCycleType, const Handler extends ErrorHandler<Definitions['error'], MergeSchema<Schema, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['standaloneSchema'] & Ephemeral['standaloneSchema'] & Volatile['standaloneSchema'], Type extends 'global' ? { store: Singleton['store']; decorator: Singleton['decorator']; derive: Singleton['derive'] & Ephemeral['derive'] & Volatile['derive']; resolve: Singleton['resolve'] & Ephemeral['resolve'] & Volatile['resolve']; } : Type extends 'scoped' ? { store: Singleton['store']; decorator: Singleton['decorator']; derive: Singleton['derive'] & Ephemeral['derive']; resolve: Singleton['resolve'] & Ephemeral['resolve']; } : Singleton, Type extends 'global' ? Ephemeral : { derive: Partial<Ephemeral['derive']>; resolve: Partial<Ephemeral['resolve']>; schema: Ephemeral['schema']; standaloneSchema: Ephemeral['standaloneSchema']; response: Ephemeral['response']; }, Type extends 'global' ? Ephemeral : Type extends 'scoped' ? Ephemeral : { derive: Partial<Ephemeral['derive']>; resolve: Partial<Ephemeral['resolve']>; schema: Ephemeral['schema']; standaloneSchema: Ephemeral['standaloneSchema']; response: Ephemeral['response']; }>>(options: { as: Type; }, handler: Handler): Type extends 'global' ? Elysia<BasePath, Singleton, Definitions, { schema: Metadata['schema']; standaloneSchema: Metadata['standaloneSchema']; macro: Metadata['macro']; macroFn: Metadata['macroFn']; parser: Metadata['parser']; response: UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchema<Handler>>; }, Routes, Ephemeral, Volatile> : Type extends 'scoped' ? Elysia<BasePath, Singleton, Definitions, Metadata, Routes, { derive: Ephemeral['derive']; resolve: Ephemeral['resolve']; schema: Ephemeral['schema']; standaloneSchema: Ephemeral['standaloneSchema']; response: UnionResponseStatus<Ephemeral['response'], ElysiaHandlerToResponseSchema<Handler>>; }, Volatile> : Elysia<BasePath, Singleton, Definitions, Metadata, Routes, Ephemeral, { derive: Volatile['