h3 1.12.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 +1 -1
- package/dist/index.cjs +47 -58
- package/dist/index.d.cts +24 -23
- package/dist/index.d.mts +24 -23
- package/dist/index.d.ts +24 -23
- package/dist/index.mjs +47 -58
- package/package.json +43 -39
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<!-- automd:badges -->
|
|
4
4
|
|
|
5
5
|
[](https://npmjs.com/package/h3)
|
|
6
|
-
[](https://
|
|
6
|
+
[](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);
|
|
@@ -414,6 +408,9 @@ function readRawBody(event, encoding = "utf8") {
|
|
|
414
408
|
if (_resolved.constructor === Object) {
|
|
415
409
|
return Buffer.from(JSON.stringify(_resolved));
|
|
416
410
|
}
|
|
411
|
+
if (_resolved instanceof URLSearchParams) {
|
|
412
|
+
return Buffer.from(_resolved.toString());
|
|
413
|
+
}
|
|
417
414
|
return Buffer.from(_resolved);
|
|
418
415
|
});
|
|
419
416
|
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
|
|
@@ -671,7 +668,7 @@ function splitCookiesString(cookiesString) {
|
|
|
671
668
|
}
|
|
672
669
|
}
|
|
673
670
|
if (!cookiesSeparatorFound || pos >= cookiesString.length) {
|
|
674
|
-
cookiesStrings.push(cookiesString.slice(start
|
|
671
|
+
cookiesStrings.push(cookiesString.slice(start));
|
|
675
672
|
}
|
|
676
673
|
}
|
|
677
674
|
return cookiesStrings;
|
|
@@ -1127,6 +1124,7 @@ async function getRequestFingerprint(event, opts = {}) {
|
|
|
1127
1124
|
const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
|
|
1128
1125
|
const ignoredHeaders = /* @__PURE__ */ new Set([
|
|
1129
1126
|
"transfer-encoding",
|
|
1127
|
+
"accept-encoding",
|
|
1130
1128
|
"connection",
|
|
1131
1129
|
"keep-alive",
|
|
1132
1130
|
"upgrade",
|
|
@@ -1147,7 +1145,7 @@ async function proxyRequest(event, target, opts = {}) {
|
|
|
1147
1145
|
}
|
|
1148
1146
|
const method = opts.fetchOptions?.method || event.method;
|
|
1149
1147
|
const fetchHeaders = mergeHeaders(
|
|
1150
|
-
getProxyRequestHeaders(event),
|
|
1148
|
+
getProxyRequestHeaders(event, { host: target.startsWith("/") }),
|
|
1151
1149
|
opts.fetchOptions?.headers,
|
|
1152
1150
|
opts.headers
|
|
1153
1151
|
);
|
|
@@ -1239,11 +1237,11 @@ async function sendProxy(event, target, opts = {}) {
|
|
|
1239
1237
|
}
|
|
1240
1238
|
return event.node.res.end();
|
|
1241
1239
|
}
|
|
1242
|
-
function getProxyRequestHeaders(event) {
|
|
1240
|
+
function getProxyRequestHeaders(event, opts) {
|
|
1243
1241
|
const headers = /* @__PURE__ */ Object.create(null);
|
|
1244
1242
|
const reqHeaders = getRequestHeaders(event);
|
|
1245
1243
|
for (const name in reqHeaders) {
|
|
1246
|
-
if (!ignoredHeaders.has(name)) {
|
|
1244
|
+
if (!ignoredHeaders.has(name) || name === "host" && opts?.host) {
|
|
1247
1245
|
headers[name] = reqHeaders[name];
|
|
1248
1246
|
}
|
|
1249
1247
|
}
|
|
@@ -1254,7 +1252,9 @@ function fetchWithEvent(event, req, init, options) {
|
|
|
1254
1252
|
...init,
|
|
1255
1253
|
context: init?.context || event.context,
|
|
1256
1254
|
headers: {
|
|
1257
|
-
...getProxyRequestHeaders(event
|
|
1255
|
+
...getProxyRequestHeaders(event, {
|
|
1256
|
+
host: typeof req === "string" && req.startsWith("/")
|
|
1257
|
+
}),
|
|
1258
1258
|
...init?.headers
|
|
1259
1259
|
}
|
|
1260
1260
|
});
|
|
@@ -1476,23 +1476,17 @@ function isHttp2Request(event) {
|
|
|
1476
1476
|
return getHeader(event, ":path") !== void 0 && getHeader(event, ":method") !== void 0;
|
|
1477
1477
|
}
|
|
1478
1478
|
|
|
1479
|
-
var __defProp$1 = Object.defineProperty;
|
|
1480
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1481
|
-
var __publicField$1 = (obj, key, value) => {
|
|
1482
|
-
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1483
|
-
return value;
|
|
1484
|
-
};
|
|
1485
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;
|
|
1486
1489
|
constructor(event, opts = {}) {
|
|
1487
|
-
__publicField$1(this, "_h3Event");
|
|
1488
|
-
__publicField$1(this, "_transformStream", new TransformStream());
|
|
1489
|
-
__publicField$1(this, "_writer");
|
|
1490
|
-
__publicField$1(this, "_encoder", new TextEncoder());
|
|
1491
|
-
__publicField$1(this, "_writerIsClosed", false);
|
|
1492
|
-
__publicField$1(this, "_paused", false);
|
|
1493
|
-
__publicField$1(this, "_unsentData");
|
|
1494
|
-
__publicField$1(this, "_disposed", false);
|
|
1495
|
-
__publicField$1(this, "_handled", false);
|
|
1496
1490
|
this._h3Event = event;
|
|
1497
1491
|
this._writer = this._transformStream.writable.getWriter();
|
|
1498
1492
|
this._writer.closed.then(() => {
|
|
@@ -1719,32 +1713,26 @@ function defineWebSocketHandler(hooks) {
|
|
|
1719
1713
|
});
|
|
1720
1714
|
}
|
|
1721
1715
|
|
|
1722
|
-
var __defProp = Object.defineProperty;
|
|
1723
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1724
|
-
var __publicField = (obj, key, value) => {
|
|
1725
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1726
|
-
return value;
|
|
1727
|
-
};
|
|
1728
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;
|
|
1729
1735
|
constructor(req, res) {
|
|
1730
|
-
__publicField(this, "__is_event__", true);
|
|
1731
|
-
// Context
|
|
1732
|
-
__publicField(this, "node");
|
|
1733
|
-
// Node
|
|
1734
|
-
__publicField(this, "web");
|
|
1735
|
-
// Web
|
|
1736
|
-
__publicField(this, "context", {});
|
|
1737
|
-
// Shared
|
|
1738
|
-
// Request
|
|
1739
|
-
__publicField(this, "_method");
|
|
1740
|
-
__publicField(this, "_path");
|
|
1741
|
-
__publicField(this, "_headers");
|
|
1742
|
-
__publicField(this, "_requestBody");
|
|
1743
|
-
// Response
|
|
1744
|
-
__publicField(this, "_handled", false);
|
|
1745
|
-
// Hooks
|
|
1746
|
-
__publicField(this, "_onBeforeResponseCalled");
|
|
1747
|
-
__publicField(this, "_onAfterResponseCalled");
|
|
1748
1736
|
this.node = { req, res };
|
|
1749
1737
|
}
|
|
1750
1738
|
// --- Request ---
|
|
@@ -2114,7 +2102,8 @@ function websocketOptions(evResolver, appOptions) {
|
|
|
2114
2102
|
return {
|
|
2115
2103
|
...appOptions.websocket,
|
|
2116
2104
|
async resolve(info) {
|
|
2117
|
-
const
|
|
2105
|
+
const url = info.request?.url || info.url || "/";
|
|
2106
|
+
const { pathname } = typeof url === "string" ? ufo.parseURL(url) : url;
|
|
2118
2107
|
const resolved = await evResolver(pathname);
|
|
2119
2108
|
return resolved?.handler?.__websocket__ || {};
|
|
2120
2109
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -48,7 +48,7 @@ declare class H3Event<_RequestT extends EventHandlerRequest = EventHandlerReques
|
|
|
48
48
|
toJSON(): string;
|
|
49
49
|
/** @deprecated Please use `event.node.req` instead. */
|
|
50
50
|
get req(): IncomingMessage & {
|
|
51
|
-
originalUrl?: string
|
|
51
|
+
originalUrl?: string;
|
|
52
52
|
};
|
|
53
53
|
/** @deprecated Please use `event.node.res` instead. */
|
|
54
54
|
get res(): ServerResponse<IncomingMessage>;
|
|
@@ -93,7 +93,7 @@ declare const lazyEventHandler: typeof defineLazyEventHandler;
|
|
|
93
93
|
* https://developer.mozilla.org/en-US/docs/Web/API/Headers
|
|
94
94
|
*/
|
|
95
95
|
declare const H3Headers: {
|
|
96
|
-
new (init?: HeadersInit
|
|
96
|
+
new (init?: HeadersInit): Headers;
|
|
97
97
|
prototype: Headers;
|
|
98
98
|
};
|
|
99
99
|
/**
|
|
@@ -101,11 +101,11 @@ declare const H3Headers: {
|
|
|
101
101
|
* https://developer.mozilla.org/en-US/docs/Web/API/Response
|
|
102
102
|
*/
|
|
103
103
|
declare const H3Response: {
|
|
104
|
-
new (body?: BodyInit | null
|
|
104
|
+
new (body?: BodyInit | null, init?: ResponseInit): Response;
|
|
105
105
|
prototype: Response;
|
|
106
106
|
error(): Response;
|
|
107
|
-
json(data: any, init?: ResponseInit
|
|
108
|
-
redirect(url: string | URL, status?: number
|
|
107
|
+
json(data: any, init?: ResponseInit): Response;
|
|
108
|
+
redirect(url: string | URL, status?: number): Response;
|
|
109
109
|
};
|
|
110
110
|
|
|
111
111
|
type SessionDataT = Record<string, any>;
|
|
@@ -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
|
|
144
|
-
clear: () => Promise
|
|
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.
|
|
@@ -470,6 +469,9 @@ declare function readRawBody<E extends Encoding = "utf8">(event: H3Event, encodi
|
|
|
470
469
|
/**
|
|
471
470
|
* Reads request body and tries to safely parse using [destr](https://github.com/unjs/destr).
|
|
472
471
|
*
|
|
472
|
+
* Be aware that this utility is not restricted to `application/json` and will parse `application/x-www-form-urlencoded` content types.
|
|
473
|
+
* Because of this, authenticated `GET`/`POST` handlers may be at risk of a [CSRF](https://owasp.org/www-community/attacks/csrf) attack, and must check the `content-type` header manually.
|
|
474
|
+
*
|
|
473
475
|
* @example
|
|
474
476
|
* export default defineEventHandler(async (event) => {
|
|
475
477
|
* const body = await readBody(event);
|
|
@@ -510,7 +512,7 @@ declare function readBody<T, Event extends H3Event = H3Event, _T = InferEventInp
|
|
|
510
512
|
*/
|
|
511
513
|
declare function readValidatedBody<T, Event extends H3Event = H3Event, _T = InferEventInput<"body", Event, T>>(event: Event, validate: ValidateFunction<_T>): Promise<_T>;
|
|
512
514
|
/**
|
|
513
|
-
* Tries to read and parse the body of
|
|
515
|
+
* Tries to read and parse the body of an H3Event as multipart form.
|
|
514
516
|
*
|
|
515
517
|
* @example
|
|
516
518
|
* export default defineEventHandler(async (event) => {
|
|
@@ -612,7 +614,7 @@ interface H3CorsOptions {
|
|
|
612
614
|
declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
|
|
613
615
|
|
|
614
616
|
/**
|
|
615
|
-
* Get query
|
|
617
|
+
* Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
|
|
616
618
|
*
|
|
617
619
|
* @example
|
|
618
620
|
* export default defineEventHandler((event) => {
|
|
@@ -621,7 +623,7 @@ declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
|
|
|
621
623
|
*/
|
|
622
624
|
declare function getQuery<T, Event extends H3Event = H3Event, _T = Exclude<InferEventInput<"query", Event, T>, undefined>>(event: Event): _T;
|
|
623
625
|
/**
|
|
624
|
-
* Get the query
|
|
626
|
+
* Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
|
|
625
627
|
*
|
|
626
628
|
* You can use a simple function to validate the query object or a library like `zod` to define a schema.
|
|
627
629
|
*
|
|
@@ -793,7 +795,7 @@ declare function getRequestProtocol(event: H3Event, opts?: {
|
|
|
793
795
|
/** @deprecated Use `event.path` instead */
|
|
794
796
|
declare function getRequestPath(event: H3Event): string;
|
|
795
797
|
/**
|
|
796
|
-
*
|
|
798
|
+
* Generate the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
|
|
797
799
|
*
|
|
798
800
|
* If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
|
|
799
801
|
*
|
|
@@ -817,7 +819,9 @@ declare function toWebRequest(event: H3Event): Request;
|
|
|
817
819
|
/**
|
|
818
820
|
* Try to get the client IP address from the incoming request.
|
|
819
821
|
*
|
|
820
|
-
* 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.
|
|
821
825
|
*
|
|
822
826
|
* If IP cannot be determined, it will default to `undefined`.
|
|
823
827
|
*
|
|
@@ -827,11 +831,6 @@ declare function toWebRequest(event: H3Event): Request;
|
|
|
827
831
|
* });
|
|
828
832
|
*/
|
|
829
833
|
declare function getRequestIP(event: H3Event, opts?: {
|
|
830
|
-
/**
|
|
831
|
-
* Use the X-Forwarded-For HTTP header set by proxies.
|
|
832
|
-
*
|
|
833
|
-
* Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
|
|
834
|
-
*/
|
|
835
834
|
xForwardedFor?: boolean;
|
|
836
835
|
}): string | undefined;
|
|
837
836
|
|
|
@@ -853,7 +852,7 @@ declare function appendCorsPreflightHeaders(event: H3Event, options: H3CorsOptio
|
|
|
853
852
|
declare function appendCorsHeaders(event: H3Event, options: H3CorsOptions): void;
|
|
854
853
|
|
|
855
854
|
/**
|
|
856
|
-
* Parse the request to get HTTP Cookie header string and
|
|
855
|
+
* Parse the request to get HTTP Cookie header string and return an object of all cookie name-value pairs.
|
|
857
856
|
* @param event {H3Event} H3 event or req passed by h3 handler
|
|
858
857
|
* @returns Object of cookie name-value pairs
|
|
859
858
|
* ```ts
|
|
@@ -954,7 +953,9 @@ declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions):
|
|
|
954
953
|
/**
|
|
955
954
|
* Get the request headers object without headers known to cause issues when proxying.
|
|
956
955
|
*/
|
|
957
|
-
declare function getProxyRequestHeaders(event: H3Event
|
|
956
|
+
declare function getProxyRequestHeaders(event: H3Event, opts?: {
|
|
957
|
+
host?: boolean;
|
|
958
|
+
}): any;
|
|
958
959
|
/**
|
|
959
960
|
* Make a fetch request with the event's context and headers.
|
|
960
961
|
*/
|
|
@@ -976,7 +977,7 @@ type IteratorSerializer<Value> = (value: Value) => SendableValue | undefined;
|
|
|
976
977
|
*/
|
|
977
978
|
declare function send(event: H3Event, data?: any, type?: MimeType): Promise<void>;
|
|
978
979
|
/**
|
|
979
|
-
* Respond with an empty payload
|
|
980
|
+
* Respond with an empty payload.
|
|
980
981
|
*
|
|
981
982
|
* Note that calling this function will close the connection and no other data can be sent to the client afterwards.
|
|
982
983
|
*
|
|
@@ -1056,7 +1057,7 @@ declare function sendRedirect(event: H3Event, location: string, code?: StatusCod
|
|
|
1056
1057
|
*/
|
|
1057
1058
|
declare function getResponseHeaders(event: H3Event): ReturnType<H3Event["node"]["res"]["getHeaders"]>;
|
|
1058
1059
|
/**
|
|
1059
|
-
*
|
|
1060
|
+
* Get a response header by name.
|
|
1060
1061
|
*
|
|
1061
1062
|
* @example
|
|
1062
1063
|
* export default defineEventHandler((event) => {
|
|
@@ -1144,7 +1145,7 @@ declare function clearResponseHeaders(event: H3Event, headerNames?: HTTPHeaderNa
|
|
|
1144
1145
|
*/
|
|
1145
1146
|
declare function removeResponseHeader(event: H3Event, name: HTTPHeaderName): void;
|
|
1146
1147
|
/**
|
|
1147
|
-
* Checks if the data is a stream
|
|
1148
|
+
* Checks if the data is a stream (Node.js Readable Stream, React Pipeable Stream, or Web Stream).
|
|
1148
1149
|
*/
|
|
1149
1150
|
declare function isStream(data: any): data is Readable | ReadableStream;
|
|
1150
1151
|
/**
|
package/dist/index.d.mts
CHANGED
|
@@ -48,7 +48,7 @@ declare class H3Event<_RequestT extends EventHandlerRequest = EventHandlerReques
|
|
|
48
48
|
toJSON(): string;
|
|
49
49
|
/** @deprecated Please use `event.node.req` instead. */
|
|
50
50
|
get req(): IncomingMessage & {
|
|
51
|
-
originalUrl?: string
|
|
51
|
+
originalUrl?: string;
|
|
52
52
|
};
|
|
53
53
|
/** @deprecated Please use `event.node.res` instead. */
|
|
54
54
|
get res(): ServerResponse<IncomingMessage>;
|
|
@@ -93,7 +93,7 @@ declare const lazyEventHandler: typeof defineLazyEventHandler;
|
|
|
93
93
|
* https://developer.mozilla.org/en-US/docs/Web/API/Headers
|
|
94
94
|
*/
|
|
95
95
|
declare const H3Headers: {
|
|
96
|
-
new (init?: HeadersInit
|
|
96
|
+
new (init?: HeadersInit): Headers;
|
|
97
97
|
prototype: Headers;
|
|
98
98
|
};
|
|
99
99
|
/**
|
|
@@ -101,11 +101,11 @@ declare const H3Headers: {
|
|
|
101
101
|
* https://developer.mozilla.org/en-US/docs/Web/API/Response
|
|
102
102
|
*/
|
|
103
103
|
declare const H3Response: {
|
|
104
|
-
new (body?: BodyInit | null
|
|
104
|
+
new (body?: BodyInit | null, init?: ResponseInit): Response;
|
|
105
105
|
prototype: Response;
|
|
106
106
|
error(): Response;
|
|
107
|
-
json(data: any, init?: ResponseInit
|
|
108
|
-
redirect(url: string | URL, status?: number
|
|
107
|
+
json(data: any, init?: ResponseInit): Response;
|
|
108
|
+
redirect(url: string | URL, status?: number): Response;
|
|
109
109
|
};
|
|
110
110
|
|
|
111
111
|
type SessionDataT = Record<string, any>;
|
|
@@ -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
|
|
144
|
-
clear: () => Promise
|
|
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.
|
|
@@ -470,6 +469,9 @@ declare function readRawBody<E extends Encoding = "utf8">(event: H3Event, encodi
|
|
|
470
469
|
/**
|
|
471
470
|
* Reads request body and tries to safely parse using [destr](https://github.com/unjs/destr).
|
|
472
471
|
*
|
|
472
|
+
* Be aware that this utility is not restricted to `application/json` and will parse `application/x-www-form-urlencoded` content types.
|
|
473
|
+
* Because of this, authenticated `GET`/`POST` handlers may be at risk of a [CSRF](https://owasp.org/www-community/attacks/csrf) attack, and must check the `content-type` header manually.
|
|
474
|
+
*
|
|
473
475
|
* @example
|
|
474
476
|
* export default defineEventHandler(async (event) => {
|
|
475
477
|
* const body = await readBody(event);
|
|
@@ -510,7 +512,7 @@ declare function readBody<T, Event extends H3Event = H3Event, _T = InferEventInp
|
|
|
510
512
|
*/
|
|
511
513
|
declare function readValidatedBody<T, Event extends H3Event = H3Event, _T = InferEventInput<"body", Event, T>>(event: Event, validate: ValidateFunction<_T>): Promise<_T>;
|
|
512
514
|
/**
|
|
513
|
-
* Tries to read and parse the body of
|
|
515
|
+
* Tries to read and parse the body of an H3Event as multipart form.
|
|
514
516
|
*
|
|
515
517
|
* @example
|
|
516
518
|
* export default defineEventHandler(async (event) => {
|
|
@@ -612,7 +614,7 @@ interface H3CorsOptions {
|
|
|
612
614
|
declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
|
|
613
615
|
|
|
614
616
|
/**
|
|
615
|
-
* Get query
|
|
617
|
+
* Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
|
|
616
618
|
*
|
|
617
619
|
* @example
|
|
618
620
|
* export default defineEventHandler((event) => {
|
|
@@ -621,7 +623,7 @@ declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
|
|
|
621
623
|
*/
|
|
622
624
|
declare function getQuery<T, Event extends H3Event = H3Event, _T = Exclude<InferEventInput<"query", Event, T>, undefined>>(event: Event): _T;
|
|
623
625
|
/**
|
|
624
|
-
* Get the query
|
|
626
|
+
* Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
|
|
625
627
|
*
|
|
626
628
|
* You can use a simple function to validate the query object or a library like `zod` to define a schema.
|
|
627
629
|
*
|
|
@@ -793,7 +795,7 @@ declare function getRequestProtocol(event: H3Event, opts?: {
|
|
|
793
795
|
/** @deprecated Use `event.path` instead */
|
|
794
796
|
declare function getRequestPath(event: H3Event): string;
|
|
795
797
|
/**
|
|
796
|
-
*
|
|
798
|
+
* Generate the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
|
|
797
799
|
*
|
|
798
800
|
* If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
|
|
799
801
|
*
|
|
@@ -817,7 +819,9 @@ declare function toWebRequest(event: H3Event): Request;
|
|
|
817
819
|
/**
|
|
818
820
|
* Try to get the client IP address from the incoming request.
|
|
819
821
|
*
|
|
820
|
-
* 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.
|
|
821
825
|
*
|
|
822
826
|
* If IP cannot be determined, it will default to `undefined`.
|
|
823
827
|
*
|
|
@@ -827,11 +831,6 @@ declare function toWebRequest(event: H3Event): Request;
|
|
|
827
831
|
* });
|
|
828
832
|
*/
|
|
829
833
|
declare function getRequestIP(event: H3Event, opts?: {
|
|
830
|
-
/**
|
|
831
|
-
* Use the X-Forwarded-For HTTP header set by proxies.
|
|
832
|
-
*
|
|
833
|
-
* Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
|
|
834
|
-
*/
|
|
835
834
|
xForwardedFor?: boolean;
|
|
836
835
|
}): string | undefined;
|
|
837
836
|
|
|
@@ -853,7 +852,7 @@ declare function appendCorsPreflightHeaders(event: H3Event, options: H3CorsOptio
|
|
|
853
852
|
declare function appendCorsHeaders(event: H3Event, options: H3CorsOptions): void;
|
|
854
853
|
|
|
855
854
|
/**
|
|
856
|
-
* Parse the request to get HTTP Cookie header string and
|
|
855
|
+
* Parse the request to get HTTP Cookie header string and return an object of all cookie name-value pairs.
|
|
857
856
|
* @param event {H3Event} H3 event or req passed by h3 handler
|
|
858
857
|
* @returns Object of cookie name-value pairs
|
|
859
858
|
* ```ts
|
|
@@ -954,7 +953,9 @@ declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions):
|
|
|
954
953
|
/**
|
|
955
954
|
* Get the request headers object without headers known to cause issues when proxying.
|
|
956
955
|
*/
|
|
957
|
-
declare function getProxyRequestHeaders(event: H3Event
|
|
956
|
+
declare function getProxyRequestHeaders(event: H3Event, opts?: {
|
|
957
|
+
host?: boolean;
|
|
958
|
+
}): any;
|
|
958
959
|
/**
|
|
959
960
|
* Make a fetch request with the event's context and headers.
|
|
960
961
|
*/
|
|
@@ -976,7 +977,7 @@ type IteratorSerializer<Value> = (value: Value) => SendableValue | undefined;
|
|
|
976
977
|
*/
|
|
977
978
|
declare function send(event: H3Event, data?: any, type?: MimeType): Promise<void>;
|
|
978
979
|
/**
|
|
979
|
-
* Respond with an empty payload
|
|
980
|
+
* Respond with an empty payload.
|
|
980
981
|
*
|
|
981
982
|
* Note that calling this function will close the connection and no other data can be sent to the client afterwards.
|
|
982
983
|
*
|
|
@@ -1056,7 +1057,7 @@ declare function sendRedirect(event: H3Event, location: string, code?: StatusCod
|
|
|
1056
1057
|
*/
|
|
1057
1058
|
declare function getResponseHeaders(event: H3Event): ReturnType<H3Event["node"]["res"]["getHeaders"]>;
|
|
1058
1059
|
/**
|
|
1059
|
-
*
|
|
1060
|
+
* Get a response header by name.
|
|
1060
1061
|
*
|
|
1061
1062
|
* @example
|
|
1062
1063
|
* export default defineEventHandler((event) => {
|
|
@@ -1144,7 +1145,7 @@ declare function clearResponseHeaders(event: H3Event, headerNames?: HTTPHeaderNa
|
|
|
1144
1145
|
*/
|
|
1145
1146
|
declare function removeResponseHeader(event: H3Event, name: HTTPHeaderName): void;
|
|
1146
1147
|
/**
|
|
1147
|
-
* Checks if the data is a stream
|
|
1148
|
+
* Checks if the data is a stream (Node.js Readable Stream, React Pipeable Stream, or Web Stream).
|
|
1148
1149
|
*/
|
|
1149
1150
|
declare function isStream(data: any): data is Readable | ReadableStream;
|
|
1150
1151
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ declare class H3Event<_RequestT extends EventHandlerRequest = EventHandlerReques
|
|
|
48
48
|
toJSON(): string;
|
|
49
49
|
/** @deprecated Please use `event.node.req` instead. */
|
|
50
50
|
get req(): IncomingMessage & {
|
|
51
|
-
originalUrl?: string
|
|
51
|
+
originalUrl?: string;
|
|
52
52
|
};
|
|
53
53
|
/** @deprecated Please use `event.node.res` instead. */
|
|
54
54
|
get res(): ServerResponse<IncomingMessage>;
|
|
@@ -93,7 +93,7 @@ declare const lazyEventHandler: typeof defineLazyEventHandler;
|
|
|
93
93
|
* https://developer.mozilla.org/en-US/docs/Web/API/Headers
|
|
94
94
|
*/
|
|
95
95
|
declare const H3Headers: {
|
|
96
|
-
new (init?: HeadersInit
|
|
96
|
+
new (init?: HeadersInit): Headers;
|
|
97
97
|
prototype: Headers;
|
|
98
98
|
};
|
|
99
99
|
/**
|
|
@@ -101,11 +101,11 @@ declare const H3Headers: {
|
|
|
101
101
|
* https://developer.mozilla.org/en-US/docs/Web/API/Response
|
|
102
102
|
*/
|
|
103
103
|
declare const H3Response: {
|
|
104
|
-
new (body?: BodyInit | null
|
|
104
|
+
new (body?: BodyInit | null, init?: ResponseInit): Response;
|
|
105
105
|
prototype: Response;
|
|
106
106
|
error(): Response;
|
|
107
|
-
json(data: any, init?: ResponseInit
|
|
108
|
-
redirect(url: string | URL, status?: number
|
|
107
|
+
json(data: any, init?: ResponseInit): Response;
|
|
108
|
+
redirect(url: string | URL, status?: number): Response;
|
|
109
109
|
};
|
|
110
110
|
|
|
111
111
|
type SessionDataT = Record<string, any>;
|
|
@@ -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
|
|
144
|
-
clear: () => Promise
|
|
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.
|
|
@@ -470,6 +469,9 @@ declare function readRawBody<E extends Encoding = "utf8">(event: H3Event, encodi
|
|
|
470
469
|
/**
|
|
471
470
|
* Reads request body and tries to safely parse using [destr](https://github.com/unjs/destr).
|
|
472
471
|
*
|
|
472
|
+
* Be aware that this utility is not restricted to `application/json` and will parse `application/x-www-form-urlencoded` content types.
|
|
473
|
+
* Because of this, authenticated `GET`/`POST` handlers may be at risk of a [CSRF](https://owasp.org/www-community/attacks/csrf) attack, and must check the `content-type` header manually.
|
|
474
|
+
*
|
|
473
475
|
* @example
|
|
474
476
|
* export default defineEventHandler(async (event) => {
|
|
475
477
|
* const body = await readBody(event);
|
|
@@ -510,7 +512,7 @@ declare function readBody<T, Event extends H3Event = H3Event, _T = InferEventInp
|
|
|
510
512
|
*/
|
|
511
513
|
declare function readValidatedBody<T, Event extends H3Event = H3Event, _T = InferEventInput<"body", Event, T>>(event: Event, validate: ValidateFunction<_T>): Promise<_T>;
|
|
512
514
|
/**
|
|
513
|
-
* Tries to read and parse the body of
|
|
515
|
+
* Tries to read and parse the body of an H3Event as multipart form.
|
|
514
516
|
*
|
|
515
517
|
* @example
|
|
516
518
|
* export default defineEventHandler(async (event) => {
|
|
@@ -612,7 +614,7 @@ interface H3CorsOptions {
|
|
|
612
614
|
declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
|
|
613
615
|
|
|
614
616
|
/**
|
|
615
|
-
* Get query
|
|
617
|
+
* Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
|
|
616
618
|
*
|
|
617
619
|
* @example
|
|
618
620
|
* export default defineEventHandler((event) => {
|
|
@@ -621,7 +623,7 @@ declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
|
|
|
621
623
|
*/
|
|
622
624
|
declare function getQuery<T, Event extends H3Event = H3Event, _T = Exclude<InferEventInput<"query", Event, T>, undefined>>(event: Event): _T;
|
|
623
625
|
/**
|
|
624
|
-
* Get the query
|
|
626
|
+
* Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
|
|
625
627
|
*
|
|
626
628
|
* You can use a simple function to validate the query object or a library like `zod` to define a schema.
|
|
627
629
|
*
|
|
@@ -793,7 +795,7 @@ declare function getRequestProtocol(event: H3Event, opts?: {
|
|
|
793
795
|
/** @deprecated Use `event.path` instead */
|
|
794
796
|
declare function getRequestPath(event: H3Event): string;
|
|
795
797
|
/**
|
|
796
|
-
*
|
|
798
|
+
* Generate the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
|
|
797
799
|
*
|
|
798
800
|
* If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
|
|
799
801
|
*
|
|
@@ -817,7 +819,9 @@ declare function toWebRequest(event: H3Event): Request;
|
|
|
817
819
|
/**
|
|
818
820
|
* Try to get the client IP address from the incoming request.
|
|
819
821
|
*
|
|
820
|
-
* 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.
|
|
821
825
|
*
|
|
822
826
|
* If IP cannot be determined, it will default to `undefined`.
|
|
823
827
|
*
|
|
@@ -827,11 +831,6 @@ declare function toWebRequest(event: H3Event): Request;
|
|
|
827
831
|
* });
|
|
828
832
|
*/
|
|
829
833
|
declare function getRequestIP(event: H3Event, opts?: {
|
|
830
|
-
/**
|
|
831
|
-
* Use the X-Forwarded-For HTTP header set by proxies.
|
|
832
|
-
*
|
|
833
|
-
* Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
|
|
834
|
-
*/
|
|
835
834
|
xForwardedFor?: boolean;
|
|
836
835
|
}): string | undefined;
|
|
837
836
|
|
|
@@ -853,7 +852,7 @@ declare function appendCorsPreflightHeaders(event: H3Event, options: H3CorsOptio
|
|
|
853
852
|
declare function appendCorsHeaders(event: H3Event, options: H3CorsOptions): void;
|
|
854
853
|
|
|
855
854
|
/**
|
|
856
|
-
* Parse the request to get HTTP Cookie header string and
|
|
855
|
+
* Parse the request to get HTTP Cookie header string and return an object of all cookie name-value pairs.
|
|
857
856
|
* @param event {H3Event} H3 event or req passed by h3 handler
|
|
858
857
|
* @returns Object of cookie name-value pairs
|
|
859
858
|
* ```ts
|
|
@@ -954,7 +953,9 @@ declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions):
|
|
|
954
953
|
/**
|
|
955
954
|
* Get the request headers object without headers known to cause issues when proxying.
|
|
956
955
|
*/
|
|
957
|
-
declare function getProxyRequestHeaders(event: H3Event
|
|
956
|
+
declare function getProxyRequestHeaders(event: H3Event, opts?: {
|
|
957
|
+
host?: boolean;
|
|
958
|
+
}): any;
|
|
958
959
|
/**
|
|
959
960
|
* Make a fetch request with the event's context and headers.
|
|
960
961
|
*/
|
|
@@ -976,7 +977,7 @@ type IteratorSerializer<Value> = (value: Value) => SendableValue | undefined;
|
|
|
976
977
|
*/
|
|
977
978
|
declare function send(event: H3Event, data?: any, type?: MimeType): Promise<void>;
|
|
978
979
|
/**
|
|
979
|
-
* Respond with an empty payload
|
|
980
|
+
* Respond with an empty payload.
|
|
980
981
|
*
|
|
981
982
|
* Note that calling this function will close the connection and no other data can be sent to the client afterwards.
|
|
982
983
|
*
|
|
@@ -1056,7 +1057,7 @@ declare function sendRedirect(event: H3Event, location: string, code?: StatusCod
|
|
|
1056
1057
|
*/
|
|
1057
1058
|
declare function getResponseHeaders(event: H3Event): ReturnType<H3Event["node"]["res"]["getHeaders"]>;
|
|
1058
1059
|
/**
|
|
1059
|
-
*
|
|
1060
|
+
* Get a response header by name.
|
|
1060
1061
|
*
|
|
1061
1062
|
* @example
|
|
1062
1063
|
* export default defineEventHandler((event) => {
|
|
@@ -1144,7 +1145,7 @@ declare function clearResponseHeaders(event: H3Event, headerNames?: HTTPHeaderNa
|
|
|
1144
1145
|
*/
|
|
1145
1146
|
declare function removeResponseHeader(event: H3Event, name: HTTPHeaderName): void;
|
|
1146
1147
|
/**
|
|
1147
|
-
* Checks if the data is a stream
|
|
1148
|
+
* Checks if the data is a stream (Node.js Readable Stream, React Pipeable Stream, or Web Stream).
|
|
1148
1149
|
*/
|
|
1149
1150
|
declare function isStream(data: any): data is Readable | ReadableStream;
|
|
1150
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);
|
|
@@ -407,6 +401,9 @@ function readRawBody(event, encoding = "utf8") {
|
|
|
407
401
|
if (_resolved.constructor === Object) {
|
|
408
402
|
return Buffer.from(JSON.stringify(_resolved));
|
|
409
403
|
}
|
|
404
|
+
if (_resolved instanceof URLSearchParams) {
|
|
405
|
+
return Buffer.from(_resolved.toString());
|
|
406
|
+
}
|
|
410
407
|
return Buffer.from(_resolved);
|
|
411
408
|
});
|
|
412
409
|
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
|
|
@@ -664,7 +661,7 @@ function splitCookiesString(cookiesString) {
|
|
|
664
661
|
}
|
|
665
662
|
}
|
|
666
663
|
if (!cookiesSeparatorFound || pos >= cookiesString.length) {
|
|
667
|
-
cookiesStrings.push(cookiesString.slice(start
|
|
664
|
+
cookiesStrings.push(cookiesString.slice(start));
|
|
668
665
|
}
|
|
669
666
|
}
|
|
670
667
|
return cookiesStrings;
|
|
@@ -1120,6 +1117,7 @@ async function getRequestFingerprint(event, opts = {}) {
|
|
|
1120
1117
|
const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
|
|
1121
1118
|
const ignoredHeaders = /* @__PURE__ */ new Set([
|
|
1122
1119
|
"transfer-encoding",
|
|
1120
|
+
"accept-encoding",
|
|
1123
1121
|
"connection",
|
|
1124
1122
|
"keep-alive",
|
|
1125
1123
|
"upgrade",
|
|
@@ -1140,7 +1138,7 @@ async function proxyRequest(event, target, opts = {}) {
|
|
|
1140
1138
|
}
|
|
1141
1139
|
const method = opts.fetchOptions?.method || event.method;
|
|
1142
1140
|
const fetchHeaders = mergeHeaders(
|
|
1143
|
-
getProxyRequestHeaders(event),
|
|
1141
|
+
getProxyRequestHeaders(event, { host: target.startsWith("/") }),
|
|
1144
1142
|
opts.fetchOptions?.headers,
|
|
1145
1143
|
opts.headers
|
|
1146
1144
|
);
|
|
@@ -1232,11 +1230,11 @@ async function sendProxy(event, target, opts = {}) {
|
|
|
1232
1230
|
}
|
|
1233
1231
|
return event.node.res.end();
|
|
1234
1232
|
}
|
|
1235
|
-
function getProxyRequestHeaders(event) {
|
|
1233
|
+
function getProxyRequestHeaders(event, opts) {
|
|
1236
1234
|
const headers = /* @__PURE__ */ Object.create(null);
|
|
1237
1235
|
const reqHeaders = getRequestHeaders(event);
|
|
1238
1236
|
for (const name in reqHeaders) {
|
|
1239
|
-
if (!ignoredHeaders.has(name)) {
|
|
1237
|
+
if (!ignoredHeaders.has(name) || name === "host" && opts?.host) {
|
|
1240
1238
|
headers[name] = reqHeaders[name];
|
|
1241
1239
|
}
|
|
1242
1240
|
}
|
|
@@ -1247,7 +1245,9 @@ function fetchWithEvent(event, req, init, options) {
|
|
|
1247
1245
|
...init,
|
|
1248
1246
|
context: init?.context || event.context,
|
|
1249
1247
|
headers: {
|
|
1250
|
-
...getProxyRequestHeaders(event
|
|
1248
|
+
...getProxyRequestHeaders(event, {
|
|
1249
|
+
host: typeof req === "string" && req.startsWith("/")
|
|
1250
|
+
}),
|
|
1251
1251
|
...init?.headers
|
|
1252
1252
|
}
|
|
1253
1253
|
});
|
|
@@ -1469,23 +1469,17 @@ function isHttp2Request(event) {
|
|
|
1469
1469
|
return getHeader(event, ":path") !== void 0 && getHeader(event, ":method") !== void 0;
|
|
1470
1470
|
}
|
|
1471
1471
|
|
|
1472
|
-
var __defProp$1 = Object.defineProperty;
|
|
1473
|
-
var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1474
|
-
var __publicField$1 = (obj, key, value) => {
|
|
1475
|
-
__defNormalProp$1(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1476
|
-
return value;
|
|
1477
|
-
};
|
|
1478
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;
|
|
1479
1482
|
constructor(event, opts = {}) {
|
|
1480
|
-
__publicField$1(this, "_h3Event");
|
|
1481
|
-
__publicField$1(this, "_transformStream", new TransformStream());
|
|
1482
|
-
__publicField$1(this, "_writer");
|
|
1483
|
-
__publicField$1(this, "_encoder", new TextEncoder());
|
|
1484
|
-
__publicField$1(this, "_writerIsClosed", false);
|
|
1485
|
-
__publicField$1(this, "_paused", false);
|
|
1486
|
-
__publicField$1(this, "_unsentData");
|
|
1487
|
-
__publicField$1(this, "_disposed", false);
|
|
1488
|
-
__publicField$1(this, "_handled", false);
|
|
1489
1483
|
this._h3Event = event;
|
|
1490
1484
|
this._writer = this._transformStream.writable.getWriter();
|
|
1491
1485
|
this._writer.closed.then(() => {
|
|
@@ -1712,32 +1706,26 @@ function defineWebSocketHandler(hooks) {
|
|
|
1712
1706
|
});
|
|
1713
1707
|
}
|
|
1714
1708
|
|
|
1715
|
-
var __defProp = Object.defineProperty;
|
|
1716
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
1717
|
-
var __publicField = (obj, key, value) => {
|
|
1718
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
1719
|
-
return value;
|
|
1720
|
-
};
|
|
1721
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;
|
|
1722
1728
|
constructor(req, res) {
|
|
1723
|
-
__publicField(this, "__is_event__", true);
|
|
1724
|
-
// Context
|
|
1725
|
-
__publicField(this, "node");
|
|
1726
|
-
// Node
|
|
1727
|
-
__publicField(this, "web");
|
|
1728
|
-
// Web
|
|
1729
|
-
__publicField(this, "context", {});
|
|
1730
|
-
// Shared
|
|
1731
|
-
// Request
|
|
1732
|
-
__publicField(this, "_method");
|
|
1733
|
-
__publicField(this, "_path");
|
|
1734
|
-
__publicField(this, "_headers");
|
|
1735
|
-
__publicField(this, "_requestBody");
|
|
1736
|
-
// Response
|
|
1737
|
-
__publicField(this, "_handled", false);
|
|
1738
|
-
// Hooks
|
|
1739
|
-
__publicField(this, "_onBeforeResponseCalled");
|
|
1740
|
-
__publicField(this, "_onAfterResponseCalled");
|
|
1741
1729
|
this.node = { req, res };
|
|
1742
1730
|
}
|
|
1743
1731
|
// --- Request ---
|
|
@@ -2107,7 +2095,8 @@ function websocketOptions(evResolver, appOptions) {
|
|
|
2107
2095
|
return {
|
|
2108
2096
|
...appOptions.websocket,
|
|
2109
2097
|
async resolve(info) {
|
|
2110
|
-
const
|
|
2098
|
+
const url = info.request?.url || info.url || "/";
|
|
2099
|
+
const { pathname } = typeof url === "string" ? parseURL(url) : url;
|
|
2111
2100
|
const resolved = await evResolver(pathname);
|
|
2112
2101
|
return resolved?.handler?.__websocket__ || {};
|
|
2113
2102
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "h3",
|
|
3
|
-
"version": "1.
|
|
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",
|
|
@@ -19,54 +19,58 @@
|
|
|
19
19
|
"files": [
|
|
20
20
|
"dist"
|
|
21
21
|
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "unbuild",
|
|
24
|
+
"dev": "vitest",
|
|
25
|
+
"lint": "eslint --cache . && prettier -c src test playground examples docs",
|
|
26
|
+
"lint:fix": "eslint --cache . --fix && prettier -c src test playground examples docs -w",
|
|
27
|
+
"play": "listhen -w ./playground/app.ts",
|
|
28
|
+
"profile": "0x -o -D .profile -P 'autocannon -c 100 -p 10 -d 40 http://localhost:$PORT' ./playground/server.cjs",
|
|
29
|
+
"release": "pnpm test && pnpm build && changelogen --release --publish --publishTag latest && git push --follow-tags",
|
|
30
|
+
"test": "pnpm lint && vitest --run --coverage"
|
|
31
|
+
},
|
|
32
|
+
"resolutions": {
|
|
33
|
+
"h3": "link:."
|
|
34
|
+
},
|
|
22
35
|
"dependencies": {
|
|
23
|
-
"cookie-es": "^1.
|
|
24
|
-
"crossws": "^0.
|
|
36
|
+
"cookie-es": "^1.2.2",
|
|
37
|
+
"crossws": "^0.3.1",
|
|
25
38
|
"defu": "^6.1.4",
|
|
26
39
|
"destr": "^2.0.3",
|
|
27
|
-
"iron-webcrypto": "^1.
|
|
28
|
-
"ohash": "^1.1.
|
|
40
|
+
"iron-webcrypto": "^1.2.1",
|
|
41
|
+
"ohash": "^1.1.4",
|
|
29
42
|
"radix3": "^1.1.2",
|
|
30
|
-
"ufo": "^1.5.
|
|
43
|
+
"ufo": "^1.5.4",
|
|
31
44
|
"uncrypto": "^0.1.3",
|
|
32
|
-
"unenv": "^1.
|
|
45
|
+
"unenv": "^1.10.0"
|
|
33
46
|
},
|
|
34
47
|
"devDependencies": {
|
|
35
|
-
"0x": "^5.
|
|
36
|
-
"@types/express": "^
|
|
37
|
-
"@types/node": "^
|
|
48
|
+
"0x": "^5.8.0",
|
|
49
|
+
"@types/express": "^5.0.0",
|
|
50
|
+
"@types/node": "^22.10.5",
|
|
38
51
|
"@types/supertest": "^6.0.2",
|
|
39
|
-
"@vitest/coverage-v8": "^1.
|
|
40
|
-
"autocannon": "^
|
|
41
|
-
"automd": "^0.3.
|
|
42
|
-
"changelogen": "^0.5.
|
|
52
|
+
"@vitest/coverage-v8": "^2.1.8",
|
|
53
|
+
"autocannon": "^8.0.0",
|
|
54
|
+
"automd": "^0.3.12",
|
|
55
|
+
"changelogen": "^0.5.7",
|
|
43
56
|
"connect": "^3.7.0",
|
|
44
|
-
"eslint": "^9.
|
|
45
|
-
"eslint-config-unjs": "^0.
|
|
46
|
-
"express": "^4.
|
|
57
|
+
"eslint": "^9.17.0",
|
|
58
|
+
"eslint-config-unjs": "^0.4.2",
|
|
59
|
+
"express": "^4.21.2",
|
|
47
60
|
"get-port": "^7.1.0",
|
|
48
|
-
"
|
|
49
|
-
"
|
|
61
|
+
"h3": "^1.13.0",
|
|
62
|
+
"jiti": "^2.4.2",
|
|
63
|
+
"listhen": "^1.9.0",
|
|
50
64
|
"node-fetch-native": "^1.6.4",
|
|
51
|
-
"prettier": "^3.2
|
|
52
|
-
"react": "^
|
|
53
|
-
"react-dom": "^
|
|
65
|
+
"prettier": "^3.4.2",
|
|
66
|
+
"react": "^19.0.0",
|
|
67
|
+
"react-dom": "^19.0.0",
|
|
54
68
|
"supertest": "^7.0.0",
|
|
55
|
-
"typescript": "^5.
|
|
56
|
-
"unbuild": "^2.0
|
|
57
|
-
"undici": "^
|
|
58
|
-
"vitest": "^1.
|
|
59
|
-
"zod": "^3.
|
|
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"
|
|
60
74
|
},
|
|
61
|
-
"
|
|
62
|
-
|
|
63
|
-
"dev": "vitest",
|
|
64
|
-
"lint": "eslint --cache . && prettier -c src test playground examples docs",
|
|
65
|
-
"lint:fix": "eslint --cache . --fix && prettier -c src test playground examples docs -w",
|
|
66
|
-
"play": "listhen -w ./playground/app.ts",
|
|
67
|
-
"profile": "0x -o -D .profile -P 'autocannon -c 100 -p 10 -d 40 http://localhost:$PORT' ./playground/server.cjs",
|
|
68
|
-
"release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags",
|
|
69
|
-
"release-rc": "pnpm test && pnpm build && changelogen --release --prerelease rc --push --publish --publishTag rc",
|
|
70
|
-
"test": "pnpm lint && vitest --run --coverage"
|
|
71
|
-
}
|
|
72
|
-
}
|
|
75
|
+
"packageManager": "pnpm@9.15.3"
|
|
76
|
+
}
|