elysia 2.0.0-beta.31 → 2.0.0-beta.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/base.d.ts +18 -18
  2. package/dist/base.js +2 -2
  3. package/dist/base.mjs +2 -2
  4. package/dist/compile/aot-capture.js +1 -1
  5. package/dist/compile/aot-capture.mjs +1 -1
  6. package/dist/compile/aot.d.ts +4 -5
  7. package/dist/compile/aot.js +11 -12
  8. package/dist/compile/aot.mjs +11 -12
  9. package/dist/compile/handler/jit.js +6 -4
  10. package/dist/compile/handler/jit.mjs +6 -4
  11. package/dist/compile/handler/utils.d.ts +1 -1
  12. package/dist/compile/handler/utils.js +2 -2
  13. package/dist/compile/handler/utils.mjs +2 -2
  14. package/dist/error.d.ts +55 -50
  15. package/dist/handler/error.d.ts +7 -8
  16. package/dist/handler/error.js +26 -10
  17. package/dist/handler/error.mjs +27 -12
  18. package/dist/plugin/aot/core.d.ts +15 -3
  19. package/dist/plugin/aot/core.js +147 -83
  20. package/dist/plugin/aot/core.mjs +148 -85
  21. package/dist/plugin/aot/source.d.ts +6 -1
  22. package/dist/plugin/aot/source.js +32 -10
  23. package/dist/plugin/aot/source.mjs +32 -12
  24. package/dist/type/bridge-live.d.ts +1 -1
  25. package/dist/type/bridge-live.js +1 -1
  26. package/dist/type/bridge-live.mjs +1 -1
  27. package/dist/type/bridge.d.ts +1 -1
  28. package/dist/type/coerce.d.ts +1 -1
  29. package/dist/type/constants.d.ts +1 -1
  30. package/dist/type/typebox-value-live.d.ts +2 -2
  31. package/dist/type/typebox-value-live.js +2 -2
  32. package/dist/type/typebox-value-live.mjs +2 -2
  33. package/dist/type/typebox-value-ops.d.ts +2 -2
  34. package/dist/type/typebox-value-ops.js +2 -2
  35. package/dist/type/typebox-value-ops.mjs +2 -2
  36. package/dist/type/typebox-value.d.ts +6 -6
  37. package/dist/types.d.ts +70 -64
  38. package/dist/ws/route.js +6 -4
  39. package/dist/ws/route.mjs +7 -5
  40. package/package.json +1 -1
package/dist/base.d.ts CHANGED
@@ -266,15 +266,15 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
266
266
  as: As;
267
267
  }, fn: MaybeArray<TransformHandler<MergeSchema<{}, {}, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, LegacyScope<As>>>): this;
268
268
  onTransform<const HookScope extends EventScope>(scope: HookScope, fn: MaybeArray<TransformHandler<MergeSchema<{}, {}, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, HookScope>>): this;
269
- onBeforeHandle<const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>>>(fn: Handler): LocalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler, true>>;
270
- onBeforeHandle<const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>>>(scope: 'local', fn: Handler): LocalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler, true>>;
271
- onBeforeHandle<const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, 'plugin'>>>(scope: 'plugin', fn: Handler): PluginHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler, true>>;
272
- onBeforeHandle<const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, 'global'>>>(scope: 'global', fn: Handler): GlobalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler, true>>;
269
+ onBeforeHandle<const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>>>(fn: Handler): LocalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler>>;
270
+ onBeforeHandle<const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>>>(scope: 'local', fn: Handler): LocalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler>>;
271
+ onBeforeHandle<const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, 'plugin'>>>(scope: 'plugin', fn: Handler): PluginHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler>>;
272
+ onBeforeHandle<const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, 'global'>>>(scope: 'global', fn: Handler): GlobalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler>>;
273
273
  /** @deprecated 1.x syntax, use `.onBeforeHandle('plugin', fn)`, `'scoped'` is now `'plugin'` */
274
274
  onBeforeHandle<const As extends 'local' | 'scoped' | 'global', const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, LegacyScope<As>>>>(options: {
275
275
  as: As;
276
- }, fn: Handler): ScopedHookReturn<LegacyScope<As>, BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler, true>>;
277
- onBeforeHandle<const HookScope extends EventScope, const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, HookScope>>>(scope: HookScope, fn: Handler): ScopedHookReturn<HookScope, BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler, true>>;
276
+ }, fn: Handler): ScopedHookReturn<LegacyScope<As>, BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler>>;
277
+ onBeforeHandle<const HookScope extends EventScope, const Handler extends MaybeArray<OptionalHandler<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, HookScope>>>(scope: HookScope, fn: Handler): ScopedHookReturn<HookScope, BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, ElysiaHandlerToResponseSchemaAmbiguous<Handler>>;
278
278
  derive<const Derivative extends Record<string, unknown> | ElysiaStatus<any, any, any> | Error | void>(transform: (context: Context<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>) => MaybePromise<Derivative>): LocalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, DeriveResponse<Derivative>, ExcludeElysiaResponse<Derivative>>;
279
279
  derive<const Derivative extends Record<string, unknown> | ElysiaStatus<any, any, any> | Error | void>(scope: 'local', transform: (context: Context<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>>) => MaybePromise<Derivative>): LocalHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, DeriveResponse<Derivative>, ExcludeElysiaResponse<Derivative>>;
