h3 1.13.0 → 1.13.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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  <!-- automd:badges -->
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/h3)](https://npmjs.com/package/h3)
6
- [![npm downloads](https://img.shields.io/npm/dm/h3)](https://npmjs.com/package/h3)
6
+ [![npm downloads](https://img.shields.io/npm/dm/h3)](https://npm.chart.dev/h3)
7
7
 
8
8
  <!-- /automd -->
9
9
 
package/dist/index.cjs CHANGED
@@ -41,21 +41,16 @@ function hasProp(obj, prop) {
41
41
  }
42
42
  }
43
43
 
44
- var __defProp$2 = Object.defineProperty;
45
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
46
- var __publicField$2 = (obj, key, value) => {
47
- __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
48
- return value;
49
- };
50
44
  class H3Error extends Error {
45
+ static __h3_error__ = true;
46
+ statusCode = 500;
47
+ fatal = false;
48
+ unhandled = false;
49
+ statusMessage;
50
+ data;
51
+ cause;
51
52
  constructor(message, opts = {}) {
52
53
  super(message, opts);
53
- __publicField$2(this, "statusCode", 500);
54
- __publicField$2(this, "fatal", false);
55
- __publicField$2(this, "unhandled", false);
56
- __publicField$2(this, "statusMessage");
57
- __publicField$2(this, "data");
58
- __publicField$2(this, "cause");
59
54
  if (opts.cause && !this.cause) {
60
55
  this.cause = opts.cause;
61
56
  }
@@ -74,7 +69,6 @@ class H3Error extends Error {
74
69
  return obj;
75
70
  }
76
71
  }
77
- __publicField$2(H3Error, "__h3_error__", true);
78
72
  function createError(input) {
79
73
  if (typeof input === "string") {
80
74
  return new H3Error(input);
@@ -1130,6 +1124,7 @@ async function getRequestFingerprint(event, opts = {}) {
1130
1124
  const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
1131
1125
  const ignoredHeaders = /* @__PURE__ */ new Set([
1132
1126
  "transfer-encoding",
1127
+ "accept-encoding",
1133
1128
  "connection",
1134
1129
  "keep-alive",
1135
1130
  "upgrade",
@@ -1150,7 +1145,7 @@ async function proxyRequest(event, target, opts = {}) {
1150
1145
  }
1151
1146
  const method = opts.fetchOptions?.method || event.method;
1152
1147
  const fetchHeaders = mergeHeaders(
1153
- getProxyRequestHeaders(event),
1148
+ getProxyRequestHeaders(event, { host: target.startsWith("/") }),
1154
1149
  opts.fetchOptions?.headers,
1155
1150
  opts.headers
1156
1151
  );
@@ -1242,11 +1237,11 @@ async function sendProxy(event, target, opts = {}) {
1242
1237
  }
1243
1238
  return event.node.res.end();
1244
1239
  }
1245
- function getProxyRequestHeaders(event) {
1240
+ function getProxyRequestHeaders(event, opts) {
1246
1241
  const headers = /* @__PURE__ */ Object.create(null);
1247
1242
  const reqHeaders = getRequestHeaders(event);
1248
1243
  for (const name in reqHeaders) {
1249
- if (!ignoredHeaders.has(name)) {
1244
+ if (!ignoredHeaders.has(name) || name === "host" && opts?.host) {
1250
1245
  headers[name] = reqHeaders[name];
1251
1246
  }
1252
1247
  }
@@ -1257,7 +1252,9 @@ function fetchWithEvent(event, req, init, options) {
1257
1252
  ...init,
1258
1253
  context: init?.context || event.context,
1259
1254
  headers: {
1260
- ...getProxyRequestHeaders(event),
1255
+ ...getProxyRequestHeaders(event, {
1256
+ host: typeof req === "string" && req.startsWith("/")
1257
+ }),
1261
1258
  ...init?.headers
1262
1259
  }
1263
1260
  });
@@ -1479,23 +1476,17 @@ function isHttp2Request(event) {
1479
1476
  return getHeader(event, ":path") !== void 0 && getHeader(event, ":method") !== void 0;
1480
1477
  }
1481
1478
 
1482
- var __defProp$1 = Object.defineProperty;
1483
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1484
- var __publicField$1 = (obj, key, value) => {
1485
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
1486
- return value;
1487
- };
1488
1479
  class EventStream {
1480
+ _h3Event;
1481
+ _transformStream = new TransformStream();
1482
+ _writer;
1483
+ _encoder = new TextEncoder();
1484
+ _writerIsClosed = false;
1485
+ _paused = false;
1486
+ _unsentData;
1487
+ _disposed = false;
1488
+ _handled = false;
1489
1489
  constructor(event, opts = {}) {
1490
- __publicField$1(this, "_h3Event");
1491
- __publicField$1(this, "_transformStream", new TransformStream());
1492
- __publicField$1(this, "_writer");
1493
- __publicField$1(this, "_encoder", new TextEncoder());
1494
- __publicField$1(this, "_writerIsClosed", false);
1495
- __publicField$1(this, "_paused", false);
1496
- __publicField$1(this, "_unsentData");
1497
- __publicField$1(this, "_disposed", false);
1498
- __publicField$1(this, "_handled", false);
1499
1490
  this._h3Event = event;
1500
1491
  this._writer = this._transformStream.writable.getWriter();
1501
1492
  this._writer.closed.then(() => {
@@ -1722,32 +1713,26 @@ function defineWebSocketHandler(hooks) {
1722
1713
  });
1723
1714
  }
1724
1715
 
1725
- var __defProp = Object.defineProperty;
1726
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1727
- var __publicField = (obj, key, value) => {
1728
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1729
- return value;
1730
- };
1731
1716
  class H3Event {
1717
+ "__is_event__" = true;
1718
+ // Context
1719
+ node;
1720
+ // Node
1721
+ web;
1722
+ // Web
1723
+ context = {};
1724
+ // Shared
1725
+ // Request
1726
+ _method;
1727
+ _path;
1728
+ _headers;
1729
+ _requestBody;
1730
+ // Response
1731
+ _handled = false;
1732
+ // Hooks
1733
+ _onBeforeResponseCalled;
1734
+ _onAfterResponseCalled;
1732
1735
  constructor(req, res) {
1733
- __publicField(this, "__is_event__", true);
1734
- // Context
1735
- __publicField(this, "node");
1736
- // Node
1737
- __publicField(this, "web");
1738
- // Web
1739
- __publicField(this, "context", {});
1740
- // Shared
1741
- // Request
1742
- __publicField(this, "_method");
1743
- __publicField(this, "_path");
1744
- __publicField(this, "_headers");
1745
- __publicField(this, "_requestBody");
1746
- // Response
1747
- __publicField(this, "_handled", false);
1748
- // Hooks
1749
- __publicField(this, "_onBeforeResponseCalled");
1750
- __publicField(this, "_onAfterResponseCalled");
1751
1736
  this.node = { req, res };
1752
1737
  }
1753
1738
  // --- Request ---
package/dist/index.d.cts CHANGED
@@ -135,13 +135,12 @@ interface SessionConfig {
135
135
  }
136
136
  /**
137
137
  * Create a session manager for the current request.
138
- *
139
138
  */
140
139
  declare function useSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig): Promise<{
141
140
  readonly id: string | undefined;
142
141
  readonly data: T;
143
- update: (update: SessionUpdate<T>) => Promise<any>;
144
- clear: () => Promise<any>;
142
+ update: (update: SessionUpdate<T>) => Promise</*elided*/ any>;
143
+ clear: () => Promise</*elided*/ any>;
145
144
  }>;
146
145
  /**
147
146
  * Get the session for the current request.
@@ -513,7 +512,7 @@ declare function readBody<T, Event extends H3Event = H3Event, _T = InferEventInp
513
512
  */
514
513
  declare function readValidatedBody<T, Event extends H3Event = H3Event, _T = InferEventInput<"body", Event, T>>(event: Event, validate: ValidateFunction<_T>): Promise<_T>;
515
514
  /**
516
- * Tries to read and parse the body of a an H3Event as multipart form.
515
+ * Tries to read and parse the body of an H3Event as multipart form.
517
516
  *
518
517
  * @example
519
518
  * export default defineEventHandler(async (event) => {
@@ -615,7 +614,7 @@ interface H3CorsOptions {
615
614
  declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
616
615
 
617
616
  /**
618
- * Get query the params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
617
+ * Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
619
618
  *
620
619
  * @example
621
620
  * export default defineEventHandler((event) => {
@@ -624,7 +623,7 @@ declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
624
623
  */
625
624
  declare function getQuery<T, Event extends H3Event = H3Event, _T = Exclude<InferEventInput<"query", Event, T>, undefined>>(event: Event): _T;
626
625
  /**
627
- * Get the query param from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
626
+ * Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
628
627
  *
629
628
  * You can use a simple function to validate the query object or a library like `zod` to define a schema.
630
629
  *
@@ -796,7 +795,7 @@ declare function getRequestProtocol(event: H3Event, opts?: {
796
795
  /** @deprecated Use `event.path` instead */
797
796
  declare function getRequestPath(event: H3Event): string;
798
797
  /**
799
- * Generated the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
798
+ * Generate the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
800
799
  *
801
800
  * If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
802
801
  *
@@ -820,7 +819,9 @@ declare function toWebRequest(event: H3Event): Request;
820
819
  /**
821
820
  * Try to get the client IP address from the incoming request.
822
821
  *
823
- * If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header if it exists.
822
+ * If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header set by proxies if it exists.
823
+ *
824
+ * Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
824
825
  *
825
826
  * If IP cannot be determined, it will default to `undefined`.
826
827
  *
@@ -830,11 +831,6 @@ declare function toWebRequest(event: H3Event): Request;
830
831
  * });
831
832
  */
832
833
  declare function getRequestIP(event: H3Event, opts?: {
833
- /**
834
- * Use the X-Forwarded-For HTTP header set by proxies.
835
- *
836
- * Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
837
- */
838
834
  xForwardedFor?: boolean;
839
835
  }): string | undefined;
840
836
 
@@ -856,7 +852,7 @@ declare function appendCorsPreflightHeaders(event: H3Event, options: H3CorsOptio
856
852
  declare function appendCorsHeaders(event: H3Event, options: H3CorsOptions): void;
857
853
 
858
854
  /**
859
- * Parse the request to get HTTP Cookie header string and returning an object of all cookie name-value pairs.
855
+ * Parse the request to get HTTP Cookie header string and return an object of all cookie name-value pairs.
860
856
  * @param event {H3Event} H3 event or req passed by h3 handler
861
857
  * @returns Object of cookie name-value pairs
862
858
  * ```ts
@@ -957,7 +953,9 @@ declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions):
957
953
  /**
958
954
  * Get the request headers object without headers known to cause issues when proxying.
959
955
  */
960
- declare function getProxyRequestHeaders(event: H3Event): any;
956
+ declare function getProxyRequestHeaders(event: H3Event, opts?: {
957
+ host?: boolean;
958
+ }): any;
961
959
  /**
962
960
  * Make a fetch request with the event's context and headers.
963
961
  */
@@ -979,7 +977,7 @@ type IteratorSerializer<Value> = (value: Value) => SendableValue | undefined;
979
977
  */
980
978
  declare function send(event: H3Event, data?: any, type?: MimeType): Promise<void>;
981
979
  /**
982
- * Respond with an empty payload.<br>
980
+ * Respond with an empty payload.
983
981
  *
984
982
  * Note that calling this function will close the connection and no other data can be sent to the client afterwards.
985
983
  *
@@ -1059,7 +1057,7 @@ declare function sendRedirect(event: H3Event, location: string, code?: StatusCod
1059
1057
  */
1060
1058
  declare function getResponseHeaders(event: H3Event): ReturnType<H3Event["node"]["res"]["getHeaders"]>;
1061
1059
  /**
1062
- * Alias for `getResponseHeaders`.
1060
+ * Get a response header by name.
1063
1061
  *
1064
1062
  * @example
1065
1063
  * export default defineEventHandler((event) => {
@@ -1147,7 +1145,7 @@ declare function clearResponseHeaders(event: H3Event, headerNames?: HTTPHeaderNa
1147
1145
  */
1148
1146
  declare function removeResponseHeader(event: H3Event, name: HTTPHeaderName): void;
1149
1147
  /**
1150
- * Checks if the data is a stream. (Node.js Readable Stream, React Pipeable Stream, or Web Stream)
1148
+ * Checks if the data is a stream (Node.js Readable Stream, React Pipeable Stream, or Web Stream).
1151
1149
  */
1152
1150
  declare function isStream(data: any): data is Readable | ReadableStream;
1153
1151
  /**
package/dist/index.d.mts CHANGED
@@ -135,13 +135,12 @@ interface SessionConfig {
135
135
  }
136
136
  /**
137
137
  * Create a session manager for the current request.
138
- *
139
138
  */
140
139
  declare function useSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig): Promise<{
141
140
  readonly id: string | undefined;
142
141
  readonly data: T;
143
- update: (update: SessionUpdate<T>) => Promise<any>;
144
- clear: () => Promise<any>;
142
+ update: (update: SessionUpdate<T>) => Promise</*elided*/ any>;
143
+ clear: () => Promise</*elided*/ any>;
145
144
  }>;
146
145
  /**
147
146
  * Get the session for the current request.
@@ -513,7 +512,7 @@ declare function readBody<T, Event extends H3Event = H3Event, _T = InferEventInp
513
512
  */
514
513
  declare function readValidatedBody<T, Event extends H3Event = H3Event, _T = InferEventInput<"body", Event, T>>(event: Event, validate: ValidateFunction<_T>): Promise<_T>;
515
514
  /**
516
- * Tries to read and parse the body of a an H3Event as multipart form.
515
+ * Tries to read and parse the body of an H3Event as multipart form.
517
516
  *
518
517
  * @example
519
518
  * export default defineEventHandler(async (event) => {
@@ -615,7 +614,7 @@ interface H3CorsOptions {
615
614
  declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
616
615
 
617
616
  /**
618
- * Get query the params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
617
+ * Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
619
618
  *
620
619
  * @example
621
620
  * export default defineEventHandler((event) => {
@@ -624,7 +623,7 @@ declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
624
623
  */
625
624
  declare function getQuery<T, Event extends H3Event = H3Event, _T = Exclude<InferEventInput<"query", Event, T>, undefined>>(event: Event): _T;
626
625
  /**
627
- * Get the query param from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
626
+ * Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
628
627
  *
629
628
  * You can use a simple function to validate the query object or a library like `zod` to define a schema.
630
629
  *
@@ -796,7 +795,7 @@ declare function getRequestProtocol(event: H3Event, opts?: {
796
795
  /** @deprecated Use `event.path` instead */
797
796
  declare function getRequestPath(event: H3Event): string;
798
797
  /**
799
- * Generated the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
798
+ * Generate the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
800
799
  *
801
800
  * If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
802
801
  *
@@ -820,7 +819,9 @@ declare function toWebRequest(event: H3Event): Request;
820
819
  /**
821
820
  * Try to get the client IP address from the incoming request.
822
821
  *
823
- * If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header if it exists.
822
+ * If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header set by proxies if it exists.
823
+ *
824
+ * Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
824
825
  *
825
826
  * If IP cannot be determined, it will default to `undefined`.
826
827
  *
@@ -830,11 +831,6 @@ declare function toWebRequest(event: H3Event): Request;
830
831
  * });
831
832
  */
832
833
  declare function getRequestIP(event: H3Event, opts?: {
833
- /**
834
- * Use the X-Forwarded-For HTTP header set by proxies.
835
- *
836
- * Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
837
- */
838
834
  xForwardedFor?: boolean;
839
835
  }): string | undefined;
840
836
 
@@ -856,7 +852,7 @@ declare function appendCorsPreflightHeaders(event: H3Event, options: H3CorsOptio
856
852
  declare function appendCorsHeaders(event: H3Event, options: H3CorsOptions): void;
857
853
 
858
854
  /**
859
- * Parse the request to get HTTP Cookie header string and returning an object of all cookie name-value pairs.
855
+ * Parse the request to get HTTP Cookie header string and return an object of all cookie name-value pairs.
860
856
  * @param event {H3Event} H3 event or req passed by h3 handler
861
857
  * @returns Object of cookie name-value pairs
862
858
  * ```ts
@@ -957,7 +953,9 @@ declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions):
957
953
  /**
958
954
  * Get the request headers object without headers known to cause issues when proxying.
959
955
  */
960
- declare function getProxyRequestHeaders(event: H3Event): any;
956
+ declare function getProxyRequestHeaders(event: H3Event, opts?: {
957
+ host?: boolean;
958
+ }): any;
961
959
  /**
962
960
  * Make a fetch request with the event's context and headers.
963
961
  */
@@ -979,7 +977,7 @@ type IteratorSerializer<Value> = (value: Value) => SendableValue | undefined;
979
977
  */
980
978
  declare function send(event: H3Event, data?: any, type?: MimeType): Promise<void>;
981
979
  /**
982
- * Respond with an empty payload.<br>
980
+ * Respond with an empty payload.
983
981
  *
984
982
  * Note that calling this function will close the connection and no other data can be sent to the client afterwards.
985
983
  *
@@ -1059,7 +1057,7 @@ declare function sendRedirect(event: H3Event, location: string, code?: StatusCod
1059
1057
  */
1060
1058
  declare function getResponseHeaders(event: H3Event): ReturnType<H3Event["node"]["res"]["getHeaders"]>;
1061
1059
  /**
1062
- * Alias for `getResponseHeaders`.
1060
+ * Get a response header by name.
1063
1061
  *
1064
1062
  * @example
1065
1063
  * export default defineEventHandler((event) => {
@@ -1147,7 +1145,7 @@ declare function clearResponseHeaders(event: H3Event, headerNames?: HTTPHeaderNa
1147
1145
  */
1148
1146
  declare function removeResponseHeader(event: H3Event, name: HTTPHeaderName): void;
1149
1147
  /**
1150
- * Checks if the data is a stream. (Node.js Readable Stream, React Pipeable Stream, or Web Stream)
1148
+ * Checks if the data is a stream (Node.js Readable Stream, React Pipeable Stream, or Web Stream).
1151
1149
  */
1152
1150
  declare function isStream(data: any): data is Readable | ReadableStream;
1153
1151
  /**
package/dist/index.d.ts CHANGED
@@ -135,13 +135,12 @@ interface SessionConfig {
135
135
  }
136
136
  /**
137
137
  * Create a session manager for the current request.
138
- *
139
138
  */
140
139
  declare function useSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig): Promise<{
141
140
  readonly id: string | undefined;
142
141
  readonly data: T;
143
- update: (update: SessionUpdate<T>) => Promise<any>;
144
- clear: () => Promise<any>;
142
+ update: (update: SessionUpdate<T>) => Promise</*elided*/ any>;
143
+ clear: () => Promise</*elided*/ any>;
145
144
  }>;
146
145
  /**
147
146
  * Get the session for the current request.
@@ -513,7 +512,7 @@ declare function readBody<T, Event extends H3Event = H3Event, _T = InferEventInp
513
512
  */
514
513
  declare function readValidatedBody<T, Event extends H3Event = H3Event, _T = InferEventInput<"body", Event, T>>(event: Event, validate: ValidateFunction<_T>): Promise<_T>;
515
514
  /**
516
- * Tries to read and parse the body of a an H3Event as multipart form.
515
+ * Tries to read and parse the body of an H3Event as multipart form.
517
516
  *
518
517
  * @example
519
518
  * export default defineEventHandler(async (event) => {
@@ -615,7 +614,7 @@ interface H3CorsOptions {
615
614
  declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
616
615
 
617
616
  /**
618
- * Get query the params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
617
+ * Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
619
618
  *
620
619
  * @example
621
620
  * export default defineEventHandler((event) => {
@@ -624,7 +623,7 @@ declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
624
623
  */
625
624
  declare function getQuery<T, Event extends H3Event = H3Event, _T = Exclude<InferEventInput<"query", Event, T>, undefined>>(event: Event): _T;
626
625
  /**
627
- * Get the query param from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
626
+ * Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
628
627
  *
629
628
  * You can use a simple function to validate the query object or a library like `zod` to define a schema.
630
629
  *
@@ -796,7 +795,7 @@ declare function getRequestProtocol(event: H3Event, opts?: {
796
795
  /** @deprecated Use `event.path` instead */
797
796
  declare function getRequestPath(event: H3Event): string;
798
797
  /**
799
- * Generated the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
798
+ * Generate the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
800
799
  *
801
800
  * If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
802
801
  *
@@ -820,7 +819,9 @@ declare function toWebRequest(event: H3Event): Request;
820
819
  /**
821
820
  * Try to get the client IP address from the incoming request.
822
821
  *
823
- * If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header if it exists.
822
+ * If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header set by proxies if it exists.
823
+ *
824
+ * Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
824
825
  *
825
826
  * If IP cannot be determined, it will default to `undefined`.
826
827
  *
@@ -830,11 +831,6 @@ declare function toWebRequest(event: H3Event): Request;
830
831
  * });
831
832
  */
832
833
  declare function getRequestIP(event: H3Event, opts?: {
833
- /**
834
- * Use the X-Forwarded-For HTTP header set by proxies.
835
- *
836
- * Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
837
- */
838
834
  xForwardedFor?: boolean;
839
835
  }): string | undefined;
840
836
 
@@ -856,7 +852,7 @@ declare function appendCorsPreflightHeaders(event: H3Event, options: H3CorsOptio
856
852
  declare function appendCorsHeaders(event: H3Event, options: H3CorsOptions): void;
857
853
 
858
854
  /**
859
- * Parse the request to get HTTP Cookie header string and returning an object of all cookie name-value pairs.
855
+ * Parse the request to get HTTP Cookie header string and return an object of all cookie name-value pairs.
860
856
  * @param event {H3Event} H3 event or req passed by h3 handler
861
857
  * @returns Object of cookie name-value pairs
862
858
  * ```ts
@@ -957,7 +953,9 @@ declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions):
957
953
  /**
958
954
  * Get the request headers object without headers known to cause issues when proxying.
959
955
  */
960
- declare function getProxyRequestHeaders(event: H3Event): any;
956
+ declare function getProxyRequestHeaders(event: H3Event, opts?: {
957
+ host?: boolean;
958
+ }): any;
961
959
  /**
962
960
  * Make a fetch request with the event's context and headers.
963
961
  */
@@ -979,7 +977,7 @@ type IteratorSerializer<Value> = (value: Value) => SendableValue | undefined;
979
977
  */
980
978
  declare function send(event: H3Event, data?: any, type?: MimeType): Promise<void>;
981
979
  /**
982
- * Respond with an empty payload.<br>
980
+ * Respond with an empty payload.
983
981
  *
984
982
  * Note that calling this function will close the connection and no other data can be sent to the client afterwards.
985
983
  *
@@ -1059,7 +1057,7 @@ declare function sendRedirect(event: H3Event, location: string, code?: StatusCod
1059
1057
  */
1060
1058
  declare function getResponseHeaders(event: H3Event): ReturnType<H3Event["node"]["res"]["getHeaders"]>;
1061
1059
  /**
1062
- * Alias for `getResponseHeaders`.
1060
+ * Get a response header by name.
1063
1061
  *
1064
1062
  * @example
1065
1063
  * export default defineEventHandler((event) => {
@@ -1147,7 +1145,7 @@ declare function clearResponseHeaders(event: H3Event, headerNames?: HTTPHeaderNa
1147
1145
  */
1148
1146
  declare function removeResponseHeader(event: H3Event, name: HTTPHeaderName): void;
1149
1147
  /**
1150
- * Checks if the data is a stream. (Node.js Readable Stream, React Pipeable Stream, or Web Stream)
1148
+ * Checks if the data is a stream (Node.js Readable Stream, React Pipeable Stream, or Web Stream).
1151
1149
  */
1152
1150
  declare function isStream(data: any): data is Readable | ReadableStream;
1153
1151
  /**
package/dist/index.mjs CHANGED
@@ -34,21 +34,16 @@ function hasProp(obj, prop) {
34
34
  }
35
35
  }
36
36
 
37
- var __defProp$2 = Object.defineProperty;
38
- var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
39
- var __publicField$2 = (obj, key, value) => {
40
- __defNormalProp$2(obj, typeof key !== "symbol" ? key + "" : key, value);
41
- return value;
42
- };
43
37
  class H3Error extends Error {
38
+ static __h3_error__ = true;
39
+ statusCode = 500;
40
+ fatal = false;
41
+ unhandled = false;
42
+ statusMessage;
43
+ data;
44
+ cause;
44
45
  constructor(message, opts = {}) {
45
46
  super(message, opts);
46
- __publicField$2(this, "statusCode", 500);
47
- __publicField$2(this, "fatal", false);
48
- __publicField$2(this, "unhandled", false);
49
- __publicField$2(this, "statusMessage");
50
- __publicField$2(this, "data");
51
- __publicField$2(this, "cause");
52
47
  if (opts.cause && !this.cause) {
53
48
  this.cause = opts.cause;
54
49
  }
@@ -67,7 +62,6 @@ class H3Error extends Error {
67
62
  return obj;
68
63
  }
69
64
  }
70
- __publicField$2(H3Error, "__h3_error__", true);
71
65
  function createError(input) {
72
66
  if (typeof input === "string") {
73
67
  return new H3Error(input);
@@ -1123,6 +1117,7 @@ async function getRequestFingerprint(event, opts = {}) {
1123
1117
  const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
1124
1118
  const ignoredHeaders = /* @__PURE__ */ new Set([
1125
1119
  "transfer-encoding",
1120
+ "accept-encoding",
1126
1121
  "connection",
1127
1122
  "keep-alive",
1128
1123
  "upgrade",
@@ -1143,7 +1138,7 @@ async function proxyRequest(event, target, opts = {}) {
1143
1138
  }
1144
1139
  const method = opts.fetchOptions?.method || event.method;
1145
1140
  const fetchHeaders = mergeHeaders(
1146
- getProxyRequestHeaders(event),
1141
+ getProxyRequestHeaders(event, { host: target.startsWith("/") }),
1147
1142
  opts.fetchOptions?.headers,
1148
1143
  opts.headers
1149
1144
  );
@@ -1235,11 +1230,11 @@ async function sendProxy(event, target, opts = {}) {
1235
1230
  }
1236
1231
  return event.node.res.end();
1237
1232
  }
1238
- function getProxyRequestHeaders(event) {
1233
+ function getProxyRequestHeaders(event, opts) {
1239
1234
  const headers = /* @__PURE__ */ Object.create(null);
1240
1235
  const reqHeaders = getRequestHeaders(event);
1241
1236
  for (const name in reqHeaders) {
1242
- if (!ignoredHeaders.has(name)) {
1237
+ if (!ignoredHeaders.has(name) || name === "host" && opts?.host) {
1243
1238
  headers[name] = reqHeaders[name];
1244
1239
  }
1245
1240
  }
@@ -1250,7 +1245,9 @@ function fetchWithEvent(event, req, init, options) {
1250
1245
  ...init,
1251
1246
  context: init?.context || event.context,
1252
1247
  headers: {
1253
- ...getProxyRequestHeaders(event),
1248
+ ...getProxyRequestHeaders(event, {
1249
+ host: typeof req === "string" && req.startsWith("/")
1250
+ }),
1254
1251
  ...init?.headers
1255
1252
  }
1256
1253
  });
@@ -1472,23 +1469,17 @@ function isHttp2Request(event) {
1472
1469
  return getHeader(event, ":path") !== void 0 && getHeader(event, ":method") !== void 0;
1473
1470
  }
1474
1471
 
1475
- var __defProp$1 = Object.defineProperty;
1476
- var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1477
- var __publicField$1 = (obj, key, value) => {
1478
- __defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
1479
- return value;
1480
- };
1481
1472
  class EventStream {
1473
+ _h3Event;
1474
+ _transformStream = new TransformStream();
1475
+ _writer;
1476
+ _encoder = new TextEncoder();
1477
+ _writerIsClosed = false;
1478
+ _paused = false;
1479
+ _unsentData;
1480
+ _disposed = false;
1481
+ _handled = false;
1482
1482
  constructor(event, opts = {}) {
1483
- __publicField$1(this, "_h3Event");
1484
- __publicField$1(this, "_transformStream", new TransformStream());
1485
- __publicField$1(this, "_writer");
1486
- __publicField$1(this, "_encoder", new TextEncoder());
1487
- __publicField$1(this, "_writerIsClosed", false);
1488
- __publicField$1(this, "_paused", false);
1489
- __publicField$1(this, "_unsentData");
1490
- __publicField$1(this, "_disposed", false);
1491
- __publicField$1(this, "_handled", false);
1492
1483
  this._h3Event = event;
1493
1484
  this._writer = this._transformStream.writable.getWriter();
1494
1485
  this._writer.closed.then(() => {
@@ -1715,32 +1706,26 @@ function defineWebSocketHandler(hooks) {
1715
1706
  });
1716
1707
  }
1717
1708
 
1718
- var __defProp = Object.defineProperty;
1719
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1720
- var __publicField = (obj, key, value) => {
1721
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
1722
- return value;
1723
- };
1724
1709
  class H3Event {
1710
+ "__is_event__" = true;
1711
+ // Context
1712
+ node;
1713
+ // Node
1714
+ web;
1715
+ // Web
1716
+ context = {};
1717
+ // Shared
1718
+ // Request
1719
+ _method;
1720
+ _path;
1721
+ _headers;
1722
+ _requestBody;
1723
+ // Response
1724
+ _handled = false;
1725
+ // Hooks
1726
+ _onBeforeResponseCalled;
1727
+ _onAfterResponseCalled;
1725
1728
  constructor(req, res) {
1726
- __publicField(this, "__is_event__", true);
1727
- // Context
1728
- __publicField(this, "node");
1729
- // Node
1730
- __publicField(this, "web");
1731
- // Web
1732
- __publicField(this, "context", {});
1733
- // Shared
1734
- // Request
1735
- __publicField(this, "_method");
1736
- __publicField(this, "_path");
1737
- __publicField(this, "_headers");
1738
- __publicField(this, "_requestBody");
1739
- // Response
1740
- __publicField(this, "_handled", false);
1741
- // Hooks
1742
- __publicField(this, "_onBeforeResponseCalled");
1743
- __publicField(this, "_onAfterResponseCalled");
1744
1729
  this.node = { req, res };
1745
1730
  }
1746
1731
  // --- Request ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "h3",
3
- "version": "1.13.0",
3
+ "version": "1.13.1",
4
4
  "description": "Minimal H(TTP) framework built for high performance and portability.",
5
5
  "repository": "unjs/h3",
6
6
  "license": "MIT",
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "cookie-es": "^1.2.2",
37
- "crossws": ">=0.2.0 <0.4.0",
37
+ "crossws": "^0.3.1",
38
38
  "defu": "^6.1.4",
39
39
  "destr": "^2.0.3",
40
40
  "iron-webcrypto": "^1.2.1",
@@ -45,32 +45,32 @@
45
45
  "unenv": "^1.10.0"
46
46
  },
47
47
  "devDependencies": {
48
- "0x": "^5.7.0",
48
+ "0x": "^5.8.0",
49
49
  "@types/express": "^5.0.0",
50
- "@types/node": "^22.7.4",
50
+ "@types/node": "^22.10.5",
51
51
  "@types/supertest": "^6.0.2",
52
- "@vitest/coverage-v8": "^2.1.2",
53
- "autocannon": "^7.15.0",
54
- "automd": "^0.3.9",
52
+ "@vitest/coverage-v8": "^2.1.8",
53
+ "autocannon": "^8.0.0",
54
+ "automd": "^0.3.12",
55
55
  "changelogen": "^0.5.7",
56
56
  "connect": "^3.7.0",
57
- "eslint": "^9.11.1",
58
- "eslint-config-unjs": "^0.4.1",
59
- "express": "^4.21.0",
57
+ "eslint": "^9.17.0",
58
+ "eslint-config-unjs": "^0.4.2",
59
+ "express": "^4.21.2",
60
60
  "get-port": "^7.1.0",
61
- "h3": "link:.",
62
- "jiti": "^2.1.2",
61
+ "h3": "^1.13.0",
62
+ "jiti": "^2.4.2",
63
63
  "listhen": "^1.9.0",
64
64
  "node-fetch-native": "^1.6.4",
65
- "prettier": "^3.3.3",
66
- "react": "^18.3.1",
67
- "react-dom": "^18.3.1",
65
+ "prettier": "^3.4.2",
66
+ "react": "^19.0.0",
67
+ "react-dom": "^19.0.0",
68
68
  "supertest": "^7.0.0",
69
- "typescript": "^5.6.2",
70
- "unbuild": "^2.0.0",
71
- "undici": "^6.19.8",
72
- "vitest": "^2.1.2",
73
- "zod": "^3.23.8"
69
+ "typescript": "^5.7.3",
70
+ "unbuild": "^3.2.0",
71
+ "undici": "^7.2.0",
72
+ "vitest": "^2.1.8",
73
+ "zod": "^3.24.1"
74
74
  },
75
- "packageManager": "pnpm@9.7.1"
75
+ "packageManager": "pnpm@9.15.3"
76
76
  }