elysia 2.0.0-exp.8 → 2.0.0-exp.9

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 (43) hide show
  1. package/dist/adapter/bun/index.d.ts +1 -1
  2. package/dist/adapter/constants.d.ts +1 -1
  3. package/dist/adapter/index.d.ts +1 -1
  4. package/dist/adapter/utils.d.ts +6 -6
  5. package/dist/adapter/utils.js +41 -60
  6. package/dist/adapter/utils.mjs +39 -58
  7. package/dist/adapter/web-standard/handler.js +2 -2
  8. package/dist/adapter/web-standard/handler.mjs +2 -2
  9. package/dist/adapter/web-standard/index.d.ts +1 -1
  10. package/dist/base.js +30 -28
  11. package/dist/base.mjs +30 -28
  12. package/dist/compile/aot.d.ts +6 -5
  13. package/dist/compile/aot.js +4 -2
  14. package/dist/compile/aot.mjs +4 -2
  15. package/dist/error.d.ts +1 -1
  16. package/dist/handler/fetch.js +29 -87
  17. package/dist/handler/fetch.mjs +29 -86
  18. package/dist/sucrose.js +31 -40
  19. package/dist/sucrose.mjs +31 -40
  20. package/dist/type/bridge.d.ts +3 -3
  21. package/dist/type/compat.js +1 -1
  22. package/dist/type/compat.mjs +2 -2
  23. package/dist/type/constants.d.ts +1 -1
  24. package/dist/type/elysia/array-string.js +1 -1
  25. package/dist/type/elysia/array-string.mjs +4 -4
  26. package/dist/type/elysia/object-string.js +1 -1
  27. package/dist/type/elysia/object-string.mjs +4 -4
  28. package/dist/type/exports.js +0 -630
  29. package/dist/type/exports.mjs +2 -92
  30. package/dist/type/validator/default-precompute.d.ts +2 -1
  31. package/dist/type/validator/default-precompute.js +23 -11
  32. package/dist/type/validator/default-precompute.mjs +23 -12
  33. package/dist/type/validator/index.js +5 -5
  34. package/dist/type/validator/index.mjs +6 -6
  35. package/dist/type/validator/string-codec-aot.js +2 -2
  36. package/dist/type/validator/string-codec-aot.mjs +2 -2
  37. package/dist/utils.js +12 -9
  38. package/dist/utils.mjs +12 -9
  39. package/dist/validator/index.js +13 -10
  40. package/dist/validator/index.mjs +13 -10
  41. package/dist/ws/route.js +7 -1
  42. package/dist/ws/route.mjs +7 -1
  43. package/package.json +1 -1
@@ -6,7 +6,7 @@ import { AnyElysia } from "../../base.js";
6
6
  declare function collectStaticRoutes(app: AnyElysia): readonly [Record<string, Record<string, Response>>, Promise<void>[]] | undefined;
