Comparing version 0.3.0-exp-240225.2119 to 0.3.0-rc.0
@@ -1,1 +0,1 @@ | ||
import{Type as e}from"@sinclair/typebox";import{TypeSystem as t}from"@sinclair/typebox/system";let i=e=>{if("string"==typeof e)switch(e.slice(-1)){case"k":return 1024*+e.slice(0,e.length-1);case"m":return 1048576*+e.slice(0,e.length-1);default:return+e}return e},r=(e,t)=>{if(!(t instanceof Blob)||e.minSize&&t.size<i(e.minSize)||e.maxSize&&t.size>i(e.maxSize))return!1;if(e.extension){if("string"==typeof e.extension){if(!t.type.startsWith(e.extension))return!1}else{for(let i=0;i<e.extension.length;i++)if(t.type.startsWith(e.extension[i]))return!0;return!1}}return!0};export const ElysiaType={File:t.CreateType("File",r),Files:t.CreateType("Files",(e,t)=>{if(!Array.isArray(t)||e.minItems&&t.length<e.minItems||e.maxItems&&t.length>e.maxItems)return!1;for(let i=0;i<t.length;i++)if(!r(e,t[i]))return!1;return!0})};e.File=e=>ElysiaType.File({default:"File",...e,extension:e?.type,type:"string",format:"binary"}),e.Files=e=>ElysiaType.Files({default:"Files",...e,extension:e?.type,type:"string",format:"binary"});export{e as t}; | ||
import{Type as e}from"@sinclair/typebox";import{TypeSystem as t}from"@sinclair/typebox/system";let i=e=>{if("string"==typeof e)switch(e.slice(-1)){case"k":return 1024*+e.slice(0,e.length-1);case"m":return 1048576*+e.slice(0,e.length-1);default:return+e}return e},r=(e,t)=>{if(!(t instanceof Blob)||e.minSize&&t.size<i(e.minSize)||e.maxSize&&t.size>i(e.maxSize))return!1;if(e.extension){if("string"==typeof e.extension){if(!t.type.startsWith(e.extension))return!1}else{for(let i=0;i<e.extension.length;i++)if(t.type.startsWith(e.extension[i]))return!0;return!1}}return!0};export const ElysiaType={File:t.CreateType("File",r),Files:t.CreateType("Files",(e,t)=>{if(!Array.isArray(t)||e.minItems&&t.length<e.minItems||e.maxItems&&t.length>e.maxItems)return!1;for(let i=0;i<t.length;i++)if(!r(e,t[i]))return!1;return!0})};e.File=e=>ElysiaType.File({default:"File",...e,extension:e?.type,type:"string",format:"binary"}),e.Files=e=>ElysiaType.Files({...e,default:"Files",extension:e?.type,type:"array",items:{...e,default:"Files",type:"string",format:"binary"}});export{e as t}; |
@@ -1,1 +0,1 @@ | ||
import{EXPOSED as e}from"./utils";import{serialize as n}from"superjson";export const permission=({value:n,allow:r,deny:i,check:t=!0})=>({[e]:!0,value:n,check:t,allow:r,deny:i});export const runFn=(r,i)=>{let t=[],o=r.body;e:for(let n=0;n<o.length;n++){let c=o[n],l=i,u=c.n;if(!Array.isArray(c.n)){t.push(Error("Invalid procedure"));continue e}let s=u[u.length-1];if(1===u.length){if(s in l&&e in l[s]){if(!1==l[s].check){t.push(Error("Forbidden"));continue e}if(!0!==l[s].check){try{let e=l[s].check({...r,key:s,params:c.p??null,match(e){}});if(e instanceof Error){t.push(e);continue e}}catch(e){t.push(e);continue e}l=l[s],s="value"}}}else for(let n=0;n<u.length-1;n++){if(!(l=l[u[n]])){t.push(Error("Invalid procedure"));continue e}if(e in l){let e=u.slice(n+1).join("."),i="function"==typeof l.check;if(!0===l.allow?.includes(e)&&!i){l=l.value;continue}if(!1!=l.check&&!0!==l.deny?.includes(e)&&(!1!==l.allow?.includes(e)||l.deny||i)){if(!0!==l.check)try{let n;let i=l.check({...r,key:e,params:c.p??null,match(e){n=e}});if(n)try{let r=(n[e]??n.default)?.(c.p??null);if(r instanceof Error)throw r}catch(r){if(!(e in n)&&l.allow?.includes(e)){l=l.value;continue}t.push(r);continue e}if(i instanceof Error){t.push(i);continue e}}catch(e){t.push(e);continue e}}else{t.push(Error("Forbidden"));continue e}l=l.value}}try{"function"!=typeof l[s]?t.push(Error("Invalid procedure")):void 0===c.p?t.push(l[s]()):1===c.p.length?t.push(l[s](c.p[0])):t.push(l[s](...c.p))}catch(e){t.push(e)}}return Promise.all(t).then(n)}; | ||
import{EXPOSED as e}from"./utils";import{serialize as n}from"superjson";export const permission=({value:n,allow:t,deny:r,check:i=!0})=>({[e]:!0,value:n,check:i,allow:t,deny:r});export const runFn=(t,r)=>{let i=[],l=t.body;e:for(let n=0;n<l.length;n++){let o=l[n],u=r,c=o.n;if(!Array.isArray(o.n)){i.push(Error("Invalid procedure"));continue e}let s=c[c.length-1];if(1===c.length){if(s in u&&e in u[s]){if(!1==u[s].check){i.push(Error("Forbidden"));continue e}if(!0!==u[s].check){try{let e=u[s].check({...t,key:s,params:o.p??null,match(e){}});if(e instanceof Error){i.push(e);continue e}}catch(e){i.push(e);continue e}u=u[s],s="value"}}}else for(let n=0;n<c.length-1;n++){if(!(u=u[c[n]])){i.push(Error("Invalid procedure"));continue e}if(e in u){let e=c.slice(n+1).join("."),r="function"==typeof u.check;if(!0===u.allow?.includes(e)&&!r){u=u.value;continue}if(!1!=u.check&&!0!==u.deny?.includes(e)&&(!1!==u.allow?.includes(e)||u.deny||r)){if(!0!==u.check)try{let n;let r=u.check({...t,key:e,params:o.p??null,match(e){n=e}});if(n)try{let t=(n[e]??n.default)?.(o.p??null);if(t instanceof Error)throw t}catch(t){if(!(e in n)&&u.allow?.includes(e)){u=u.value;continue}i.push(t);continue e}if(r instanceof Error){i.push(r);continue e}}catch(e){i.push(e);continue e}}else{i.push(Error("Forbidden"));continue e}u=u.value}}try{"function"!=typeof u[s]?i.push(Error("Invalid procedure")):void 0===o.p?i.push(u[s]()):1===o.p.length?i.push(u[s](o.p[0])):i.push(u[s](...o.p))}catch(e){i.push(e)}}return Promise.allSettled(i).then(e=>{let n=[];for(let t=0;t<e.length;t++){let r=e[t];"fulfilled"===r.status?n.push(r.value):n.push(r.reason)}return n}).then(n)}; |
@@ -6,4 +6,5 @@ /// <reference types="bun-types" /> | ||
import type { Context } from './context'; | ||
import type { Handler, BeforeRequestHandler, TypedRoute, ElysiaInstance, ElysiaConfig, HTTPMethod, InternalRoute, BodyParser, ErrorHandler, TypedSchema, LocalHook, LocalHandler, LifeCycle, LifeCycleEvent, LifeCycleStore, VoidLifeCycle, AfterRequestHandler, IsAny, OverwritableTypeRoute, MergeSchema, ListenCallback, NoReturnHandler, ElysiaRoute, MaybePromise, IsNever } from './types'; | ||
import type { Handler, BeforeRequestHandler, TypedRoute, ElysiaInstance, ElysiaConfig, HTTPMethod, InternalRoute, BodyParser, ErrorHandler, TypedSchema, LocalHook, LocalHandler, LifeCycle, LifeCycleEvent, LifeCycleStore, VoidLifeCycle, AfterRequestHandler, IsAny, OverwritableTypeRoute, MergeSchema, ListenCallback, NoReturnHandler, MaybePromise, IsNever, MergeUnionObjects, TypedRouteToEden } from './types'; | ||
import { type TSchema } from '@sinclair/typebox'; | ||
import { ElysiaWSOptions, WSTypedSchema } from './ws'; | ||
export default class Elysia<Instance extends ElysiaInstance = ElysiaInstance> { | ||
@@ -19,2 +20,3 @@ config: ElysiaConfig; | ||
protected routes: InternalRoute<Instance>[]; | ||
private wsRouter; | ||
private lazyLoadModules; | ||
@@ -56,13 +58,113 @@ constructor(config?: Partial<ElysiaConfig>); | ||
}>): IsNever<LazyLoadElysia> extends false ? Elysia<LazyLoadElysia & Instance> : NewElysia extends Elysia<infer NewInstance> ? IsNever<NewInstance> extends true ? Elysia<Instance> : Elysia<NewInstance & Instance> : NewElysia extends Promise<Elysia<infer NewInstance>> ? Elysia<NewInstance & Instance> : this; | ||
get<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'GET', Schema, Instance, Path, Response>; | ||
post<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'POST', Schema, Instance, Path, Response>; | ||
put<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'PUT', Schema, Instance, Path, Response>; | ||
patch<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'PATCH', Schema, Instance, Path, Response>; | ||
delete<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'DELETE', Schema, Instance, Path, Response>; | ||
options<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'OPTIONS', Schema, Instance, Path, Response>; | ||
all<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'ALL', Schema, Instance, Path, Response>; | ||
head<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'HEAD', Schema, Instance, Path, Response>; | ||
trace<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'TRACE', Schema, Instance, Path, Response>; | ||
connect<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Response = unknown>(path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<'CONNECT', Schema, Instance, Path, Response>; | ||
route<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Method extends HTTPMethod = HTTPMethod, Path extends string = string, Response = unknown>(method: Method, path: Path, handler: LocalHandler<Schema, Instance, Path, Response>, hook?: LocalHook<Schema, Instance, Path>): ElysiaRoute<Method, Schema, Instance, Path, Response>; | ||
get<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'get']: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
post<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'post']: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
put<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'put']: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
patch<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'patch']: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
delete<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'delete']: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
options<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'options']: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
all<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'all']: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
head<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'head']: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
trace<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'trace']: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
connect<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'connect']: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
ws<Path extends string = '', Schema = {}>(path: Path, options: Path extends '' ? never : this extends Elysia<infer Instance> ? ElysiaWSOptions<Path, Schema extends WSTypedSchema ? Schema : WSTypedSchema, Instance['meta'][typeof DEFS]> : never): this extends Elysia<infer Instance> ? Elysia<Instance> : ElysiaInstance; | ||
route<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = {}, Method extends HTTPMethod = HTTPMethod, Path extends string = string, Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler<Schema, Instance, Path>>(method: Method, path: Path, handler: Handler, hook?: LocalHook<Schema, Instance, Path>): Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & Record<typeof SCHEMA, MergeUnionObjects<Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in Uppercase<Method>]: TypedRouteToEden<Schema, Instance['meta'][typeof DEFS], Path, ReturnType<Handler>>; | ||
}; | ||
}>>; | ||
}>; | ||
state<Key extends string | number | symbol = keyof Instance['store'], Value = Instance['store'][keyof Instance['store']], NewInstance = Elysia<{ | ||
@@ -102,5 +204,5 @@ store: Instance['store'] & { | ||
schema: Instance['schema']; | ||
meta: Instance['meta'] & Record<typeof EXPOSED, T extends (store: any) => infer Returned ? Returned : T>; | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED] & (T extends (store: any) => infer Returned ? Returned : T)> & Record<typeof SCHEMA, Instance['meta'][typeof SCHEMA]>; | ||
}>; | ||
schema<Schema extends TypedSchema<Exclude<keyof Instance['store'][typeof DEFS], number | symbol>> = TypedSchema<Exclude<keyof Instance['store'][typeof DEFS], number | symbol>>, NewInstance = Elysia<{ | ||
schema<Schema extends TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>> = TypedSchema<Exclude<keyof Instance['meta'][typeof DEFS], number | symbol>>, NewInstance = Elysia<{ | ||
request: Instance['request']; | ||
@@ -125,4 +227,5 @@ store: Instance['store']; | ||
export { t } from './custom-types'; | ||
export { ws } from './ws'; | ||
export { SCHEMA, DEFS, EXPOSED, createValidationError, getSchemaValidator, mergeDeep, mergeHook, mergeObjectArray, mapPathnameAndQueryRegEx, mapQuery } from './utils'; | ||
export type { Context, PreContext } from './context'; | ||
export type { Handler, RegisteredHook, BeforeRequestHandler, TypedRoute, OverwritableTypeRoute, ElysiaInstance, ElysiaConfig, HTTPMethod, ComposedHandler, InternalRoute, BodyParser, ErrorHandler, ErrorCode, TypedSchema, LocalHook, LocalHandler, LifeCycle, LifeCycleEvent, AfterRequestHandler, HookHandler, TypedSchemaToRoute, UnwrapSchema, LifeCycleStore, VoidLifeCycle, SchemaValidator, ElysiaRoute, ExtractPath, IsPathParameter, IsAny, IsNever, UnknownFallback, WithArray, ObjectValues, PickInOrder, MaybePromise, MergeIfNotNull } from './types'; | ||
export type { Handler, RegisteredHook, BeforeRequestHandler, TypedRoute, OverwritableTypeRoute, ElysiaInstance, ElysiaConfig, HTTPMethod, ComposedHandler, InternalRoute, BodyParser, ErrorHandler, ErrorCode, TypedSchema, LocalHook, LocalHandler, LifeCycle, LifeCycleEvent, AfterRequestHandler, HookHandler, TypedSchemaToRoute, UnwrapSchema, LifeCycleStore, VoidLifeCycle, SchemaValidator, ExtractPath, IsPathParameter, IsAny, IsNever, UnknownFallback, WithArray, ObjectValues, PickInOrder, MaybePromise, MergeIfNotNull, ElysiaDefaultMeta, TypedRouteToEden, AnyTypedSchema, RouteToSchema, DeepMergeTwoTypes, ConnectedKeysType } from './types'; |
@@ -1,1 +0,1 @@ | ||
import{Raikiri as e}from"raikiri";import{mapResponse as t,mapEarlyResponse as r}from"./handler";import{permission as s}from"./fn";import{SCHEMA as a,EXPOSED as n,DEFS as i,mapQuery as o,clone as h,mergeHook as l,mergeDeep as u,createValidationError as d,getSchemaValidator as f,getResponseSchemaValidator as c,mapPathnameAndQueryRegEx as m}from"./utils";import{registerSchemaPath as p}from"./schema";import{mapErrorCode as v,mapErrorStatus as g}from"./error";import{runFn as y}from"./fn";import{deserialize as b}from"superjson";export default class H{store={};meta={[a]:Object.create(null),[i]:Object.create(null),[n]:Object.create(null)};decorators={query:{},set:{status:200,headers:{}},store:this.store,[a]:this.meta[a],[i]:this.meta[i]};event={start:[],request:[],parse:[],transform:[],beforeHandle:[],afterHandle:[],error:[],stop:[]};server=null;$schema=null;router=new e;routes=[];lazyLoadModules=[];constructor(e){this.config={fn:"/~fn",...e}}_addHandler(e,t,r,s){t=t.startsWith("/")?t:`/${t}`,this.routes.push({method:e,path:t,handler:r,hooks:l(h(this.event),s)});let n=this.meta[i],o=f(s?.schema?.body??this.$schema?.body,n),u=f(s?.schema?.headers??this.$schema?.headers,n,!0),d=f(s?.schema?.params??this.$schema?.params,n),m=f(s?.schema?.query??this.$schema?.query,n),v=c(s?.schema?.response??this.$schema?.response,n);p({schema:this.meta[a],contentType:s?.schema?.contentType,hook:s,method:e,path:t,models:this.meta[i]});let g=l(h(this.event),s);g.schema||g.transform.length||g.beforeHandle.length||g.error.length||g.afterHandle.length||(g=void 0);let y={handle:r,hooks:g,validator:o||u||d||m||v?{body:o,header:u,params:d,query:m,response:v}:void 0};this.router.add(e,t,y)}onStart(e){return this.event.start.push(e),this}onRequest(e){return this.event.request.push(e),this}onParse(e){return this.event.parse.splice(this.event.parse.length-1,0,e),this}onTransform(e){return this.event.transform.push(e),this}onBeforeHandle(e){return this.event.beforeHandle.push(e),this}onAfterHandle(e){return this.event.afterHandle.push(e),this}onError(e){return this.event.error.push(e),this}onStop(e){return this.event.stop.push(e),this}on(e,t){switch(e){case"start":this.event.start.push(t);break;case"request":this.event.request.push(t);break;case"parse":this.event.parse.push(t);break;case"transform":this.event.transform.push(t);break;case"beforeHandle":this.event.beforeHandle.push(t);break;case"afterHandle":this.event.afterHandle.push(t);break;case"error":this.event.error.push(t);break;case"stop":this.event.stop.push(t)}return this}group(e,t){let r=new H;r.store=this.store;let s=t(r);return s.event.request.length&&(this.event.request=[...this.event.request,...s.event.request]),Object.values(r.routes).forEach(({method:t,path:r,handler:a,hooks:n})=>{"/"===r?this._addHandler(t,e,a,l(n,{error:s.event.error})):this._addHandler(t,`${e}${r}`,a,l(n,{error:s.event.error}))}),this}guard(e,t){let r=new H;r.store=this.store;let s=t(r);return s.event.request.length&&(this.event.request=[...this.event.request,...s.event.request]),Object.values(r.routes).forEach(({method:t,path:r,handler:s,hooks:a})=>{this._addHandler(t,r,s,l(e,a))}),this}use(e){if(e instanceof Promise)return this.lazyLoadModules.push(e.then(e=>"function"==typeof e?e(this):e.default(this))),this;let t=e(this);return t instanceof Promise?(this.lazyLoadModules.push(t),this):t}get(e,t,r){return this._addHandler("GET",e,t,r),this}post(e,t,r){return this._addHandler("POST",e,t,r),this}put(e,t,r){return this._addHandler("PUT",e,t,r),this}patch(e,t,r){return this._addHandler("PATCH",e,t,r),this}delete(e,t,r){return this._addHandler("DELETE",e,t,r),this}options(e,t,r){return this._addHandler("OPTIONS",e,t,r),this}all(e,t,r){return this._addHandler("ALL",e,t,r),this}head(e,t,r){return this._addHandler("HEAD",e,t,r),this}trace(e,t,r){return this._addHandler("TRACE",e,t,r),this}connect(e,t,r){return this._addHandler("CONNECT",e,t,r),this}route(e,t,r,s){return this._addHandler(e,t,r,s),this}state(e,t){return e in this.store||(this.store[e]=t),this}decorate(e,t){return e in this.decorators||(this.decorators[e]=t),this}inject(e){return this.onTransform(t=>{Object.assign(t,e(t))})}fn(e){return 0===Object.keys(this.meta[n]).length&&this.post(this.config.fn??"/~fn",e=>y(e,this.meta[n])),this.meta[n]=u(this.meta[n],"function"==typeof e?e({...this.decorators,store:this.store,permission:s}):e),this}schema(e){let t=this.meta[i];return this.$schema={body:f(e.body,t),headers:f(e?.headers,t,!0),params:f(e?.params,t),query:f(e?.query,t),response:f(e?.response,t)},this}handle=async e=>{let s;let a=h(this.decorators);a.request=e;try{let n;if(this.event.request.length)for(let e=0;e<this.event.request.length;e++){let t=this.event.request[e](a);if(t instanceof Promise&&(t=await t),t=r(t,a.set))return t}let i=e.url.match(m);if(!i)throw Error("NOT_FOUND");let h=this.router.match(e.method,i[1])??this.router.match("ALL",i[1]);if(!h)throw Error("NOT_FOUND");let l=h.store,u=l.hooks;if(u?.error&&(s=u?.error),"GET"!==e.method){let t=e.headers.get("content-type");if(t){let r=t.indexOf(";");if(-1!==r&&(t=t.slice(0,r)),this.event.parse.length)for(let e=0;e<this.event.parse.length;e++){let r=this.event.parse[e](a,t);if(r instanceof Promise&&(r=await r),void 0!==r){n=r;break}}if(void 0===n)switch(t){case"application/json":n=await e.json();break;case"text/plain":n=await e.text();break;case"application/x-www-form-urlencoded":n=o(await e.text());break;case"multipart/form-data":n={},await e.formData().then(e=>{for(let t of e.keys()){if(t in n)continue;let r=e.getAll(t);1===r.length?n[t]=r[0]:n[t]=r}});break;case"elysia/fn":n=b(await e.json())}}}if(a.body=n,a.params=h.params,i[2]&&(a.query=o(i[2])),u?.transform.length)for(let e=0;e<u.transform.length;e++){let t=u.transform[e](a);t instanceof Promise&&await t}if(l.validator){let t=l.validator;if(u?.error&&(s=u?.error),t.headers){let r={};for(let t in e.headers)r[t]=e.headers.get(t);if(!1===t.headers.Check(r))throw d("header",t.headers,r)}if(!1===t.params?.Check(a.params))throw d("params",t.params,a.params);if(!1===t.query?.Check(a.query))throw d("query",t.query,a.query);if(!1===t.body?.Check(n))throw d("body",t.body,n)}if(u?.beforeHandle.length)for(let e=0;e<u.beforeHandle.length;e++){let t=u.beforeHandle[e](a);if(t instanceof Promise&&(t=await t),null!=t){for(let e=0;e<u.afterHandle.length;e++){let r=u.afterHandle[e](a,t);r instanceof Promise&&(r=await r),r&&(t=r)}let e=r(t,a.set);if(e)return e}}let f=l.handle(a);if(f instanceof Promise&&(f=await f),!1===l.validator?.response?.Check(f))throw u?.error&&(s=u?.error),d("response",l.validator.response,f);if(u?.afterHandle.length)for(let e=0;e<u.afterHandle.length;e++){let t=u.afterHandle[e](a,f);t instanceof Promise&&(t=await t);let s=r(t,a.set);if(s)return s}return t(f,a.set)}catch(n){let t=a.set;if((!t.status||t.status<300)&&(t.status=500),s){let a=v(n.message);for(let i=0;i<s.length;i++){let o=s[i]({request:e,error:n,set:t,code:a});o instanceof Promise&&(o=await o);let h=r(o,t);if(h)return h}}return this.handleError(e,n,t)}};async handleError(e,r,s={headers:{}}){for(let a=0;a<this.event.error.length;a++){let n=this.event.error[a]({request:e,code:v(r.message),error:r,set:s});if(n instanceof Promise&&(n=await n),null!=n)return t(n,s)}return new Response("string"==typeof r.cause?r.cause:r.message,{headers:s.headers,status:g(v(r.message))})}listen=(e,t)=>{if(!Bun)throw Error("Bun to run");if("string"==typeof e&&Number.isNaN(e=+e))throw Error("Port must be a numeric value");let r=this.handle,s="object"==typeof e?{...this.config.serve,...e,fetch:r}:{...this.config.serve,port:e,fetch:r},a=`$$Elysia:${s.port}`;globalThis[a]?(this.server=globalThis[a],this.server.reload(s)):globalThis[a]=this.server=Bun.serve(s);for(let e=0;e<this.event.start.length;e++)this.event.start[e](this);return t&&t(this.server),Promise.all(this.lazyLoadModules).then(()=>{this.server.pendingRequests||Bun.gc(!0)}),this};stop=async()=>{if(!this.server)throw Error("Elysia isn't running. Call `app.listen` to start the server.");this.server.stop();for(let e=0;e<this.event.stop.length;e++)await this.event.stop[e](this)};get modules(){return Promise.all(this.lazyLoadModules)}setModel(e){return Object.entries(e).forEach(([e,t])=>{e in this.meta[i]||(this.meta[i][e]=t)}),this}}export{t}from"./custom-types";export{SCHEMA,DEFS,EXPOSED,createValidationError,getSchemaValidator,mergeDeep,mergeHook,mergeObjectArray,mapPathnameAndQueryRegEx,mapQuery}from"./utils";export{H as Elysia,s as permission}; | ||
import{nanoid as e}from"nanoid";import{Raikiri as t}from"raikiri";import{mapResponse as r,mapEarlyResponse as s}from"./handler";import{permission as a}from"./fn";import{SCHEMA as n,EXPOSED as i,DEFS as o,mapQuery as h,clone as l,mergeHook as d,mergeDeep as u,createValidationError as f,getSchemaValidator as m,getResponseSchemaValidator as c,mapPathnameAndQueryRegEx as p}from"./utils";import{registerSchemaPath as v}from"./schema";import{mapErrorCode as g,mapErrorStatus as y}from"./error";import{runFn as b}from"./fn";import{deserialize as w}from"superjson";export default class H{store={};meta={[n]:Object.create(null),[o]:Object.create(null),[i]:Object.create(null)};decorators={[n]:this.meta[n],[o]:this.meta[o]};event={start:[],request:[],parse:[],transform:[],beforeHandle:[],afterHandle:[],error:[],stop:[]};server=null;$schema=null;router=new t;routes=[];lazyLoadModules=[];constructor(e){this.config={fn:"/~fn",...e}}_addHandler(e,t,r,s){t=t.startsWith("/")?t:`/${t}`,this.routes.push({method:e,path:t,handler:r,hooks:d(l(this.event),s)});let a=this.meta[o],i=m(s?.schema?.body??this.$schema?.body,a),h=m(s?.schema?.headers??this.$schema?.headers,a,!0),u=m(s?.schema?.params??this.$schema?.params,a),f=m(s?.schema?.query??this.$schema?.query,a),p=c(s?.schema?.response??this.$schema?.response,a);v({schema:this.meta[n],contentType:s?.schema?.contentType,hook:s,method:e,path:t,models:this.meta[o]});let g=d(l(this.event),s);g.schema||g.transform.length||g.beforeHandle.length||g.error.length||g.afterHandle.length||(g=void 0);let y={handle:r,hooks:g,validator:i||h||u||f||p?{body:i,header:h,params:u,query:f,response:p}:void 0};this.router.add(e,t,y)}onStart(e){return this.event.start.push(e),this}onRequest(e){return this.event.request.push(e),this}onParse(e){return this.event.parse.splice(this.event.parse.length-1,0,e),this}onTransform(e){return this.event.transform.push(e),this}onBeforeHandle(e){return this.event.beforeHandle.push(e),this}onAfterHandle(e){return this.event.afterHandle.push(e),this}onError(e){return this.event.error.push(e),this}onStop(e){return this.event.stop.push(e),this}on(e,t){switch(e){case"start":this.event.start.push(t);break;case"request":this.event.request.push(t);break;case"parse":this.event.parse.push(t);break;case"transform":this.event.transform.push(t);break;case"beforeHandle":this.event.beforeHandle.push(t);break;case"afterHandle":this.event.afterHandle.push(t);break;case"error":this.event.error.push(t);break;case"stop":this.event.stop.push(t)}return this}group(e,t){let r=new H;r.store=this.store;let s=t(r);return s.event.request.length&&(this.event.request=[...this.event.request,...s.event.request]),Object.values(r.routes).forEach(({method:t,path:r,handler:a,hooks:n})=>{"/"===r?this._addHandler(t,e,a,d(n,{error:s.event.error})):this._addHandler(t,`${e}${r}`,a,d(n,{error:s.event.error}))}),this}guard(e,t){let r=new H;r.store=this.store;let s=t(r);return s.event.request.length&&(this.event.request=[...this.event.request,...s.event.request]),Object.values(r.routes).forEach(({method:t,path:r,handler:s,hooks:a})=>{this._addHandler(t,r,s,d(e,a))}),this}use(e){if(e instanceof Promise)return this.lazyLoadModules.push(e.then(e=>"function"==typeof e?e(this):e.default(this))),this;let t=e(this);return t instanceof Promise?(this.lazyLoadModules.push(t),this):t}get(e,t,r){return this._addHandler("GET",e,t,r),this}post(e,t,r){return this._addHandler("POST",e,t,r),this}put(e,t,r){return this._addHandler("PUT",e,t,r),this}patch(e,t,r){return this._addHandler("PATCH",e,t,r),this}delete(e,t,r){return this._addHandler("DELETE",e,t,r),this}options(e,t,r){return this._addHandler("OPTIONS",e,t,r),this}all(e,t,r){return this._addHandler("ALL",e,t,r),this}head(e,t,r){return this._addHandler("HEAD",e,t,r),this}trace(e,t,r){return this._addHandler("TRACE",e,t,r),this}connect(e,t,r){return this._addHandler("CONNECT",e,t,r),this}ws(t,r){if(!this.wsRouter)throw Error("Can't find WebSocket. Please register WebSocket plugin first by importing 'elysia/ws'");return this.wsRouter.add("subscribe",t,r),this.get(t,t=>{if(!this.server.upgrade(t.request,{headers:"function"==typeof r.headers?r.headers(t):r.headers,data:{...t,id:e(),message:m(r.schema?.body,this.meta[o]),transformMessage:r.transform?Array.isArray(r.transformMessage)?r.transformMessage:[r.transformMessage]:[]}}))return t.set.status=400,"Expected a websocket connection"},{beforeHandle:r.beforeHandle,transform:r.transform,schema:{headers:r.schema?.headers,params:r.schema?.params,query:r.schema?.query}}),this}route(e,t,r,s){return this._addHandler(e,t,r,s),this}state(e,t){return e in this.store||(this.store[e]=t),this}decorate(e,t){return e in this.decorators||(this.decorators[e]=t),this}inject(e){return this.onTransform(t=>{Object.assign(t,e(t))})}fn(e){return 0===Object.keys(this.meta[i]).length&&this.post(this.config.fn??"/~fn",e=>b(e,this.meta[i])),this.meta[i]=u(this.meta[i],"function"==typeof e?e({...this.decorators,store:this.store,permission:a}):e),this}schema(e){let t=this.meta[o];return this.$schema={body:m(e.body,t),headers:m(e?.headers,t,!0),params:m(e?.params,t),query:m(e?.query,t),response:m(e?.response,t)},this}handle=async e=>{let t;let a=this.decorators;a.store=this.store,a.request=e,a.query={},a.set={status:200,headers:{}};try{let n;if(this.event.request.length)for(let e=0;e<this.event.request.length;e++){let t=this.event.request[e](a);if(t instanceof Promise&&(t=await t),t=s(t,a.set))return t}let i=e.url.match(p);if(!i)throw Error("NOT_FOUND");let o=this.router.match(e.method,i[1])??this.router.match("ALL",i[1]);if(!o)throw Error("NOT_FOUND");let l=o.store,d=l.hooks;if(d?.error&&(t=d?.error),"GET"!==e.method){let t=e.headers.get("content-type");if(t){let r=t.indexOf(";");if(-1!==r&&(t=t.slice(0,r)),this.event.parse.length)for(let e=0;e<this.event.parse.length;e++){let r=this.event.parse[e](a,t);if(r instanceof Promise&&(r=await r),void 0!==r){n=r;break}}if(void 0===n)switch(t){case"application/json":n=await e.json();break;case"text/plain":n=await e.text();break;case"application/x-www-form-urlencoded":n=h(await e.text());break;case"multipart/form-data":n={},await e.formData().then(e=>{for(let t of e.keys()){if(t in n)continue;let r=e.getAll(t);1===r.length?n[t]=r[0]:n[t]=r}});break;case"elysia/fn":n=w(await e.json())}}}if(a.body=n,a.params=o.params,i[2]&&(a.query=h(i[2])),d?.transform.length)for(let e=0;e<d.transform.length;e++){let t=d.transform[e](a);t instanceof Promise&&await t}if(l.validator){let r=l.validator;if(d?.error&&(t=d?.error),r.headers){let t={};for(let r in e.headers)t[r]=e.headers.get(r);if(!1===r.headers.Check(t))throw f("header",r.headers,t)}if(!1===r.params?.Check(a.params))throw f("params",r.params,a.params);if(!1===r.query?.Check(a.query))throw f("query",r.query,a.query);if(!1===r.body?.Check(n))throw f("body",r.body,n)}if(d?.beforeHandle.length)for(let e=0;e<d.beforeHandle.length;e++){let t=d.beforeHandle[e](a);if(t instanceof Promise&&(t=await t),null!=t){for(let e=0;e<d.afterHandle.length;e++){let r=d.afterHandle[e](a,t);r instanceof Promise&&(r=await r),r&&(t=r)}let e=s(t,a.set);if(e)return e}}let u=l.handle(a);if(u instanceof Promise&&(u=await u),!1===l.validator?.response?.Check(u))throw d?.error&&(t=d?.error),f("response",l.validator.response,u);if(d?.afterHandle.length)for(let e=0;e<d.afterHandle.length;e++){let t=d.afterHandle[e](a,u);t instanceof Promise&&(t=await t);let r=s(t,a.set);if(r)return r}return r(u,a.set)}catch(n){let r=a.set;if((!r.status||r.status<300)&&(r.status=500),t){let a=g(n.message);for(let i=0;i<t.length;i++){let o=t[i]({request:e,error:n,set:r,code:a});o instanceof Promise&&(o=await o);let h=s(o,r);if(h)return h}}return this.handleError(e,n,r)}};async handleError(e,t,s={headers:{}}){for(let a=0;a<this.event.error.length;a++){let n=this.event.error[a]({request:e,code:g(t.message),error:t,set:s});if(n instanceof Promise&&(n=await n),null!=n)return r(n,s)}return new Response("string"==typeof t.cause?t.cause:t.message,{headers:s.headers,status:y(g(t.message))})}listen=(e,t)=>{if(!Bun)throw Error("Bun to run");if("string"==typeof e&&Number.isNaN(e=+e))throw Error("Port must be a numeric value");let r=this.handle,s="object"==typeof e?{...this.config.serve,...e,fetch:r}:{...this.config.serve,port:e,fetch:r},a=`$$Elysia:${s.port}`;globalThis[a]?(this.server=globalThis[a],this.server.reload(s)):globalThis[a]=this.server=Bun.serve(s);for(let e=0;e<this.event.start.length;e++)this.event.start[e](this);return t&&t(this.server),Promise.all(this.lazyLoadModules).then(()=>{this.server.pendingRequests||Bun.gc(!0)}),this};stop=async()=>{if(!this.server)throw Error("Elysia isn't running. Call `app.listen` to start the server.");this.server.stop();for(let e=0;e<this.event.stop.length;e++)await this.event.stop[e](this)};get modules(){return Promise.all(this.lazyLoadModules)}setModel(e){return Object.entries(e).forEach(([e,t])=>{e in this.meta[o]||(this.meta[o][e]=t)}),this}}export{t}from"./custom-types";export{ws}from"./ws";export{SCHEMA,DEFS,EXPOSED,createValidationError,getSchemaValidator,mergeDeep,mergeHook,mergeObjectArray,mapPathnameAndQueryRegEx,mapQuery}from"./utils";export{H as Elysia,a as permission}; |
@@ -12,3 +12,3 @@ import { type TSchema } from '@sinclair/typebox'; | ||
hook?: LocalHook<import("./types").TypedSchema<string>, import("./types").ElysiaInstance<{ | ||
store: Record<any, any>; | ||
store: Record<string, unknown>; | ||
request: {}; | ||
@@ -15,0 +15,0 @@ schema: {}; |
/// <reference types="bun-types" /> | ||
import type { Elysia } from '.'; | ||
import type { Serve, Server } from 'bun'; | ||
import type { Context, PreContext } from './context'; | ||
import type { Static, TObject, TSchema } from '@sinclair/typebox'; | ||
import type { TypeCheck } from '@sinclair/typebox/compiler'; | ||
import type { SCHEMA, DEFS, EXPOSED } from './utils'; | ||
import type { OpenAPIV3 } from 'openapi-types'; | ||
import type { Context, PreContext } from './context'; | ||
import { SCHEMA, DEFS, EXPOSED } from './utils'; | ||
export type WithArray<T> = T | T[]; | ||
export type ObjectValues<T extends object> = T[keyof T]; | ||
export type ElysiaDefaultMeta = Record<typeof SCHEMA, Partial<OpenAPIV3.PathsObject>> & Record<typeof DEFS, { | ||
[x in string]: TSchema; | ||
}> & Record<typeof EXPOSED, Record<string, Record<string, unknown>>>; | ||
export type ElysiaInstance<Instance extends { | ||
store?: Record<any, any>; | ||
request?: Record<any, any>; | ||
store?: Record<string, unknown>; | ||
request?: Record<string, unknown>; | ||
schema?: TypedSchema; | ||
meta?: Record<typeof SCHEMA, Partial<OpenAPIV3.PathsObject>> & Record<typeof DEFS, { | ||
[x in string]: TSchema; | ||
}> & Record<typeof EXPOSED, Record<string, Record<string, unknown>>>; | ||
meta?: ElysiaDefaultMeta; | ||
} = { | ||
store: Record<any, any>; | ||
store: Record<string, unknown>; | ||
request: {}; | ||
@@ -29,7 +30,3 @@ schema: {}; | ||
}; | ||
export type Handler<Route extends TypedRoute = TypedRoute, Instance extends ElysiaInstance = ElysiaInstance, CatchResponse = Route['response']> = (context: Context<Route, Instance['store']> & Instance['request'] & { | ||
a: Instance; | ||
r: Route; | ||
merged: MergeSchema<Instance['schema'], Route>; | ||
}) => Route['response'] extends (models: Record<string, TSchema>) => TSchema ? undefined extends ReturnType<Route['response']> ? MaybePromise<CatchResponse> | Response : MaybePromise<ReturnType<Route['response']>> | Response : undefined extends Route['response'] ? MaybePromise<CatchResponse> | Response : MaybePromise<Route['response']> | Response; | ||
export type Handler<Route extends OverwritableTypeRoute, Instance extends ElysiaInstance = ElysiaInstance, CatchResponse = unknown> = (context: Context<Route, Instance['store']> & Instance['request']) => IsUnknown<Route['response']> extends false ? Response | MaybePromise<Route['response']> : Response | MaybePromise<CatchResponse>; | ||
export type NoReturnHandler<Route extends TypedRoute = TypedRoute, Instance extends ElysiaInstance = ElysiaInstance> = (context: Context<Route, Instance['store']> & Instance['request']) => void | Promise<void>; | ||
@@ -93,3 +90,3 @@ export type LifeCycleEvent = 'start' | 'request' | 'parse' | 'transform' | 'beforeHandle' | 'afterHandle' | 'error' | 'stop'; | ||
params: Record<string, any> | undefined; | ||
response: TSchema | unknown | undefined; | ||
response: any; | ||
}; | ||
@@ -133,22 +130,17 @@ export type SchemaValidator = { | ||
} | ||
export type RouteToSchema<Schema extends TypedSchema, InstanceSchema extends ElysiaInstance['schema'], Definitions extends ElysiaInstance['meta'][typeof DEFS], Path extends string = string, FinalSchema extends MergeSchema<Schema, InstanceSchema> = MergeSchema<Schema, InstanceSchema>> = FinalSchema['params'] extends NonNullable<Schema['params']> ? TypedSchemaToRoute<FinalSchema, Definitions> : Omit<TypedSchemaToRoute<FinalSchema, Definitions>, 'params'> & { | ||
export type RouteToSchema<Schema extends TypedSchema, InstanceSchema extends ElysiaInstance['schema'], Definitions extends ElysiaInstance['meta'][typeof DEFS], Path extends string = string> = MergeSchema<Schema, InstanceSchema> extends infer Typed extends TypedSchema ? undefined extends Typed['params'] ? Omit<TypedSchemaToRoute<Typed, Definitions>, 'params'> & { | ||
params: Record<ExtractPath<Path>, string>; | ||
} : TypedSchemaToRoute<Typed, Definitions> : never; | ||
export type MergeUnionObjects<T> = {} & { | ||
[P in keyof T]: T[P]; | ||
}; | ||
export type ElysiaRoute<Method extends string = string, Schema extends TypedSchema = TypedSchema, Instance extends ElysiaInstance = ElysiaInstance, Path extends string = string, CatchResponse = unknown> = Elysia<{ | ||
request: Instance['request']; | ||
store: Instance['store']; | ||
schema: Instance['schema']; | ||
meta: Instance['meta'] & Record<typeof SCHEMA, { | ||
[path in Path]: { | ||
[method in Method]: TypedRouteToEden<Schema, Instance['schema'], Path> extends infer FinalSchema extends AnyTypedSchema ? Omit<FinalSchema, 'response'> & { | ||
response: undefined extends FinalSchema['response'] ? { | ||
'200': CatchResponse; | ||
} : FinalSchema['response']; | ||
} : never; | ||
}; | ||
}>; | ||
}>; | ||
export type TypedRouteToEden<Schema extends TypedSchema = TypedSchema, InstanceSchema extends TypedSchema<string> = ElysiaInstance['schema'], Path extends string = string, FinalSchema extends MergeSchema<Schema, InstanceSchema> = MergeSchema<Schema, InstanceSchema>> = FinalSchema['params'] extends NonNullable<Schema['params']> ? TypedSchemaToEden<FinalSchema, InstanceSchema> : Omit<TypedSchemaToEden<FinalSchema, InstanceSchema>, 'params'> & { | ||
params: Record<ExtractPath<Path>, string>; | ||
}; | ||
export type TypedRouteToEden<Schema extends TypedSchema = TypedSchema, Definitions extends TypedSchema<string> = ElysiaInstance['meta'][typeof DEFS], Path extends string = string, Catch = unknown> = TypedSchemaToEden<Schema, Definitions> extends infer Typed extends AnyTypedSchema ? { | ||
body: Typed['body']; | ||
headers: Typed['headers']; | ||
query: Typed['query']; | ||
params: undefined extends Typed['params'] ? Record<ExtractPath<Path>, string> : Typed['params']; | ||
response: undefined extends Typed['response'] ? { | ||
'200': Catch; | ||
} : Typed['response']; | ||
} : never; | ||
export type TypedSchemaToEden<Schema extends TypedSchema, Definitions extends ElysiaInstance['meta'][typeof DEFS]> = { | ||
@@ -200,3 +192,3 @@ body: UnwrapSchema<Schema['body'], Definitions>; | ||
export type HTTPMethod = 'ACL' | 'BIND' | 'CHECKOUT' | 'CONNECT' | 'COPY' | 'DELETE' | 'GET' | 'HEAD' | 'LINK' | 'LOCK' | 'M-SEARCH' | 'MERGE' | 'MKACTIVITY' | 'MKCALENDAR' | 'MKCOL' | 'MOVE' | 'NOTIFY' | 'OPTIONS' | 'PATCH' | 'POST' | 'PROPFIND' | 'PROPPATCH' | 'PURGE' | 'PUT' | 'REBIND' | 'REPORT' | 'SEARCH' | 'SOURCE' | 'SUBSCRIBE' | 'TRACE' | 'UNBIND' | 'UNLINK' | 'UNLOCK' | 'UNSUBSCRIBE' | 'ALL'; | ||
export type ErrorCode = 'NOT_FOUND' | 'INTERNAL_SERVER_ERROR' | 'VALIDATION' | 'UNKNOWN'; | ||
export type ErrorCode = (string & {}) | 'NOT_FOUND' | 'INTERNAL_SERVER_ERROR' | 'VALIDATION' | 'UNKNOWN'; | ||
export type ErrorHandler = (params: { | ||
@@ -234,5 +226,6 @@ request: Request; | ||
}] ? MergeTwoObjects<T, U> : T | U; | ||
export type IsAny<T> = unknown extends T ? [keyof T] extends [never] ? false : true : false; | ||
export type IsAny<T> = 0 extends 1 & T ? true : false; | ||
export type IsNever<T> = [T] extends [never] ? true : false; | ||
export type IsUnknown<T> = IsAny<T> extends true ? false : unknown extends T ? true : false; | ||
export type MaybePromise<T> = T | Promise<T>; | ||
export type IsNever<T> = [T] extends [never] ? true : false; | ||
export type FunctionProperties<T> = { | ||
@@ -239,0 +232,0 @@ [K in keyof T as T[K] extends Record<any, any> | ((...args: any[]) => any) ? IsAny<T[K]> extends true ? never : K : never]: T[K] extends (...args: any[]) => any ? T[K] : T[K] extends Record<string, any> ? FunctionProperties<T[K]> : never; |
{ | ||
"name": "elysia", | ||
"description": "Fast, and friendly Bun web framework", | ||
"version": "0.3.0-exp-240225.2119", | ||
"version": "0.3.0-rc.0", | ||
"author": { | ||
@@ -12,5 +12,62 @@ "name": "saltyAom", | ||
"exports": { | ||
"import": "./dist/index.js", | ||
"default": "./dist/index.js", | ||
"node": "./dist/index.js" | ||
"." :{ | ||
"bun": "./dist/index.js", | ||
"import": "./dist/index.js", | ||
"default": "./dist/index.js", | ||
"node": "./dist/index.js" | ||
}, | ||
"./ws" :{ | ||
"bun": "./dist/ws/index.js", | ||
"import": "./dist/ws/index.js", | ||
"default": "./dist/ws/index.js", | ||
"node": "./dist/ws/index.js" | ||
}, | ||
"./context" :{ | ||
"bun": "./dist/ws/context.js", | ||
"import": "./dist/ws/context.js", | ||
"default": "./dist/ws/context.js", | ||
"node": "./dist/ws/context.js" | ||
}, | ||
"./custom-types" :{ | ||
"bun": "./dist/custom-types.js", | ||
"import": "./dist/custom-types.js", | ||
"default": "./dist/custom-types.js", | ||
"node": "./dist/custom-types.js" | ||
}, | ||
"./error" :{ | ||
"bun": "./dist/error.js", | ||
"import": "./dist/error.js", | ||
"default": "./dist/error.js", | ||
"node": "./dist/error.js" | ||
}, | ||
"./fn" :{ | ||
"bun": "./dist/fn.js", | ||
"import": "./dist/fn.js", | ||
"default": "./dist/fn.js", | ||
"node": "./dist/fn.js" | ||
}, | ||
"./handler": { | ||
"bun": "./dist/handler.js", | ||
"import": "./dist/handler.js", | ||
"default": "./dist/handler.js", | ||
"node": "./dist/handler.js" | ||
}, | ||
"./schema": { | ||
"bun": "./dist/schema.js", | ||
"import": "./dist/schema.js", | ||
"default": "./dist/schema.js", | ||
"node": "./dist/schema.js" | ||
}, | ||
"./types": { | ||
"bun": "./dist/types.js", | ||
"import": "./dist/types.js", | ||
"default": "./dist/types.js", | ||
"node": "./dist/types.js" | ||
}, | ||
"./utils": { | ||
"bun": "./dist/utils.js", | ||
"import": "./dist/utils.js", | ||
"default": "./dist/utils.js", | ||
"node": "./dist/utils.js" | ||
} | ||
}, | ||
@@ -17,0 +74,0 @@ "types": "./src/index.ts", |
@@ -141,9 +141,14 @@ import { Type, type SchemaOptions } from '@sinclair/typebox' | ||
ElysiaType.Files({ | ||
...arg, | ||
default: 'Files', | ||
...arg, | ||
extension: arg?.type, | ||
type: 'string', | ||
format: 'binary' | ||
type: 'array', | ||
items: { | ||
...arg, | ||
default: 'Files', | ||
type: 'string', | ||
format: 'binary' | ||
} | ||
}) | ||
export { Type as t } |
@@ -221,3 +221,16 @@ import { EXPOSED } from './utils' | ||
return Promise.all(results).then(superjsonSerialize) | ||
return Promise.allSettled(results) | ||
.then((x) => { | ||
const ops: any[] = [] | ||
for (let i = 0; i < x.length; i++) { | ||
const op = x[i] | ||
if (op.status === 'fulfilled') ops.push(op.value) | ||
else ops.push(op.reason) | ||
} | ||
return ops | ||
}) | ||
.then(superjsonSerialize) | ||
} |
470
src/index.ts
import type { Serve, Server } from 'bun' | ||
import { nanoid } from 'nanoid' | ||
import { Raikiri } from 'raikiri' | ||
@@ -53,7 +54,9 @@ import { mapResponse, mapEarlyResponse } from './handler' | ||
NoReturnHandler, | ||
ElysiaRoute, | ||
MaybePromise, | ||
IsNever | ||
IsNever, | ||
MergeUnionObjects, | ||
TypedRouteToEden | ||
} from './types' | ||
import { type TSchema } from '@sinclair/typebox' | ||
import { ElysiaWSContext, ElysiaWSOptions, WSTypedSchema } from './ws' | ||
@@ -85,8 +88,2 @@ /** | ||
protected decorators: ElysiaInstance['request'] = { | ||
query: {}, | ||
set: { | ||
status: 200, | ||
headers: {} | ||
}, | ||
store: this.store, | ||
[SCHEMA]: this.meta[SCHEMA], | ||
@@ -112,2 +109,3 @@ [DEFS]: this.meta[DEFS] | ||
protected routes: InternalRoute<Instance>[] = [] | ||
private wsRouter: Raikiri<ElysiaWSOptions> | undefined | ||
@@ -684,8 +682,33 @@ private lazyLoadModules: Promise<Elysia<any>>[] = [] | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<'GET', Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'get']: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler('GET', path, handler, hook as LocalHook) | ||
@@ -719,8 +742,33 @@ | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<'POST', Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'post']: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler('POST', path, handler, hook as LocalHook) | ||
@@ -754,8 +802,33 @@ | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<'PUT', Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'put']: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler('PUT', path, handler, hook as LocalHook) | ||
@@ -789,8 +862,33 @@ | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<'PATCH', Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'patch']: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler('PATCH', path, handler, hook as LocalHook) | ||
@@ -824,8 +922,33 @@ | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<'DELETE', Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'delete']: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler('DELETE', path, handler, hook as LocalHook) | ||
@@ -859,8 +982,33 @@ | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<'OPTIONS', Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'options']: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler('OPTIONS', path, handler, hook as LocalHook) | ||
@@ -889,8 +1037,33 @@ | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<'ALL', Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'all']: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler('ALL', path, handler, hook as LocalHook) | ||
@@ -924,8 +1097,33 @@ | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<'HEAD', Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'head']: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler('HEAD', path, handler, hook as LocalHook) | ||
@@ -959,8 +1157,33 @@ | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<'TRACE', Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'trace']: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler('TRACE', path, handler, hook as LocalHook) | ||
@@ -994,8 +1217,33 @@ | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<'CONNECT', Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in 'connect']: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler('CONNECT', path, handler, hook as LocalHook) | ||
@@ -1007,2 +1255,87 @@ | ||
/** | ||
* ### connect | ||
* Register handler for path with method [CONNECT] | ||
* | ||
* --- | ||
* @example | ||
* ```typescript | ||
* import { Elysia, t } from 'elysia' | ||
* | ||
* new Elysia() | ||
* .connect('/', () => 'hi') | ||
* .connect('/with-hook', () => 'hi', { | ||
* schema: { | ||
* response: t.String() | ||
* } | ||
* }) | ||
* ``` | ||
*/ | ||
ws<Path extends string = '', Schema = {}>( | ||
/** | ||
* Path to register websocket to | ||
*/ | ||
path: Path, | ||
options: Path extends '' | ||
? never | ||
: this extends Elysia<infer Instance> | ||
? ElysiaWSOptions< | ||
Path, | ||
Schema extends WSTypedSchema ? Schema : WSTypedSchema, | ||
Instance['meta'][typeof DEFS] | ||
> | ||
: never | ||
): this extends Elysia<infer Instance> ? Elysia<Instance> : ElysiaInstance { | ||
if (!this.wsRouter) | ||
throw new Error( | ||
"Can't find WebSocket. Please register WebSocket plugin first by importing 'elysia/ws'" | ||
) | ||
this.wsRouter.add('subscribe', path, options as any) | ||
this.get( | ||
path, | ||
(context) => { | ||
if ( | ||
// @ts-ignore | ||
this.server!.upgrade(context.request, { | ||
headers: | ||
typeof options.headers === 'function' | ||
? options.headers(context as any) | ||
: options.headers, | ||
data: { | ||
...context, | ||
id: nanoid(), | ||
message: getSchemaValidator( | ||
options.schema?.body, | ||
this.meta[DEFS] | ||
), | ||
transformMessage: !options.transform | ||
? [] | ||
: Array.isArray(options.transformMessage) | ||
? options.transformMessage | ||
: [options.transformMessage] | ||
} as ElysiaWSContext<any>['data'] | ||
}) | ||
) | ||
return | ||
context.set.status = 400 | ||
return 'Expected a websocket connection' | ||
}, | ||
{ | ||
beforeHandle: options.beforeHandle, | ||
transform: options.transform, | ||
schema: { | ||
headers: options.schema?.headers, | ||
params: options.schema?.params, | ||
query: options.schema?.query | ||
} | ||
} as any | ||
) | ||
return this as any | ||
} | ||
/** | ||
* ### route | ||
@@ -1031,9 +1364,34 @@ * Register handler for path with custom method | ||
Path extends string = string, | ||
Response = unknown | ||
Handler extends LocalHandler<Schema, Instance, Path> = LocalHandler< | ||
Schema, | ||
Instance, | ||
Path | ||
> | ||
>( | ||
method: Method, | ||
path: Path, | ||
handler: LocalHandler<Schema, Instance, Path, Response>, | ||
handler: Handler, | ||
hook?: LocalHook<Schema, Instance, Path> | ||
): ElysiaRoute<Method, Schema, Instance, Path, Response> { | ||
): Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record<typeof EXPOSED, Instance['meta'][typeof EXPOSED]> & | ||
Record< | ||
typeof SCHEMA, | ||
MergeUnionObjects< | ||
Instance['meta'][typeof SCHEMA] & { | ||
[path in Path]: { | ||
[method in Uppercase<Method>]: TypedRouteToEden< | ||
Schema, | ||
Instance['meta'][typeof DEFS], | ||
Path, | ||
ReturnType<Handler> | ||
> | ||
} | ||
} | ||
> | ||
> | ||
}> { | ||
this._addHandler(method, path, handler, hook as LocalHook) | ||
@@ -1153,7 +1511,9 @@ | ||
schema: Instance['schema'] | ||
meta: Instance['meta'] & | ||
meta: Record<typeof DEFS, Instance['meta'][typeof DEFS]> & | ||
Record< | ||
typeof EXPOSED, | ||
T extends (store: any) => infer Returned ? Returned : T | ||
> | ||
Instance['meta'][typeof EXPOSED] & | ||
(T extends (store: any) => infer Returned ? Returned : T) | ||
> & | ||
Record<typeof SCHEMA, Instance['meta'][typeof SCHEMA]> | ||
}> { | ||
@@ -1199,5 +1559,5 @@ if (Object.keys(this.meta[EXPOSED]).length === 0) { | ||
Schema extends TypedSchema< | ||
Exclude<keyof Instance['store'][typeof DEFS], number | symbol> | ||
Exclude<keyof Instance['meta'][typeof DEFS], number | symbol> | ||
> = TypedSchema< | ||
Exclude<keyof Instance['store'][typeof DEFS], number | symbol> | ||
Exclude<keyof Instance['meta'][typeof DEFS], number | symbol> | ||
>, | ||
@@ -1226,4 +1586,10 @@ NewInstance = Elysia<{ | ||
handle = async (request: Request): Promise<Response> => { | ||
const context = clone(this.decorators) as any as Context | ||
const context = this.decorators as any as Context | ||
context.store = this.store | ||
context.request = request | ||
context.query = {} | ||
context.set = { | ||
status: 200, | ||
headers: {} | ||
} | ||
@@ -1583,2 +1949,3 @@ let handleErrors: ErrorHandler[] | undefined | ||
export { t } from './custom-types' | ||
export { ws } from './ws' | ||
@@ -1625,3 +1992,2 @@ export { | ||
SchemaValidator, | ||
ElysiaRoute, | ||
ExtractPath, | ||
@@ -1636,3 +2002,9 @@ IsPathParameter, | ||
MaybePromise, | ||
MergeIfNotNull | ||
MergeIfNotNull, | ||
ElysiaDefaultMeta, | ||
TypedRouteToEden, | ||
AnyTypedSchema, | ||
RouteToSchema, | ||
DeepMergeTwoTypes, | ||
ConnectedKeysType | ||
} from './types' |
153
src/types.ts
import type { Elysia } from '.' | ||
import type { Serve, Server } from 'bun' | ||
import type { Context, PreContext } from './context' | ||
import type { Static, TObject, TSchema } from '@sinclair/typebox' | ||
import type { TypeCheck } from '@sinclair/typebox/compiler' | ||
import type { SCHEMA, DEFS, EXPOSED } from './utils' | ||
import type { OpenAPIV3 } from 'openapi-types' | ||
import type { Context, PreContext } from './context' | ||
import { SCHEMA, DEFS, EXPOSED } from './utils' | ||
export type WithArray<T> = T | T[] | ||
export type ObjectValues<T extends object> = T[keyof T] | ||
export type ElysiaDefaultMeta = Record< | ||
typeof SCHEMA, | ||
Partial<OpenAPIV3.PathsObject> | ||
> & | ||
Record<typeof DEFS, { [x in string]: TSchema }> & | ||
Record<typeof EXPOSED, Record<string, Record<string, unknown>>> | ||
export type ElysiaInstance< | ||
Instance extends { | ||
store?: Record<any, any> | ||
request?: Record<any, any> | ||
store?: Record<string, unknown> | ||
request?: Record<string, unknown> | ||
schema?: TypedSchema | ||
meta?: Record<typeof SCHEMA, Partial<OpenAPIV3.PathsObject>> & | ||
Record<typeof DEFS, { [x in string]: TSchema }> & | ||
Record<typeof EXPOSED, Record<string, Record<string, unknown>>> | ||
meta?: ElysiaDefaultMeta | ||
} = { | ||
store: Record<any, any> | ||
store: Record<string, unknown> | ||
request: {} | ||
@@ -39,22 +45,15 @@ schema: {} | ||
export type Handler< | ||
Route extends TypedRoute = TypedRoute, | ||
Route extends OverwritableTypeRoute, | ||
Instance extends ElysiaInstance = ElysiaInstance, | ||
CatchResponse = Route['response'] | ||
CatchResponse = unknown | ||
> = ( | ||
context: Context<Route, Instance['store']> & | ||
Instance['request'] & { | ||
a: Instance | ||
r: Route | ||
merged: MergeSchema<Instance['schema'], Route> | ||
} | ||
) => // Catch function | ||
Route['response'] extends (models: Record<string, TSchema>) => TSchema | ||
? undefined extends ReturnType<Route['response']> | ||
? MaybePromise<CatchResponse> | Response | ||
: MaybePromise<ReturnType<Route['response']>> | Response | ||
: // Catch non-function | ||
undefined extends Route['response'] | ||
? MaybePromise<CatchResponse> | Response | ||
: MaybePromise<Route['response']> | Response | ||
context: Context<Route, Instance['store']> & Instance['request'] | ||
) => IsUnknown<Route['response']> extends false | ||
? Response | MaybePromise<Route['response']> | ||
: Response | MaybePromise<CatchResponse> | ||
// undefined extends Route['response'] | ||
// ? MaybePromise<CatchResponse> | Response | ||
// : MaybePromise<Route['response']> | Response | ||
export type NoReturnHandler< | ||
@@ -203,3 +202,3 @@ Route extends TypedRoute = TypedRoute, | ||
params: Record<string, any> | undefined | ||
response: TSchema | unknown | undefined | ||
response: any | ||
} | ||
@@ -290,59 +289,36 @@ | ||
Definitions extends ElysiaInstance['meta'][typeof DEFS], | ||
Path extends string = string, | ||
FinalSchema extends MergeSchema<Schema, InstanceSchema> = MergeSchema< | ||
Schema, | ||
InstanceSchema | ||
> | ||
> = FinalSchema['params'] extends NonNullable<Schema['params']> | ||
? TypedSchemaToRoute<FinalSchema, Definitions> | ||
: Omit<TypedSchemaToRoute<FinalSchema, Definitions>, 'params'> & { | ||
params: Record<ExtractPath<Path>, string> | ||
} | ||
Path extends string = string | ||
> = MergeSchema<Schema, InstanceSchema> extends infer Typed extends TypedSchema | ||
? undefined extends Typed['params'] | ||
? Omit<TypedSchemaToRoute<Typed, Definitions>, 'params'> & { | ||
params: Record<ExtractPath<Path>, string> | ||
} | ||
: TypedSchemaToRoute<Typed, Definitions> | ||
: never | ||
export type ElysiaRoute< | ||
Method extends string = string, | ||
Schema extends TypedSchema = TypedSchema, | ||
Instance extends ElysiaInstance = ElysiaInstance, | ||
Path extends string = string, | ||
CatchResponse = unknown | ||
> = Elysia<{ | ||
request: Instance['request'] | ||
store: Instance['store'] | ||
schema: Instance['schema'] | ||
meta: Instance['meta'] & | ||
Record< | ||
typeof SCHEMA, | ||
{ | ||
[path in Path]: { | ||
[method in Method]: TypedRouteToEden< | ||
Schema, | ||
Instance['schema'], | ||
Path | ||
> extends infer FinalSchema extends AnyTypedSchema | ||
? Omit<FinalSchema, 'response'> & { | ||
response: undefined extends FinalSchema['response'] | ||
? { | ||
'200': CatchResponse | ||
} | ||
: FinalSchema['response'] | ||
} | ||
: never | ||
} | ||
} | ||
> | ||
}> | ||
export type MergeUnionObjects<T> = {} & { [P in keyof T]: T[P] } | ||
export type TypedRouteToEden< | ||
Schema extends TypedSchema = TypedSchema, | ||
InstanceSchema extends TypedSchema<string> = ElysiaInstance['schema'], | ||
Definitions extends TypedSchema<string> = ElysiaInstance['meta'][typeof DEFS], | ||
Path extends string = string, | ||
FinalSchema extends MergeSchema<Schema, InstanceSchema> = MergeSchema< | ||
Schema, | ||
InstanceSchema | ||
> | ||
> = FinalSchema['params'] extends NonNullable<Schema['params']> | ||
? TypedSchemaToEden<FinalSchema, InstanceSchema> | ||
: Omit<TypedSchemaToEden<FinalSchema, InstanceSchema>, 'params'> & { | ||
params: Record<ExtractPath<Path>, string> | ||
Catch = unknown | ||
> = TypedSchemaToEden< | ||
Schema, | ||
Definitions | ||
> extends infer Typed extends AnyTypedSchema | ||
? { | ||
body: Typed['body'] | ||
headers: Typed['headers'] | ||
query: Typed['query'] | ||
params: undefined extends Typed['params'] | ||
? Record<ExtractPath<Path>, string> | ||
: Typed['params'] | ||
response: undefined extends Typed['response'] | ||
? { | ||
'200': Catch | ||
} | ||
: Typed['response'] | ||
} | ||
: never | ||
@@ -484,2 +460,3 @@ export type TypedSchemaToEden< | ||
export type ErrorCode = | ||
| (string & {}) | ||
// ? Default 404 | ||
@@ -553,10 +530,22 @@ | 'NOT_FOUND' | ||
export type IsAny<T> = unknown extends T | ||
? [keyof T] extends [never] | ||
? false | ||
: true | ||
/** | ||
* @link https://stackoverflow.com/a/49928360/1490091 | ||
*/ | ||
export type IsAny<T> = 0 extends 1 & T ? true : false | ||
/** | ||
* Returns a boolean for whether the the type is `never`. | ||
*/ | ||
export type IsNever<T> = [T] extends [never] ? true : false | ||
/** | ||
* Returns a boolean for whether the the type is `unknown`. | ||
*/ | ||
export type IsUnknown<T> = IsAny<T> extends true | ||
? false | ||
: unknown extends T | ||
? true | ||
: false | ||
export type MaybePromise<T> = T | Promise<T> | ||
export type IsNever<T> = [T] extends [never] ? true : false | ||
@@ -563,0 +552,0 @@ export type FunctionProperties<T> = { |
@@ -44,3 +44,3 @@ import { Kind, TSchema, Type } from '@sinclair/typebox' | ||
: undefined, | ||
transform: mergeObjectArray(a.transform ?? [], b?.transform ?? []), | ||
transform: mergeObjectArray(a.transform ?? [], b?.transform ?? []) as any, | ||
beforeHandle: mergeObjectArray( | ||
@@ -47,0 +47,0 @@ a.beforeHandle ?? [], |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
167036
36
4395
0