elysia 2.0.0-beta.21 → 2.0.0-beta.22

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 (215) hide show
  1. package/dist/_virtual/_rolldown/runtime.mjs +1 -0
  2. package/dist/adapter/bun/index.d.ts +6 -8
  3. package/dist/adapter/bun/index.js +6 -8
  4. package/dist/adapter/bun/index.mjs +7 -8
  5. package/dist/adapter/constants.mjs +1 -0
  6. package/dist/adapter/default-headers.mjs +1 -0
  7. package/dist/adapter/index.mjs +1 -0
  8. package/dist/adapter/origin.mjs +1 -0
  9. package/dist/adapter/response-ownership.mjs +1 -0
  10. package/dist/adapter/skip-clone.mjs +1 -0
  11. package/dist/adapter/types.mjs +1 -0
  12. package/dist/adapter/utils.d.ts +5 -8
  13. package/dist/adapter/utils.js +24 -18
  14. package/dist/adapter/utils.mjs +25 -18
  15. package/dist/adapter/web-standard/handler.mjs +2 -1
  16. package/dist/adapter/web-standard/index.mjs +1 -0
  17. package/dist/adapter/web-standard/utils.mjs +1 -0
  18. package/dist/base.d.ts +118 -69
  19. package/dist/base.js +213 -193
  20. package/dist/base.mjs +220 -199
  21. package/dist/compile/aot-capture.js +2 -2
  22. package/dist/compile/aot-capture.mjs +4 -3
  23. package/dist/compile/aot-emit.js +7 -8
  24. package/dist/compile/aot-emit.mjs +8 -8
  25. package/dist/compile/aot-reconstruct.mjs +3 -2
  26. package/dist/compile/aot.d.ts +3 -3
  27. package/dist/compile/aot.js +5 -5
  28. package/dist/compile/aot.mjs +6 -5
  29. package/dist/compile/handler/descriptor.d.ts +2 -5
  30. package/dist/compile/handler/descriptor.js +12 -17
  31. package/dist/compile/handler/descriptor.mjs +16 -21
  32. package/dist/compile/handler/frozen-validator.d.ts +2 -2
  33. package/dist/compile/handler/frozen-validator.js +3 -3
  34. package/dist/compile/handler/frozen-validator.mjs +4 -3
  35. package/dist/compile/handler/index.d.ts +3 -1
  36. package/dist/compile/handler/index.js +77 -118
  37. package/dist/compile/handler/index.mjs +83 -125
  38. package/dist/compile/handler/jit.d.ts +12 -12
  39. package/dist/compile/handler/jit.js +60 -43
  40. package/dist/compile/handler/jit.mjs +63 -47
  41. package/dist/compile/handler/params.d.ts +5 -1
  42. package/dist/compile/handler/params.js +14 -5
  43. package/dist/compile/handler/params.mjs +16 -7
  44. package/dist/compile/handler/reconstruct.d.ts +2 -2
  45. package/dist/compile/handler/reconstruct.js +2 -2
  46. package/dist/compile/handler/reconstruct.mjs +3 -2
  47. package/dist/compile/handler/static-clone-resolver.mjs +1 -0
  48. package/dist/compile/handler/utils.d.ts +13 -7
  49. package/dist/compile/handler/utils.js +75 -52
  50. package/dist/compile/handler/utils.mjs +77 -54
  51. package/dist/compile/jit-probe.mjs +1 -0
  52. package/dist/compile/lexer.js +4 -4
  53. package/dist/compile/lexer.mjs +5 -4
  54. package/dist/compile/utils.d.ts +2 -1
  55. package/dist/compile/utils.js +8 -3
  56. package/dist/compile/utils.mjs +8 -3
  57. package/dist/compiled.mjs +1 -0
  58. package/dist/constants.mjs +1 -0
  59. package/dist/context.d.ts +1 -1
  60. package/dist/context.js +1 -0
  61. package/dist/context.mjs +3 -1
  62. package/dist/cookie/config.d.ts +2 -2
  63. package/dist/cookie/config.js +21 -26
  64. package/dist/cookie/config.mjs +22 -26
  65. package/dist/cookie/cookie.mjs +1 -0
  66. package/dist/cookie/crypto.mjs +1 -0
  67. package/dist/cookie/error.mjs +1 -0
  68. package/dist/cookie/lib.mjs +1 -0
  69. package/dist/cookie/serialize.mjs +1 -0
  70. package/dist/cookie/types.mjs +1 -0
  71. package/dist/cookie/utils.d.ts +1 -1
  72. package/dist/cookie/utils.js +64 -45
  73. package/dist/cookie/utils.mjs +66 -46
  74. package/dist/error.d.ts +10 -6
  75. package/dist/error.js +22 -6
  76. package/dist/error.mjs +25 -9
  77. package/dist/generation.mjs +1 -0
  78. package/dist/handler/error.d.ts +12 -15
  79. package/dist/handler/error.js +43 -40
  80. package/dist/handler/error.mjs +45 -41
  81. package/dist/handler/fetch.js +59 -21
  82. package/dist/handler/fetch.mjs +61 -22
  83. package/dist/handler/utils.d.ts +16 -3
  84. package/dist/handler/utils.js +14 -13
  85. package/dist/handler/utils.mjs +16 -15
  86. package/dist/index.d.ts +9 -9
  87. package/dist/index.js +1 -0
  88. package/dist/index.mjs +3 -2
  89. package/dist/memory.mjs +1 -0
  90. package/dist/package.js +1 -1
  91. package/dist/package.mjs +2 -1
  92. package/dist/parse-query.js +76 -76
  93. package/dist/parse-query.mjs +77 -76
  94. package/dist/plugin/aot/bun.mjs +1 -0
  95. package/dist/plugin/aot/core.js +7 -4
  96. package/dist/plugin/aot/core.mjs +8 -5
  97. package/dist/plugin/aot/esbuild.mjs +1 -0
  98. package/dist/plugin/aot/rspack-loader.mjs +1 -0
  99. package/dist/plugin/aot/rspack.mjs +1 -0
  100. package/dist/plugin/aot/treeshake.mjs +1 -0
  101. package/dist/plugin/aot/unplugin.mjs +4 -3
  102. package/dist/plugin/aot/vite.mjs +1 -0
  103. package/dist/plugin/aot/worker.mjs +1 -0
  104. package/dist/plugin/auto-head.mjs +1 -0
  105. package/dist/plugin/trace.mjs +1 -0
  106. package/dist/plugin/websocket.mjs +1 -0
  107. package/dist/route-table.mjs +1 -0
  108. package/dist/schema-snapshot.mjs +1 -0
  109. package/dist/sucrose.d.ts +2 -2
  110. package/dist/sucrose.js +11 -11
  111. package/dist/sucrose.mjs +12 -11
  112. package/dist/trace.js +8 -10
  113. package/dist/trace.mjs +10 -11
  114. package/dist/type/bridge-live.d.ts +1 -1
  115. package/dist/type/bridge-live.mjs +1 -0
  116. package/dist/type/bridge.d.ts +1 -1
  117. package/dist/type/bridge.mjs +1 -0
  118. package/dist/type/coerce-plan.mjs +1 -0
  119. package/dist/type/coerce.d.ts +1 -1
  120. package/dist/type/coerce.mjs +1 -0
  121. package/dist/type/compat.mjs +1 -0
  122. package/dist/type/constants.d.ts +1 -1
  123. package/dist/type/constants.mjs +1 -0
  124. package/dist/type/elysia/accelerate.mjs +1 -0
  125. package/dist/type/elysia/array-buffer.d.ts +3 -2
  126. package/dist/type/elysia/array-buffer.js +5 -5
  127. package/dist/type/elysia/array-buffer.mjs +6 -5
  128. package/dist/type/elysia/array-string.mjs +1 -0
  129. package/dist/type/elysia/array.mjs +1 -0
  130. package/dist/type/elysia/boolean-string.mjs +1 -0
  131. package/dist/type/elysia/boolean.mjs +1 -0
  132. package/dist/type/elysia/cookie.mjs +1 -0
  133. package/dist/type/elysia/date.mjs +1 -0
  134. package/dist/type/elysia/file-type.mjs +1 -0
  135. package/dist/type/elysia/file.mjs +1 -0
  136. package/dist/type/elysia/files.mjs +1 -0
  137. package/dist/type/elysia/form.mjs +1 -0
  138. package/dist/type/elysia/integer-string.mjs +1 -0
  139. package/dist/type/elysia/integer.mjs +1 -0
  140. package/dist/type/elysia/intersect.mjs +1 -0
  141. package/dist/type/elysia/json-string.mjs +1 -0
  142. package/dist/type/elysia/keep-config.js +8 -8
  143. package/dist/type/elysia/keep-config.mjs +9 -8
  144. package/dist/type/elysia/maybe-empty.mjs +1 -0
  145. package/dist/type/elysia/no-validate.mjs +1 -0
  146. package/dist/type/elysia/nullable.mjs +1 -0
  147. package/dist/type/elysia/number.mjs +1 -0
  148. package/dist/type/elysia/numeric-enum.d.ts +4 -2
  149. package/dist/type/elysia/numeric-enum.mjs +1 -0
  150. package/dist/type/elysia/numeric.mjs +1 -0
  151. package/dist/type/elysia/object-string.mjs +1 -0
  152. package/dist/type/elysia/object.mjs +1 -0
  153. package/dist/type/elysia/optional.mjs +1 -0
  154. package/dist/type/elysia/problem.mjs +1 -0
  155. package/dist/type/elysia/string.mjs +1 -0
  156. package/dist/type/elysia/uint8-array.d.ts +2 -1
  157. package/dist/type/elysia/uint8-array.js +2 -2
  158. package/dist/type/elysia/uint8-array.mjs +3 -2
  159. package/dist/type/elysia/union-enum.mjs +1 -0
  160. package/dist/type/elysia/union.mjs +1 -0
  161. package/dist/type/elysia/utils.js +3 -3
  162. package/dist/type/elysia/utils.mjs +4 -3
  163. package/dist/type/exports.mjs +1 -0
  164. package/dist/type/index.mjs +2 -1
  165. package/dist/type/shared.mjs +1 -0
  166. package/dist/type/sync-require.mjs +1 -0
  167. package/dist/type/typebox-system-lite.mjs +1 -0
  168. package/dist/type/typebox-system-require.mjs +1 -0
  169. package/dist/type/typebox-type-live.mjs +1 -0
  170. package/dist/type/typebox-value-live.mjs +1 -0
  171. package/dist/type/typebox-value-ops.mjs +1 -0
  172. package/dist/type/typebox-value.mjs +1 -0
  173. package/dist/type/types.d.ts +1 -1
  174. package/dist/type/types.mjs +1 -0
  175. package/dist/type/utils.mjs +1 -0
  176. package/dist/type/validator/clean-safe.mjs +1 -0
  177. package/dist/type/validator/custom-error.js +41 -33
  178. package/dist/type/validator/custom-error.mjs +42 -33
  179. package/dist/type/validator/default-precompute.d.ts +2 -2
  180. package/dist/type/validator/default-precompute.js +10 -11
  181. package/dist/type/validator/default-precompute.mjs +13 -13
  182. package/dist/type/validator/exact-mirror.mjs +1 -0
  183. package/dist/type/validator/frozen-check.js +7 -7
  184. package/dist/type/validator/frozen-check.mjs +8 -7
  185. package/dist/type/validator/index.d.ts +2 -2
  186. package/dist/type/validator/index.js +4 -8
  187. package/dist/type/validator/index.mjs +5 -8
  188. package/dist/type/validator/string-codec-aot.d.ts +1 -1
  189. package/dist/type/validator/string-codec-aot.mjs +1 -0
  190. package/dist/type/validator/validator-cache.js +18 -18
  191. package/dist/type/validator/validator-cache.mjs +19 -18
  192. package/dist/types.d.ts +105 -69
  193. package/dist/types.mjs +1 -0
  194. package/dist/universal/constants.mjs +1 -0
  195. package/dist/universal/file.mjs +1 -0
  196. package/dist/universal/index.mjs +1 -0
  197. package/dist/universal/is-production.mjs +1 -0
  198. package/dist/universal/server.mjs +1 -0
  199. package/dist/utils.d.ts +49 -31
  200. package/dist/utils.js +221 -109
  201. package/dist/utils.mjs +215 -106
  202. package/dist/validator/index.d.ts +3 -3
  203. package/dist/validator/index.js +4 -4
  204. package/dist/validator/index.mjs +5 -4
  205. package/dist/validator/route.d.ts +2 -2
  206. package/dist/validator/route.mjs +1 -0
  207. package/dist/ws/context.js +1 -1
  208. package/dist/ws/context.mjs +2 -1
  209. package/dist/ws/index.mjs +1 -0
  210. package/dist/ws/parser.mjs +1 -0
  211. package/dist/ws/route.js +34 -25
  212. package/dist/ws/route.mjs +40 -30
  213. package/dist/ws/types.d.ts +2 -3
  214. package/dist/ws/types.mjs +1 -0
  215. package/package.json +2 -2
