elysia 2.0.0-exp.1 → 2.0.0-exp.2

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 (136) hide show
  1. package/dist/_virtual/_rolldown/runtime.js +0 -2
  2. package/dist/adapter/bun/index.d.ts +1 -1
  3. package/dist/adapter/bun/router.js +1 -1
  4. package/dist/adapter/bun/router.mjs +1 -1
  5. package/dist/adapter/constants.d.ts +1 -1
  6. package/dist/adapter/index.d.ts +1 -1
  7. package/dist/adapter/utils.d.ts +1 -1
  8. package/dist/adapter/utils.js +4 -2
  9. package/dist/adapter/utils.mjs +4 -2
  10. package/dist/adapter/web-standard/index.d.ts +1 -1
  11. package/dist/base.js +54 -17
  12. package/dist/base.mjs +56 -19
  13. package/dist/compile/aot.d.ts +41 -35
  14. package/dist/compile/aot.js +13 -37
  15. package/dist/compile/aot.mjs +13 -38
  16. package/dist/compile/handler/index.d.ts +4 -2
  17. package/dist/compile/handler/index.js +31 -16
  18. package/dist/compile/handler/index.mjs +31 -17
  19. package/dist/compile/handler/utils.js +3 -3
  20. package/dist/compile/handler/utils.mjs +3 -3
  21. package/dist/compile/index.d.ts +2 -2
  22. package/dist/compile/index.js +2 -1
  23. package/dist/compile/index.mjs +2 -2
  24. package/dist/cookie/config.js +7 -6
  25. package/dist/cookie/config.mjs +7 -6
  26. package/dist/cookie/cookie.js +1 -3
  27. package/dist/cookie/cookie.mjs +1 -3
  28. package/dist/cookie/utils.js +6 -4
  29. package/dist/cookie/utils.mjs +6 -4
  30. package/dist/error.d.ts +6 -9
  31. package/dist/error.js +26 -19
  32. package/dist/error.mjs +26 -19
  33. package/dist/handler/error.js +2 -2
  34. package/dist/handler/error.mjs +3 -3
  35. package/dist/handler/fetch.js +40 -11
  36. package/dist/handler/fetch.mjs +41 -12
  37. package/dist/index.d.ts +2 -2
  38. package/dist/index.js +2 -7
  39. package/dist/index.mjs +2 -2
  40. package/dist/plugin/bun.js +29 -3
  41. package/dist/plugin/bun.mjs +28 -3
  42. package/dist/plugin/core.d.ts +8 -1
  43. package/dist/plugin/esbuild.js +28 -3
  44. package/dist/plugin/esbuild.mjs +28 -3
  45. package/dist/plugin/source.js +22 -0
  46. package/dist/plugin/source.mjs +23 -1
  47. package/dist/plugin/treeshake.d.ts +10 -0
  48. package/dist/plugin/treeshake.js +63 -0
  49. package/dist/plugin/treeshake.mjs +61 -0
  50. package/dist/plugin/vite.js +7 -1
  51. package/dist/plugin/vite.mjs +7 -1
  52. package/dist/trace.js +1 -1
  53. package/dist/trace.mjs +1 -1
  54. package/dist/type/bridge.d.ts +7 -11
  55. package/dist/type/bridge.js +0 -10
  56. package/dist/type/bridge.mjs +1 -9
  57. package/dist/type/coerce.d.ts +1 -1
  58. package/dist/type/coerce.js +38 -4
  59. package/dist/type/coerce.mjs +38 -4
  60. package/dist/type/compat.js +2 -4
  61. package/dist/type/compat.mjs +5 -7
  62. package/dist/type/constants.d.ts +1 -1
  63. package/dist/type/elysia/array-buffer.js +4 -4
  64. package/dist/type/elysia/array-buffer.mjs +4 -4
  65. package/dist/type/elysia/array-string.d.ts +2 -2
  66. package/dist/type/elysia/array-string.js +5 -5
  67. package/dist/type/elysia/array-string.mjs +6 -6
  68. package/dist/type/elysia/array.js +11 -8
  69. package/dist/type/elysia/array.mjs +11 -8
  70. package/dist/type/elysia/boolean-string.js +3 -3
  71. package/dist/type/elysia/boolean-string.mjs +3 -3
  72. package/dist/type/elysia/boolean.js +2 -2
  73. package/dist/type/elysia/boolean.mjs +2 -2
  74. package/dist/type/elysia/cookie.js +1 -4
  75. package/dist/type/elysia/cookie.mjs +1 -4
  76. package/dist/type/elysia/date.js +11 -10
  77. package/dist/type/elysia/date.mjs +11 -10
  78. package/dist/type/elysia/file.js +4 -4
  79. package/dist/type/elysia/file.mjs +4 -4
  80. package/dist/type/elysia/files.js +4 -4
  81. package/dist/type/elysia/files.mjs +4 -4
  82. package/dist/type/elysia/form.js +2 -2
  83. package/dist/type/elysia/form.mjs +4 -4
  84. package/dist/type/elysia/integer-string.js +6 -6
  85. package/dist/type/elysia/integer-string.mjs +7 -7
  86. package/dist/type/elysia/integer.js +2 -2
  87. package/dist/type/elysia/integer.mjs +2 -2
  88. package/dist/type/elysia/maybe-empty.d.ts +3 -2
  89. package/dist/type/elysia/maybe-empty.js +4 -4
  90. package/dist/type/elysia/maybe-empty.mjs +4 -4
  91. package/dist/type/elysia/nullable.d.ts +3 -2
  92. package/dist/type/elysia/nullable.js +3 -3
  93. package/dist/type/elysia/nullable.mjs +3 -3
  94. package/dist/type/elysia/number.js +2 -2
  95. package/dist/type/elysia/number.mjs +2 -2
  96. package/dist/type/elysia/numeric-enum.js +3 -3
  97. package/dist/type/elysia/numeric-enum.mjs +3 -3
  98. package/dist/type/elysia/numeric.js +7 -7
  99. package/dist/type/elysia/numeric.mjs +7 -7
  100. package/dist/type/elysia/object-string.d.ts +2 -2
  101. package/dist/type/elysia/object-string.js +5 -5
  102. package/dist/type/elysia/object-string.mjs +6 -6
  103. package/dist/type/elysia/object.js +12 -9
  104. package/dist/type/elysia/object.mjs +12 -9
  105. package/dist/type/elysia/optional.js +12 -5
  106. package/dist/type/elysia/optional.mjs +12 -5
  107. package/dist/type/elysia/string.js +2 -2
  108. package/dist/type/elysia/string.mjs +2 -2
  109. package/dist/type/elysia/uint8-array.js +2 -2
  110. package/dist/type/elysia/uint8-array.mjs +2 -2
  111. package/dist/type/elysia/union-enum.d.ts +3 -2
  112. package/dist/type/elysia/union-enum.js +2 -2
  113. package/dist/type/elysia/union-enum.mjs +2 -2
  114. package/dist/type/elysia/utils.js +4 -8
  115. package/dist/type/elysia/utils.mjs +4 -8
  116. package/dist/type/exports.js +2071 -39
  117. package/dist/type/exports.mjs +307 -17
  118. package/dist/type/index.d.ts +3 -3
  119. package/dist/type/index.js +4 -31
  120. package/dist/type/index.mjs +4 -26
  121. package/dist/type/types.d.ts +1 -1
  122. package/dist/type/validator.d.ts +3 -3
  123. package/dist/type/validator.js +539 -173
  124. package/dist/type/validator.mjs +541 -175
  125. package/dist/types.d.ts +1 -1
  126. package/dist/utils.js +11 -9
  127. package/dist/utils.mjs +11 -9
  128. package/dist/validator/index.js +7 -6
  129. package/dist/validator/index.mjs +7 -6
  130. package/dist/validator/route.js +1 -1
  131. package/dist/validator/route.mjs +1 -1
  132. package/dist/ws/context.js +4 -7
  133. package/dist/ws/context.mjs +4 -7
  134. package/dist/ws/route.js +6 -4
  135. package/dist/ws/route.mjs +6 -4
  136. package/package.json +10 -2
