elysia 2.0.0-beta.21 → 2.0.0-beta.23

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 (217) 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 +214 -194
  20. package/dist/base.mjs +221 -200
  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 +78 -118
  37. package/dist/compile/handler/index.mjs +84 -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.d.ts +1 -1
  96. package/dist/plugin/aot/core.js +7 -4
  97. package/dist/plugin/aot/core.mjs +8 -5
  98. package/dist/plugin/aot/esbuild.mjs +1 -0
  99. package/dist/plugin/aot/rspack-loader.mjs +1 -0
  100. package/dist/plugin/aot/rspack.mjs +1 -0
  101. package/dist/plugin/aot/treeshake.mjs +1 -0
  102. package/dist/plugin/aot/unplugin.mjs +4 -3
  103. package/dist/plugin/aot/vite.mjs +1 -0
  104. package/dist/plugin/aot/worker.mjs +1 -0
  105. package/dist/plugin/auto-head.mjs +1 -0
  106. package/dist/plugin/trace.mjs +1 -0
  107. package/dist/plugin/websocket.mjs +1 -0
  108. package/dist/route-table.mjs +1 -0
  109. package/dist/schema-snapshot.js +28 -3
  110. package/dist/schema-snapshot.mjs +29 -3
  111. package/dist/sucrose.d.ts +2 -2
  112. package/dist/sucrose.js +11 -11
  113. package/dist/sucrose.mjs +12 -11
  114. package/dist/trace.js +8 -10
  115. package/dist/trace.mjs +10 -11
  116. package/dist/type/bridge-live.d.ts +1 -1
  117. package/dist/type/bridge-live.mjs +1 -0
  118. package/dist/type/bridge.d.ts +1 -1
  119. package/dist/type/bridge.mjs +1 -0
  120. package/dist/type/coerce-plan.mjs +1 -0
  121. package/dist/type/coerce.d.ts +1 -1
  122. package/dist/type/coerce.mjs +1 -0
  123. package/dist/type/compat.mjs +1 -0
  124. package/dist/type/constants.d.ts +1 -1
  125. package/dist/type/constants.mjs +1 -0
  126. package/dist/type/elysia/accelerate.mjs +1 -0
  127. package/dist/type/elysia/array-buffer.d.ts +3 -2
  128. package/dist/type/elysia/array-buffer.js +5 -5
  129. package/dist/type/elysia/array-buffer.mjs +6 -5
  130. package/dist/type/elysia/array-string.mjs +1 -0
  131. package/dist/type/elysia/array.mjs +1 -0
  132. package/dist/type/elysia/boolean-string.mjs +1 -0
  133. package/dist/type/elysia/boolean.mjs +1 -0
  134. package/dist/type/elysia/cookie.mjs +1 -0
  135. package/dist/type/elysia/date.mjs +1 -0
  136. package/dist/type/elysia/file-type.mjs +1 -0
  137. package/dist/type/elysia/file.mjs +1 -0
  138. package/dist/type/elysia/files.mjs +1 -0
  139. package/dist/type/elysia/form.mjs +1 -0
  140. package/dist/type/elysia/integer-string.mjs +1 -0
  141. package/dist/type/elysia/integer.mjs +1 -0
  142. package/dist/type/elysia/intersect.mjs +1 -0
  143. package/dist/type/elysia/json-string.mjs +1 -0
  144. package/dist/type/elysia/keep-config.js +8 -8
  145. package/dist/type/elysia/keep-config.mjs +9 -8
  146. package/dist/type/elysia/maybe-empty.mjs +1 -0
  147. package/dist/type/elysia/no-validate.mjs +1 -0
  148. package/dist/type/elysia/nullable.mjs +1 -0
  149. package/dist/type/elysia/number.mjs +1 -0
  150. package/dist/type/elysia/numeric-enum.d.ts +4 -2
  151. package/dist/type/elysia/numeric-enum.mjs +1 -0
  152. package/dist/type/elysia/numeric.mjs +1 -0
  153. package/dist/type/elysia/object-string.mjs +1 -0
  154. package/dist/type/elysia/object.mjs +1 -0
  155. package/dist/type/elysia/optional.mjs +1 -0
  156. package/dist/type/elysia/problem.mjs +1 -0
  157. package/dist/type/elysia/string.mjs +1 -0
  158. package/dist/type/elysia/uint8-array.d.ts +2 -1
  159. package/dist/type/elysia/uint8-array.js +2 -2
  160. package/dist/type/elysia/uint8-array.mjs +3 -2
  161. package/dist/type/elysia/union-enum.mjs +1 -0
  162. package/dist/type/elysia/union.mjs +1 -0
  163. package/dist/type/elysia/utils.js +3 -3
  164. package/dist/type/elysia/utils.mjs +4 -3
  165. package/dist/type/exports.mjs +1 -0
  166. package/dist/type/index.mjs +2 -1
  167. package/dist/type/shared.mjs +1 -0
  168. package/dist/type/sync-require.mjs +1 -0
  169. package/dist/type/typebox-system-lite.mjs +1 -0
  170. package/dist/type/typebox-system-require.mjs +1 -0
  171. package/dist/type/typebox-type-live.mjs +1 -0
  172. package/dist/type/typebox-value-live.mjs +1 -0
  173. package/dist/type/typebox-value-ops.mjs +1 -0
  174. package/dist/type/typebox-value.mjs +1 -0
  175. package/dist/type/types.d.ts +1 -1
  176. package/dist/type/types.mjs +1 -0
  177. package/dist/type/utils.mjs +1 -0
  178. package/dist/type/validator/clean-safe.mjs +1 -0
  179. package/dist/type/validator/custom-error.js +41 -33
  180. package/dist/type/validator/custom-error.mjs +42 -33
  181. package/dist/type/validator/default-precompute.d.ts +2 -2
  182. package/dist/type/validator/default-precompute.js +10 -11
  183. package/dist/type/validator/default-precompute.mjs +13 -13
  184. package/dist/type/validator/exact-mirror.mjs +1 -0
  185. package/dist/type/validator/frozen-check.js +7 -7
  186. package/dist/type/validator/frozen-check.mjs +8 -7
  187. package/dist/type/validator/index.d.ts +2 -2
  188. package/dist/type/validator/index.js +4 -8
  189. package/dist/type/validator/index.mjs +5 -8
  190. package/dist/type/validator/string-codec-aot.d.ts +1 -1
  191. package/dist/type/validator/string-codec-aot.mjs +1 -0
  192. package/dist/type/validator/validator-cache.js +18 -18
  193. package/dist/type/validator/validator-cache.mjs +19 -18
  194. package/dist/types.d.ts +108 -70
  195. package/dist/types.mjs +1 -0
  196. package/dist/universal/constants.mjs +1 -0
  197. package/dist/universal/file.mjs +1 -0
  198. package/dist/universal/index.mjs +1 -0
  199. package/dist/universal/is-production.mjs +1 -0
  200. package/dist/universal/server.mjs +1 -0
  201. package/dist/utils.d.ts +49 -31
  202. package/dist/utils.js +221 -109
  203. package/dist/utils.mjs +215 -106
  204. package/dist/validator/index.d.ts +3 -3
  205. package/dist/validator/index.js +4 -4
  206. package/dist/validator/index.mjs +5 -4
  207. package/dist/validator/route.d.ts +2 -2
  208. package/dist/validator/route.mjs +1 -0
  209. package/dist/ws/context.js +1 -1
  210. package/dist/ws/context.mjs +2 -1
  211. package/dist/ws/index.mjs +1 -0
  212. package/dist/ws/parser.mjs +1 -0
  213. package/dist/ws/route.js +34 -25
  214. package/dist/ws/route.mjs +40 -30
  215. package/dist/ws/types.d.ts +2 -3
  216. package/dist/ws/types.mjs +1 -0
  217. package/package.json +2 -2