7
7
  declare const BunAdapter: {
8
8
  parse: {
9
- default: (context: Context, contentType: string) => string | unknown[] | ArrayBuffer | Record<string, unknown> | Promise<unknown[] | Record<string | number | symbol, undefined>> | Promise<ArrayBuffer> | Promise<Record<string, unknown>> | Promise<string> | undefined;
9
+ default: (context: Context, contentType: string) => string | ArrayBuffer | unknown[] | Record<string, unknown> | Promise<unknown[] | Record<string | number | symbol, undefined>> | Promise<ArrayBuffer> | Promise<Record<string, unknown>> | Promise<string> | undefined;
10
10
  json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
11
11
  text: (context: Context) => MaybePromise<string>;
12
12
  urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
@@ -5,7 +5,7 @@ import { AnyElysia } from "../base.js";
5
5
  //#region src/adapter/constants.d.ts
6
6
  declare const defaultAdapter: {
7
7
  parse: {
8
- default: (context: Context, contentType: string) => string | unknown[] | ArrayBuffer | Record<string, unknown> | Promise<unknown[] | Record<string | number | symbol, undefined>> | Promise<ArrayBuffer> | Promise<Record<string, unknown>> | Promise<string> | undefined;
8
+ default: (context: Context, contentType: string) => string | ArrayBuffer | unknown[] | Record<string, unknown> | Promise<unknown[] | Record<string | number | symbol, undefined>> | Promise<ArrayBuffer> | Promise<Record<string, unknown>> | Promise<string> | undefined;
9
9
  json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
10
10
  text: (context: Context) => MaybePromise<string>;
11
11
  urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
@@ -7,7 +7,7 @@ import { AnyElysia } from "../base.js";
7
7
  //#region src/adapter/index.d.ts
8
8
  declare function createAdapter(adapter: ElysiaAdapterOptions): {
9
9
  parse: {
10
- default: (context: Context, contentType: string) => string | unknown[] | ArrayBuffer | Record<string, unknown> | Promise<unknown[] | Record<string | number | symbol, undefined>> | Promise<ArrayBuffer> | Promise<Record<string, unknown>> | Promise<string> | undefined;
10
+ default: (context: Context, contentType: string) => string | ArrayBuffer | unknown[] | Record<string, unknown> | Promise<unknown[] | Record<string | number | symbol, undefined>> | Promise<ArrayBuffer> | Promise<Record<string, unknown>> | Promise<string> | undefined;
11
11
  json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
12
12
  text: (context: Context) => MaybePromise<string>;
13
13
  urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
@@ -5,23 +5,23 @@ import { Context } from "../context.js";
5
5
 
6
6
  //#region src/adapter/utils.d.ts
7
7
  declare function handleFile(response: File | Blob, set?: Context['set'], request?: Request): Response;
8
- declare function parseSetCookies(headers: Headers, setCookie: string[]): Headers;
8
+ declare function parseSetCookies(headers: Headers, setCookies: string[]): Headers;
9
9
  declare function responseToSetHeaders(response: Response, set?: Context['set']): {
10
10
  headers: HTTPHeaders;
11
11
  status?: number | keyof StatusMap;
12
12
  cookie?: Record<string, BaseCookie>;
13
- } | {
14
- headers: any;
15
- status: number | "Continue" | "Switching Protocols" | "Processing" | "Early Hints" | "OK" | "Created" | "Accepted" | "Non-Authoritative Information" | "No Content" | "Reset Content" | "Partial Content" | "Multi-Status" | "Already Reported" | "Multiple Choices" | "Moved Permanently" | "Found" | "See Other" | "Not Modified" | "Temporary Redirect" | "Permanent Redirect" | "Bad Request" | "Unauthorized" | "Payment Required" | "Forbidden" | "Not Found" | "Method Not Allowed" | "Not Acceptable" | "Proxy Authentication Required" | "Request Timeout" | "Conflict" | "Gone" | "Length Required" | "Precondition Failed" | "Payload Too Large" | "URI Too Long" | "Unsupported Media Type" | "Range Not Satisfiable" | "Expectation Failed" | "I'm a teapot" | "Enhance Your Calm" | "Misdirected Request" | "Unprocessable Content" | "Locked" | "Failed Dependency" | "Too Early" | "Upgrade Required" | "Precondition Required" | "Too Many Requests" | "Request Header Fields Too Large" | "Unavailable For Legal Reasons" | "Internal Server Error" | "Not Implemented" | "Bad Gateway" | "Service Unavailable" | "Gateway Timeout" | "HTTP Version Not Supported" | "Variant Also Negotiates" | "Insufficient Storage" | "Loop Detected" | "Not Extended" | "Network Authentication Required";
16
13
  };
17
14
  interface CreateHandlerParameter {
18
15
  mapResponse(response: unknown, set: Context['set'], request?: Request): Response;
19
16
  mapCompactResponse(response: unknown, request?: Request): Response;
20
17
  }
21
- declare function createStreamHandler(_: CreateHandlerParameter): (generator: Generator | AsyncGenerator | ReadableStream, set?: Context["set"], request?: Request, skipFormat?: boolean) => Promise<Response>;
18
+ declare function createStreamHandler({
19
+ mapResponse,
20
+ mapCompactResponse
21
+ }: CreateHandlerParameter): (generator: Generator | AsyncGenerator | ReadableStream, set?: Context["set"], request?: Request, skipFormat?: boolean) => Promise<Response>;
22
22
  declare function streamResponse(response: Response): AsyncGenerator<any, void, any>;
23
23
  declare function handleSet(set: Context['set']): void;
24
- declare function mergeHeaders(responseHeaders: Headers, setHeaders: Context['set']['headers']): Headers;
24
+ declare function mergeHeaders(responseHeaders: Headers, setHeaders?: Context['set']['headers']): Headers;
25
25
  declare function mergeStatus(responseStatus: number, setStatus: Context['set']['status']): number | undefined;
26
26
  declare function createResponseHandler(handler: CreateHandlerParameter): (response: Response, set?: Context["set"], request?: Request) => any;
27
27
  /**
@@ -3,10 +3,13 @@ const require_universal_constants = require('../universal/constants.js');
3
3
  const require_constants = require('../constants.js');
4
4
  const require_utils = require('../utils.js');
5
5
  const require_cookie_serialize = require('../cookie/serialize.js');
6
- const require_adapter_web_standard_handler = require('./web-standard/handler.js');
7
6
 
8
7
  //#region src/adapter/utils.ts
9
8
  const setCookie = "set-cookie";
9
+ const rangeNotSatisfiable = (size, set) => new Response(null, {
10
+ status: 416,
11
+ headers: mergeHeaders(new Headers({ "content-range": `bytes */${size}` }), set?.headers)
12
+ });
10
13
  function handleFile(response, set, request) {
11
14
  if (!require_universal_constants.isBun && response instanceof Promise) return response.then((res) => handleFile(res, set, request));
12
15
  const size = response.size;
@@ -14,10 +17,7 @@ function handleFile(response, set, request) {
14
17
  if (rangeHeader) {
15
18
  const match = /bytes=(\d*)-(\d*)/.exec(rangeHeader);
16
19
  if (match) {
17
- if (!match[1] && !match[2]) return new Response(null, {
18
- status: 416,
19
- headers: mergeHeaders(new Headers({ "content-range": `bytes */${size}` }), set?.headers ?? require_utils.nullObject())
20
- });
20
+ if (!match[1] && !match[2]) return rangeNotSatisfiable(size, set);
21
21
  let start;
22
22
  let end;
23
23
  if (!match[1] && match[2]) {
@@ -28,10 +28,7 @@ function handleFile(response, set, request) {
28
28
  start = match[1] ? parseInt(match[1]) : 0;
29
29
  end = match[2] ? Math.min(parseInt(match[2]), size - 1) : size - 1;
30
30
  }
31
- if (start >= size || start > end) return new Response(null, {
32
- status: 416,
33
- headers: mergeHeaders(new Headers({ "content-range": `bytes */${size}` }), set?.headers ?? require_utils.nullObject())
34
- });
31
+ if (start >= size || start > end) return rangeNotSatisfiable(size, set);
35
32
  const contentLength = end - start + 1;
36
33
  const rangeHeaders = new Headers({
37
34
  "accept-ranges": "bytes",
@@ -40,7 +37,7 @@ function handleFile(response, set, request) {
40
37
  });
41
38
  return new Response(response.slice(start, end + 1, response.type), {
42
39
  status: 206,
43
- headers: mergeHeaders(rangeHeaders, set?.headers ?? require_utils.nullObject())
40
+ headers: mergeHeaders(rangeHeaders, set?.headers)
44
41
  });
45
42
  }
46
43
  }
@@ -68,25 +65,21 @@ function handleFile(response, set, request) {
68
65
  headers: defaultHeader
69
66
  });
70
67
  }
71
- function parseSetCookies(headers, setCookie) {
68
+ function parseSetCookies(headers, setCookies) {
72
69
  if (!headers) return headers;
73
- headers.delete("set-cookie");
74
- for (let i = 0; i < setCookie.length; i++) {
75
- const index = setCookie[i].indexOf("=");
76
- headers.append("set-cookie", `${setCookie[i].slice(0, index)}=${setCookie[i].slice(index + 1) || ""}`);
70
+ headers.delete(setCookie);
71
+ for (let i = 0; i < setCookies.length; i++) {
72
+ const index = setCookies[i].indexOf("=");
73
+ headers.append(setCookie, `${setCookies[i].slice(0, index)}=${setCookies[i].slice(index + 1) || ""}`);
77
74
  }
78
75
  return headers;
79
76
  }
80
77
  function responseToSetHeaders(response, set) {
81
78
  if (set?.headers) {
82
- if (response) if (require_universal_constants.hasHeaderShorthand) Object.assign(set.headers, response.headers.toJSON());
79
+ if (require_universal_constants.hasHeaderShorthand) Object.assign(set.headers, response.headers.toJSON());
83
80
  else for (const [key, value] of response.headers.entries()) set.headers[key] = value;
84
81
  if (set.status === void 0 || set.status === 200) set.status = response.status;
85
- } else if (!response) return {
86
- headers: require_utils.nullObject(),
87
- status: set?.status ?? 200
88
- };
89
- else if (require_universal_constants.hasHeaderShorthand) set = {
82
+ } else if (require_universal_constants.hasHeaderShorthand) set = {
90
83
  headers: response.headers.toJSON(),
91
84
  status: set?.status ?? 200
92
85
  };
@@ -121,15 +114,31 @@ function enqueueBinaryChunk(controller, chunk) {
121
114
  }
122
115
  return false;
123
116
  }
124
- function createStreamHandler(_) {
117
+ function enqueueChunk(controller, chunk, format) {
118
+ if (chunk === void 0 || chunk === null) return;
119
+ if (chunk.toSSE) controller.enqueue(chunk.toSSE());
120
+ else if (enqueueBinaryChunk(controller, chunk)) return;
121
+ else if (typeof chunk === "object") try {
122
+ controller.enqueue(format(JSON.stringify(chunk)));
123
+ } catch {
124
+ controller.enqueue(format(chunk.toString()));
125
+ }
126
+ else controller.enqueue(format(chunk.toString()));
127
+ }
128
+ function safeClose(controller) {
129
+ try {
130
+ controller.close();
131
+ } catch {}
132
+ }
133
+ function createStreamHandler({ mapResponse, mapCompactResponse }) {
125
134
  return async (generator, set, request, skipFormat) => {
126
135
  let init = generator.next?.();
127
136
  if (set) handleSet(set);
128
137
  if (init instanceof Promise) init = await init;
129
138
  if (init?.value instanceof ReadableStream) generator = init.value;
130
139
  else if (init && (typeof init?.done === "undefined" || init?.done)) {
131
- if (set) return require_adapter_web_standard_handler.mapResponse(init.value, set, request);
132
- return require_adapter_web_standard_handler.mapCompactResponse(init.value, request);
140
+ if (set) return mapResponse(init.value, set, request);
141
+ return mapCompactResponse(init.value, request);
133
142
  }
134
143
  const isSSE = !skipFormat && (init?.value?.sse ?? generator?.sse ?? set?.headers["content-type"]?.startsWith("text/event-stream"));
135
144
  const format = isSSE ? (data) => `data: ${data}\n\n` : (data) => data;
@@ -155,49 +164,20 @@ function createStreamHandler(_) {
155
164
  request?.signal?.addEventListener("abort", () => {
156
165
  end = true;
157
166
  iterator.return?.();
158
- try {
159
- controller.close();
160
- } catch {}
167
+ safeClose(controller);
161
168
  });
162
- if (!init || init.value instanceof ReadableStream || init.value === void 0 || init.value === null) return;
163
- if (init.value.toSSE) controller.enqueue(init.value.toSSE());
164
- else if (enqueueBinaryChunk(controller, init.value)) return;
165
- else if (typeof init.value === "object") try {
166
- controller.enqueue(format(JSON.stringify(init.value)));
167
- } catch {
168
- controller.enqueue(format(init.value.toString()));
169
- }
170
- else controller.enqueue(format(init.value.toString()));
169
+ if (!init || init.value instanceof ReadableStream) return;
170
+ enqueueChunk(controller, init.value, format);
171
171
  },
172
172
  async pull(controller) {
173
- if (end) {
174
- try {
175
- controller.close();
176
- } catch {}
177
- return;
178
- }
173
+ if (end) return safeClose(controller);
179
174
  try {
180
175
  const { value: chunk, done } = await iterator.next();
181
- if (done || end) {
182
- try {
183
- controller.close();
184
- } catch {}
185
- return;
186
- }
187
- if (chunk === void 0 || chunk === null) return;
188
- if (chunk.toSSE) controller.enqueue(chunk.toSSE());
189
- else if (enqueueBinaryChunk(controller, chunk)) return;
190
- else if (typeof chunk === "object") try {
191
- controller.enqueue(format(JSON.stringify(chunk)));
192
- } catch {
193
- controller.enqueue(format(chunk.toString()));
194
- }
195
- else controller.enqueue(format(chunk.toString()));
176
+ if (done || end) return safeClose(controller);
177
+ enqueueChunk(controller, chunk, format);
196
178
  } catch (error) {
197
179
  console.warn(error);
198
- try {
199
- controller.close();
200
- } catch {}
180
+ safeClose(controller);
201
181
  }
202
182
  },
203
183
  cancel() {
@@ -235,6 +215,7 @@ function applySetHeaders(target, setHeaders, present) {
235
215
  else if (!present.has(key)) target.set(key, setHeaders[key]);
236
216
  }
237
217
  function mergeHeaders(responseHeaders, setHeaders) {
218
+ if (!setHeaders) return responseHeaders;
238
219
  const headers = new Headers(responseHeaders);
239
220
  applySetHeaders(headers, setHeaders, responseHeaders);
240
221
  return headers;
@@ -2,10 +2,13 @@ import { hasHeaderShorthand, isBun } from "../universal/constants.mjs";
2
2
  import { StatusMap } from "../constants.mjs";
3
3
  import { isNotEmpty, nullObject } from "../utils.mjs";
4
4
  import { serializeCookie } from "../cookie/serialize.mjs";
5
- import { mapCompactResponse, mapResponse } from "./web-standard/handler.mjs";
6
5
 
7
6
  //#region src/adapter/utils.ts
8
7
  const setCookie = "set-cookie";
8
+ const rangeNotSatisfiable = (size, set) => new Response(null, {
9
+ status: 416,
10
+ headers: mergeHeaders(new Headers({ "content-range": `bytes */${size}` }), set?.headers)
11
+ });
9
12
  function handleFile(response, set, request) {
10
13
  if (!isBun && response instanceof Promise) return response.then((res) => handleFile(res, set, request));
11
14
  const size = response.size;
@@ -13,10 +16,7 @@ function handleFile(response, set, request) {
13
16
  if (rangeHeader) {
14
17
  const match = /bytes=(\d*)-(\d*)/.exec(rangeHeader);
15
18
  if (match) {
16
- if (!match[1] && !match[2]) return new Response(null, {
17
- status: 416,
18
- headers: mergeHeaders(new Headers({ "content-range": `bytes */${size}` }), set?.headers ?? nullObject())
19
- });
19
+ if (!match[1] && !match[2]) return rangeNotSatisfiable(size, set);
20
20
  let start;
21
21
  let end;
22
22
  if (!match[1] && match[2]) {
@@ -27,10 +27,7 @@ function handleFile(response, set, request) {
27
27
  start = match[1] ? parseInt(match[1]) : 0;
28
28
  end = match[2] ? Math.min(parseInt(match[2]), size - 1) : size - 1;
29
29
  }
30
- if (start >= size || start > end) return new Response(null, {
31
- status: 416,
32
- headers: mergeHeaders(new Headers({ "content-range": `bytes */${size}` }), set?.headers ?? nullObject())
33
- });
30
+ if (start >= size || start > end) return rangeNotSatisfiable(size, set);
34
31
  const contentLength = end - start + 1;
35
32
  const rangeHeaders = new Headers({
36
33
  "accept-ranges": "bytes",
@@ -39,7 +36,7 @@ function handleFile(response, set, request) {
39
36
  });
40
37
  return new Response(response.slice(start, end + 1, response.type), {
41
38
  status: 206,
42
- headers: mergeHeaders(rangeHeaders, set?.headers ?? nullObject())
39
+ headers: mergeHeaders(rangeHeaders, set?.headers)
43
40
  });
44
41
  }
45
42
  }
@@ -67,25 +64,21 @@ function handleFile(response, set, request) {
67
64
  headers: defaultHeader
68
65
  });
69
66
  }
70
- function parseSetCookies(headers, setCookie) {
67
+ function parseSetCookies(headers, setCookies) {
71
68
  if (!headers) return headers;
72
- headers.delete("set-cookie");
73
- for (let i = 0; i < setCookie.length; i++) {
74
- const index = setCookie[i].indexOf("=");
75
- headers.append("set-cookie", `${setCookie[i].slice(0, index)}=${setCookie[i].slice(index + 1) || ""}`);
69
+ headers.delete(setCookie);
70
+ for (let i = 0; i < setCookies.length; i++) {
71
+ const index = setCookies[i].indexOf("=");
72
+ headers.append(setCookie, `${setCookies[i].slice(0, index)}=${setCookies[i].slice(index + 1) || ""}`);
76
73
  }
77
74
  return headers;
78
75
  }
79
76
  function responseToSetHeaders(response, set) {
80
77
  if (set?.headers) {
81
- if (response) if (hasHeaderShorthand) Object.assign(set.headers, response.headers.toJSON());
78
+ if (hasHeaderShorthand) Object.assign(set.headers, response.headers.toJSON());
82
79
  else for (const [key, value] of response.headers.entries()) set.headers[key] = value;
83
80
  if (set.status === void 0 || set.status === 200) set.status = response.status;
84
- } else if (!response) return {
85
- headers: nullObject(),
86
- status: set?.status ?? 200
87
- };
88
- else if (hasHeaderShorthand) set = {
81
+ } else if (hasHeaderShorthand) set = {
89
82
  headers: response.headers.toJSON(),
90
83
  status: set?.status ?? 200
91
84
  };
@@ -120,7 +113,23 @@ function enqueueBinaryChunk(controller, chunk) {
120
113
  }
121
114
  return false;
122
115
  }
123
- function createStreamHandler(_) {
116
+ function enqueueChunk(controller, chunk, format) {
117
+ if (chunk === void 0 || chunk === null) return;
118
+ if (chunk.toSSE) controller.enqueue(chunk.toSSE());
119
+ else if (enqueueBinaryChunk(controller, chunk)) return;
120
+ else if (typeof chunk === "object") try {
121
+ controller.enqueue(format(JSON.stringify(chunk)));
122
+ } catch {
123
+ controller.enqueue(format(chunk.toString()));
124
+ }
125
+ else controller.enqueue(format(chunk.toString()));
126
+ }
127
+ function safeClose(controller) {
128
+ try {
129
+ controller.close();
130
+ } catch {}
131
+ }
132
+ function createStreamHandler({ mapResponse, mapCompactResponse }) {
124
133
  return async (generator, set, request, skipFormat) => {
125
134
  let init = generator.next?.();
126
135
  if (set) handleSet(set);
@@ -154,49 +163,20 @@ function createStreamHandler(_) {
154
163
  request?.signal?.addEventListener("abort", () => {
155
164
  end = true;
156
165
  iterator.return?.();
157
- try {
158
- controller.close();
159
- } catch {}
166
+ safeClose(controller);
160
167
  });
161
- if (!init || init.value instanceof ReadableStream || init.value === void 0 || init.value === null) return;
162
- if (init.value.toSSE) controller.enqueue(init.value.toSSE());
163
- else if (enqueueBinaryChunk(controller, init.value)) return;
164
- else if (typeof init.value === "object") try {
165
- controller.enqueue(format(JSON.stringify(init.value)));
166
- } catch {
167
- controller.enqueue(format(init.value.toString()));
168
- }
169
- else controller.enqueue(format(init.value.toString()));
168
+ if (!init || init.value instanceof ReadableStream) return;
169
+ enqueueChunk(controller, init.value, format);
170
170
  },
171
171
  async pull(controller) {
172
- if (end) {
173
- try {
174
- controller.close();
175
- } catch {}
176
- return;
177
- }
172
+ if (end) return safeClose(controller);
178
173
  try {
179
174
  const { value: chunk, done } = await iterator.next();
180
- if (done || end) {
181
- try {
182
- controller.close();
183
- } catch {}
184
- return;
185
- }
186
- if (chunk === void 0 || chunk === null) return;
187
- if (chunk.toSSE) controller.enqueue(chunk.toSSE());
188
- else if (enqueueBinaryChunk(controller, chunk)) return;
189
- else if (typeof chunk === "object") try {
190
- controller.enqueue(format(JSON.stringify(chunk)));
191
- } catch {
192
- controller.enqueue(format(chunk.toString()));
193
- }
194
- else controller.enqueue(format(chunk.toString()));
175
+ if (done || end) return safeClose(controller);
176
+ enqueueChunk(controller, chunk, format);
195
177
  } catch (error) {
196
178
  console.warn(error);
197
- try {
198
- controller.close();
199
- } catch {}
179
+ safeClose(controller);
200
180
  }
201
181
  },
202
182
  cancel() {
@@ -234,6 +214,7 @@ function applySetHeaders(target, setHeaders, present) {
234
214
  else if (!present.has(key)) target.set(key, setHeaders[key]);
235
215
  }
236
216
  function mergeHeaders(responseHeaders, setHeaders) {
217
+ if (!setHeaders) return responseHeaders;
237
218
  const headers = new Headers(responseHeaders);
238
219
  applySetHeaders(headers, setHeaders, responseHeaders);
239
220
  return headers;
@@ -109,7 +109,7 @@ function errorToResponse(error, set) {
109
109
  headers
110
110
  });
111
111
  }
112
- function mapFallback(map, mustReturn = true) {
112
+ function mapFallback(map) {
113
113
  return (response, set, request) => {
114
114
  if (response instanceof Response) return handleResponse(response, set, request);
115
115
  if (response instanceof Promise) return response.then((x) => map(x, set, request));
@@ -126,7 +126,7 @@ function mapFallback(map, mustReturn = true) {
126
126
  if (Array.isArray(response)) return Response.json(response);
127
127
  if (typeof response?.toResponse === "function") return map(response.toResponse(), set, request);
128
128
  if (response?.constructor?.name === "Cookie" && response.jar) return new Response(response.value, set);
129
- if (mustReturn) return new Response(response, set);
129
+ return new Response(response, set);
130
130
  };
131
131
  }
132
132
  const mapResponseFallback = mapFallback(mapResponse);
@@ -108,7 +108,7 @@ function errorToResponse(error, set) {
108
108
  headers
109
109
  });
110
110
  }
111
- function mapFallback(map, mustReturn = true) {
111
+ function mapFallback(map) {
112
112
  return (response, set, request) => {
113
113
  if (response instanceof Response) return handleResponse(response, set, request);
114
114
  if (response instanceof Promise) return response.then((x) => map(x, set, request));
@@ -125,7 +125,7 @@ function mapFallback(map, mustReturn = true) {
125
125
  if (Array.isArray(response)) return Response.json(response);
126
126
  if (typeof response?.toResponse === "function") return map(response.toResponse(), set, request);
127
127
  if (response?.constructor?.name === "Cookie" && response.jar) return new Response(response.value, set);
128
- if (mustReturn) return new Response(response, set);
128
+ return new Response(response, set);
129
129
  };
130
130
  }
131
131
  const mapResponseFallback = mapFallback(mapResponse);
@@ -5,7 +5,7 @@ import { AnyElysia } from "../../base.js";
5
5
  //#region src/adapter/web-standard/index.d.ts
6
6
  declare const WebStandardAdapter: {
7
7
  parse: {
8
- default: (context: Context, contentType: string) => string | unknown[] | ArrayBuffer | Record<string, unknown> | Promise<unknown[] | Record<string | number | symbol, undefined>> | Promise<ArrayBuffer> | Promise<Record<string, unknown>> | Promise<string> | undefined;
8
+ default: (context: Context, contentType: string) => string | ArrayBuffer | unknown[] | Record<string, unknown> | Promise<unknown[] | Record<string | number | symbol, undefined>> | Promise<ArrayBuffer> | Promise<Record<string, unknown>> | Promise<string> | undefined;
9
9
  json: (context: Context) => MaybePromise<Record<keyof any, undefined> | unknown[]>;
10
10
  text: (context: Context) => MaybePromise<string>;
11
11
  urlencoded: (context: Context) => MaybePromise<Record<string, string | string[]>>;
package/dist/base.js CHANGED
@@ -11,12 +11,19 @@ const require_handler_fetch = require('./handler/fetch.js');
11
11
  const require_compile_handler_index = require('./compile/handler/index.js');
12
12
  let memoirist = require("memoirist");
13
13
  memoirist = require_runtime.__toESM(memoirist);
14
+ let deuri = require("deuri");
14
15
 
15
16
  //#region src/base.ts
16
17
  const useNodesBuffer = [];
18
+ const extAssignKeys = [
19
+ "headers",
20
+ "models",
21
+ "parser",
22
+ "macro"
23
+ ];
17
24
  var Elysia = class Elysia {
18
- #hasPlugin = false;
19
- #hasGlobal = false;
25
+ #hasPlugin;
26
+ #hasGlobal;
20
27
  #ready;
21
28
  #pending = 0;
22
29
  #error;
@@ -151,7 +158,11 @@ var Elysia = class Elysia {
151
158
  this.#cachedRoutes = void 0;
152
159
  if (scope === "plugin") this.#hasPlugin = true;
153
160
  else if (scope === "global") this.#hasGlobal = true;
154
- if (this.#hash !== void 0 && !require_utils.fnOrigin.has(fn)) require_utils.fnOrigin.set(fn, this.#hash);
161
+ if (this.#hash !== void 0) {
162
+ if (Array.isArray(fn)) {
163
+ for (const f of fn) if (typeof f === "function" && !require_utils.fnOrigin.has(f)) require_utils.fnOrigin.set(f, this.#hash);
164
+ } else if (typeof fn === "function" && !require_utils.fnOrigin.has(fn)) require_utils.fnOrigin.set(fn, this.#hash);
165
+ }
155
166
  return this;
156
167
  }
157
168
  #onBranch(type, scopeOrFn, fn) {
@@ -273,15 +284,7 @@ var Elysia = class Elysia {
273
284
  }
274
285
  }
275
286
  guard() {
276
- if (arguments.length === 1) {
277
- const arg = arguments[0];
278
- let scope = "local";
279
- if (arg && typeof arg === "object" && "as" in arg && arg.as) {
280
- scope = arg.as;
281
- delete arg.as;
282
- }
283
- return this.#guard(scope, arg);
284
- }
287
+ if (arguments.length === 1) return this.#guard("local", arguments[0]);
285
288
  if (arguments.length === 2) {
286
289
  if (typeof arguments[1] === "function") return this.group("", arguments[0], arguments[1]);
287
290
  return this.#guard(arguments[0], arguments[1]);
@@ -541,7 +544,8 @@ var Elysia = class Elysia {
541
544
  }
542
545
  const hookChain = app["~hookChain"];
543
546
  if (app["~ext"]) {
544
- const { decorator, store, headers, models, parser, macro, error, hoc } = app["~ext"];
547
+ const source = app["~ext"];
548
+ const { decorator, store, error, hoc } = source;
545
549
  const ext = this["~ext"] ??= require_utils.nullObject();
546
550
  if (decorator) {
547
551
  const cloned = require_utils.clonePlainDecorators(decorator);
@@ -550,14 +554,12 @@ var Elysia = class Elysia {
550
554
  }
551
555
  if (store) if (ext.store) require_utils.mergeDeep(ext.store, store);
552
556
  else ext.store = Object.assign(require_utils.nullObject(), store);
553
- if (headers) if (ext.headers) Object.assign(ext.headers, headers);
554
- else ext.headers = Object.assign(require_utils.nullObject(), headers);
555
- if (models) if (ext.models) Object.assign(ext.models, models);
556
- else ext.models = Object.assign(require_utils.nullObject(), models);
557
- if (parser) if (ext.parser) Object.assign(ext.parser, parser);
558
- else ext.parser = Object.assign(require_utils.nullObject(), parser);
559
- if (macro) if (ext.macro) Object.assign(ext.macro, macro);
560
- else ext.macro = Object.assign(require_utils.nullObject(), macro);
557
+ for (const key of extAssignKeys) {
558
+ const value = source[key];
559
+ if (!value) continue;
560
+ if (ext[key]) Object.assign(ext[key], value);
561
+ else ext[key] = Object.assign(require_utils.nullObject(), value);
562
+ }
561
563
  if (error) if (ext.error) for (const [code, handler] of error) ext.error.set(code, handler);
562
564
  else ext.error = new Map(error);
563
565
  if (hoc) if (ext.hoc) {
@@ -805,7 +807,7 @@ var Elysia = class Elysia {
805
807
  }
806
808
  const handle = typeof handleOrConfig === "function" ? handleOrConfig : null;
807
809
  if (!handle) throw new Error("Invalid handler");
808
- const length = (typeof path === "string" && this["~Prefix"] ? this["~Prefix"] + path : path).length - (path.endsWith("*") ? 1 : 0);
810
+ const length = (this["~Prefix"] ? require_utils.joinPath(this["~Prefix"], path) : path.charCodeAt(0) !== 47 ? "/" + path : path).length - (path.endsWith("*") ? 1 : 0);
809
811
  const handler = (c) => handle(new Request(require_utils.replaceUrlPath(c.request.url, c.path.slice(length) || "/"), c.request));
810
812
  this.all(path, options, handler);
811
813
  this.all(path + (path.endsWith("/") ? "*" : "/*"), options, handler);
@@ -825,6 +827,7 @@ var Elysia = class Elysia {
825
827
  compile() {
826
828
  this["~config"] ??= require_utils.nullObject();
827
829
  this["~config"].precompile = true;
830
+ this.#routerBuilt = false;
828
831
  this.fetch;
829
832
  return this;
830
833
  }
@@ -897,7 +900,10 @@ var Elysia = class Elysia {
897
900
  }
898
901
  const wrapHeadHandler = Elysia.#wrapHeadHandler;
899
902
  const strict = !!this["~config"]?.strictPath;
900
- const routerOptions = strict ? void 0 : { loosePath: true };
903
+ const routerOptions = {
904
+ loosePath: !strict,
905
+ onParam: (value) => value.indexOf("%") !== -1 ? (0, deuri.decodeComponent)(value) ?? value : void 0
906
+ };
901
907
  const getRouter = () => this["~router"] ??= new memoirist.default(routerOptions);
902
908
  let explicitPaths;
903
909
  if (!strict && this["~config"]?.distinctPath) {
@@ -937,11 +943,7 @@ var Elysia = class Elysia {
937
943
  this["~config"] ??= require_utils.nullObject();
938
944
  const existing = this["~config"].websocket;
939
945
  if (existing && require_universal_constants.isBun) {
940
- for (const key in options) if (key in existing && existing[key] !== options[key]) {
941
- console.warn(`[Elysia] Conflicting per-route WebSocket option '${key}'`);
942
- console.warn(`Bun uses one global WebSocket config per server, so per-route values are not enforced (the last-registered route wins).`);
943
- console.warn((/* @__PURE__ */ new Error()).stack);
944
- }
946
+ for (const key in options) if (key in existing && existing[key] !== options[key]) console.warn(`[Elysia] Conflicting per-route WebSocket option '${key}' — Bun uses one global WebSocket config per server, so the last-registered route wins.`);
945
947
  Object.assign(existing, options);
946
948
  } else this["~config"].websocket = options;
947
949
  }