@@ -32,7 +32,6 @@ var __copyProps = (to, from, except, desc) => {
32
32
  }
33
33
  return to;
34
34
  };
35
- var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
36
35
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
37
36
  value: mod,
38
37
  enumerable: true
@@ -41,5 +40,4 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
41
40
  //#endregion
42
41
 
43
42
  exports.__exportAll = __exportAll;
44
- exports.__reExport = __reExport;
45
43
  exports.__toESM = __toESM;
@@ -6,7 +6,7 @@ import { AnyElysia } from "../../base.js";
6
6
  declare function collectStaticRoutes(app: AnyElysia): readonly [Record<string, Record<string, Response>>, Promise<void>[]] | undefined;
7
7
  declare const BunAdapter: {
8
8
  parse: {
9
- default: (context: Context, contentType: string) => string | ArrayBuffer | unknown[] | Record<string, unknown> | Promise<Record<string, unknown>> | Promise<ArrayBuffer> | Promise<string> | Promise<unknown[] | Record<string | number | symbol, undefined>> | undefined;
9
+ default: (context: Context, contentType: string) => string | unknown[] | ArrayBuffer | Record<string, unknown> | Promise<Record<string, unknown>> | Promise<ArrayBuffer> | Promise<string> | Promise<unknown[] | Record<string | number | symbol, undefined>> | undefined;
10
10
  json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
11
11
  text: (context: Context) => MaybePromise<string>;
12
12
  urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
@@ -62,13 +62,13 @@ function createPlainHandler(handler, handleError, Context) {
62
62
  }
63
63
  function createRouteMap(app) {
64
64
  const Context = createBunContext(app);
65
+ const handleError = require_handler_error.createErrorHandler(require_utils.flattenChain(app["~hookChain"])?.error, require_adapter_web_standard_index.WebStandardAdapter.response.map, new Response("Not Found", { status: 404 }), app["~config"]?.allowUnsafeValidationDetails);
65
66
  function fetch(request) {
66
67
  return handleError(new Context(request), new require_error.NotFound());
67
68
  }
68
69
  const history = app.history;
69
70
  const length = history?.length ?? 0;
70
71
  if (length === 0) return [{ "/elysia": new Response("hi") }, fetch];
71
- const handleError = require_handler_error.createErrorHandler(require_utils.flattenChain(app["~hookChain"])?.error, require_adapter_web_standard_index.WebStandardAdapter.response.map, new Response("Not Found", { status: 404 }), app["~config"]?.allowUnsafeValidationDetails);
72
72
  const routes = require_utils.nullObject();
73
73
  for (let i = 0; i < length; i++) {
74
74
  const route = history[i];
@@ -61,13 +61,13 @@ function createPlainHandler(handler, handleError, Context) {
61
61
  }
62
62
  function createRouteMap(app) {
63
63
  const Context = createBunContext(app);
64
+ const handleError = createErrorHandler(flattenChain(app["~hookChain"])?.error, WebStandardAdapter.response.map, new Response("Not Found", { status: 404 }), app["~config"]?.allowUnsafeValidationDetails);
64
65
  function fetch(request) {
65
66
  return handleError(new Context(request), new NotFound());
66
67
  }
67
68
  const history = app.history;
68
69
  const length = history?.length ?? 0;
69
70
  if (length === 0) return [{ "/elysia": new Response("hi") }, fetch];
70
- const handleError = createErrorHandler(flattenChain(app["~hookChain"])?.error, WebStandardAdapter.response.map, new Response("Not Found", { status: 404 }), app["~config"]?.allowUnsafeValidationDetails);
71
71
  const routes = nullObject();
72
72
  for (let i = 0; i < length; i++) {
73
73
  const route = history[i];
@@ -5,7 +5,7 @@ import { AnyElysia } from "../base.js";
5
5
  //#region src/adapter/constants.d.ts
6
6
  declare const defaultAdapter: {
7
7
  parse: {
8
- default: (context: Context, contentType: string) => string | ArrayBuffer | unknown[] | Record<string, unknown> | Promise<Record<string, unknown>> | Promise<ArrayBuffer> | Promise<string> | Promise<unknown[] | Record<string | number | symbol, undefined>> | undefined;
8
+ default: (context: Context, contentType: string) => string | unknown[] | ArrayBuffer | Record<string, unknown> | Promise<Record<string, unknown>> | Promise<ArrayBuffer> | Promise<string> | Promise<unknown[] | Record<string | number | symbol, undefined>> | undefined;
9
9
  json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
10
10
  text: (context: Context) => MaybePromise<string>;
11
11
  urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
@@ -7,7 +7,7 @@ import { AnyElysia } from "../base.js";
7
7
  //#region src/adapter/index.d.ts
8
8
  declare function createAdapter(adapter: ElysiaAdapterOptions): {
9
9
  parse: {
10
- default: (context: Context, contentType: string) => string | ArrayBuffer | unknown[] | Record<string, unknown> | Promise<Record<string, unknown>> | Promise<ArrayBuffer> | Promise<string> | Promise<unknown[] | Record<string | number | symbol, undefined>> | undefined;
10
+ default: (context: Context, contentType: string) => string | unknown[] | ArrayBuffer | Record<string, unknown> | Promise<Record<string, unknown>> | Promise<ArrayBuffer> | Promise<string> | Promise<unknown[] | Record<string | number | symbol, undefined>> | undefined;
11
11
  json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
12
12
  text: (context: Context) => MaybePromise<string>;
13
13
  urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
@@ -12,7 +12,7 @@ declare function responseToSetHeaders(response: Response, set?: Context['set']):
12
12
  cookie?: Record<string, BaseCookie>;
13
13
  } | {
14
14
  headers: any;
15
- status: number | "Bad Request" | "Continue" | "Switching Protocols" | "Processing" | "Early Hints" | "OK" | "Created" | "Accepted" | "Non-Authoritative Information" | "No Content" | "Reset Content" | "Partial Content" | "Multi-Status" | "Already Reported" | "Multiple Choices" | "Moved Permanently" | "Found" | "See Other" | "Not Modified" | "Temporary Redirect" | "Permanent Redirect" | "Unauthorized" | "Payment Required" | "Forbidden" | "Not Found" | "Method Not Allowed" | "Not Acceptable" | "Proxy Authentication Required" | "Request Timeout" | "Conflict" | "Gone" | "Length Required" | "Precondition Failed" | "Payload Too Large" | "URI Too Long" | "Unsupported Media Type" | "Range Not Satisfiable" | "Expectation Failed" | "I'm a teapot" | "Enhance Your Calm" | "Misdirected Request" | "Unprocessable Content" | "Locked" | "Failed Dependency" | "Too Early" | "Upgrade Required" | "Precondition Required" | "Too Many Requests" | "Request Header Fields Too Large" | "Unavailable For Legal Reasons" | "Internal Server Error" | "Not Implemented" | "Bad Gateway" | "Service Unavailable" | "Gateway Timeout" | "HTTP Version Not Supported" | "Variant Also Negotiates" | "Insufficient Storage" | "Loop Detected" | "Not Extended" | "Network Authentication Required";
15
+ status: number | "Continue" | "Switching Protocols" | "Processing" | "Early Hints" | "OK" | "Created" | "Accepted" | "Non-Authoritative Information" | "No Content" | "Reset Content" | "Partial Content" | "Multi-Status" | "Already Reported" | "Multiple Choices" | "Moved Permanently" | "Found" | "See Other" | "Not Modified" | "Temporary Redirect" | "Permanent Redirect" | "Bad Request" | "Unauthorized" | "Payment Required" | "Forbidden" | "Not Found" | "Method Not Allowed" | "Not Acceptable" | "Proxy Authentication Required" | "Request Timeout" | "Conflict" | "Gone" | "Length Required" | "Precondition Failed" | "Payload Too Large" | "URI Too Long" | "Unsupported Media Type" | "Range Not Satisfiable" | "Expectation Failed" | "I'm a teapot" | "Enhance Your Calm" | "Misdirected Request" | "Unprocessable Content" | "Locked" | "Failed Dependency" | "Too Early" | "Upgrade Required" | "Precondition Required" | "Too Many Requests" | "Request Header Fields Too Large" | "Unavailable For Legal Reasons" | "Internal Server Error" | "Not Implemented" | "Bad Gateway" | "Service Unavailable" | "Gateway Timeout" | "HTTP Version Not Supported" | "Variant Also Negotiates" | "Insufficient Storage" | "Loop Detected" | "Not Extended" | "Network Authentication Required";
16
16
  };
17
17
  interface CreateHandlerParameter {
18
18
  mapResponse(response: unknown, set: Context['set'], request?: Request): Response;
@@ -51,7 +51,7 @@ function handleFile(response, set, request) {
51
51
  if (!set && !size) return new Response(response);
52
52
  if (!set) return new Response(response, { headers: defaultHeader });
53
53
  if (set.headers instanceof Headers) {
54
- for (const key of Object.keys(defaultHeader)) if (key in set.headers) set.headers.append(key, defaultHeader[key]);
54
+ for (const key of Object.keys(defaultHeader)) if (!set.headers.has(key)) set.headers.append(key, defaultHeader[key]);
55
55
  if (immutable) {
56
56
  set.headers.delete("content-length");
57
57
  set.headers.delete("accept-ranges");
@@ -96,7 +96,9 @@ function responseToSetHeaders(response, set) {
96
96
  };
97
97
  for (const [key, value] of response.headers.entries()) set.headers[key] = value;
98
98
  }
99
- if (set.headers["content-encoding"]) delete set.headers["content-encoding"];
99
+ if (set.headers instanceof Headers) {
100
+ if (set.headers.has("content-encoding")) set.headers.delete("content-encoding");
101
+ } else if (set.headers["content-encoding"]) delete set.headers["content-encoding"];
100
102
  return set;
101
103
  }
102
104
  const enqueueBinaryChunk = (controller, chunk) => {
@@ -50,7 +50,7 @@ function handleFile(response, set, request) {
50
50
  if (!set && !size) return new Response(response);
51
51
  if (!set) return new Response(response, { headers: defaultHeader });
52
52
  if (set.headers instanceof Headers) {
53
- for (const key of Object.keys(defaultHeader)) if (key in set.headers) set.headers.append(key, defaultHeader[key]);
53
+ for (const key of Object.keys(defaultHeader)) if (!set.headers.has(key)) set.headers.append(key, defaultHeader[key]);
54
54
  if (immutable) {
55
55
  set.headers.delete("content-length");
56
56
  set.headers.delete("accept-ranges");
@@ -95,7 +95,9 @@ function responseToSetHeaders(response, set) {
95
95
  };
96
96
  for (const [key, value] of response.headers.entries()) set.headers[key] = value;
97
97
  }
98
- if (set.headers["content-encoding"]) delete set.headers["content-encoding"];
98
+ if (set.headers instanceof Headers) {
99
+ if (set.headers.has("content-encoding")) set.headers.delete("content-encoding");
100
+ } else if (set.headers["content-encoding"]) delete set.headers["content-encoding"];
99
101
  return set;
100
102
  }
101
103
  const enqueueBinaryChunk = (controller, chunk) => {
@@ -5,7 +5,7 @@ import { AnyElysia } from "../../base.js";
5
5
  //#region src/adapter/web-standard/index.d.ts
6
6
  declare const WebStandardAdapter: {
7
7
  parse: {
8
- default: (context: Context, contentType: string) => string | ArrayBuffer | unknown[] | Record<string, unknown> | Promise<Record<string, unknown>> | Promise<ArrayBuffer> | Promise<string> | Promise<unknown[] | Record<string | number | symbol, undefined>> | undefined;
8
+ default: (context: Context, contentType: string) => string | unknown[] | ArrayBuffer | Record<string, unknown> | Promise<Record<string, unknown>> | Promise<ArrayBuffer> | Promise<string> | Promise<unknown[] | Record<string | number | symbol, undefined>> | undefined;
9
9
  json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
10
10
  text: (context: Context) => MaybePromise<string>;
11
11
  urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
package/dist/base.js CHANGED
@@ -14,6 +14,22 @@ memoirist = require_runtime.__toESM(memoirist);
14
14
 
15
15
  //#region src/base.ts
16
16
  const useNodesBuffer = [];
17
+ const isPlainObject = (v) => {
18
+ if (!v || typeof v !== "object" || Array.isArray(v)) return false;
19
+ const proto = Object.getPrototypeOf(v);
20
+ return proto === Object.prototype || proto === null;
21
+ };
22
+ function clonePlainDecorators(source, seen = /* @__PURE__ */ new WeakMap()) {
23
+ const existing = seen.get(source);
24
+ if (existing) return existing;
25
+ const out = require_utils.nullObject();
26
+ seen.set(source, out);
27
+ for (const key in source) {
28
+ const value = source[key];
29
+ out[key] = isPlainObject(value) ? clonePlainDecorators(value, seen) : value;
30
+ }
31
+ return out;
32
+ }
17
33
  var Elysia = class Elysia {
18
34
  #hasPlugin = false;
19
35
  #hasGlobal = false;
@@ -31,7 +47,7 @@ var Elysia = class Elysia {
31
47
  }
32
48
  }
33
49
  get history() {
34
- if (!this.#history) return void 0;
50
+ if (!this.#history) return;
35
51
  this.#resolveMacros();
36
52
  return this.#history;
37
53
  }
@@ -47,9 +63,8 @@ var Elysia = class Elysia {
47
63
  if (!this.#history) return [];
48
64
  if (this.#cachedRoutes) return this.#cachedRoutes;
49
65
  this.#resolveMacros();
50
- const routes = this.#history.map(([method, path, handler, , hook, appHook]) => {
51
- const flatAppHook = require_utils.flattenChain(appHook);
52
- const merged = flatAppHook ? hook ? require_utils.mergeHook(require_utils.cloneHook(hook), flatAppHook) : flatAppHook : hook;
66
+ const routes = this.#history.map(([method, path, handler, instance, hook, appHook, inheritedChain]) => {
67
+ const merged = require_compile_handler_index.composeRouteHook(instance, hook, appHook, inheritedChain, this);
53
68
  if (merged?.schemas?.length) for (const entry of merged.schemas) {
54
69
  if (!entry?.response) continue;
55
70
  merged.response = require_utils.mergeResponse(merged.response, entry.response);
@@ -138,7 +153,7 @@ var Elysia = class Elysia {
138
153
  headers(headers) {
139
154
  const ext = this.#ext;
140
155
  if (ext.headers) Object.assign(ext.headers, headers);
141
- else ext.headers = headers;
156
+ else ext.headers = Object.assign(require_utils.nullObject(), headers);
142
157
  return this;
143
158
  }
144
159
  #on(type, fn, scope = this["~config"]?.as) {
@@ -293,7 +308,8 @@ var Elysia = class Elysia {
293
308
  require_utils.hookToGuard(hook);
294
309
  if (hook.derive) {
295
310
  this["~derive"] ??= /* @__PURE__ */ new WeakSet();
296
- this["~derive"].add(hook.derive);
311
+ if (Array.isArray(hook.derive)) for (const fn of hook.derive) this["~derive"].add(fn);
312
+ else this["~derive"].add(hook.derive);
297
313
  }
298
314
  const trackFn = (fn) => {
299
315
  if (typeof fn !== "function") return;
@@ -355,7 +371,8 @@ var Elysia = class Elysia {
355
371
  if (hook.derive) {
356
372
  const promoted = require_utils.nullObject();
357
373
  for (const key of Object.keys(hook)) {
358
- if (!require_utils.eventProperties.has(key)) continue;
374
+ if (key === "derive" || key === "resolve") continue;
375
+ if (!require_utils.eventProperties.has(key) && !require_utils.schemaProperties.has(key) && key !== "schema" && key !== "schemas") continue;
359
376
  promoted[key] = hook[key];
360
377
  }
361
378
  const extras = [];
@@ -542,8 +559,11 @@ var Elysia = class Elysia {
542
559
  if (app["~ext"]) {
543
560
  const { decorator, store, headers, models, parser, macro, error, hoc } = app["~ext"];
544
561
  const ext = this["~ext"] ??= require_utils.nullObject();
545
- if (decorator) if (ext.decorator) require_utils.mergeDeep(ext.decorator, decorator);
546
- else ext.decorator = Object.assign(require_utils.nullObject(), decorator);
562
+ if (decorator) {
563
+ const cloned = clonePlainDecorators(decorator);
564
+ if (ext.decorator) require_utils.mergeDeep(ext.decorator, cloned);
565
+ else ext.decorator = Object.assign(require_utils.nullObject(), cloned);
566
+ }
547
567
  if (store) if (ext.store) require_utils.mergeDeep(ext.store, store);
548
568
  else ext.store = Object.assign(require_utils.nullObject(), store);
549
569
  if (headers) if (ext.headers) Object.assign(ext.headers, headers);
@@ -774,7 +794,7 @@ var Elysia = class Elysia {
774
794
  if (!adapter?.websocket && !require_universal_constants.isBun) throw new Error(`[Elysia] WebSocket is not supported on '${adapter?.name ?? "web-standard"}' adapter.`);
775
795
  let opts;
776
796
  if (handler !== void 0) {
777
- opts = optionsOrHandler ?? require_utils.nullObject();
797
+ opts = Object.assign(require_utils.nullObject(), optionsOrHandler);
778
798
  if (opts.message != null && opts.message !== handler) throw new Error("[Elysia] .ws(): cannot specify 'message' as both positional handler and options.message");
779
799
  opts.message = handler;
780
800
  } else if (typeof optionsOrHandler === "function") {
@@ -892,6 +912,22 @@ var Elysia = class Elysia {
892
912
  }
893
913
  const wrapHeadHandler = Elysia.#wrapHeadHandler;
894
914
  const strict = !!this["~config"]?.strictPath;
915
+ let explicitPaths;
916
+ if (!strict) {
917
+ explicitPaths = /* @__PURE__ */ new Map();
918
+ for (let i = 0; i < length; i++) {
919
+ const route = this.#history[i];
920
+ const m = route[0] === "WS" ? "WS" : require_utils.mapMethodBack(route[0]);
921
+ const p = route[1];
922
+ let set = explicitPaths.get(m);
923
+ if (!set) explicitPaths.set(m, set = /* @__PURE__ */ new Set());
924
+ set.add(p);
925
+ if (require_constants.needEncodeRegex.test(p)) {
926
+ const encoded = encodeURI(p);
927
+ if (encoded !== p) set.add(encoded);
928
+ }
929
+ }
930
+ }
895
931
  for (let i = 0; i < length; i++) {
896
932
  const route = this.#history[i];
897
933
  const method = require_utils.mapMethodBack(route[0]);
@@ -907,7 +943,7 @@ var Elysia = class Elysia {
907
943
  wsMap[path] = handler;
908
944
  if (!this["~config"]?.strictPath) {
909
945
  const loose = require_utils.getLoosePath(path);
910
- if (loose !== path) wsMap[loose] = handler;
946
+ if (loose !== path && !explicitPaths?.get("WS")?.has(loose)) wsMap[loose] = handler;
911
947
  }
912
948
  }
913
949
  if (options && require_utils.isNotEmpty(options)) {
@@ -933,19 +969,20 @@ var Elysia = class Elysia {
933
969
  (target[path] ??= require_utils.nullObject())[method] = staticResponse;
934
970
  if (!this["~config"]?.strictPath) {
935
971
  const loose = require_utils.getLoosePath(path);
936
- (target[loose] ??= require_utils.nullObject())[method] = staticResponse;
972
+ if (!explicitPaths?.get(method)?.has(loose)) (target[loose] ??= require_utils.nullObject())[method] = staticResponse;
937
973
  }
938
974
  }
939
975
  }
940
976
  const sharedStatic = maybeStatic && staticResponse instanceof Response ? staticResponse : void 0;
941
977
  const autoHead = enableAutoHead && method === "GET" && !explicitHead?.has(path);
942
- const registerPattern = (registerMain, registerHead, handler, headHandler) => {
978
+ const registerPattern = (registerMain, registerHead, handler, headHandler, registerLoose) => {
979
+ const explicitMain = explicitPaths?.get(method);
943
980
  const add = (p) => {
944
981
  registerMain(p, handler);
945
982
  if (headHandler) registerHead(p, headHandler);
946
- if (!strict) {
983
+ if (registerLoose) {
947
984
  const loose = require_utils.getLoosePath(p);
948
- if (loose !== p) {
985
+ if (loose !== p && !explicitMain?.has(loose)) {
949
986
  registerMain(loose, handler);
950
987
  if (headHandler) registerHead(loose, headHandler);
951
988
  }
@@ -960,7 +997,7 @@ var Elysia = class Elysia {
960
997
  if (require_constants.isDynamicRegex.test(path)) {
961
998
  const router = this["~router"] ??= new memoirist.default();
962
999
  const handler = this.handler(i, precompile, void 0, sharedStatic);
963
- registerPattern((p, h) => router.add(method, p, h, false), (p, h) => router.add("HEAD", p, h, false), handler, autoHead ? wrapHeadHandler(handler) : void 0);
1000
+ registerPattern((p, h) => router.add(method, p, h, false), (p, h) => router.add("HEAD", p, h, false), handler, autoHead ? wrapHeadHandler(handler) : void 0, false);
964
1001
  } else {
965
1002
  const map = methods[method] ??= require_utils.nullObject();
966
1003
  const handler = this.handler(i, precompile, route, sharedStatic);
@@ -970,7 +1007,7 @@ var Elysia = class Elysia {
970
1007
  map[p] = h;
971
1008
  }, (p, h) => {
972
1009
  head[p] = h;
973
- }, handler, headHandler);
1010
+ }, handler, headHandler, !strict);
974
1011
  }
975
1012
  }
976
1013
  }
package/dist/base.mjs CHANGED
@@ -1,16 +1,32 @@
1
1
  import { isBun } from "./universal/constants.mjs";
2
2
  import { MethodMap, isDynamicRegex, needEncodeRegex } from "./constants.mjs";
3
- import { cloneHook, coalesceStandaloneSchemas, createErrorEventHandler, eventProperties, flattenChain, fnOrigin, fnv1a, getLoosePath, hookToGuard, isEmpty, isNotEmpty, isRecordNumber, joinPath, mapMethodBack, mergeDeep, mergeHook, mergeResponse, nullObject, pushField, replaceUrlPath, schemaProperties } from "./utils.mjs";
3
+ import { coalesceStandaloneSchemas, createErrorEventHandler, eventProperties, flattenChain, fnOrigin, fnv1a, getLoosePath, hookToGuard, isEmpty, isNotEmpty, isRecordNumber, joinPath, mapMethodBack, mergeDeep, mergeResponse, nullObject, pushField, replaceUrlPath, schemaProperties } from "./utils.mjs";
4
4
  import { Ref } from "./type/bridge.mjs";
5
5
  import { env } from "./universal/env.mjs";
6
6
  import { buildWSRoute } from "./ws/route.mjs";
7
7
  import { BunAdapter } from "./adapter/bun/index.mjs";
8
8
  import { applyHoc, createFetchHandler } from "./handler/fetch.mjs";
9
- import { buildNativeStaticResponse, compileHandler } from "./compile/handler/index.mjs";
9
+ import { buildNativeStaticResponse, compileHandler, composeRouteHook } from "./compile/handler/index.mjs";
10
10
  import Memoirist from "memoirist";
11
11
 
12
12
  //#region src/base.ts
13
13
  const useNodesBuffer = [];
14
+ const isPlainObject = (v) => {
15
+ if (!v || typeof v !== "object" || Array.isArray(v)) return false;
16
+ const proto = Object.getPrototypeOf(v);
17
+ return proto === Object.prototype || proto === null;
18
+ };
19
+ function clonePlainDecorators(source, seen = /* @__PURE__ */ new WeakMap()) {
20
+ const existing = seen.get(source);
21
+ if (existing) return existing;
22
+ const out = nullObject();
23
+ seen.set(source, out);
24
+ for (const key in source) {
25
+ const value = source[key];
26
+ out[key] = isPlainObject(value) ? clonePlainDecorators(value, seen) : value;
27
+ }
28
+ return out;
29
+ }
14
30
  var Elysia = class Elysia {
15
31
  #hasPlugin = false;
16
32
  #hasGlobal = false;
@@ -28,7 +44,7 @@ var Elysia = class Elysia {
28
44
  }
29
45
  }
30
46
  get history() {
31
- if (!this.#history) return void 0;
47
+ if (!this.#history) return;
32
48
  this.#resolveMacros();
33
49
  return this.#history;
34
50
  }
@@ -44,9 +60,8 @@ var Elysia = class Elysia {
44
60
  if (!this.#history) return [];
45
61
  if (this.#cachedRoutes) return this.#cachedRoutes;
46
62
  this.#resolveMacros();
47
- const routes = this.#history.map(([method, path, handler, , hook, appHook]) => {
48
- const flatAppHook = flattenChain(appHook);
49
- const merged = flatAppHook ? hook ? mergeHook(cloneHook(hook), flatAppHook) : flatAppHook : hook;
63
+ const routes = this.#history.map(([method, path, handler, instance, hook, appHook, inheritedChain]) => {
64
+ const merged = composeRouteHook(instance, hook, appHook, inheritedChain, this);
50
65
  if (merged?.schemas?.length) for (const entry of merged.schemas) {
51
66
  if (!entry?.response) continue;
52
67
  merged.response = mergeResponse(merged.response, entry.response);
@@ -135,7 +150,7 @@ var Elysia = class Elysia {
135
150
  headers(headers) {
136
151
  const ext = this.#ext;
137
152
  if (ext.headers) Object.assign(ext.headers, headers);
138
- else ext.headers = headers;
153
+ else ext.headers = Object.assign(nullObject(), headers);
139
154
  return this;
140
155
  }
141
156
  #on(type, fn, scope = this["~config"]?.as) {
@@ -290,7 +305,8 @@ var Elysia = class Elysia {
290
305
  hookToGuard(hook);
291
306
  if (hook.derive) {
292
307
  this["~derive"] ??= /* @__PURE__ */ new WeakSet();
293
- this["~derive"].add(hook.derive);
308
+ if (Array.isArray(hook.derive)) for (const fn of hook.derive) this["~derive"].add(fn);
309
+ else this["~derive"].add(hook.derive);
294
310
  }
295
311
  const trackFn = (fn) => {
296
312
  if (typeof fn !== "function") return;
@@ -352,7 +368,8 @@ var Elysia = class Elysia {
352
368
  if (hook.derive) {
353
369
  const promoted = nullObject();
354
370
  for (const key of Object.keys(hook)) {
355
- if (!eventProperties.has(key)) continue;
371
+ if (key === "derive" || key === "resolve") continue;
372
+ if (!eventProperties.has(key) && !schemaProperties.has(key) && key !== "schema" && key !== "schemas") continue;
356
373
  promoted[key] = hook[key];
357
374
  }
358
375
  const extras = [];
@@ -539,8 +556,11 @@ var Elysia = class Elysia {
539
556
  if (app["~ext"]) {
540
557
  const { decorator, store, headers, models, parser, macro, error, hoc } = app["~ext"];
541
558
  const ext = this["~ext"] ??= nullObject();
542
- if (decorator) if (ext.decorator) mergeDeep(ext.decorator, decorator);
543
- else ext.decorator = Object.assign(nullObject(), decorator);
559
+ if (decorator) {
560
+ const cloned = clonePlainDecorators(decorator);
561
+ if (ext.decorator) mergeDeep(ext.decorator, cloned);
562
+ else ext.decorator = Object.assign(nullObject(), cloned);
563
+ }
544
564
  if (store) if (ext.store) mergeDeep(ext.store, store);
545
565
  else ext.store = Object.assign(nullObject(), store);
546
566
  if (headers) if (ext.headers) Object.assign(ext.headers, headers);
@@ -771,7 +791,7 @@ var Elysia = class Elysia {
771
791
  if (!adapter?.websocket && !isBun) throw new Error(`[Elysia] WebSocket is not supported on '${adapter?.name ?? "web-standard"}' adapter.`);
772
792
  let opts;
773
793
  if (handler !== void 0) {
774
- opts = optionsOrHandler ?? nullObject();
794
+ opts = Object.assign(nullObject(), optionsOrHandler);
775
795
  if (opts.message != null && opts.message !== handler) throw new Error("[Elysia] .ws(): cannot specify 'message' as both positional handler and options.message");
776
796
  opts.message = handler;
777
797
  } else if (typeof optionsOrHandler === "function") {
@@ -889,6 +909,22 @@ var Elysia = class Elysia {
889
909
  }
890
910
  const wrapHeadHandler = Elysia.#wrapHeadHandler;
891
911
  const strict = !!this["~config"]?.strictPath;
912
+ let explicitPaths;
913
+ if (!strict) {
914
+ explicitPaths = /* @__PURE__ */ new Map();
915
+ for (let i = 0; i < length; i++) {
916
+ const route = this.#history[i];
917
+ const m = route[0] === "WS" ? "WS" : mapMethodBack(route[0]);
918
+ const p = route[1];
919
+ let set = explicitPaths.get(m);
920
+ if (!set) explicitPaths.set(m, set = /* @__PURE__ */ new Set());
921
+ set.add(p);
922
+ if (needEncodeRegex.test(p)) {
923
+ const encoded = encodeURI(p);
924
+ if (encoded !== p) set.add(encoded);
925
+ }
926
+ }
927
+ }
892
928
  for (let i = 0; i < length; i++) {
893
929
  const route = this.#history[i];
894
930
  const method = mapMethodBack(route[0]);
@@ -904,7 +940,7 @@ var Elysia = class Elysia {
904
940
  wsMap[path] = handler;
905
941
  if (!this["~config"]?.strictPath) {
906
942
  const loose = getLoosePath(path);
907
- if (loose !== path) wsMap[loose] = handler;
943
+ if (loose !== path && !explicitPaths?.get("WS")?.has(loose)) wsMap[loose] = handler;
908
944
  }
909
945
  }
910
946
  if (options && isNotEmpty(options)) {
@@ -930,19 +966,20 @@ var Elysia = class Elysia {
930
966
  (target[path] ??= nullObject())[method] = staticResponse;
931
967
  if (!this["~config"]?.strictPath) {
932
968
  const loose = getLoosePath(path);
933
- (target[loose] ??= nullObject())[method] = staticResponse;
969
+ if (!explicitPaths?.get(method)?.has(loose)) (target[loose] ??= nullObject())[method] = staticResponse;
934
970
  }
935
971
  }
936
972
  }
937
973
  const sharedStatic = maybeStatic && staticResponse instanceof Response ? staticResponse : void 0;
938
974
  const autoHead = enableAutoHead && method === "GET" && !explicitHead?.has(path);
939
- const registerPattern = (registerMain, registerHead, handler, headHandler) => {
975
+ const registerPattern = (registerMain, registerHead, handler, headHandler, registerLoose) => {
976
+ const explicitMain = explicitPaths?.get(method);
940
977
  const add = (p) => {
941
978
  registerMain(p, handler);
942
979
  if (headHandler) registerHead(p, headHandler);
943
- if (!strict) {
980
+ if (registerLoose) {
944
981
  const loose = getLoosePath(p);
945
- if (loose !== p) {
982
+ if (loose !== p && !explicitMain?.has(loose)) {
946
983
  registerMain(loose, handler);
947
984
  if (headHandler) registerHead(loose, headHandler);
948
985
  }
@@ -957,7 +994,7 @@ var Elysia = class Elysia {
957
994
  if (isDynamicRegex.test(path)) {
958
995
  const router = this["~router"] ??= new Memoirist();
959
996
  const handler = this.handler(i, precompile, void 0, sharedStatic);
960
- registerPattern((p, h) => router.add(method, p, h, false), (p, h) => router.add("HEAD", p, h, false), handler, autoHead ? wrapHeadHandler(handler) : void 0);
997
+ registerPattern((p, h) => router.add(method, p, h, false), (p, h) => router.add("HEAD", p, h, false), handler, autoHead ? wrapHeadHandler(handler) : void 0, false);
961
998
  } else {
962
999
  const map = methods[method] ??= nullObject();
963
1000
  const handler = this.handler(i, precompile, route, sharedStatic);
@@ -967,7 +1004,7 @@ var Elysia = class Elysia {
967
1004
  map[p] = h;
968
1005
  }, (p, h) => {
969
1006
  head[p] = h;
970
- }, handler, headHandler);
1007
+ }, handler, headHandler, !strict);
971
1008
  }
972
1009
  }
973
1010
  }
@@ -29,6 +29,22 @@ interface FrozenValidator {
29
29
  d?: 1;
30
30
  k?: 1;
31
31
  r?: 1;
32
+ ps?: 1;
33
+ pd?: unknown;
34
+ pod?: Record<string, unknown>;
35
+ ce?: Array<{
36
+ p: string;
37
+ c: FrozenCheckFactory;
38
+ e?: 1;
39
+ }>;
40
+ ic?: Array<{
41
+ o: number;
42
+ c: FrozenCheckFactory;
43
+ e?: 1;
44
+ d: FrozenMirror & {
45
+ x?: 1;
46
+ };
47
+ }>;
32
48
  }
33
49
  interface ValidatorManifest {
34
50
  [method: string]: {
@@ -83,8 +99,9 @@ declare const Source: {
83
99
  readonly bothFactory: (identifier: string, checkDefs: string, checkValue: string, mirrorSource: string, mirrorHasExternals: boolean) => string;
84
100
  };
85
101
  declare function instantiateFrozenMirror(frozen: FrozenMirror, schema: unknown): (value: unknown) => unknown;
86
- declare function instantiateFrozenDecodeMirror(frozen: FrozenMirror, schema: unknown): (value: unknown) => unknown;
87
- declare function instantiateFrozenEncodeMirror(frozen: FrozenMirror, schema: unknown): (value: unknown) => unknown;
102
+ declare function instantiateFrozenDecodeMirror(frozen: FrozenMirror, schema: unknown, dir?: 'decode' | 'encode'): (value: unknown) => unknown;
103
+ declare const instantiateFrozenEncodeMirror: (frozen: FrozenMirror, schema: unknown) => ((value: unknown) => unknown);
104
+ declare const EMPTY_EXTERNALS: unknown[];
88
105
  declare function instantiateFrozenBoth(frozen: FrozenValidator, checkSchema: unknown, mirrorSchema: unknown): {
89
106
  check?: (value: unknown) => boolean;
90
107
  clean?: (value: unknown) => unknown;
@@ -123,6 +140,24 @@ interface CapturedValidator {
123
140
  mirror?: CapturedMirror;
124
141
  decodeMirror?: CapturedMirror;
125
142
  encodeMirror?: CapturedMirror;
143
+ precomputeSafe?: boolean;
144
+ precomputedDefault?: unknown;
145
+ precomputedObjectDefault?: Record<string, unknown>;
146
+ customErrors?: Array<{
147
+ path: string;
148
+ identifier: string;
149
+ checkDefs: string;
150
+ checkValue: string;
151
+ external: boolean;
152
+ }>;
153
+ innerCodecs?: Array<{
154
+ open: number;
155
+ identifier: string;
156
+ checkDefs: string;
157
+ checkValue: string;
158
+ external: boolean;
159
+ decode: CapturedMirror;
160
+ }>;
126
161
  }
127
162
  declare function beginValidatorCapture(): void;
128
163
  declare function endValidatorCapture(): CapturedValidator[];
@@ -134,46 +169,17 @@ interface CapturedHandler {
134
169
  }
135
170
  declare function captureHandler(v: CapturedHandler): void;
136
171
  declare function endHandlerCapture(): CapturedHandler[];
137
- declare function captureValidator(v: {
138
- method: string;
139
- path: string;
140
- slot: ValidatorSlot;
141
- identifier: string;
142
- checkDefs: string;
143
- checkValue: string;
144
- external: boolean;
145
- async: boolean;
146
- hasDefault: boolean;
147
- hasCodec: boolean;
148
- hasRef: boolean;
149
- }): void;
150
- declare function captureMirror(v: {
151
- method: string;
152
- path: string;
153
- slot: ValidatorSlot;
154
- mirror: CapturedMirror;
155
- }): void;
156
- declare function captureDecodeMirror(v: {
157
- method: string;
158
- path: string;
159
- slot: ValidatorSlot;
160
- mirror: CapturedMirror;
161
- }): void;
162
- declare function captureEncodeMirror(v: {
172
+ declare function captureSet(loc: {
163
173
  method: string;
164
174
  path: string;
165
175
  slot: ValidatorSlot;
166
- mirror: CapturedMirror;
167
- }): void;
176
+ }, partial: Partial<CapturedValidator>): void;
168
177
  declare const Capture: {
169
- readonly validator: typeof captureValidator;
178
+ readonly set: typeof captureSet;
170
179
  readonly handler: typeof captureHandler;
171
- readonly mirror: typeof captureMirror;
172
- readonly mirrorDecode: typeof captureDecodeMirror;
173
- readonly mirrorEncode: typeof captureEncodeMirror;
174
180
  readonly mirrorUnions: typeof captureMirrorUnions;
175
181
  readonly mirrorCodecs: typeof captureMirrorCodecs;
176
182
  readonly isCapturing: () => boolean;
177
183
  };
178
184
  //#endregion
179
- export { Capture, CapturedHandler, CapturedMirror, CapturedValidator, CheckBuildResult, Compiled, FrozenBothFactory, FrozenCheckFactory, FrozenHandler, FrozenMirror, FrozenMirrorFactory, FrozenValidator, HandlerManifest, Source, ValidatorManifest, ValidatorSlot, beginValidatorCapture, collectExternals, endHandlerCapture, endValidatorCapture, externalsMatch, instantiateFrozenBoth, instantiateFrozenDecodeMirror, instantiateFrozenEncodeMirror, instantiateFrozenMirror, reconstructCheck };
185
+ export { Capture, CapturedHandler, CapturedMirror, CapturedValidator, CheckBuildResult, Compiled, EMPTY_EXTERNALS, FrozenBothFactory, FrozenCheckFactory, FrozenHandler, FrozenMirror, FrozenMirrorFactory, FrozenValidator, HandlerManifest, Source, ValidatorManifest, ValidatorSlot, beginValidatorCapture, collectExternals, endHandlerCapture, endValidatorCapture, externalsMatch, instantiateFrozenBoth, instantiateFrozenDecodeMirror, instantiateFrozenEncodeMirror, instantiateFrozenMirror, reconstructCheck };