280
280
  derive<const Derivative extends Record<string, unknown> | ElysiaStatus<any, any, any> | Error | void>(scope: 'plugin', transform: (context: LifecycleContext<HookContextSchema<Metadata, Ephemeral, Volatile, BasePath>, HookContextSingleton<Singleton, Ephemeral, Volatile>, undefined, 'plugin'>) => MaybePromise<Derivative>): PluginHookReturn<BasePath, Scope, Singleton, Definitions, Metadata, Routes, Ephemeral, Volatile, DeriveResponse<Derivative>, ExcludeElysiaResponse<Derivative>>;
@@ -475,7 +475,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
475
475
  derive: Volatile['derive'] & MacroContext['derive'];
476
476
  schema: Volatile['schema'];
477
477
  schemas: Volatile['schemas'] & UnwrapRoute<Input, Definitions['typebox']> & MacroContext;
478
- response: UnionResponseStatus<UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
478
+ response: UnionResponseStatus<UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
479
479
  error: [...Volatile['error'], ...CatchAllEntries<ErrorHandle>, ...MacroCatchAll<MacroContext['return' & keyof MacroContext]>];
480
480
  }>;
481
481
  guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Input, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>>(hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle, 'override'> & MacroOptionContext<Metadata['macroFn'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, {
@@ -484,7 +484,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
484
484
  derive: Volatile['derive'] & MacroContext['derive'];
485
485
  schema: {} extends Pick<Input, Extract<keyof Input, InputSchemaKey>> ? Volatile['schema'] : MergeSchema<UnwrapRoute<Input, Definitions['typebox']>, Volatile['schema']>;
486
486
  schemas: Volatile['schemas'] & MacroContext;
487
- response: UnionResponseStatus<UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
487
+ response: UnionResponseStatus<UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
488
488
  error: [...Volatile['error'], ...CatchAllEntries<ErrorHandle>, ...MacroCatchAll<MacroContext['return' & keyof MacroContext]>];
489
489
  }>;
490
490
  guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Input, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const NewElysia extends AnyElysia>(hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle, 'merge'> & {
@@ -501,7 +501,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
501
501
  macro: Metadata['macro'];
502
502
  macroFn: Metadata['macroFn'];
503
503
  parser: Metadata['parser'];
504
- response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
504
+ response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
505
505
  }, {}, Ephemeral, Volatile>) => NewElysia): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes & NewElysia['~Routes'], Ephemeral, Volatile>;
506
506
  guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Input, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const NewElysia extends AnyElysia>(hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle, 'override'> & MacroOptionContext<Metadata['macroFn'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, {
507
507
  derive: {};
@@ -515,7 +515,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
515
515
  macro: Metadata['macro'];
516
516
  macroFn: Metadata['macroFn'];
517
517
  parser: Metadata['parser'];
518
- response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
518
+ response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
519
519
  }, {}, {
520
520
  derive: Ephemeral['derive'];
521
521
  schema: {};
@@ -537,7 +537,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
537
537
  derive: Volatile['derive'] & MacroContext['derive'];
538
538
  schema: Volatile['schema'];
539
539
  schemas: Volatile['schemas'] & UnwrapRoute<Input, Definitions['typebox']> & MacroContext;
540
- response: UnionResponseStatus<UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
540
+ response: UnionResponseStatus<UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
541
541
  error: [...Volatile['error'], ...CatchAllEntries<ErrorHandle>, ...MacroCatchAll<MacroContext['return' & keyof MacroContext]>];
542
542
  }>;
543
543
  guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Input, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>>(scope: 'local', hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle, 'override'> & MacroOptionContext<Metadata['macroFn'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, {
@@ -546,7 +546,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
546
546
  derive: Volatile['derive'] & MacroContext['derive'];
547
547
  schema: {} extends Pick<Input, Extract<keyof Input, InputSchemaKey>> ? Volatile['schema'] : MergeSchema<UnwrapRoute<Input, Definitions['typebox']>, Volatile['schema']>;
548
548
  schemas: Volatile['schemas'] & MacroContext;
549
- response: UnionResponseStatus<UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
549
+ response: UnionResponseStatus<UnionResponseStatus<Volatile['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
550
550
  error: [...Volatile['error'], ...CatchAllEntries<ErrorHandle>, ...MacroCatchAll<MacroContext['return' & keyof MacroContext]>];
551
551
  }>;
552
552
  guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Input, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>>(scope: 'plugin', hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle, 'merge'> & {
@@ -557,7 +557,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
557
557
  derive: Ephemeral['derive'] & MacroContext['derive'];
558
558
  schema: Ephemeral['schema'];
559
559
  schemas: Ephemeral['schemas'] & UnwrapRoute<Input, Definitions['typebox']> & MacroContext;
560
- response: UnionResponseStatus<UnionResponseStatus<Ephemeral['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
560
+ response: UnionResponseStatus<UnionResponseStatus<Ephemeral['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
561
561
  error: [...Ephemeral['error'], ...CatchAllEntries<ErrorHandle>, ...MacroCatchAll<MacroContext['return' & keyof MacroContext]>];
562
562
  }, Volatile>;
563
563
  guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Input, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>>(scope: 'plugin', hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle, 'override'> & MacroOptionContext<Metadata['macroFn'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, {
@@ -566,7 +566,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
566
566
  derive: Ephemeral['derive'] & MacroContext['derive'];
567
567
  schema: {} extends Pick<Input, Extract<keyof Input, InputSchemaKey>> ? Ephemeral['schema'] : MergeSchema<UnwrapRoute<Input, Definitions['typebox']>, Ephemeral['schema']>;
568
568
  schemas: Ephemeral['schemas'] & MacroContext;
569
- response: UnionResponseStatus<UnionResponseStatus<Ephemeral['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
569
+ response: UnionResponseStatus<UnionResponseStatus<Ephemeral['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
570
570
  error: [...Ephemeral['error'], ...CatchAllEntries<ErrorHandle>, ...MacroCatchAll<MacroContext['return' & keyof MacroContext]>];
571
571
  }, Volatile>;
572
572
  guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Input, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>>(scope: 'global', hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle, 'merge'> & {
@@ -583,7 +583,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
583
583
  macro: Metadata['macro'];
584
584
  macroFn: Metadata['macroFn'];
585
585
  parser: Metadata['parser'];
586
- response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
586
+ response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
587
587
  }, Routes, Ephemeral, Volatile>;
588
588
  guard<const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], BasePath>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Input, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>>(scope: 'global', hook: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle, 'override'> & MacroOptionContext<Metadata['macroFn'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, {
589
589
  derive: {};
@@ -597,7 +597,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
597
597
  macro: Metadata['macro'];
598
598
  macroFn: Metadata['macroFn'];
599
599
  parser: Metadata['parser'];
600
- response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
600
+ response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
601
601
  }, Routes, Ephemeral, Volatile>;
602
602
  group<const Prefix extends string, const NewElysia extends AnyElysia>(prefix: Prefix, run: (group: Elysia<Prefix extends '' ? BasePath : JoinPath<BasePath, Prefix>, Scope, Singleton, Definitions, {
603
603
  schema: MergeSchema<UnwrapRoute<{}, Definitions['typebox']>, Metadata['schema']>;
@@ -621,7 +621,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
621
621
  macro: Metadata['macro'];
622
622
  macroFn: Metadata['macroFn'];
623
623
  parser: Metadata['parser'];
624
- response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
624
+ response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
625
625
  }, {}, Ephemeral, Volatile>) => NewElysia): Elysia<BasePath, Scope, Singleton, Definitions, Metadata, Routes & NewElysia['~Routes'], Ephemeral, Volatile>;
626
626
  group<const Prefix extends string, const Input extends Metadata['macro'] & InputSchema<keyof Definitions['typebox'] & string>, const Schema extends MergeSchema<UnwrapRoute<Input, Definitions['typebox'], JoinPath<BasePath, Prefix>>, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>> & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], const MacroContext extends ({} extends Metadata['macroFn'] ? {} : MacroToContext<Metadata['macroFn'], Input, Definitions['typebox']>), const BeforeHandle extends MaybeArray<OptionalHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const AfterHandle extends MaybeArray<AfterHandler<Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const ErrorHandle extends MaybeArray<ErrorHandler<Definitions['error'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>>>, const NewElysia extends AnyElysia>(prefix: Prefix, schema: GuardLocalHook<Input, Schema & MacroContext, GuardHookSingleton<Singleton, Ephemeral, Volatile, MacroContext>, keyof Metadata['parser'], BeforeHandle, AfterHandle, ErrorHandle, 'override'> & MacroOptionContext<Metadata['macroFn'], Schema, GuardHookSingleton<Singleton, Ephemeral, Volatile, {
627
627
  derive: {};
@@ -635,7 +635,7 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
635
635
  macro: Metadata['macro'];
636
636
  macroFn: Metadata['macroFn'];
637
637
  parser: Metadata['parser'];
638
- response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle, true>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
638
+ response: UnionResponseStatus<UnionResponseStatus<Metadata['response'], ElysiaHandlerToResponseSchemaAmbiguous<BeforeHandle>>, UnionResponseStatus<ElysiaHandlerToResponseSchemaAmbiguous<AfterHandle>, UnionResponseStatus<ErrorHookStatus<ErrorHandle>, WithoutMacroCatch<MacroContext['return' & keyof MacroContext]> & {}>>>;
639
639
  }, {}, {
640
640
  derive: Ephemeral['derive'];
641
641
  schema: {};
package/dist/base.js CHANGED
@@ -970,7 +970,7 @@ var Elysia = class Elysia {
970
970
  this.fetchFn = void 0;
971
971
  this.#routerBuilt = false;
972
972
  require_context.clearContextCache(this);
973
- try {
973
+ if (this["~map"]) try {
974
974
  this.#buildRouter(false);
975
975
  } catch (error) {
976
976
  this.compiled = previousCompiled;
@@ -1499,7 +1499,7 @@ var Elysia = class Elysia {
1499
1499
  let eager = false;
1500
1500
  if (length) {
1501
1501
  const programId = this["~programId"];
1502
- if (!require_compile_aot.Compiled.claim(programId, this["~aotFingerprint"] = require_compile_aot.createAotFingerprint())) require_compile_aot.Compiled.assertUncontested(programId);
1502
+ require_compile_aot.Compiled.claim(programId, this["~aotFingerprint"] = require_compile_aot.createAotFingerprint(), this["~config"]?.name || "");
1503
1503
  markDuplicates = require_compile_aot.Compiled.hasProgram(programId) || precompile !== true && require_universal_is_production.isProduction() && !require_compile_aot.Capture.isAotBuildEnv();
1504
1504
  if (hasTypeBoxSchema) try {
1505
1505
  require_type_bridge.warmTypebox();
package/dist/base.mjs CHANGED
@@ -968,7 +968,7 @@ var Elysia = class Elysia {
968
968
  this.fetchFn = void 0;
969
969
  this.#routerBuilt = false;
970
970
  clearContextCache(this);
971
- try {
971
+ if (this["~map"]) try {
972
972
  this.#buildRouter(false);
973
973
  } catch (error) {
974
974
  this.compiled = previousCompiled;
@@ -1497,7 +1497,7 @@ var Elysia = class Elysia {
1497
1497
  let eager = false;
1498
1498
  if (length) {
1499
1499
  const programId = this["~programId"];
1500
- if (!Compiled.claim(programId, this["~aotFingerprint"] = createAotFingerprint())) Compiled.assertUncontested(programId);
1500
+ Compiled.claim(programId, this["~aotFingerprint"] = createAotFingerprint(), this["~config"]?.name || "");
1501
1501
  markDuplicates = Compiled.hasProgram(programId) || precompile !== true && isProduction() && !Capture.isAotBuildEnv();
1502
1502
  if (hasTypeBoxSchema) try {
1503
1503
  warmTypebox();
@@ -13,8 +13,8 @@ const require_type_validator_frozen_check = require('../type/validator/frozen-ch
13
13
  const require_type_validator_custom_error = require('../type/validator/custom-error.js');
14
14
  const require_type_validator_exact_mirror = require('../type/validator/exact-mirror.js');
15
15
  const require_type_validator_string_codec_aot = require('../type/validator/string-codec-aot.js');
16
- let typebox_value = require("typebox/value");
17
16
  let typebox_schema = require("typebox/schema");
17
+ let typebox_value = require("typebox/value");
18
18
 
19
19
  //#region src/compile/aot-capture.ts
20
20
  function emptyContainers(node, depth) {
@@ -12,8 +12,8 @@ import { buildFrozenCheck } from "../type/validator/frozen-check.mjs";
12
12
  import { captureCustomErrors } from "../type/validator/custom-error.mjs";
13
13
  import { getExactMirror } from "../type/validator/exact-mirror.mjs";
14
14
  import { captureStringCodecEntries, compileWithBuild } from "../type/validator/string-codec-aot.mjs";
15
- import { Default } from "typebox/value";
16
15
  import { Build, Compile } from "typebox/schema";
16
+ import { Default } from "typebox/value";
17
17
 
18
18
  //#region src/compile/aot-capture.ts
19
19
  function emptyContainers(node, depth) {
@@ -89,8 +89,8 @@ interface HandlerManifest {
89
89
  };
90
90
  }
91
91
  interface CompiledSnapshot {
92
- registered: CompiledProgramRegistration | undefined;
93
- claimed: WeakRef<ProgramId> | undefined;
92
+ registered: Record<string, CompiledProgramRegistration | undefined> | undefined;
93
+ claimed: Record<string, WeakRef<ProgramId> | undefined> | undefined;
94
94
  programs: WeakMap<ProgramId, CompiledProgram>;
95
95
  }
96
96
  interface CompiledProgramRegistration {
@@ -129,9 +129,8 @@ declare function reconstruct(): ReconstructImpl;
129
129
  declare const aotDriftMessage: (method: string, path: string) => string;
130
130
  declare function warnAotDrift(method: string, path: string): void;
131
131
  declare abstract class Compiled {
132
- static register(manifest: CompiledProgramRegistration): void;
133
- static claim(id: ProgramId, fingerprint: AotFingerprint): boolean;
134
- static assertUncontested(id: ProgramId): void;
132
+ static register(manifest: CompiledProgramRegistration, key?: string): void;
133
+ static claim(id: ProgramId, fingerprint: AotFingerprint, key?: string): boolean;
135
134
  static set reconstruct(impl: ReconstructImpl | undefined);
136
135
  static getHandler(id: ProgramId | undefined, method: string, path: string): FrozenHandler | undefined;
137
136
  static hasProgram(id: ProgramId | undefined): boolean;
@@ -51,26 +51,25 @@ let claimed;
51
51
  let programs = /* @__PURE__ */ new WeakMap();
52
52
  const programFor = (id) => id ? programs.get(id) : void 0;
53
53
  var Compiled = class {
54
- static register(manifest) {
55
- registered = manifest;
56
- claimed = void 0;
54
+ static register(manifest, key = "") {
55
+ (registered ??= require_utils.nullObject())[key] = manifest;
56
+ claimed ??= require_utils.nullObject();
57
57
  }
58
- static claim(id, fingerprint) {
59
- if (!registered || claimed) return false;
60
- const manifest = registered;
58
+ static claim(id, fingerprint, key = "") {
59
+ const manifest = registered?.[key];
60
+ if (!manifest) {
61
+ if (claimed && claimed[key]?.deref() !== id && !isAotBuildEnv()) throw new Error(`[elysia-aot] App "${key}" has no AOT manifest. Name and export it, .mount() ones too`);
62
+ return false;
63
+ }
61
64
  if (manifest.fingerprint.abi !== fingerprint.abi) throw new Error(`[elysia-aot] Mismatch fingerprint`);
62
- claimed = new WeakRef(id);
63
- registered = void 0;
65
+ claimed[key] = new WeakRef(id);
66
+ registered[key] = void 0;
64
67
  programs.set(id, {
65
68
  ...manifest,
66
69
  builtGroups: /* @__PURE__ */ new Set()
67
70
  });
68
71
  return true;
69
72
  }
70
- static assertUncontested(id) {
71
- if (claimed === void 0 || claimed.deref() === id || isAotBuildEnv()) return;
72
- throw new Error("[elysia-aot] A second Elysia app built a router in this process. An AOT build seals one app per process.");
73
- }
74
73
  static set reconstruct(impl) {
75
74
  reconstructImpl = impl;
76
75
  }
@@ -51,26 +51,25 @@ let claimed;
51
51
  let programs = /* @__PURE__ */ new WeakMap();
52
52
  const programFor = (id) => id ? programs.get(id) : void 0;
53
53
  var Compiled = class {
54
- static register(manifest) {
55
- registered = manifest;
56
- claimed = void 0;
54
+ static register(manifest, key = "") {
55
+ (registered ??= nullObject())[key] = manifest;
56
+ claimed ??= nullObject();
57
57
  }
58
- static claim(id, fingerprint) {
59
- if (!registered || claimed) return false;
60
- const manifest = registered;
58
+ static claim(id, fingerprint, key = "") {
59
+ const manifest = registered?.[key];
60
+ if (!manifest) {
61
+ if (claimed && claimed[key]?.deref() !== id && !isAotBuildEnv()) throw new Error(`[elysia-aot] App "${key}" has no AOT manifest. Name and export it, .mount() ones too`);
62
+ return false;
63
+ }
61
64
  if (manifest.fingerprint.abi !== fingerprint.abi) throw new Error(`[elysia-aot] Mismatch fingerprint`);
62
- claimed = new WeakRef(id);
63
- registered = void 0;
65
+ claimed[key] = new WeakRef(id);
66
+ registered[key] = void 0;
64
67
  programs.set(id, {
65
68
  ...manifest,
66
69
  builtGroups: /* @__PURE__ */ new Set()
67
70
  });
68
71
  return true;
69
72
  }
70
- static assertUncontested(id) {
71
- if (claimed === void 0 || claimed.deref() === id || isAotBuildEnv()) return;
72
- throw new Error("[elysia-aot] A second Elysia app built a router in this process. An AOT build seals one app per process.");
73
- }
74
73
  static set reconstruct(impl) {
75
74
  reconstructImpl = impl;
76
75
  }
@@ -463,7 +463,7 @@ function compileHandlerJit(options, tailPass) {
463
463
  code += require_compile_handler_utils.mapChainHook(hook.afterHandle, "af", asyncMode, buildReport("afterHandle"), abortChainGuard(), arm);
464
464
  }
465
465
  code += endTrace("afterHandle");
466
- if (hasAfterHandle) code += abortCheck();
466
+ if (hasAfterHandle) code += abortCheck() + plain(rethrow("_r"));
467
467
  }
468
468
  if (hasMapResponse || hasTrace) {
469
469
  const mrLen = hook?.mapResponse?.length ?? 0;
@@ -531,15 +531,17 @@ function compileHandlerJit(options, tailPass) {
531
531
  asyncMode.r = false;
532
532
  asyncMode.e = true;
533
533
  }
534
+ const declined = endTrace("error") + (hasDeriveDispose ? schedule + abortCatch : abortCatch + schedule);
534
535
  body += errorHead + `let _r${hasMapResponse ? ",tmp" : ""}\n` + require_compile_handler_utils.mapError(hook.error, [
535
536
  map,
536
537
  link,
537
538
  responseMap,
538
- (hasMapResponse ? `c.responseValue=_r\n` + require_compile_handler_utils.mapChainHook(hook.mapResponse, "mr", asyncMode, void 0, abortChainGuard(), arm) : "") + endTrace("error") + (hasDeriveDispose ? schedule + abortCatch : abortCatch + schedule),
539
+ (hasMapResponse ? `c.responseValue=_r\n` + require_compile_handler_utils.mapChainHook(hook.mapResponse, "mr", asyncMode, void 0, abortChainGuard(), arm) : "") + declined,
539
540
  signPrefix,
540
541
  asyncMode,
541
- arm
542
- ], abortChainGuard(), require_compile_handler_utils.asyncTail(asyncMode)) + endTrace("error") + (hasDeriveDispose ? schedule + abortCatch : abortCatch + schedule) + `return _efb(e,c)\n`;
542
+ arm,
543
+ declined
544
+ ], abortChainGuard(), require_compile_handler_utils.asyncTail(asyncMode)) + declined + `return _efb(e,c)\n`;
543
545
  } else body += endTrace("error") + freThenSchedule("e");
544
546
  const hookThrew = `catch(_ee){${freThenSchedule("_ee").trimEnd()}}}\n`;
545
547
  const syncFirst = typeof asyncMode === "object" && !asyncMode.async;
@@ -463,7 +463,7 @@ function compileHandlerJit(options, tailPass) {
463
463
  code += mapChainHook(hook.afterHandle, "af", asyncMode, buildReport("afterHandle"), abortChainGuard(), arm);
464
464
  }
465
465
  code += endTrace("afterHandle");
466
- if (hasAfterHandle) code += abortCheck();
466
+ if (hasAfterHandle) code += abortCheck() + plain(rethrow("_r"));
467
467
  }
468
468
  if (hasMapResponse || hasTrace) {
469
469
  const mrLen = hook?.mapResponse?.length ?? 0;
@@ -531,15 +531,17 @@ function compileHandlerJit(options, tailPass) {
531
531
  asyncMode.r = false;
532
532
  asyncMode.e = true;
533
533
  }
534
+ const declined = endTrace("error") + (hasDeriveDispose ? schedule + abortCatch : abortCatch + schedule);
534
535
  body += errorHead + `let _r${hasMapResponse ? ",tmp" : ""}\n` + mapError(hook.error, [
535
536
  map,
536
537
  link,
537
538
  responseMap,
538
- (hasMapResponse ? `c.responseValue=_r\n` + mapChainHook(hook.mapResponse, "mr", asyncMode, void 0, abortChainGuard(), arm) : "") + endTrace("error") + (hasDeriveDispose ? schedule + abortCatch : abortCatch + schedule),
539
+ (hasMapResponse ? `c.responseValue=_r\n` + mapChainHook(hook.mapResponse, "mr", asyncMode, void 0, abortChainGuard(), arm) : "") + declined,
539
540
  signPrefix,
540
541
  asyncMode,
541
- arm
542
- ], abortChainGuard(), asyncTail(asyncMode)) + endTrace("error") + (hasDeriveDispose ? schedule + abortCatch : abortCatch + schedule) + `return _efb(e,c)\n`;
542
+ arm,
543
+ declined
544
+ ], abortChainGuard(), asyncTail(asyncMode)) + declined + `return _efb(e,c)\n`;
543
545
  } else body += endTrace("error") + freThenSchedule("e");
544
546
  const hookThrew = `catch(_ee){${freThenSchedule("_ee").trimEnd()}}}\n`;
545
547
  const syncFirst = typeof asyncMode === "object" && !asyncMode.async;
@@ -39,7 +39,7 @@ declare function runBeforeHandlePrefix(prefix: CompactBeforeHandlePrefix, contex
39
39
  declare function runBeforeHandlePrefixAsync(prefix: CompactBeforeHandlePrefix, context: BeforeHandleContext, abort?: 1): Promise<any>;
40
40
  declare function mapChainHook(_hooks: Function | Function[], prefix: string, mode: AsyncMode, report?: TraceReporter, abortGuard?: string, arm?: string): string;
41
41
  declare const mapAfterResponse: (event: MaybeArray<AfterResponseHandler<any, any, undefined, "local">>, rest?: [report?: TraceReporter | undefined] | undefined, abortGuard?: string, tail?: TailMode) => string;
42
- declare const mapError: (event: MaybeArray<ErrorHandler<any, any, any>>, rest?: [map: string, link: Link, mapResponse: (response: unknown, set: Context["set"], ...params: unknown[]) => unknown, schedule: string, sign: string, mode: AsyncMode, arm?: string | undefined] | undefined, abortGuard?: string, tail?: TailMode) => string;
42
+ declare const mapError: (event: MaybeArray<ErrorHandler<any, any, any>>, rest?: [map: string, link: Link, mapResponse: (response: unknown, set: Context["set"], ...params: unknown[]) => unknown, schedule: string, sign: string, mode: AsyncMode, arm: string | undefined, declined: string] | undefined, abortGuard?: string, tail?: TailMode) => string;
43
43
  interface QueryWalkState {
44
44
  array: Record<string, 1> | undefined;
45
45
  object: Record<string, 1> | undefined;
@@ -297,11 +297,11 @@ const mapAfterResponse = /* @__PURE__ */ map((i, fn, [report]) => {
297
297
  const call = require_compile_utils.isAsyncFunction(fn) ? `await ar${at(i)}(c)\n` : `let _ar=ar${at(i)}(c)\nif(typeof _ar?.then==='function')await _ar\n`;
298
298
  return `try{${t.begin}${call}${t.end()}}catch(_e){${t.end("_e")}console.error(_e)}\n`;
299
299
  });
300
- const mapError = /* @__PURE__ */ map((i, fn, [map, link, mapResponse, schedule, sign, mode, arm]) => {
300
+ const mapError = /* @__PURE__ */ map((i, fn, [map, link, mapResponse, schedule, sign, mode, arm, declined]) => {
301
301
  link(mapResponse, "rm");
302
302
  link(require_handler_error.adoptErrorType, "aet");
303
303
  link(require_error.ElysiaStatus, "es");
304
- return awaitSite(`er${at(i)}(c)`, fn, mode, "_r", arm) + "if(_r!==undefined){\nif(_r instanceof es||_r instanceof Response)c.set.status=_r.status\nelse if(c.set.status===undefined||c.set.status===200)c.set.status=500\n" + schedule + sign + `return _em(c,${map}(aet(_r,e),c.set,c.request,true))\n}\n`;
304
+ return awaitSite(`er${at(i)}(c)`, fn, mode, "_r", arm) + `if(_r!==undefined){\nif(_r instanceof Error){c.set.status=_r.status||500\n${declined}return _efb(_r,c)}\nif(_r instanceof es||_r instanceof Response)c.set.status=_r.status\nelse if(c.set.status===undefined||c.set.status===200)c.set.status=500\n` + schedule + sign + `return _em(c,${map}(aet(_r,e),c.set,c.request,true))\n}\n`;
305
305
  });
306
306
  function map(map) {
307
307
  return function(event, rest, abortGuard, tail) {
@@ -297,11 +297,11 @@ const mapAfterResponse = /* @__PURE__ */ map((i, fn, [report]) => {
297
297
  const call = isAsyncFunction(fn) ? `await ar${at(i)}(c)\n` : `let _ar=ar${at(i)}(c)\nif(typeof _ar?.then==='function')await _ar\n`;
298
298
  return `try{${t.begin}${call}${t.end()}}catch(_e){${t.end("_e")}console.error(_e)}\n`;
299
299
  });
300
- const mapError = /* @__PURE__ */ map((i, fn, [map, link, mapResponse, schedule, sign, mode, arm]) => {
300
+ const mapError = /* @__PURE__ */ map((i, fn, [map, link, mapResponse, schedule, sign, mode, arm, declined]) => {
301
301
  link(mapResponse, "rm");
302
302
  link(adoptErrorType, "aet");
303
303
  link(ElysiaStatus, "es");
304
- return awaitSite(`er${at(i)}(c)`, fn, mode, "_r", arm) + "if(_r!==undefined){\nif(_r instanceof es||_r instanceof Response)c.set.status=_r.status\nelse if(c.set.status===undefined||c.set.status===200)c.set.status=500\n" + schedule + sign + `return _em(c,${map}(aet(_r,e),c.set,c.request,true))\n}\n`;
304
+ return awaitSite(`er${at(i)}(c)`, fn, mode, "_r", arm) + `if(_r!==undefined){\nif(_r instanceof Error){c.set.status=_r.status||500\n${declined}return _efb(_r,c)}\nif(_r instanceof es||_r instanceof Response)c.set.status=_r.status\nelse if(c.set.status===undefined||c.set.status===200)c.set.status=500\n` + schedule + sign + `return _em(c,${map}(aet(_r,e),c.set,c.request,true))\n}\n`;
305
305
  });
306
306
  function map(map) {
307
307
  return function(event, rest, abortGuard, tail) {
package/dist/error.d.ts CHANGED
@@ -232,55 +232,36 @@ type TaggedHTTPError<Type extends string, Annotation = {}> = {
232
232
  /**
233
233
  * Self-describing HTTP error
234
234
  *
235
- * Annotate `status`, `headers` and `value` on the subclass and Elysia maps
236
- * the instance to a response on its own, no `.onError(Class, handler)` needed
235
+ * Set `status`, `headers`, `detail`, `extension` and `value` to map to response
237
236
  *
238
- * Everything an owned `HTTPError` serves is an RFC 9457 problem document:
239
- * `type` is the problem type carried on the wire, and the body (or the error
240
- * message, when there is none) becomes `detail`, an object nested verbatim
241
- * and never merged into the envelope. Given neither, the document has no
242
- * `detail`: `new OutOfCredit()` serves none, `new OutOfCredit('')` an empty one
237
+ * Send RFC 9457 problem document by default that can be overridden by `value()`
243
238
  *
244
- * - `detail()` - the common case. Whatever it returns becomes the `detail`
245
- * member of the problem document, verbatim, objects included. The envelope
246
- * still carries `type`, `status` and an auto-filled `title`
247
- * - `value()` - the escape hatch. Whatever it returns replaces the *whole*
248
- * response: no envelope, no `application/problem+json`. The annotated
249
- * `status` and `headers` still apply, only the content is yours
239
+ * - `detail` - add `detail` field to the problem document
240
+ * - `extension()` - add extension members to the problem document
241
+ * - `value()` - override the whole response, return `problem()` to keep the shape
250
242
  *
251
- * `value` wins over `detail`, `detail` over the error message. A knob
252
- * returning `undefined` falls through to the next one.
243
+ * `value` wins over `detail`, `detail` over an `extension()` string `detail`,
244
+ * that over message. A `value` returning `undefined` falls
245
+ * through to the next one. A response that depends on the request belongs in
246
+ * `.onError(Class, handler)`
253
247
  *
254
248
  * @example
255
249
  * ```ts
256
- * class OutOfCredit extends HTTPError<'OUT_OF_CREDIT'> {
257
- * type = 'OUT_OF_CREDIT' as const
258
- * override readonly status = 402
259
- *
260
- * detail() {
261
- * return { balance: 0, currency: 'usd' }
262
- * }
250
+ * class OutOfCredit extends HTTPError.id('OUT_OF_CREDIT') {
251
+ * readonly status = 402
252
+ * readonly detail = 'Top up to continue'
263
253
  * }
264
- * // → { type: 'OUT_OF_CREDIT', title: 'Payment Required', status: 402,
265
- * // detail: { balance: 0, currency: 'usd' } }
266
254
  *
267
- * class Overdrawn extends HTTPError<'OVERDRAWN'> {
268
- * type = 'OVERDRAWN' as const
269
- * override readonly status = 402
255
+ * class Overdrawn extends Error implements HTTPError {
256
+ * readonly type = 'OVERDRAWN'
257
+ * readonly status = 402
270
258
  *
271
- * async detail() {
272
- * return await describeBalance()
273
- * }
274
- * }
275
- *
276
- * class Legacy extends HTTPError<'LEGACY'> {
277
- * type = 'LEGACY' as const
278
- * override readonly status = 402
279
- *
280
- * // full control, served as-is
281
- * value() {
282
- * return { code: 'OUT_OF_CREDIT', ok: false }
283
- * }
259
+ * value() {
260
+ * return problem(402, {
261
+ * type: 'OVERDRAWN',
262
+ * detail: await describeBalance()
263
+ * })
264
+ * }
284
265
  * }
285
266
  * ```
286
267
  *
@@ -329,18 +310,44 @@ declare abstract class HTTPError<const in out T extends string = string> extends
329
310
  /** Headers merged into `set.headers` when the error is served */
330
311
  readonly headers?: Record<string, string>;
331
312
  /**
332
- * Return a value to serve as the whole response
313
+ * Return a value to serve as the whole response, may be `async`
333
314
  *
334
315
  * Supports `status()`/`problem()` for status-based Eden response
335
316
  */
336
317
  value?(): MaybePromise<unknown>;
337
318
  /**
338
- * Return the `detail` member of the RFC 9457 problem document,
339
- * similar to `problem()`
319
+ * `detail` member of the RFC 9457 problem document, served in place of
320
+ * the error message
340
321
  *
341
- * Use `value()` to override the entire response
322
+ * Use `value()` for anything computed asynchronously
342
323
  */
343
- detail?(): MaybePromise<unknown>;
324
+ readonly detail?: string;
325
+ /**
326
+ * Return RFC 9457 extension members added to the problem document,
327
+ * synchronously
328
+ *
329
+ * `type`, `code` and `status` stay the error's own. A string `detail` is
330
+ * served when the error has no `detail` of its own, in place of the
331
+ * message. `title` and `instance` may be overridden. Not served when
332
+ * `value()` answers
333
+ *
334
+ * Only a plain object's own data members are served, which types can't
335
+ * check: return an object literal, not a class instance
336
+ *
337
+ * @example
338
+ * ```ts
339
+ * class OutOfCredit extends HTTPError.id('OUT_OF_CREDIT', 402) {
340
+ * constructor(readonly balance: number) {
341
+ * super()
342
+ * }
343
+ *
344
+ * extension() {
345
+ * return { balance: this.balance, accounts: ['/account/12345'] }
346
+ * }
347
+ * }
348
+ * ```
349
+ */
350
+ extension?(): Record<string, unknown>;
344
351
  /**
345
352
  * Create a concrete `HTTPError` subclass carrying `code`, mirrored into
346
353
  * `type` unless {@link HTTPError.typeBase} is set
@@ -363,16 +370,14 @@ declare abstract class HTTPError<const in out T extends string = string> extends
363
370
  * Create a concrete `HTTPError` subclass carrying `code`, annotated with
364
371
  * `status` as a number or a status name
365
372
  *
366
- * Annotate what is served with `detail()` (problem `detail` member) or
367
- * `value()` (whole-response override), either of which may be `async`
373
+ * Annotate what is served with `detail` (problem `detail` member) or
374
+ * `value()` (whole-response override, may be `async`)
368
375
  *
369
376
  * @example
370
377
  * ```ts
371
378
  * class OutOfCredit extends HTTPError.id('OUT_OF_CREDIT', 402) {}
372
379
  * class Denied extends HTTPError.id('DENIED', 'Payment Required') {
373
- * async detail() {
374
- * return await describeBalance()
375
- * }
380
+ * override readonly detail = 'Top up to continue'
376
381
  * }
377
382
  * ```
378
383
  */
@@ -21,17 +21,16 @@ declare const resolveStatus: (status: unknown) => unknown;
21
21
  * Body served by an error that carries a status but no usable body:
22
22
  * its declared `response`, otherwise its message, or `mask` in its place
23
23
  * on a production 5xx
24
- *
25
- * As a problem `detail`, an error given no message has none (`undefined`):
26
- * `Error` only defines an own `message` for one passed, `''` included
27
24
  */
28
25
  declare function statusFallbackBody(error: any, status: unknown, mask?: string, asDetail?: boolean): any;
29
26
  /**
30
- * Read one annotation knob, a method (may be `async`) or a plain value.
31
- * A method may have side effects, so only an error claiming a problem type
32
- * gets it invoked; a plain value is read from any error
27
+ * RFC 9457 extension members of an error claiming a problem type. Sync
28
+ * only: anything but a plain object, a Promise included, adds nothing.
29
+ * `type`, `code` and `status` stay the error's own, `detail` only when a
30
+ * string
33
31
  */
34
- declare const readAnnotation: (self: any, key: "value" | "detail", claimsProblem: boolean) => any;
32
+ declare function extensionOf(self: any): any;
33
+ declare function readAnnotation(self: any, key: 'value' | 'detail', claimsProblem: boolean): any;
35
34
  declare function createErrorHandler(onErrors: AppHook['error'] | undefined, mapResponse: (response: unknown, set: Context['set'], ...any: unknown[]) => unknown, allowUnsafe?: boolean): (context: Context, error: Error, sign?: ((set: Context["set"]) => unknown) | undefined) => unknown;
36
35
  //#endregion
37
- export { adoptErrorType, claimsProblemType, createErrorHandler, fallbackResponse, readAnnotation, resolveStatus, statusFallbackBody };
36
+ export { adoptErrorType, claimsProblemType, createErrorHandler, extensionOf, fallbackResponse, readAnnotation, resolveStatus, statusFallbackBody };