@@ -1,7 +1,8 @@
1
+ // @bun
1
2
  import { StatusMap } from "../constants.mjs";
2
3
  import { isNotEmpty } from "../utils.mjs";
3
4
  import { isProduction } from "../universal/is-production.mjs";
4
- import { ElysiaStatus, HTTPError, NotFound, PROBLEM_JSON, ValidationError, internalServerErrorResponse, problemBody } from "../error.mjs";
5
+ import { ElysiaStatus, HTTPError, NotFound, PROBLEM_JSON, ValidationError, internalServerErrorResponse, problemBody, titleOf } from "../error.mjs";
5
6
  import { materializeSetHeaders } from "../adapter/utils.mjs";
6
7
  import { parseQueryFromURL } from "../parse-query.mjs";
7
8
  import { getNotFound, hasAsync } from "./utils.mjs";
@@ -30,14 +31,21 @@ function parseQuery(context) {
30
31
  });
31
32
  }
32
33
  const isPristineNotFound = (context, error) => error instanceof NotFound && error.response === "Not Found" && !context.set.cookie && !isNotEmpty(context.set.headers);
33
- const claimsProblemType = (error) => typeof error?.type === "string" ? !(error instanceof ValidationError) && error.constructor?.name !== "ValidationError" : error instanceof HTTPError;
34
+ /**
35
+ * Whether an error claims a problem type, judged on `type` as the caller
36
+ * read it once: a getter read again could answer anything else, `undefined`
37
+ * included
38
+ */
39
+ const claimsProblemType = (error, type) => typeof type === "string" ? !(error instanceof ValidationError) && error.constructor?.name !== "ValidationError" : error instanceof HTTPError;
34
40
  function adoptErrorType(result, error) {
35
41
  const body = result?.response;
36
- if (typeof error?.type !== "string" || !claimsProblemType(error) || body?.type !== "about:blank" || result.headers?.["content-type"] !== "application/problem+json") return result;
42
+ const type = error?.type;
43
+ if (typeof type !== "string" || !claimsProblemType(error, type) || body?.type !== "about:blank" || result.headers?.["content-type"] !== "application/problem+json") return result;
44
+ const code = error.code;
37
45
  return new ElysiaStatus(result.status, {
38
46
  ...body,
39
- type: error.type,
40
- ...typeof error.code === "string" ? { code: error.code } : {}
47
+ type,
48
+ ...typeof code === "string" ? { code } : {}
41
49
  }, result.headers);
42
50
  }
43
51
  /**
@@ -54,38 +62,35 @@ function fallbackResponse(context, error, mapResponse) {
54
62
  } catch {}
55
63
  return fallbackErrorResponse(context, error, mapResponse);
56
64
  }
57
- /**
58
- * Numeric form of an annotated status, which may be written as a name.
59
- * A numeric string keeps coercing so the production mask below can't be
60
- * slipped past with `'502'`
61
- */
62
65
  const resolveStatus = (status) => typeof status === "string" ? StatusMap[status] ?? +status : status;
63
66
  /**
64
67
  * Body served by an error that carries a status but no usable body:
65
- * its declared `response`, otherwise its message
68
+ * its declared `response`, otherwise its message, or `mask` in its place
69
+ * on a production 5xx
66
70
  */
