h3 0.8.6 → 1.0.1

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.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2020 Nuxt Contrib
3
+ Copyright (c) Pooya Parsa <pooya@pi0.io>
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -40,7 +40,7 @@ pnpm add h3
40
40
 
41
41
  ```ts
42
42
  import { createServer } from 'http'
43
- import { createApp, eventHandler } from 'h3'
43
+ import { createApp, eventHandler, toNodeListener } from 'h3'
44
44
 
45
45
  const app = createApp()
46
46
  app.use('/', eventHandler(() => 'Hello world!'))
@@ -88,7 +88,7 @@ Routes are internally stored in a [Radix Tree](https://en.wikipedia.org/wiki/Rad
88
88
 
89
89
  ```js
90
90
  // Handle can directly return object or Promise<object> for JSON response
91
- app.use('/api', eventHandler((event) => ({ url: event.req.url }))
91
+ app.use('/api', eventHandler((event) => ({ url: event.node.req.url }))
92
92
 
93
93
  // We can have better matching other than quick prefix match
94
94
  app.use('/odd', eventHandler(() => 'Is odd!'), { match: url => url.substr(1) % 2 })
@@ -137,6 +137,7 @@ H3 has concept of compasable utilities that accept `event` (from `eventHandler((
137
137
  - `assertMethod(event, expected, allowHead?)`
138
138
  - `createError({ statusCode, statusMessage, data? })`
139
139
  - `sendProxy(event, { target, headers?, fetchOptions?, fetch?, sendStream? })`
140
+ - `proxyRequest(event, { target, headers?, fetchOptions?, fetch?, sendStream? })`
140
141
 
141
142
  👉 You can learn more about usage in [JSDocs Documentation](https://www.jsdocs.io/package/h3#package-functions).
142
143
 
@@ -146,6 +147,8 @@ More composable utilities can be found in community packages.
146
147
 
147
148
  - `validateBody(event, schema)` from [h3-typebox](https://github.com/kevinmarrec/h3-typebox)
148
149
  - `validateQuery(event, schema)` from [h3-typebox](https://github.com/kevinmarrec/h3-typebox)
150
+ - `useValidatedBody(event, schema)` from [h3-zod](https://github.com/wobsoriano/h3-zod)
151
+ - `useValidatedQuery(event, schema)` from [h3-zod](https://github.com/wobsoriano/h3-zod)
149
152
 
150
153
  ## License
151
154
 
package/dist/index.cjs CHANGED
@@ -11,8 +11,8 @@ function useBase(base, handler) {
11
11
  return handler;
12
12
  }
13
13
  return eventHandler((event) => {
14
- event.req.originalUrl = event.req.originalUrl || event.req.url || "/";
15
- event.req.url = ufo.withoutBase(event.req.url || "/", base);
14
+ event.node.req.originalUrl = event.node.req.originalUrl || event.node.req.url || "/";
15
+ event.node.req.url = ufo.withoutBase(event.node.req.url || "/", base);
16
16
  return handler(event);
17
17
  });
18
18
  }
@@ -82,7 +82,7 @@ function createError(input) {
82
82
  return err;
83
83
  }
84
84
  function sendError(event, error, debug) {
85
- if (event.res.writableEnded) {
85
+ if (event.node.res.writableEnded) {
86
86
  return;
87
87
  }
88
88
  const h3Error = isError(error) ? error : createError(error);
@@ -95,27 +95,26 @@ function sendError(event, error, debug) {
95
95
  if (debug) {
96
96
  responseBody.stack = (h3Error.stack || "").split("\n").map((l) => l.trim());
97
97
  }
98
- if (event.res.writableEnded) {
98
+ if (event.node.res.writableEnded) {
99
99
  return;
100
100
  }
101
- const _code = parseInt(h3Error.statusCode);
101
+ const _code = Number.parseInt(h3Error.statusCode);
102
102
  if (_code) {
103
- event.res.statusCode = _code;
103
+ event.node.res.statusCode = _code;
104
104
  }
105
105
  if (h3Error.statusMessage) {
106
- event.res.statusMessage = h3Error.statusMessage;
106
+ event.node.res.statusMessage = h3Error.statusMessage;
107
107
  }
108
- event.res.setHeader("content-type", MIMES.json);
109
- event.res.end(JSON.stringify(responseBody, null, 2));
108
+ event.node.res.setHeader("content-type", MIMES.json);
109
+ event.node.res.end(JSON.stringify(responseBody, void 0, 2));
110
110
  }
111
111
  function isError(input) {
112
112
  return input?.constructor?.__h3_error__ === true;
113
113
  }
114
114
 
115
115
  function getQuery(event) {
116
- return ufo.getQuery(event.req.url || "");
116
+ return ufo.getQuery(event.node.req.url || "");
117
117
  }
118
- const useQuery = getQuery;
119
118
  function getRouterParams(event) {
120
119
  return event.context.params || {};
121
120
  }
@@ -124,9 +123,8 @@ function getRouterParam(event, name) {
124
123
  return params[name];
125
124
  }
126
125
  function getMethod(event, defaultMethod = "GET") {
127
- return (event.req.method || defaultMethod).toUpperCase();
126
+ return (event.node.req.method || defaultMethod).toUpperCase();
128
127
  }
129
- const useMethod = getMethod;
130
128
  function isMethod(event, expected, allowHead) {
131
129
  const method = getMethod(event);
132
130
  if (allowHead && method === "HEAD") {
@@ -151,8 +149,8 @@ function assertMethod(event, expected, allowHead) {
151
149
  }
152
150
  function getRequestHeaders(event) {
153
151
  const _headers = {};
154
- for (const key in event.req.headers) {
155
- const val = event.req.headers[key];
152
+ for (const key in event.node.req.headers) {
153
+ const val = event.node.req.headers[key];
156
154
  _headers[key] = Array.isArray(val) ? val.filter(Boolean).join(", ") : val;
157
155
  }
158
156
  return _headers;
@@ -167,22 +165,22 @@ const getHeader = getRequestHeader;
167
165
 
168
166
  const RawBodySymbol = Symbol.for("h3RawBody");
169
167
  const ParsedBodySymbol = Symbol.for("h3ParsedBody");
170
- const PayloadMethods = ["PATCH", "POST", "PUT", "DELETE"];
171
- function readRawBody(event, encoding = "utf-8") {
172
- assertMethod(event, PayloadMethods);
173
- if (RawBodySymbol in event.req) {
174
- const promise2 = Promise.resolve(event.req[RawBodySymbol]);
168
+ const PayloadMethods$1 = ["PATCH", "POST", "PUT", "DELETE"];
169
+ function readRawBody(event, encoding = "utf8") {
170
+ assertMethod(event, PayloadMethods$1);
171
+ if (RawBodySymbol in event.node.req) {
172
+ const promise2 = Promise.resolve(event.node.req[RawBodySymbol]);
175
173
  return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
176
174
  }
177
- if ("body" in event.req) {
178
- return Promise.resolve(event.req.body);
175
+ if ("body" in event.node.req) {
176
+ return Promise.resolve(event.node.req.body);
179
177
  }
180
- if (!parseInt(event.req.headers["content-length"] || "")) {
178
+ if (!Number.parseInt(event.node.req.headers["content-length"] || "")) {
181
179
  return Promise.resolve(void 0);
182
180
  }
183
- const promise = event.req[RawBodySymbol] = new Promise((resolve, reject) => {
181
+ const promise = event.node.req[RawBodySymbol] = new Promise((resolve, reject) => {
184
182
  const bodyData = [];
185
- event.req.on("error", (err) => {
183
+ event.node.req.on("error", (err) => {
186
184
  reject(err);
187
185
  }).on("data", (chunk) => {
188
186
  bodyData.push(chunk);
@@ -192,49 +190,45 @@ function readRawBody(event, encoding = "utf-8") {
192
190
  });
193
191
  return encoding ? promise.then((buff) => buff.toString(encoding)) : promise;
194
192
  }
195
- const useRawBody = readRawBody;
196
193
  async function readBody(event) {
197
- if (ParsedBodySymbol in event.req) {
198
- return event.req[ParsedBodySymbol];
194
+ if (ParsedBodySymbol in event.node.req) {
195
+ return event.node.req[ParsedBodySymbol];
199
196
  }
200
197
  const body = await readRawBody(event);
201
- if (event.req.headers["content-type"] === "application/x-www-form-urlencoded") {
198
+ if (event.node.req.headers["content-type"] === "application/x-www-form-urlencoded") {
202
199
  const parsedForm = Object.fromEntries(new URLSearchParams(body));
203
200
  return parsedForm;
204
201
  }
205
202
  const json = destr(body);
206
- event.req[ParsedBodySymbol] = json;
203
+ event.node.req[ParsedBodySymbol] = json;
207
204
  return json;
208
205
  }
209
- const useBody = readBody;
210
206
 
211
207
  function handleCacheHeaders(event, opts) {
212
- const cacheControls = ["public"].concat(opts.cacheControls || []);
208
+ const cacheControls = ["public", ...opts.cacheControls || []];
213
209
  let cacheMatched = false;
214
210
  if (opts.maxAge !== void 0) {
215
211
  cacheControls.push(`max-age=${+opts.maxAge}`, `s-maxage=${+opts.maxAge}`);
216
212
  }
217
213
  if (opts.modifiedTime) {
218
214
  const modifiedTime = new Date(opts.modifiedTime);
219
- const ifModifiedSince = event.req.headers["if-modified-since"];
220
- event.res.setHeader("last-modified", modifiedTime.toUTCString());
221
- if (ifModifiedSince) {
222
- if (new Date(ifModifiedSince) >= opts.modifiedTime) {
223
- cacheMatched = true;
224
- }
215
+ const ifModifiedSince = event.node.req.headers["if-modified-since"];
216
+ event.node.res.setHeader("last-modified", modifiedTime.toUTCString());
217
+ if (ifModifiedSince && new Date(ifModifiedSince) >= opts.modifiedTime) {
218
+ cacheMatched = true;
225
219
  }
226
220
  }
227
221
  if (opts.etag) {
228
- event.res.setHeader("etag", opts.etag);
229
- const ifNonMatch = event.req.headers["if-none-match"];
222
+ event.node.res.setHeader("etag", opts.etag);
223
+ const ifNonMatch = event.node.req.headers["if-none-match"];
230
224
  if (ifNonMatch === opts.etag) {
231
225
  cacheMatched = true;
232
226
  }
233
227
  }
234
- event.res.setHeader("cache-control", cacheControls.join(", "));
228
+ event.node.res.setHeader("cache-control", cacheControls.join(", "));
235
229
  if (cacheMatched) {
236
- event.res.statusCode = 304;
237
- event.res.end();
230
+ event.node.res.statusCode = 304;
231
+ event.node.res.end();
238
232
  return true;
239
233
  }
240
234
  return false;
@@ -252,51 +246,55 @@ function send(event, data, type) {
252
246
  }
253
247
  return new Promise((resolve) => {
254
248
  defer(() => {
255
- event.res.end(data);
256
- resolve(void 0);
249
+ event.node.res.end(data);
250
+ resolve();
257
251
  });
258
252
  });
259
253
  }
260
254
  function defaultContentType(event, type) {
261
- if (type && !event.res.getHeader("content-type")) {
262
- event.res.setHeader("content-type", type);
255
+ if (type && !event.node.res.getHeader("content-type")) {
256
+ event.node.res.setHeader("content-type", type);
263
257
  }
264
258
  }
265
259
  function sendRedirect(event, location, code = 302) {
266
- event.res.statusCode = code;
267
- event.res.setHeader("location", location);
260
+ event.node.res.statusCode = code;
261
+ event.node.res.setHeader("location", location);
268
262
  const encodedLoc = location.replace(/"/g, "%22");
269
263
  const html = `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`;
270
264
  return send(event, html, MIMES.html);
271
265
  }
272
266
  function getResponseHeaders(event) {
273
- return event.res.getHeaders();
267
+ return event.node.res.getHeaders();
274
268
  }
275
269
  function getResponseHeader(event, name) {
276
- return event.res.getHeader(name);
270
+ return event.node.res.getHeader(name);
277
271
  }
278
272
  function setResponseHeaders(event, headers) {
279
- Object.entries(headers).forEach(([name, value]) => event.res.setHeader(name, value));
273
+ for (const [name, value] of Object.entries(headers)) {
274
+ event.node.res.setHeader(name, value);
275
+ }
280
276
  }
281
277
  const setHeaders = setResponseHeaders;
282
278
  function setResponseHeader(event, name, value) {
283
- event.res.setHeader(name, value);
279
+ event.node.res.setHeader(name, value);
284
280
  }
285
281
  const setHeader = setResponseHeader;
286
282
  function appendResponseHeaders(event, headers) {
287
- Object.entries(headers).forEach(([name, value]) => appendResponseHeader(event, name, value));
283
+ for (const [name, value] of Object.entries(headers)) {
284
+ appendResponseHeader(event, name, value);
285
+ }
288
286
  }
289
287
  const appendHeaders = appendResponseHeaders;
290
288
  function appendResponseHeader(event, name, value) {
291
- let current = event.res.getHeader(name);
289
+ let current = event.node.res.getHeader(name);
292
290
  if (!current) {
293
- event.res.setHeader(name, value);
291
+ event.node.res.setHeader(name, value);
294
292
  return;
295
293
  }
296
294
  if (!Array.isArray(current)) {
297
295
  current = [current.toString()];
298
296
  }
299
- event.res.setHeader(name, current.concat(value));
297
+ event.node.res.setHeader(name, [...current, value]);
300
298
  }
301
299
  const appendHeader = appendResponseHeader;
302
300
  function isStream(data) {
@@ -304,15 +302,15 @@ function isStream(data) {
304
302
  }
305
303
  function sendStream(event, data) {
306
304
  return new Promise((resolve, reject) => {
307
- data.pipe(event.res);
308
- data.on("end", () => resolve(void 0));
305
+ data.pipe(event.node.res);
306
+ data.on("end", () => resolve());
309
307
  data.on("error", (error) => reject(createError(error)));
310
308
  });
311
309
  }
312
310
  const noop = () => {
313
311
  };
314
312
  function writeEarlyHints(event, hints, cb = noop) {
315
- if (!event.res.socket) {
313
+ if (!event.node.res.socket) {
316
314
  cb();
317
315
  return;
318
316
  }
@@ -323,7 +321,7 @@ function writeEarlyHints(event, hints, cb = noop) {
323
321
  hints.link = Array.isArray(hints.link) ? hints.link : hints.link.split(",");
324
322
  }
325
323
  const headers = Object.entries(hints).map((e) => [e[0].toLowerCase(), e[1]]);
326
- if (!headers.length) {
324
+ if (headers.length === 0) {
327
325
  cb();
328
326
  return;
329
327
  }
@@ -339,19 +337,17 @@ Link: ${hints.link.join(", ")}`;
339
337
  hint += `\r
340
338
  ${header}: ${value}`;
341
339
  }
342
- event.res.socket.write(`${hint}\r
340
+ event.node.res.socket.write(`${hint}\r
343
341
  \r
344
- `, "utf-8", cb);
342
+ `, "utf8", cb);
345
343
  }
346
344
 
347
345
  function parseCookies(event) {
348
- return cookieEs.parse(event.req.headers.cookie || "");
346
+ return cookieEs.parse(event.node.req.headers.cookie || "");
349
347
  }
350
- const useCookies = parseCookies;
351
348
  function getCookie(event, name) {
352
349
  return parseCookies(event)[name];
353
350
  }
354
- const useCookie = getCookie;
355
351
  function setCookie(event, name, value, serializeOptions) {
356
352
  const cookieStr = cookieEs.serialize(name, value, {
357
353
  path: "/",
@@ -366,6 +362,43 @@ function deleteCookie(event, name, serializeOptions) {
366
362
  });
367
363
  }
368
364
 
365
+ const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
366
+ const ignoredHeaders = /* @__PURE__ */ new Set([
367
+ "transfer-encoding",
368
+ "connection",
369
+ "keep-alive",
370
+ "upgrade",
371
+ "expect"
372
+ ]);
373
+ async function proxyRequest(event, target, opts = {}) {
374
+ const method = getMethod(event);
375
+ let body;
376
+ if (PayloadMethods.has(method)) {
377
+ body = await readRawBody(event).catch(() => void 0);
378
+ }
379
+ const headers = /* @__PURE__ */ Object.create(null);
380
+ const reqHeaders = getRequestHeaders(event);
381
+ for (const name in reqHeaders) {
382
+ if (!ignoredHeaders.has(name)) {
383
+ headers[name] = reqHeaders[name];
384
+ }
385
+ }
386
+ if (opts.fetchOptions?.headers) {
387
+ Object.assign(headers, opts.fetchOptions.headers);
388
+ }
389
+ if (opts.headers) {
390
+ Object.assign(headers, opts.headers);
391
+ }
392
+ return sendProxy(event, target, {
393
+ ...opts,
394
+ fetchOptions: {
395
+ headers,
396
+ method,
397
+ body,
398
+ ...opts.fetchOptions
399
+ }
400
+ });
401
+ }
369
402
  async function sendProxy(event, target, opts = {}) {
370
403
  const _fetch = opts.fetch || globalThis.fetch;
371
404
  if (!_fetch) {
@@ -375,8 +408,8 @@ async function sendProxy(event, target, opts = {}) {
375
408
  headers: opts.headers,
376
409
  ...opts.fetchOptions
377
410
  });
378
- event.res.statusCode = response.status;
379
- event.res.statusMessage = response.statusText;
411
+ event.node.res.statusCode = response.status;
412
+ event.node.res.statusMessage = response.statusText;
380
413
  for (const [key, value] of response.headers.entries()) {
381
414
  if (key === "content-encoding") {
382
415
  continue;
@@ -384,23 +417,23 @@ async function sendProxy(event, target, opts = {}) {
384
417
  if (key === "content-length") {
385
418
  continue;
386
419
  }
387
- event.res.setHeader(key, value);
420
+ event.node.res.setHeader(key, value);
388
421
  }
389
422
  try {
390
423
  if (response.body) {
391
424
  if (opts.sendStream === false) {
392
425
  const data = new Uint8Array(await response.arrayBuffer());
393
- event.res.end(data);
426
+ event.node.res.end(data);
394
427
  } else {
395
428
  for await (const chunk of response.body) {
396
- event.res.write(chunk);
429
+ event.node.res.write(chunk);
397
430
  }
398
- event.res.end();
431
+ event.node.res.end();
399
432
  }
400
433
  }
401
- } catch (err) {
402
- event.res.end();
403
- throw err;
434
+ } catch (error) {
435
+ event.node.res.end();
436
+ throw error;
404
437
  }
405
438
  }
406
439
 
@@ -411,7 +444,7 @@ class H3Headers {
411
444
  } else if (Array.isArray(init)) {
412
445
  this._headers = Object.fromEntries(init.map(([key, value]) => [key.toLowerCase(), value]));
413
446
  } else if (init && "append" in init) {
414
- this._headers = Object.fromEntries([...init.entries()]);
447
+ this._headers = Object.fromEntries(init.entries());
415
448
  } else {
416
449
  this._headers = Object.fromEntries(Object.entries(init).map(([key, value]) => [key.toLowerCase(), value]));
417
450
  }
@@ -445,7 +478,9 @@ class H3Headers {
445
478
  this._headers[name.toLowerCase()] = String(value);
446
479
  }
447
480
  forEach(callbackfn) {
448
- Object.entries(this._headers).forEach(([key, value]) => callbackfn(value, key, this));
481
+ for (const [key, value] of Object.entries(this._headers)) {
482
+ callbackfn(value, key, this);
483
+ }
449
484
  }
450
485
  }
451
486
 
@@ -490,8 +525,16 @@ class H3Event {
490
525
  constructor(req, res) {
491
526
  this["__is_event__"] = true;
492
527
  this.context = {};
493
- this.req = req;
494
- this.res = res;
528
+ this.node = { req, res };
529
+ }
530
+ get path() {
531
+ return this.req.url;
532
+ }
533
+ get req() {
534
+ return this.node.req;
535
+ }
536
+ get res() {
537
+ return this.node.res;
495
538
  }
496
539
  respondWith(r) {
497
540
  Promise.resolve(r).then((_response) => {
@@ -499,9 +542,9 @@ class H3Event {
499
542
  return;
500
543
  }
501
544
  const response = _response instanceof H3Response ? _response : new H3Response(_response);
502
- response.headers.forEach((value, key) => {
545
+ for (const [key, value] of response.headers.entries()) {
503
546
  this.res.setHeader(key, value);
504
- });
547
+ }
505
548
  if (response.status) {
506
549
  this.res.statusCode = response.status;
507
550
  }
@@ -604,9 +647,13 @@ function createApp(options = {}) {
604
647
  }
605
648
  function use(app, arg1, arg2, arg3) {
606
649
  if (Array.isArray(arg1)) {
607
- arg1.forEach((i) => use(app, i, arg2, arg3));
650
+ for (const i of arg1) {
651
+ use(app, i, arg2, arg3);
652
+ }
608
653
  } else if (Array.isArray(arg2)) {
609
- arg2.forEach((i) => use(app, arg1, i, arg3));
654
+ for (const i of arg2) {
655
+ use(app, arg1, i, arg3);
656
+ }
610
657
  } else if (typeof arg1 === "string") {
611
658
  app.stack.push(normalizeLayer({ ...arg3, route: arg1, handler: arg2 }));
612
659
  } else if (typeof arg1 === "function") {
@@ -619,22 +666,22 @@ function use(app, arg1, arg2, arg3) {
619
666
  function createAppEventHandler(stack, options) {
620
667
  const spacing = options.debug ? 2 : void 0;
621
668
  return eventHandler(async (event) => {
622
- event.req.originalUrl = event.req.originalUrl || event.req.url || "/";
623
- const reqUrl = event.req.url || "/";
669
+ event.node.req.originalUrl = event.node.req.originalUrl || event.node.req.url || "/";
670
+ const reqUrl = event.node.req.url || "/";
624
671
  for (const layer of stack) {
625
672
  if (layer.route.length > 1) {
626
673
  if (!reqUrl.startsWith(layer.route)) {
627
674
  continue;
628
675
  }
629
- event.req.url = reqUrl.slice(layer.route.length) || "/";
676
+ event.node.req.url = reqUrl.slice(layer.route.length) || "/";
630
677
  } else {
631
- event.req.url = reqUrl;
678
+ event.node.req.url = reqUrl;
632
679
  }
633
- if (layer.match && !layer.match(event.req.url, event)) {
680
+ if (layer.match && !layer.match(event.node.req.url, event)) {
634
681
  continue;
635
682
  }
636
683
  const val = await layer.handler(event);
637
- if (event.res.writableEnded) {
684
+ if (event.node.res.writableEnded) {
638
685
  return;
639
686
  }
640
687
  const type = typeof val;
@@ -643,7 +690,7 @@ function createAppEventHandler(stack, options) {
643
690
  } else if (isStream(val)) {
644
691
  return sendStream(event, val);
645
692
  } else if (val === null) {
646
- event.res.statusCode = 204;
693
+ event.node.res.statusCode = 204;
647
694
  return send(event);
648
695
  } else if (type === "object" || type === "boolean" || type === "number") {
649
696
  if (val.buffer) {
@@ -651,14 +698,14 @@ function createAppEventHandler(stack, options) {
651
698
  } else if (val instanceof Error) {
652
699
  throw createError(val);
653
700
  } else {
654
- return send(event, JSON.stringify(val, null, spacing), MIMES.json);
701
+ return send(event, JSON.stringify(val, void 0, spacing), MIMES.json);
655
702
  }
656
703
  }
657
704
  }
658
- if (!event.res.writableEnded) {
705
+ if (!event.node.res.writableEnded) {
659
706
  throw createError({
660
707
  statusCode: 404,
661
- statusMessage: `Cannot find any route matching ${event.req.url || "/"}.`
708
+ statusMessage: `Cannot find any route matching ${event.node.req.url || "/"}.`
662
709
  });
663
710
  }
664
711
  });
@@ -671,7 +718,7 @@ function normalizeLayer(input) {
671
718
  if (input.lazy) {
672
719
  handler = lazyEventHandler(handler);
673
720
  } else if (!isEventHandler(handler)) {
674
- handler = toEventHandler(handler, null, input.route);
721
+ handler = toEventHandler(handler, void 0, input.route);
675
722
  }
676
723
  return {
677
724
  route: ufo.withoutTrailingSlash(input.route),
@@ -690,7 +737,7 @@ function fromNodeMiddleware(handler) {
690
737
  throw new TypeError("Invalid handler. It should be a function:", handler);
691
738
  }
692
739
  return eventHandler((event) => {
693
- return callNodeListener(handler, event.req, event.res);
740
+ return callNodeListener(handler, event.node.req, event.node.res);
694
741
  });
695
742
  }
696
743
  function toNodeListener(app) {
@@ -738,8 +785,8 @@ function callNodeListener(handler, req, res) {
738
785
  } else {
739
786
  resolve(returned);
740
787
  }
741
- } catch (err) {
742
- next(err);
788
+ } catch (error) {
789
+ next(error);
743
790
  }
744
791
  });
745
792
  }
@@ -756,9 +803,11 @@ function createRouter(opts = {}) {
756
803
  _router.insert(path, route);
757
804
  }
758
805
  if (Array.isArray(method)) {
759
- method.forEach((m) => addRoute(path, handler, m));
806
+ for (const m of method) {
807
+ addRoute(path, handler, m);
808
+ }
760
809
  } else {
761
- route.handlers[method] = toEventHandler(handler, null, path);
810
+ route.handlers[method] = toEventHandler(handler, void 0, path);
762
811
  }
763
812
  return router;
764
813
  };
@@ -767,10 +816,10 @@ function createRouter(opts = {}) {
767
816
  router[method] = (path, handle) => router.add(path, handle, method);
768
817
  }
769
818
  router.handler = eventHandler((event) => {
770
- let path = event.req.url || "/";
819
+ let path = event.node.req.url || "/";
771
820
  const qIndex = path.indexOf("?");
772
821
  if (qIndex !== -1) {
773
- path = path.substring(0, qIndex);
822
+ path = path.slice(0, Math.max(0, qIndex));
774
823
  }
775
824
  const matched = _router.lookup(path);
776
825
  if (!matched) {
@@ -778,13 +827,13 @@ function createRouter(opts = {}) {
778
827
  throw createError({
779
828
  statusCode: 404,
780
829
  name: "Not Found",
781
- statusMessage: `Cannot find any route matching ${event.req.url || "/"}.`
830
+ statusMessage: `Cannot find any route matching ${event.node.req.url || "/"}.`
782
831
  });
783
832
  } else {
784
833
  return;
785
834
  }
786
835
  }
787
- const method = (event.req.method || "get").toLowerCase();
836
+ const method = (event.node.req.method || "get").toLowerCase();
788
837
  const handler = matched.handlers[method] || matched.handlers.all;
789
838
  if (!handler) {
790
839
  throw createError({
@@ -845,6 +894,7 @@ exports.isStream = isStream;
845
894
  exports.lazyEventHandler = lazyEventHandler;
846
895
  exports.parseCookies = parseCookies;
847
896
  exports.promisifyNodeListener = promisifyNodeListener;
897
+ exports.proxyRequest = proxyRequest;
848
898
  exports.readBody = readBody;
849
899
  exports.readRawBody = readRawBody;
850
900
  exports.send = send;
@@ -861,10 +911,4 @@ exports.toEventHandler = toEventHandler;
861
911
  exports.toNodeListener = toNodeListener;
862
912
  exports.use = use;
863
913
  exports.useBase = useBase;
864
- exports.useBody = useBody;
865
- exports.useCookie = useCookie;
866
- exports.useCookies = useCookies;
867
- exports.useMethod = useMethod;
868
- exports.useQuery = useQuery;
869
- exports.useRawBody = useRawBody;
870
914
  exports.writeEarlyHints = writeEarlyHints;