package/dist/types.d.ts CHANGED
@@ -1,16 +1,16 @@
1
- import { CookieOptions } from "./cookie/types.js";
2
- import { AnySchema, StandardSchemaV1Like, TypeBoxSchema } from "./type/types.js";
3
1
  import { StatusMap, StatusMapBack } from "./constants.js";
4
2
  import { ElysiaError, ElysiaStatus, ProblemResponseBody, ValidationErrorResponse } from "./error.js";
5
3
  import { ChainNode } from "./utils.js";
6
4
  import { Serve } from "./universal/server.js";
5
+ import { CookieOptions } from "./cookie/types.js";
7
6
  import { Context, ErrorContext, LifecycleContext, PreContext } from "./context.js";
8
7
  import { TraceHandler } from "./trace.js";
9
8
  import { ElysiaFile } from "./universal/file.js";
9
+ import { AnySchema, StandardSchemaV1Like, TypeBoxSchema } from "./type/types.js";
10
10
  import { AnyElysia, Elysia } from "./base.js";
11
11
  import { ElysiaAdapter } from "./adapter/index.js";
12
- import { Static, StaticDecode, StaticEncode, TIntersect, TObject, TRef, TSchema } from "typebox";
13
12
  import { OpenAPIV3 } from "openapi-types";
13
+ import { Static, StaticDecode, StaticEncode, TIntersect, TObject, TRef, TSchema } from "typebox";
14
14
 
15
15
  //#region src/types.d.ts
16
16
  interface ElysiaConfig<in out Prefix extends string | undefined, in out Scope extends EventScope, in out Adapter extends ElysiaAdapter = ElysiaAdapter> {
@@ -235,43 +235,43 @@ type LocalHook<Input extends BaseMacro, Schema extends RouteSchemaWithResolvedMa
235
235
  * - 'arraybuffer': parse body as readable stream
236
236
  */
237
237
  parse?: MaybeArray<BodyHandler<Schema, Singleton & {
238
- derive: Schema['resolve'];
238
+ derive: Schema['derive'];
239
239
  }> | ContentType | Parser>;
240
240
  /**
241
241
  * Transform context's value
242
242
  */
243
243
  transform?: MaybeArray<TransformHandler<Schema, Singleton & {
244
- derive: Schema['resolve'];
244
+ derive: Schema['derive'];
245
245
  }>>;
246
246
  /**
247
247
  * Execute before main handler
248
248
  */
249
249
  beforeHandle?: MaybeArray<OptionalHandler<Schema, Singleton & {
250
- derive: Schema['resolve'];
250
+ derive: Schema['derive'];
251
251
  }>>;
252
252
  /**
253
253
  * Execute after main handler
254
254
  */
255
255
  afterHandle?: MaybeArray<AfterHandler<Schema, Singleton & {
256
- derive: Schema['resolve'];
256
+ derive: Schema['derive'];
257
257
  }>>;
258
258
  /**
259
259
  * Execute after main handler
260
260
  */
261
261
  mapResponse?: MaybeArray<MapResponse<Schema, Singleton & {
262
- derive: Schema['resolve'];
262
+ derive: Schema['derive'];
263
263
  }>>;
264
264
  /**
265
265
  * Execute after response is sent
266
266
  */
267
267
  afterResponse?: MaybeArray<AfterResponseHandler<Schema, Singleton & {
268
- derive: Schema['resolve'];
268
+ derive: Schema['derive'];
269
269
  }>>;
270
270
  /**
271
271
  * Catch error
272
272
  */
273
273
  error?: MaybeArray<ErrorHandler<Errors, Schema, Singleton & {
274
- derive: Schema['resolve'];
274
+ derive: Schema['derive'];
275
275
  }>>;
276
276
  tags?: DocumentDecoration['tags'];
277
277
  } & (Input extends any ? Input : Prettify<Input>);
