elysia 2.0.0-beta.4 → 2.0.0-beta.5

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.
@@ -1,6 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_adapter_index = require('../index.js');
3
- const require_constants = require('../../constants.js');
4
3
  const require_utils = require('../../utils.js');
5
4
  const require_adapter_web_standard_index = require('../web-standard/index.js');
6
5
  const require_generation = require('../../generation.js');
@@ -97,6 +96,7 @@ const withOrigin = (fetch) => (request, server) => {
97
96
  require_adapter_origin.origin.request = void 0;
98
97
  }
99
98
  };
99
+ const isNativeStaticMethod = (method) => method === "GET" || method === "POST" || method === "PUT" || method === "DELETE" || method === "PATCH" || method === "HEAD" || method === "OPTIONS";
100
100
  function collectStaticRoutes(app) {
101
101
  if (app["~config"]?.nativeStaticResponse === false) return;
102
102
  app.fetch;
@@ -106,66 +106,57 @@ function collectStaticRoutes(app) {
106
106
  const table = app["~generation"]?.routeTable ?? app["~routeTable"];
107
107
  const length = table?.length ?? 0;
108
108
  if (!table || !length) return;
109
- const { method: methods, path: paths, handler: handlers } = table;
110
- const nativeStaticMethods = new Set([
111
- "GET",
112
- "POST",
113
- "PUT",
114
- "DELETE",
115
- "PATCH",
116
- "HEAD",
117
- "OPTIONS"
118
- ]);
109
+ const { method: methods, path: paths, handler: handlers, flags } = table;
119
110
  let hasCandidate = false;
120
111
  for (let i = 0; i < length; i++) {
112
+ if (!isNativeStaticMethod(methods[i]) || (flags[i] & require_route_table.RouteFlag.Dynamic) !== 0) continue;
121
113
  const h = handlers[i];
122
- if (typeof h === "function" || h instanceof Error || h instanceof Promise) continue;
123
- if (!nativeStaticMethods.has(methods[i])) continue;
124
- hasCandidate = true;
125
- break;
114
+ if (typeof h !== "function" && !(h instanceof Error) && !(h instanceof Promise)) {
115
+ hasCandidate = true;
116
+ break;
117
+ }
126
118
  }
127
119
  if (!hasCandidate) return;
128
- const ready = require_utils.nullObject();
129
120
  const strictPath = frozenRoot["~config"]?.strictPath === true;
130
- const seen = /* @__PURE__ */ new Map();
131
- for (let i = 0; i < length; i++) seen.set(methods[i] + " " + paths[i], i);
132
- let explicitPaths;
133
- if (!strictPath) {
134
- explicitPaths = /* @__PURE__ */ new Map();
135
- for (let i = 0; i < length; i++) {
136
- const method = methods[i];
137
- const path = paths[i];
138
- let set = explicitPaths.get(method);
139
- if (!set) explicitPaths.set(method, set = /* @__PURE__ */ new Set());
140
- set.add(path);
141
- if (require_constants.needEncodeRegex.test(path)) {
142
- const encoded = encodeURI(path);
143
- if (encoded !== path) set.add(encoded);
144
- }
121
+ const routeIndex = /* @__PURE__ */ new Map();
122
+ for (let i = 0; i < length; i++) {
123
+ const method = methods[i];
124
+ if (!isNativeStaticMethod(method) || (flags[i] & require_route_table.RouteFlag.Dynamic) !== 0) continue;
125
+ const path = paths[i];
126
+ let pathsByMethod = routeIndex.get(method);
127
+ if (!pathsByMethod) routeIndex.set(method, pathsByMethod = /* @__PURE__ */ new Map());
128
+ pathsByMethod.set(path, i);
129
+ if (!strictPath && (flags[i] & require_route_table.RouteFlag.Encode) !== 0) {
130
+ const encoded = encodeURI(path);
131
+ if (encoded !== path && !pathsByMethod.has(encoded)) pathsByMethod.set(encoded, -1);
145
132
  }
146
133
  }
147
- const add = (method, path, value) => {
148
- if (require_constants.needEncodeRegex.test(path)) path = encodeURI(path);
134
+ const ready = require_utils.nullObject();
135
+ let hasReady = false;
136
+ const add = (method, path, value, needsEncode) => {
137
+ if (needsEncode) path = encodeURI(path);
149
138
  (ready[path] ??= require_utils.nullObject())[method] = value;
139
+ hasReady = true;
150
140
  };
151
141
  for (let i = 0; i < length; i++) {
152
142
  const method = methods[i];
153
- if (method === "WS") continue;
143
+ const routeFlags = flags[i];
144
+ if (!isNativeStaticMethod(method) || (routeFlags & require_route_table.RouteFlag.Dynamic) !== 0) continue;
145
+ const pathsByMethod = routeIndex.get(method);
154
146
  const path = paths[i];
155
- if (seen.get(method + " " + path) !== i) continue;
156
- if (!nativeStaticMethods.has(method)) continue;
157
- if (require_constants.isDynamicRegex.test(path)) continue;
147
+ if (pathsByMethod.get(path) !== i) continue;
158
148
  const h = handlers[i];
159
149
  if (typeof h === "function" || h instanceof Error || h instanceof Promise) continue;
160
150
  const value = require_compile_handler_index.buildNativeStaticResponse(require_route_table.routeRow(table, i), app);
161
151
  if (!value) continue;
162
- add(method, path, value);
152
+ const needsEncode = (routeFlags & require_route_table.RouteFlag.Encode) !== 0;
153
+ add(method, path, value, needsEncode);
163
154
  if (!strictPath) {
164
155
  const loose = require_utils.getLoosePath(path);
165
- if (loose !== path && !explicitPaths?.get(method)?.has(loose)) add(method, loose, value);
156
+ if (loose !== path && !pathsByMethod.has(loose)) add(method, loose, value, needsEncode);
166
157
  }
167
158
  }
168
- if (!Object.keys(ready).length) return;
159
+ if (!hasReady) return;
169
160
  return ready;
170
161
  }
171
162
  const BunAdapter = require_adapter_index.createAdapter({
@@ -176,31 +167,40 @@ const BunAdapter = require_adapter_index.createAdapter({
176
167
  response: require_adapter_web_standard_index.WebStandardAdapter.response,
177
168
  listen(app, options, callback) {
178
169
  if (app.server || app["~ext"]?.stop) throw new Error("[Elysia] Cannot call listen() while a server or teardown is active");
179
- const _config = app["~config"]?.serve;
170
+ function gatedFetch(request, server) {
171
+ return live ? live(request, server) : Promise.resolve(ready).then(async () => {
172
+ if (!live) {
173
+ await startupShutdown;
174
+ throw new Error("[Elysia] Server was stopped before it was ready");
175
+ }
176
+ return live(request, server);
177
+ });
178
+ }
180
179
  const optionsIsObject = typeof options === "object";
181
- let live;
182
- let cancelled = false;
183
- let startupShutdown;
184
- let shutdownAttempt;
185
- const gatedFetch = (request, server) => live ? live(request, server) : Promise.resolve(ready).then(async () => {
186
- if (!live) {
187
- await startupShutdown;
188
- throw new Error("[Elysia] Server was stopped before it was ready");
189
- }
190
- return live(request, server);
191
- });
192
180
  const _options = optionsIsObject ? { ...options } : {
193
181
  port: +options,
194
182
  fetch: gatedFetch
195
183
  };
196
184
  if (optionsIsObject) _options.fetch = gatedFetch;
185
+ const _config = app["~config"]?.serve;
197
186
  const serve = _config ? {
198
187
  ..._config,
199
188
  ..._options
200
189
  } : _options;
190
+ const server = app.server = Bun.serve(serve.routes || serve.error ? {
191
+ ...serve,
192
+ error: unavailableFetch,
193
+ routes: {}
194
+ } : serve);
195
+ let live;
196
+ let cancelled = false;
197
+ let startupShutdown;
198
+ let shutdownAttempt;
201
199
  let ready;
202
200
  let wsLifecycle;
203
201
  let modulesReady;
202
+ let built;
203
+ let pendingSetups;
204
204
  const build = () => {
205
205
  const fetch = app.fetch;
206
206
  let routes;
@@ -231,13 +231,6 @@ const BunAdapter = require_adapter_index.createAdapter({
231
231
  websocket
232
232
  };
233
233
  };
234
- let built;
235
- let pendingSetups;
236
- const server = app.server = Bun.serve(serve.routes || serve.error ? {
237
- ...serve,
238
- error: unavailableFetch,
239
- routes: {}
240
- } : serve);
241
234
  let startupFailure;
242
235
  let forceRequested = false;
243
236
  let forceDone = false;
@@ -1,11 +1,10 @@
1
1
  import { createAdapter } from "../index.mjs";
2
- import { isDynamicRegex, needEncodeRegex } from "../../constants.mjs";
3
2
  import { flattenChain, getLoosePath, isSocketQuiet, nullObject, throwLifecycleErrors } from "../../utils.mjs";
4
3
  import { WebStandardAdapter } from "../web-standard/index.mjs";
5
4
  import { frozenRootOf, resolvedWsOf } from "../../generation.mjs";
6
5
  import { origin } from "../origin.mjs";
7
6
  import { buildNativeStaticResponse } from "../../compile/handler/index.mjs";
8
- import { routeRow } from "../../route-table.mjs";
7
+ import { RouteFlag, routeRow } from "../../route-table.mjs";
9
8
 
10
9
  //#region src/adapter/bun/index.ts
11
10
  function runLifecycle(epoch, callback, ...args) {
@@ -96,6 +95,7 @@ const withOrigin = (fetch) => (request, server) => {
96
95
  origin.request = void 0;
97
96
  }
98
97
  };
98
+ const isNativeStaticMethod = (method) => method === "GET" || method === "POST" || method === "PUT" || method === "DELETE" || method === "PATCH" || method === "HEAD" || method === "OPTIONS";
99
99
  function collectStaticRoutes(app) {
100
100
  if (app["~config"]?.nativeStaticResponse === false) return;
101
101
  app.fetch;
@@ -105,66 +105,57 @@ function collectStaticRoutes(app) {
105
105
  const table = app["~generation"]?.routeTable ?? app["~routeTable"];
106
106
  const length = table?.length ?? 0;
107
107
  if (!table || !length) return;
108
- const { method: methods, path: paths, handler: handlers } = table;
109
- const nativeStaticMethods = new Set([
110
- "GET",
111
- "POST",
112
- "PUT",
113
- "DELETE",
114
- "PATCH",
115
- "HEAD",
116
- "OPTIONS"
117
- ]);
108
+ const { method: methods, path: paths, handler: handlers, flags } = table;
118
109
  let hasCandidate = false;
119
110
  for (let i = 0; i < length; i++) {
111
+ if (!isNativeStaticMethod(methods[i]) || (flags[i] & RouteFlag.Dynamic) !== 0) continue;
120
112
  const h = handlers[i];
121
- if (typeof h === "function" || h instanceof Error || h instanceof Promise) continue;
122
- if (!nativeStaticMethods.has(methods[i])) continue;
123
- hasCandidate = true;
124
- break;
113
+ if (typeof h !== "function" && !(h instanceof Error) && !(h instanceof Promise)) {
114
+ hasCandidate = true;
115
+ break;
116
+ }
125
117
  }
126
118
  if (!hasCandidate) return;
127
- const ready = nullObject();
128
119
  const strictPath = frozenRoot["~config"]?.strictPath === true;
129
- const seen = /* @__PURE__ */ new Map();
130
- for (let i = 0; i < length; i++) seen.set(methods[i] + " " + paths[i], i);
131
- let explicitPaths;
132
- if (!strictPath) {
133
- explicitPaths = /* @__PURE__ */ new Map();
134
- for (let i = 0; i < length; i++) {
135
- const method = methods[i];
136
- const path = paths[i];
137
- let set = explicitPaths.get(method);
138
- if (!set) explicitPaths.set(method, set = /* @__PURE__ */ new Set());
139
- set.add(path);
140
- if (needEncodeRegex.test(path)) {
141
- const encoded = encodeURI(path);
142
- if (encoded !== path) set.add(encoded);
143
- }
120
+ const routeIndex = /* @__PURE__ */ new Map();
121
+ for (let i = 0; i < length; i++) {
122
+ const method = methods[i];
123
+ if (!isNativeStaticMethod(method) || (flags[i] & RouteFlag.Dynamic) !== 0) continue;
124
+ const path = paths[i];
125
+ let pathsByMethod = routeIndex.get(method);
126
+ if (!pathsByMethod) routeIndex.set(method, pathsByMethod = /* @__PURE__ */ new Map());
127
+ pathsByMethod.set(path, i);
128
+ if (!strictPath && (flags[i] & RouteFlag.Encode) !== 0) {
129
+ const encoded = encodeURI(path);
130
+ if (encoded !== path && !pathsByMethod.has(encoded)) pathsByMethod.set(encoded, -1);
144
131
  }
145
132
  }
146
- const add = (method, path, value) => {
147
- if (needEncodeRegex.test(path)) path = encodeURI(path);
133
+ const ready = nullObject();
134
+ let hasReady = false;
135
+ const add = (method, path, value, needsEncode) => {
136
+ if (needsEncode) path = encodeURI(path);
148
137
  (ready[path] ??= nullObject())[method] = value;
138
+ hasReady = true;
149
139
  };
150
140
  for (let i = 0; i < length; i++) {
151
141
  const method = methods[i];
152
- if (method === "WS") continue;
142
+ const routeFlags = flags[i];
143
+ if (!isNativeStaticMethod(method) || (routeFlags & RouteFlag.Dynamic) !== 0) continue;
144
+ const pathsByMethod = routeIndex.get(method);
153
145
  const path = paths[i];
154
- if (seen.get(method + " " + path) !== i) continue;
155
- if (!nativeStaticMethods.has(method)) continue;
156
- if (isDynamicRegex.test(path)) continue;
146
+ if (pathsByMethod.get(path) !== i) continue;
157
147
  const h = handlers[i];
158
148
  if (typeof h === "function" || h instanceof Error || h instanceof Promise) continue;
159
149
  const value = buildNativeStaticResponse(routeRow(table, i), app);
160
150
  if (!value) continue;
161
- add(method, path, value);
151
+ const needsEncode = (routeFlags & RouteFlag.Encode) !== 0;
152
+ add(method, path, value, needsEncode);
162
153
  if (!strictPath) {
163
154
  const loose = getLoosePath(path);
164
- if (loose !== path && !explicitPaths?.get(method)?.has(loose)) add(method, loose, value);
155
+ if (loose !== path && !pathsByMethod.has(loose)) add(method, loose, value, needsEncode);
165
156
  }
166
157
  }
167
- if (!Object.keys(ready).length) return;
158
+ if (!hasReady) return;
168
159
  return ready;
169
160
  }
170
161
  const BunAdapter = createAdapter({
@@ -175,31 +166,40 @@ const BunAdapter = createAdapter({
175
166
  response: WebStandardAdapter.response,
176
167
  listen(app, options, callback) {
177
168
  if (app.server || app["~ext"]?.stop) throw new Error("[Elysia] Cannot call listen() while a server or teardown is active");
178
- const _config = app["~config"]?.serve;
169
+ function gatedFetch(request, server) {
170
+ return live ? live(request, server) : Promise.resolve(ready).then(async () => {
171
+ if (!live) {
172
+ await startupShutdown;
173
+ throw new Error("[Elysia] Server was stopped before it was ready");
174
+ }
175
+ return live(request, server);
176
+ });
177
+ }
179
178
  const optionsIsObject = typeof options === "object";
180
- let live;
181
- let cancelled = false;
182
- let startupShutdown;
183
- let shutdownAttempt;
184
- const gatedFetch = (request, server) => live ? live(request, server) : Promise.resolve(ready).then(async () => {
185
- if (!live) {
186
- await startupShutdown;
187
- throw new Error("[Elysia] Server was stopped before it was ready");
188
- }
189
- return live(request, server);
190
- });
191
179
  const _options = optionsIsObject ? { ...options } : {
192
180
  port: +options,
193
181
  fetch: gatedFetch
194
182
  };
195
183
  if (optionsIsObject) _options.fetch = gatedFetch;
184
+ const _config = app["~config"]?.serve;
196
185
  const serve = _config ? {
197
186
  ..._config,
198
187
  ..._options
199
188
  } : _options;
189
+ const server = app.server = Bun.serve(serve.routes || serve.error ? {
190
+ ...serve,
191
+ error: unavailableFetch,
192
+ routes: {}
193
+ } : serve);
194
+ let live;
195
+ let cancelled = false;
196
+ let startupShutdown;
197
+ let shutdownAttempt;
200
198
  let ready;
201
199
  let wsLifecycle;
202
200
  let modulesReady;
201
+ let built;
202
+ let pendingSetups;
203
203
  const build = () => {
204
204
  const fetch = app.fetch;
205
205
  let routes;
@@ -230,13 +230,6 @@ const BunAdapter = createAdapter({
230
230
  websocket
231
231
  };
232
232
  };
233
- let built;
234
- let pendingSetups;
235
- const server = app.server = Bun.serve(serve.routes || serve.error ? {
236
- ...serve,
237
- error: unavailableFetch,
238
- routes: {}
239
- } : serve);
240
233
  let startupFailure;
241
234
  let forceRequested = false;
242
235
  let forceDone = false;
@@ -370,7 +370,6 @@ function cancelPropagatingBody(clonedBody, orphanedBranch, preserveOrphan = fals
370
370
  }
371
371
  });
372
372
  }
373
- const warnedStreamBorrows = /* @__PURE__ */ new WeakSet();
374
373
  function createResponseHandler(handler) {
375
374
  const handleStream = createStreamHandler(handler);
376
375
  return (response, set, request, owned = false) => {
@@ -390,12 +389,7 @@ function createResponseHandler(handler) {
390
389
  if (!borrowed && response.body?.locked) throw new TypeError("Cannot patch a Response whose body is locked");
391
390
  let body = response.body;
392
391
  if (borrowed) {
393
- const bodyBefore = body;
394
392
  const cloned = response.clone();
395
- if (explicitlyBorrowed && bodyBefore && response.body !== bodyBefore && !warnedStreamBorrows.has(response)) {
396
- warnedStreamBorrows.add(response);
397
- console.warn("[elysia] borrow() was called on a stream-backed Response");
398
- }
399
393
  body = cloned.body && response.body ? cancelPropagatingBody(cloned.body, response.body, explicitlyBorrowed) : cloned.body;
400
394
  }
401
395
  const newResponse = new Response(body, set ? {
@@ -369,7 +369,6 @@ function cancelPropagatingBody(clonedBody, orphanedBranch, preserveOrphan = fals
369
369
  }
370
370
  });
371
371
  }
372
- const warnedStreamBorrows = /* @__PURE__ */ new WeakSet();
373
372
  function createResponseHandler(handler) {
374
373
  const handleStream = createStreamHandler(handler);
375
374
  return (response, set, request, owned = false) => {
@@ -389,12 +388,7 @@ function createResponseHandler(handler) {
389
388
  if (!borrowed && response.body?.locked) throw new TypeError("Cannot patch a Response whose body is locked");
390
389
  let body = response.body;
391
390
  if (borrowed) {
392
- const bodyBefore = body;
393
391
  const cloned = response.clone();
394
- if (explicitlyBorrowed && bodyBefore && response.body !== bodyBefore && !warnedStreamBorrows.has(response)) {
395
- warnedStreamBorrows.add(response);
396
- console.warn("[elysia] borrow() was called on a stream-backed Response");
397
- }
398
392
  body = cloned.body && response.body ? cancelPropagatingBody(cloned.body, response.body, explicitlyBorrowed) : cloned.body;
399
393
  }
400
394
  const newResponse = new Response(body, set ? {
package/dist/base.js CHANGED
@@ -578,6 +578,8 @@ var Elysia = class Elysia {
578
578
  for (const k in hook) {
579
579
  const v = hook[k];
580
580
  if (k === "seed") continue;
581
+ if (k === "meta") continue;
582
+ if (k === "$type") continue;
581
583
  if (k === "introspect") {
582
584
  v?.(input);
583
585
  delete input[key];
package/dist/base.mjs CHANGED
@@ -575,6 +575,8 @@ var Elysia = class Elysia {
575
575
  for (const k in hook) {
576
576
  const v = hook[k];
577
577
  if (k === "seed") continue;
578
+ if (k === "meta") continue;
579
+ if (k === "$type") continue;
578
580
  if (k === "introspect") {
579
581
  v?.(input);
580
582
  delete input[key];
@@ -13,8 +13,8 @@ const require_type_validator_frozen_check = require('../type/validator/frozen-ch
13
13
  const require_type_validator_custom_error = require('../type/validator/custom-error.js');
14
14
  const require_type_validator_exact_mirror = require('../type/validator/exact-mirror.js');
15
15
  const require_type_validator_string_codec_aot = require('../type/validator/string-codec-aot.js');
16
- let typebox_schema = require("typebox/schema");
17
16
  let typebox_value = require("typebox/value");
17
+ let typebox_schema = require("typebox/schema");
18
18
 
19
19
  //#region src/compile/aot-capture.ts
20
20
  function emptyContainers(node, depth) {
@@ -11,8 +11,8 @@ import { buildFrozenCheck } from "../type/validator/frozen-check.mjs";
11
11
  import { captureCustomErrors } from "../type/validator/custom-error.mjs";
12
12
  import { getExactMirror } from "../type/validator/exact-mirror.mjs";
13
13
  import { captureStringCodecEntries } from "../type/validator/string-codec-aot.mjs";
14
- import { Build, Compile } from "typebox/schema";
15
14
  import { Default } from "typebox/value";
15
+ import { Build, Compile } from "typebox/schema";
16
16
 
17
17
  //#region src/compile/aot-capture.ts
18
18
  function emptyContainers(node, depth) {
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ import { StatusMap, StatusMapBack } from "./constants.js";
5
5
  import { env } from "./universal/env.js";
6
6
  import { Server } from "./universal/server.js";
7
7
  import { bytes, form, prefix, redirect, sse } from "./utils.js";
8
- import { HTTPHeaders, InputSchema, Macro, MacroToContext, MacroToProperty, RouteSchema, SSEPayload, UnwrapRoute, UnwrapSchema } from "./types.js";
8
+ import { HTTPHeaders, InputSchema, Macro, MacroToContext, MacroToProperty, MacroTypeLambda, RouteSchema, SSEPayload, UnwrapRoute, UnwrapSchema } from "./types.js";
9
9
  import { ElysiaError, ElysiaStatus, HTTPError, InternalServerError, NotFound, ParseError, Problem, SelectiveStatus, TaggedHTTPError, ValidationError, problem, status, validationDetail } from "./error.js";
10
10
  import { Context, ErrorContext, createBaseContext, createContext } from "./context.js";
11
11
  import { InvalidCookie } from "./cookie/error.js";
@@ -20,4 +20,4 @@ import { TypeSystem, t } from "./type/index.js";
20
20
  import { AotFingerprint, Capture, Compiled, CompilerSession, ProgramId } from "./compile/aot.js";
21
21
  import { AnyElysia, Elysia } from "./base.js";
22
22
  import { borrow } from "./adapter/response-ownership.js";
23
- export { AnyElysia, type AnySchema, type AotFingerprint, type BaseCookie, type BaseSchema, Compiled, type CompilerSession, type Context, type Cookie, type CookieOptions, Elysia, Elysia as default, ElysiaError, ElysiaFile, ElysiaStatus, type ErrorContext, type FileTypeDetector, HTTPError, type HTTPHeaders, type InputSchema, InternalServerError, InvalidCookie, type Macro, type MacroToContext, type MacroToProperty, Capture as Manifest, MultiValidator, NotFound, ParseError, type Problem, type ProgramId, type RouteSchema, type SSEPayload, type SelectiveStatus, type Server, type StandardJSONSchemaV1Like, type StandardSchemaV1Like, StandardValidator, StatusMap, StatusMapBack, type TCookieField, type TCookieObject, type TFiles, type TaggedHTTPError, TypeBoxValidator, TypeSystem, type UnwrapRoute, type UnwrapSchema, ValidationError, Validator, borrow, bytes, createBaseContext, createContext, env, file, fileType, form, prefix, problem, redirect, setFileTypeDetector, setupTypebox, sse, status, t, validationDetail };
23
+ export { AnyElysia, type AnySchema, type AotFingerprint, type BaseCookie, type BaseSchema, Compiled, type CompilerSession, type Context, type Cookie, type CookieOptions, Elysia, Elysia as default, ElysiaError, ElysiaFile, ElysiaStatus, type ErrorContext, type FileTypeDetector, HTTPError, type HTTPHeaders, type InputSchema, InternalServerError, InvalidCookie, type Macro, type MacroToContext, type MacroToProperty, type MacroTypeLambda, Capture as Manifest, MultiValidator, NotFound, ParseError, type Problem, type ProgramId, type RouteSchema, type SSEPayload, type SelectiveStatus, type Server, type StandardJSONSchemaV1Like, type StandardSchemaV1Like, StandardValidator, StatusMap, StatusMapBack, type TCookieField, type TCookieObject, type TFiles, type TaggedHTTPError, TypeBoxValidator, TypeSystem, type UnwrapRoute, type UnwrapSchema, ValidationError, Validator, borrow, bytes, createBaseContext, createContext, env, file, fileType, form, prefix, problem, redirect, setFileTypeDetector, setupTypebox, sse, status, t, validationDetail };
package/dist/package.js CHANGED
@@ -1,6 +1,6 @@
1
1
 
2
2
  //#region package.json
3
- var version = "2.0.0-beta.4";
3
+ var version = "2.0.0-beta.5";
4
4
 
5
5
  //#endregion
6
6
  Object.defineProperty(exports, 'version', {
package/dist/package.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "2.0.0-beta.4";
2
+ var version = "2.0.0-beta.5";
3
3
 
4
4
  //#endregion
5
5
  export { version };
@@ -95,7 +95,7 @@ interface ElysiaAotOptions {
95
95
  }
96
96
  declare const resolveEntry: (entry: string) => string;
97
97
  /** @internal Resolve the package condition used to evaluate an AOT entry. */
98
- declare const resolveEntryModuleKind: (entry: string) => "cjs" | "esm";
98
+ declare const resolveEntryModuleKind: (entry: string) => "esm" | "cjs";
99
99
  /** Runtime handler-JIT module a strip build can replace with a throwing stub. */
100
100
  interface StubPlan {
101
101
  /** Stub the internal handler codegen module. */
package/dist/sucrose.js CHANGED
@@ -754,6 +754,7 @@ function inferFunction(source) {
754
754
  const token = tokens[i];
755
755
  if (token.value === "{") depth++;
756
756
  else if (token.value === "}") depth--;
757
+ else if (token.value === "," && depth === 0) break;
757
758
  else if (token.value === "[" && depth === 1 && (tokens[i - 1]?.value === "{" || tokens[i - 1]?.value === ",")) {
758
759
  const computed = computedDestructuringChannel(tokens, i);
759
760
  if (computed === false) {
@@ -765,6 +766,11 @@ function inferFunction(source) {
765
766
  const rest = tokens[i + 1];
766
767
  if (rest?.k === "i") aliases.add(rest.value);
767
768
  } else if (token.k === "i" && depth === 1) {
769
+ if (token.value === "ws" && (tokens[i - 1]?.value === "{" || tokens[i - 1]?.value === ",")) {
770
+ const renamed = tokens[i + 1]?.value === ":" && tokens[i + 2]?.k === "i" ? tokens[i + 2].value : token.value;
771
+ aliases.add(renamed);
772
+ continue;
773
+ }
768
774
  const key = channel(token.value);
769
775
  if (key) inference[key] = true;
770
776
  }
package/dist/sucrose.mjs CHANGED
@@ -753,6 +753,7 @@ function inferFunction(source) {
753
753
  const token = tokens[i];
754
754
  if (token.value === "{") depth++;
755
755
  else if (token.value === "}") depth--;
756
+ else if (token.value === "," && depth === 0) break;
756
757
  else if (token.value === "[" && depth === 1 && (tokens[i - 1]?.value === "{" || tokens[i - 1]?.value === ",")) {
757
758
  const computed = computedDestructuringChannel(tokens, i);
758
759
  if (computed === false) {
@@ -764,6 +765,11 @@ function inferFunction(source) {
764
765
  const rest = tokens[i + 1];
765
766
  if (rest?.k === "i") aliases.add(rest.value);
766
767
  } else if (token.k === "i" && depth === 1) {
768
+ if (token.value === "ws" && (tokens[i - 1]?.value === "{" || tokens[i - 1]?.value === ",")) {
769
+ const renamed = tokens[i + 1]?.value === ":" && tokens[i + 2]?.k === "i" ? tokens[i + 2].value : token.value;
770
+ aliases.add(renamed);
771
+ continue;
772
+ }
767
773
  const key = channel(token.value);
768
774
  if (key) inference[key] = true;
769
775
  }
@@ -4,9 +4,9 @@ import { useTypebox as useTypebox$1 } from "./bridge.js";
4
4
  import { TypeBoxValidatorCache, mayHaveFileType } from "./validator/validator-cache.js";
5
5
  import { TypeBoxValidator } from "./validator/index.js";
6
6
  import { applyCoercions, coerceBody, coerceFormData, coerceQuery, coerceRoot, coerceStringToStructure } from "./coerce.js";
7
+ import { Compile } from "typebox/compile";
7
8
  import { Ref } from "typebox/type";
8
9
  import { Check, Clone, Create, Decode, Default, HasCodec } from "typebox/value";
9
- import { Compile } from "typebox/compile";
10
10
 
11
11
  //#region src/type/bridge-live.d.ts
12
12
  declare function useTypebox(_mod?: Parameters<typeof useTypebox$1>[0]): void;
@@ -5,9 +5,9 @@ const require_type_coerce = require('./coerce.js');
5
5
  const require_type_validator_validator_cache = require('./validator/validator-cache.js');
6
6
  const require_type_validator_index = require('./validator/index.js');
7
7
  const require_type_elysia_intersect = require('./elysia/intersect.js');
8
- let typebox_value = require("typebox/value");
9
8
  let typebox_compile = require("typebox/compile");
10
9
  let typebox_type = require("typebox/type");
10
+ let typebox_value = require("typebox/value");
11
11
  let typebox_system = require("typebox/system");
12
12
 
13
13
  //#region src/type/bridge-live.ts
@@ -3,9 +3,9 @@ import { applyCoercions, coerceBody, coerceFormData, coerceQuery, coerceRoot, co
3
3
  import { TypeBoxValidatorCache, mayHaveFileType } from "./validator/validator-cache.mjs";
4
4
  import { TypeBoxValidator } from "./validator/index.mjs";
5
5
  import { Intersect } from "./elysia/intersect.mjs";
6
- import { Check, Clone, Create, Decode, Default, HasCodec } from "typebox/value";
7
6
  import { Compile } from "typebox/compile";
8
7
  import { Ref } from "typebox/type";
8
+ import { Check, Clone, Create, Decode, Default, HasCodec } from "typebox/value";
9
9
  import { Settings } from "typebox/system";
10
10
 
11
11
  //#region src/type/bridge-live.ts
@@ -3,9 +3,9 @@ import { hasTypes as hasTypes$1 } from "./utils.js";
3
3
  import { TypeBoxValidatorCache as TypeBoxValidatorCache$1, mayHaveFileType as mayHaveFileType$1 } from "./validator/validator-cache.js";
4
4
  import { TypeBoxValidator as TypeBoxValidator$1 } from "./validator/index.js";
5
5
  import { applyCoercions as applyCoercions$1, coerceBody as coerceBody$1, coerceFormData as coerceFormData$1, coerceQuery as coerceQuery$1, coerceRoot as coerceRoot$1, coerceStringToStructure as coerceStringToStructure$1 } from "./coerce.js";
6
+ import { Compile as Compile$1 } from "typebox/compile";
6
7
  import { Ref as Ref$1, TAny, TSchema } from "typebox/type";
7
8
  import { Check as Check$1, Clone as Clone$1, Create as Create$1, Decode as Decode$2, Default as Default$1, HasCodec as HasCodec$1 } from "typebox/value";
8
- import { Compile as Compile$1 } from "typebox/compile";
9
9
 
10
10
  //#region src/type/bridge.d.ts
11
11
  interface TypeboxModule {
@@ -1,7 +1,7 @@
1
1
  import { TypeboxNamespaces } from "./typebox-value.js";
2
- import { Build, Compile as SchemaCompile } from "typebox/schema";
3
- import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
4
2
  import { Compile } from "typebox/compile";
3
+ import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
4
+ import { Build, Compile as SchemaCompile } from "typebox/schema";
5
5
 
6
6
  //#region src/type/typebox-value-live.d.ts
7
7
  declare function injectTypebox(_typebox?: TypeboxNamespaces): void;
@@ -1,9 +1,9 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../_virtual/_rolldown/runtime.js');
3
- let typebox_schema = require("typebox/schema");
4
- let typebox_value = require("typebox/value");
5
3
  let typebox_compile = require("typebox/compile");
4
+ let typebox_value = require("typebox/value");
6
5
  let typebox_system = require("typebox/system");
6
+ let typebox_schema = require("typebox/schema");
7
7
 
8
8
  //#region src/type/typebox-value-live.ts
9
9
  typebox_system.Settings.Set({ unionPrioritySort: false });
@@ -1,7 +1,7 @@
1
- import { Build, Compile as SchemaCompile } from "typebox/schema";
2
- import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
3
1
  import { Compile } from "typebox/compile";
2
+ import { Check, Clean, Clone, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec } from "typebox/value";
4
3
  import { Settings } from "typebox/system";
4
+ import { Build, Compile as SchemaCompile } from "typebox/schema";
5
5
 
6
6
  //#region src/type/typebox-value-live.ts
7
7
  Settings.Set({ unionPrioritySort: false });
@@ -1,9 +1,9 @@
1
- import * as _$typebox_schema0 from "typebox/schema";
2
- import { Build as Build$1, Compile as Compile$1 } from "typebox/schema";
1
+ import * as _$typebox_compile0 from "typebox/compile";
2
+ import { Compile as Compile$1 } from "typebox/compile";
3
3
  import * as _$typebox_value0 from "typebox/value";
4
4
  import { Check as Check$1, Clean as Clean$1, Clone as Clone$1, Create as Create$1, Decode as Decode$1, DecodeUnsafe as DecodeUnsafe$1, Default as Default$1, Encode as Encode$1, EncodeUnsafe as EncodeUnsafe$1, Errors as Errors$1, HasCodec as HasCodec$1 } from "typebox/value";
5
- import * as _$typebox_compile0 from "typebox/compile";
6
- import { Compile as Compile$2 } from "typebox/compile";
5
+ import * as _$typebox_schema0 from "typebox/schema";
6
+ import { Build as Build$1, Compile as Compile$2 } from "typebox/schema";
7
7
 
8
8
  //#region src/type/typebox-value.d.ts
9
9
  interface TypeboxNamespaces {
@@ -22,9 +22,9 @@ declare let Encode: typeof Encode$1;
22
22
  declare let EncodeUnsafe: typeof EncodeUnsafe$1;
23
23
  declare let Errors: typeof Errors$1;
24
24
  declare let HasCodec: typeof HasCodec$1;
25
- declare let SchemaCompile: typeof Compile$1;
25
+ declare let SchemaCompile: typeof Compile$2;
26
26
  declare let Build: typeof Build$1;
27
- declare let Compile: typeof Compile$2;
27
+ declare let Compile: typeof Compile$1;
28
28
  declare function injectTypebox(typebox: TypeboxNamespaces): void;
29
29
  //#endregion
30
30
  export { Build, Check, Clean, Clone, Compile, Create, Decode, DecodeUnsafe, Default, Encode, EncodeUnsafe, Errors, HasCodec, SchemaCompile, TypeboxNamespaces, injectTypebox };
@@ -1,8 +1,8 @@
1
1
  import { MaybePromise } from "../../types.js";
2
2
  import { Validator as Validator$1, ValidatorOptions } from "../../validator/index.js";
3
3
  import { TypeBoxValidatorCache, mayHaveFileType } from "./validator-cache.js";
4
- import { Validator } from "typebox/schema";
5
4
  import { Static, StaticDecode, StaticEncode, TAny, TSchema } from "typebox/type";
5
+ import { Validator } from "typebox/schema";
6
6
  import { TLocalizedValidationError } from "typebox/error";
7
7
 
8
8
  //#region src/type/validator/index.d.ts
@@ -1,7 +1,7 @@
1
1
  import { CoerceOption } from "../coerce.js";
2
+ import { TSchema } from "typebox/type";
2
3
  import * as _$typebox_schema0 from "typebox/schema";
3
4
  import { Validator } from "typebox/schema";
4
- import { TSchema } from "typebox/type";
5
5
 
6
6
  //#region src/type/validator/validator-cache.d.ts
7
7
  interface SchemaMeta {
package/dist/types.d.ts CHANGED
@@ -499,6 +499,19 @@ type MacroProperty<Macro extends BaseMacro = {}, TypedRoute extends RouteSchema
499
499
  afterResponse?: MaybeArray<AfterResponseHandler<TypedRoute, Singleton>>;
500
500
  derive?: MaybeArray<ResolveHandler<TypedRoute, Singleton>>;
501
501
  detail?: DocumentDecoration;
502
+ /**
503
+ * Type-level route metadata surfaced on the route's Eden type
504
+ * (`CreateEdenResponse['meta']`). Reserved key like `seed`/`detail`/
505
+ * `introspect` — stripped at runtime, never lands on route hooks
506
+ */
507
+ meta?: unknown;
508
+ /**
509
+ * Phantom {@link MacroTypeLambda} computing per call site context from
510
+ * the route's literal hook value. Reserved key like `seed`/`meta`/
511
+ * `introspect` — carry it on the declared return type only; a runtime
512
+ * value is tolerated and stripped
513
+ */
514
+ $type?: MacroTypeLambda;
502
515
  /**
503
516
  * Introspect hook option for documentation generation or analysis
504
517
  *
@@ -657,9 +670,9 @@ interface MergeScopedSchemas<Global extends RouteSchema, Scoped extends RouteSch
657
670
  response: { [K in keyof Global['response'] | keyof Scoped['response'] | keyof Local['response']]: K extends keyof Local['response'] ? Local['response'][K] : K extends keyof Scoped['response'] ? Scoped['response'][K] : K extends keyof Global['response'] ? Global['response'][K] : never };
658
671
  }
659
672
  type ReturnTypeIfPossible<T, Enabled = true> = false extends Enabled ? {} : T extends ((...a: any) => infer R) ? R : T;
660
- type FunctionArrayReturnType<T> = any[] extends T ? never : T extends any[] ? _FunctionArrayReturnType<T> : Awaited<ReturnType<T>>;
673
+ type FunctionArrayReturnType<T> = any[] extends T ? never : T extends any[] ? _FunctionArrayReturnType<T> : Awaited<ReturnType<NonNullable<T>>>;
661
674
  type _FunctionArrayReturnType<T, Carry = undefined> = T extends [infer Fn, ...infer Rest] ? _FunctionArrayReturnType<Rest, Awaited<ReturnType<Fn>> extends infer A ? IsNever<A> extends true ? Carry : A | Carry : Carry> : Carry;
662
- type FunctionArrayReturnTypeNonNullable<T> = any[] extends T ? never : T extends any[] ? _FunctionArrayReturnTypeNonNullable<T> : NonNullable<Awaited<ReturnType<T>>>;
675
+ type FunctionArrayReturnTypeNonNullable<T> = any[] extends T ? never : T extends any[] ? _FunctionArrayReturnTypeNonNullable<T> : NonNullable<Awaited<ReturnType<NonNullable<T>>>>;
663
676
  type _FunctionArrayReturnTypeNonNullable<T, Carry = undefined> = T extends [infer Fn, ...infer Rest] ? _FunctionArrayReturnTypeNonNullable<Rest, NonNullable<Awaited<ReturnType<Fn>>> extends infer A ? IsNever<A> extends true ? Carry : A | Carry : Carry> : Carry;
664
677
  type AnyElysiaStatus = ElysiaStatus<any, any, any>;
665
678
  type ExcludeElysiaResponse<T> = Exclude<Awaited<T>, AnyElysiaStatus> extends infer A ? IsNever<A & {}> extends true ? {} : undefined extends A ? Partial<A & {}> : A & {} : {};
@@ -676,6 +689,22 @@ type ExtractAllResponseFromMacro<A> = IsNever<A> extends true ? {} : {
676
689
  } : {});
677
690
  };
678
691
  type FlattenMacroResponse<T> = T extends object ? '_' extends keyof T ? UnionResponseStatus<Omit<T, '_'>, FlattenMacroResponse<MergeStatusUnion<T['_']>>> : T : T;
692
+ /**
693
+ * Type-level lambda applied to a macro's per call site hook value. Extend
694
+ * this interface, compute `output` from `this['input']`, and carry it on
695
+ * the macro's declared return type as a phantom `$type` member — the
696
+ * computed `output` joins the route's context
697
+ */
698
+ interface MacroTypeLambda {
699
+ input: unknown;
700
+ }
701
+ type MacroLambdaContext<Value, HookValue> = NonNullable<Value> extends {
702
+ $type?: infer Lambda extends MacroTypeLambda;
703
+ } ? (Lambda & {
704
+ input: HookValue;
705
+ }) extends {
706
+ output: infer Output;
707
+ } ? Output : {} : {};
679
708
  type UnionMacroContext<A> = UnionToIntersect<{ [K in Exclude<keyof A, 'return'>]: A[K] }> & {
680
709
  return: {
681
710
  _: A['return'];
@@ -686,7 +715,8 @@ type MacroToContext<in out MacroFn extends Macro = {}, in out SelectedMacro exte
686
715
  }> : {}>;
687
716
  type InnerMacroToContext<MacroFn extends Macro = {}, SelectedMacro extends BaseMacro = {}, Definitions extends DefinitionBase['typebox'] = {}, R extends 1[] = []> = {} extends SelectedMacro ? {} : R['length'] extends 15 ? {} : UnionMacroContext<{ [key in keyof SelectedMacro]: ReturnTypeIfPossible<MacroFn[key], SelectedMacro[key]> extends infer Value ? {
688
717
  q: UnwrapMacroSchema<Value, Definitions>;
689
- resolve: ExtractResolveFromMacro<Extract<Exclude<FunctionArrayReturnType<Value['derive']>, AnyElysiaStatus>, Record<any, unknown>>>;
718
+ meta: 'meta' extends keyof NonNullable<Value> ? NonNullable<Value>['meta'] : never;
719
+ resolve: ExtractResolveFromMacro<Extract<Exclude<FunctionArrayReturnType<Value['derive']>, AnyElysiaStatus>, Record<any, unknown>>> & MacroLambdaContext<Value, SelectedMacro[key]>;
690
720
  } & UnwrapMacroSchema<Value, Definitions> & ExtractAllResponseFromMacro<FunctionArrayReturnTypeNonNullable<Value['beforeHandle']>> & ExtractAllResponseFromMacro<FunctionArrayReturnTypeNonNullable<Value['afterHandle']>> & ExtractAllResponseFromMacro<FunctionArrayReturnType<Value['error']>> & ExtractOnlyResponseFromMacro<FunctionArrayReturnTypeNonNullable<Value['derive']>> & InnerMacroToContext<MacroFn, Pick<Value, Extract<keyof MacroFn, keyof Value>>, Definitions, [...R, 1]> : {} }[keyof SelectedMacro]>;
691
721
  type UnwrapMacroSchema<T extends Partial<InputSchema<any>>, Definitions extends DefinitionBase['typebox'] = {}> = UnwrapRoute<{
692
722
  body: 'body' extends keyof T ? T['body'] : undefined;
@@ -839,7 +869,11 @@ type CreateEdenResponse<Path extends string, Schema extends RouteSchema, MacroCo
839
869
  headers: Prettify<Schema['headers'] & MacroContext['headers']>;
840
870
  response: Prettify<UnionResponseStatus<Res, UnhandledErrorResponse<Err>>>;
841
871
  error: Err;
842
- };
872
+ } & (MacroContext extends {
873
+ meta: infer Meta;
874
+ } ? IsNever<Meta> extends true ? {} : unknown extends Meta ? {} : {
875
+ meta: Meta;
876
+ } : {});
843
877
  type CreateWSEdenResponse<Path extends string, Schema extends RouteSchema, MacroContext extends RouteSchema, Res extends PossibleResponse> = Omit<CreateEdenResponse<Path, Schema, MacroContext, Res>, 'error'>;
844
878
  type Extract200<T> = T extends AnyElysiaStatus ? Exclude<T, AnyElysiaStatus> | Extract<T, ElysiaStatus<200, any, 200>>['response'] : T;
845
879
  type ValueToResponseSchema<Value, Errors extends ErrorDefinition[] = []> = ExtractErrorFromHandle<Exclude<Value, Error>> & ExtractReturnedError<Value, Errors> & (Extract200<Exclude<Value, Error>> extends infer R200 ? undefined extends R200 ? {} : IsNever<R200> extends true ? {} : {
@@ -1057,4 +1091,4 @@ type LazyComposeEntry = {
1057
1091
  source?: string;
1058
1092
  };
1059
1093
  //#endregion
1060
- export { AddRoute, AddWSRoute, AfterHandler, AfterResponseHandler, AnyErrorConstructor, AnyLocalHook, type AnySchema, AnyWSLocalHook, AppEvent, AppHook, BaseMacro, BodyHandler, BunHTMLBundlelike, CompiledHandler, ComposeElysiaResponse, ContentType, ContextAppendType, CreateEden, CreateEdenResponse, CreateWSEdenResponse, DefaultEphemeral, DefaultMetadata, DefaultSingleton, DefinitionBase, DocumentDecoration, ElysiaConfig, ElysiaFormData, ElysiaHandlerToResponseSchema, ElysiaHandlerToResponseSchemaAmbiguous, ElysiaHandlerToResponseSchemas, EmptyInputSchema, EphemeralType, Equal, ErrorDefinition, ErrorDefinitionEntry, ErrorHandler, ErrorHandlerResponseSchema, EventFn, EventScope, ExcludeElysiaResponse, ExtractErrorFromHandle, ExtractReturnedError, GetPathParameter, GlobalHookReturn, GracefulHandler, GuardHookSingleton, GuardLocalHook, GuardSchemaType, HTTPHeaders, HTTPMethod, Handler, HistoryEntry, HookContextSchema, HookContextSingleton, InlineHandler, InlineHandlerNonMacro, InlineHandlerResponse, InlineResponse, InputSchema, InputSchemaKey, InternalRoute, IntersectIfObject, IntersectIfObjectSchema, IsAny, IsNever, IsTuple, JoinPath, LazyComposeEntry, LocalHook, LocalHookReturn, Macro, MacroProperty, MacroPropertyKey, MacroSchemaChannel, MacroToContext, MacroToProperty, MapResponse, MaybeArray, MaybePromise, MaybeValueOrVoidFunction, MergeElysiaInstances, MergeSchema, MergeScopedSchemas, MetadataBase, NonResolvableMacroKey, ObjectMacroDefs, OptionalHandler, PluginHookReturn, PossibleResponse, PreHandler, Prettify, PublicRoute, Replace, ResolveHandler, ResolvePath, ResolveRouteErrors, RouteBase, RouteSchema, SSEPayload, ScopedHookReturn, ScopedMapDeriveReturn, SingletonBase, type StandardSchemaV1Like, StaticMapAliases, TransformHandler, type TypeBoxSchema, UnhandledReturnedError, UnhandledReturnedErrorOf, UnionResponseStatus, UnionToIntersect, UnwrapArray, UnwrapBodySchema, UnwrapMacroSchema, UnwrapRoute, UnwrapSchema, ValueOrFunctionToResponseSchema, ValueToResponseSchema, VoidHandler, WrapFn };
1094
+ export { AddRoute, AddWSRoute, AfterHandler, AfterResponseHandler, AnyErrorConstructor, AnyLocalHook, type AnySchema, AnyWSLocalHook, AppEvent, AppHook, BaseMacro, BodyHandler, BunHTMLBundlelike, CompiledHandler, ComposeElysiaResponse, ContentType, ContextAppendType, CreateEden, CreateEdenResponse, CreateWSEdenResponse, DefaultEphemeral, DefaultMetadata, DefaultSingleton, DefinitionBase, DocumentDecoration, ElysiaConfig, ElysiaFormData, ElysiaHandlerToResponseSchema, ElysiaHandlerToResponseSchemaAmbiguous, ElysiaHandlerToResponseSchemas, EmptyInputSchema, EphemeralType, Equal, ErrorDefinition, ErrorDefinitionEntry, ErrorHandler, ErrorHandlerResponseSchema, EventFn, EventScope, ExcludeElysiaResponse, ExtractErrorFromHandle, ExtractReturnedError, GetPathParameter, GlobalHookReturn, GracefulHandler, GuardHookSingleton, GuardLocalHook, GuardSchemaType, HTTPHeaders, HTTPMethod, Handler, HistoryEntry, HookContextSchema, HookContextSingleton, InlineHandler, InlineHandlerNonMacro, InlineHandlerResponse, InlineResponse, InputSchema, InputSchemaKey, InternalRoute, IntersectIfObject, IntersectIfObjectSchema, IsAny, IsNever, IsTuple, JoinPath, LazyComposeEntry, LocalHook, LocalHookReturn, Macro, MacroProperty, MacroPropertyKey, MacroSchemaChannel, MacroToContext, MacroToProperty, MacroTypeLambda, MapResponse, MaybeArray, MaybePromise, MaybeValueOrVoidFunction, MergeElysiaInstances, MergeSchema, MergeScopedSchemas, MetadataBase, NonResolvableMacroKey, ObjectMacroDefs, OptionalHandler, PluginHookReturn, PossibleResponse, PreHandler, Prettify, PublicRoute, Replace, ResolveHandler, ResolvePath, ResolveRouteErrors, RouteBase, RouteSchema, SSEPayload, ScopedHookReturn, ScopedMapDeriveReturn, SingletonBase, type StandardSchemaV1Like, StaticMapAliases, TransformHandler, type TypeBoxSchema, UnhandledReturnedError, UnhandledReturnedErrorOf, UnionResponseStatus, UnionToIntersect, UnwrapArray, UnwrapBodySchema, UnwrapMacroSchema, UnwrapRoute, UnwrapSchema, ValueOrFunctionToResponseSchema, ValueToResponseSchema, VoidHandler, WrapFn };
package/dist/ws/route.js CHANGED
@@ -3,6 +3,7 @@ const require_universal_constants = require('../universal/constants.js');
3
3
  const require_utils = require('../utils.js');
4
4
  const require_type_bridge = require('../type/bridge.js');
5
5
  const require_error = require('../error.js');
6
+ const require_cookie_crypto = require('../cookie/crypto.js');
6
7
  const require_adapter_web_standard_handler = require('../adapter/web-standard/handler.js');
7
8
  const require_parse_query = require('../parse-query.js');
8
9
  const require_generation = require('../generation.js');
@@ -10,6 +11,7 @@ const require_cookie_config = require('../cookie/config.js');
10
11
  const require_cookie_utils = require('../cookie/utils.js');
11
12
  const require_handler_error = require('../handler/error.js');
12
13
  const require_compile_handler_utils = require('../compile/handler/utils.js');
14
+ const require_sucrose = require('../sucrose.js');
13
15
  const require_validator_index = require('../validator/index.js');
14
16
  const require_validator_route = require('../validator/route.js');
15
17
  const require_compile_handler_frozen_validator = require('../compile/handler/frozen-validator.js');
@@ -283,7 +285,6 @@ function buildWSRoute(route, app) {
283
285
  }
284
286
  const responseValidator = validators.response;
285
287
  const defaultResponseValidator = responseValidator ? responseValidator[200] ?? responseValidator[Object.keys(responseValidator)[0]] : void 0;
286
- const cookieConfig = validators.cookie ? require_cookie_config.compileCookieConfig(composed.cookie, require_generation.frozenRootOf(app)["~config"]?.cookie) : void 0;
287
288
  const cookieIsOptional = !!composed.cookie?.["~optional"];
288
289
  const queryChannels = require_compile_handler_utils.getQueryParseChannels(validators.query?.schema);
289
290
  const queryArray = queryChannels?.array;
@@ -300,6 +301,24 @@ function buildWSRoute(route, app) {
300
301
  const mapResponses = concatHooks(flatAppHook.mapResponse, hook.mapResponse);
301
302
  const afterResponses = concatHooks(flatAppHook.afterResponse, hook.afterResponse);
302
303
  const errorHandlers = concatHooks(hook.error, flatAppHook.error);
304
+ const inference = require_sucrose.sucrose(hook.message, {
305
+ beforeHandle: [
306
+ ...allBeforeHandles,
307
+ hook.open,
308
+ hook.close,
309
+ hook.drain,
310
+ hook.ping,
311
+ hook.pong,
312
+ typeof hook.upgrade === "function" ? hook.upgrade : void 0
313
+ ].filter(Boolean),
314
+ parse: parseHooks,
315
+ transform: transforms,
316
+ error: errorHandlers,
317
+ afterHandle: afterHandles,
318
+ mapResponse: mapResponses,
319
+ afterResponse: afterResponses
320
+ });
321
+ const cookieConfig = validators.cookie || inference.cookie ? require_cookie_config.compileCookieConfig(composed.cookie, require_generation.frozenRootOf(app)["~config"]?.cookie) : void 0;
303
322
  const parseMessage = require_ws_parser.createMessageParser(parseHooks);
304
323
  const handleUpgradeError = require_handler_error.createErrorHandler(errorHandlers.length ? errorHandlers : void 0, ((response, set, context) => require_adapter_web_standard_handler.mapResponse(response, set, context?.request)), void 0, require_generation.frozenRootOf(app)["~config"]?.allowUnsafeValidationDetails);
305
324
  async function handleError(ws, error) {
@@ -456,21 +475,29 @@ function buildWSRoute(route, app) {
456
475
  let r = validateUpgradeChannel(validators.query, query, "query");
457
476
  if (r instanceof Promise) r = await r;
458
477
  context.query = r;
478
+ } else if (inference.query) {
479
+ const url = request.url;
480
+ context.query = require_parse_query.parseQueryFromURL(url, context.qi ?? url.indexOf("?"));
459
481
  }
460
482
  if (validators.headers) {
461
483
  const headers = require_universal_constants.isBun ? request.headers.toJSON() : Object.fromEntries(request.headers);
462
484
  let r = validateUpgradeChannel(validators.headers, headers, "headers");
463
485
  if (r instanceof Promise) r = await r;
464
486
  context.headers = r;
465
- }
487
+ } else if (inference.headers) context.headers = require_universal_constants.isBun ? request.headers.toJSON() : Object.fromEntries(request.headers);
466
488
  if (cookieConfig) {
467
- const raw = await require_cookie_utils.parseCookieRaw(request.headers.get("cookie"), cookieConfig);
468
- let r = raw;
469
- if (!cookieIsOptional || Object.keys(raw).length) {
470
- r = validateUpgradeChannel(validators.cookie, raw, "cookie");
471
- if (r instanceof Promise) r = await r;
472
- }
473
- context.cookie = require_cookie_utils.buildCookieJar(context.set, r, cookieConfig);
489
+ const cookieHeader = request.headers.get("cookie");
490
+ if (validators.cookie) {
491
+ const raw = await require_cookie_utils.parseCookieRaw(cookieHeader, cookieConfig);
492
+ let r = raw;
493
+ if (!cookieIsOptional || Object.keys(raw).length) {
494
+ r = validateUpgradeChannel(validators.cookie, raw, "cookie");
495
+ if (r instanceof Promise) r = await r;
496
+ }
497
+ context.cookie = require_cookie_utils.buildCookieJar(context.set, r, cookieConfig);
498
+ } else if (!cookieConfig.hasSign) context.cookie = require_cookie_utils.buildCookieJar(context.set, require_cookie_utils.parseCookieRawDeferred(cookieHeader, cookieConfig), cookieConfig, void 0, 1);
499
+ else if (require_cookie_crypto.hasSyncHmac && cookieConfig.verify === "lazy") context.cookie = require_cookie_utils.buildCookieJar(context.set, require_cookie_utils.parseCookieRawLazy(cookieHeader, cookieConfig), cookieConfig, 1);
500
+ else context.cookie = require_cookie_utils.buildCookieJar(context.set, await require_cookie_utils.parseCookieRaw(cookieHeader, cookieConfig), cookieConfig);
474
501
  }
475
502
  for (let i = 0; i < transforms.length; i++) {
476
503
  const r = transforms[i](context);
package/dist/ws/route.mjs CHANGED
@@ -2,13 +2,15 @@ import { isBun } from "../universal/constants.mjs";
2
2
  import { assignOwn, deriveEntryFn, isNotEmpty, isSocketQuiet, nullObject } from "../utils.mjs";
3
3
  import { isBridgeLive } from "../type/bridge.mjs";
4
4
  import { ElysiaError, ElysiaStatus, ValidationError, internalServerErrorBodyString, problemBody, problemResponse } from "../error.mjs";
5
+ import { hasSyncHmac } from "../cookie/crypto.mjs";
5
6
  import { mapResponse } from "../adapter/web-standard/handler.mjs";
6
7
  import { parseQueryFromURL } from "../parse-query.mjs";
7
8
  import { frozenRootOf } from "../generation.mjs";
8
9
  import { compileCookieConfig } from "../cookie/config.mjs";
9
- import { buildCookieJar, parseCookieRaw } from "../cookie/utils.mjs";
10
+ import { buildCookieJar, parseCookieRaw, parseCookieRawDeferred, parseCookieRawLazy } from "../cookie/utils.mjs";
10
11
  import { adoptErrorType, claimsProblemType, createErrorHandler, readAnnotation, resolveStatus, statusFallbackBody } from "../handler/error.mjs";
11
12
  import { deriveModes, getQueryParseChannels, replaceDeriveContext } from "../compile/handler/utils.mjs";
13
+ import { sucrose } from "../sucrose.mjs";
12
14
  import { StandardValidator } from "../validator/index.mjs";
13
15
  import { RouteValidator } from "../validator/route.mjs";
14
16
  import { buildFrozenRouteValidator, isBridgeNotInitialized } from "../compile/handler/frozen-validator.mjs";
@@ -282,7 +284,6 @@ function buildWSRoute(route, app) {
282
284
  }
283
285
  const responseValidator = validators.response;
284
286
  const defaultResponseValidator = responseValidator ? responseValidator[200] ?? responseValidator[Object.keys(responseValidator)[0]] : void 0;
285
- const cookieConfig = validators.cookie ? compileCookieConfig(composed.cookie, frozenRootOf(app)["~config"]?.cookie) : void 0;
286
287
  const cookieIsOptional = !!composed.cookie?.["~optional"];
287
288
  const queryChannels = getQueryParseChannels(validators.query?.schema);
288
289
  const queryArray = queryChannels?.array;
@@ -299,6 +300,24 @@ function buildWSRoute(route, app) {
299
300
  const mapResponses = concatHooks(flatAppHook.mapResponse, hook.mapResponse);
300
301
  const afterResponses = concatHooks(flatAppHook.afterResponse, hook.afterResponse);
301
302
  const errorHandlers = concatHooks(hook.error, flatAppHook.error);
303
+ const inference = sucrose(hook.message, {
304
+ beforeHandle: [
305
+ ...allBeforeHandles,
306
+ hook.open,
307
+ hook.close,
308
+ hook.drain,
309
+ hook.ping,
310
+ hook.pong,
311
+ typeof hook.upgrade === "function" ? hook.upgrade : void 0
312
+ ].filter(Boolean),
313
+ parse: parseHooks,
314
+ transform: transforms,
315
+ error: errorHandlers,
316
+ afterHandle: afterHandles,
317
+ mapResponse: mapResponses,
318
+ afterResponse: afterResponses
319
+ });
320
+ const cookieConfig = validators.cookie || inference.cookie ? compileCookieConfig(composed.cookie, frozenRootOf(app)["~config"]?.cookie) : void 0;
302
321
  const parseMessage = createMessageParser(parseHooks);
303
322
  const handleUpgradeError = createErrorHandler(errorHandlers.length ? errorHandlers : void 0, ((response, set, context) => mapResponse(response, set, context?.request)), void 0, frozenRootOf(app)["~config"]?.allowUnsafeValidationDetails);
304
323
  async function handleError(ws, error) {
@@ -455,21 +474,29 @@ function buildWSRoute(route, app) {
455
474
  let r = validateUpgradeChannel(validators.query, query, "query");
456
475
  if (r instanceof Promise) r = await r;
457
476
  context.query = r;
477
+ } else if (inference.query) {
478
+ const url = request.url;
479
+ context.query = parseQueryFromURL(url, context.qi ?? url.indexOf("?"));
458
480
  }
459
481
  if (validators.headers) {
460
482
  const headers = isBun ? request.headers.toJSON() : Object.fromEntries(request.headers);
461
483
  let r = validateUpgradeChannel(validators.headers, headers, "headers");
462
484
  if (r instanceof Promise) r = await r;
463
485
  context.headers = r;
464
- }
486
+ } else if (inference.headers) context.headers = isBun ? request.headers.toJSON() : Object.fromEntries(request.headers);
465
487
  if (cookieConfig) {
466
- const raw = await parseCookieRaw(request.headers.get("cookie"), cookieConfig);
467
- let r = raw;
468
- if (!cookieIsOptional || Object.keys(raw).length) {
469
- r = validateUpgradeChannel(validators.cookie, raw, "cookie");
470
- if (r instanceof Promise) r = await r;
471
- }
472
- context.cookie = buildCookieJar(context.set, r, cookieConfig);
488
+ const cookieHeader = request.headers.get("cookie");
489
+ if (validators.cookie) {
490
+ const raw = await parseCookieRaw(cookieHeader, cookieConfig);
491
+ let r = raw;
492
+ if (!cookieIsOptional || Object.keys(raw).length) {
493
+ r = validateUpgradeChannel(validators.cookie, raw, "cookie");
494
+ if (r instanceof Promise) r = await r;
495
+ }
496
+ context.cookie = buildCookieJar(context.set, r, cookieConfig);
497
+ } else if (!cookieConfig.hasSign) context.cookie = buildCookieJar(context.set, parseCookieRawDeferred(cookieHeader, cookieConfig), cookieConfig, void 0, 1);
498
+ else if (hasSyncHmac && cookieConfig.verify === "lazy") context.cookie = buildCookieJar(context.set, parseCookieRawLazy(cookieHeader, cookieConfig), cookieConfig, 1);
499
+ else context.cookie = buildCookieJar(context.set, await parseCookieRaw(cookieHeader, cookieConfig), cookieConfig);
473
500
  }
474
501
  for (let i = 0; i < transforms.length; i++) {
475
502
  const r = transforms[i](context);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "elysia",
3
3
  "description": "Ergonomic Framework for Human",
4
- "version": "2.0.0-beta.4",
4
+ "version": "2.0.0-beta.5",
5
5
  "author": {
6
6
  "name": "saltyAom",
7
7
  "url": "https://github.com/SaltyAom",