67
- function statusFallbackBody(error, status) {
71
+ function statusFallbackBody(error, status, mask = "Internal Server Error") {
68
72
  const masked = isProduction() && status >= 500;
69
73
  const declared = error.response;
70
- return declared !== void 0 && !(masked && typeof declared === "object") ? declared : masked ? "Internal Server Error" : error.message ?? "";
74
+ return declared !== void 0 && !(masked && typeof declared === "object") ? declared : masked ? mask : error.message ?? "";
71
75
  }
72
76
  /**
73
77
  * RFC 9457 problem document carrying `detail` verbatim, mirroring `problem()`.
78
+ * `type` comes in as the value the claim was checked on, and `code` is read
79
+ * once, so a getter can't put anything but a string on the wire
74
80
  */
75
- const problemOf = (self, detail, status, claimsProblem) => new ElysiaStatus(status, problemBody({
76
- type: self.type ?? "about:blank",
77
- ...claimsProblem && typeof self.code === "string" ? { code: self.code } : {},
78
- detail,
79
- status
80
- }), { "content-type": PROBLEM_JSON });
81
+ const problemOf = (self, type, detail, status, claimsProblem) => {
82
+ const code = claimsProblem ? self.code : void 0;
83
+ return new ElysiaStatus(status, problemBody({
84
+ type: typeof type === "string" ? type : "about:blank",
85
+ ...typeof code === "string" ? { code } : {},
86
+ detail,
87
+ status
88
+ }), { "content-type": PROBLEM_JSON });
89
+ };
81
90
  /**
82
- * Read one annotation knob.
83
- *
84
- * Both knobs are canonically methods, so they're evaluated per serve and may
85
- * be `async`. Running a stranger's function is side-effect surface (it may
86
- * consume a stream or do IO), so it takes the same problem claim the shaping
87
- * does — an unclaimed duck error never invokes one. A *value* annotation stays
88
- * inert data and keeps duck-participating as it always has
91
+ * Read one annotation knob, a method (may be `async`) or a plain value.
92
+ * A method may have side effects, so only an error claiming a problem type
93
+ * gets it invoked; a plain value is read from any error
89
94
  */
90
95
  const readAnnotation = (self, key, claimsProblem) => {
91
96
  const annotation = self[key];
@@ -97,7 +102,8 @@ function fallbackErrorResponse(context, error, mapResponse) {
97
102
  const self = error ?? {};
98
103
  const status = resolveStatus(self.status);
99
104
  const owned = error instanceof HTTPError;
100
- const claimsProblem = claimsProblemType(error);
105
+ const type = self.type;
106
+ const claimsProblem = claimsProblemType(error, type);
101
107
  const served = typeof status === "number" ? status : resolveStatus(context.set.status);
102
108
  const failed = (cause) => {
103
109
  context.set.status = 500;
@@ -108,32 +114,29 @@ function fallbackErrorResponse(context, error, mapResponse) {
108
114
  }
109
115
  const legacy = () => {
110
116
  if (error?.status) return mapResponse(statusFallbackBody(error, status), context.set, context);
111
- if (error?.message != null) {
112
- if (context.set.status === void 0 || context.set.status === 200) context.set.status = 500;
113
- return mapResponse(internalServerErrorResponse(error), context.set, context);
114
- }
117
+ if (error?.message != null && (context.set.status === void 0 || context.set.status === 200)) context.set.status = 500;
115
118
  return mapResponse(internalServerErrorResponse(error), context.set, context);
116
119
  };
117
120
  const serveMessage = () => {
118
121
  if (!claimsProblem) return legacy();
119
122
  mergeHeaders();
120
- return mapResponse(problemOf(self, statusFallbackBody(error, served), served, claimsProblem), context.set, context);
123
+ return mapResponse(problemOf(self, type, statusFallbackBody(error, served, titleOf(served)), served, claimsProblem), context.set, context);
121
124
  };
122
- const tier = (key) => {
125
+ const serveAnnotation = (key) => {
123
126
  let annotation;
124
127
  try {
125
128
  annotation = readAnnotation(self, key, claimsProblem);
126
129
  } catch (cause) {
127
130
  return failed(cause);
128
131
  }
129
- if (annotation === void 0) return key === "value" ? tier("detail") : serveMessage();
132
+ if (annotation === void 0) return key === "value" ? serveAnnotation("detail") : serveMessage();
130
133
  if (annotation instanceof Promise) return annotation.then((resolved) => {
131
- if (resolved === void 0) return key === "value" ? tier("detail") : serveMessage();
134
+ if (resolved === void 0) return key === "value" ? serveAnnotation("detail") : serveMessage();
132
135
  mergeHeaders();
133
- return mapResponse(key === "value" ? resolved : problemOf(self, resolved, served, claimsProblem), context.set, context);
136
+ return mapResponse(key === "value" ? resolved : problemOf(self, type, resolved, served, claimsProblem), context.set, context);
134
137
  }, failed);
135
138
  mergeHeaders();
136
- return mapResponse(key === "value" ? annotation : problemOf(self, annotation, served, claimsProblem), context.set, context);
139
+ return mapResponse(key === "value" ? annotation : problemOf(self, type, annotation, served, claimsProblem), context.set, context);
137
140
  };
138
141
  if (error instanceof ValidationError) return mapResponse(error.type === "response" ? internalServerErrorResponse(void 0) : new ElysiaStatus(422, problemBody({
139
142
  type: "validation",
@@ -141,7 +144,8 @@ function fallbackErrorResponse(context, error, mapResponse) {
141
144
  title: "Validation Error",
142
145
  status: 422
143
146
  }), { "content-type": PROBLEM_JSON }), context.set, context);
144
- if (owned || error instanceof Error && typeof status === "number" && status >= 100 && !(isProduction() && status >= 500)) return tier("value");
147
+ if (owned || error instanceof Error && typeof status === "number" && status >= 100 && !(isProduction() && status >= 500)) return serveAnnotation("value");
148
+ if (claimsProblem && error instanceof Error && typeof status === "number" && status >= 500) return mapResponse(problemOf(self, type, titleOf(status), status, false), context.set, context);
145
149
  return legacy();
146
150
  }
147
151
  function applyErrorStatus(context, error) {
@@ -165,7 +169,7 @@ function createErrorHandler(onErrors, mapResponse, allowUnsafe = false) {
165
169
  else if (context.set.status === void 0 || context.set.status === 200) context.set.status = 500;
166
170
  return mapWith(sign)(adoptErrorType(result, error), context.set, context);
167
171
  };
168
- const settle = (context, error, sign) => isPristineNotFound(context, error) ? getNotFound() : fallbackResponse(context, error, mapWith(sign));
172
+ const serveUnhandled = (context, error, sign) => isPristineNotFound(context, error) ? getNotFound() : fallbackResponse(context, error, mapWith(sign));
169
173
  if (hasAsync(onErrors)) return async (context, error, sign) => {
170
174
  materializeSetHeaders(context.set);
171
175
  enter(context, error);
@@ -174,7 +178,7 @@ function createErrorHandler(onErrors, mapResponse, allowUnsafe = false) {
174
178
  if (typeof result?.then === "function") result = await result;
175
179
  if (result !== void 0) return respond(context, error, result, sign);
176
180
  }
177
- return settle(context, error, sign);
181
+ return serveUnhandled(context, error, sign);
178
182
  };
179
183
  return (context, error, sign) => {
180
184
  materializeSetHeaders(context.set);
@@ -183,7 +187,7 @@ function createErrorHandler(onErrors, mapResponse, allowUnsafe = false) {
183
187
  const result = onErrors[i](context);
184
188
  if (result !== void 0) return respond(context, error, result, sign);
185
189
  }
186
- return settle(context, error, sign);
190
+ return serveUnhandled(context, error, sign);
187
191
  };
188
192
  }
189
193
 
@@ -69,7 +69,7 @@ function dispatchResult(result, context, handleError, afterResponse) {
69
69
  if (typeof result?.then === "function") return Promise.resolve(result).catch(catchError(context, handleError, afterResponse));
70
70
  return result;
71
71
  }
72
- function findRoute(context, request, map, router, hasError, handleError, afterResponse, strictPath, hasWS, hasDynamicWS) {
72
+ function findRoute(context, request, map, router, onNotFound, handleError, afterResponse, strictPath, hasWS, hasDynamicWS, app) {
73
73
  const path = context.path;
74
74
  const method = request.method;
75
75
  if (hasWS && method === "GET") {
@@ -98,11 +98,11 @@ function findRoute(context, request, map, router, hasError, handleError, afterRe
98
98
  const found = router?.find(method, path) ?? router?.find("*", path);
99
99
  if (found) {
100
100
  context.params = path.indexOf("%") === -1 ? found.params : decodeParams(found.params);
101
- return dispatchResult(found.store(context), context, handleError, afterResponse);
101
+ const store = found.store;
102
+ const dynamic = typeof store === "number" ? app["compiled"]?.[store] : store;
103
+ return dispatchResult(dynamic ? dynamic(context) : app["~dispatch"](store, context), context, handleError, afterResponse);
102
104
  }
103
- if (hasError) return finalizeError(context, handleError, afterResponse, new require_error.NotFound());
104
- afterResponse?.(context, 404);
105
- return notFound(context);
105
+ return onNotFound(context);
106
106
  }
107
107
  function createFetchHandler(app) {
108
108
  const Context = require_context.createContext(app);
@@ -143,8 +143,8 @@ function createFetchHandler(app) {
143
143
  } catch {}
144
144
  return pending ? pending.then(() => baseMapResponse(response, set, request, true), () => baseMapResponse(response, set, request, true)) : baseMapResponse(response, set, request, true);
145
145
  }
146
- const mapResponseHooks = hook?.mapResponse;
147
- const mapResponse = mapResponseHooks?.length ? (response, set, context, sign) => {
146
+ const plainMap = (response, set, context, sign) => finalMap(response, set, context?.request, sign);
147
+ function mapWithHooks(mapResponseHooks, response, set, context, sign) {
148
148
  if (!context) return baseMapResponse(response, set, void 0, true);
149
149
  context.responseValue = response;
150
150
  const request = context.request;
@@ -160,8 +160,12 @@ function createFetchHandler(app) {
160
160
  return finalMap(response, set, request, sign);
161
161
  };
162
162
  return run(0);
163
- } : (response, set, context, sign) => finalMap(response, set, context?.request, sign);
164
- const handleError = require_handler_error.createErrorHandler(hook?.error, mapResponse, app["~config"]?.allowUnsafeValidationDetails);
163
+ }
164
+ const mapResponseHooks = hook?.mapResponse;
165
+ const mapResponse = mapResponseHooks?.length ? mapWithHooks.bind(null, mapResponseHooks) : plainMap;
166
+ const allowUnsafe = app["~config"]?.allowUnsafeValidationDetails;
167
+ const handleError = require_handler_error.createErrorHandler(hook?.error, mapResponse, allowUnsafe);
168
+ const handleRouteError = hook?.error || mapResponseHooks?.length ? require_handler_error.createErrorHandler(void 0, plainMap, allowUnsafe) : handleError;
165
169
  const traceHandlers = hook?.trace;
166
170
  const hasTrace = !!traceHandlers?.length;
167
171
  const traceProvider = hasTrace ? app["~resolvedCapability"]("trace") : void 0;
@@ -169,8 +173,7 @@ function createFetchHandler(app) {
169
173
  const traceRequestPhase = hasTrace && (tracePhases === null || tracePhases.has("request"));
170
174
  const traceAfterResponsePhase = hasTrace && (tracePhases === null || tracePhases.has("afterResponse"));
171
175
  const tracerFactories = hasTrace ? traceHandlers.map((fn) => traceProvider.createTracer(fn)) : void 0;
172
- const afterResponses = hook?.afterResponse;
173
- const afterResponse = (context, status) => {
176
+ const afterResponse = (context, status, afterResponses = hook?.afterResponse) => {
174
177
  if (context._arf) return;
175
178
  const queue = context["~afterResponse"];
176
179
  if (!afterResponses?.length && !traceAfterResponsePhase && !queue?.length && !context["~dispose"]) return;
@@ -182,7 +185,7 @@ function createFetchHandler(app) {
182
185
  let reports;
183
186
  if (traceAfterResponsePhase) {
184
187
  cache = context.trace;
185
- if (!cache && tracerFactories) {
188
+ if (!cache && tracerFactories && afterResponses !== null) {
186
189
  context.rid ??= require_utils.requestId();
187
190
  cache = tracerFactories.map((f) => f(context));
188
191
  context.trace = cache;
@@ -218,7 +221,36 @@ function createFetchHandler(app) {
218
221
  });
219
222
  };
220
223
  const fail = (context, error, sign) => finalizeError(context, handleError, afterResponse, error, sign);
221
- app["~finalizeError"] = fail;
224
+ const routeAfterResponse = (context, status) => afterResponse(context, status, null);
225
+ const failRoute = (context, error, sign) => finalizeError(context, handleRouteError, routeAfterResponse, error, sign);
226
+ const routeHandlers = /* @__PURE__ */ new WeakMap();
227
+ app["~finalizeError"] = (context, error, sign, wholeChain, route) => {
228
+ if (wholeChain) return fail(context, error, sign);
229
+ if (!route) return failRoute(context, error, sign);
230
+ let handle = routeHandlers.get(route);
231
+ if (!handle) {
232
+ const withHooks = require_handler_error.createErrorHandler(route.error?.length ? route.error : void 0, route.mapResponse?.length ? mapWithHooks.bind(null, route.mapResponse) : plainMap, allowUnsafe);
233
+ handle = (context, error, sign) => {
234
+ const set = context.set;
235
+ const end = () => handleRouteError(context, set["~signFailed"] ? new require_error.InternalServerError() : error, sign);
236
+ if (set["~signFailed"]) return end();
237
+ const signed = (r) => set["~signFailed"] ? end() : r;
238
+ try {
239
+ const response = withHooks(context, error, sign);
240
+ return response instanceof Promise ? response.then(signed, end) : signed(response);
241
+ } catch {
242
+ return end();
243
+ }
244
+ };
245
+ routeHandlers.set(route, handle);
246
+ }
247
+ return finalizeError(context, handle, routeAfterResponse, error, sign);
248
+ };
249
+ const onNotFound = (context) => {
250
+ if (hasError) return finalizeError(context, handleError, afterResponse, new require_error.NotFound());
251
+ afterResponse(context, 404);
252
+ return notFound(context);
253
+ };
222
254
  if (traceRequestPhase) {
223
255
  const onRequests = hook?.request ?? [];
224
256
  return async (request, server) => {
@@ -240,6 +272,7 @@ function createFetchHandler(app) {
240
272
  begin: performance.now(),
241
273
  total: onRequests.length
242
274
  });
275
+ let routed = false;
243
276
  try {
244
277
  const endReports = new Array(traceLength);
245
278
  for (let i = 0; i < onRequests.length; i++) {
@@ -268,10 +301,11 @@ function createFetchHandler(app) {
268
301
  }
269
302
  }
270
303
  for (let i = 0; i < traceLength; i++) trace[i].r(requestReports[i]);
271
- return await findRoute(context, request, map, router, hasError, handleError, afterResponse, strictPath, hasWS, hasDynamicWS);
304
+ routed = true;
305
+ return await findRoute(context, request, map, router, onNotFound, handleRouteError, routeAfterResponse, strictPath, hasWS, hasDynamicWS, app);
272
306
  } catch (error) {
273
307
  for (let i = 0; i < traceLength; i++) trace[i].r(requestReports[i], error);
274
- return fail(context, error);
308
+ return (routed ? failRoute : fail)(context, error);
275
309
  }
276
310
  };
277
311
  }
@@ -283,6 +317,7 @@ function createFetchHandler(app) {
283
317
  if (armEager(request, context)) return require_handler_utils.emptyResponse.clone();
284
318
  const path = extractPath(request.url, context);
285
319
  context.server = server ?? null;
320
+ let routed = false;
286
321
  try {
287
322
  for (let i = 0; i < onRequests.length; i++) {
288
323
  let result = onRequests[i](context);
@@ -298,9 +333,10 @@ function createFetchHandler(app) {
298
333
  return response;
299
334
  }
300
335
  }
301
- return findRoute(context, request, map, router, hasError, handleError, afterResponse, strictPath, hasWS, hasDynamicWS);
336
+ routed = true;
337
+ return findRoute(context, request, map, router, onNotFound, handleRouteError, routeAfterResponse, strictPath, hasWS, hasDynamicWS, app);
302
338
  } catch (error) {
303
- return fail(context, error);
339
+ return (routed ? failRoute : fail)(context, error);
304
340
  }
305
341
  };
306
342
  return (request, server) => {
@@ -309,6 +345,7 @@ function createFetchHandler(app) {
309
345
  if (armEager(request, context)) return require_handler_utils.emptyResponse.clone();
310
346
  const path = extractPath(request.url, context);
311
347
  context.server = server ?? null;
348
+ let routed = false;
312
349
  try {
313
350
  for (let i = 0; i < onRequests.length; i++) {
314
351
  const result = onRequests[i](context);
@@ -324,9 +361,10 @@ function createFetchHandler(app) {
324
361
  return response;
325
362
  }
326
363
  }
327
- return findRoute(context, request, map, router, hasError, handleError, afterResponse, strictPath, hasWS, hasDynamicWS);
364
+ routed = true;
365
+ return findRoute(context, request, map, router, onNotFound, handleRouteError, routeAfterResponse, strictPath, hasWS, hasDynamicWS, app);
328
366
  } catch (error) {
329
- return fail(context, error);
367
+ return (routed ? failRoute : fail)(context, error);
330
368
  }
331
369
  };
332
370
  }
@@ -335,9 +373,9 @@ function createFetchHandler(app) {
335
373
  extractPath(request.url, context);
336
374
  context.server = server ?? null;
337
375
  try {
338
- return findRoute(context, request, map, router, hasError, handleError, afterResponse, strictPath, hasWS, hasDynamicWS);
376
+ return findRoute(context, request, map, router, onNotFound, handleRouteError, routeAfterResponse, strictPath, hasWS, hasDynamicWS, app);
339
377
  } catch (error) {
340
- return fail(context, error);
378
+ return failRoute(context, error);
341
379
  }
342
380
  };
343
381
  }
@@ -1,6 +1,7 @@
1
+ // @bun
1
2
  import { authorityEnd, flattenChain, isNotEmpty, nullObject, requestId } from "../utils.mjs";
2
3
  import { isProduction } from "../universal/is-production.mjs";
3
- import { NotFound, PROBLEM_JSON, internalServerErrorResponse } from "../error.mjs";
4
+ import { InternalServerError, NotFound, PROBLEM_JSON, internalServerErrorResponse } from "../error.mjs";
4
5
  import { handleSet, materializeSetHeaders } from "../adapter/utils.mjs";
5
6
  import { drainDisposables, emptyResponse, getNotFound, getNotFoundBody, hasAsync } from "./utils.mjs";
6
7
  import { createErrorHandler } from "./error.mjs";
@@ -66,7 +67,7 @@ function dispatchResult(result, context, handleError, afterResponse) {
66
67
  if (typeof result?.then === "function") return Promise.resolve(result).catch(catchError(context, handleError, afterResponse));
67
68
  return result;
68
69
  }
69
- function findRoute(context, request, map, router, hasError, handleError, afterResponse, strictPath, hasWS, hasDynamicWS) {
70
+ function findRoute(context, request, map, router, onNotFound, handleError, afterResponse, strictPath, hasWS, hasDynamicWS, app) {
70
71
  const path = context.path;
71
72
  const method = request.method;
72
73
  if (hasWS && method === "GET") {
@@ -95,11 +96,11 @@ function findRoute(context, request, map, router, hasError, handleError, afterRe
95
96
  const found = router?.find(method, path) ?? router?.find("*", path);
96
97
  if (found) {
97
98
  context.params = path.indexOf("%") === -1 ? found.params : decodeParams(found.params);
98
- return dispatchResult(found.store(context), context, handleError, afterResponse);
99
+ const store = found.store;
100
+ const dynamic = typeof store === "number" ? app["compiled"]?.[store] : store;
101
+ return dispatchResult(dynamic ? dynamic(context) : app["~dispatch"](store, context), context, handleError, afterResponse);
99
102
  }
100
- if (hasError) return finalizeError(context, handleError, afterResponse, new NotFound());
101
- afterResponse?.(context, 404);
102
- return notFound(context);
103
+ return onNotFound(context);
103
104
  }
104
105
  function createFetchHandler(app) {
105
106
  const Context = createContext(app);
@@ -140,8 +141,8 @@ function createFetchHandler(app) {
140
141
  } catch {}
141
142
  return pending ? pending.then(() => baseMapResponse(response, set, request, true), () => baseMapResponse(response, set, request, true)) : baseMapResponse(response, set, request, true);
142
143
  }
143
- const mapResponseHooks = hook?.mapResponse;
144
- const mapResponse = mapResponseHooks?.length ? (response, set, context, sign) => {
144
+ const plainMap = (response, set, context, sign) => finalMap(response, set, context?.request, sign);
145
+ function mapWithHooks(mapResponseHooks, response, set, context, sign) {
145
146
  if (!context) return baseMapResponse(response, set, void 0, true);
146
147
  context.responseValue = response;
147
148
  const request = context.request;
@@ -157,8 +158,12 @@ function createFetchHandler(app) {
157
158
  return finalMap(response, set, request, sign);
158
159
  };
159
160
  return run(0);
160
- } : (response, set, context, sign) => finalMap(response, set, context?.request, sign);
161
- const handleError = createErrorHandler(hook?.error, mapResponse, app["~config"]?.allowUnsafeValidationDetails);
161
+ }
162
+ const mapResponseHooks = hook?.mapResponse;
163
+ const mapResponse = mapResponseHooks?.length ? mapWithHooks.bind(null, mapResponseHooks) : plainMap;
164
+ const allowUnsafe = app["~config"]?.allowUnsafeValidationDetails;
165
+ const handleError = createErrorHandler(hook?.error, mapResponse, allowUnsafe);
166
+ const handleRouteError = hook?.error || mapResponseHooks?.length ? createErrorHandler(void 0, plainMap, allowUnsafe) : handleError;
162
167
  const traceHandlers = hook?.trace;
163
168
  const hasTrace = !!traceHandlers?.length;
164
169
  const traceProvider = hasTrace ? app["~resolvedCapability"]("trace") : void 0;
@@ -166,8 +171,7 @@ function createFetchHandler(app) {
166
171
  const traceRequestPhase = hasTrace && (tracePhases === null || tracePhases.has("request"));
167
172
  const traceAfterResponsePhase = hasTrace && (tracePhases === null || tracePhases.has("afterResponse"));
168
173
  const tracerFactories = hasTrace ? traceHandlers.map((fn) => traceProvider.createTracer(fn)) : void 0;
169
- const afterResponses = hook?.afterResponse;
170
- const afterResponse = (context, status) => {
174
+ const afterResponse = (context, status, afterResponses = hook?.afterResponse) => {
171
175
  if (context._arf) return;
172
176
  const queue = context["~afterResponse"];
173
177
  if (!afterResponses?.length && !traceAfterResponsePhase && !queue?.length && !context["~dispose"]) return;
@@ -179,7 +183,7 @@ function createFetchHandler(app) {
179
183
  let reports;
180
184
  if (traceAfterResponsePhase) {
181
185
  cache = context.trace;
182
- if (!cache && tracerFactories) {
186
+ if (!cache && tracerFactories && afterResponses !== null) {
183
187
  context.rid ??= requestId();
184
188
  cache = tracerFactories.map((f) => f(context));
185
189
  context.trace = cache;
@@ -215,7 +219,36 @@ function createFetchHandler(app) {
215
219
  });
216
220
  };
217
221
  const fail = (context, error, sign) => finalizeError(context, handleError, afterResponse, error, sign);
218
- app["~finalizeError"] = fail;
222
+ const routeAfterResponse = (context, status) => afterResponse(context, status, null);
223
+ const failRoute = (context, error, sign) => finalizeError(context, handleRouteError, routeAfterResponse, error, sign);
224
+ const routeHandlers = /* @__PURE__ */ new WeakMap();
225
+ app["~finalizeError"] = (context, error, sign, wholeChain, route) => {
226
+ if (wholeChain) return fail(context, error, sign);
227
+ if (!route) return failRoute(context, error, sign);
228
+ let handle = routeHandlers.get(route);
229
+ if (!handle) {
230
+ const withHooks = createErrorHandler(route.error?.length ? route.error : void 0, route.mapResponse?.length ? mapWithHooks.bind(null, route.mapResponse) : plainMap, allowUnsafe);
231
+ handle = (context, error, sign) => {
232
+ const set = context.set;
233
+ const end = () => handleRouteError(context, set["~signFailed"] ? new InternalServerError() : error, sign);
234
+ if (set["~signFailed"]) return end();
235
+ const signed = (r) => set["~signFailed"] ? end() : r;
236
+ try {
237
+ const response = withHooks(context, error, sign);
238
+ return response instanceof Promise ? response.then(signed, end) : signed(response);
239
+ } catch {
240
+ return end();
241
+ }
242
+ };
243
+ routeHandlers.set(route, handle);
244
+ }
245
+ return finalizeError(context, handle, routeAfterResponse, error, sign);
246
+ };
247
+ const onNotFound = (context) => {
248
+ if (hasError) return finalizeError(context, handleError, afterResponse, new NotFound());
249
+ afterResponse(context, 404);
250
+ return notFound(context);
251
+ };
219
252
  if (traceRequestPhase) {
220
253
  const onRequests = hook?.request ?? [];
221
254
  return async (request, server) => {
@@ -237,6 +270,7 @@ function createFetchHandler(app) {
237
270
  begin: performance.now(),
238
271
  total: onRequests.length
239
272
  });
273
+ let routed = false;
240
274
  try {
241
275
  const endReports = new Array(traceLength);
242
276
  for (let i = 0; i < onRequests.length; i++) {
@@ -265,10 +299,11 @@ function createFetchHandler(app) {
265
299
  }
266
300
  }
267
301
  for (let i = 0; i < traceLength; i++) trace[i].r(requestReports[i]);
268
- return await findRoute(context, request, map, router, hasError, handleError, afterResponse, strictPath, hasWS, hasDynamicWS);
302
+ routed = true;
303
+ return await findRoute(context, request, map, router, onNotFound, handleRouteError, routeAfterResponse, strictPath, hasWS, hasDynamicWS, app);
269
304
  } catch (error) {
270
305
  for (let i = 0; i < traceLength; i++) trace[i].r(requestReports[i], error);
271
- return fail(context, error);
306
+ return (routed ? failRoute : fail)(context, error);
272
307
  }
273
308
  };
274
309
  }
@@ -280,6 +315,7 @@ function createFetchHandler(app) {
280
315
  if (armEager(request, context)) return emptyResponse.clone();
281
316
  const path = extractPath(request.url, context);
282
317
  context.server = server ?? null;
318
+ let routed = false;
283
319
  try {
284
320
  for (let i = 0; i < onRequests.length; i++) {
285
321
  let result = onRequests[i](context);
@@ -295,9 +331,10 @@ function createFetchHandler(app) {
295
331
  return response;
296
332
  }
297
333
  }
298
- return findRoute(context, request, map, router, hasError, handleError, afterResponse, strictPath, hasWS, hasDynamicWS);
334
+ routed = true;
335
+ return findRoute(context, request, map, router, onNotFound, handleRouteError, routeAfterResponse, strictPath, hasWS, hasDynamicWS, app);
299
336
  } catch (error) {
300
- return fail(context, error);
337
+ return (routed ? failRoute : fail)(context, error);
301
338
  }
302
339
  };
303
340
  return (request, server) => {
@@ -306,6 +343,7 @@ function createFetchHandler(app) {
306
343
  if (armEager(request, context)) return emptyResponse.clone();
307
344
  const path = extractPath(request.url, context);
308
345
  context.server = server ?? null;
346
+ let routed = false;
309
347
  try {
310
348
  for (let i = 0; i < onRequests.length; i++) {
311
349
  const result = onRequests[i](context);
@@ -321,9 +359,10 @@ function createFetchHandler(app) {
321
359
  return response;
322
360
  }
323
361
  }
324
- return findRoute(context, request, map, router, hasError, handleError, afterResponse, strictPath, hasWS, hasDynamicWS);
362
+ routed = true;
363
+ return findRoute(context, request, map, router, onNotFound, handleRouteError, routeAfterResponse, strictPath, hasWS, hasDynamicWS, app);
325
364
  } catch (error) {
326
- return fail(context, error);
365
+ return (routed ? failRoute : fail)(context, error);
327
366
  }
328
367
  };
329
368
  }
@@ -332,9 +371,9 @@ function createFetchHandler(app) {
332
371
  extractPath(request.url, context);
333
372
  context.server = server ?? null;
334
373
  try {
335
- return findRoute(context, request, map, router, hasError, handleError, afterResponse, strictPath, hasWS, hasDynamicWS);
374
+ return findRoute(context, request, map, router, onNotFound, handleRouteError, routeAfterResponse, strictPath, hasWS, hasDynamicWS, app);
336
375
  } catch (error) {
337
- return fail(context, error);
376
+ return failRoute(context, error);
338
377
  }
339
378
  };
340
379
  }
@@ -9,13 +9,26 @@ declare const emptyResponse: Response | {
9
9
  declare function getNotFoundBody(): string;
10
10
  declare function getNotFound(): Response;
11
11
  declare function forwardError<T>(value: T): T;
12
+ /**
13
+ * Non-Error classes the route's own error hooks register: like any hook, a
14
+ * class registered after the route doesn't reach it
15
+ */
12
16
  declare function returnedErrorClasses(hook: {
13
17
  error?: unknown;
14
- } | undefined, root: AnyElysia): Function[] | undefined;
18
+ } | undefined): Function[] | undefined;
15
19
  declare const forwardErrorOf: (classes: Function[]) => <T>(value: T) => T;
16
- declare function finalizeRouteError(app: AnyElysia, context: Partial<Context>, error: unknown, sign?: (set: Context['set']) => unknown): MaybePromise<Response>;
20
+ declare function finalizeRouteError(app: AnyElysia, context: Partial<Context>, error: unknown, sign?: (set: Context['set']) => unknown, route?: RouteErrorHooks): MaybePromise<Response>;
21
+ /**
22
+ * The hooks a matched route's error ends with: its own, never one the app
23
+ * registered after it
24
+ */
25
+ interface RouteErrorHooks {
26
+ error?: Function[];
27
+ mapResponse?: Function[];
28
+ }
29
+ declare const finalizeRouteErrorOf: (route: RouteErrorHooks | undefined) => typeof finalizeRouteError;
17
30
  declare function registerDeriveDisposable(context: any, value: unknown, scan?: any): void;
18
31
  declare function drainDisposables(context: any): Promise<void>;
19
32
  declare const hasAsync: (fns: Function[]) => boolean;
20
33
  //#endregion
21
- export { drainDisposables, emptyResponse, finalizeRouteError, forwardError, forwardErrorOf, getNotFound, getNotFoundBody, hasAsync, registerDeriveDisposable, returnedErrorClasses };
34
+ export { RouteErrorHooks, drainDisposables, emptyResponse, finalizeRouteError, finalizeRouteErrorOf, forwardError, forwardErrorOf, getNotFound, getNotFoundBody, hasAsync, registerDeriveDisposable, returnedErrorClasses };
@@ -38,32 +38,32 @@ function forwardError(value) {
38
38
  if (value instanceof Error) throw value;
39
39
  return value;
40
40
  }
41
- const chainErrorClasses = /* @__PURE__ */ new WeakMap();
42
- function collectErrorClasses(error, into) {
43
- if (!error) return into;
41
+ /**
42
+ * Non-Error classes the route's own error hooks register: like any hook, a
43
+ * class registered after the route doesn't reach it
44
+ */
45
+ function returnedErrorClasses(hook) {
46
+ const error = hook?.error;
47
+ if (!error) return;
48
+ let into;
44
49
  const list = Array.isArray(error) ? error : [error];
45
50
  for (let i = 0; i < list.length; i++) {
46
- const C = list[i]?.["~errorClass"];
47
- if (C && !into?.includes(C)) (into ??= []).push(C);
51
+ const errorClass = list[i]?.["~errorClass"];
52
+ if (errorClass && !into?.includes(errorClass)) (into ??= []).push(errorClass);
48
53
  }
49
54
  return into;
50
55
  }
51
- function returnedErrorClasses(hook, root) {
52
- const head = root["~hookChain"];
53
- let rootClasses = head && chainErrorClasses.get(head);
54
- if (head && rootClasses === void 0) chainErrorClasses.set(head, rootClasses = collectErrorClasses(require_utils.flattenChain(head)?.error, void 0) ?? null);
55
- return collectErrorClasses(hook?.error, rootClasses?.slice());
56
- }
57
56
  const forwardErrorOf = (classes) => (value) => {
58
57
  if (value instanceof Error) throw value;
59
58
  for (let i = 0; i < classes.length; i++) if (value instanceof classes[i]) throw value;
60
59
  return value;
61
60
  };
62
- function finalizeRouteError(app, context, error, sign) {
61
+ function finalizeRouteError(app, context, error, sign, route) {
63
62
  const finalize = app["~finalizeError"];
64
63
  if (!finalize) throw error;
65
- return finalize(context, error, sign);
64
+ return finalize(context, error, sign, false, route);
66
65
  }
66
+ const finalizeRouteErrorOf = (route) => route?.error?.length || route?.mapResponse?.length ? (app, context, error, sign) => finalizeRouteError(app, context, error, sign, route) : finalizeRouteError;
67
67
  function registerDeriveDisposable(context, value, scan = context) {
68
68
  if (!require_utils.isDisposable(value)) return;
69
69
  if (require_utils.isSingleton(value)) return;
@@ -95,6 +95,7 @@ const hasAsync = (fns) => fns.some((fn) => require_compile_utils.isAsyncFunction
95
95
  exports.drainDisposables = drainDisposables;
96
96
  exports.emptyResponse = emptyResponse;
97
97
  exports.finalizeRouteError = finalizeRouteError;
98
+ exports.finalizeRouteErrorOf = finalizeRouteErrorOf;
98
99
  exports.forwardError = forwardError;
99
100
  exports.forwardErrorOf = forwardErrorOf;
100
101
  exports.getNotFound = getNotFound;