@@ -433,13 +433,13 @@ type InlineHandlerResponse<Route extends RouteSchema['response']> = { [Status in
433
433
  type InlineHandler<Route extends RouteSchema = {}, Singleton extends SingletonBase = DefaultSingleton, MacroContext extends {
434
434
  response: PossibleResponse;
435
435
  return: PossibleResponse;
436
- resolve: Record<string, unknown>;
436
+ derive: Record<string, unknown>;
437
437
  } = {
438
438
  response: {};
439
439
  return: {};
440
- resolve: {};
440
+ derive: {};
441
441
  }> = InlineHandlerNonMacro<Route & MacroContext, Singleton & {
442
- derive: MacroContext['resolve'];
442
+ derive: MacroContext['derive'];
443
443
  }>;
444
444
  type InlineHandlerNonMacro<Route extends RouteSchema = {}, Singleton extends SingletonBase = DefaultSingleton> = (Route['response'] extends infer ResponseSchema ? {} extends ResponseSchema ? MaybePromise<InlineResponse> : MaybePromise<ResponseSchema[keyof ResponseSchema] | InlineHandlerResponse<ResponseSchema>> : never) | ((context: Context<Route, Singleton>) => MaybePromise<Response> | MaybePromise<{} extends Route['response'] ? unknown : (Route['response'] extends {
445
445
  200: any;
@@ -460,9 +460,9 @@ type ErrorHandler<T extends ErrorDefinition[] = [], in out Route extends RouteSc
460
460
  }> & {
461
461
  error: T[number]['error'] | unknown;
462
462
  }) => unknown;
463
- type MergeSchema<A extends RouteSchema, B extends RouteSchema, Path extends string = '', AParamsPathDerived extends boolean = false> = {} extends A ? Path extends PathParameterLike ? Omit<B, 'params'> & {
463
+ type MergeSchema<A extends RouteSchema, B extends RouteSchema, Path extends string = '', AParamsPathDerived extends boolean = false> = {} extends A ? Path extends PathParameterLike ? IsNever<keyof B['params']> extends true ? Omit<B, 'params'> & {
464
464
  params: ResolvePath<Path>;
465
- } : B : {} extends B ? Path extends PathParameterLike ? Omit<A, 'params'> & {
465
+ } : B : B : {} extends B ? Path extends PathParameterLike ? Omit<A, 'params'> & {
466
466
  params: ResolvePath<Path>;
467
467
  } : A : {
468
468
  body: undefined extends A['body'] ? B['body'] : A['body'];
@@ -499,6 +499,11 @@ type MacroProperty<Macro extends BaseMacro = {}, TypedRoute extends RouteSchema
499
499
  mapResponse?: MaybeArray<MapResponse<TypedRoute, Singleton>>;
500
500
  afterResponse?: MaybeArray<AfterResponseHandler<TypedRoute, Singleton>>;
501
501
  derive?: MaybeArray<ResolveHandler<TypedRoute, Singleton>>;
502
+ /**
503
+ * Wrap the route handler. The wrapper's return is the handler value.
504
+ * A macro listed later in the route options wraps outside an earlier one
505
+ */
506
+ handler?: (handler: (context: Context<TypedRoute, Singleton>) => unknown) => (context: Context<TypedRoute, Singleton>) => unknown;
502
507
  detail?: DocumentDecoration;
503
508
  /**
504
509
  * Type-level route metadata surfaced on the route's Eden type
@@ -509,12 +514,16 @@ type MacroProperty<Macro extends BaseMacro = {}, TypedRoute extends RouteSchema
509
514
  /**
510
515
  * Phantom {@link MacroTypeLambda} computing per call site context from
511
516
  * the route's literal hook value. Reserved key like `seed`/`meta`/
512
- * `introspect` — carry it on the declared return type only; a runtime
513
- * value is tolerated and stripped
517
+ * `introspect` — set it with `macroType<Lambda>()`; stripped at runtime
514
518
  */
515
519
  $type?: MacroTypeLambda;
516
520
  /**
517
- * Introspect hook option for documentation generation or analysis
521
+ * Inspect or rewrite the hooks a route compiles with. Runs once per
522
+ * route at compile time, after every macro on the route has expanded,
523
+ * on the route's final hooks: its own, the ones every macro added and
524
+ * the ones it inherits from hooks registered before it. A WebSocket
525
+ * route hands over its own hooks only. Applied by
526
+ * a guard, it sees the guard's hooks once instead of each route's
518
527
  *
519
528
  * @param option
520
529
  */
@@ -698,11 +707,11 @@ interface UnwrapRoute<in out Schema extends InputSchema<any>, in out Definitions
698
707
  } : Schema['response'] extends { [status in number]: AnySchema | string } ? { [k in keyof Schema['response']]: UnwrapResponseSchema<Schema['response'][k], Definitions> extends infer A ? A extends File ? File | ElysiaFile : A : unknown } : unknown | void;
699
708
  }
700
709
  type UnwrapModels<T extends Record<string, unknown>, Iteration extends number[] = []> = Iteration['length'] extends 8 ? T : { [K in keyof T]: T[K] extends AnySchema ? UnwrapSchema<T[K]> : T[K] extends Record<string, unknown> ? UnwrapModels<T[K], [...Iteration, 0]> : T[K] };
701
- type MacroToProperty<in out T> = Prettify<{ [K in keyof T]: T[K] extends Function ? T[K] extends ((a: infer Params) => any) ? Params : boolean : boolean }>;
710
+ type MacroToProperty<in out T> = Prettify<{ [K in keyof T]: T[K] extends Function ? T[K] extends ((a: infer Params) => any) ? MacroOptionLambda<T[K]> extends never ? Params : unknown : boolean : boolean }>;
702
711
  interface RouteSchemaWithResolvedMacro extends RouteSchema {
703
712
  response: PossibleResponse;
704
713
  return: PossibleResponse;
705
- resolve: Record<string, unknown>;
714
+ derive: Record<string, unknown>;
706
715
  }
707
716
  type IntersectIfObject<A, B> = unknown extends A ? B : A extends Record<any, any> ? B extends Record<any, any> ? A & B : A : B extends Record<any, any> ? B : A;
708
717
  interface IntersectIfObjectSchema<A extends RouteSchema, B extends RouteSchema> {
@@ -734,7 +743,7 @@ type FunctionArrayReturnTypeNonNullable<T> = any[] extends T ? never : T extends
734
743
  type _FunctionArrayReturnTypeNonNullable<T, Carry = undefined> = T extends [infer Fn, ...infer Rest] ? _FunctionArrayReturnTypeNonNullable<Rest, NonNullable<Awaited<ReturnType<Fn>>> extends infer A ? IsNever<A> extends true ? Carry : A | Carry : Carry> : Carry;
735
744
  type AnyElysiaStatus = ElysiaStatus<any, any, any>;
736
745
  type ExcludeElysiaResponse<T> = Exclude<Awaited<T>, AnyElysiaStatus> extends infer A ? IsNever<A & {}> extends true ? {} : undefined extends A ? Partial<A & {}> : A & {} : {};
737
- type ExtractResolveFromMacro<A> = IsNever<A> extends true ? {} : A extends AnyElysiaStatus ? A : Exclude<A, AnyElysiaStatus> extends infer A ? IsAny<A> extends true ? {} : A : {};
746
+ type ExtractDeriveFromMacro<A> = IsNever<A> extends true ? {} : A extends AnyElysiaStatus ? A : Exclude<A, AnyElysiaStatus> extends infer A ? IsAny<A> extends true ? {} : A : {};
738
747
  type ExtractOnlyResponseFromMacro<A> = IsNever<A> extends true ? {} : Extract<A, AnyElysiaStatus> extends infer A ? IsNever<A> extends true ? {} : {
739
748
  return: MergeResponseStatus<A>;
740
749
  } : {};
@@ -748,14 +757,44 @@ type ExtractAllResponseFromMacro<A> = IsNever<A> extends true ? {} : {
748
757
  };
749
758
  type FlattenMacroResponse<T> = T extends object ? '_' extends keyof T ? UnionResponseStatus<Omit<T, '_'>, FlattenMacroResponse<MergeStatusUnion<T['_']>>> : T : T;
750
759
  /**
751
- * Type-level lambda applied to a macro's per call site hook value. Extend
752
- * this interface, compute `output` from `this['input']`, and carry it on
753
- * the macro's declared return type as a phantom `$type` member — the
754
- * computed `output` joins the route's context
760
+ * Type-level lambda applied to a macro's per call site hook value
761
+ *
762
+ * Return type as `$type: macroType<Lambda>()`
763
+ * `output` will be added to route's context
764
+ *
765
+ * A function-form macro may also compute `option` from `this['context']`.
766
+ * The hook value is then typed as `option` per route, guard, group and ws,
767
+ * replacing the macro's declared parameter
768
+ *
769
+ * `this` is not allowed in a nested type literal
770
+ *
771
+ * ```ts
772
+ * interface LiveOption<Context> { topic?: (ctx: Context) => string }
773
+ * interface Live extends MacroTypeLambda { option: LiveOption<this['context']> }
774
+ *
775
+ * new Elysia().macro({
776
+ * live: (option: LiveOption<Context>) => ({
777
+ * $type: macroType<Live>(),
778
+ * beforeHandle() {}
779
+ * })
780
+ * })
781
+ * ```
755
782
  */
756
783
  interface MacroTypeLambda {
757
784
  input: unknown;
785
+ /**
786
+ * The call-site schema and accumulated singleton context, excluding output
787
+ * from macros selected at the same call site
788
+ */
789
+ context: unknown;
758
790
  }
791
+ type MacroOptionLambda<Fn> = Fn extends ((option: any) => infer Def) ? NonNullable<Def> extends {
792
+ $type?: infer Lambda extends MacroTypeLambda;
793
+ } ? 'option' extends keyof Lambda ? Lambda : never : never : never;
794
+ type MacroOptionContext<MacroFn, Route extends RouteSchema, Singleton extends SingletonBase> = { [K in keyof MacroFn]?: MacroOptionLambda<MacroFn[K]> extends never ? unknown : ElaborateOption<(MacroOptionLambda<MacroFn[K]> & {
795
+ context: Context<Route, Singleton>;
796
+ })['option']> };
797
+ type ElaborateOption<Option, Keys extends PropertyKey = keyof Extract<Option, object>> = unknown extends Option ? Option : Option extends boolean ? Option & { [K in Exclude<Keys, keyof Option> as {} extends Record<K, 0> ? never : K]?: never } : Option;
759
798
  type MacroLambdaContext<Value, HookValue> = NonNullable<Value> extends {
760
799
  $type?: infer Lambda extends MacroTypeLambda;
761
800
  } ? Lambda & {
@@ -763,17 +802,21 @@ type MacroLambdaContext<Value, HookValue> = NonNullable<Value> extends {
763
802
  } extends {
764
803
  output: infer Output;
765
804
  } ? Output : {} : {};
766
- type UnionMacroContext<A> = UnionToIntersect<{ [K in Exclude<keyof A, 'return'>]: A[K] }> & {
805
+ type UnionMacroContext<A> = UnionToIntersect<A extends unknown ? { [K in Exclude<keyof A, 'return'>]: A[K] } : never> & {
767
806
  return: {
768
807
  _: A['return'];
769
808
  };
770
809
  };
771
- type MacroToContext<in out MacroFn extends Macro = {}, in out SelectedMacro extends BaseMacro = {}, in out Definitions extends DefinitionBase['typebox'] = {}, in out R extends 1[] = []> = Prettify<InnerMacroToContext<MacroFn, Pick<SelectedMacro, Extract<keyof MacroFn, keyof SelectedMacro>>, Definitions, R> extends infer A ? { [K in Exclude<keyof A, 'return'>]: UnionToIntersect<A[K]> } & Prettify<{
810
+ type MacroToContext<in out MacroFn extends Macro = {}, in out SelectedMacro extends BaseMacro = {}, in out Definitions extends DefinitionBase['typebox'] = {}, in out R extends 1[] = []> = Prettify<InnerMacroToContext<MacroFn, Pick<SelectedMacro, Extract<keyof MacroFn, keyof SelectedMacro>>, Definitions, R> extends infer A ? { [K in Exclude<keyof A, 'return'>]: K extends 'derive' ? UnionToIntersect<A[K]> : K extends 'meta' ? (A[K] & {
811
+ value: unknown;
812
+ })['value'] : A[K] } & Prettify<{
772
813
  return: FlattenMacroResponse<A['return']>;
773
814
  }> : {}>;
774
815
  type InnerMacroToContext<MacroFn extends Macro = {}, SelectedMacro extends BaseMacro = {}, Definitions extends DefinitionBase['typebox'] = {}, R extends 1[] = []> = {} extends SelectedMacro ? {} : R['length'] extends 15 ? {} : UnionMacroContext<{ [key in keyof SelectedMacro]: ReturnTypeIfPossible<MacroFn[key], SelectedMacro[key]> extends infer Value ? NonNullable<Value> extends infer Def ? {
775
- meta: 'meta' extends keyof Def ? Def['meta'] : never;
776
- resolve: ExtractResolveFromMacro<Extract<Exclude<FunctionArrayReturnType<Def['derive']>, AnyElysiaStatus>, Record<any, unknown>>> & MacroLambdaContext<Value, SelectedMacro[key]>;
816
+ meta: 'meta' extends keyof Def ? {
817
+ value: Def['meta'];
818
+ } : unknown;
819
+ derive: ExtractDeriveFromMacro<Extract<Exclude<FunctionArrayReturnType<Def['derive']>, AnyElysiaStatus>, Record<any, unknown>>> & MacroLambdaContext<Value, SelectedMacro[key]>;
777
820
  } & UnwrapMacroSchema<Def, Definitions> & ExtractAllResponseFromMacro<FunctionArrayReturnTypeNonNullable<Def['beforeHandle']>> & ExtractAllResponseFromMacro<FunctionArrayReturnTypeNonNullable<Def['afterHandle']>> & ExtractAllResponseFromMacro<FunctionArrayReturnType<Def['error']>> & ExtractOnlyResponseFromMacro<FunctionArrayReturnTypeNonNullable<Def['derive']>> & InnerMacroToContext<MacroFn, Pick<Def, Extract<keyof MacroFn, keyof Def>>, Definitions, [...R, 1]> : {} : {} }[keyof SelectedMacro]>;
778
821
  type UnwrapMacroSchema<T extends Partial<InputSchema<any>>, Definitions extends DefinitionBase['typebox'] = {}> = UnwrapRoute<{
779
822
  body: 'body' extends keyof T ? T['body'] : undefined;
@@ -804,22 +847,21 @@ type RefDefSchema<D> = {
804
847
  response: undefined;
805
848
  };
806
849
  /**
807
- * Captures the verbatim `.macro()` definition record into a separate first-pass
808
- * generic. This lets each definition's enabled
809
- * sibling flags (`{ auth: true }`) be read back without reusing the contextually
810
- * typed `NewMacro`, which would form the record -> handler-typing inference
811
- * cycle documented on {@link ObjectMacroDefs}.
850
+ * Captures the verbatim `.macro()` definition record in a first-pass generic,
851
+ * so each definition's sibling flags (`{ auth: true }`) are read back without
852
+ * reusing the contextually typed `NewMacro`, which would form the inference
853
+ * cycle documented on {@link ObjectMacroDefs}
812
854
  */
813
855
  type MacroRefChannel<Refs> = { [K in keyof Refs]: MaybeValueOrVoidFunction<{ [M in keyof Refs[K]]?: Refs[K][M] } & Record<string, unknown>> };
814
856
  /**
815
- * `resolve` (derive) context contributed by the sibling macros a definition
857
+ * `derive` context contributed by the sibling macros a definition
816
858
  * enables via `{ name: true }`. Extracted through `infer` because
817
- * {@link MacroToContext} is a mapped type whose `resolve` key cannot be indexed
818
- * with a plain `['resolve']` on the generic form.
859
+ * {@link MacroToContext} is a mapped type whose `derive` key cannot be indexed
860
+ * with a plain `['derive']` on the generic form.
819
861
  */
820
- type MacroRefResolve<MacroFn, SelectedMacro, Definitions> = MacroToContext<MacroFn, SelectedMacro, Definitions> extends {
821
- resolve: infer Resolve;
822
- } ? Resolve : {};
862
+ type MacroRefDerive<MacroFn, SelectedMacro, Definitions> = MacroToContext<MacroFn, SelectedMacro, Definitions> extends {
863
+ derive: infer Derive;
864
+ } ? Derive : {};
823
865
  /**
824
866
  * Parameter type of the object-form `.macro({ name: definition })`
825
867
  *
@@ -833,7 +875,7 @@ type MacroRefResolve<MacroFn, SelectedMacro, Definitions> = MacroToContext<Macro
833
875
  * `Metadata['macroFn']` for the consuming route)
834
876
  */
835
877
  type ObjectMacroDefs<N, AmbientSchema extends RouteSchema, ScopedSchemas extends RouteSchema, Singleton extends SingletonBase, Definitions extends DefinitionBase, MacroNames extends BaseMacro, MacroFn = {}, Refs = {}> = MacroRefChannel<Refs> & { [K in keyof N]: MaybeValueOrVoidFunction<MacroProperty<MacroNames & InputSchema<keyof Definitions['typebox'] & string>, IntersectIfObjectSchema<MergeSchema<UnwrapMacroSchema<RefDefSchema<K extends keyof Refs ? Refs[K] : {}>, Definitions['typebox']>, AmbientSchema>, ScopedSchemas>, Singleton & {
836
- derive: Singleton['derive'] & MacroRefResolve<MacroFn, K extends keyof Refs ? Refs[K] : {}, Definitions['typebox']>;
878
+ derive: Singleton['derive'] & MacroRefDerive<MacroFn, K extends keyof Refs ? Refs[K] : {}, Definitions['typebox']>;
837
879
  }, Definitions['error']>> } & { [K in keyof N]: N[K] extends ((...a: any[]) => any) ? unknown : string extends keyof N[K] ? unknown : { [P in Exclude<keyof N[K], MacroPropertyKey | InputSchemaKey | keyof MacroFn | keyof N>]: `Unknown macro property '${P & string}'` } } & N;
838
880
  type CreateEden<Path extends string, Property extends Record<string, unknown> = {}> = Path extends `/${infer Rest}` ? _CreateEden<Rest, Property> : Path extends '' | '/' ? Property : _CreateEden<Path, Property>;
839
881
  type CreateRouteEden<BasePath extends string, Path extends string, Property extends Record<string, unknown>> = string extends Path ? {} : CreateEden<JoinPath<BasePath, Path>, Property>;
@@ -842,13 +884,8 @@ type _CreateEden<Path extends string, Property extends Record<string, unknown> =
842
884
  * Value an annotation knob resolves to, `never` when it annotates nothing.
843
885
  *
844
886
  * Both knobs are canonically methods, so what they *return* is the
845
- * annotation. A value or getter reads as the value itself. An `unknown`
846
- * declaration resolves to `unknown` — the runtime serves whatever a knob
847
- * returns and can't see its declared type — and `undefined` is excluded, it
848
- * falls through to the next tier rather than being served.
849
- *
850
- * The base declares both knobs optional, so a subclass that doesn't override
851
- * them never reaches here
887
+ * annotation. A value or getter reads as the value itself. `unknown` stays
888
+ * `unknown`, and `undefined` is excluded: it falls through to the next tier
852
889
  */
853
890
  type ResolveAnnotation<V> = (V extends ((...args: any) => infer Returned) ? Returned : V) extends infer Value ? Exclude<Awaited<Value>, undefined> extends infer Resolved ? IsNever<Resolved> extends true ? never : Resolved : never : never;
854
891
  /** Whether a knob may resolve `undefined` and fall through to the next tier */
@@ -979,16 +1016,10 @@ type ComposeElysiaResponse<Schema extends RouteSchema, Handle, Possibility exten
979
1016
  })>>;
980
1017
  type ExtractErrorFromHandle<in out Handle> = { [ErrorResponse in Extract<Handle, AnyElysiaStatus> as ErrorResponse extends AnyElysiaStatus ? ErrorResponse['status'] : never]: Prettify<ErrorResponse['response']> };
981
1018
  /**
982
- * Status used when an error handler returns a plain value (or falls through):
983
- * the error's declared literal `status`, otherwise 500
1019
+ * Status used when an error handler returns a plain value: the error's
1020
+ * declared literal `status`, otherwise 500
984
1021
  */
985
1022
  type ErrorFallbackStatus<E> = IsNever<LiteralErrorStatus<E>> extends true ? 500 : LiteralErrorStatus<E>;
986
- /**
987
- * Body produced when no error handler returns a value. Falling through lands
988
- * on exactly the lane an unhandled error takes, so it resolves the same three
989
- * tiers — `MessageTier` already carries the foreign `response` fallback
990
- */
991
- type ErrorFallbackBody<E> = ValueTier<E>;
992
1023
  /**
993
1024
  * `Definitions['error']` / `EphemeralType['error']` entry registered by an
994
1025
  * `.error(Class, handler)` call
@@ -996,10 +1027,22 @@ type ErrorFallbackBody<E> = ValueTier<E>;
996
1027
  type ErrorDefinitionEntry<E extends abstract new (...args: any) => Error, R> = {
997
1028
  error: InstanceType<E>;
998
1029
  response: ErrorHandlerResponseSchema<Awaited<R>, InstanceType<E>>;
1030
+ /**
1031
+ * The handler may return nothing, which passes the error on to the next
1032
+ * hook: it answers sometimes, but doesn't handle the error
1033
+ */
1034
+ passes: undefined extends Awaited<R> ? true : false;
999
1035
  };
1000
- type ErrorHandlerResponseSchema<R, E> = ExtractErrorFromHandle<Exclude<R, Error>> & (Exclude<R, Extract<Exclude<R, Error>, AnyElysiaStatus> | undefined> | (undefined extends R ? ErrorFallbackBody<E> : never) extends infer Served ? ServedAtStatus<Served, ErrorFallbackStatus<E>> : {});
1001
- type MatchRegisteredError<V, Errors extends ErrorDefinition[]> = Errors extends [infer Head extends ErrorDefinition, ...infer Rest extends ErrorDefinition[]] ? V extends Head['error'] ? Head['response'] : MatchRegisteredError<V, Rest> : never;
1002
- type HasErrorMatch<V, Errors extends ErrorDefinition[]> = Errors extends [infer Head extends ErrorDefinition, ...infer Rest extends ErrorDefinition[]] ? [V] extends [Head['error']] ? true : HasErrorMatch<V, Rest> : false;
1036
+ type ErrorHandlerResponseSchema<R, E> = ExtractErrorFromHandle<Exclude<R, Error>> & (Exclude<R, Extract<Exclude<R, Error>, AnyElysiaStatus> | undefined | void> extends infer Served ? ServedAtStatus<Served, ErrorFallbackStatus<E>> : {});
1037
+ type PassesError<Entry> = Entry extends {
1038
+ passes: true;
1039
+ } ? true : false;
1040
+ /**
1041
+ * What the handlers registered for `V` respond with: the first one that
1042
+ * always answers, and every one before it that may pass the error on
1043
+ */
1044
+ type MatchRegisteredError<V, Errors extends ErrorDefinition[]> = Errors extends [infer Head extends ErrorDefinition, ...infer Rest extends ErrorDefinition[]] ? V extends Head['error'] ? PassesError<Head> extends true ? Head['response'] | MatchRegisteredError<V, Rest> : Head['response'] : MatchRegisteredError<V, Rest> : never;
1045
+ type HasErrorMatch<V, Errors extends ErrorDefinition[]> = Errors extends [infer Head extends ErrorDefinition, ...infer Rest extends ErrorDefinition[]] ? [V] extends [Head['error']] ? PassesError<Head> extends true ? HasErrorMatch<V, Rest> : true : HasErrorMatch<V, Rest> : false;
1003
1046
  type UnhandledReturnedError<Value, Errors extends ErrorDefinition[]> = 0 extends 1 & Value ? never : ErrorOf<Value> extends infer Es ? Es extends Error ? HasErrorMatch<Es, Errors> extends true ? never : Es : never : never;
1004
1047
  type UnhandledReturnedErrorOf<T, Errors extends ErrorDefinition[]> = T extends ((...a: any) => MaybePromise<infer R>) ? UnhandledReturnedError<R, Errors> : UnhandledReturnedError<T, Errors>;
1005
1048
  /**
@@ -1053,13 +1096,6 @@ type ResolveRouteLeafErrors<Route extends {
1053
1096
  response: Prettify<UnionResponseStatus<WithoutUnhandledErrorResponse<Route['response'], Route['error']>, UnionResponseStatus<ExtractReturnedError<Route['error'], Errors>, UnhandledErrorResponse<UnhandledReturnedError<Route['error'], Errors>>>>>;
1054
1097
  error: UnhandledReturnedError<Route['error'], Errors>;
1055
1098
  } & HandledErrorKey<RouteHandled<Route> | HandledReturnedError<Route['error'], Errors>>;
1056
- type ResolveRouteErrors<Routes, Errors extends ErrorDefinition[]> = Errors extends [] ? Routes : { [K in keyof Routes]: Routes[K] extends {
1057
- params: any;
1058
- query: any;
1059
- headers: any;
1060
- response: any;
1061
- error: any;
1062
- } ? ResolveRouteLeafErrors<Routes[K], Errors> : Routes[K] extends Record<keyof any, any> ? ResolveRouteErrors<Routes[K], Errors> : Routes[K] };
1063
1099
  /**
1064
1100
  * Take a parent's handlers registered before `.use()` in front of the
1065
1101
  * plugin's own: at runtime they run first, so an error the plugin already
@@ -1107,7 +1143,7 @@ type MergeElysiaInstances<Instances extends AnyElysia[] = [], Prefix extends str
1107
1143
  schemas: Volatile['schemas'] & Current['~Ephemeral']['schemas'];
1108
1144
  response: Volatile['response'] & Current['~Ephemeral']['response'];
1109
1145
  error: [...Volatile['error'], ...Current['~Ephemeral']['error']];
1110
- }, ResolveRouteErrors<Routes, [...Current['~Definitions']['error'], ...Current['~Ephemeral']['error']]> & (Prefix extends `` ? ResolveUsedRouteErrors<Current['~Routes'], [...Definitions['error'], ...Ephemeral['error'], ...Volatile['error']], ParentResponse<Metadata, Ephemeral, Volatile>> : CreateEden<Prefix, ResolveUsedRouteErrors<Current['~Routes'], [...Definitions['error'], ...Ephemeral['error'], ...Volatile['error']], ParentResponse<Metadata, Ephemeral, Volatile>>>)> : Elysia<Prefix, Scope, {
1146
+ }, Routes & (Prefix extends `` ? ResolveUsedRouteErrors<Current['~Routes'], [...Definitions['error'], ...Ephemeral['error'], ...Volatile['error']], ParentResponse<Metadata, Ephemeral, Volatile>> : CreateEden<Prefix, ResolveUsedRouteErrors<Current['~Routes'], [...Definitions['error'], ...Ephemeral['error'], ...Volatile['error']], ParentResponse<Metadata, Ephemeral, Volatile>>>)> : Elysia<Prefix, Scope, {
1111
1147
  decorator: Singleton['decorator'];
1112
1148
  store: Prettify<Singleton['store']>;
1113
1149
  derive: Singleton['derive'];
@@ -1218,11 +1254,11 @@ type AddWSRoute<BasePath extends string, Scope extends EventScope, Singleton ext
1218
1254
  subscribe: CreateWSEdenResponse<Path, Schema, MacroContext, ComposeElysiaResponse<Schema & MacroContext & Metadata['schemas'] & Ephemeral['schemas'] & Volatile['schemas'], Response, UnionResponseStatus<Metadata['response'], UnionResponseStatus<Ephemeral['response'], UnionResponseStatus<Volatile['response'], MacroContext['return'] & {}>>>, [...Definitions['error'], ...Ephemeral['error'], ...Volatile['error']], Path>>;
1219
1255
  }>, Ephemeral, Volatile>;
1220
1256
  type GuardHookSingleton<Singleton extends SingletonBase, Ephemeral extends EphemeralType, Volatile extends EphemeralType, MacroContext> = Singleton & {
1221
- derive: Ephemeral['derive'] & Volatile['derive'] & MacroContext['resolve'];
1257
+ derive: Ephemeral['derive'] & Volatile['derive'] & MacroContext['derive'];
1222
1258
  };
1223
1259
  interface StaticMapAliases {
1224
1260
  method: string;
1225
1261
  paths: string[];
1226
1262
  }
1227
1263
  //#endregion
1228
- export { AddRoute, AddWSRoute, AfterHandler, AfterResponseHandler, AnyErrorConstructor, AnyLocalHook, type AnySchema, AnyWSLocalHook, AppEvent, AppHook, BaseMacro, BodyHandler, BunHTMLBundlelike, CompiledHandler, ComposeElysiaResponse, ContentType, ContextAppendType, CreateEden, CreateEdenResponse, CreateWSEdenResponse, DefaultEphemeral, DefaultMetadata, DefaultSingleton, DefinitionBase, DocumentDecoration, ElysiaConfig, ElysiaFormData, ElysiaHandlerToResponseSchema, ElysiaHandlerToResponseSchemaAmbiguous, ElysiaHandlerToResponseSchemas, EmptyInputSchema, EphemeralType, Equal, ErrorDefinition, ErrorDefinitionEntry, ErrorHandler, ErrorHandlerResponseSchema, EventFn, EventScope, ExcludeElysiaResponse, ExtractErrorFromHandle, ExtractReturnedError, GetPathParameter, GlobalHookReturn, GracefulHandler, GuardHookSingleton, GuardLocalHook, GuardSchemaType, HTTPHeaders, HTTPMethod, HandledErrorKey, HandledReturnedErrorOf, Handler, HistoryEntry, HookContextSchema, HookContextSingleton, InlineHandler, InlineHandlerNonMacro, InlineHandlerResponse, InlineResponse, InputSchema, InputSchemaKey, InternalRoute, IntersectIfObject, IntersectIfObjectSchema, IsAny, IsNever, IsTuple, JoinPath, LocalHook, LocalHookReturn, Macro, MacroProperty, MacroPropertyKey, MacroToContext, MacroToProperty, MacroTypeLambda, MapResponse, MaybeArray, MaybePromise, MaybeValueOrVoidFunction, MergeElysiaInstances, MergeSchema, MergeScopedSchemas, MetadataBase, ObjectMacroDefs, OptionalHandler, ParentResponse, PluginHookReturn, PossibleResponse, PreHandler, Prettify, PublicRoute, Replace, ResolveHandler, ResolvePath, ResolveRouteErrors, ResolveUsedRouteErrors, RouteBase, RouteInput, RouteSchema, SSEPayload, ScopedHookReturn, ScopedMapDeriveReturn, SingletonBase, type StandardSchemaV1Like, StaticMapAliases, TransformHandler, type TypeBoxSchema, UnhandledReturnedError, UnhandledReturnedErrorOf, UnionResponseStatus, UnionToIntersect, UnwrapArray, UnwrapBodySchema, UnwrapMacroSchema, UnwrapModels, UnwrapRoute, UnwrapSchema, ValueOrFunctionToResponseSchema, ValueToResponseSchema, VoidHandler, WithHandledErrors, WrapFn };
1264
+ export { AddRoute, AddWSRoute, AfterHandler, AfterResponseHandler, AnyErrorConstructor, AnyLocalHook, type AnySchema, AnyWSLocalHook, AppEvent, AppHook, BaseMacro, BodyHandler, BunHTMLBundlelike, CompiledHandler, ComposeElysiaResponse, ContentType, ContextAppendType, CreateEden, CreateEdenResponse, CreateWSEdenResponse, DefaultEphemeral, DefaultMetadata, DefaultSingleton, DefinitionBase, DocumentDecoration, ElysiaConfig, ElysiaFormData, ElysiaHandlerToResponseSchema, ElysiaHandlerToResponseSchemaAmbiguous, ElysiaHandlerToResponseSchemas, EmptyInputSchema, EphemeralType, Equal, ErrorDefinition, ErrorDefinitionEntry, ErrorHandler, ErrorHandlerResponseSchema, EventFn, EventScope, ExcludeElysiaResponse, ExtractErrorFromHandle, ExtractReturnedError, GetPathParameter, GlobalHookReturn, GracefulHandler, GuardHookSingleton, GuardLocalHook, GuardSchemaType, HTTPHeaders, HTTPMethod, HandledErrorKey, HandledReturnedErrorOf, Handler, HistoryEntry, HookContextSchema, HookContextSingleton, InlineHandler, InlineHandlerNonMacro, InlineHandlerResponse, InlineResponse, InputSchema, InputSchemaKey, InternalRoute, IntersectIfObject, IntersectIfObjectSchema, IsAny, IsNever, IsTuple, JoinPath, LocalHook, LocalHookReturn, Macro, MacroOptionContext, MacroProperty, MacroPropertyKey, MacroToContext, MacroToProperty, MacroTypeLambda, MapResponse, MaybeArray, MaybePromise, MaybeValueOrVoidFunction, MergeElysiaInstances, MergeSchema, MergeScopedSchemas, MetadataBase, ObjectMacroDefs, OptionalHandler, ParentResponse, PluginHookReturn, PossibleResponse, PreHandler, Prettify, PublicRoute, Replace, ResolveHandler, ResolvePath, ResolveUsedRouteErrors, RouteBase, RouteInput, RouteSchema, SSEPayload, ScopedHookReturn, ScopedMapDeriveReturn, SingletonBase, type StandardSchemaV1Like, StaticMapAliases, TransformHandler, type TypeBoxSchema, UnhandledReturnedError, UnhandledReturnedErrorOf, UnionResponseStatus, UnionToIntersect, UnwrapArray, UnwrapBodySchema, UnwrapMacroSchema, UnwrapModels, UnwrapRoute, UnwrapSchema, ValueOrFunctionToResponseSchema, ValueToResponseSchema, VoidHandler, WithHandledErrors, WrapFn };
package/dist/types.mjs CHANGED
@@ -1 +1,2 @@
1
+ // @bun
1
2
  export { };
@@ -1,3 +1,4 @@
1
+ // @bun
1
2
  //#region src/universal/constants.ts
2
3
  const isBun = typeof Bun !== "undefined";
3
4
  const isFastly = typeof fastly !== "undefined";
@@ -1,3 +1,4 @@
1
+ // @bun
1
2
  import { isBun } from "./constants.mjs";
2
3
 
3
4
  //#region src/universal/file.ts
@@ -1,3 +1,4 @@
1
+ // @bun
1
2
  import { file } from "./file.mjs";
2
3
  import { env } from "./env.mjs";
3
4
  import { isProduction } from "./is-production.mjs";
@@ -1,3 +1,4 @@
1
+ // @bun
1
2
  import { env, hasReadableEnv } from "./env.mjs";
2
3
 
3
4
  //#region src/universal/is-production.ts
@@ -1 +1,2 @@
1
+ // @bun
1
2
  export { };
package/dist/utils.d.ts CHANGED
@@ -1,13 +1,23 @@
1
- import { AnySchema, StandardSchemaV1Like } from "./type/types.js";
2
1
  import { Context } from "./context.js";
3
- import { AnyLocalHook, AppHook, BunHTMLBundlelike, ElysiaFormData, EventFn, EventScope, GuardSchemaType, InputSchema, Macro, MaybeArray, Prettify, SSEPayload } from "./types.js";
2
+ import { AnySchema, StandardSchemaV1Like } from "./type/types.js";
3
+ import { AnyLocalHook, AppHook, BunHTMLBundlelike, ElysiaFormData, EventFn, EventScope, GuardSchemaType, InputSchema, Macro, MacroTypeLambda, MaybeArray, Prettify, SSEPayload } from "./types.js";
4
4
 
5
5
  //#region src/utils.d.ts
6
- type DeriveEntry = Function | readonly [Function, 'mapDerive'];
6
+ type DeriveEntry = Function | readonly [Function, 'mapDerive' | 'beforeHandle'];
7
7
  declare const nullObject: () => any;
8
8
  declare const mapDeriveEntry: (fn: Function) => DeriveEntry;
9
9
  declare const deriveEntryFn: (entry: DeriveEntry) => any;
10
10
  declare const isMapDeriveEntry: (entry: DeriveEntry) => boolean;
11
+ declare const isPlainDeriveEntry: (entry: DeriveEntry) => boolean;
12
+ /**
13
+ * `~deriveEntries` for `hooks` whose role per occurrence is `at` (an entry
14
+ * for a derive, undefined for a plain hook). `deriveModes` gives each
15
+ * function's entries to its occurrences in order, so a plain occurrence
16
+ * before a derive of the same function gets a placeholder
17
+ */
18
+ declare function occurrenceDeriveEntries(hooks: readonly Function[], at: readonly (DeriveEntry | undefined)[]): DeriveEntry[];
19
+ /** Each function's derive entries, in occurrence order */
20
+ declare const deriveQueues: (entries: readonly DeriveEntry[] | undefined) => Map<any, DeriveEntry[]> | undefined;
11
21
  declare function isEmpty<T extends Object>(obj: T): boolean;
12
22
  declare const isNotEmpty: <T extends Object>(obj?: T) => boolean | undefined;
13
23
  /**
@@ -20,20 +30,20 @@ declare const isNotEmpty: <T extends Object>(obj?: T) => boolean | undefined;
20
30
  */
21
31
  declare function evictOldestHalf(cache: Map<any, any>): void;
22
32
  declare function fnv1a(str: string): number;
33
+ /**
34
+ * 48-bit hash of a named plugin's key (fnv1a + 16 bits of a second hash): at
35
+ * 32 bits two plugins collide by ~77k and the second is dropped. 48 keeps
36
+ * `origin * 16 + slot` exact
37
+ */
38
+ declare function pluginHash(str: string): number;
23
39
  declare const compositionKeys: readonly string[];
24
40
  declare function refTargets(roots: unknown[], models?: Record<string, unknown>): (name: string) => Iterable<unknown>;
41
+ declare const macroOrigin: WeakMap<object | Function, number>;
25
42
  /**
26
- * Maps each lifecycle/derive function to the hash of the named plugin it was
27
- * first registered on. Used by `.use()` to dedup absorbed hooks: if a fn's
28
- * origin is already in `parent.#apps`, the parent has already absorbed that
29
- * named plugin via another path and should skip re-adding the fn.
30
- *
31
- * Anonymous plugins (no name) don't tag their fns - there's no hash to dedup
32
- * by, so their fns always propagate.
43
+ * Id of an unnamed plugin in `childrenHash`, negative so it never collides
44
+ * with a named plugin's unsigned hash
33
45
  */
34
- declare const fnOrigin: WeakMap<Function, number>;
35
- declare const macroOrigin: WeakMap<object | Function, number>;
36
- declare const isLocalScope: (s: EventScope | undefined) => s is "local" | undefined;
46
+ declare const pluginId: (plugin: object) => number;
37
47
  /**
38
48
  * Linked-list representation of the scope/global hook chain of a route
39
49
  *
@@ -51,10 +61,9 @@ declare const isLocalScope: (s: EventScope | undefined) => s is "local" | undefi
51
61
  * without flattening - `over` is walked first (older / outer context),
52
62
  * then `combine` (newer / inner context)
53
63
  *
54
- * `tail` is the child's own chain head at that `.use()`. Its local hooks
55
- * registered after the child absorbed the route run after the route's own
56
- * hooks, as they would with the child as the root (`afterUseHooks` in
57
- * `compile/handler`)
64
+ * `callback` is the chain of a `.group()`/`.guard()` callback the route came
65
+ * out of: its error hooks cover every route the callback produced. Flattening
66
+ * never reads it
58
67
  *
59
68
  * Use with {@link flattenChain} to walk tail-first and reconstruct
60
69
  * flat `Partial<AppHook>` at compile time
@@ -66,18 +75,15 @@ type ChainNode = {
66
75
  scope?: EventScope;
67
76
  propagated?: boolean;
68
77
  owner?: object;
78
+ origin?: number;
79
+ registration?: ChainNode;
69
80
  } | {
70
81
  combine: ChainNode | undefined;
71
82
  over: ChainNode | undefined;
72
- tail?: ChainNode;
83
+ callback?: ChainNode;
84
+ inner?: ChainNode;
73
85
  refs: boolean;
74
86
  };
75
- /**
76
- * The absorbing instance's chain as it stood at `.use()`: the `over` of a
77
- * combine node, or the node itself. A combine node is never on an instance's
78
- * own chain, so it can't serve as a `stopAt` directly
79
- */
80
- declare const rootSnapshot: (node: ChainNode | undefined) => ChainNode | undefined;
81
87
  interface CompactBeforeHandleChunk {
82
88
  parent?: CompactBeforeHandleChunk;
83
89
  values: readonly Function[];
@@ -91,19 +97,30 @@ interface CompactBeforeHandlePrefix {
91
97
  declare const isCompactBeforeHandleOnly: (hook: Partial<AppHook> | undefined) => boolean;
92
98
  declare function compactBeforeHandleConflicts(hook: Partial<AppHook> | undefined): boolean;
93
99
  declare function compactBeforeHandlePrefix(start: ChainNode | undefined): CompactBeforeHandlePrefix | undefined;
100
+ interface ChainInfo {
101
+ installs?: ReadonlySet<number>;
102
+ named?: true;
103
+ }
94
104
  /**
95
105
  * Walk the chain tail-first into a fresh `Partial<AppHook>`
96
106
  *
107
+ * Each instance chain a combine node links is one layer, outermost first.
108
+ * A named plugin's hook is skipped when an outer layer, or `skip`, already
109
+ * installed that plugin's same lifecycle event: it runs once, at its
110
+ * outermost position. Within a layer every registration stays
111
+ *
97
112
  * Explicit-stack walk (no recursion) so it works uniformly for linear
98
113
  * chains and combine nodes without risking stack overflow on deep chains
99
114
  */
100
- declare function flattenChain(start: ChainNode | undefined, keep?: (s: EventScope | undefined) => boolean, stopAt?: ChainNode, resolveAdded?: (node: ChainNode) => Partial<AppHook> | undefined): Partial<AppHook> | undefined;
115
+ declare function flattenChain(start: ChainNode | undefined, resolveAdded?: (node: ChainNode) => Partial<AppHook> | undefined, skip?: ReadonlySet<number>, info?: ChainInfo): Partial<AppHook> | undefined;
101
116
  declare const macroEpoch: () => number;
102
117
  declare const invalidateMacroEpoch: () => void;
103
118
  /** Drop this root's flattened-chain memo. Recomputable on next compile. */
104
119
  declare function clearFlattenChainMemo(root: object): void;
105
- declare function flattenChainMemoReadonly(root: object, start: ChainNode | undefined, resolveAdded?: (node: ChainNode) => Partial<AppHook> | undefined): Partial<AppHook> | undefined;
106
- declare function flattenChainMemo(root: object, start: ChainNode | undefined, resolveAdded?: (node: ChainNode) => Partial<AppHook> | undefined): Partial<AppHook> | undefined;
120
+ /** What the chain installs, see {@link flattenChain} */
121
+ declare function flattenChainInfo(root: object, start: ChainNode | undefined, resolveAdded?: (node: ChainNode) => Partial<AppHook> | undefined): ChainInfo | undefined;
122
+ declare function flattenChainMemoReadonly(root: object, start: ChainNode | undefined, resolveAdded?: (node: ChainNode) => Partial<AppHook> | undefined, skip?: ReadonlySet<number>): Partial<AppHook> | undefined;
123
+ declare function flattenChainMemo(root: object, start: ChainNode | undefined, resolveAdded?: (node: ChainNode) => Partial<AppHook> | undefined, skip?: ReadonlySet<number>): Partial<AppHook> | undefined;
107
124
  /**
108
125
  *
109
126
  * @param url URL to redirect to
@@ -130,6 +147,7 @@ declare function formToFormData(value: Record<keyof any, unknown>): FormData;
130
147
  * ```
131
148
  */
132
149
  declare const form: <const T extends Record<keyof any, unknown>>(value: T) => ElysiaFormData<T>;
150
+ declare const macroType: <L extends MacroTypeLambda>() => L | undefined;
133
151
  declare const assignOwn: <T extends object>(target: T, source: any) => T;
134
152
  declare const getLoosePath: (path: string) => string;
135
153
  /**
@@ -171,7 +189,7 @@ declare function hookToGuard(a: Partial<AppHook & Macro> & {
171
189
  schema?: GuardSchemaType;
172
190
  }): Partial<AppHook & Macro>;
173
191
  declare function coalesceSchemas(existing: any[], incoming: any[]): void;
174
- declare function mergeHook(a: Partial<AppHook>, b: Partial<AppHook> | undefined, reverse?: boolean, dedup?: boolean): Partial<AppHook>;
192
+ declare function mergeHook(a: Partial<AppHook>, b: Partial<AppHook> | undefined): Partial<AppHook>;
175
193
  declare const createErrorEventHandler: (fn: EventFn<"error">, error: Error) => (context: Context) => unknown;
176
194
  declare function mergeDeep<A extends Record<string, any>, B extends Record<string, any>>(target: A, source: B, skipKeys?: string[], override?: boolean, mergeArray?: boolean, seen?: WeakSet<object>, cloneAdopt?: {
177
195
  map?: WeakMap<object, any>;
@@ -181,7 +199,6 @@ declare function cloneHook<T extends Partial<AnyLocalHook> | Partial<AppHook>>(s
181
199
  declare function clonePlainDeep<T>(value: T, seen?: WeakMap<object, any>): T;
182
200
  declare function guardNonPlainLeaves(target: Record<string, unknown>, source: Record<string, unknown>): void;
183
201
  declare function joinPath(base: string, path: string): string;
184
- declare function pushField<K extends keyof any>(target: Record<K, unknown>, key: K, item: unknown): void;
185
202
  declare const requestId: typeof Bun.randomUUIDv7 | (() => `${string}-${string}-${string}-${string}-${string}`);
186
203
  /**
187
204
  * Offset of the first byte after `://`, so the authority is never scanned as
@@ -200,7 +217,8 @@ declare function serializeMacroSeed(_key: string, value: unknown): unknown;
200
217
  declare const throwLifecycleErrors: (errors: unknown[]) => void;
201
218
  declare const isDisposable: (value: any) => boolean;
202
219
  declare const isSingleton: (value: object) => boolean;
203
- declare const markSingletons: (value: unknown, depth?: number, seen?: Set<object>) => void;
220
+ declare const markSingletons: (value: unknown, depth?: number) => void;
221
+ declare const markPropertySingletons: (object: object) => void;
204
222
  declare const isSocketQuiet: (socket: {
205
223
  readyState: number;
206
224
  data: {
@@ -211,4 +229,4 @@ declare const isSocketQuiet: (socket: {
211
229
  }) => boolean;
212
230
  declare const isHTMLBundle: (value: unknown) => value is BunHTMLBundlelike;
213
231
  //#endregion
214
- export { ChainNode, CompactBeforeHandleChunk, CompactBeforeHandlePrefix, DeriveEntry, ELYSIA_FORM_PROTOTYPE, assignOwn, authorityEnd, bytes, clearFlattenChainMemo, cloneHook, clonePlainDecorators, clonePlainDeep, coalesceSchemas, compactBeforeHandleConflicts, compactBeforeHandlePrefix, compositionKeys, constantTimeEqual, createErrorEventHandler, deriveEntryFn, eventProperties, evictOldestHalf, flattenChain, flattenChainMemo, flattenChainMemoReadonly, fnOrigin, fnv1a, form, formToFormData, getLoosePath, guardNonPlainLeaves, hookToGuard, invalidateMacroEpoch, isBlob, isByteStream, isCompactBeforeHandleOnly, isDisposable, isElysiaForm, isEmpty, isHTMLBundle, isLocalScope, isMapDeriveEntry, isNotEmpty, isPlainObject, isRecordNumber, isSingleton, isSocketQuiet, joinPath, macroEpoch, macroOrigin, mapDeriveEntry, markSingletons, mergeArray, mergeDeep, mergeHook, mergeResponse, nullObject, prefix, pushField, redirect, refTargets, replaceUrlPath, requestId, rootSnapshot, schemaProperties, serializeMacroSeed, sse, sseData, throwLifecycleErrors };
232
+ export { ChainInfo, ChainNode, CompactBeforeHandleChunk, CompactBeforeHandlePrefix, DeriveEntry, ELYSIA_FORM_PROTOTYPE, assignOwn, authorityEnd, bytes, clearFlattenChainMemo, cloneHook, clonePlainDecorators, clonePlainDeep, coalesceSchemas, compactBeforeHandleConflicts, compactBeforeHandlePrefix, compositionKeys, constantTimeEqual, createErrorEventHandler, deriveEntryFn, deriveQueues, eventProperties, evictOldestHalf, flattenChain, flattenChainInfo, flattenChainMemo, flattenChainMemoReadonly, fnv1a, form, formToFormData, getLoosePath, guardNonPlainLeaves, hookToGuard, invalidateMacroEpoch, isBlob, isByteStream, isCompactBeforeHandleOnly, isDisposable, isElysiaForm, isEmpty, isHTMLBundle, isMapDeriveEntry, isNotEmpty, isPlainDeriveEntry, isPlainObject, isRecordNumber, isSingleton, isSocketQuiet, joinPath, macroEpoch, macroOrigin, macroType, mapDeriveEntry, markPropertySingletons, markSingletons, mergeArray, mergeDeep, mergeHook, mergeResponse, nullObject, occurrenceDeriveEntries, pluginHash, pluginId, prefix, redirect, refTargets, replaceUrlPath, requestId, schemaProperties, serializeMacroSeed, sse, sseData, throwLifecycleErrors };