h3 1.13.0 → 1.14.0
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 +98 -88
- package/dist/index.d.cts +30 -24
- package/dist/index.d.mts +30 -24
- package/dist/index.d.ts +30 -24
- package/dist/index.mjs +98 -88
- package/package.json +22 -22
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
|
}
|
|
@@ -68,13 +63,12 @@ class H3Error extends Error {
|
|
|
68
63
|
if (this.statusMessage) {
|
|
69
64
|
obj.statusMessage = sanitizeStatusMessage(this.statusMessage);
|
|
70
65
|
}
|
|
71
|
-
if (this.data !==
|
|
66
|
+
if (this.data !== undefined) {
|
|
72
67
|
obj.data = this.data;
|
|
73
68
|
}
|
|
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);
|
|
@@ -121,10 +115,10 @@ function createError(input) {
|
|
|
121
115
|
);
|
|
122
116
|
}
|
|
123
117
|
}
|
|
124
|
-
if (input.fatal !==
|
|
118
|
+
if (input.fatal !== undefined) {
|
|
125
119
|
err.fatal = input.fatal;
|
|
126
120
|
}
|
|
127
|
-
if (input.unhandled !==
|
|
121
|
+
if (input.unhandled !== undefined) {
|
|
128
122
|
err.unhandled = input.unhandled;
|
|
129
123
|
}
|
|
130
124
|
return err;
|
|
@@ -149,7 +143,7 @@ function sendError(event, error, debug) {
|
|
|
149
143
|
const _code = Number.parseInt(h3Error.statusCode);
|
|
150
144
|
setResponseStatus(event, _code, h3Error.statusMessage);
|
|
151
145
|
event.node.res.setHeader("content-type", MIMES.json);
|
|
152
|
-
event.node.res.end(JSON.stringify(responseBody,
|
|
146
|
+
event.node.res.end(JSON.stringify(responseBody, undefined, 2));
|
|
153
147
|
}
|
|
154
148
|
function isError(input) {
|
|
155
149
|
return input?.constructor?.__h3_error__ === true;
|
|
@@ -422,7 +416,7 @@ function readRawBody(event, encoding = "utf8") {
|
|
|
422
416
|
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
|
|
423
417
|
}
|
|
424
418
|
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")) {
|
|
425
|
-
return Promise.resolve(
|
|
419
|
+
return Promise.resolve(undefined);
|
|
426
420
|
}
|
|
427
421
|
const promise = event.node.req[RawBodySymbol] = new Promise(
|
|
428
422
|
(resolve, reject) => {
|
|
@@ -517,7 +511,7 @@ function getRequestWebStream(event) {
|
|
|
517
511
|
}
|
|
518
512
|
function _parseJSON(body = "", strict) {
|
|
519
513
|
if (!body) {
|
|
520
|
-
return
|
|
514
|
+
return undefined;
|
|
521
515
|
}
|
|
522
516
|
try {
|
|
523
517
|
return destr__default(body, { strict });
|
|
@@ -548,7 +542,7 @@ function _parseURLEncodedBody(body) {
|
|
|
548
542
|
function handleCacheHeaders(event, opts) {
|
|
549
543
|
const cacheControls = ["public", ...opts.cacheControls || []];
|
|
550
544
|
let cacheMatched = false;
|
|
551
|
-
if (opts.maxAge !==
|
|
545
|
+
if (opts.maxAge !== undefined) {
|
|
552
546
|
cacheControls.push(`max-age=${+opts.maxAge}`, `s-maxage=${+opts.maxAge}`);
|
|
553
547
|
}
|
|
554
548
|
if (opts.modifiedTime) {
|
|
@@ -693,7 +687,7 @@ function serializeIterableValue(value) {
|
|
|
693
687
|
}
|
|
694
688
|
case "function":
|
|
695
689
|
case "undefined": {
|
|
696
|
-
return
|
|
690
|
+
return undefined;
|
|
697
691
|
}
|
|
698
692
|
case "object": {
|
|
699
693
|
if (value instanceof Uint8Array) {
|
|
@@ -966,9 +960,9 @@ function sendIterable(event, iterable, options) {
|
|
|
966
960
|
new ReadableStream({
|
|
967
961
|
async pull(controller) {
|
|
968
962
|
const { value, done } = await iterator.next();
|
|
969
|
-
if (value !==
|
|
963
|
+
if (value !== undefined) {
|
|
970
964
|
const chunk = serializer(value);
|
|
971
|
-
if (chunk !==
|
|
965
|
+
if (chunk !== undefined) {
|
|
972
966
|
controller.enqueue(chunk);
|
|
973
967
|
}
|
|
974
968
|
}
|
|
@@ -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",
|
|
@@ -1145,12 +1140,12 @@ async function proxyRequest(event, target, opts = {}) {
|
|
|
1145
1140
|
body = getRequestWebStream(event);
|
|
1146
1141
|
duplex = "half";
|
|
1147
1142
|
} else {
|
|
1148
|
-
body = await readRawBody(event, false).catch(() =>
|
|
1143
|
+
body = await readRawBody(event, false).catch(() => undefined);
|
|
1149
1144
|
}
|
|
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
|
);
|
|
@@ -1225,7 +1220,7 @@ async function sendProxy(event, target, opts = {}) {
|
|
|
1225
1220
|
if (opts.onResponse) {
|
|
1226
1221
|
await opts.onResponse(event, response);
|
|
1227
1222
|
}
|
|
1228
|
-
if (response._data !==
|
|
1223
|
+
if (response._data !== undefined) {
|
|
1229
1224
|
return response._data;
|
|
1230
1225
|
}
|
|
1231
1226
|
if (event.handled) {
|
|
@@ -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
|
});
|
|
@@ -1298,7 +1295,7 @@ function mergeHeaders(defaults, ...inputs) {
|
|
|
1298
1295
|
const merged = new Headers(defaults);
|
|
1299
1296
|
for (const input of _inputs) {
|
|
1300
1297
|
for (const [key, value] of Object.entries(input)) {
|
|
1301
|
-
if (value !==
|
|
1298
|
+
if (value !== undefined) {
|
|
1302
1299
|
merged.set(key, value);
|
|
1303
1300
|
}
|
|
1304
1301
|
}
|
|
@@ -1324,10 +1321,16 @@ async function useSession(event, config) {
|
|
|
1324
1321
|
return event.context.sessions?.[sessionName]?.data || {};
|
|
1325
1322
|
},
|
|
1326
1323
|
update: async (update) => {
|
|
1324
|
+
if (!isEvent(event)) {
|
|
1325
|
+
throw new Error("[h3] Cannot update read-only session.");
|
|
1326
|
+
}
|
|
1327
1327
|
await updateSession(event, config, update);
|
|
1328
1328
|
return sessionManager;
|
|
1329
1329
|
},
|
|
1330
1330
|
clear: () => {
|
|
1331
|
+
if (!isEvent(event)) {
|
|
1332
|
+
throw new Error("[h3] Cannot clear read-only session.");
|
|
1333
|
+
}
|
|
1331
1334
|
clearSession(event, config);
|
|
1332
1335
|
return Promise.resolve(sessionManager);
|
|
1333
1336
|
}
|
|
@@ -1352,13 +1355,16 @@ async function getSession(event, config) {
|
|
|
1352
1355
|
let sealedSession;
|
|
1353
1356
|
if (config.sessionHeader !== false) {
|
|
1354
1357
|
const headerName = typeof config.sessionHeader === "string" ? config.sessionHeader.toLowerCase() : `x-${sessionName.toLowerCase()}-session`;
|
|
1355
|
-
const headerValue = event
|
|
1358
|
+
const headerValue = _getReqHeader(event, headerName);
|
|
1356
1359
|
if (typeof headerValue === "string") {
|
|
1357
1360
|
sealedSession = headerValue;
|
|
1358
1361
|
}
|
|
1359
1362
|
}
|
|
1360
1363
|
if (!sealedSession) {
|
|
1361
|
-
|
|
1364
|
+
const cookieHeader = _getReqHeader(event, "cookie");
|
|
1365
|
+
if (cookieHeader) {
|
|
1366
|
+
sealedSession = cookieEs.parse(cookieHeader + "")[sessionName];
|
|
1367
|
+
}
|
|
1362
1368
|
}
|
|
1363
1369
|
if (sealedSession) {
|
|
1364
1370
|
const promise = unsealSession(event, config, sealedSession).catch(() => {
|
|
@@ -1371,12 +1377,28 @@ async function getSession(event, config) {
|
|
|
1371
1377
|
await promise;
|
|
1372
1378
|
}
|
|
1373
1379
|
if (!session.id) {
|
|
1380
|
+
if (!isEvent(event)) {
|
|
1381
|
+
throw new Error(
|
|
1382
|
+
"Cannot initialize a new session. Make sure using `useSession(event)` in main handler."
|
|
1383
|
+
);
|
|
1384
|
+
}
|
|
1374
1385
|
session.id = config.generateId?.() ?? (config.crypto || crypto__default).randomUUID();
|
|
1375
1386
|
session.createdAt = Date.now();
|
|
1376
1387
|
await updateSession(event, config);
|
|
1377
1388
|
}
|
|
1378
1389
|
return session;
|
|
1379
1390
|
}
|
|
1391
|
+
function _getReqHeader(event, name) {
|
|
1392
|
+
if (event.node) {
|
|
1393
|
+
return event.node?.req.headers[name];
|
|
1394
|
+
}
|
|
1395
|
+
if (event.request) {
|
|
1396
|
+
return event.request.headers?.get(name);
|
|
1397
|
+
}
|
|
1398
|
+
if (event.headers) {
|
|
1399
|
+
return event.headers.get(name);
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1380
1402
|
async function updateSession(event, config, update) {
|
|
1381
1403
|
const sessionName = config.name || DEFAULT_NAME;
|
|
1382
1404
|
const session = event.context.sessions?.[sessionName] || await getSession(event, config);
|
|
@@ -1390,7 +1412,7 @@ async function updateSession(event, config, update) {
|
|
|
1390
1412
|
const sealed = await sealSession(event, config);
|
|
1391
1413
|
setCookie(event, sessionName, sealed, {
|
|
1392
1414
|
...DEFAULT_COOKIE,
|
|
1393
|
-
expires: config.maxAge ? new Date(session.createdAt + config.maxAge * 1e3) :
|
|
1415
|
+
expires: config.maxAge ? new Date(session.createdAt + config.maxAge * 1e3) : undefined,
|
|
1394
1416
|
...config.cookie
|
|
1395
1417
|
});
|
|
1396
1418
|
}
|
|
@@ -1476,26 +1498,20 @@ function setEventStreamHeaders(event) {
|
|
|
1476
1498
|
setResponseHeaders(event, headers);
|
|
1477
1499
|
}
|
|
1478
1500
|
function isHttp2Request(event) {
|
|
1479
|
-
return getHeader(event, ":path") !==
|
|
1501
|
+
return getHeader(event, ":path") !== undefined && getHeader(event, ":method") !== undefined;
|
|
1480
1502
|
}
|
|
1481
1503
|
|
|
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
1504
|
class EventStream {
|
|
1505
|
+
_h3Event;
|
|
1506
|
+
_transformStream = new TransformStream();
|
|
1507
|
+
_writer;
|
|
1508
|
+
_encoder = new TextEncoder();
|
|
1509
|
+
_writerIsClosed = false;
|
|
1510
|
+
_paused = false;
|
|
1511
|
+
_unsentData;
|
|
1512
|
+
_disposed = false;
|
|
1513
|
+
_handled = false;
|
|
1489
1514
|
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
1515
|
this._h3Event = event;
|
|
1500
1516
|
this._writer = this._transformStream.writable.getWriter();
|
|
1501
1517
|
this._writer.closed.then(() => {
|
|
@@ -1572,7 +1588,7 @@ class EventStream {
|
|
|
1572
1588
|
}
|
|
1573
1589
|
if (this._unsentData?.length) {
|
|
1574
1590
|
await this._writer.write(this._encoder.encode(this._unsentData));
|
|
1575
|
-
this._unsentData =
|
|
1591
|
+
this._unsentData = undefined;
|
|
1576
1592
|
}
|
|
1577
1593
|
}
|
|
1578
1594
|
/**
|
|
@@ -1682,7 +1698,7 @@ async function serveStatic(event, options) {
|
|
|
1682
1698
|
if (meta.encoding && !getResponseHeader(event, "content-encoding")) {
|
|
1683
1699
|
setResponseHeader(event, "content-encoding", meta.encoding);
|
|
1684
1700
|
}
|
|
1685
|
-
if (meta.size !==
|
|
1701
|
+
if (meta.size !== undefined && meta.size > 0 && !getResponseHeader(event, "content-length")) {
|
|
1686
1702
|
setResponseHeader(event, "content-length", meta.size);
|
|
1687
1703
|
}
|
|
1688
1704
|
if (event.method === "HEAD") {
|
|
@@ -1722,32 +1738,26 @@ function defineWebSocketHandler(hooks) {
|
|
|
1722
1738
|
});
|
|
1723
1739
|
}
|
|
1724
1740
|
|
|
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
1741
|
class H3Event {
|
|
1742
|
+
"__is_event__" = true;
|
|
1743
|
+
// Context
|
|
1744
|
+
node;
|
|
1745
|
+
// Node
|
|
1746
|
+
web;
|
|
1747
|
+
// Web
|
|
1748
|
+
context = {};
|
|
1749
|
+
// Shared
|
|
1750
|
+
// Request
|
|
1751
|
+
_method;
|
|
1752
|
+
_path;
|
|
1753
|
+
_headers;
|
|
1754
|
+
_requestBody;
|
|
1755
|
+
// Response
|
|
1756
|
+
_handled = false;
|
|
1757
|
+
// Hooks
|
|
1758
|
+
_onBeforeResponseCalled;
|
|
1759
|
+
_onAfterResponseCalled;
|
|
1732
1760
|
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
1761
|
this.node = { req, res };
|
|
1752
1762
|
}
|
|
1753
1763
|
// --- Request ---
|
|
@@ -1830,7 +1840,7 @@ function defineEventHandler(handler) {
|
|
|
1830
1840
|
return _handler;
|
|
1831
1841
|
}
|
|
1832
1842
|
function _normalizeArray(input) {
|
|
1833
|
-
return input ? Array.isArray(input) ? input : [input] :
|
|
1843
|
+
return input ? Array.isArray(input) ? input : [input] : undefined;
|
|
1834
1844
|
}
|
|
1835
1845
|
async function _callHandler(event, handler, hooks) {
|
|
1836
1846
|
if (hooks.onRequest) {
|
|
@@ -1960,7 +1970,7 @@ function use(app, arg1, arg2, arg3) {
|
|
|
1960
1970
|
return app;
|
|
1961
1971
|
}
|
|
1962
1972
|
function createAppEventHandler(stack, options) {
|
|
1963
|
-
const spacing = options.debug ? 2 :
|
|
1973
|
+
const spacing = options.debug ? 2 : undefined;
|
|
1964
1974
|
return eventHandler(async (event) => {
|
|
1965
1975
|
event.node.req.originalUrl = event.node.req.originalUrl || event.node.req.url || "/";
|
|
1966
1976
|
const _reqPath = event._path || event.node.req.url || "/";
|
|
@@ -1983,8 +1993,8 @@ function createAppEventHandler(stack, options) {
|
|
|
1983
1993
|
event._path = _layerPath;
|
|
1984
1994
|
event.node.req.url = _layerPath;
|
|
1985
1995
|
const val = await layer.handler(event);
|
|
1986
|
-
const _body = val ===
|
|
1987
|
-
if (_body !==
|
|
1996
|
+
const _body = val === undefined ? undefined : await val;
|
|
1997
|
+
if (_body !== undefined) {
|
|
1988
1998
|
const _response = { body: _body };
|
|
1989
1999
|
if (options.onBeforeResponse) {
|
|
1990
2000
|
event._onBeforeResponseCalled = true;
|
|
@@ -2000,7 +2010,7 @@ function createAppEventHandler(stack, options) {
|
|
|
2000
2010
|
if (event.handled) {
|
|
2001
2011
|
if (options.onAfterResponse) {
|
|
2002
2012
|
event._onAfterResponseCalled = true;
|
|
2003
|
-
await options.onAfterResponse(event,
|
|
2013
|
+
await options.onAfterResponse(event, undefined);
|
|
2004
2014
|
}
|
|
2005
2015
|
return;
|
|
2006
2016
|
}
|
|
@@ -2013,7 +2023,7 @@ function createAppEventHandler(stack, options) {
|
|
|
2013
2023
|
}
|
|
2014
2024
|
if (options.onAfterResponse) {
|
|
2015
2025
|
event._onAfterResponseCalled = true;
|
|
2016
|
-
await options.onAfterResponse(event,
|
|
2026
|
+
await options.onAfterResponse(event, undefined);
|
|
2017
2027
|
}
|
|
2018
2028
|
});
|
|
2019
2029
|
}
|
|
@@ -2028,7 +2038,7 @@ function createResolver(stack) {
|
|
|
2028
2038
|
continue;
|
|
2029
2039
|
}
|
|
2030
2040
|
_layerPath = path.slice(layer.route.length) || "/";
|
|
2031
|
-
if (layer.match && !layer.match(_layerPath,
|
|
2041
|
+
if (layer.match && !layer.match(_layerPath, undefined)) {
|
|
2032
2042
|
continue;
|
|
2033
2043
|
}
|
|
2034
2044
|
let res = { route: layer.route, handler: layer.handler };
|
|
@@ -2055,7 +2065,7 @@ function normalizeLayer(input) {
|
|
|
2055
2065
|
if (input.lazy) {
|
|
2056
2066
|
handler = lazyEventHandler(handler);
|
|
2057
2067
|
} else if (!isEventHandler(handler)) {
|
|
2058
|
-
handler = toEventHandler(handler,
|
|
2068
|
+
handler = toEventHandler(handler, undefined, input.route);
|
|
2059
2069
|
}
|
|
2060
2070
|
return {
|
|
2061
2071
|
route: ufo.withoutTrailingSlash(input.route),
|
|
@@ -2094,7 +2104,7 @@ function handleHandlerResponse(event, val, jsonSpace) {
|
|
|
2094
2104
|
return send(event, val, MIMES.html);
|
|
2095
2105
|
}
|
|
2096
2106
|
if (valType === "object" || valType === "boolean" || valType === "number") {
|
|
2097
|
-
return send(event, JSON.stringify(val,
|
|
2107
|
+
return send(event, JSON.stringify(val, undefined, jsonSpace), MIMES.json);
|
|
2098
2108
|
}
|
|
2099
2109
|
if (valType === "bigint") {
|
|
2100
2110
|
return send(event, val.toString(), MIMES.json);
|
|
@@ -2152,7 +2162,7 @@ function createRouter(opts = {}) {
|
|
|
2152
2162
|
addRoute(path, handler, m);
|
|
2153
2163
|
}
|
|
2154
2164
|
} else {
|
|
2155
|
-
route.handlers[method] = toEventHandler(handler,
|
|
2165
|
+
route.handlers[method] = toEventHandler(handler, undefined, path);
|
|
2156
2166
|
}
|
|
2157
2167
|
return router;
|
|
2158
2168
|
};
|
|
@@ -2222,7 +2232,7 @@ function createRouter(opts = {}) {
|
|
|
2222
2232
|
const params = match.matched.params || {};
|
|
2223
2233
|
event.context.params = params;
|
|
2224
2234
|
return Promise.resolve(match.handler(event)).then((res) => {
|
|
2225
|
-
if (res ===
|
|
2235
|
+
if (res === undefined && isPreemptive) {
|
|
2226
2236
|
return null;
|
|
2227
2237
|
}
|
|
2228
2238
|
return res;
|
|
@@ -2314,7 +2324,7 @@ function callNodeListener(handler, req, res) {
|
|
|
2314
2324
|
res.off("close", next);
|
|
2315
2325
|
res.off("error", next);
|
|
2316
2326
|
}
|
|
2317
|
-
return err ? reject(createError(err)) : resolve(
|
|
2327
|
+
return err ? reject(createError(err)) : resolve(undefined);
|
|
2318
2328
|
};
|
|
2319
2329
|
try {
|
|
2320
2330
|
const returned = handler(req, res, next);
|
|
@@ -2414,7 +2424,7 @@ function _normalizeUnenvHeaders(input) {
|
|
|
2414
2424
|
for (const _value of value) {
|
|
2415
2425
|
headers.push([key, _value]);
|
|
2416
2426
|
}
|
|
2417
|
-
} else if (value !==
|
|
2427
|
+
} else if (value !== undefined) {
|
|
2418
2428
|
headers.push([key, String(value)]);
|
|
2419
2429
|
}
|
|
2420
2430
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -133,20 +133,28 @@ interface SessionConfig {
|
|
|
133
133
|
/** Default is Crypto.randomUUID */
|
|
134
134
|
generateId?: () => string;
|
|
135
135
|
}
|
|
136
|
+
type CompatEvent = {
|
|
137
|
+
request: {
|
|
138
|
+
headers: Headers;
|
|
139
|
+
};
|
|
140
|
+
context: any;
|
|
141
|
+
} | {
|
|
142
|
+
headers: Headers;
|
|
143
|
+
context: any;
|
|
144
|
+
};
|
|
136
145
|
/**
|
|
137
146
|
* Create a session manager for the current request.
|
|
138
|
-
*
|
|
139
147
|
*/
|
|
140
|
-
declare function useSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig): Promise<{
|
|
141
|
-
readonly id:
|
|
148
|
+
declare function useSession<T extends SessionDataT = SessionDataT>(event: H3Event | CompatEvent, config: SessionConfig): Promise<{
|
|
149
|
+
readonly id: any;
|
|
142
150
|
readonly data: T;
|
|
143
|
-
update: (update: SessionUpdate<T>) => Promise
|
|
144
|
-
clear: () => Promise
|
|
151
|
+
update: (update: SessionUpdate<T>) => Promise</*elided*/ any>;
|
|
152
|
+
clear: () => Promise</*elided*/ any>;
|
|
145
153
|
}>;
|
|
146
154
|
/**
|
|
147
155
|
* Get the session for the current request.
|
|
148
156
|
*/
|
|
149
|
-
declare function getSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig): Promise<Session<T>>;
|
|
157
|
+
declare function getSession<T extends SessionDataT = SessionDataT>(event: H3Event | CompatEvent, config: SessionConfig): Promise<Session<T>>;
|
|
150
158
|
type SessionUpdate<T extends SessionDataT = SessionDataT> = Partial<SessionData<T>> | ((oldData: SessionData<T>) => Partial<SessionData<T>> | undefined);
|
|
151
159
|
/**
|
|
152
160
|
* Update the session data for the current request.
|
|
@@ -155,11 +163,11 @@ declare function updateSession<T extends SessionDataT = SessionDataT>(event: H3E
|
|
|
155
163
|
/**
|
|
156
164
|
* Encrypt and sign the session data for the current request.
|
|
157
165
|
*/
|
|
158
|
-
declare function sealSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig): Promise<string>;
|
|
166
|
+
declare function sealSession<T extends SessionDataT = SessionDataT>(event: H3Event | CompatEvent, config: SessionConfig): Promise<string>;
|
|
159
167
|
/**
|
|
160
168
|
* Decrypt and verify the session data for the current request.
|
|
161
169
|
*/
|
|
162
|
-
declare function unsealSession(_event: H3Event, config: SessionConfig, sealed: string): Promise<Partial<Session<SessionDataT>>>;
|
|
170
|
+
declare function unsealSession(_event: H3Event | CompatEvent, config: SessionConfig, sealed: string): Promise<Partial<Session<SessionDataT>>>;
|
|
163
171
|
/**
|
|
164
172
|
* Clear the session data for the current request.
|
|
165
173
|
*/
|
|
@@ -311,7 +319,6 @@ type LazyEventHandler = () => EventHandler | Promise<EventHandler>;
|
|
|
311
319
|
* @property {boolean} unhandled - Indicates if the error was unhandled and auto captured.
|
|
312
320
|
* @property {DataT} data - An extra data that will be included in the response.
|
|
313
321
|
* This can be used to pass additional information about the error.
|
|
314
|
-
* @property {boolean} internal - Setting this property to `true` will mark the error as an internal error.
|
|
315
322
|
*/
|
|
316
323
|
declare class H3Error<DataT = unknown> extends Error {
|
|
317
324
|
static __h3_error__: boolean;
|
|
@@ -513,7 +520,7 @@ declare function readBody<T, Event extends H3Event = H3Event, _T = InferEventInp
|
|
|
513
520
|
*/
|
|
514
521
|
declare function readValidatedBody<T, Event extends H3Event = H3Event, _T = InferEventInput<"body", Event, T>>(event: Event, validate: ValidateFunction<_T>): Promise<_T>;
|
|
515
522
|
/**
|
|
516
|
-
* Tries to read and parse the body of
|
|
523
|
+
* Tries to read and parse the body of an H3Event as multipart form.
|
|
517
524
|
*
|
|
518
525
|
* @example
|
|
519
526
|
* export default defineEventHandler(async (event) => {
|
|
@@ -615,7 +622,7 @@ interface H3CorsOptions {
|
|
|
615
622
|
declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
|
|
616
623
|
|
|
617
624
|
/**
|
|
618
|
-
* Get query
|
|
625
|
+
* Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io).
|
|
619
626
|
*
|
|
620
627
|
* @example
|
|
621
628
|
* export default defineEventHandler((event) => {
|
|
@@ -624,7 +631,7 @@ declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
|
|
|
624
631
|
*/
|
|
625
632
|
declare function getQuery<T, Event extends H3Event = H3Event, _T = Exclude<InferEventInput<"query", Event, T>, undefined>>(event: Event): _T;
|
|
626
633
|
/**
|
|
627
|
-
* Get the query
|
|
634
|
+
* Get the query params object from the request URL parsed with [unjs/ufo](https://ufo.unjs.io) and validated with validate function.
|
|
628
635
|
*
|
|
629
636
|
* You can use a simple function to validate the query object or a library like `zod` to define a schema.
|
|
630
637
|
*
|
|
@@ -796,7 +803,7 @@ declare function getRequestProtocol(event: H3Event, opts?: {
|
|
|
796
803
|
/** @deprecated Use `event.path` instead */
|
|
797
804
|
declare function getRequestPath(event: H3Event): string;
|
|
798
805
|
/**
|
|
799
|
-
*
|
|
806
|
+
* Generate the full incoming request URL using `getRequestProtocol`, `getRequestHost` and `event.path`.
|
|
800
807
|
*
|
|
801
808
|
* If `xForwardedHost` is `true`, it will use the `x-forwarded-host` header if it exists.
|
|
802
809
|
*
|
|
@@ -820,7 +827,9 @@ declare function toWebRequest(event: H3Event): Request;
|
|
|
820
827
|
/**
|
|
821
828
|
* Try to get the client IP address from the incoming request.
|
|
822
829
|
*
|
|
823
|
-
* If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header if it exists.
|
|
830
|
+
* If `xForwardedFor` is `true`, it will use the `x-forwarded-for` header set by proxies if it exists.
|
|
831
|
+
*
|
|
832
|
+
* Note: Make sure that this header can be trusted (your application running behind a CDN or reverse proxy) before enabling.
|
|
824
833
|
*
|
|
825
834
|
* If IP cannot be determined, it will default to `undefined`.
|
|
826
835
|
*
|
|
@@ -830,11 +839,6 @@ declare function toWebRequest(event: H3Event): Request;
|
|
|
830
839
|
* });
|
|
831
840
|
*/
|
|
832
841
|
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
842
|
xForwardedFor?: boolean;
|
|
839
843
|
}): string | undefined;
|
|
840
844
|
|
|
@@ -856,7 +860,7 @@ declare function appendCorsPreflightHeaders(event: H3Event, options: H3CorsOptio
|
|
|
856
860
|
declare function appendCorsHeaders(event: H3Event, options: H3CorsOptions): void;
|
|
857
861
|
|
|
858
862
|
/**
|
|
859
|
-
* Parse the request to get HTTP Cookie header string and
|
|
863
|
+
* Parse the request to get HTTP Cookie header string and return an object of all cookie name-value pairs.
|
|
860
864
|
* @param event {H3Event} H3 event or req passed by h3 handler
|
|
861
865
|
* @returns Object of cookie name-value pairs
|
|
862
866
|
* ```ts
|
|
@@ -957,7 +961,9 @@ declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions):
|
|
|
957
961
|
/**
|
|
958
962
|
* Get the request headers object without headers known to cause issues when proxying.
|
|
959
963
|
*/
|
|
960
|
-
declare function getProxyRequestHeaders(event: H3Event
|
|
964
|
+
declare function getProxyRequestHeaders(event: H3Event, opts?: {
|
|
965
|
+
host?: boolean;
|
|
966
|
+
}): any;
|
|
961
967
|
/**
|
|
962
968
|
* Make a fetch request with the event's context and headers.
|
|
963
969
|
*/
|
|
@@ -979,7 +985,7 @@ type IteratorSerializer<Value> = (value: Value) => SendableValue | undefined;
|
|
|
979
985
|
*/
|
|
980
986
|
declare function send(event: H3Event, data?: any, type?: MimeType): Promise<void>;
|
|
981
987
|
/**
|
|
982
|
-
* Respond with an empty payload
|
|
988
|
+
* Respond with an empty payload.
|
|
983
989
|
*
|
|
984
990
|
* Note that calling this function will close the connection and no other data can be sent to the client afterwards.
|
|
985
991
|
*
|
|
@@ -1059,7 +1065,7 @@ declare function sendRedirect(event: H3Event, location: string, code?: StatusCod
|
|
|
1059
1065
|
*/
|
|
1060
1066
|
declare function getResponseHeaders(event: H3Event): ReturnType<H3Event["node"]["res"]["getHeaders"]>;
|
|
1061
1067
|
/**
|
|
1062
|
-
*
|
|
1068
|
+
* Get a response header by name.
|
|
1063
1069
|
*
|
|
1064
1070
|
* @example
|
|
1065
1071
|
* export default defineEventHandler((event) => {
|
|
@@ -1147,7 +1153,7 @@ declare function clearResponseHeaders(event: H3Event, headerNames?: HTTPHeaderNa
|
|
|
1147
1153
|
*/
|
|
1148
1154
|
declare function removeResponseHeader(event: H3Event, name: HTTPHeaderName): void;
|
|
1149
1155
|
/**
|
|
1150
|
-
* Checks if the data is a stream
|
|
1156
|
+
* Checks if the data is a stream (Node.js Readable Stream, React Pipeable Stream, or Web Stream).
|
|
1151
1157
|
*/
|
|
1152
1158
|
declare function isStream(data: any): data is Readable | ReadableStream;
|
|
1153
1159
|
/**
|