Security:
- reject invalid cookie signature when using cookie rotation
Improvement
- #1609 calling afterResponse with aot: false
- #1607, #1606, #1139 data coercion on nested form data
- #1604 save lazy compilation of
Elysia.fetchfor up to 45x performance improvement - #1588, #1587 add seen weakset during mergeDeep
Bug fix:
- #1614 Cloudflare Worker with dynamic path
- add set immediate fallback
- #1597 safeParse, parse to static type
- #1596 handle context pass to function with sub context
- #1591, #1590 merge set.headers without duplicating Response
- #1546 override group prefix type
- #1526 default error handler doesn't work in Cloudflare Workers
- handle group with empty prefix in type-level
Security:
- use
JSON.stringifyover custom escape implementation
Improvement:
- #1573
Serveris always resolved toanywhen@types/bunis missing - #1568 optimize cookie value comparison using FNV-1a hash
- #1549 Set-Cookie headers not sent when errors are thrown
- #1579 HEAD to handle Promise value
Security:
- cookie injection, prototype pollution, and RCE
Bug fix:
- #1550 excess property checking
- allow cookie.sign to be string
Change:
- #1584 change customError property to unknown
- #1556 prevent sending set-cookie header when cookie value is not modified
- #1563 standard schema on websocket
- conditional parseQuery parameter
- conditional pass
c.requestto handler for streaming response - fix missing
contentTypetype onparser
Improvement:
- ValidationError: add
messageValueas an alias oferrorValue - ValidationError.detail now accept optional 2nd parameter
allowUnsafeValidatorDetails - macro: add
introspect - prevent redundant route compilation
- merge multiple macro resolve response
Bug fix:
- #1543 respect toResponse() method on Error classes
- #1537 websocket: ping/pong not being called
- #1536 export ExtractErrorFromHandle
- #1535 skip response validation for generators and streams
- #1531 typo in ElysiaTypeCustomErrorCallback: valdation to validation
- #1528 error in parsing request body validation errors with Zod
- #1527 bracket handling in exact mirror
- #1524 head request handler not working
Bug fix:
- 1.4.14 regression with Eden Treaty, and OpenAPI type gen
Feature:
- #1520, #1522 async handlers crash on HEAD request
- #1510 strict status response
- #1503 add t.NumericEnum() for numeric enum query handling
- #1450 call onAfterResponse when onError returns a value
- remove redundant
Prettify - prettify response for OpenAPI type gen
- conditional apply macro context in type level
- improve type performance in general
Change:
- remove
Prettify2,Partial2
Feature:
- #1453 add
allowUnsafeValidationDetailsfor disabling unsafe validation details in production mode - allow rapid stream in non browser mode or
ELYSIA_RAPID_STREAMis set afterResponsenow wait for generator stream to finish- trace of
handle, andafterResponsenow wait for generator stream to finish
Bug fix:
- #1502, #1501 afterHandle doesn't update status
- #1500 export
InvalidFileTypefrom root - #1495 request server hook parameters are typed as any (Bun 1.3.0)
- #1483 handle standard schema validators in ValidationError.all
- #1459 fix strictPath behavior when aot: false is set
- #1455 graceful shutdown not awaiting server.stop
- #1499 fails when merging with t.Optional schema
- remove encoding chunk from native static response in Bun adapter
Change:
- make
@types/bunan optional dependency
Improvement:
- named macro function callback
- adjust build script
Bug fix:
- #1469 incorrect ping, pong type signature
- #1467 better error union handling in
onError - #1463 responseValue is undefined in afterHandle when beforeHandle returns status
- #1460 compressed response in mapResponse is corrupted if status !== 200
- #1456 add response type check for stream
- #1451 cookie validation is not running when there's no body schema
- make
file-typenon optional dependency to fix default build problem
Bug fix:
- #1406 enforce return type in OptionalHandler
- static handlers in Bun 1.3
- conditional use
cryptorandomUUID if not available (eg. iOS Safari)
Change:
Elysia.filereadstream value is now IIFE to re-read
Improvement:
- add Cloudflare Worker test
- add
Sucrose.Settings - #1443 add knip for detecting deadcode
Improvement:
- automatically clear up sucrose cache when not used
- remove
Bun.hashfrom checksum calculation
Change:
- make
file-typeoptional to reduce bundle size - #1432 missing context (set) in mapResponse for ElysiaFile
- #1435 missing cookies in SSE
Feature:
- experimental
adapter/cloudflare-worker - add
ElysiaAdapter.beforeCompile
Change:
- do not prettify routes when using
guard,group - use
process.getBuiltinModuleinstead of dynamic import for file Elysia.file.valueon Web Standard Adapter now is not a promise
Improvement:
- #1406 strictly check for 200 inline status code
- coerce union status value and return type
- add
BunHTMLBundleLiketo Elysia inline handler - #1405 prevent Elysia from being a dependency of itself
- #1416 check if object is frozen before merging, add try-catch to prevent crash
- #1419 guard doesn't apply scoped/global schema to object macro
- #1425 DELETE doesn't inherit derive/resolve type
Change:
- #1409 onTransform now doesn't include type as it isn't validated yet, creating confusion
Bug fix:
- #1410 handle union derive/resolve property
- probably fix mergeDeep attempted to assign to readonly property
- derive/resolve inherit type in inline handler
Improvement:
- soundness for guard, group
- overwrite primitive value if collide (intersectIfObject)
Bug fix:
- standard schema incorrectly validate cookie and coercion
- merge nested guard, group standalone schema properly
Breaking Change:
- no longer coerce type for .model with
t.Refby default
Bug fix:
- merge schema in GET method
- remove accidental console.log
Bug fix:
mapValueErrorshould return all possible value both in dev environment and production environment- inline lifecycle get method doesn't inherit Singleton
Bug fix:
- remove debug
qfrom inline handler
Bug fix:
- type error for inline Elysia.file
Feature:
- standard validator
- macro schema, macro extension, macro detail
- lifecycle type soundness
- type inference reduced by ~11%
- #861 missing HEAD method when register route with GET
Improvement
- #861 automatically add HEAD method when defining GET route
Change
- ObjectString/ArrayString no longer produce default value by default due to security reasons
- Cookie now dynamically parse when format is likely JSON
- export
fileTypefor external file type validation for accurate response
Breaking Change
- remove macro v1 due to non type soundness
- remove
errorfunction, usestatusinstead - deprecation notice for
responseinmapResponse,afterResponse, useresponseValueinstead - remove reference array model by string eg.
user[], uset.Array(t.Ref('user'))instead
Bug fix:
- safely unwrap t.Record
Bug fix:
- #1356 webSocket validation error handling in BunAdapter
- #1358 allow overriding websocket handler with listen options
- #1365 check if the plugin.constructor (fix import module in Bun 1.2.21)
- #1367 .trace hooks (onAfterResponse, etc...) not being called
- #1369 don't block microtask queue in SSE
Change:
- mime is undefined when using
Elysia.filein Web Standard Adapter
Change:
- #1357 return
Responseproxy as-is
Bug fix:
- elysiajs/node#45 detect Response polyfill on Node
Bug fix:
ReadableStreamis not pass tohandleStreaminmapCompactResponse, andmapEarlyResponse
Bug fix:
- #1353 normalize encodeSchema with Transform
Improvement:
ssenow infer typessenow acceptsReadableStreamto return stream astext/event-stream- refactor SSE handler
- support returning
ReadableStreamfrom generator or async generator
Change:
- sse no longer include generated id by default
Bug fix:
- static response now use callback clone instead of bind
Bug fix:
- ValidationError.detail only handle custom error
Improvement:
- custom error on production mode
- add
ValidationError.withDetail - add
withDetailfor additional error information
Bug fix:
- important performance degration, exact mirror normalize doesn't apply correctly
- normalize optional property with special character
Change:
- update
exact-mirrorto0.1.6
Bug fix:
- #1348 onAfterResponse runs twice if NotFoundError thrown and onError provided
Bug fix:
- #1346 cannot declare 'mep' twice
Bug fix:
- #1028 query array nuqs format in dynamic mode
- unwrap t.Import in dynamic mode
Feature:
- #932 add
t.ArrayBuffer,t.Uint8Array
Bug fix:
- #459 route prefix should give type error when prefix is not start with '/'
- #669 add nullable field to t.Nullable for OpenAPI 3.0 spec
- #711 set default headers for non-aot
- #713 NotFoundError doesn't call onAfterResponse hook
- #771 skip body parsing if Content-Type is present but body is not
- #747 mapResponse inside mapError override error value
- #812 check for minItems length before array validation
- #833 cookie signing doesn't work in dynamic mode
- #859 clean non-root additionalProperties
- #924 decode path param
- #985 Nullable accept options
- #1028 string | string[] query parameter, reference array
- #1120 cannot set multiple cookies when response is a file
- #1124 validate url encoded query
- #1158 prevent side-effect from guard merge
- #1162 handle encoded space in array query string
- #1267 parse without contentType headers throw Bad Request
- #1274 support .use(undefined | false) for conditional plugin
- #1276 mapResponse with set inference produce invalid instruction
- #1268 using number instead of stringifed value for reporting validation error
- #1288 handle array query string in dynamic mode
- #1294 return status from
deriveandresolveshouldn't callonError - #1297, #1325 fix HTML imported pages in compiled apps
- #1319 fix array of plugin usage causes incorrect path aggregation
- #1323 don't duplicate error from plugin
- #1327 ensure that t.Date value is Date in Encode
- dynamic handle should handle named parser
- instanceof ElysiaCustomStatusResponse should return true when import from root Elysia module
Improvement:
- remove
finallyfrom compose NotFoundErrorshould parse query if inferred- #853 Bun Static response now handle pre-compute
onRequest, andonError - prettify ElysiaWS type
- export
ElysiaCustomStatusResponse - handle type-level status check in after response
Change:
- status no longer make value as readonly
- afterResponse now call after response by scheduling setImmediate
- update memoirist to 0.4.0
- update exact-mirror to 0.1.5
Improvement:
- ElysiaFile doesn't inherits
set.headerseg. cors - [Web Standard] automatically set
Content-Type,Content-Rangeof ElysiaFile
Bug fix:
- #1316 fix context type when multiple macros are selected
- #1306 preserve type narrowing in getSchemaValidator
- add
settohandleFilewhen file isElysiaFile - [Web Standard] inherit set.status for
ElysiaFile - make
ElysiaAdapter.stopoptional
Bug fix:
- #1314 coerce TransformDecodeError to ValidationError
- #1313 onRequest not firing
- #1311 [Exact Mirror] handle property starts with a number
- #1310 webSocket fails to connect when inside group and guard
- #1309 encode is not called when using dynamic handler
- #1304 remove response body from HTTP 101, 204, 205, 304, 307, 308
Change:
- update exact mirror to 0.1.3
- warn when stop is called instead of throwing an error
Improvement:
- #1263 bun adapter add qi to routes that need query from guard
- #1270 add Symbol.dispose
- #1089 add stop function to ElysiaAdapter type
Bug fix:
- #1126 websocket errors not catching
- #1281 automatically enforce additional properties in nested schema (eg. array)
- Dynamic handle decode signed cookie secret instead of accidental hardcoded value
Bug fix:
- #1255 regression in serving an imported HTML file
- #1251 property 'status' does not exist onError function
- #1247 ensure WebSockets get routed properly without AoT compilation
- #1246 property 'timeout' does not exist on type 'Server'
- #1245 error on onAfterHandle (no property 'response')
- #1239 t.Files validator breaks for response schema
- #1187, #1169 websocket beforeLoad not being executed
Feature:
- sse helper
Bug fix:
- #1237 ws in a group merge error
- #1235 errors not handled correctly in resolve hook on dynamic mode
- #1234 optional path parameters can't follow required ones
- #1232 t.Files fails with array of files
Change:
- When yield is not sse, content-type is set to either
text/plainorapplication/jsonbased on the response type
Bug fix:
- mapResponseContext is not passed to compose
- await
ElysiaFilewhen not using Bun - export
adapter/utils
Feature:
- Support Bun native static response per method for Bun >= 1.2.14
- #1213 trace.time is undefined in .trace() callback
Improvement:
- implement all universal type
- offload
AsyncGenerator,ReplaceFilefrom Eden Treaty toCreateEden - #1223 infer
status(200)response from handler if not specified - #1185 use non-greedy match for
isContextPassToFunctionto prevent false positive
Bug fix:
- #1200 limited Bun Router to supported method
- #1199 object are not normalized when t.Transform is provided
- #1198, #1188, #1186 exclude wildcard route from Bun router
- #1197 leave incorrect union field as-is
- #1195 invalid onAfterHandle typing
- #1194 normalize array response
- #1193 undefine value.schema.noValidate
- #1192 using a macro inside a group does not call the handler when using the
precompileoption - #1190 derive and resolve handlers not being executed on WS context
- #1189 Type Inference Issue with Eden Treaty Group Endpoints
- #1185 path is missing from Context when Bun System Router is used
- #1184 Missing
mapEarlyResponseon Bun System Router
Change:
- update
exact-mirrorto0.1.2
Feature:
- add
exactMirror - add
systemRouterconfig standalone Validator- add
Elysia.Reffor referencing schema with autocompletion instead oft.Ref - support Ref inside inline schema
- add sucrose cache
- new validation
t.Form,t.NoValidate - use
file-typeto check file type - add
INVALID_FILE_TYPEerror - add
sanitizeoptions
Improvement:
encodeSchemanow stable and enabled by default- optimize types
- reduce redundant type check when using Encode
- optimize isAsync
- unwrap Definition['typebox'] by default to prevent unnecessary UnwrapTypeModule call
- Elysia.form can now be type check
- refactor type-system
- refactor
_typesinto~Types - using aot compilation to check for custom Elysia type, eg. Numeric
- refactor
app.router.static, and move static router code generation to compile phase - optimize memory usage on
add,_use, and some utility functions - improve start up time on multiple route
- dynamically create cookie validator as needed in compilation process
- reduce object cloning
- optimize start index for finding delimiter of a content type header
- Promise can now be a static response
ParseErrornow keeps stack trace- refactor
parseQueryandparseQueryFromURL - add
configoptions tomount - recompile automatically after async modules is mounted
- support macro on when hook has function
- support resolve macro on ws
- #1146 add support to return web API's File from handler
- #1165 skip non-numeric status codes in response schema validation
- #1177 cookie does not sign when an error is thrown
Bug fix:
Responsereturned fromonErroris using octet stream- unintentional memory allocation when using
mergeObjectArray - handle empty space on Date query
Change:
- only provide
c.requestto mapResponse whenmaybeStreamis true - use plain object for
routeTreeinstead ofMap - remove
compressHistoryHookanddecompressHistoryHook - webstandard handler now return
text/plainif not on Bun - use non const value for
decorateunless explicitly specified Elysia.mountnow setdetail.hide = trueby default
Breaking Change:
- remove
as('plugin')in favor ofas('scoped') - remove root
indexfor Eden Treaty - remove
websocketfromElysiaAdapter - remove
inference.request
Bug fix:
- #1108 use validation response instead of return type when schema is provided
- #1105, #1003 invalid parsing body with missed fields if used object model
Bug fix:
- 200 object response is not inferring type in type-level
- #1091 route is not defined when using trace
Bug fix:
Bug fix:
Bug fix:
- #671 Transform inside t.Intersect isn't detected
Bug fix:
- #671 Transform query schema check fails
- model type
Bug fix:
- #1078 array string default to '[]' instead of undefined
Bug fix:
- duplicated static route may cause index conflict resulting in incorrect route
Bug fix:
.mountdoesn't return pass entire request
Improvement:
AfterHandlerinfer response type
Change:
- #1068 update
@sinclair/typeboxto0.34.27
Bug fix:
- #1075 nested async plugins mismatch routes to handlers
- #1073 file type validation not working
- #1070 .mount is mutating the incoming request method
- mount path is incorrect when using prefix with trailing
* - #873 add
experimental.encodeSchemafor customTransformEncode type
Bug fix:
- #1067 recompile async plugin once registered
- #1052 webSocket errors not getting catched by error handler
- #1038 incorrect type inference with deferred modules leads to TypeErrors in runtime
- #1015 using a model by name in route query leads to type mispatch, yet validation succeeds if doesn't use Ref
- #1047 ampersand in URL search params is discarded
- detect
Transforminsidet.ArrayinhasTransform
Improvement:
- add test cases for
hasTransform hasTransformnow supports Union, Intersect- remove redundant
decodeURIComponentin nested query
Feature:
- parse nuqs string array format if query is specified as
t.Array(t.String())
Improvement:
- handle recursive nested async plugin
- Response now handle proxy streaming
- #971 wrap import("fs/promises") AND wrap import("fs") in try-catch to avoid error (silly me, tee-hee~)
- handle nested array property swap for
replaceSchemaType
Breaking Change:
- [Internal]
Elysia.modulesnow return void
Improvement:
- #977 use Registry instead of TypeSystem
- remove redundant switch-case for path mapping when strictPath is disabled and path is overlapped
- remove redundant allocation for nativeStaticHanlder when strictPath path is overlapped
Bug fix:
- #1062 correctly set t.Date() defaults
- #1050 app.onRequest(ctx => {ctx.server}): Can't find variable: getServer
- #1040 undefined route context on aot=false
- #1017 replace t.Number() for Type.Integer()
- #976 error responses with aot: false
- #975 await nested async plugins
- #971 wrap import("fs/promises") in try-catch to avoid error
- discord file format doesn't check for '*' format
Bug fix:
- warn when non-existing macro is used
- parser doesn't generate optimize instruction
Feature:
- Reduce memory usage:
- Compressed lifecycle event
- Avoid unnecessary declaration in compose.ts
- Lazily build radix tree for dynamic router
Change:
- Update TypeBox to 0.34.15
Bug fix:
- #1039 Elysia fails to start with an error inside its own code when using decorate twice with Object.create(null)
- #1005 Parsing malformed body with NODE_ENV 'production' results in UNKNOWN error
- #1037 Validation errors in production throw undefined is not an object (evaluating 'error2.schema')
- #1036 Support Bun HTML import
Feature:
- add shorthand property for macro function
Improvement:
- use
deuriinstead offast-decode-uri-component - #985 MaybeEmpty and Nullable should have options args
Bug fix:
- Macro function doesn't inherits local/scoped derive and resolve in type-level
Bug fix:
- Resolve macro unintentionally return instead of assign new context
Bug fix:
- #966 generic error somehow return 200
Bug fix:
- macro doesn't work with guard
- #981 unable to deference schema, create default, and coerce value
- #966
error's value return as-if when thrown - #964 InvalidCookieSignature errors are not caught by onError
- #952 onAfterResponse does not provide mapped response value unless aot is disabled
mapResponse.responseis{}if no response schema is provided- Response doesn't reconcile when handler return
Responseis used withmapResponse onErrornow acceptserrorasnumberwhenElysia.erroris thrown (but not returned)
Bug fix:
- mapResponse with onError caused compilation error
Bug fix:
- define universal/file in package export
Bug fix:
- performance regression from eager access abortSignal
Bug fix:
- #973 Parsing malformed body results in
UNKNOWN-Error instead ofParseError - #971 remove top level import, use dynamic import instead
- #969 Invalid context on
.onStart,.onStop - #965 [Composer] failed to generate optimized handler. Unexpected identifier 'mapCompactResponse'
- #962 fix schema default value when AOT is of
- decorator name with space is not working
Bug fix:
- conditional import and require
Bug fix:
- conditional import for fs
- object macro parameter maybe array
- optional return for macro
Feature:
- Commitment to Universal Runtime Support
- Node Adapter
- Web Standard Adapter
- Bun Adapter
- Universal Utilities
- Name parser
- Add resolve support to Macro
- Improve WebSocket
- Support ping, pong and latest Bun feature
- Match type declaration with Bun
- Support for return, yield
- Match Context type
- Performance Improvement
- Entire rewrite
- bind over getter return
- Infer 422 validation
- Compilation minification
- Validation Stuff
- t.MaybeArray
- Typebox Module & Nested model
- Inline module
Improvement:
- Memory Usage
- [Internal] Register loosePath in compilation process to reduce memory usage and reduce registration time from O(2n) to O(n)
- Try to accept and coerce different version of Elysia plugin
- Event Listener now infers path parameter automatically based on scope
- Add ‘scoped’ to bulk
asfor casting type to ‘scoped’ similar to ‘plugin’
Change:
- Update
cookieto 1.0.1 - Update TypeBox to 0.33
content-lengthnow accept number
Breaking Change:
- [Internal] Remove router internal property static.http.staticHandlers
- [Internal] Router history compile now link with history composed
Bug fix:
Bug fix:
- #907, #872, #926 BooleanString is not behave correctly if property is not provided
- #929 Non-ASCII characters cause querystring index to be incorrectly slice
- #912 handle JavaScript date numeric offset
Bug fix:
Change:
- don't minify identifiers in bun bundle
Security:
- #891 Upgrade Cookie to 0.7.x to fix CVE-2024-47764
Bug fix:
Bug fix:
- Handle object with
.theneven if it's not promise (looking at you, Drizzle)
Bug fix:
- Fix
set-cookieto resent if value is accessed even without set
Improvement:
- infer 200 response from handle if not specified
Bug fix:
- merge guard and not specified hook responses status
Bug fix:
- unable to return
errorfrom derive/resolve
Breaking change:
- remove automatic conversion of 1-level deep object with file field to formdata
- migration: wrap a response with
formdata
- migration: wrap a response with
- (internal): remove
ELYSIA_RESPONSEsymbol - (internal)
errornow useclass ElysiaCustomStatusResponseinstead of plain object
Improvement:
- Optimize
object typeresponse mapping performance
Change:
- Coerce number to numeric on body root automatically
- Coerce boolean to booleanString on body root automatically
Bug fix:
- #838 invalid
onAfterResponsetyping - #855 Validation with Numeric & Number options doesn't work
- #843 Resolve does not work with aot: false
Bug fix:
- separate between
createStaticHandlerandcreateNativeStaticHandlerfor maintainability - performance degradation using inline fetch on text static response and file
Bug fix:
createStaticResponseunintentionally mutateset.headers
Feature:
- add auto-completion to
Content-Typeheaders
Bug fix:
- exclude file from Bun native static response until Bun support
- set 'text/plain' for string if no content-type is set for native static response
Feature:
- #813 allow UnionEnum to get readonly array by @BleedingDev
Bug fix:
- #830 Incorrect type for ws.publish
- #827 returning a response is forcing application/json content-type
- #821 handle "+" in query with validation
- #820 params in hooks inside prefixed groups are incorrectly typed never
- #819 setting cookie attribute before value cause cookie attribute to not be set
- #810 wrong inference of response in afterResponse, includes status code
Feature:
- setup provenance publish
- #808 add UnionEnum type with JSON schema enum usage
- #807 add closeActiveConnections to Elysia.stop()
Bug fix:
- #808 ArrayString type cast as Object instead of Array
- config.nativeStaticResponse is not defined
Feature:
- native Bun static response
- can be disabled by setting
app.config.nativeStaticResponse = false
- can be disabled by setting
- #93 export TypeSystemPolicy
- #752 tye coercion on dynamic mode
Bug fix:
- #332 mount() does not preserve body when fetching through http server
- Using as('plugin') cast cause derive key to be unknown
Bug fix:
- incorrect named export 'fasti-querystring' to 'fast-querystring'
Change:
- getter fields no longer stringified to JSON by default on returning response
Bug fix:
- #796 ValueClone: Unable to clone value after 1.1.8 update
- #795 Broken Dates after 1.1.8 update
- #793 Unable to delete property. t.File()
Feature:
- #748 add standardHostname config
Bug fix:
- #787 #789 #737 Unexpected TypeError on NODE_ENV=production in mapValueError
- #793 unable to delete property t.File()
- #780 error from sending empty body multipart/form-data
- #779 custom errors thrown in onRequest are not usable when caught in onError
- #771 error from body-parser when sent Content-Type header without body
- #679 plugin registered by async inline function don't work
- #670 support for classes and getter fields
Bug fix:
parseQueryis not parsing array on body
Change:
- rename
parseQuerytoparseQueryFromURL - export fast-querystring.js path
Feature:
- #763 add hide in detail to hide route from OpenAPI/swagger
- add streaming support for fetch proxy
Bug fix:
- #776 custom errors throw in onRequest do not get proper code set in onError
Feature:
- refactor fastQuerystring using switch and bitwise flag
Bug fix:
- sucrose: invalid separateFunction on minified async function
- #758 guard doesn't apply cookie schema
Feature:
- #718 implement normalization support for class instances with getter functions
Bug fix:
- removeColonAlias accidentally slice -2 end index for last parameter
- #726 lazy instantiation of
stringToStructureCoercions - #750 Cookie: Right side of assignment cannot be destructured
- #749 Query params following an array query are parsed as array items
- #751 Dynamic mode response failed if null or undefined value is returned
- #741 stream stringify object
Change:
- sucrose: exact inference name
- use
mapResponseinstead ofmapCompactResponsefor stream - defers first stream execution before returning response
- #722 derive context is not passed to onError
Bug fix:
onErrorwith scope not being able to infer context type
Bug fix:
- #724, bun#12594 sucrose: possibly fix
bun build --compilenot being able to infer first, and last context parameter - derive is being override by resolve in certain function
- #722 Type error with global
app.derivefollowed by onError
- #722 Type error with global
- params on
onErroris now{ [key in string]: string }instead ofnever - #721 unexpected isContextPassToFunction: minified whitespace of arrow function causing inaccurate separateFunction
Breaking Change:
- parse query as
stringinstead ofstring | string[]unless specified
Feature:
- Trace v2
- Normalization is on by default
- Data type coercion
- Guard as, bulk as cast
- Response status coercion
- Optional path parameter
- Generator response stream
Breaking Change:
- Parse value as string for all validators unless explicitly specified.
- Rename
onResponsetoonAfterResponse - [Internal] Remove $passthrough in favor of toResponse
- [Internal] UnwrapRoute type now always resolve with status code
Improvement:
- Add auto-complete for
set.headers - Add
serverproperty onErrorsupports array function- Parse query object with and without schema
- Sucrose: improve isContextPassToFunction, and extractMainParameter stability
- Add
replaceSchemaType - Add
routetocontext - Optimize recursive MacroToProperty type
- Parse query array and object
- Optimize code path for
composeGeneralHandler - Add debug report on compiler panic
- Reduce memory usage of route registration ~36% on large codebase
- Reduce compilation code path
- Remove trace inference
- Reduce router compilation code path
- removing route handler compilation cache (st${index}, stc${index})
- Add undefined union to cookie in case if cookie is not present
- Optimize response status resolve type inference
Change:
- Deprecated
ObjectStringfor parsing array - Using
Cookie<unknown>instead ofCookie<any>if schema is not defined - Remove prototype poluation from hook
- remove static analysis for query name
- remove query replace '+' in favor removing static query analysis
- mapResponse is now called in error event
- reconcilation decorator in type level
Bug fix:
- Normalize headers accidentally use query validator check instead
onErrormissing trace symbol- Headers validator compilation is not cached
- Deduplicate macro propagation
- Websocket in nested group now work
- Error response is not check unless successful status code is provided
Bug fix:
Bug fix:
- mapResponse is not called on beforeHandle, and afterHandle
Bug fix:
- type is resolved as
Fileif@types/bunis not installed when using with Eden Treaty
Bug fix:
derive,resolvesupport void return- #677 Query params validation for array of string fail
Feature:
- add
toResponsefor mapping custom response - #606 Object encoding in query parameters
Bug fix:
- #654 set correct normalization behavior for addtional properties
- #649 cookie decode value might be null
- #664 "default" option is not being applied on validation
- #656 ctx.query doesn't work in some case
- set forceDynamicQuery to true by default
- #658 aot does not recognize the use of ctx.body within a try catch
- #630 accessing ctx.query directly breaks the object
Breaking Change:
- set default cookie path to
/
Feature:
- add
formutility for returning explicit formdata - add object with image to return as
formdata
Bug fix:
- return
Bun.fileby specifyingt.File()andt.Object({ any: t.File() })as a response
Breaking Change:
t.type({ error })now accepts(error: ({ type, validator, value, errors }) => unknown)instead of(error: (type, validator, value) => unknown)
Improvement:
t.type({ error })acceptsstring | number | boolean | Objectinstead ofstringt.type({ error })returnstring | number | boolean | Object | voidinstead ofstring- add
errors: ValueError[]tot.type({ error({ errors }) {} })
Bug fix:
- #644 redirect doesn't work with
aot: false - #641 cookie schema validation doesn't work with
aot: true - #615 highlight derive and resolve when using
onError
Bug fix:
- macro is not inherits inside group
Bug fix:
- remove set.clone spread operator for mapping Response
Feature:
- add support for partitioned cookie
Bug fix:
- recursive MacroToProperty type on unknown macro
Improvement:
- add context.url to get full URL string (including query)
- reduce query parsing instruction
Bug fix:
- ratelimit#28 trace hang when using server-timing with rate-limit plugin
Feature:
- add
redirectfunction toContext
Improvement:
- sucrose: remove unreachable query bracket check, reduce bracket instruction
- sucrose: query accessor keyword check at initialization instead of in loop
- sucrose: remove accessor check
- sucrose: skip query check for immediate return
Change:
- sucrose: add
isArrowReturntoseparateFunction - sucrose: skip inference queries check if
queryis not found
Change:
- allow custom parser when
typeis specified - add
contentTypeto context - soft deprecate
contentTypeas 2ndparseparameter
Bug fix:
- #622 sucrose: mistake cookie for query
- duplicate format found
- using
parse,type,bodygenerate invalid syntax
Improvement:
- #596 account for 20x response status schemas for type safety
Bug fix:
- #615
- 588 separate async derive/resolve function doesn't get await
- primitive thrown result in invalid type
Improvement:
- export
InferContextandInferHandler
Bug fix:
- remove accidental
console.logincompile
Feature:
- add
InferContext
Bug fix:
- returning null with response validation cause error
Bug fix:
- possibly fix for "Duplicate type kind 'Files' detected"
- add ajv-formats
- #562 %26 (&) to be interpreted as & (query separator)
Bug fix:
- ServerTiming#1 late beforeHandle on set trace inference doesn't produce exit instruction
Feature:
Elysia.config.detailconstructor- shorthand
Elysia.tagsto constructor,LocalHook - guard inherits detail
Bug fix:
- inference link on
precompile: falsecreating unnecessary instruction
Feature:
- #562 add
normalizeconfig
Improvement:
- Scope cookie instruction to route level instead of global config
- #557 cache tsc buildinfo for running faster
- #551 use AnyElysia instead of inline Elysia
Bug fix:
Feature:
- add Elysia.propagate to propagate hook type from 'local' to 'scoped'
Improvement:
- remove function.$elysia
- remove function extension
Bug fix:
- duplicate macro call
- #548 additional case for "accessing all query params using property name (ctx.query) doesn't work anymore"
- #599 plugin with scoped settings not functioning correctly
Bug fix:
- inline function doesn't propagate correctly on type level
Improvement:
- using regex for date pattern matching before using new Date validation
- using tsc to emit declaration file instead of tsup
- add
mapResponseto MacroManager
Bug fix:
- Ephemeral and Volatile type isn't recognize by MacroManager
- inline guard cookie doesn't apply to local instance
Improvement:
- resolve, derive soundness
Improvement:
- Reduce instruction for static resource
Bug fix:
- Fix returning mulitple status code using
errordoesn't accept the response
Feature:
- add
scopedsupport forderiveandresolve
Improvement:
- Type soundness
- type inference performance improvement
Improvement:
mapHandlernow check passthrough once instead of twice- exclude return type of
ELYSIA_RESPONSEtype fromderiveandresolve - throw error if
erroris return inderiveandresolve - handle
return errorontransform - #502 merge response schema from parent scope
Bug fix:
- explicit
type: 'json'with body schema throw unexpectedbody.Checkis not a function - #549 await the .modules of nested Elysia instances
- #548 Accessing all query params using property name (ctx.query) doesn't work anymore
Improvement:
- fine-grained reactive cookie
- using single source of truth for cookie
- macro support for websocket
- add
mapResolve - add
{ as: 'global' | 'scoped' | 'local' }to lifecycle event - add ephemeral type
- inline
errorto handler - inline
errorhas auto-completion and type checking based on status code - handler now check return type of
errorbased on status code - utility
Elysia._typesfor types inference - #495 Provide user friendly error for failed parse
- handler now infers return type for error status for Treaty
t.Datenow allow stringified date- improves type test case
- add test case for all life-cycle
- resolve, mapResolve, derive, mapDerive use ephemeral type to scope down accurately
- inference query dynamic variable
Breaking Change:
- #513 lifecycle is now local first
Change:
- group private API property
- move
Elysia.routestoElysia.router.history - detect possible json before return
- unknown response now return as-is instead of JSON.stringify()
- change Elysia validation error to JSON instead of string
- static content evalute hook JIT instead of AOT
Bug fix:
- #466 Async Derive leaks request context to other requests if
aot: true - #505 Empty ObjectString missing validation inside query schema
- #503 Beta: undefined class when using decorate and derive
- onStop callback called twice when calling .stop
- mapDerive now resolve to
Singleton['derive']instead ofSingleton['store'] ValidationErrordoesn't returncontent-typeasapplication/json- validate
error(status, value)validate per status - derive/resolve always scoped to Global
- duplicated onError call if not handled
- #516 server timing breaks beforeHandle guards
- cookie.remove() doesn't set correct cookie path
Feature:
- #474 Numeric Cookie with length >= 16 cant be parsed to number
- #476 Using a query key that contains a hyphen or a dot raises a SyntaxError
- #460
Change:
- #472 Move documentation issue template to documentation repository
Feature:
- #448 BooleanString - @bogeychan
Bug fix:
Bug fix:
- #451 macro does not run when it should (macro deduplication)
- #450 Local hook parse doesn't get executed with
aot: false
Bug fix:
- types are missing in
exports.* - #441 Vite doesn't get bundle without main
Bug fix:
- types is not import
- bun build regression on export * from '@sinclair/typebox/system'
- update memoirist to use mjs
Change:
- using .mjs for es module
Change:
- using tsup instead of swc
- #441 remove nanoid, using web crypto randomInt instead
Bug fix:
- #446 numeric string check to use Number instead of parseInt
- #445 empty body custom response when set.headers is empty
Bug fix:
- #440 query params with + sign did not get converted
- #433 remove crypto, unblock vite bundling, cloudflare worker support
- #422 add check for instanceof if constructor.name doesn't match
Bug fix:
- macro panic
Bug fix:
- Add TypeBox back to Bun bundle
Improvement:
- #385 If error is instanceof Response, respond with it
Bug fix:
- onRequest doesn't early return
- handle thrown error function
- #373 cookie is not set when File is return
- #379 WebSocket: Sending a space character ' ' receives 0
- #317 Exclude TypeBox from bundling
Bug fix:
- body without default value thrown Object.assign error
Bug fix:
- Bun entry point
Bug fix:
- macro caused an Object.entries cannot be undefined
mapResponseandafterHandlemissing decorators
Bug fix:
- add early return on
isContextPassToFunctionfor static content to prevent invalid regex
Bug fix:
ctx.pathandctx.qiis missing when usingonRequest
Bug fix:
beis undefined when usingafterResponsewithmapResponse
Feature:
headersinitialization function- macro
- static content
- default property
- error function
- add stack trace to plugin checksum configurable by
config.analytic(default to false) - new life-cycle
resolve: derive after validationmapResponse: custom response mapping
Improvement:
- lazy query reference
- add content-range header to
FileandBlobby default if etag is not used - update TypeBox to 0.32
- override lifecycle response of
beandaf
Breaking Change:
afterHandleno longer early return
Change:
- change validation response to JSON
- differentiate derive from
decorator['request']asdecorator['derive'] derivenow don't show infer type in onRequest
Bug fix:
- remove
headers,pathfromPreContext - remove
derivefromPreContext - Elysia type doesn't output custom
error onStartdoesn't reflect server
Improvement:
- #345 add font to
SchemaOptions - Update
@types/cookieto^0.6.0
Bug fix:
- #338 guard sandbox did not inherit global config.
- #330 preserve query params for mounted handler
- #332 reexport TSchema from typebox
- #319 TypeBox Ref error when using Elysia.group()
Bug fix:
- Emergency release override latest beta
Bug fix:
- WebSocket params conflict with defined type
- Inherits status code on custom error
Chore:
- Update
cookieto0.6.0
Bug fix:
- #314 Unable to dereference schema with 'undefined' when using t.Ref
Bug fix:
- #312 default params type suggestion for WebSocket
- #310 Preserve original hostname when using
.mount() - #309 t.RegExp doesn't work due to requiring default value
- #308 t.Numeric should not convert empty string to 0
- #305 Elysia({ scoped: true }) should still expose defined routes on type level
- #304 Using a hook/guard/schema with a handler function and request without body results in a "Unexpected end of JSON input"-error
- #299 Missing request.path parameter in .onRequest
- #289 Ability to localize TypeBox errors
- #272 onError handler has error property as undefined on Cloudflare Workers
- #210 t.Numeric not validating properly
- #188 Status codes of the error classes don't match the response through onError
- #140 plugin hierarchy messes up derive function in child plugin
- #27 Websocket definition in groups
Bug fix:
- duplicated lifecycle event if using function plugin async
Bug fix:
- Leaked type from
guardcallback andgroup guard
Bug fix:
- add
ReadableStreamto response mapping tomapResponse
Bug fix:
- Send
exitstatus on early return with trace set
Change:
- Rewrite
trace
Bug fix:
- trace not awaiting multiple trace process
- trace hang on early
beforeHandlereturn afterHandlewithtrace.afterHandleAoT cause duplicate value header
Bug fix:
- #281 add cookie.remove options
- add
await traceDoneto early return
Bug fix:
traceis stuck when inherits to plugin
Improvement:
- add unit test for
mapCompactResponse,Passthrough
Bug fix:
- add
$passthroughformapCompactResponse
Feature:
- add map handler for
ReadableStream - add
$passthroughfor custom property for response mapping
Bug fix:
.routeacceptstring[]instead ofstring
Change:
- remove
ElyEden
Feature:
- add
ElyEden - re-add
idto websocket
Bug fix:
- #255 removeCookie sends HTTP-Header that is ignored by the Browser
- #263 http and websocket on same route
- #269 Correct handling of Buffer object
Improvement:
t.Cookiecookie option type- #253 platform agnostic cookie
- Decorator like
state,decorateandderive, doesn't apply to WebSocketdata - re-export
Staticfrom
Change:
- Update TypeBox to 0.31.17
- #218 Fix #213 prepend async redefined routes (partial fix)
- Using set
onRequestdoesn't set headers and status on empty error handler
Bug fix:
- Make
t.Filesparameter optional - model remap now using
TSchemainstead of literal type for creating type abstraction
Improvement:
- Using listener instead of microtick to handle
trace.set - Set default cookie path to '/'
Bug fix:
- Duplicate group path when hook is provided
Bug fix:
- Handle cookie expire time
- Set default value of config.cookie.path to '/'
Improvement:
- Skip cookie validation if schema is empty object
Bug fix:
- Accept cookie property from constructor when schema is not defined
Bug fix:
- handle FFI object in deepMerge, fix Prisma
Bug fix:
- async instance cause config to be undefined
Bug fix:
- async instance cause type conflict
Bug fix:
- #210
t.Numericallowing plainString t.ObjectStringallowing plainString- #209
t.MaybeEmptytoleratenullandundefined - #205 WebSocket routes not working in plugins
- #195, #201 allow WebSocket destructuring
Bug fix:
- Separate return type by status
Bug fix:
- inject derive to
GraceHandler
Bug fix:
- check for class-like object
- add
GraceHandlerto access bothappandcontext
Bug fix:
- resolve 200 by default when type is not provided
Bug fix:
- decorator and store is resolved as
undefinedinonErrorhook - deepMerge with Module object
- Retain comment in
.d.ts
Bug Fix:
- Class property is removed when calling deepMerge
Feature:
- rewrite type
- rewrite Web Socket
- add mapper method
- add affix, prefix, suffix
- trace
- typeBox.Transfom
- rewrite Type.ElysiaMeta to use TypeBox.Transform
- new type:
- t.Cookie
- t.ObjectString
- t.MaybeEmpty
- t.Nullable
- add
ContexttoonError - lifecycle hook now accept array function
- true encapsulation scope
Improvement:
- static Code Analysis now support rest parameter
- breakdown dynamic router into single pipeline instead of inlining to static router to reduce memory usage
- set
t.Fileandt.FilestoFileinstead ofBlob - skip class instance merging
- handle
UnknownContextPassToFunction - #157 WebSocket - added unit tests and fixed example & api by @bogeychan
- #179 add github action to run bun test by @arthurfiorette
Breaking Change:
- remove
wsplugin, migrate to core - rename
addErrortoerror
Change:
- using single findDynamicRoute instead of inlining to static map
- remove
mergician - remove array routes due to problem with TypeScript
Bug fix:
- strictly validate response by default
t.Numericnot working on headers / query / paramst.Optional(t.Object({ [name]: t.Numeric }))causing error- add null check before converting
Numeric - inherits store to instance plugin
- handle class overlapping
- #187 InternalServerError message fixed to "INTERNAL_SERVER_ERROR" instead of "NOT_FOUND" by @bogeychan
- #167 mapEarlyResponse with aot on after handle
Feature:
- #149 support additional status codes in redirects
Improvement:
- #157 added unit tests and fixed example & api
Bug fix:
- #167 mapEarlyResponse with aot on after handle
- #160 typo in test suite name
- #152 bad code in Internal server error class
Bug fix:
- Maximum callstack for duplicated deep class / object
- #121 Cannot use PrismaClient in .decorate or .state
Bug fix:
- Remove
constandRemoveDeepWritablefrom decorate to allow function call
Feature:
- #112 Route arrays
Bug fix:
- #107 Elysia handler local hooks not recognizing registered errors on app instance
Bug fix:
- Inherits state and error from plugin instance
Improvement:
- Automatically parse File to
Filesif set
Bug fix:
- #98 Add context.set.cookie to accept array of string
- #92 WebSocket beforeHandle unable to access plugins / state / derive's
Bug fix:
- inherits
onErrorlifecycle from plugin instance
Bug fix:
- inherits
setifResponseis returned
Bug fix:
- deduplicate plugin via global model
- duplicated life-cycle
- top-down plugin deduplication
- plugin life-cycle leak on new model
- add
Elysia.scopeto contain lifecycle, store, and decorators
Bug fix:
- make this.server.reload optional to make Node compatability work
- duplicate path name when using prefix config with group
- don't filter local event inside new plugin model group
- Remove post.handler in return
Bug fix:
- Make this.server.reload optional to make Node compatability work
Bug fix:
- #86 Group prefix repeating on inline function callback
- #88, onResponse hooks validation return non 400
Bug fix:
- Query is set to pathname when ? not presented in dynamic mode
Bug fix:
- Derive not working on dynamic mode
Bug fix:
- append routes on dynamic mode
Bug fix:
- use: Plugin type inference
Bug fix:
- Collide Elysia.prefix on other methods
Bug fix:
- Collide Elysia.prefix type
Bug fix:
- Collide Elysia.prefix type
- Add skip group with prefix instance see #85
Bug fix:
- resolve .code and [ERROR_CODE]
Change:
- Add ErrorCode symbol
Bug fix:
- Inline guard hook
- Error code not handled
- Set default query to {} when presented
Improvement:
- Drop usage of
node:processto support Cloudflare Worker
Feature:
- Introducing Dynamic Mode (aot: false)
- Introducing
.mount - Introducing
.errorfor handling Strict Error Type - Plugin checksum for plugin deduplication
- Add
.onResponse
Improvement:
- TypeBox 0.30
- AfterHandle now automatically maps the value
- Using Bun Build for targeting Bun
- Support Cloudflare worker with Dynamic Mode (and ENV)
Change:
- Moved registerSchemaPath to @elysiajs/swagger
Feature:
- Add
addErrorto declaratively add Error to scope - Add
afterHandlenow can return a literal value instead of limited to onlyResponse
Feature:
- Introduce
.mount - Add dynamic mode for TypeBox
- Add $elysiaChecksum to deduplicate lifecycle event
- Add $elysiaHookType to differentiate between global and local hook in
use
Fix:
- Deduplication of plugin's lifecycle (see $elysiaHookType)
Change:
- Using Bun Build for target Bun
Breaking Change:
- [Internal] refactored
getSchemaValidator,getResponseSchemaValidatorto named parameters - [Internal] moved
registerSchemaPathto@elysiajs/swagger
Feature:
- [Internal] Add qi (queryIndex) to context
- Add
errorfield to Elysia type system for adding custom error message
Feature:
- [Internal] Add support for accessing composedHandler via routes
Feature:
- Dynamic mode for Cloudflare Worker
- Support for registering custom error code
- Using
loosePath(by default), and add `config.strictPath - Support for setting basePath
- Recursive path typing
Improvement:
- Slighty improve type checking speed
Bug Fix:
- recursive schema collision causing infinite type
Breaking Change:
- Remove Elysia Symbol (Internal)
Bug fix:
- ws resolve type to undefined instead of unknown cause unexpected type mismatched when not provided
Bug fix:
- #68 invalid path params when using numeric
Bug fix:
- #68 invalid optional query params when using numeric
Bug fix:
- update onAfterHandle to be Response only
Bug fix:
- async fn on Static Code Analysis
Bug fix:
- optimize
wsplugin type
Bug fix:
mapEarlyResponseis missing on request
Improvement:
- Respect explicit body type first
mapCompactResponseonnullorundefinedtype
Bug fix:
- Mapped unioned type on Static Code Analysis
formisundefinedwhen using parsingformData
Improvement:
- Respect inner scope of lifecycle first
- Add type support for local
afterHandle
Bug fix:
onAfterHandlercause response to mutate on void
Improvement:
- Map CommonJS module in package.json
Improvement:
- Using tsc to compile CommonJS instead of SWC to support
module.exportssyntax
Bug fix:
- Add loosen type for onError's code for defying custom error status
Bug fix:
- Multiple onRequest cause error
Improvement:
- Experimental basic support for Static Code Analysis in Nodejs
Bug fix:
- h is undefined when using headers in Node environment
- Update Memoirist to 0.1.4 to support full CommonJS
Improvement:
- Add content-type support for 'none', 'arrayBuffer' / 'application/octet-stream'
- Add type support type registration of wildcard params
- Add support for 'config.basePath'
Improvement:
- Add support for returning a class instance
Bug fix:
- Bun is undefined on other runtime
Improvement:
- Using
new Responseinstead of factoryResponse.json
Improvement:
- Using request.json() to handle application/json body instead of JSON.parse(await c.text())
Improvement:
- Add Static Code Analysis for conditional try-catch
- Reduce usage of method to accessor
Improvement:
- Add
mapCompactResponsefor static code analysis - Using
constructor.nameto inline object mapping - Using single assignment for URL destructuring
- Using default map for dynamic route to remove static map label and break
Bug fix:
- Web Socket context.headers is empty Elysia#46
Improvement:
- Static Code Analysis for fallback route
Bug fix:
- Remove constant generic from
stateto be mutable
Bug fix:
- Syntax error if multiple numeric type is set
- Prevent fallthrough behavior of switch map
Improvement:
- Add CommonJS support for running Elysia with Node adapter
- Remove manual fragment mapping to speed up path extraction
- Inline validator in
composeHandlerto improve performance - Use one time context assignment
- Add support for lazy context injection via Static Code Analysis
- Ensure response non nullability
- Add unioned body validator check
- Set default object handler to inherits
- Using
constructor.namemapping instead ofinstanceofto improve speed - Add dedicated error constructor to improve performance
- Conditional literal fn for checking onRequest iteration
- improve WebSocket type
Bug fix:
- Possible
Breaking Change:
- Rename
innerHandletofetch- to migrate: rename
.innerHandletofetch
- to migrate: rename
- Rename
.setModelto.model- to migrate: rename
setModeltomodel
- to migrate: rename
- Remove
hook.schematohook- to migrate: remove schema and curly brace
schema.type:
// from app.post('/', ({ body }) => body, { schema: { body: t.Object({ username: t.String() }) } }) // to app.post('/', ({ body }) => body, { body: t.Object({ username: t.String() }) })
- to migrate: remove schema and curly brace
- remove
mapPathnameRegex(internal)
Bug fix:
- it recompile on async
Bug fix:
- detect promise on parse
- using swc to compile to commonjs
Improvement:
- Improve merge schema type
Bug fix:
- Add support for ALL method for dynamic path
- Add support for parser in pre-compiled body
Bug fix:
- Use Memoirist instead of Raikiri in ws
Improvement:
- Static Code Analysis on derive
Improvement:
- Re-compile on lazy modules
Improvement:
- Merge nested schema type
Fix:
- set default object handler to inherits
Fix:
- emergency override experimental version
Fix:
- CatchResponse to return 200 status code by default when using Eden Treaty
Fix:
- response schema doesn't unwrap response type
Fix:
- Update Raikiri stability
Improvement:
- Add support for
parsein websocket #33
Fix:
- Inherits out-of-order
onErrorlife cycle in nested group - Update Raikiri to 0.1.2 to handle mangled part
Fix:
- Fix LocalHandler doesn't check single type response
Improvement:
- Update Raikiri to ^1.1.0
Improvement:
- perf: add static route main class
- perf: reduce
ComposedHandlerto function instead of nested object
Fix:
groupandguardshouldn't decorate a request on type-level (acceptable on run-time level for shared memory)
Fix:
- Using default value check for
set.statusinstead truthy value
Improvement:
- using
isNotEmptyformapResponse - pre check if
set.headers['Set-Cookie']is array before converting to headers - using
mapPathnameAndQueryRegEx.exec(request.url)instead ofrequest.url.match(mapPathnameAndQueryRegEx)
Fix:
- Scoped decorators
Improvement:
- Use constructor name for faster handler matching
- Map Promise
Fix:
- remove type module from package.json
Feature:
- Ahead of Time compilation
- TypeBox 0.26
- Validate response per status instead of union
- Add
iffor conditional route - Custom Validation Error
Improvement:
- Update TypeBox to 0.26.8
- Inline a declaration for response type
- Refactor some type for faster response
- Use Typebox
Error().First()instead of iteration - Add
innerHandlefor returning an actual response (for benchmark)
Breaking Change:
- Separate
.fnto@elysiajs/fn
Fix:
- child to inhertis WebSocket plugin (elysiajs#27)
- multiple status response does not work with the group (elysiajs#28)
Fix:
- Wildcard fallback of Raikiri
Feature:
- Elysia Fn
- Suport
multipart/form-data t.Fileandt.Filesfor file validationschema.contentfor specifying content type
Improvement:
- Add string format: 'email', 'uuid', 'date', 'date-time'
- Update @sinclair/typebox to 0.25.24
- Update Raikiri to 0.2.0-beta.0 (ei)
- Add file upload test thanks to #21 (@amirrezamahyari)
- Pre compile lowercase method for Eden
- Reduce complex instruction for most Elysia types
- Change store type to
unknown - Compile
ElysiaRoutetype to literal - Optimize type compliation, type inference and auto-completion
- Improve type compilation speed
- Improve TypeScript inference between plugin registration
- Optimize TypeScript inference size
- Context creation optimization
- Use Raikiri router by default
- Remove unused function
- Refactor
registerSchemaPathto support OpenAPI 3.0.3 - Add
errorinference for Eden - Mark
@sinclair/typeboxas optionalpeerDenpendencies
Fix:
- Raikiri 0.2 thrown error on not found
- Union response with
t.Fileis not working - Definitions isn't defined on Swagger
- details are missing on group plugin
- group plugin, isn't unable to compile schema
- group is not exportable because EXPOSED is a private property
- Multiple cookies doesn't set
content-typetoapplication/json EXPOSEDis not export when usingfn.permission- Missing merged return type for
.ws - Missing nanoid
- context side-effects
t.Filesin swagger is referring to single file- Eden response type is unknown
- Unable to type
setModelinference definition via Eden - Handle error thrown in non permission function
- Exported variable has or is using name 'SCHEMA' from external module
- Exported variable has or is using name 'DEFS' from external module
- Possible errors for building Elysia app with
declaration: trueintsconfig.json
Breaking Change:
- Rename
injecttoderive - Depreacate
ElysiaRoute, changed to inline - Remove
derive - Update from OpenAPI 2.x to OpenAPI 3.0.3
- Move context.store[SYMBOL] to meta[SYMBOL]
Improvement:
- Add string format: 'email', 'uuid', 'date', 'date-time'
Fix:
- Raikiri 0.2 thrown error on not found
Improvement:
- Update @sinclair/typebox to 0.25.24
- Update Raikiri to 0.2.0-beta.0 (ei)
- Add file upload test thanks to #21 (@amirrezamahyari)
Fix:
- Union response with
t.Fileis not working
Fix:
- Definitions isn't defined on Swagger
- details are missing on group plugin
- group plugin, isn't unable to compile schema
- group is not exportable because EXPOSED is a private property
Fix:
- console.log while using cookie
Breaking Change:
- Rename
injecttoderive
Fix:
- Multiple cookies doesn't set
content-typetoapplication/json EXPOSEDis not export when usingfn.permission
Fix:
- Missing merged return type for
.ws
Fix:
- Missing nanoid
Fix:
- context side-effects
Improvement:
- Pre compile lowercase method for Eden
Improvement:
- ~33% faster for compiling type inference
- Reduce complex instruction for most Elysia types
- Change store type to
unknown
Fix:
t.Filesin swagger is referring to single file- Eden response type is unknown
Improvement:
- Compile
ElysiaRoutetype to literal - Optimize type compliation, type inference and auto-completion
- Improve type compilation speed by ~3x
Fix:
- Unable to type
setModelinference definition via Eden
Breaking Change:
- Depreacate
ElysiaRoute, changed to inline
Fix:
- Handle error thrown in non permission function
Feature:
- Elysia Fn
- Suport
multipart/form-data t.Fileandt.Filesfor file validationschema.contentfor specifying content type
Improvement:
- Improve TypeScript inference between plugin registration
- Optimize TypeScript inference size
- Context creation optimization
- Use Raikiri router by default
- Remove unused function
- Refactor
registerSchemaPathto support OpenAPI 3.0.3 - Add
errorinference for Eden - Mark
@sinclair/typeboxas optionalpeerDenpendencies
Fix:
- Exported variable has or is using name 'SCHEMA' from external module
- Exported variable has or is using name 'DEFS' from external module
- Possible errors for building Elysia app with
declaration: trueintsconfig.json
Breaking Change:
- Remove
derive - Update from OpenAPI 2.x to OpenAPI 3.0.3
- Move context.store[SYMBOL] to meta[SYMBOL]
Bug fix:
groupdoesn't inheritsonError
Bug fix:
groupdoesn't inheritsonError
Improvement:
- Remove
bind(this)
Feature:
- Add supports for multiple cookie
Improvement:
- Minor optimization
Improvement:
- Using SWC to bundle and minification
- Minor optimization
Improvement:
- Update Raikiri to 0.0.0-beta.4
Change:
- Remove strictPath option and enabled by default
Improvement:
- Migrate from @medley/router to Raikiri
- Minor optimization
Improvement:
- Map OpenAPI's schema detail on response
- Fix Type instantiation is excessively deep and possibly infinite
- Improve TypeScript inference time by removing recursive type in generic
- Inferred body is never instead of unknown
Feature:
- Add support for reference model via
.model - Add support for OpenAPI's
definitionsfield
Feature:
- Add support for custom openapi field using
schema.detail - Add support for custom code for
response
Improvement:
- Unioned status type for response
- Optimize TypeScript inference performance
Breaking Change:
onParsenow accepts(context: PreContext, contentType: string)instead of(request: Request, contentType: string)- To migrate, add
.requestto context to accessRequest
- To migrate, add
Feature:
onRequestandonParsenow can accessPreContext- Support
application/x-www-form-urlencodedby default
Improvement:
- body parser now parse
content-typewith extra attribute eg.application/json;charset=utf-8
Feature:
- Support for Async / lazy-load plugin
Improvement:
- Decode URI parameter path parameter
- Handle union type correctly
Improvement:
- Validate
Responseobject - Union type inference on response
Bug fix:
- onRequest doesn't run in
groupandguard
Improvement:
- Parse encoded URI on querystring
- Exclude URI fragment from querystring
- Blasphemy hack for updating Elysia server using
--hot - Exclude fragment on
getPath
[Reburn] is the first stable beta release for Elysia.
Happy Christmas, wishing you happy tonight as we release the first stable release of Elysia.
With this API is now stabilized, and Elysia will focus on growing its ecosystem and plugins for common patterns.
Introducing Eden, a fully type-safe client for Elysia server like tRPC.
A 600 bytes client for Elysia server, no code generation need, creating a fully type-safe, and auto-complete for both client and server.
See Eden in action on Twitter
With a lot effort put into micro-optimization and re-architecture, Elysia is the fastest Bun web framework benchmarked on 24 December 2022, outperformed 2/3 category put into test.
See benchmark results at Bun http benchmark
Elysia now have an improved documentation at elysiajs.com.
Now with a proper landing page, searchable content, and revised content put into.
Merry Christmas, and happy new year.
As 0.1 released, we recommended to give Elysia a try and build stuff with it.
With the wonderful tools, we are happy to looking forward to see what wonderful software will you build.
Fly away, let me fly away Never hide in dark Head on, start a riot Fly away, defying fate in my way Crush it Make it! Feel My Heart!
Change:
- Remove cjs format as Bun can import ESM from CJS
- Remove comment on build file, rely on .t.ds instead
Change:
- Support plugins which use
getPath, andmapQueryon 0.1.0-rc.6
Improvement:
- Infers type from
group, andguard
Change:
Elysia.handlenow only accept validURL
Improvement:
- Minor optimization
Router.registernow returns type- Inline default bodyParser
Fix:
.listenobject is now optional
Breaking Change:
onErrorchange its type:
// Previously
onError: (error: Error, code: ErrorCode)
// Now
onError: (params: {
error: Error
code: ErrorCode
set: Context['set']
}) => anyTo migrate, add curly brace to onError parameters.
onRequestchange its type:
// Previously
onRequest: (request: Request, store: Instance['Store']) => any
// Now
onRequest: (params: {
request: Request,
store: Instance['store']
set: Context['set']
})To migrate, add curly brace to onRequest parameters.
Feature:
- Manual patch for bun#1435, and unblock test suite for error handler.
Fix:
- Remove
console.logfor '*'
Feature:
- Strict type for
SCHEMA - Infered type parameters for
SCHEMA
Fix:
- Auto prefix path with
/for non - Fallback catch all route for registered parameter
Fix:
- skip body parsing for 'HEAD'
- missing response status on some error
- compatability for cjs
- add main fields for Bundlephobia supports
- add declaration file for both esm and cjs
- ship
srcfor TypeScript support withdeclare global
Stabilized API
Feature:
- add header access to context via
context.header
Breaking Change:
- rename
schema.headertoschema.headers
Bug fix:
injectnow acceptContext
Feature:
deriveto creating derive stateinjectto decorate method based on context
Feature:
.allfor registering path with any method
Improvement:
getSchemaValidatornow infer output type to be reusable with@kingworldjs/trpc
Bug fix:
handler.hooksis undefined on 404
Improvement:
- Decorators is now lazily allocate
.servenow accept numberic string as port for convenient withprocess.env
[Just Right Slow] introduce breaking major changes of KingWorld, specific on a plugin system.
Previously, we define plugin by accepting 2 parameters, KingWorld and Config like this:
const plugin = (app: KingWorld, config) => app
new KingWorld().use(plugin, {
// Provide some config here
})However, this has flaw by the design because:
- No support for async plugin
- No generic for type inference
- Not possible to accept 3...n parameters (if need)
- Hard/heavy work to get type inference
To fix all of the problem above, KingWorld now accept only one parameter.
A callback which return KingWorld Instance, but accept anything before that.
const plugin = (config) => (app: KingWorld) => app
new KingWorld().use(plugin({
// provide some config here
}))This is a workaround just like the way to register async plugin before exp.51, we accept any parameters in a function which return callback of a KingWorld instance.
This open a new possibility, plugin can now be async, generic type is now possible.
More over that, decorate can now accept any parameters as it doesn't really affect any performance or any real restriction.
Which means that something like this is now possible.
const a = <Name extends string = string>(name: Name) => (app: KingWorld) => app.decorate(name, {
hi: () => 'hi'
})
new KingWorld()
.use(a('customName'))
// Retrieve generic from plugin, not possible before exp.51
.get({ customName } => customName.hi())This lead to even more safe with type safety, as you can now use any generic as you would like.
The first plugin to leverage this feature is jwt which can introduce jwt function with custom namespace which is type safe.
Change:
- new
decoratorsproperty for assigning fastContext
Improvement:
- Faster router.find performance
- Faster query map performance
- Early return on not found
- Better type for
router
Change:
- Remove
storeFactoryfrom router
Bug fix:
- Conditionally return header in response
Bug fix:
- Import Context as non-default
- TypeScript's type not infering Context
Bug fix:
- Remove
export default Contextas it's a type - Import Context as non-default
Bug fix:
- Add custom response to
Blob
Bug fix:
- Set default HTTP status to 200 (oven-sh/bun#1523)
Improvement:
- Faster object iteration for setting headers
KingWorldconfig now acceptServeincludingSSL
Change:
- Use direct comparison for falsey value
Bug fix:
- Router doesn't handle part which start with the same letter
Change:
- Internal schema now use correct OpenAPI type (KingWorld need CORRECTION 💢💢)
Breaking Change:
Contextis nowinterface(non-constructable)responseHeaders,status,redirectis now replaced withset- To migrate:
// From app.get('/', ({ responseHeaders, status, redirect }) => { responseHeaders['server'] = 'KingWorld' status(401) redirect('/') }) // To app.get('/', ({ set }) => { set.headers['server'] = 'KingWorld' set.status = 401 set.redirect = '/' })
Improvement:
- Global
.schemanow infer type for handler - Add JSDocs for main method with example
.listennow acceptBun.Serveras a callback function- Response support for
FileBlob
Breaking Change:
methodis changed toroute
Improvement:
LocalHooknow prefers the nearest type instead of the merge- Merge the nearest schema first
- add
contentTypeas a second parameter forBodyParser
Bug fix:
- Correct type for
after handle - Fix infinite cycling infer type for
Handler
Bug fix:
- Correct type for
afterHandle
[Sage] is one of the major experimental releases and breaking changes of KingWorld.
The major improvement of Sage is that it provides almost (if not) full support for TypeScript and type inference.
KingWorld has a complex type of system. It's built with the DRY principle in mind, to reduce the developer's workload.
That's why KingWorld tries to type everything at its best, inferring type from your code into TypeScript's type.
For example, writing schema with nested guard is instructed with type and validation.
This ensures that your type will always be valid no matter what, and inferring type to your IDE automatically.

You can even type response to make your that you didn't leak any important data by forgetting to update the response when you're doing a migration.
KingWorld's validator now replaced zod, and ajv with @sinclair/typebox.
With the new validator, validation is now faster than the previous version by 188x if you're using zod, and 4.1x if you're using ajv adapter.
With Edge Computing in mind, refactoring to new validate dropped the unused packages and reduced size by 181.2KB. To give you an idea, KingWorld without a validator is around 10KB (non-gzipped).
Memory usage is also reduced by almost half by changing the validator.
According to M1 Max running example/simple.ts, running exp.36 uses 24MB of memory while exp.37 use 12MB of memory
This greatly improves the performance of KingWorld in a long run.
Breaking Change:
- Replace
zod,zod-to-json-schema,ajv, with@sinclair/typebox
Improvement:
usenow accept any nonKingWorld<{}, any>usenow combine typed between current instance and pluginusenow auto infer type if function is inlineLocalHookcan now inferparamstype from path string
Change:
TypedSchemais now replaced withInstance['schema']
Breaking Change:
AfterRequestHandlenow accept (Context,Response) instead of(Response, Context)
Improvement:
.guardnow combine global and local recursively.usenow inherits schema
Bug fix:
- Remove
console.logon failed validation
Improvement:
- Add Ajv 8.11.0
- Error log for validation is updated to
instancePath
Feature:
.schemafor global schema validation.start,.stopand acceptKingWorld<Instance>as first parameter
Improvement:
.guardnow auto infer type from schema toHandler- scoped
.guardnow inherits hook NewInstancenow inheritsInheritSchema
Bug fix:
- Rename
afterHandletoonAfterHandleto match naming convention - Make
afterHandleinRegisterHookoptional - Internal type conversion between
Hook,LocalHook
Feature:
- add
afterHandlehook
Improvement:
- Using
WithArray<T>to reduce redundant type
Bug fix:
beforeHandlehook doesn't accept array
Bug fix:
- Add
zodby default
Bug fix:
- Add
zod-to-json-schemaby default
[Regulus]
This version introduces rework for internal architecture. Refine, and unify the structure of how KingWorld works internally.
Although many refactoring might require, I can assure you that this is for the greater good, as the API refinement lay down a solid structure for the future of KingWorld.
Thanks to API refinement, this version also introduced a lot of new interesting features, and many APIs simplified.
Notable improvements and new features:
- Define Schema, auto-infer type, and validation
- Simplifying Handler's generic
- Unifying Life Cycle into one property
- Custom Error handler, and body-parser
- Before start/stop and clean up effect
Happy halloween.
This version named [GHOST FOOD] is one of the big improvement for KingWorld, I have been working on lately. It has a lot of feature change for better performance, and introduce lots of deprecation.
Be sure to follow the migration section in Breaking Change.
Feature:
- Auto infer type from
pluginafter merging withuse decorateto extendsContextmethod- add
addParser, for custom handler for parsing body
Breaking Change:
-
Moved
storeintocontext.store- To migrate:
// From app.get(({}, store) => store.a) // To app.get(({ store }) => store.a)
-
ref, andrefFnis now removed -
Remove
Plugintype, simplified Plugin type declaration- To migrate:
// From import type { Plugin } from 'kingworld' const a: Plugin = (app) => app // To import type { KingWorld } from 'kingworld' const a = (app: KingWorld) => app
-
Migrate
HeadertoRecord<string, unknown>- To migrate:
app.get("/", ({ responseHeader }) => { // From responseHeader.append('X-Powered-By', 'KingWorld') // To responseHeader['X-Powered-By', 'KingWorld'] return "KingWorld" })
Change:
- Store is now globally mutable
Improvement:
- Faster header initialization
- Faster hook initialization
Feature:
- Add
config.strictPathfor handling strict path
Improvement:
- Improve
cloneperformance - Inline
refvalue - Using object to store internal route
Bug fix:
- 404 on absolute path
Feature:
- Auto infer typed for
params,state,ref onRequestnow accept async functionrefFnsyntax sugar for adding fn as reference instead of() => () => value
Improvement:
- Switch from
@saltyaom/trek-routerto@medley/router - Using
cloneinstead of flatten object - Refactor path fn for inline cache
- Refactor
Contextto class
Bug fix:
.ref()throw error when accept function
Change:
- optimized for
await
Feature:
- Initialial config is now available, starting with
bodyLimitconfig for limiting body size
Breaking Change:
ctx.bodyis now a literal value instead ofPromise- To migrate, simply remove
await
- To migrate, simply remove
Change:
defaultnow acceptHandlerinstead ofEmptyHandler
Bug fix:
- Default Error response now return
responseHeaders - Possibly fixed parsing body error benchmark
Breaking Change:
- context.body is now deprecated, use request.text() or request.json() instead
Improvement:
- Using reference header to increase json response speed
- Remove
bodygetter, setter
Change:
- Using
instanceofto early returnResponse
Breaking Change:
context.headersnow returnHeaderinstead ofRecord<string, string>
Feature:
- Add status function to
Context handlenow acceptnumber | Serve- Remove
querystringto support native Cloudflare Worker - Using raw headers check to parse
bodytype
Feature:
- Handle error as response
Change:
- Use Array Spread instead of concat as it's faster by 475%
- Update to @saltyaom/trek-router 0.0.7 as it's faster by 10%
- Use array.length instead of array[0] as it's faster by 4%
Change:
- With lazy initialization, KingWorld is faster by 15% (tested on 14' M1 Max)
- Micro optimization
- Remove
setfrom headers
Change:
- Remove dependencies:
fluent-json-schema,fluent-schema-validator - Update
@saltyaom/trek-routerto0.0.2
Breaking Change:
- Move
hook.schemato separate plugin, @kingworldjs/schema- To migrate, simply move all
hook.schematopreHandlerinstead
- To migrate, simply move all
Change:
- Rename type
ParsedRequesttoContext - Exposed
#addHandlerto_addHandler
Breaking Change:
- Rename
context.responseHeadertocontext.responseHeaders - Change type of
responseHeaderstoHeaderinstead ofRecord<string, string>