h3 1.15.0 → 1.15.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  const ufo = require('ufo');
4
4
  const cookieEs = require('cookie-es');
5
- const ohash = require('ohash');
6
5
  const radix3 = require('radix3');
7
6
  const destr = require('destr');
8
7
  const defu = require('defu');
@@ -63,7 +62,7 @@ class H3Error extends Error {
63
62
  if (this.statusMessage) {
64
63
  obj.statusMessage = sanitizeStatusMessage(this.statusMessage);
65
64
  }
66
- if (this.data !== undefined) {
65
+ if (this.data !== void 0) {
67
66
  obj.data = this.data;
68
67
  }
69
68
  return obj;
@@ -115,10 +114,10 @@ function createError(input) {
115
114
  );
116
115
  }
117
116
  }
118
- if (input.fatal !== undefined) {
117
+ if (input.fatal !== void 0) {
119
118
  err.fatal = input.fatal;
120
119
  }
121
- if (input.unhandled !== undefined) {
120
+ if (input.unhandled !== void 0) {
122
121
  err.unhandled = input.unhandled;
123
122
  }
124
123
  return err;
@@ -143,7 +142,7 @@ function sendError(event, error, debug) {
143
142
  const _code = Number.parseInt(h3Error.statusCode);
144
143
  setResponseStatus(event, _code, h3Error.statusMessage);
145
144
  event.node.res.setHeader("content-type", MIMES.json);
146
- event.node.res.end(JSON.stringify(responseBody, undefined, 2));
145
+ event.node.res.end(JSON.stringify(responseBody, void 0, 2));
147
146
  }
148
147
  function isError(input) {
149
148
  return input?.constructor?.__h3_error__ === true;
@@ -411,12 +410,15 @@ function readRawBody(event, encoding = "utf8") {
411
410
  if (_resolved instanceof URLSearchParams) {
412
411
  return Buffer.from(_resolved.toString());
413
412
  }
413
+ if (_resolved instanceof FormData) {
414
+ return new Response(_resolved).bytes().then((uint8arr) => Buffer.from(uint8arr));
415
+ }
414
416
  return Buffer.from(_resolved);
415
417
  });
416
418
  return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
417
419
  }
418
420
  if (!Number.parseInt(event.node.req.headers["content-length"] || "") && !String(event.node.req.headers["transfer-encoding"] ?? "").split(",").map((e) => e.trim()).filter(Boolean).includes("chunked")) {
419
- return Promise.resolve(undefined);
421
+ return Promise.resolve(void 0);
420
422
  }
421
423
  const promise = event.node.req[RawBodySymbol] = new Promise(
422
424
  (resolve, reject) => {
@@ -511,7 +513,7 @@ function getRequestWebStream(event) {
511
513
  }
512
514
  function _parseJSON(body = "", strict) {
513
515
  if (!body) {
514
- return undefined;
516
+ return void 0;
515
517
  }
516
518
  try {
517
519
  return destr__default(body, { strict });
@@ -542,14 +544,14 @@ function _parseURLEncodedBody(body) {
542
544
  function handleCacheHeaders(event, opts) {
543
545
  const cacheControls = ["public", ...opts.cacheControls || []];
544
546
  let cacheMatched = false;
545
- if (opts.maxAge !== undefined) {
547
+ if (opts.maxAge !== void 0) {
546
548
  cacheControls.push(`max-age=${+opts.maxAge}`, `s-maxage=${+opts.maxAge}`);
547
549
  }
548
550
  if (opts.modifiedTime) {
549
551
  const modifiedTime = new Date(opts.modifiedTime);
550
552
  const ifModifiedSince = event.node.req.headers["if-modified-since"];
551
553
  event.node.res.setHeader("last-modified", modifiedTime.toUTCString());
552
- if (ifModifiedSince && new Date(ifModifiedSince) >= opts.modifiedTime) {
554
+ if (ifModifiedSince && new Date(ifModifiedSince) >= modifiedTime) {
553
555
  cacheMatched = true;
554
556
  }
555
557
  }
@@ -593,24 +595,39 @@ function sanitizeStatusCode(statusCode, defaultStatusCode = 200) {
593
595
  return statusCode;
594
596
  }
595
597
 
598
+ function getDistinctCookieKey(name, opts) {
599
+ return [name, opts.domain || "", opts.path || "/"].join(";");
600
+ }
601
+
596
602
  function parseCookies(event) {
597
603
  return cookieEs.parse(event.node.req.headers.cookie || "");
598
604
  }
599
605
  function getCookie(event, name) {
600
606
  return parseCookies(event)[name];
601
607
  }
602
- function setCookie(event, name, value, serializeOptions) {
603
- serializeOptions = { path: "/", ...serializeOptions };
604
- const cookieStr = cookieEs.serialize(name, value, serializeOptions);
605
- let setCookies = event.node.res.getHeader("set-cookie");
606
- if (!Array.isArray(setCookies)) {
607
- setCookies = [setCookies];
608
+ function setCookie(event, name, value, serializeOptions = {}) {
609
+ if (!serializeOptions.path) {
610
+ serializeOptions = { path: "/", ...serializeOptions };
608
611
  }
609
- const _optionsHash = ohash.objectHash(serializeOptions);
610
- setCookies = setCookies.filter((cookieValue) => {
611
- return cookieValue && _optionsHash !== ohash.objectHash(cookieEs.parse(cookieValue));
612
- });
613
- event.node.res.setHeader("set-cookie", [...setCookies, cookieStr]);
612
+ const newCookie = cookieEs.serialize(name, value, serializeOptions);
613
+ const currentCookies = splitCookiesString(
614
+ event.node.res.getHeader("set-cookie")
615
+ );
616
+ if (currentCookies.length === 0) {
617
+ event.node.res.setHeader("set-cookie", newCookie);
618
+ return;
619
+ }
620
+ const newCookieKey = getDistinctCookieKey(name, serializeOptions);
621
+ event.node.res.removeHeader("set-cookie");
622
+ for (const cookie of currentCookies) {
623
+ const parsed = cookieEs.parseSetCookie(cookie);
624
+ const key = getDistinctCookieKey(parsed.name, parsed);
625
+ if (key === newCookieKey) {
626
+ continue;
627
+ }
628
+ event.node.res.appendHeader("set-cookie", cookie);
629
+ }
630
+ event.node.res.appendHeader("set-cookie", newCookie);
614
631
  }
615
632
  function deleteCookie(event, name, serializeOptions) {
616
633
  setCookie(event, name, "", {
@@ -687,7 +704,7 @@ function serializeIterableValue(value) {
687
704
  }
688
705
  case "function":
689
706
  case "undefined": {
690
- return undefined;
707
+ return void 0;
691
708
  }
692
709
  case "object": {
693
710
  if (value instanceof Uint8Array) {
@@ -960,9 +977,9 @@ function sendIterable(event, iterable, options) {
960
977
  new ReadableStream({
961
978
  async pull(controller) {
962
979
  const { value, done } = await iterator.next();
963
- if (value !== undefined) {
980
+ if (value !== void 0) {
964
981
  const chunk = serializer(value);
965
- if (chunk !== undefined) {
982
+ if (chunk !== void 0) {
966
983
  controller.enqueue(chunk);
967
984
  }
968
985
  }
@@ -1140,7 +1157,7 @@ async function proxyRequest(event, target, opts = {}) {
1140
1157
  body = getRequestWebStream(event);
1141
1158
  duplex = "half";
1142
1159
  } else {
1143
- body = await readRawBody(event, false).catch(() => undefined);
1160
+ body = await readRawBody(event, false).catch(() => void 0);
1144
1161
  }
1145
1162
  }
1146
1163
  const method = opts.fetchOptions?.method || event.method;
@@ -1220,7 +1237,7 @@ async function sendProxy(event, target, opts = {}) {
1220
1237
  if (opts.onResponse) {
1221
1238
  await opts.onResponse(event, response);
1222
1239
  }
1223
- if (response._data !== undefined) {
1240
+ if (response._data !== void 0) {
1224
1241
  return response._data;
1225
1242
  }
1226
1243
  if (event.handled) {
@@ -1294,8 +1311,9 @@ function mergeHeaders(defaults, ...inputs) {
1294
1311
  }
1295
1312
  const merged = new Headers(defaults);
1296
1313
  for (const input of _inputs) {
1297
- for (const [key, value] of Object.entries(input)) {
1298
- if (value !== undefined) {
1314
+ const entries = Array.isArray(input) ? input : typeof input.entries === "function" ? input.entries() : Object.entries(input);
1315
+ for (const [key, value] of entries) {
1316
+ if (value !== void 0) {
1299
1317
  merged.set(key, value);
1300
1318
  }
1301
1319
  }
@@ -1412,7 +1430,7 @@ async function updateSession(event, config, update) {
1412
1430
  const sealed = await sealSession(event, config);
1413
1431
  setCookie(event, sessionName, sealed, {
1414
1432
  ...DEFAULT_COOKIE,
1415
- expires: config.maxAge ? new Date(session.createdAt + config.maxAge * 1e3) : undefined,
1433
+ expires: config.maxAge ? new Date(session.createdAt + config.maxAge * 1e3) : void 0,
1416
1434
  ...config.cookie
1417
1435
  });
1418
1436
  }
@@ -1498,7 +1516,7 @@ function setEventStreamHeaders(event) {
1498
1516
  setResponseHeaders(event, headers);
1499
1517
  }
1500
1518
  function isHttp2Request(event) {
1501
- return getHeader(event, ":path") !== undefined && getHeader(event, ":method") !== undefined;
1519
+ return getHeader(event, ":path") !== void 0 && getHeader(event, ":method") !== void 0;
1502
1520
  }
1503
1521
 
1504
1522
  class EventStream {
@@ -1588,7 +1606,7 @@ class EventStream {
1588
1606
  }
1589
1607
  if (this._unsentData?.length) {
1590
1608
  await this._writer.write(this._encoder.encode(this._unsentData));
1591
- this._unsentData = undefined;
1609
+ this._unsentData = void 0;
1592
1610
  }
1593
1611
  }
1594
1612
  /**
@@ -1698,7 +1716,7 @@ async function serveStatic(event, options) {
1698
1716
  if (meta.encoding && !getResponseHeader(event, "content-encoding")) {
1699
1717
  setResponseHeader(event, "content-encoding", meta.encoding);
1700
1718
  }
1701
- if (meta.size !== undefined && meta.size > 0 && !getResponseHeader(event, "content-length")) {
1719
+ if (meta.size !== void 0 && meta.size > 0 && !getResponseHeader(event, "content-length")) {
1702
1720
  setResponseHeader(event, "content-length", meta.size);
1703
1721
  }
1704
1722
  if (event.method === "HEAD") {
@@ -1840,7 +1858,7 @@ function defineEventHandler(handler) {
1840
1858
  return _handler;
1841
1859
  }
1842
1860
  function _normalizeArray(input) {
1843
- return input ? Array.isArray(input) ? input : [input] : undefined;
1861
+ return input ? Array.isArray(input) ? input : [input] : void 0;
1844
1862
  }
1845
1863
  async function _callHandler(event, handler, hooks) {
1846
1864
  if (hooks.onRequest) {
@@ -1970,7 +1988,7 @@ function use(app, arg1, arg2, arg3) {
1970
1988
  return app;
1971
1989
  }
1972
1990
  function createAppEventHandler(stack, options) {
1973
- const spacing = options.debug ? 2 : undefined;
1991
+ const spacing = options.debug ? 2 : void 0;
1974
1992
  return eventHandler(async (event) => {
1975
1993
  event.node.req.originalUrl = event.node.req.originalUrl || event.node.req.url || "/";
1976
1994
  const _reqPath = event._path || event.node.req.url || "/";
@@ -1993,8 +2011,8 @@ function createAppEventHandler(stack, options) {
1993
2011
  event._path = _layerPath;
1994
2012
  event.node.req.url = _layerPath;
1995
2013
  const val = await layer.handler(event);
1996
- const _body = val === undefined ? undefined : await val;
1997
- if (_body !== undefined) {
2014
+ const _body = val === void 0 ? void 0 : await val;
2015
+ if (_body !== void 0) {
1998
2016
  const _response = { body: _body };
1999
2017
  if (options.onBeforeResponse) {
2000
2018
  event._onBeforeResponseCalled = true;
@@ -2010,7 +2028,7 @@ function createAppEventHandler(stack, options) {
2010
2028
  if (event.handled) {
2011
2029
  if (options.onAfterResponse) {
2012
2030
  event._onAfterResponseCalled = true;
2013
- await options.onAfterResponse(event, undefined);
2031
+ await options.onAfterResponse(event, void 0);
2014
2032
  }
2015
2033
  return;
2016
2034
  }
@@ -2023,7 +2041,7 @@ function createAppEventHandler(stack, options) {
2023
2041
  }
2024
2042
  if (options.onAfterResponse) {
2025
2043
  event._onAfterResponseCalled = true;
2026
- await options.onAfterResponse(event, undefined);
2044
+ await options.onAfterResponse(event, void 0);
2027
2045
  }
2028
2046
  });
2029
2047
  }
@@ -2038,7 +2056,7 @@ function createResolver(stack) {
2038
2056
  continue;
2039
2057
  }
2040
2058
  _layerPath = path.slice(layer.route.length) || "/";
2041
- if (layer.match && !layer.match(_layerPath, undefined)) {
2059
+ if (layer.match && !layer.match(_layerPath, void 0)) {
2042
2060
  continue;
2043
2061
  }
2044
2062
  let res = { route: layer.route, handler: layer.handler };
@@ -2065,7 +2083,7 @@ function normalizeLayer(input) {
2065
2083
  if (input.lazy) {
2066
2084
  handler = lazyEventHandler(handler);
2067
2085
  } else if (!isEventHandler(handler)) {
2068
- handler = toEventHandler(handler, undefined, input.route);
2086
+ handler = toEventHandler(handler, void 0, input.route);
2069
2087
  }
2070
2088
  return {
2071
2089
  route: ufo.withoutTrailingSlash(input.route),
@@ -2104,7 +2122,7 @@ function handleHandlerResponse(event, val, jsonSpace) {
2104
2122
  return send(event, val, MIMES.html);
2105
2123
  }
2106
2124
  if (valType === "object" || valType === "boolean" || valType === "number") {
2107
- return send(event, JSON.stringify(val, undefined, jsonSpace), MIMES.json);
2125
+ return send(event, JSON.stringify(val, void 0, jsonSpace), MIMES.json);
2108
2126
  }
2109
2127
  if (valType === "bigint") {
2110
2128
  return send(event, val.toString(), MIMES.json);
@@ -2162,7 +2180,7 @@ function createRouter(opts = {}) {
2162
2180
  addRoute(path, handler, m);
2163
2181
  }
2164
2182
  } else {
2165
- route.handlers[method] = toEventHandler(handler, undefined, path);
2183
+ route.handlers[method] = toEventHandler(handler, void 0, path);
2166
2184
  }
2167
2185
  return router;
2168
2186
  };
@@ -2232,7 +2250,7 @@ function createRouter(opts = {}) {
2232
2250
  const params = match.matched.params || {};
2233
2251
  event.context.params = params;
2234
2252
  return Promise.resolve(match.handler(event)).then((res) => {
2235
- if (res === undefined && isPreemptive) {
2253
+ if (res === void 0 && isPreemptive) {
2236
2254
  return null;
2237
2255
  }
2238
2256
  return res;
@@ -2324,7 +2342,7 @@ function callNodeListener(handler, req, res) {
2324
2342
  res.off("close", next);
2325
2343
  res.off("error", next);
2326
2344
  }
2327
- return err ? reject(createError(err)) : resolve(undefined);
2345
+ return err ? reject(createError(err)) : resolve(void 0);
2328
2346
  };
2329
2347
  try {
2330
2348
  const returned = handler(req, res, next);
@@ -2424,7 +2442,7 @@ function _normalizeUnenvHeaders(input) {
2424
2442
  for (const _value of value) {
2425
2443
  headers.push([key, _value]);
2426
2444
  }
2427
- } else if (value !== undefined) {
2445
+ } else if (value !== void 0) {
2428
2446
  headers.push([key, String(value)]);
2429
2447
  }
2430
2448
  }
package/dist/index.d.cts CHANGED
@@ -331,7 +331,7 @@ declare class H3Error<DataT = unknown> extends Error {
331
331
  constructor(message: string, opts?: {
332
332
  cause?: unknown;
333
333
  });
334
- toJSON(): Pick<H3Error<DataT>, "data" | "statusCode" | "statusMessage" | "message">;
334
+ toJSON(): Pick<H3Error<DataT>, "message" | "statusCode" | "statusMessage" | "data">;
335
335
  }
336
336
  /**
337
337
  * Creates a new `Error` that can be used to handle both internal and runtime errors.
@@ -1392,4 +1392,5 @@ declare function toPlainHandler(app: App): PlainHandler;
1392
1392
  /** @experimental */
1393
1393
  declare function fromPlainHandler(handler: PlainHandler): EventHandler<EventHandlerRequest, Promise<unknown>>;
1394
1394
 
1395
- export { type AddRouteShortcuts, type App, type AppOptions, type AppUse, type CacheConditions, type CreateRouterOptions, type Duplex, type DynamicEventHandler, type Encoding, type EventHandler, type EventHandlerObject, type EventHandlerRequest, type EventHandlerResolver, type EventHandlerResponse, type EventStream, type EventStreamMessage, type EventStreamOptions, type H3CorsOptions, H3Error, H3Event, type H3EventContext, H3Headers, H3Response, type HTTPHeaderName, type HTTPMethod, type InferEventInput, type InputLayer, type InputStack, type Layer, type LazyEventHandler, MIMES, type Matcher, type MimeType, type MultiPartData, type NodeEventContext, type NodeListener, type NodeMiddleware, type NodePromisifiedHandler, type PlainHandler, type PlainRequest, type PlainResponse, type ProxyOptions, type RequestFingerprintOptions, type RequestHeaders, type RouteNode, type Router, type RouterMethod, type RouterUse, type ServeStaticOptions, type Session, type SessionConfig, type SessionData, type Stack, type StaticAssetMeta, type StatusCode, type TypedHeaders, type ValidateFunction, type ValidateResult, type WebEventContext, type WebHandler, type WebSocketOptions, type _RequestMiddleware, type _ResponseMiddleware, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearResponseHeaders, clearSession, createApp, createAppEventHandler, createError, createEvent, createEventStream, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, defineRequestMiddleware, defineResponseMiddleware, defineWebSocket, defineWebSocketHandler, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, fromPlainHandler, fromWebHandler, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestFingerprint, getRequestHeader, getRequestHeaders, getRequestHost, getRequestIP, getRequestPath, getRequestProtocol, getRequestURL, getRequestWebStream, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, getValidatedQuery, getValidatedRouterParams, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, isWebResponse, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readFormData, readMultipartFormData, readRawBody, readValidatedBody, removeResponseHeader, sanitizeStatusCode, sanitizeStatusMessage, sealSession, send, sendError, sendIterable, sendNoContent, sendProxy, sendRedirect, sendStream, sendWebResponse, serveStatic, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, toPlainHandler, toWebHandler, toWebRequest, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
1395
+ export { H3Error, H3Event, H3Headers, H3Response, MIMES, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearResponseHeaders, clearSession, createApp, createAppEventHandler, createError, createEvent, createEventStream, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, defineRequestMiddleware, defineResponseMiddleware, defineWebSocket, defineWebSocketHandler, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, fromPlainHandler, fromWebHandler, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestFingerprint, getRequestHeader, getRequestHeaders, getRequestHost, getRequestIP, getRequestPath, getRequestProtocol, getRequestURL, getRequestWebStream, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, getValidatedQuery, getValidatedRouterParams, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, isWebResponse, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readFormData, readMultipartFormData, readRawBody, readValidatedBody, removeResponseHeader, sanitizeStatusCode, sanitizeStatusMessage, sealSession, send, sendError, sendIterable, sendNoContent, sendProxy, sendRedirect, sendStream, sendWebResponse, serveStatic, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, toPlainHandler, toWebHandler, toWebRequest, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
1396
+ export type { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, Duplex, DynamicEventHandler, Encoding, EventHandler, EventHandlerObject, EventHandlerRequest, EventHandlerResolver, EventHandlerResponse, EventStream, EventStreamMessage, EventStreamOptions, H3CorsOptions, H3EventContext, HTTPHeaderName, HTTPMethod, InferEventInput, InputLayer, InputStack, Layer, LazyEventHandler, Matcher, MimeType, MultiPartData, NodeEventContext, NodeListener, NodeMiddleware, NodePromisifiedHandler, PlainHandler, PlainRequest, PlainResponse, ProxyOptions, RequestFingerprintOptions, RequestHeaders, RouteNode, Router, RouterMethod, RouterUse, ServeStaticOptions, Session, SessionConfig, SessionData, Stack, StaticAssetMeta, StatusCode, TypedHeaders, ValidateFunction, ValidateResult, WebEventContext, WebHandler, WebSocketOptions, _RequestMiddleware, _ResponseMiddleware };
package/dist/index.d.mts CHANGED
@@ -331,7 +331,7 @@ declare class H3Error<DataT = unknown> extends Error {
331
331
  constructor(message: string, opts?: {
332
332
  cause?: unknown;
333
333
  });
334
- toJSON(): Pick<H3Error<DataT>, "data" | "statusCode" | "statusMessage" | "message">;
334
+ toJSON(): Pick<H3Error<DataT>, "message" | "statusCode" | "statusMessage" | "data">;
335
335
  }
336
336
  /**
337
337
  * Creates a new `Error` that can be used to handle both internal and runtime errors.
@@ -1392,4 +1392,5 @@ declare function toPlainHandler(app: App): PlainHandler;
1392
1392
  /** @experimental */
1393
1393
  declare function fromPlainHandler(handler: PlainHandler): EventHandler<EventHandlerRequest, Promise<unknown>>;
1394
1394
 
1395
- export { type AddRouteShortcuts, type App, type AppOptions, type AppUse, type CacheConditions, type CreateRouterOptions, type Duplex, type DynamicEventHandler, type Encoding, type EventHandler, type EventHandlerObject, type EventHandlerRequest, type EventHandlerResolver, type EventHandlerResponse, type EventStream, type EventStreamMessage, type EventStreamOptions, type H3CorsOptions, H3Error, H3Event, type H3EventContext, H3Headers, H3Response, type HTTPHeaderName, type HTTPMethod, type InferEventInput, type InputLayer, type InputStack, type Layer, type LazyEventHandler, MIMES, type Matcher, type MimeType, type MultiPartData, type NodeEventContext, type NodeListener, type NodeMiddleware, type NodePromisifiedHandler, type PlainHandler, type PlainRequest, type PlainResponse, type ProxyOptions, type RequestFingerprintOptions, type RequestHeaders, type RouteNode, type Router, type RouterMethod, type RouterUse, type ServeStaticOptions, type Session, type SessionConfig, type SessionData, type Stack, type StaticAssetMeta, type StatusCode, type TypedHeaders, type ValidateFunction, type ValidateResult, type WebEventContext, type WebHandler, type WebSocketOptions, type _RequestMiddleware, type _ResponseMiddleware, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearResponseHeaders, clearSession, createApp, createAppEventHandler, createError, createEvent, createEventStream, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, defineRequestMiddleware, defineResponseMiddleware, defineWebSocket, defineWebSocketHandler, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, fromPlainHandler, fromWebHandler, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestFingerprint, getRequestHeader, getRequestHeaders, getRequestHost, getRequestIP, getRequestPath, getRequestProtocol, getRequestURL, getRequestWebStream, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, getValidatedQuery, getValidatedRouterParams, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, isWebResponse, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readFormData, readMultipartFormData, readRawBody, readValidatedBody, removeResponseHeader, sanitizeStatusCode, sanitizeStatusMessage, sealSession, send, sendError, sendIterable, sendNoContent, sendProxy, sendRedirect, sendStream, sendWebResponse, serveStatic, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, toPlainHandler, toWebHandler, toWebRequest, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
1395
+ export { H3Error, H3Event, H3Headers, H3Response, MIMES, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearResponseHeaders, clearSession, createApp, createAppEventHandler, createError, createEvent, createEventStream, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, defineRequestMiddleware, defineResponseMiddleware, defineWebSocket, defineWebSocketHandler, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, fromPlainHandler, fromWebHandler, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestFingerprint, getRequestHeader, getRequestHeaders, getRequestHost, getRequestIP, getRequestPath, getRequestProtocol, getRequestURL, getRequestWebStream, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, getValidatedQuery, getValidatedRouterParams, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, isWebResponse, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readFormData, readMultipartFormData, readRawBody, readValidatedBody, removeResponseHeader, sanitizeStatusCode, sanitizeStatusMessage, sealSession, send, sendError, sendIterable, sendNoContent, sendProxy, sendRedirect, sendStream, sendWebResponse, serveStatic, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, toPlainHandler, toWebHandler, toWebRequest, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
1396
+ export type { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, Duplex, DynamicEventHandler, Encoding, EventHandler, EventHandlerObject, EventHandlerRequest, EventHandlerResolver, EventHandlerResponse, EventStream, EventStreamMessage, EventStreamOptions, H3CorsOptions, H3EventContext, HTTPHeaderName, HTTPMethod, InferEventInput, InputLayer, InputStack, Layer, LazyEventHandler, Matcher, MimeType, MultiPartData, NodeEventContext, NodeListener, NodeMiddleware, NodePromisifiedHandler, PlainHandler, PlainRequest, PlainResponse, ProxyOptions, RequestFingerprintOptions, RequestHeaders, RouteNode, Router, RouterMethod, RouterUse, ServeStaticOptions, Session, SessionConfig, SessionData, Stack, StaticAssetMeta, StatusCode, TypedHeaders, ValidateFunction, ValidateResult, WebEventContext, WebHandler, WebSocketOptions, _RequestMiddleware, _ResponseMiddleware };
package/dist/index.d.ts CHANGED
@@ -331,7 +331,7 @@ declare class H3Error<DataT = unknown> extends Error {
331
331
  constructor(message: string, opts?: {
332
332
  cause?: unknown;
333
333
  });
334
- toJSON(): Pick<H3Error<DataT>, "data" | "statusCode" | "statusMessage" | "message">;
334
+ toJSON(): Pick<H3Error<DataT>, "message" | "statusCode" | "statusMessage" | "data">;
335
335
  }
336
336
  /**
337
337
  * Creates a new `Error` that can be used to handle both internal and runtime errors.
@@ -1392,4 +1392,5 @@ declare function toPlainHandler(app: App): PlainHandler;
1392
1392
  /** @experimental */
1393
1393
  declare function fromPlainHandler(handler: PlainHandler): EventHandler<EventHandlerRequest, Promise<unknown>>;
1394
1394
 
1395
- export { type AddRouteShortcuts, type App, type AppOptions, type AppUse, type CacheConditions, type CreateRouterOptions, type Duplex, type DynamicEventHandler, type Encoding, type EventHandler, type EventHandlerObject, type EventHandlerRequest, type EventHandlerResolver, type EventHandlerResponse, type EventStream, type EventStreamMessage, type EventStreamOptions, type H3CorsOptions, H3Error, H3Event, type H3EventContext, H3Headers, H3Response, type HTTPHeaderName, type HTTPMethod, type InferEventInput, type InputLayer, type InputStack, type Layer, type LazyEventHandler, MIMES, type Matcher, type MimeType, type MultiPartData, type NodeEventContext, type NodeListener, type NodeMiddleware, type NodePromisifiedHandler, type PlainHandler, type PlainRequest, type PlainResponse, type ProxyOptions, type RequestFingerprintOptions, type RequestHeaders, type RouteNode, type Router, type RouterMethod, type RouterUse, type ServeStaticOptions, type Session, type SessionConfig, type SessionData, type Stack, type StaticAssetMeta, type StatusCode, type TypedHeaders, type ValidateFunction, type ValidateResult, type WebEventContext, type WebHandler, type WebSocketOptions, type _RequestMiddleware, type _ResponseMiddleware, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearResponseHeaders, clearSession, createApp, createAppEventHandler, createError, createEvent, createEventStream, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, defineRequestMiddleware, defineResponseMiddleware, defineWebSocket, defineWebSocketHandler, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, fromPlainHandler, fromWebHandler, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestFingerprint, getRequestHeader, getRequestHeaders, getRequestHost, getRequestIP, getRequestPath, getRequestProtocol, getRequestURL, getRequestWebStream, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, getValidatedQuery, getValidatedRouterParams, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, isWebResponse, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readFormData, readMultipartFormData, readRawBody, readValidatedBody, removeResponseHeader, sanitizeStatusCode, sanitizeStatusMessage, sealSession, send, sendError, sendIterable, sendNoContent, sendProxy, sendRedirect, sendStream, sendWebResponse, serveStatic, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, toPlainHandler, toWebHandler, toWebRequest, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
1395
+ export { H3Error, H3Event, H3Headers, H3Response, MIMES, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearResponseHeaders, clearSession, createApp, createAppEventHandler, createError, createEvent, createEventStream, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, defineRequestMiddleware, defineResponseMiddleware, defineWebSocket, defineWebSocketHandler, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, fromPlainHandler, fromWebHandler, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestFingerprint, getRequestHeader, getRequestHeaders, getRequestHost, getRequestIP, getRequestPath, getRequestProtocol, getRequestURL, getRequestWebStream, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, getValidatedQuery, getValidatedRouterParams, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, isWebResponse, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readFormData, readMultipartFormData, readRawBody, readValidatedBody, removeResponseHeader, sanitizeStatusCode, sanitizeStatusMessage, sealSession, send, sendError, sendIterable, sendNoContent, sendProxy, sendRedirect, sendStream, sendWebResponse, serveStatic, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, toPlainHandler, toWebHandler, toWebRequest, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
1396
+ export type { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, Duplex, DynamicEventHandler, Encoding, EventHandler, EventHandlerObject, EventHandlerRequest, EventHandlerResolver, EventHandlerResponse, EventStream, EventStreamMessage, EventStreamOptions, H3CorsOptions, H3EventContext, HTTPHeaderName, HTTPMethod, InferEventInput, InputLayer, InputStack, Layer, LazyEventHandler, Matcher, MimeType, MultiPartData, NodeEventContext, NodeListener, NodeMiddleware, NodePromisifiedHandler, PlainHandler, PlainRequest, PlainResponse, ProxyOptions, RequestFingerprintOptions, RequestHeaders, RouteNode, Router, RouterMethod, RouterUse, ServeStaticOptions, Session, SessionConfig, SessionData, Stack, StaticAssetMeta, StatusCode, TypedHeaders, ValidateFunction, ValidateResult, WebEventContext, WebHandler, WebSocketOptions, _RequestMiddleware, _ResponseMiddleware };
package/dist/index.mjs CHANGED
@@ -1,6 +1,5 @@
1
1
  import { withoutTrailingSlash, withoutBase, getQuery as getQuery$1, decode, decodePath, withLeadingSlash, parseURL, joinURL } from 'ufo';
2
- import { parse as parse$1, serialize } from 'cookie-es';
3
- import { objectHash } from 'ohash';
2
+ import { parse as parse$1, serialize, parseSetCookie } from 'cookie-es';
4
3
  import { createRouter as createRouter$1, toRouteMatcher } from 'radix3';
5
4
  import destr from 'destr';
6
5
  import { defu } from 'defu';
@@ -56,7 +55,7 @@ class H3Error extends Error {
56
55
  if (this.statusMessage) {
57
56
  obj.statusMessage = sanitizeStatusMessage(this.statusMessage);
58
57
  }
59
- if (this.data !== undefined) {
58
+ if (this.data !== void 0) {
60
59
  obj.data = this.data;
61
60
  }
62
61
  return obj;
@@ -108,10 +107,10 @@ function createError(input) {
108
107
  );
109
108
  }
110
109
  }
111
- if (input.fatal !== undefined) {
110
+ if (input.fatal !== void 0) {
112
111
  err.fatal = input.fatal;
113
112
  }
114
- if (input.unhandled !== undefined) {
113
+ if (input.unhandled !== void 0) {
115
114
  err.unhandled = input.unhandled;
116
115
  }
117
116
  return err;
@@ -136,7 +135,7 @@ function sendError(event, error, debug) {
136
135
  const _code = Number.parseInt(h3Error.statusCode);
137
136
  setResponseStatus(event, _code, h3Error.statusMessage);
138
137
  event.node.res.setHeader("content-type", MIMES.json);
139
- event.node.res.end(JSON.stringify(responseBody, undefined, 2));
138
+ event.node.res.end(JSON.stringify(responseBody, void 0, 2));
140
139
  }
141
140
  function isError(input) {
142
141
  return input?.constructor?.__h3_error__ === true;
@@ -404,12 +403,15 @@ function readRawBody(event, encoding = "utf8") {
404
403
  if (_resolved instanceof URLSearchParams) {
405
404
  return Buffer.from(_resolved.toString());
406
405
  }
406
+ if (_resolved instanceof FormData) {
407
+ return new Response(_resolved).bytes().then((uint8arr) => Buffer.from(uint8arr));
408
+ }
407
409
  return Buffer.from(_resolved);
408
410
  });
409
411
  return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
410
412
  }
411
413
  if (!Number.parseInt(event.node.req.headers["content-length"] || "") && !String(event.node.req.headers["transfer-encoding"] ?? "").split(",").map((e) => e.trim()).filter(Boolean).includes("chunked")) {
412
- return Promise.resolve(undefined);
414
+ return Promise.resolve(void 0);
413
415
  }
414
416
  const promise = event.node.req[RawBodySymbol] = new Promise(
415
417
  (resolve, reject) => {
@@ -504,7 +506,7 @@ function getRequestWebStream(event) {
504
506
  }
505
507
  function _parseJSON(body = "", strict) {
506
508
  if (!body) {
507
- return undefined;
509
+ return void 0;
508
510
  }
509
511
  try {
510
512
  return destr(body, { strict });
@@ -535,14 +537,14 @@ function _parseURLEncodedBody(body) {
535
537
  function handleCacheHeaders(event, opts) {
536
538
  const cacheControls = ["public", ...opts.cacheControls || []];
537
539
  let cacheMatched = false;
538
- if (opts.maxAge !== undefined) {
540
+ if (opts.maxAge !== void 0) {
539
541
  cacheControls.push(`max-age=${+opts.maxAge}`, `s-maxage=${+opts.maxAge}`);
540
542
  }
541
543
  if (opts.modifiedTime) {
542
544
  const modifiedTime = new Date(opts.modifiedTime);
543
545
  const ifModifiedSince = event.node.req.headers["if-modified-since"];
544
546
  event.node.res.setHeader("last-modified", modifiedTime.toUTCString());
545
- if (ifModifiedSince && new Date(ifModifiedSince) >= opts.modifiedTime) {
547
+ if (ifModifiedSince && new Date(ifModifiedSince) >= modifiedTime) {
546
548
  cacheMatched = true;
547
549
  }
548
550
  }
@@ -586,24 +588,39 @@ function sanitizeStatusCode(statusCode, defaultStatusCode = 200) {
586
588
  return statusCode;
587
589
  }
588
590
 
591
+ function getDistinctCookieKey(name, opts) {
592
+ return [name, opts.domain || "", opts.path || "/"].join(";");
593
+ }
594
+
589
595
  function parseCookies(event) {
590
596
  return parse$1(event.node.req.headers.cookie || "");
591
597
  }
592
598
  function getCookie(event, name) {
593
599
  return parseCookies(event)[name];
594
600
  }
595
- function setCookie(event, name, value, serializeOptions) {
596
- serializeOptions = { path: "/", ...serializeOptions };
597
- const cookieStr = serialize(name, value, serializeOptions);
598
- let setCookies = event.node.res.getHeader("set-cookie");
599
- if (!Array.isArray(setCookies)) {
600
- setCookies = [setCookies];
601
+ function setCookie(event, name, value, serializeOptions = {}) {
602
+ if (!serializeOptions.path) {
603
+ serializeOptions = { path: "/", ...serializeOptions };
601
604
  }
602
- const _optionsHash = objectHash(serializeOptions);
603
- setCookies = setCookies.filter((cookieValue) => {
604
- return cookieValue && _optionsHash !== objectHash(parse$1(cookieValue));
605
- });
606
- event.node.res.setHeader("set-cookie", [...setCookies, cookieStr]);
605
+ const newCookie = serialize(name, value, serializeOptions);
606
+ const currentCookies = splitCookiesString(
607
+ event.node.res.getHeader("set-cookie")
608
+ );
609
+ if (currentCookies.length === 0) {
610
+ event.node.res.setHeader("set-cookie", newCookie);
611
+ return;
612
+ }
613
+ const newCookieKey = getDistinctCookieKey(name, serializeOptions);
614
+ event.node.res.removeHeader("set-cookie");
615
+ for (const cookie of currentCookies) {
616
+ const parsed = parseSetCookie(cookie);
617
+ const key = getDistinctCookieKey(parsed.name, parsed);
618
+ if (key === newCookieKey) {
619
+ continue;
620
+ }
621
+ event.node.res.appendHeader("set-cookie", cookie);
622
+ }
623
+ event.node.res.appendHeader("set-cookie", newCookie);
607
624
  }
608
625
  function deleteCookie(event, name, serializeOptions) {
609
626
  setCookie(event, name, "", {
@@ -680,7 +697,7 @@ function serializeIterableValue(value) {
680
697
  }
681
698
  case "function":
682
699
  case "undefined": {
683
- return undefined;
700
+ return void 0;
684
701
  }
685
702
  case "object": {
686
703
  if (value instanceof Uint8Array) {
@@ -953,9 +970,9 @@ function sendIterable(event, iterable, options) {
953
970
  new ReadableStream({
954
971
  async pull(controller) {
955
972
  const { value, done } = await iterator.next();
956
- if (value !== undefined) {
973
+ if (value !== void 0) {
957
974
  const chunk = serializer(value);
958
- if (chunk !== undefined) {
975
+ if (chunk !== void 0) {
959
976
  controller.enqueue(chunk);
960
977
  }
961
978
  }
@@ -1133,7 +1150,7 @@ async function proxyRequest(event, target, opts = {}) {
1133
1150
  body = getRequestWebStream(event);
1134
1151
  duplex = "half";
1135
1152
  } else {
1136
- body = await readRawBody(event, false).catch(() => undefined);
1153
+ body = await readRawBody(event, false).catch(() => void 0);
1137
1154
  }
1138
1155
  }
1139
1156
  const method = opts.fetchOptions?.method || event.method;
@@ -1213,7 +1230,7 @@ async function sendProxy(event, target, opts = {}) {
1213
1230
  if (opts.onResponse) {
1214
1231
  await opts.onResponse(event, response);
1215
1232
  }
1216
- if (response._data !== undefined) {
1233
+ if (response._data !== void 0) {
1217
1234
  return response._data;
1218
1235
  }
1219
1236
  if (event.handled) {
@@ -1287,8 +1304,9 @@ function mergeHeaders(defaults, ...inputs) {
1287
1304
  }
1288
1305
  const merged = new Headers(defaults);
1289
1306
  for (const input of _inputs) {
1290
- for (const [key, value] of Object.entries(input)) {
1291
- if (value !== undefined) {
1307
+ const entries = Array.isArray(input) ? input : typeof input.entries === "function" ? input.entries() : Object.entries(input);
1308
+ for (const [key, value] of entries) {
1309
+ if (value !== void 0) {
1292
1310
  merged.set(key, value);
1293
1311
  }
1294
1312
  }
@@ -1405,7 +1423,7 @@ async function updateSession(event, config, update) {
1405
1423
  const sealed = await sealSession(event, config);
1406
1424
  setCookie(event, sessionName, sealed, {
1407
1425
  ...DEFAULT_COOKIE,
1408
- expires: config.maxAge ? new Date(session.createdAt + config.maxAge * 1e3) : undefined,
1426
+ expires: config.maxAge ? new Date(session.createdAt + config.maxAge * 1e3) : void 0,
1409
1427
  ...config.cookie
1410
1428
  });
1411
1429
  }
@@ -1491,7 +1509,7 @@ function setEventStreamHeaders(event) {
1491
1509
  setResponseHeaders(event, headers);
1492
1510
  }
1493
1511
  function isHttp2Request(event) {
1494
- return getHeader(event, ":path") !== undefined && getHeader(event, ":method") !== undefined;
1512
+ return getHeader(event, ":path") !== void 0 && getHeader(event, ":method") !== void 0;
1495
1513
  }
1496
1514
 
1497
1515
  class EventStream {
@@ -1581,7 +1599,7 @@ class EventStream {
1581
1599
  }
1582
1600
  if (this._unsentData?.length) {
1583
1601
  await this._writer.write(this._encoder.encode(this._unsentData));
1584
- this._unsentData = undefined;
1602
+ this._unsentData = void 0;
1585
1603
  }
1586
1604
  }
1587
1605
  /**
@@ -1691,7 +1709,7 @@ async function serveStatic(event, options) {
1691
1709
  if (meta.encoding && !getResponseHeader(event, "content-encoding")) {
1692
1710
  setResponseHeader(event, "content-encoding", meta.encoding);
1693
1711
  }
1694
- if (meta.size !== undefined && meta.size > 0 && !getResponseHeader(event, "content-length")) {
1712
+ if (meta.size !== void 0 && meta.size > 0 && !getResponseHeader(event, "content-length")) {
1695
1713
  setResponseHeader(event, "content-length", meta.size);
1696
1714
  }
1697
1715
  if (event.method === "HEAD") {
@@ -1833,7 +1851,7 @@ function defineEventHandler(handler) {
1833
1851
  return _handler;
1834
1852
  }
1835
1853
  function _normalizeArray(input) {
1836
- return input ? Array.isArray(input) ? input : [input] : undefined;
1854
+ return input ? Array.isArray(input) ? input : [input] : void 0;
1837
1855
  }
1838
1856
  async function _callHandler(event, handler, hooks) {
1839
1857
  if (hooks.onRequest) {
@@ -1963,7 +1981,7 @@ function use(app, arg1, arg2, arg3) {
1963
1981
  return app;
1964
1982
  }
1965
1983
  function createAppEventHandler(stack, options) {
1966
- const spacing = options.debug ? 2 : undefined;
1984
+ const spacing = options.debug ? 2 : void 0;
1967
1985
  return eventHandler(async (event) => {
1968
1986
  event.node.req.originalUrl = event.node.req.originalUrl || event.node.req.url || "/";
1969
1987
  const _reqPath = event._path || event.node.req.url || "/";
@@ -1986,8 +2004,8 @@ function createAppEventHandler(stack, options) {
1986
2004
  event._path = _layerPath;
1987
2005
  event.node.req.url = _layerPath;
1988
2006
  const val = await layer.handler(event);
1989
- const _body = val === undefined ? undefined : await val;
1990
- if (_body !== undefined) {
2007
+ const _body = val === void 0 ? void 0 : await val;
2008
+ if (_body !== void 0) {
1991
2009
  const _response = { body: _body };
1992
2010
  if (options.onBeforeResponse) {
1993
2011
  event._onBeforeResponseCalled = true;
@@ -2003,7 +2021,7 @@ function createAppEventHandler(stack, options) {
2003
2021
  if (event.handled) {
2004
2022
  if (options.onAfterResponse) {
2005
2023
  event._onAfterResponseCalled = true;
2006
- await options.onAfterResponse(event, undefined);
2024
+ await options.onAfterResponse(event, void 0);
2007
2025
  }
2008
2026
  return;
2009
2027
  }
@@ -2016,7 +2034,7 @@ function createAppEventHandler(stack, options) {
2016
2034
  }
2017
2035
  if (options.onAfterResponse) {
2018
2036
  event._onAfterResponseCalled = true;
2019
- await options.onAfterResponse(event, undefined);
2037
+ await options.onAfterResponse(event, void 0);
2020
2038
  }
2021
2039
  });
2022
2040
  }
@@ -2031,7 +2049,7 @@ function createResolver(stack) {
2031
2049
  continue;
2032
2050
  }
2033
2051
  _layerPath = path.slice(layer.route.length) || "/";
2034
- if (layer.match && !layer.match(_layerPath, undefined)) {
2052
+ if (layer.match && !layer.match(_layerPath, void 0)) {
2035
2053
  continue;
2036
2054
  }
2037
2055
  let res = { route: layer.route, handler: layer.handler };
@@ -2058,7 +2076,7 @@ function normalizeLayer(input) {
2058
2076
  if (input.lazy) {
2059
2077
  handler = lazyEventHandler(handler);
2060
2078
  } else if (!isEventHandler(handler)) {
2061
- handler = toEventHandler(handler, undefined, input.route);
2079
+ handler = toEventHandler(handler, void 0, input.route);
2062
2080
  }
2063
2081
  return {
2064
2082
  route: withoutTrailingSlash(input.route),
@@ -2097,7 +2115,7 @@ function handleHandlerResponse(event, val, jsonSpace) {
2097
2115
  return send(event, val, MIMES.html);
2098
2116
  }
2099
2117
  if (valType === "object" || valType === "boolean" || valType === "number") {
2100
- return send(event, JSON.stringify(val, undefined, jsonSpace), MIMES.json);
2118
+ return send(event, JSON.stringify(val, void 0, jsonSpace), MIMES.json);
2101
2119
  }
2102
2120
  if (valType === "bigint") {
2103
2121
  return send(event, val.toString(), MIMES.json);
@@ -2155,7 +2173,7 @@ function createRouter(opts = {}) {
2155
2173
  addRoute(path, handler, m);
2156
2174
  }
2157
2175
  } else {
2158
- route.handlers[method] = toEventHandler(handler, undefined, path);
2176
+ route.handlers[method] = toEventHandler(handler, void 0, path);
2159
2177
  }
2160
2178
  return router;
2161
2179
  };
@@ -2225,7 +2243,7 @@ function createRouter(opts = {}) {
2225
2243
  const params = match.matched.params || {};
2226
2244
  event.context.params = params;
2227
2245
  return Promise.resolve(match.handler(event)).then((res) => {
2228
- if (res === undefined && isPreemptive) {
2246
+ if (res === void 0 && isPreemptive) {
2229
2247
  return null;
2230
2248
  }
2231
2249
  return res;
@@ -2317,7 +2335,7 @@ function callNodeListener(handler, req, res) {
2317
2335
  res.off("close", next);
2318
2336
  res.off("error", next);
2319
2337
  }
2320
- return err ? reject(createError(err)) : resolve(undefined);
2338
+ return err ? reject(createError(err)) : resolve(void 0);
2321
2339
  };
2322
2340
  try {
2323
2341
  const returned = handler(req, res, next);
@@ -2417,7 +2435,7 @@ function _normalizeUnenvHeaders(input) {
2417
2435
  for (const _value of value) {
2418
2436
  headers.push([key, _value]);
2419
2437
  }
2420
- } else if (value !== undefined) {
2438
+ } else if (value !== void 0) {
2421
2439
  headers.push([key, String(value)]);
2422
2440
  }
2423
2441
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "h3",
3
- "version": "1.15.0",
3
+ "version": "1.15.2",
4
4
  "description": "Minimal H(TTP) framework built for high performance and portability.",
5
5
  "repository": "unjs/h3",
6
6
  "license": "MIT",
@@ -34,43 +34,42 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "cookie-es": "^1.2.2",
37
- "crossws": "^0.3.3",
37
+ "crossws": "^0.3.4",
38
38
  "defu": "^6.1.4",
39
- "destr": "^2.0.3",
39
+ "destr": "^2.0.5",
40
40
  "iron-webcrypto": "^1.2.1",
41
41
  "node-mock-http": "^1.0.0",
42
- "ohash": "^1.1.4",
43
42
  "radix3": "^1.1.2",
44
- "ufo": "^1.5.4",
43
+ "ufo": "^1.6.1",
45
44
  "uncrypto": "^0.1.3"
46
45
  },
47
46
  "devDependencies": {
48
47
  "0x": "^5.8.0",
49
- "@types/express": "^5.0.0",
50
- "@types/node": "^22.13.1",
51
- "@types/supertest": "^6.0.2",
52
- "@vitest/coverage-v8": "^3.0.5",
48
+ "@types/express": "^5.0.1",
49
+ "@types/node": "^22.15.2",
50
+ "@types/supertest": "^6.0.3",
51
+ "@vitest/coverage-v8": "^3.1.2",
53
52
  "autocannon": "^8.0.0",
54
- "automd": "^0.3.12",
55
- "changelogen": "^0.5.7",
53
+ "automd": "^0.4.0",
54
+ "changelogen": "^0.6.1",
56
55
  "connect": "^3.7.0",
57
- "eslint": "^9.19.0",
56
+ "eslint": "^9.25.1",
58
57
  "eslint-config-unjs": "^0.4.2",
59
- "express": "^4.21.2",
58
+ "express": "^5.1.0",
60
59
  "get-port": "^7.1.0",
61
- "h3": "^1.14.0",
60
+ "h3": "^1.15.1",
62
61
  "jiti": "^2.4.2",
63
62
  "listhen": "^1.9.0",
64
63
  "node-fetch-native": "^1.6.6",
65
- "prettier": "^3.4.2",
66
- "react": "^19.0.0",
67
- "react-dom": "^19.0.0",
68
- "supertest": "^7.0.0",
69
- "typescript": "^5.7.3",
70
- "unbuild": "^3.3.1",
71
- "undici": "^7.3.0",
72
- "vitest": "^3.0.5",
73
- "zod": "^3.24.1"
64
+ "prettier": "^3.5.3",
65
+ "react": "^19.1.0",
66
+ "react-dom": "^19.1.0",
67
+ "supertest": "^7.1.0",
68
+ "typescript": "^5.8.3",
69
+ "unbuild": "^3.5.0",
70
+ "undici": "^7.8.0",
71
+ "vitest": "^3.1.2",
72
+ "zod": "^3.24.3"
74
73
  },
75
74
  "packageManager": "pnpm@10.2.0"
76
75
  }