elysia 2.0.0-exp.37 → 2.0.0-exp.39

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 (50) hide show
  1. package/dist/adapter/utils.d.ts +1 -4
  2. package/dist/adapter/utils.js +3 -4
  3. package/dist/adapter/utils.mjs +4 -2
  4. package/dist/base.d.ts +3 -3
  5. package/dist/base.js +27 -15
  6. package/dist/base.mjs +27 -15
  7. package/dist/compile/handler/frozen-validator.d.ts +1 -1
  8. package/dist/compile/handler/frozen-validator.js +3 -7
  9. package/dist/compile/handler/frozen-validator.mjs +3 -7
  10. package/dist/compile/handler/index.js +2 -2
  11. package/dist/compile/handler/index.mjs +3 -3
  12. package/dist/compile/handler/jit.js +12 -4
  13. package/dist/compile/handler/jit.mjs +12 -4
  14. package/dist/compile/handler/params.js +2 -1
  15. package/dist/compile/handler/params.mjs +3 -2
  16. package/dist/compile/handler/utils.d.ts +2 -1
  17. package/dist/compile/handler/utils.js +29 -23
  18. package/dist/compile/handler/utils.mjs +29 -24
  19. package/dist/compile/utils.js +6 -2
  20. package/dist/compile/utils.mjs +6 -2
  21. package/dist/cookie/config.d.ts +1 -0
  22. package/dist/cookie/config.js +2 -1
  23. package/dist/cookie/config.mjs +2 -1
  24. package/dist/cookie/utils.js +1 -1
  25. package/dist/cookie/utils.mjs +1 -1
  26. package/dist/error.js +20 -17
  27. package/dist/error.mjs +20 -17
  28. package/dist/handler/fetch.js +1 -1
  29. package/dist/handler/fetch.mjs +1 -1
  30. package/dist/index.d.ts +4 -4
  31. package/dist/parse-query.js +13 -12
  32. package/dist/parse-query.mjs +13 -12
  33. package/dist/sucrose.js +48 -32
  34. package/dist/sucrose.mjs +48 -32
  35. package/dist/trace.d.ts +1 -2
  36. package/dist/trace.js +0 -1
  37. package/dist/trace.mjs +1 -1
  38. package/dist/type/bridge.d.ts +6 -6
  39. package/dist/type/constants.d.ts +1 -1
  40. package/dist/type/elysia/file-type.d.ts +1 -1
  41. package/dist/type/types.d.ts +1 -1
  42. package/dist/type/validator/index.d.ts +2 -2
  43. package/dist/types.d.ts +25 -6
  44. package/dist/utils.d.ts +3 -2
  45. package/dist/utils.js +22 -6
  46. package/dist/utils.mjs +22 -7
  47. package/dist/validator/index.d.ts +1 -1
  48. package/dist/ws/route.js +11 -10
  49. package/dist/ws/route.mjs +12 -11
  50. package/package.json +6 -5
@@ -4,7 +4,6 @@ import { HTTPHeaders } from "../types.js";
4
4
  import { Context } from "../context.js";
5
5
  //#region src/adapter/utils.d.ts
6
6
  declare function handleFile(response: File | Blob, set?: Context['set'], request?: Request): Response;
7
- declare function normalizeHeaders(set: Context['set']): void;
8
7
  declare function parseSetCookies(headers: Headers, setCookie: string[]): Headers;
9
8
  declare function responseToSetHeaders(response: Response, set?: Context['set']): {
10
9
  headers: HTTPHeaders;
@@ -24,8 +23,6 @@ declare function createStreamHandler({
24
23
  }: CreateHandlerParameter): (generator: Generator | AsyncGenerator | ReadableStream, set?: Context["set"], request?: Request, skipFormat?: boolean) => Promise<Response>;
25
24
  declare function streamResponse(response: Response): AsyncGenerator<any, void, any>;
26
25
  declare function handleSet(set: Context['set']): void;
27
- declare function mergeHeaders(responseHeaders: Headers, setHeaders: Context['set']['headers']): Headers;
28
- declare function mergeStatus(responseStatus: number, setStatus: Context['set']['status']): number | undefined;
29
26
  declare function createResponseHandler(handler: CreateHandlerParameter): (response: Response, set?: Context["set"], request?: Request) => any;
30
27
  /**
31
28
  * Split async source into `branches` independent iterators
@@ -47,4 +44,4 @@ declare function createResponseHandler(handler: CreateHandlerParameter): (respon
47
44
  */
48
45
  declare function tee<T>(source: AsyncIterable<T>, branches?: number, cap?: number, capBytes?: number): AsyncIterableIterator<T>[];
49
46
  //#endregion
50
- export { createResponseHandler, createStreamHandler, handleFile, handleSet, mergeHeaders, mergeStatus, normalizeHeaders, parseSetCookies, responseToSetHeaders, streamResponse, tee };
47
+ export { createResponseHandler, createStreamHandler, handleFile, handleSet, parseSetCookies, responseToSetHeaders, streamResponse, tee };
@@ -7,6 +7,8 @@ const require_cookie_serialize = require('../cookie/serialize.js');
7
7
 
8
8
  //#region src/adapter/utils.ts
9
9
  const setCookie = "set-cookie";
10
+ const sseFormat = (data) => `data: ${data}\n\n`;
11
+ const identityFormat = (data) => data;
10
12
  const textEncoder = new TextEncoder();
11
13
  const encodeChunk = (s) => textEncoder.encode(s);
12
14
  function handleFile(response, set, request) {
@@ -144,7 +146,7 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
144
146
  return mapCompactResponse(init.value, request);
145
147
  }
146
148
  const isSSE = !skipFormat && (init?.value?.sse ?? generator?.sse ?? (set?.headers instanceof Headers ? set.headers.get("content-type")?.startsWith("text/event-stream") : set?.headers["content-type"]?.startsWith("text/event-stream")));
147
- const format = isSSE ? (data) => `data: ${data}\n\n` : (data) => data;
149
+ const format = isSSE ? sseFormat : identityFormat;
148
150
  const contentType = isSSE ? "text/event-stream" : init?.value && typeof init?.value === "object" ? ArrayBuffer.isView(init.value) ? "application/octet-stream" : "application/json" : "text/plain";
149
151
  const headers = set?.headers;
150
152
  if (headers instanceof Headers) {
@@ -489,9 +491,6 @@ exports.createResponseHandler = createResponseHandler;
489
491
  exports.createStreamHandler = createStreamHandler;
490
492
  exports.handleFile = handleFile;
491
493
  exports.handleSet = handleSet;
492
- exports.mergeHeaders = mergeHeaders;
493
- exports.mergeStatus = mergeStatus;
494
- exports.normalizeHeaders = normalizeHeaders;
495
494
  exports.parseSetCookies = parseSetCookies;
496
495
  exports.responseToSetHeaders = responseToSetHeaders;
497
496
  exports.streamResponse = streamResponse;
@@ -6,6 +6,8 @@ import { serializeCookie } from "../cookie/serialize.mjs";
6
6
 
7
7
  //#region src/adapter/utils.ts
8
8
  const setCookie = "set-cookie";
9
+ const sseFormat = (data) => `data: ${data}\n\n`;
10
+ const identityFormat = (data) => data;
9
11
  const textEncoder = new TextEncoder();
10
12
  const encodeChunk = (s) => textEncoder.encode(s);
11
13
  function handleFile(response, set, request) {
@@ -143,7 +145,7 @@ function createStreamHandler({ mapResponse, mapCompactResponse }) {
143
145
  return mapCompactResponse(init.value, request);
144
146
  }
145
147
  const isSSE = !skipFormat && (init?.value?.sse ?? generator?.sse ?? (set?.headers instanceof Headers ? set.headers.get("content-type")?.startsWith("text/event-stream") : set?.headers["content-type"]?.startsWith("text/event-stream")));
146
- const format = isSSE ? (data) => `data: ${data}\n\n` : (data) => data;
148
+ const format = isSSE ? sseFormat : identityFormat;
147
149
  const contentType = isSSE ? "text/event-stream" : init?.value && typeof init?.value === "object" ? ArrayBuffer.isView(init.value) ? "application/octet-stream" : "application/json" : "text/plain";
148
150
  const headers = set?.headers;
149
151
  if (headers instanceof Headers) {
@@ -484,4 +486,4 @@ function tee(source, branches = 2, cap = 64, capBytes = 1 << 22) {
484
486
  }
485
487
 
486
488
  //#endregion
487
- export { createResponseHandler, createStreamHandler, handleFile, handleSet, mergeHeaders, mergeStatus, normalizeHeaders, parseSetCookies, responseToSetHeaders, streamResponse, tee };
489
+ export { createResponseHandler, createStreamHandler, handleFile, handleSet, parseSetCookies, responseToSetHeaders, streamResponse, tee };
package/dist/base.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { ElysiaStatus } from "./error.js";
2
2
  import { TraceHandler } from "./trace.js";
3
+ import { AnySchema } from "./type/types.js";
3
4
  import { ListenCallback, Serve, Server } from "./universal/server.js";
4
5
  import { AddRoute, AddWSRoute, AfterHandler, AfterResponseHandler, AnyErrorConstructor, AnyLocalHook, BodyHandler, CompiledHandler, CreateEden, DefaultEphemeral, DefaultMetadata, DefaultSingleton, DefinitionBase, DocumentDecoration, ElysiaConfig, ElysiaHandlerToResponseSchemaAmbiguous, EphemeralType, ErrorDefinitionEntry, ErrorHandler, EventScope, ExcludeElysiaResponse, ExtractErrorFromHandle, GlobalHookReturn, GracefulHandler, GuardHookSingleton, GuardLocalHook, HTTPMethod, HookContextSchema, HookContextSingleton, InlineHandler, InlineHandlerNonMacro, InputSchema, InputSchemaKey, InternalRoute, IntersectIfObjectSchema, JoinPath, LocalHook, LocalHookReturn, Macro, MacroSchemaChannel, MacroToContext, MacroToProperty, MapResponse, MaybeArray, MaybePromise, MergeElysiaInstances, MergeSchema, MergeScopedSchemas, MetadataBase, NonResolvableMacroKey, ObjectMacroDefs, OptionalHandler, PluginHookReturn, PreHandler, Prettify, PublicRoute, ResolveRouteErrors, RouteBase, SingletonBase, TransformHandler, UnionResponseStatus, UnwrapRoute, WrapFn } from "./types.js";
5
- import { AnySchema } from "./type/types.js";
6
6
  import { ChainNode } from "./utils.js";
7
7
  import { Context, ErrorContext, LifecycleContext } from "./context.js";
8
8
  import { WSHandlerResponse, WSLocalHook, WSMessageHandler } from "./ws/types.js";
@@ -523,9 +523,9 @@ declare class Elysia<const in out BasePath extends string = '', const in out Sco
523
523
  * .get('/', ({ user }) => user, { auth: true, role: 'admin' })
524
524
  * ```
525
525
  */
526
- macro<const Body extends MacroSchemaChannel<Definitions>, const Headers extends MacroSchemaChannel<Definitions>, const Query extends MacroSchemaChannel<Definitions>, const Params extends MacroSchemaChannel<Definitions>, const Cookie extends MacroSchemaChannel<Definitions>, const NewMacro>(macro: ObjectMacroDefs<Body, Headers, Query, Params, Cookie, NewMacro, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, MergeScopedSchemas<Metadata['schemas'], Ephemeral['schemas'], Volatile['schemas']>, Singleton & {
526
+ macro<const Body extends MacroSchemaChannel<Definitions>, const Headers extends MacroSchemaChannel<Definitions>, const Query extends MacroSchemaChannel<Definitions>, const Params extends MacroSchemaChannel<Definitions>, const Cookie extends MacroSchemaChannel<Definitions>, const NewMacro, const Refs = {}>(macro: ObjectMacroDefs<Body, Headers, Query, Params, Cookie, NewMacro, MergeSchema<Volatile['schema'], MergeSchema<Ephemeral['schema'], Metadata['schema']>>, MergeScopedSchemas<Metadata['schemas'], Ephemeral['schemas'], Volatile['schemas']>, Singleton & {
527
527
  derive: Partial<Ephemeral['derive'] & Volatile['derive']>;
528
- }, Definitions, Metadata['macro']>): Elysia<BasePath, Scope, Singleton, Definitions, {
528
+ }, Definitions, Metadata['macro'], Metadata['macroFn'], Refs>): Elysia<BasePath, Scope, Singleton, Definitions, {
529
529
  schema: Metadata['schema'];
530
530
  schemas: Metadata['schemas'];
531
531
  macro: Metadata['macro'] & Partial<MacroToProperty<NewMacro>>;
package/dist/base.js CHANGED
@@ -641,13 +641,25 @@ var Elysia = class Elysia {
641
641
  if (error) if (ext.error) for (const [code, handler] of error) ext.error.set(code, handler);
642
642
  else ext.error = new Map(error);
643
643
  if (hoc) if (ext.hoc) {
644
- for (const fn of hoc) if (!ext.hoc.includes(fn)) ext.hoc.push(fn);
644
+ const seen = new Set(ext.hoc);
645
+ for (const fn of hoc) if (!seen.has(fn)) {
646
+ seen.add(fn);
647
+ ext.hoc.push(fn);
648
+ }
645
649
  } else ext.hoc = hoc.slice();
646
650
  if (setup) if (ext.setup) {
647
- for (const fn of setup) if (!ext.setup.includes(fn)) ext.setup.push(fn);
651
+ const seen = new Set(ext.setup);
652
+ for (const fn of setup) if (!seen.has(fn)) {
653
+ seen.add(fn);
654
+ ext.setup.push(fn);
655
+ }
648
656
  } else ext.setup = setup.slice();
649
657
  if (cleanup) if (ext.cleanup) {
650
- for (const fn of cleanup) if (!ext.cleanup.includes(fn)) ext.cleanup.push(fn);
658
+ const seen = new Set(ext.cleanup);
659
+ for (const fn of cleanup) if (!seen.has(fn)) {
660
+ seen.add(fn);
661
+ ext.cleanup.push(fn);
662
+ }
651
663
  } else ext.cleanup = cleanup.slice();
652
664
  }
653
665
  if (app.#hasPlugin || app.#hasGlobal || hookChain) {
@@ -1095,19 +1107,18 @@ var Elysia = class Elysia {
1095
1107
  this.#initMap();
1096
1108
  const methods = this["~map"];
1097
1109
  const length = this.#history.length;
1098
- let explicitHead;
1099
- if (enableAutoHead) {
1100
- for (let i = 0; i < length; i++) if (require_utils.mapMethodBack(this.#history[i][0]) === "HEAD") (explicitHead ??= /* @__PURE__ */ new Set()).add(this.#history[i][1]);
1101
- }
1102
1110
  const wrapHeadHandler = Elysia.#wrapHeadHandler;
1103
1111
  const isLoose = this["~config"]?.strictPath !== true;
1112
+ let explicitHead;
1104
1113
  let explicitPaths;
1105
- if (isLoose) {
1106
- explicitPaths = /* @__PURE__ */ new Map();
1107
- for (let i = 0; i < length; i++) {
1108
- const route = this.#history[i];
1109
- const m = route[0] === "WS" ? "WS" : require_utils.mapMethodBack(route[0]);
1110
- const p = route[1];
1114
+ if (isLoose) explicitPaths = /* @__PURE__ */ new Map();
1115
+ if (enableAutoHead || isLoose) for (let i = 0; i < length; i++) {
1116
+ const route = this.#history[i];
1117
+ const isWS = route[0] === "WS";
1118
+ const m = isWS ? "WS" : require_utils.mapMethodBack(route[0]);
1119
+ const p = route[1];
1120
+ if (enableAutoHead && !isWS && m === "HEAD") (explicitHead ??= /* @__PURE__ */ new Set()).add(p);
1121
+ if (explicitPaths) {
1111
1122
  let set = explicitPaths.get(m);
1112
1123
  if (!set) explicitPaths.set(m, set = /* @__PURE__ */ new Set());
1113
1124
  set.add(p);
@@ -1153,9 +1164,10 @@ var Elysia = class Elysia {
1153
1164
  }
1154
1165
  const autoHead = enableAutoHead && method === "GET" && !explicitHead?.has(path);
1155
1166
  const isDynamic = require_constants.isDynamicRegex.test(path);
1167
+ const needsEncode = require_constants.needEncodeRegex.test(path);
1156
1168
  const registerLoose = !isDynamic && isLoose && (path.length === 0 || path.charCodeAt(path.length - 1) === 47);
1157
1169
  const explicitMain = registerLoose ? explicitPaths?.get(method) : void 0;
1158
- if (!isDynamic && !require_constants.needEncodeRegex.test(path) && !registerLoose) {
1170
+ if (!isDynamic && !needsEncode && !registerLoose) {
1159
1171
  const map = methods[method] ??= require_utils.nullObject();
1160
1172
  const handler = this.handler(i, precompile, route, void 0, autoHead ? {
1161
1173
  method,
@@ -1170,7 +1182,7 @@ var Elysia = class Elysia {
1170
1182
  continue;
1171
1183
  }
1172
1184
  const variants = [path];
1173
- if (require_constants.needEncodeRegex.test(path)) {
1185
+ if (needsEncode) {
1174
1186
  const encoded = encodeURI(path);
1175
1187
  if (encoded !== path) variants.push(encoded);
1176
1188
  }
package/dist/base.mjs CHANGED
@@ -638,13 +638,25 @@ var Elysia = class Elysia {
638
638
  if (error) if (ext.error) for (const [code, handler] of error) ext.error.set(code, handler);
639
639
  else ext.error = new Map(error);
640
640
  if (hoc) if (ext.hoc) {
641
- for (const fn of hoc) if (!ext.hoc.includes(fn)) ext.hoc.push(fn);
641
+ const seen = new Set(ext.hoc);
642
+ for (const fn of hoc) if (!seen.has(fn)) {
643
+ seen.add(fn);
644
+ ext.hoc.push(fn);
645
+ }
642
646
  } else ext.hoc = hoc.slice();
643
647
  if (setup) if (ext.setup) {
644
- for (const fn of setup) if (!ext.setup.includes(fn)) ext.setup.push(fn);
648
+ const seen = new Set(ext.setup);
649
+ for (const fn of setup) if (!seen.has(fn)) {
650
+ seen.add(fn);
651
+ ext.setup.push(fn);
652
+ }
645
653
  } else ext.setup = setup.slice();
646
654
  if (cleanup) if (ext.cleanup) {
647
- for (const fn of cleanup) if (!ext.cleanup.includes(fn)) ext.cleanup.push(fn);
655
+ const seen = new Set(ext.cleanup);
656
+ for (const fn of cleanup) if (!seen.has(fn)) {
657
+ seen.add(fn);
658
+ ext.cleanup.push(fn);
659
+ }
648
660
  } else ext.cleanup = cleanup.slice();
649
661
  }
650
662
  if (app.#hasPlugin || app.#hasGlobal || hookChain) {
@@ -1092,19 +1104,18 @@ var Elysia = class Elysia {
1092
1104
  this.#initMap();
1093
1105
  const methods = this["~map"];
1094
1106
  const length = this.#history.length;
1095
- let explicitHead;
1096
- if (enableAutoHead) {
1097
- for (let i = 0; i < length; i++) if (mapMethodBack(this.#history[i][0]) === "HEAD") (explicitHead ??= /* @__PURE__ */ new Set()).add(this.#history[i][1]);
1098
- }
1099
1107
  const wrapHeadHandler = Elysia.#wrapHeadHandler;
1100
1108
  const isLoose = this["~config"]?.strictPath !== true;
1109
+ let explicitHead;
1101
1110
  let explicitPaths;
1102
- if (isLoose) {
1103
- explicitPaths = /* @__PURE__ */ new Map();
1104
- for (let i = 0; i < length; i++) {
1105
- const route = this.#history[i];
1106
- const m = route[0] === "WS" ? "WS" : mapMethodBack(route[0]);
1107
- const p = route[1];
1111
+ if (isLoose) explicitPaths = /* @__PURE__ */ new Map();
1112
+ if (enableAutoHead || isLoose) for (let i = 0; i < length; i++) {
1113
+ const route = this.#history[i];
1114
+ const isWS = route[0] === "WS";
1115
+ const m = isWS ? "WS" : mapMethodBack(route[0]);
1116
+ const p = route[1];
1117
+ if (enableAutoHead && !isWS && m === "HEAD") (explicitHead ??= /* @__PURE__ */ new Set()).add(p);
1118
+ if (explicitPaths) {
1108
1119
  let set = explicitPaths.get(m);
1109
1120
  if (!set) explicitPaths.set(m, set = /* @__PURE__ */ new Set());
1110
1121
  set.add(p);
@@ -1150,9 +1161,10 @@ var Elysia = class Elysia {
1150
1161
  }
1151
1162
  const autoHead = enableAutoHead && method === "GET" && !explicitHead?.has(path);
1152
1163
  const isDynamic = isDynamicRegex.test(path);
1164
+ const needsEncode = needEncodeRegex.test(path);
1153
1165
  const registerLoose = !isDynamic && isLoose && (path.length === 0 || path.charCodeAt(path.length - 1) === 47);
1154
1166
  const explicitMain = registerLoose ? explicitPaths?.get(method) : void 0;
1155
- if (!isDynamic && !needEncodeRegex.test(path) && !registerLoose) {
1167
+ if (!isDynamic && !needsEncode && !registerLoose) {
1156
1168
  const map = methods[method] ??= nullObject();
1157
1169
  const handler = this.handler(i, precompile, route, void 0, autoHead ? {
1158
1170
  method,
@@ -1167,7 +1179,7 @@ var Elysia = class Elysia {
1167
1179
  continue;
1168
1180
  }
1169
1181
  const variants = [path];
1170
- if (needEncodeRegex.test(path)) {
1182
+ if (needsEncode) {
1171
1183
  const encoded = encodeURI(path);
1172
1184
  if (encoded !== path) variants.push(encoded);
1173
1185
  }
@@ -1,5 +1,5 @@
1
- import { AnyLocalHook, HTTPMethod } from "../../types.js";
2
1
  import { CapturedValidator, FrozenValidator } from "../aot.js";
2
+ import { AnyLocalHook, HTTPMethod } from "../../types.js";
3
3
  import { AnyElysia } from "../../base.js";
4
4
 
5
5
  //#region src/compile/handler/frozen-validator.d.ts
@@ -79,11 +79,6 @@ var FrozenSlotValidator = class {
79
79
  #applyDefault(value) {
80
80
  return this.#defaultFastPath.merge(value);
81
81
  }
82
- #optionalBypass(value) {
83
- const schema = this.schema;
84
- if (value === void 0 || value === null) return { value: schema["~kind"] === "Object" ? require_utils.nullObject() : value };
85
- if (schema["~kind"] === "Object" && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0) return { value: require_utils.nullObject() };
86
- }
87
82
  From(value, type) {
88
83
  if (this.#hasDefault) {
89
84
  const defaults = this.#defaultFastPath;
@@ -93,8 +88,9 @@ var FrozenSlotValidator = class {
93
88
  }
94
89
  }
95
90
  if (this.#hasOptional) {
96
- const bypass = this.#optionalBypass(value);
97
- if (bypass) return bypass.value;
91
+ const schema = this.schema;
92
+ if (value === void 0 || value === null) return schema["~kind"] === "Object" ? require_utils.nullObject() : value;
93
+ if (schema["~kind"] === "Object" && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0) return require_utils.nullObject();
98
94
  }
99
95
  if (!this.#noValidate && !this.#check(value)) throw this.#error(value, type);
100
96
  if (this.#decode) return this.#decode(value);
@@ -78,11 +78,6 @@ var FrozenSlotValidator = class {
78
78
  #applyDefault(value) {
79
79
  return this.#defaultFastPath.merge(value);
80
80
  }
81
- #optionalBypass(value) {
82
- const schema = this.schema;
83
- if (value === void 0 || value === null) return { value: schema["~kind"] === "Object" ? nullObject() : value };
84
- if (schema["~kind"] === "Object" && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0) return { value: nullObject() };
85
- }
86
81
  From(value, type) {
87
82
  if (this.#hasDefault) {
88
83
  const defaults = this.#defaultFastPath;
@@ -92,8 +87,9 @@ var FrozenSlotValidator = class {
92
87
  }
93
88
  }
94
89
  if (this.#hasOptional) {
95
- const bypass = this.#optionalBypass(value);
96
- if (bypass) return bypass.value;
90
+ const schema = this.schema;
91
+ if (value === void 0 || value === null) return schema["~kind"] === "Object" ? nullObject() : value;
92
+ if (schema["~kind"] === "Object" && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0) return nullObject();
97
93
  }
98
94
  if (!this.#noValidate && !this.#check(value)) throw this.#error(value, type);
99
95
  if (this.#decode) return this.#decode(value);
@@ -188,8 +188,8 @@ const chainResolver = (root) => root["~ext"]?.macro || root["~scopeChildren"] ?
188
188
  const localMacroRoot = (instance, root) => instance !== root && instance["~scopeChild"] === true && instance["~ext"]?.macro ? instance : root;
189
189
  function composeRootHook(root, inheritedChain) {
190
190
  const resolve = chainResolver(root);
191
- const inherited = require_utils.flattenChainMemo(root, inheritedChain, resolve);
192
191
  const locals = require_utils.flattenChain(root["~hookChain"], require_utils.isLocalScope, inheritedChain, resolve);
192
+ const inherited = locals ? require_utils.flattenChainMemo(root, inheritedChain, resolve) : require_utils.flattenChainMemoReadonly(root, inheritedChain, resolve);
193
193
  if (!inherited) return locals;
194
194
  if (!locals) return inherited;
195
195
  return require_utils.mergeHook(inherited, locals);
@@ -232,7 +232,7 @@ function composeRouteHook(instance, localHook, appHook, inheritedChain, root, ma
232
232
  const resolve = chainResolver(root);
233
233
  localHook = resolveLocalHook(localMacroRoot(macroScope ?? instance, root), localHook, root);
234
234
  const flatAppHook = appHook ? require_utils.flattenChainMemo(root, appHook, resolve) : void 0;
235
- let inherited = instance !== root ? require_utils.flattenChainMemo(root, inheritedChain, resolve) : void 0;
235
+ let inherited = instance !== root ? require_utils.flattenChainMemoReadonly(root, inheritedChain, resolve) : void 0;
236
236
  let locals = instance !== root ? require_utils.flattenChain(root["~hookChain"], require_utils.isLocalScope, inheritedChain, resolve) : void 0;
237
237
  if ((inherited || locals) && (flatAppHook || localHook)) {
238
238
  const present = /* @__PURE__ */ new Set();
@@ -1,4 +1,4 @@
1
- import { cloneHook, eventProperties, flattenChain, flattenChainMemo, fnOrigin, isLocalScope, macroEpoch, mapMethodBack, mergeHook, nullObject, replaceUrlPath } from "../../utils.mjs";
1
+ import { cloneHook, eventProperties, flattenChain, flattenChainMemo, flattenChainMemoReadonly, fnOrigin, isLocalScope, macroEpoch, mapMethodBack, mergeHook, nullObject, replaceUrlPath } from "../../utils.mjs";
2
2
  import { Compiled } from "../aot.mjs";
3
3
  import { resolveHandlerParams } from "./params.mjs";
4
4
  import { compileHandlerJit, setCaptureHeaderShorthand } from "./jit.mjs";
@@ -187,8 +187,8 @@ const chainResolver = (root) => root["~ext"]?.macro || root["~scopeChildren"] ?
187
187
  const localMacroRoot = (instance, root) => instance !== root && instance["~scopeChild"] === true && instance["~ext"]?.macro ? instance : root;
188
188
  function composeRootHook(root, inheritedChain) {
189
189
  const resolve = chainResolver(root);
190
- const inherited = flattenChainMemo(root, inheritedChain, resolve);
191
190
  const locals = flattenChain(root["~hookChain"], isLocalScope, inheritedChain, resolve);
191
+ const inherited = locals ? flattenChainMemo(root, inheritedChain, resolve) : flattenChainMemoReadonly(root, inheritedChain, resolve);
192
192
  if (!inherited) return locals;
193
193
  if (!locals) return inherited;
194
194
  return mergeHook(inherited, locals);
@@ -231,7 +231,7 @@ function composeRouteHook(instance, localHook, appHook, inheritedChain, root, ma
231
231
  const resolve = chainResolver(root);
232
232
  localHook = resolveLocalHook(localMacroRoot(macroScope ?? instance, root), localHook, root);
233
233
  const flatAppHook = appHook ? flattenChainMemo(root, appHook, resolve) : void 0;
234
- let inherited = instance !== root ? flattenChainMemo(root, inheritedChain, resolve) : void 0;
234
+ let inherited = instance !== root ? flattenChainMemoReadonly(root, inheritedChain, resolve) : void 0;
235
235
  let locals = instance !== root ? flattenChain(root["~hookChain"], isLocalScope, inheritedChain, resolve) : void 0;
236
236
  if ((inherited || locals) && (flatAppHook || localHook)) {
237
237
  const present = /* @__PURE__ */ new Set();
@@ -18,7 +18,14 @@ const require_compile_jit_probe = require('../jit-probe.js');
18
18
  //#region src/compile/handler/jit.ts
19
19
  const parseFormData = "c.body=await pf(c)\n";
20
20
  const matchReturnIdentifier = /(?:=>\s*|\breturn\s+)(?!(?:true|false|null|undefined|void|new|typeof|async|await|function|class)\b)[A-Za-z_$][\w$]*(?:\s*\.\s*[A-Za-z_$][\w$]*)*\s*(?![\w$([])/;
21
- const mayReturnIdentifier = (fn) => matchReturnIdentifier.test(fn.toString());
21
+ const mayReturnIdentifierCache = /* @__PURE__ */ new WeakMap();
22
+ const mayReturnIdentifier = (fn) => {
23
+ let result = mayReturnIdentifierCache.get(fn);
24
+ if (result !== void 0) return result;
25
+ result = matchReturnIdentifier.test(fn.toString());
26
+ mayReturnIdentifierCache.set(fn, result);
27
+ return result;
28
+ };
22
29
  const lifecycleMayReturnPromise = (handlers, observed) => handlers ? Array.isArray(handlers) ? handlers.some((fn) => !require_compile_utils.isAsyncFunction(fn) && (require_compile_utils.mayReturnPromise(fn) || observed && mayReturnIdentifier(fn))) : !require_compile_utils.isAsyncFunction(handlers) && (require_compile_utils.mayReturnPromise(handlers) || observed && mayReturnIdentifier(handlers)) : false;
23
30
  let captureHeaderShorthand;
24
31
  const setCaptureHeaderShorthand = (value) => {
@@ -303,15 +310,16 @@ function compileHandlerJit({ method, path, handler, root, hook, adapter, buildVa
303
310
  if (cookieConfig) {
304
311
  link(require_cookie_utils.buildCookieJar, "bcj");
305
312
  link(cookieConfig, "cc");
313
+ const cookieHeaderExpr = hasHeaders && !vali?.headers ? "c.headers['cookie']" : "c.request.headers.get('cookie')";
306
314
  if (!hasCookieSign && !cookieValidIsAsync) {
307
315
  link(require_cookie_utils.parseCookieRawSync, "pcrs");
308
- code += `let _ck=pcrs(c.request.headers.get('cookie'),cc)\n`;
316
+ code += `let _ck=pcrs(${cookieHeaderExpr},cc)\n`;
309
317
  } else if (syncCookieSign && !cookieValidIsAsync) {
310
318
  link(require_cookie_utils.parseCookieRawSigned, "pcrsg");
311
- code += `let _ck=pcrsg(c.request.headers.get('cookie'),cc)\n`;
319
+ code += `let _ck=pcrsg(${cookieHeaderExpr},cc)\n`;
312
320
  } else {
313
321
  link(require_cookie_utils.parseCookieRaw, "pcr");
314
- code += `let _ck=await pcr(c.request.headers.get('cookie'),cc)\n`;
322
+ code += `let _ck=await pcr(${cookieHeaderExpr},cc)\n`;
315
323
  }
316
324
  if (vali?.cookie) {
317
325
  link(vali, "va");
@@ -17,7 +17,14 @@ import { JITProbe } from "../jit-probe.mjs";
17
17
  //#region src/compile/handler/jit.ts
18
18
  const parseFormData = "c.body=await pf(c)\n";
19
19
  const matchReturnIdentifier = /(?:=>\s*|\breturn\s+)(?!(?:true|false|null|undefined|void|new|typeof|async|await|function|class)\b)[A-Za-z_$][\w$]*(?:\s*\.\s*[A-Za-z_$][\w$]*)*\s*(?![\w$([])/;
20
- const mayReturnIdentifier = (fn) => matchReturnIdentifier.test(fn.toString());
20
+ const mayReturnIdentifierCache = /* @__PURE__ */ new WeakMap();
21
+ const mayReturnIdentifier = (fn) => {
22
+ let result = mayReturnIdentifierCache.get(fn);
23
+ if (result !== void 0) return result;
24
+ result = matchReturnIdentifier.test(fn.toString());
25
+ mayReturnIdentifierCache.set(fn, result);
26
+ return result;
27
+ };
21
28
  const lifecycleMayReturnPromise = (handlers, observed) => handlers ? Array.isArray(handlers) ? handlers.some((fn) => !isAsyncFunction(fn) && (mayReturnPromise(fn) || observed && mayReturnIdentifier(fn))) : !isAsyncFunction(handlers) && (mayReturnPromise(handlers) || observed && mayReturnIdentifier(handlers)) : false;
22
29
  let captureHeaderShorthand;
23
30
  const setCaptureHeaderShorthand = (value) => {
@@ -302,15 +309,16 @@ function compileHandlerJit({ method, path, handler, root, hook, adapter, buildVa
302
309
  if (cookieConfig) {
303
310
  link(buildCookieJar, "bcj");
304
311
  link(cookieConfig, "cc");
312
+ const cookieHeaderExpr = hasHeaders && !vali?.headers ? "c.headers['cookie']" : "c.request.headers.get('cookie')";
305
313
  if (!hasCookieSign && !cookieValidIsAsync) {
306
314
  link(parseCookieRawSync, "pcrs");
307
- code += `let _ck=pcrs(c.request.headers.get('cookie'),cc)\n`;
315
+ code += `let _ck=pcrs(${cookieHeaderExpr},cc)\n`;
308
316
  } else if (syncCookieSign && !cookieValidIsAsync) {
309
317
  link(parseCookieRawSigned, "pcrsg");
310
- code += `let _ck=pcrsg(c.request.headers.get('cookie'),cc)\n`;
318
+ code += `let _ck=pcrsg(${cookieHeaderExpr},cc)\n`;
311
319
  } else {
312
320
  link(parseCookieRaw, "pcr");
313
- code += `let _ck=await pcr(c.request.headers.get('cookie'),cc)\n`;
321
+ code += `let _ck=await pcr(${cookieHeaderExpr},cc)\n`;
314
322
  }
315
323
  if (vali?.cookie) {
316
324
  link(vali, "va");
@@ -24,9 +24,10 @@ const HANDLER_PARAMS = {
24
24
  pq: () => require_parse_query.parseQueryFromURL,
25
25
  pe: () => require_error.ParseError,
26
26
  es: () => require_error.ElysiaStatus,
27
+ rdc: () => require_compile_handler_utils.replaceDeriveContext,
27
28
  ise: () => require_error.internalServerErrorResponse,
28
29
  emp: () => require_handler_utils.emptyResponse,
29
- isprod: () => require_error.isProduction,
30
+ isprod: require_error.isProduction,
30
31
  verr: () => require_error.ValidationError,
31
32
  tee: () => require_adapter_utils.tee,
32
33
  cr: () => require_compile_handler_utils.cloneResponse,
@@ -4,7 +4,7 @@ import { tee } from "../../adapter/utils.mjs";
4
4
  import { parseQueryFromURL } from "../../parse-query.mjs";
5
5
  import { buildCookieJar, parseCookieRaw, parseCookieRawSigned, parseCookieRawSync, signCookieValues, signCookieValuesSync } from "../../cookie/utils.mjs";
6
6
  import { emptyResponse, forwardError } from "../../handler/utils.mjs";
7
- import { cloneResponse, getQueryParseChannels, hasRequestBody } from "./utils.mjs";
7
+ import { cloneResponse, getQueryParseChannels, hasRequestBody, replaceDeriveContext } from "./utils.mjs";
8
8
 
9
9
  //#region src/compile/handler/params.ts
10
10
  const HANDLER_PARAMS = {
@@ -23,9 +23,10 @@ const HANDLER_PARAMS = {
23
23
  pq: () => parseQueryFromURL,
24
24
  pe: () => ParseError,
25
25
  es: () => ElysiaStatus,
26
+ rdc: () => replaceDeriveContext,
26
27
  ise: () => internalServerErrorResponse,
27
28
  emp: () => emptyResponse,
28
- isprod: () => isProduction,
29
+ isprod: isProduction,
29
30
  verr: () => ValidationError,
30
31
  tee: () => tee,
31
32
  cr: () => cloneResponse,
@@ -17,6 +17,7 @@ declare const mapTransform: (event: MaybeArray<TransformHandler<any, any, undefi
17
17
  declare function extractDeriveKeys(fn: Function): string[] | null;
18
18
  declare function replaceDeriveContext(context: any, derivative: any): any;
19
19
  declare function deriveModeQueues(entries?: readonly DeriveEntry[]): Map<Function, boolean[]> | undefined;
20
+ declare function deriveModes(hooks: Function[], entries?: readonly DeriveEntry[]): (boolean | undefined)[] | undefined;
20
21
  declare function mapBeforeHandle(_hooks: AppHook['beforeHandle'] | AppHook['beforeHandle'][0], derive: readonly DeriveEntry[] | undefined, link: Link, isAsync: boolean, report?: TraceReporter, abortGuard?: string): string;
21
22
  declare const mapAfterHandle: (_hooks: AppHook["afterHandle"] | AppHook["afterHandle"][0], isAsync: boolean, report?: TraceReporter, abortGuard?: string) => string;
22
23
  declare const mapMapResponse: (_hooks: AppHook["mapResponse"] | AppHook["mapResponse"][0], isAsync: boolean, report?: TraceReporter, abortGuard?: string) => string;
@@ -28,4 +29,4 @@ interface QueryWalkState {
28
29
  }
29
30
  declare function getQueryParseChannels(querySchema: any): QueryWalkState | undefined;
30
31
  //#endregion
31
- export { Link, TraceReporter, cloneResponse, deriveModeQueues, emptyResponse, extractDeriveKeys, getQueryParseChannels, hasRequestBody, mapAfterHandle, mapAfterResponse, mapBeforeHandle, mapError, mapMapResponse, mapTransform, replaceDeriveContext };
32
+ export { Link, TraceReporter, cloneResponse, deriveModeQueues, deriveModes, emptyResponse, extractDeriveKeys, getQueryParseChannels, hasRequestBody, mapAfterHandle, mapAfterResponse, mapBeforeHandle, mapError, mapMapResponse, mapTransform, replaceDeriveContext };
@@ -44,26 +44,27 @@ function extractDeriveKeys(fn) {
44
44
  return result;
45
45
  }
46
46
  function replaceDeriveContext(context, derivative) {
47
- Object.setPrototypeOf(derivative, Object.getPrototypeOf(context));
48
- derivative.request = context.request;
49
- derivative.store = context.store;
50
- derivative.set = context.set;
51
- derivative.body = context.body;
52
- derivative.query = context.query;
53
- derivative.params = context.params;
54
- derivative.headers = context.headers;
55
- derivative.cookie = context.cookie;
56
- derivative.server = context.server;
57
- derivative.path = context.path;
58
- derivative.route = context.route;
59
- derivative.rid = context.rid;
60
- derivative.trace = context.trace;
61
- derivative.qi = context.qi;
62
- derivative.responseValue = context.responseValue;
63
- derivative.error = context.error;
64
- derivative.status = context.status;
65
- derivative.redirect = context.redirect;
66
- return derivative;
47
+ const next = Object.create(Object.getPrototypeOf(context));
48
+ Object.assign(next, derivative);
49
+ next.request = context.request;
50
+ next.store = context.store;
51
+ next.set = context.set;
52
+ next.body = context.body;
53
+ next.query = context.query;
54
+ next.params = context.params;
55
+ next.headers = context.headers;
56
+ next.cookie = context.cookie;
57
+ next.server = context.server;
58
+ next.path = context.path;
59
+ next.route = context.route;
60
+ next.rid = context.rid;
61
+ next.trace = context.trace;
62
+ next.qi = context.qi;
63
+ next.responseValue = context.responseValue;
64
+ next.error = context.error;
65
+ next.status = context.status;
66
+ next.redirect = context.redirect;
67
+ return next;
67
68
  }
68
69
  function deriveModeQueues(entries) {
69
70
  if (!entries?.length) return;
@@ -426,15 +427,19 @@ function getQueryParseArgsCollect(node, seen, state) {
426
427
  if (Array.isArray(arr)) for (const x of arr) getQueryParseArgsCollect(x, seen, state);
427
428
  }
428
429
  }
430
+ const queryParseChannelsCache = /* @__PURE__ */ new WeakMap();
429
431
  function getQueryParseChannels(querySchema) {
430
- if (!querySchema) return;
432
+ if (!querySchema || typeof querySchema !== "object") return;
433
+ const cached = queryParseChannelsCache.get(querySchema);
434
+ if (cached !== void 0) return cached ?? void 0;
431
435
  const state = {
432
436
  array: void 0,
433
437
  object: void 0
434
438
  };
435
439
  getQueryParseArgsCollect(querySchema, /* @__PURE__ */ new WeakSet(), state);
436
- if (!state.array && !state.object) return void 0;
437
- return state;
440
+ const result = state.array || state.object ? state : null;
441
+ queryParseChannelsCache.set(querySchema, result);
442
+ return result ?? void 0;
438
443
  }
439
444
  const Await = (fn) => require_compile_utils.isAsyncFunction(fn) ? "await " : "";
440
445
  const awaitGuard = (fn, isAsync, target) => isAsync && !require_compile_utils.isAsyncFunction(fn) ? `if(${target} instanceof Promise)${target}=await ${target}\n` : "";
@@ -442,6 +447,7 @@ const awaitGuard = (fn, isAsync, target) => isAsync && !require_compile_utils.is
442
447
  //#endregion
443
448
  exports.cloneResponse = cloneResponse;
444
449
  exports.deriveModeQueues = deriveModeQueues;
450
+ exports.deriveModes = deriveModes;
445
451
  exports.emptyResponse = require_handler_utils.emptyResponse;
446
452
  exports.extractDeriveKeys = extractDeriveKeys;
447
453
  exports.getQueryParseChannels = getQueryParseChannels;