h3 1.4.0 → 1.6.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 +46 -13
- package/dist/index.cjs +233 -2
- package/dist/index.d.ts +42 -6
- package/dist/index.mjs +225 -3
- package/package.json +17 -15
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
[](https://npmjs.com/package/h3)
|
|
3
|
-
[](https://bundlephobia.com/result?p=h3)
|
|
4
|
-
[](https://github.com/unjs/h3/actions)
|
|
5
|
-
[](https://codecov.io/gh/unjs/h3)
|
|
6
|
-
[](https://www.jsdocs.io/package/h3)
|
|
1
|
+
# H3
|
|
7
2
|
|
|
8
|
-
|
|
3
|
+
[![npm version][npm-version-src]][npm-version-href]
|
|
4
|
+
[![npm downloads][npm-downloads-src]][npm-downloads-href]
|
|
5
|
+
[![bundle][bundle-src]][bundle-href]
|
|
6
|
+
[![Codecov][codecov-src]][codecov-href]
|
|
7
|
+
[![License][license-src]][license-href]
|
|
8
|
+
[![JSDocs][jsdocs-src]][jsdocs-href]
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
H3 is a minimal h(ttp) framework built for high performance and portability.
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
@@ -110,6 +110,19 @@ app.use(eventHandler(() => '<h1>Hello world!</h1>'))
|
|
|
110
110
|
app.use('/1', eventHandler(() => '<h1>Hello world!</h1>'))
|
|
111
111
|
.use('/2', eventHandler(() => '<h1>Goodbye!</h1>'))
|
|
112
112
|
|
|
113
|
+
// We can proxy requests and rewrite cookie's domain and path
|
|
114
|
+
app.use('/api', eventHandler((event) => proxyRequest('https://example.com', {
|
|
115
|
+
// f.e. keep one domain unchanged, rewrite one domain and remove other domains
|
|
116
|
+
cookieDomainRewrite: {
|
|
117
|
+
"example.com": "example.com",
|
|
118
|
+
"example.com": "somecompany.co.uk",
|
|
119
|
+
"*": "",
|
|
120
|
+
},
|
|
121
|
+
cookiePathRewrite: {
|
|
122
|
+
"/": "/api"
|
|
123
|
+
},
|
|
124
|
+
}))
|
|
125
|
+
|
|
113
126
|
// Legacy middleware with 3rd argument are automatically promisified
|
|
114
127
|
app.use(fromNodeMiddleware((req, res, next) => { req.setHeader('x-foo', 'bar'); next() }))
|
|
115
128
|
|
|
@@ -146,8 +159,8 @@ H3 has a concept of composable utilities that accept `event` (from `eventHandler
|
|
|
146
159
|
- `isMethod(event, expected, allowHead?)`
|
|
147
160
|
- `assertMethod(event, expected, allowHead?)`
|
|
148
161
|
- `createError({ statusCode, statusMessage, data? })`
|
|
149
|
-
- `sendProxy(event, { target,
|
|
150
|
-
- `proxyRequest(event, { target,
|
|
162
|
+
- `sendProxy(event, { target, ...options })`
|
|
163
|
+
- `proxyRequest(event, { target, ...options })`
|
|
151
164
|
- `fetchWithEvent(event, req, init, { fetch? }?)`
|
|
152
165
|
- `getProxyRequestHeaders(event)`
|
|
153
166
|
- `sendNoContent(event, code = 204)`
|
|
@@ -161,6 +174,14 @@ H3 has a concept of composable utilities that accept `event` (from `eventHandler
|
|
|
161
174
|
- `clearSession(event, config)`
|
|
162
175
|
- `sealSession(event, config)`
|
|
163
176
|
- `unsealSession(event, config, sealed)`
|
|
177
|
+
- `handleCors(options)` (see [h3-cors](https://github.com/NozomuIkuta/h3-cors) for more detail about options)
|
|
178
|
+
- `isPreflightRequest(event)`
|
|
179
|
+
- `isCorsOriginAllowed(event)`
|
|
180
|
+
- `appendCorsHeaders(event, options)` (see [h3-cors](https://github.com/NozomuIkuta/h3-cors) for more detail about options)
|
|
181
|
+
- `appendCorsPreflightHeaders(event, options)` (see [h3-cors](https://github.com/NozomuIkuta/h3-cors) for more detail about options)
|
|
182
|
+
- `getRequestHost(event)`
|
|
183
|
+
- `getRequestProtocol(event)`
|
|
184
|
+
- `getRequestURL(event)`
|
|
164
185
|
|
|
165
186
|
👉 You can learn more about usage in [JSDocs Documentation](https://www.jsdocs.io/package/h3#package-functions).
|
|
166
187
|
|
|
@@ -172,9 +193,6 @@ Please check their READMEs for more details.
|
|
|
172
193
|
|
|
173
194
|
PRs are welcome to add your packages.
|
|
174
195
|
|
|
175
|
-
- [h3-cors](https://github.com/NozomuIkuta/h3-cors)
|
|
176
|
-
- `defineCorsEventHandler(options)`
|
|
177
|
-
- `isPreflight(event)`
|
|
178
196
|
- [h3-typebox](https://github.com/kevinmarrec/h3-typebox)
|
|
179
197
|
- `validateBody(event, schema)`
|
|
180
198
|
- `validateQuery(event, schema)`
|
|
@@ -185,3 +203,18 @@ PRs are welcome to add your packages.
|
|
|
185
203
|
## License
|
|
186
204
|
|
|
187
205
|
MIT
|
|
206
|
+
|
|
207
|
+
<!-- Badges -->
|
|
208
|
+
|
|
209
|
+
[npm-version-src]: https://img.shields.io/npm/v/h3?style=flat&colorA=18181B&colorB=F0DB4F
|
|
210
|
+
[npm-version-href]: https://npmjs.com/package/h3
|
|
211
|
+
[npm-downloads-src]: https://img.shields.io/npm/dm/h3?style=flat&colorA=18181B&colorB=F0DB4F
|
|
212
|
+
[npm-downloads-href]: https://npmjs.com/package/h3
|
|
213
|
+
[codecov-src]: https://img.shields.io/codecov/c/gh/unjs/h3/main?style=flat&colorA=18181B&colorB=F0DB4F
|
|
214
|
+
[codecov-href]: https://codecov.io/gh/unjs/h3
|
|
215
|
+
[bundle-src]: https://img.shields.io/bundlephobia/minzip/h3?style=flat&colorA=18181B&colorB=F0DB4F
|
|
216
|
+
[bundle-href]: https://bundlephobia.com/result?p=h3
|
|
217
|
+
[license-src]: https://img.shields.io/github/license/unjs/h3.svg?style=flat&colorA=18181B&colorB=F0DB4F
|
|
218
|
+
[license-href]: https://github.com/unjs/h3/blob/main/LICENSE
|
|
219
|
+
[jsdocs-src]: https://img.shields.io/badge/jsDocs.io-reference-18181B?style=flat&colorA=18181B&colorB=F0DB4F
|
|
220
|
+
[jsdocs-href]: https://www.jsdocs.io/package/h3
|
package/dist/index.cjs
CHANGED
|
@@ -6,6 +6,7 @@ const destr = require('destr');
|
|
|
6
6
|
const cookieEs = require('cookie-es');
|
|
7
7
|
const crypto = require('uncrypto');
|
|
8
8
|
const ironWebcrypto = require('iron-webcrypto');
|
|
9
|
+
const defu = require('defu');
|
|
9
10
|
|
|
10
11
|
function useBase(base, handler) {
|
|
11
12
|
base = ufo.withoutTrailingSlash(base);
|
|
@@ -247,6 +248,24 @@ function getRequestHeader(event, name) {
|
|
|
247
248
|
return value;
|
|
248
249
|
}
|
|
249
250
|
const getHeader = getRequestHeader;
|
|
251
|
+
function getRequestHost(event) {
|
|
252
|
+
const xForwardedHost = event.node.req.headers["x-forwarded-host"];
|
|
253
|
+
if (xForwardedHost) {
|
|
254
|
+
return xForwardedHost;
|
|
255
|
+
}
|
|
256
|
+
return event.node.req.headers.host || "localhost";
|
|
257
|
+
}
|
|
258
|
+
function getRequestProtocol(event) {
|
|
259
|
+
if (event.node.req.headers["x-forwarded-proto"] === "https") {
|
|
260
|
+
return "https";
|
|
261
|
+
}
|
|
262
|
+
return event.node.req.connection.encrypted ? "https" : "http";
|
|
263
|
+
}
|
|
264
|
+
function getRequestURL(event) {
|
|
265
|
+
const host = getRequestHost(event);
|
|
266
|
+
const protocol = getRequestProtocol(event);
|
|
267
|
+
return new URL(event.path || "/", `${protocol}://${host}`);
|
|
268
|
+
}
|
|
250
269
|
|
|
251
270
|
const RawBodySymbol = Symbol.for("h3RawBody");
|
|
252
271
|
const ParsedBodySymbol = Symbol.for("h3ParsedBody");
|
|
@@ -379,6 +398,58 @@ function deleteCookie(event, name, serializeOptions) {
|
|
|
379
398
|
maxAge: 0
|
|
380
399
|
});
|
|
381
400
|
}
|
|
401
|
+
function splitCookiesString(cookiesString) {
|
|
402
|
+
if (typeof cookiesString !== "string") {
|
|
403
|
+
return [];
|
|
404
|
+
}
|
|
405
|
+
const cookiesStrings = [];
|
|
406
|
+
let pos = 0;
|
|
407
|
+
let start;
|
|
408
|
+
let ch;
|
|
409
|
+
let lastComma;
|
|
410
|
+
let nextStart;
|
|
411
|
+
let cookiesSeparatorFound;
|
|
412
|
+
function skipWhitespace() {
|
|
413
|
+
while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) {
|
|
414
|
+
pos += 1;
|
|
415
|
+
}
|
|
416
|
+
return pos < cookiesString.length;
|
|
417
|
+
}
|
|
418
|
+
function notSpecialChar() {
|
|
419
|
+
ch = cookiesString.charAt(pos);
|
|
420
|
+
return ch !== "=" && ch !== ";" && ch !== ",";
|
|
421
|
+
}
|
|
422
|
+
while (pos < cookiesString.length) {
|
|
423
|
+
start = pos;
|
|
424
|
+
cookiesSeparatorFound = false;
|
|
425
|
+
while (skipWhitespace()) {
|
|
426
|
+
ch = cookiesString.charAt(pos);
|
|
427
|
+
if (ch === ",") {
|
|
428
|
+
lastComma = pos;
|
|
429
|
+
pos += 1;
|
|
430
|
+
skipWhitespace();
|
|
431
|
+
nextStart = pos;
|
|
432
|
+
while (pos < cookiesString.length && notSpecialChar()) {
|
|
433
|
+
pos += 1;
|
|
434
|
+
}
|
|
435
|
+
if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
|
|
436
|
+
cookiesSeparatorFound = true;
|
|
437
|
+
pos = nextStart;
|
|
438
|
+
cookiesStrings.push(cookiesString.slice(start, lastComma));
|
|
439
|
+
start = pos;
|
|
440
|
+
} else {
|
|
441
|
+
pos = lastComma + 1;
|
|
442
|
+
}
|
|
443
|
+
} else {
|
|
444
|
+
pos += 1;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (!cookiesSeparatorFound || pos >= cookiesString.length) {
|
|
448
|
+
cookiesStrings.push(cookiesString.slice(start, cookiesString.length));
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
return cookiesStrings;
|
|
452
|
+
}
|
|
382
453
|
|
|
383
454
|
const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
|
|
384
455
|
const ignoredHeaders = /* @__PURE__ */ new Set([
|
|
@@ -426,6 +497,27 @@ async function sendProxy(event, target, opts = {}) {
|
|
|
426
497
|
if (key === "content-length") {
|
|
427
498
|
continue;
|
|
428
499
|
}
|
|
500
|
+
if (key === "set-cookie") {
|
|
501
|
+
const cookies = splitCookiesString(value).map((cookie) => {
|
|
502
|
+
if (opts.cookieDomainRewrite) {
|
|
503
|
+
cookie = rewriteCookieProperty(
|
|
504
|
+
cookie,
|
|
505
|
+
opts.cookieDomainRewrite,
|
|
506
|
+
"domain"
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
if (opts.cookiePathRewrite) {
|
|
510
|
+
cookie = rewriteCookieProperty(
|
|
511
|
+
cookie,
|
|
512
|
+
opts.cookiePathRewrite,
|
|
513
|
+
"path"
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
return cookie;
|
|
517
|
+
});
|
|
518
|
+
event.node.res.setHeader("set-cookie", cookies);
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
429
521
|
event.node.res.setHeader(key, value);
|
|
430
522
|
}
|
|
431
523
|
if (response._data !== void 0) {
|
|
@@ -453,8 +545,7 @@ function getProxyRequestHeaders(event) {
|
|
|
453
545
|
function fetchWithEvent(event, req, init, options) {
|
|
454
546
|
return _getFetch(options?.fetch)(req, {
|
|
455
547
|
...init,
|
|
456
|
-
|
|
457
|
-
context: init.context || event.context,
|
|
548
|
+
context: init?.context || event.context,
|
|
458
549
|
headers: {
|
|
459
550
|
...getProxyRequestHeaders(event),
|
|
460
551
|
...init?.headers
|
|
@@ -472,6 +563,23 @@ function _getFetch(_fetch) {
|
|
|
472
563
|
"fetch is not available. Try importing `node-fetch-native/polyfill` for Node.js."
|
|
473
564
|
);
|
|
474
565
|
}
|
|
566
|
+
function rewriteCookieProperty(header, map, property) {
|
|
567
|
+
const _map = typeof map === "string" ? { "*": map } : map;
|
|
568
|
+
return header.replace(
|
|
569
|
+
new RegExp(`(;\\s*${property}=)([^;]+)`, "gi"),
|
|
570
|
+
(match, prefix, previousValue) => {
|
|
571
|
+
let newValue;
|
|
572
|
+
if (previousValue in _map) {
|
|
573
|
+
newValue = _map[previousValue];
|
|
574
|
+
} else if ("*" in _map) {
|
|
575
|
+
newValue = _map["*"];
|
|
576
|
+
} else {
|
|
577
|
+
return match;
|
|
578
|
+
}
|
|
579
|
+
return newValue ? prefix + newValue : "";
|
|
580
|
+
}
|
|
581
|
+
);
|
|
582
|
+
}
|
|
475
583
|
|
|
476
584
|
const defer = typeof setImmediate !== "undefined" ? setImmediate : (fn) => fn();
|
|
477
585
|
function send(event, data, type) {
|
|
@@ -730,6 +838,120 @@ async function clearSession(event, config) {
|
|
|
730
838
|
});
|
|
731
839
|
}
|
|
732
840
|
|
|
841
|
+
function resolveCorsOptions(options = {}) {
|
|
842
|
+
const defaultOptions = {
|
|
843
|
+
origin: "*",
|
|
844
|
+
methods: "*",
|
|
845
|
+
allowHeaders: "*",
|
|
846
|
+
exposeHeaders: "*",
|
|
847
|
+
credentials: false,
|
|
848
|
+
maxAge: false,
|
|
849
|
+
preflight: {
|
|
850
|
+
statusCode: 204
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
return defu.defu(options, defaultOptions);
|
|
854
|
+
}
|
|
855
|
+
function isPreflightRequest(event) {
|
|
856
|
+
const method = getMethod(event);
|
|
857
|
+
const origin = getRequestHeader(event, "origin");
|
|
858
|
+
const accessControlRequestMethod = getRequestHeader(
|
|
859
|
+
event,
|
|
860
|
+
"access-control-request-method"
|
|
861
|
+
);
|
|
862
|
+
return method === "OPTIONS" && !!origin && !!accessControlRequestMethod;
|
|
863
|
+
}
|
|
864
|
+
function isCorsOriginAllowed(origin, options) {
|
|
865
|
+
const { origin: originOption } = options;
|
|
866
|
+
if (!origin || !originOption || originOption === "*" || originOption === "null") {
|
|
867
|
+
return true;
|
|
868
|
+
}
|
|
869
|
+
if (Array.isArray(originOption)) {
|
|
870
|
+
return originOption.some((_origin) => {
|
|
871
|
+
if (_origin instanceof RegExp) {
|
|
872
|
+
return _origin.test(origin);
|
|
873
|
+
}
|
|
874
|
+
return origin === _origin;
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
return originOption(origin);
|
|
878
|
+
}
|
|
879
|
+
function createOriginHeaders(event, options) {
|
|
880
|
+
const { origin: originOption } = options;
|
|
881
|
+
const origin = getRequestHeader(event, "origin");
|
|
882
|
+
if (!origin || !originOption || originOption === "*") {
|
|
883
|
+
return { "access-control-allow-origin": "*" };
|
|
884
|
+
}
|
|
885
|
+
if (typeof originOption === "string") {
|
|
886
|
+
return { "access-control-allow-origin": originOption, vary: "origin" };
|
|
887
|
+
}
|
|
888
|
+
return isCorsOriginAllowed(origin, options) ? { "access-control-allow-origin": origin, vary: "origin" } : {};
|
|
889
|
+
}
|
|
890
|
+
function createMethodsHeaders(options) {
|
|
891
|
+
const { methods } = options;
|
|
892
|
+
if (!methods) {
|
|
893
|
+
return {};
|
|
894
|
+
}
|
|
895
|
+
if (methods === "*") {
|
|
896
|
+
return { "access-control-allow-methods": "*" };
|
|
897
|
+
}
|
|
898
|
+
return methods.length > 0 ? { "access-control-allow-methods": methods.join(",") } : {};
|
|
899
|
+
}
|
|
900
|
+
function createCredentialsHeaders(options) {
|
|
901
|
+
const { credentials } = options;
|
|
902
|
+
if (credentials) {
|
|
903
|
+
return { "access-control-allow-credentials": "true" };
|
|
904
|
+
}
|
|
905
|
+
return {};
|
|
906
|
+
}
|
|
907
|
+
function createAllowHeaderHeaders(event, options) {
|
|
908
|
+
const { allowHeaders } = options;
|
|
909
|
+
if (!allowHeaders || allowHeaders === "*" || allowHeaders.length === 0) {
|
|
910
|
+
const header = getRequestHeader(event, "access-control-request-headers");
|
|
911
|
+
return header ? {
|
|
912
|
+
"access-control-allow-headers": header,
|
|
913
|
+
vary: "access-control-request-headers"
|
|
914
|
+
} : {};
|
|
915
|
+
}
|
|
916
|
+
return {
|
|
917
|
+
"access-control-allow-headers": allowHeaders.join(","),
|
|
918
|
+
vary: "access-control-request-headers"
|
|
919
|
+
};
|
|
920
|
+
}
|
|
921
|
+
function createExposeHeaders(options) {
|
|
922
|
+
const { exposeHeaders } = options;
|
|
923
|
+
if (!exposeHeaders) {
|
|
924
|
+
return {};
|
|
925
|
+
}
|
|
926
|
+
if (exposeHeaders === "*") {
|
|
927
|
+
return { "access-control-expose-headers": exposeHeaders };
|
|
928
|
+
}
|
|
929
|
+
return { "access-control-expose-headers": exposeHeaders.join(",") };
|
|
930
|
+
}
|
|
931
|
+
function appendCorsPreflightHeaders(event, options) {
|
|
932
|
+
appendHeaders(event, createOriginHeaders(event, options));
|
|
933
|
+
appendHeaders(event, createCredentialsHeaders(options));
|
|
934
|
+
appendHeaders(event, createExposeHeaders(options));
|
|
935
|
+
appendHeaders(event, createMethodsHeaders(options));
|
|
936
|
+
appendHeaders(event, createAllowHeaderHeaders(event, options));
|
|
937
|
+
}
|
|
938
|
+
function appendCorsHeaders(event, options) {
|
|
939
|
+
appendHeaders(event, createOriginHeaders(event, options));
|
|
940
|
+
appendHeaders(event, createCredentialsHeaders(options));
|
|
941
|
+
appendHeaders(event, createExposeHeaders(options));
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
function handleCors(event, options) {
|
|
945
|
+
const _options = resolveCorsOptions(options);
|
|
946
|
+
if (isPreflightRequest(event)) {
|
|
947
|
+
appendCorsPreflightHeaders(event, options);
|
|
948
|
+
sendNoContent(event, _options.preflight.statusCode);
|
|
949
|
+
return true;
|
|
950
|
+
}
|
|
951
|
+
appendCorsHeaders(event, options);
|
|
952
|
+
return false;
|
|
953
|
+
}
|
|
954
|
+
|
|
733
955
|
class H3Headers {
|
|
734
956
|
constructor(init) {
|
|
735
957
|
if (!init) {
|
|
@@ -1184,6 +1406,8 @@ exports.H3Event = H3Event;
|
|
|
1184
1406
|
exports.H3Headers = H3Headers;
|
|
1185
1407
|
exports.H3Response = H3Response;
|
|
1186
1408
|
exports.MIMES = MIMES;
|
|
1409
|
+
exports.appendCorsHeaders = appendCorsHeaders;
|
|
1410
|
+
exports.appendCorsPreflightHeaders = appendCorsPreflightHeaders;
|
|
1187
1411
|
exports.appendHeader = appendHeader;
|
|
1188
1412
|
exports.appendHeaders = appendHeaders;
|
|
1189
1413
|
exports.appendResponseHeader = appendResponseHeader;
|
|
@@ -1214,6 +1438,9 @@ exports.getProxyRequestHeaders = getProxyRequestHeaders;
|
|
|
1214
1438
|
exports.getQuery = getQuery;
|
|
1215
1439
|
exports.getRequestHeader = getRequestHeader;
|
|
1216
1440
|
exports.getRequestHeaders = getRequestHeaders;
|
|
1441
|
+
exports.getRequestHost = getRequestHost;
|
|
1442
|
+
exports.getRequestProtocol = getRequestProtocol;
|
|
1443
|
+
exports.getRequestURL = getRequestURL;
|
|
1217
1444
|
exports.getResponseHeader = getResponseHeader;
|
|
1218
1445
|
exports.getResponseHeaders = getResponseHeaders;
|
|
1219
1446
|
exports.getResponseStatus = getResponseStatus;
|
|
@@ -1222,10 +1449,13 @@ exports.getRouterParam = getRouterParam;
|
|
|
1222
1449
|
exports.getRouterParams = getRouterParams;
|
|
1223
1450
|
exports.getSession = getSession;
|
|
1224
1451
|
exports.handleCacheHeaders = handleCacheHeaders;
|
|
1452
|
+
exports.handleCors = handleCors;
|
|
1453
|
+
exports.isCorsOriginAllowed = isCorsOriginAllowed;
|
|
1225
1454
|
exports.isError = isError;
|
|
1226
1455
|
exports.isEvent = isEvent;
|
|
1227
1456
|
exports.isEventHandler = isEventHandler;
|
|
1228
1457
|
exports.isMethod = isMethod;
|
|
1458
|
+
exports.isPreflightRequest = isPreflightRequest;
|
|
1229
1459
|
exports.isStream = isStream;
|
|
1230
1460
|
exports.lazyEventHandler = lazyEventHandler;
|
|
1231
1461
|
exports.parseCookies = parseCookies;
|
|
@@ -1247,6 +1477,7 @@ exports.setHeaders = setHeaders;
|
|
|
1247
1477
|
exports.setResponseHeader = setResponseHeader;
|
|
1248
1478
|
exports.setResponseHeaders = setResponseHeaders;
|
|
1249
1479
|
exports.setResponseStatus = setResponseStatus;
|
|
1480
|
+
exports.splitCookiesString = splitCookiesString;
|
|
1250
1481
|
exports.toEventHandler = toEventHandler;
|
|
1251
1482
|
exports.toNodeListener = toNodeListener;
|
|
1252
1483
|
exports.unsealSession = unsealSession;
|
package/dist/index.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ interface SessionConfig {
|
|
|
27
27
|
}
|
|
28
28
|
declare function useSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig): Promise<{
|
|
29
29
|
readonly id: string | undefined;
|
|
30
|
-
readonly data:
|
|
30
|
+
readonly data: T;
|
|
31
31
|
update: (update: SessionUpdate<T>) => Promise<any>;
|
|
32
32
|
clear: () => Promise<any>;
|
|
33
33
|
}>;
|
|
@@ -36,7 +36,7 @@ type SessionUpdate<T extends SessionDataT = SessionDataT> = Partial<SessionData<
|
|
|
36
36
|
declare function updateSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig, update?: SessionUpdate<T>): Promise<Session<T>>;
|
|
37
37
|
declare function sealSession<T extends SessionDataT = SessionDataT>(event: H3Event, config: SessionConfig): Promise<string>;
|
|
38
38
|
declare function unsealSession(_event: H3Event, config: SessionConfig, sealed: string): Promise<Partial<Session<SessionDataT>>>;
|
|
39
|
-
declare function clearSession(event: H3Event, config: SessionConfig): Promise<void>;
|
|
39
|
+
declare function clearSession(event: H3Event, config: Partial<SessionConfig>): Promise<void>;
|
|
40
40
|
|
|
41
41
|
type HTTPMethod = "GET" | "HEAD" | "PATCH" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE";
|
|
42
42
|
type Encoding = false | "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";
|
|
@@ -231,7 +231,7 @@ declare function readRawBody<E extends Encoding = "utf8">(event: H3Event, encodi
|
|
|
231
231
|
* @return {*} The `Object`, `Array`, `String`, `Number`, `Boolean`, or `null` value corresponding to the request JSON body
|
|
232
232
|
*
|
|
233
233
|
* ```ts
|
|
234
|
-
* const body = await
|
|
234
|
+
* const body = await readBody(req)
|
|
235
235
|
* ```
|
|
236
236
|
*/
|
|
237
237
|
declare function readBody<T = any>(event: H3Event): Promise<T>;
|
|
@@ -270,7 +270,7 @@ declare function parseCookies(event: H3Event): Record<string, string>;
|
|
|
270
270
|
* @param name Name of the cookie to get
|
|
271
271
|
* @returns {*} Value of the cookie (String or undefined)
|
|
272
272
|
* ```ts
|
|
273
|
-
* const authorization =
|
|
273
|
+
* const authorization = getCookie(request, 'Authorization')
|
|
274
274
|
* ```
|
|
275
275
|
*/
|
|
276
276
|
declare function getCookie(event: H3Event, name: string): string | undefined;
|
|
@@ -295,17 +295,31 @@ declare function setCookie(event: H3Event, name: string, value: string, serializ
|
|
|
295
295
|
* ```
|
|
296
296
|
*/
|
|
297
297
|
declare function deleteCookie(event: H3Event, name: string, serializeOptions?: CookieSerializeOptions): void;
|
|
298
|
+
/**
|
|
299
|
+
* Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas
|
|
300
|
+
* that are within a single set-cookie field-value, such as in the Expires portion.
|
|
301
|
+
* This is uncommon, but explicitly allowed - see https://tools.ietf.org/html/rfc2616#section-4.2
|
|
302
|
+
* Node.js does this for every header *except* set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128
|
|
303
|
+
* Based on: https://github.com/google/j2objc/commit/16820fdbc8f76ca0c33472810ce0cb03d20efe25
|
|
304
|
+
* Credits to: https://github.com/tomball for original and https://github.com/chrusart for JavaScript implementation
|
|
305
|
+
* @source https://github.com/nfriedly/set-cookie-parser/blob/3eab8b7d5d12c8ed87832532861c1a35520cf5b3/lib/set-cookie.js#L144
|
|
306
|
+
*/
|
|
307
|
+
declare function splitCookiesString(cookiesString: string): string[];
|
|
298
308
|
|
|
299
309
|
interface ProxyOptions {
|
|
300
310
|
headers?: RequestHeaders | HeadersInit;
|
|
301
311
|
fetchOptions?: RequestInit;
|
|
302
312
|
fetch?: typeof fetch;
|
|
303
313
|
sendStream?: boolean;
|
|
314
|
+
cookieDomainRewrite?: string | Record<string, string>;
|
|
315
|
+
cookiePathRewrite?: string | Record<string, string>;
|
|
304
316
|
}
|
|
305
317
|
declare function proxyRequest(event: H3Event, target: string, opts?: ProxyOptions): Promise<any>;
|
|
306
318
|
declare function sendProxy(event: H3Event, target: string, opts?: ProxyOptions): Promise<any>;
|
|
307
319
|
declare function getProxyRequestHeaders(event: H3Event): any;
|
|
308
|
-
declare function fetchWithEvent(event: H3Event, req: RequestInfo | URL, init?: RequestInit
|
|
320
|
+
declare function fetchWithEvent(event: H3Event, req: RequestInfo | URL, init?: RequestInit & {
|
|
321
|
+
context?: H3EventContext;
|
|
322
|
+
}, options?: {
|
|
309
323
|
fetch: typeof fetch;
|
|
310
324
|
}): Promise<Response>;
|
|
311
325
|
|
|
@@ -319,6 +333,9 @@ declare function getRequestHeaders(event: H3Event): RequestHeaders;
|
|
|
319
333
|
declare const getHeaders: typeof getRequestHeaders;
|
|
320
334
|
declare function getRequestHeader(event: H3Event, name: string): RequestHeaders[string];
|
|
321
335
|
declare const getHeader: typeof getRequestHeader;
|
|
336
|
+
declare function getRequestHost(event: H3Event): string;
|
|
337
|
+
declare function getRequestProtocol(event: H3Event): "https" | "http";
|
|
338
|
+
declare function getRequestURL(event: H3Event): URL;
|
|
322
339
|
|
|
323
340
|
declare function send(event: H3Event, data?: any, type?: string): Promise<void>;
|
|
324
341
|
/**
|
|
@@ -348,6 +365,25 @@ declare function isStream(data: any): any;
|
|
|
348
365
|
declare function sendStream(event: H3Event, data: any): Promise<void>;
|
|
349
366
|
declare function writeEarlyHints(event: H3Event, hints: string | string[] | Record<string, string | string[]>, cb?: () => void): void;
|
|
350
367
|
|
|
368
|
+
interface H3CorsOptions {
|
|
369
|
+
origin?: "*" | "null" | (string | RegExp)[] | ((origin: string) => boolean);
|
|
370
|
+
methods?: "*" | HTTPMethod[];
|
|
371
|
+
allowHeaders?: "*" | string[];
|
|
372
|
+
exposeHeaders?: "*" | string[];
|
|
373
|
+
credentials?: boolean;
|
|
374
|
+
maxAge?: string | false;
|
|
375
|
+
preflight?: {
|
|
376
|
+
statusCode?: number;
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
declare function handleCors(event: H3Event, options: H3CorsOptions): boolean;
|
|
381
|
+
|
|
382
|
+
declare function isPreflightRequest(event: H3Event): boolean;
|
|
383
|
+
declare function isCorsOriginAllowed(origin: ReturnType<typeof getRequestHeaders>["origin"], options: H3CorsOptions): boolean;
|
|
384
|
+
declare function appendCorsPreflightHeaders(event: H3Event, options: H3CorsOptions): void;
|
|
385
|
+
declare function appendCorsHeaders(event: H3Event, options: H3CorsOptions): void;
|
|
386
|
+
|
|
351
387
|
type RouterMethod = Lowercase<HTTPMethod>;
|
|
352
388
|
type RouterUse = (path: string, handler: EventHandler, method?: RouterMethod | RouterMethod[]) => Router;
|
|
353
389
|
type AddRouteShortcuts = Record<RouterMethod, RouterUse>;
|
|
@@ -363,4 +399,4 @@ interface CreateRouterOptions {
|
|
|
363
399
|
}
|
|
364
400
|
declare function createRouter(opts?: CreateRouterOptions): Router;
|
|
365
401
|
|
|
366
|
-
export { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, DynamicEventHandler, Encoding, EventHandler, EventHandlerResponse, H3Error, H3Event, H3EventContext, H3Headers, H3Response, HTTPMethod, InputLayer, InputStack, Layer, LazyEventHandler, MIMES, Matcher, NodeEventContext, NodeListener, NodeMiddleware, NodePromisifiedHandler, ProxyOptions, RequestHeaders, Router, RouterMethod, RouterUse, Session, SessionConfig, SessionData, Stack, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearSession, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestHeader, getRequestHeaders, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, handleCacheHeaders, isError, isEvent, isEventHandler, isMethod, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readMultipartFormData, readRawBody, sealSession, send, sendError, sendNoContent, sendProxy, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, toEventHandler, toNodeListener, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
|
|
402
|
+
export { AddRouteShortcuts, App, AppOptions, AppUse, CacheConditions, CreateRouterOptions, DynamicEventHandler, Encoding, EventHandler, EventHandlerResponse, H3CorsOptions, H3Error, H3Event, H3EventContext, H3Headers, H3Response, HTTPMethod, InputLayer, InputStack, Layer, LazyEventHandler, MIMES, Matcher, MultiPartData, NodeEventContext, NodeListener, NodeMiddleware, NodePromisifiedHandler, ProxyOptions, RequestHeaders, Router, RouterMethod, RouterUse, Session, SessionConfig, SessionData, Stack, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearSession, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestHeader, getRequestHeaders, getRequestHost, getRequestProtocol, getRequestURL, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readMultipartFormData, readRawBody, sealSession, send, sendError, sendNoContent, sendProxy, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
|
package/dist/index.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import destr from 'destr';
|
|
|
4
4
|
import { parse as parse$1, serialize } from 'cookie-es';
|
|
5
5
|
import crypto from 'uncrypto';
|
|
6
6
|
import { seal, defaults, unseal } from 'iron-webcrypto';
|
|
7
|
+
import { defu } from 'defu';
|
|
7
8
|
|
|
8
9
|
function useBase(base, handler) {
|
|
9
10
|
base = withoutTrailingSlash(base);
|
|
@@ -245,6 +246,24 @@ function getRequestHeader(event, name) {
|
|
|
245
246
|
return value;
|
|
246
247
|
}
|
|
247
248
|
const getHeader = getRequestHeader;
|
|
249
|
+
function getRequestHost(event) {
|
|
250
|
+
const xForwardedHost = event.node.req.headers["x-forwarded-host"];
|
|
251
|
+
if (xForwardedHost) {
|
|
252
|
+
return xForwardedHost;
|
|
253
|
+
}
|
|
254
|
+
return event.node.req.headers.host || "localhost";
|
|
255
|
+
}
|
|
256
|
+
function getRequestProtocol(event) {
|
|
257
|
+
if (event.node.req.headers["x-forwarded-proto"] === "https") {
|
|
258
|
+
return "https";
|
|
259
|
+
}
|
|
260
|
+
return event.node.req.connection.encrypted ? "https" : "http";
|
|
261
|
+
}
|
|
262
|
+
function getRequestURL(event) {
|
|
263
|
+
const host = getRequestHost(event);
|
|
264
|
+
const protocol = getRequestProtocol(event);
|
|
265
|
+
return new URL(event.path || "/", `${protocol}://${host}`);
|
|
266
|
+
}
|
|
248
267
|
|
|
249
268
|
const RawBodySymbol = Symbol.for("h3RawBody");
|
|
250
269
|
const ParsedBodySymbol = Symbol.for("h3ParsedBody");
|
|
@@ -377,6 +396,58 @@ function deleteCookie(event, name, serializeOptions) {
|
|
|
377
396
|
maxAge: 0
|
|
378
397
|
});
|
|
379
398
|
}
|
|
399
|
+
function splitCookiesString(cookiesString) {
|
|
400
|
+
if (typeof cookiesString !== "string") {
|
|
401
|
+
return [];
|
|
402
|
+
}
|
|
403
|
+
const cookiesStrings = [];
|
|
404
|
+
let pos = 0;
|
|
405
|
+
let start;
|
|
406
|
+
let ch;
|
|
407
|
+
let lastComma;
|
|
408
|
+
let nextStart;
|
|
409
|
+
let cookiesSeparatorFound;
|
|
410
|
+
function skipWhitespace() {
|
|
411
|
+
while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) {
|
|
412
|
+
pos += 1;
|
|
413
|
+
}
|
|
414
|
+
return pos < cookiesString.length;
|
|
415
|
+
}
|
|
416
|
+
function notSpecialChar() {
|
|
417
|
+
ch = cookiesString.charAt(pos);
|
|
418
|
+
return ch !== "=" && ch !== ";" && ch !== ",";
|
|
419
|
+
}
|
|
420
|
+
while (pos < cookiesString.length) {
|
|
421
|
+
start = pos;
|
|
422
|
+
cookiesSeparatorFound = false;
|
|
423
|
+
while (skipWhitespace()) {
|
|
424
|
+
ch = cookiesString.charAt(pos);
|
|
425
|
+
if (ch === ",") {
|
|
426
|
+
lastComma = pos;
|
|
427
|
+
pos += 1;
|
|
428
|
+
skipWhitespace();
|
|
429
|
+
nextStart = pos;
|
|
430
|
+
while (pos < cookiesString.length && notSpecialChar()) {
|
|
431
|
+
pos += 1;
|
|
432
|
+
}
|
|
433
|
+
if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
|
|
434
|
+
cookiesSeparatorFound = true;
|
|
435
|
+
pos = nextStart;
|
|
436
|
+
cookiesStrings.push(cookiesString.slice(start, lastComma));
|
|
437
|
+
start = pos;
|
|
438
|
+
} else {
|
|
439
|
+
pos = lastComma + 1;
|
|
440
|
+
}
|
|
441
|
+
} else {
|
|
442
|
+
pos += 1;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
if (!cookiesSeparatorFound || pos >= cookiesString.length) {
|
|
446
|
+
cookiesStrings.push(cookiesString.slice(start, cookiesString.length));
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
return cookiesStrings;
|
|
450
|
+
}
|
|
380
451
|
|
|
381
452
|
const PayloadMethods = /* @__PURE__ */ new Set(["PATCH", "POST", "PUT", "DELETE"]);
|
|
382
453
|
const ignoredHeaders = /* @__PURE__ */ new Set([
|
|
@@ -424,6 +495,27 @@ async function sendProxy(event, target, opts = {}) {
|
|
|
424
495
|
if (key === "content-length") {
|
|
425
496
|
continue;
|
|
426
497
|
}
|
|
498
|
+
if (key === "set-cookie") {
|
|
499
|
+
const cookies = splitCookiesString(value).map((cookie) => {
|
|
500
|
+
if (opts.cookieDomainRewrite) {
|
|
501
|
+
cookie = rewriteCookieProperty(
|
|
502
|
+
cookie,
|
|
503
|
+
opts.cookieDomainRewrite,
|
|
504
|
+
"domain"
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
if (opts.cookiePathRewrite) {
|
|
508
|
+
cookie = rewriteCookieProperty(
|
|
509
|
+
cookie,
|
|
510
|
+
opts.cookiePathRewrite,
|
|
511
|
+
"path"
|
|
512
|
+
);
|
|
513
|
+
}
|
|
514
|
+
return cookie;
|
|
515
|
+
});
|
|
516
|
+
event.node.res.setHeader("set-cookie", cookies);
|
|
517
|
+
continue;
|
|
518
|
+
}
|
|
427
519
|
event.node.res.setHeader(key, value);
|
|
428
520
|
}
|
|
429
521
|
if (response._data !== void 0) {
|
|
@@ -451,8 +543,7 @@ function getProxyRequestHeaders(event) {
|
|
|
451
543
|
function fetchWithEvent(event, req, init, options) {
|
|
452
544
|
return _getFetch(options?.fetch)(req, {
|
|
453
545
|
...init,
|
|
454
|
-
|
|
455
|
-
context: init.context || event.context,
|
|
546
|
+
context: init?.context || event.context,
|
|
456
547
|
headers: {
|
|
457
548
|
...getProxyRequestHeaders(event),
|
|
458
549
|
...init?.headers
|
|
@@ -470,6 +561,23 @@ function _getFetch(_fetch) {
|
|
|
470
561
|
"fetch is not available. Try importing `node-fetch-native/polyfill` for Node.js."
|
|
471
562
|
);
|
|
472
563
|
}
|
|
564
|
+
function rewriteCookieProperty(header, map, property) {
|
|
565
|
+
const _map = typeof map === "string" ? { "*": map } : map;
|
|
566
|
+
return header.replace(
|
|
567
|
+
new RegExp(`(;\\s*${property}=)([^;]+)`, "gi"),
|
|
568
|
+
(match, prefix, previousValue) => {
|
|
569
|
+
let newValue;
|
|
570
|
+
if (previousValue in _map) {
|
|
571
|
+
newValue = _map[previousValue];
|
|
572
|
+
} else if ("*" in _map) {
|
|
573
|
+
newValue = _map["*"];
|
|
574
|
+
} else {
|
|
575
|
+
return match;
|
|
576
|
+
}
|
|
577
|
+
return newValue ? prefix + newValue : "";
|
|
578
|
+
}
|
|
579
|
+
);
|
|
580
|
+
}
|
|
473
581
|
|
|
474
582
|
const defer = typeof setImmediate !== "undefined" ? setImmediate : (fn) => fn();
|
|
475
583
|
function send(event, data, type) {
|
|
@@ -728,6 +836,120 @@ async function clearSession(event, config) {
|
|
|
728
836
|
});
|
|
729
837
|
}
|
|
730
838
|
|
|
839
|
+
function resolveCorsOptions(options = {}) {
|
|
840
|
+
const defaultOptions = {
|
|
841
|
+
origin: "*",
|
|
842
|
+
methods: "*",
|
|
843
|
+
allowHeaders: "*",
|
|
844
|
+
exposeHeaders: "*",
|
|
845
|
+
credentials: false,
|
|
846
|
+
maxAge: false,
|
|
847
|
+
preflight: {
|
|
848
|
+
statusCode: 204
|
|
849
|
+
}
|
|
850
|
+
};
|
|
851
|
+
return defu(options, defaultOptions);
|
|
852
|
+
}
|
|
853
|
+
function isPreflightRequest(event) {
|
|
854
|
+
const method = getMethod(event);
|
|
855
|
+
const origin = getRequestHeader(event, "origin");
|
|
856
|
+
const accessControlRequestMethod = getRequestHeader(
|
|
857
|
+
event,
|
|
858
|
+
"access-control-request-method"
|
|
859
|
+
);
|
|
860
|
+
return method === "OPTIONS" && !!origin && !!accessControlRequestMethod;
|
|
861
|
+
}
|
|
862
|
+
function isCorsOriginAllowed(origin, options) {
|
|
863
|
+
const { origin: originOption } = options;
|
|
864
|
+
if (!origin || !originOption || originOption === "*" || originOption === "null") {
|
|
865
|
+
return true;
|
|
866
|
+
}
|
|
867
|
+
if (Array.isArray(originOption)) {
|
|
868
|
+
return originOption.some((_origin) => {
|
|
869
|
+
if (_origin instanceof RegExp) {
|
|
870
|
+
return _origin.test(origin);
|
|
871
|
+
}
|
|
872
|
+
return origin === _origin;
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
return originOption(origin);
|
|
876
|
+
}
|
|
877
|
+
function createOriginHeaders(event, options) {
|
|
878
|
+
const { origin: originOption } = options;
|
|
879
|
+
const origin = getRequestHeader(event, "origin");
|
|
880
|
+
if (!origin || !originOption || originOption === "*") {
|
|
881
|
+
return { "access-control-allow-origin": "*" };
|
|
882
|
+
}
|
|
883
|
+
if (typeof originOption === "string") {
|
|
884
|
+
return { "access-control-allow-origin": originOption, vary: "origin" };
|
|
885
|
+
}
|
|
886
|
+
return isCorsOriginAllowed(origin, options) ? { "access-control-allow-origin": origin, vary: "origin" } : {};
|
|
887
|
+
}
|
|
888
|
+
function createMethodsHeaders(options) {
|
|
889
|
+
const { methods } = options;
|
|
890
|
+
if (!methods) {
|
|
891
|
+
return {};
|
|
892
|
+
}
|
|
893
|
+
if (methods === "*") {
|
|
894
|
+
return { "access-control-allow-methods": "*" };
|
|
895
|
+
}
|
|
896
|
+
return methods.length > 0 ? { "access-control-allow-methods": methods.join(",") } : {};
|
|
897
|
+
}
|
|
898
|
+
function createCredentialsHeaders(options) {
|
|
899
|
+
const { credentials } = options;
|
|
900
|
+
if (credentials) {
|
|
901
|
+
return { "access-control-allow-credentials": "true" };
|
|
902
|
+
}
|
|
903
|
+
return {};
|
|
904
|
+
}
|
|
905
|
+
function createAllowHeaderHeaders(event, options) {
|
|
906
|
+
const { allowHeaders } = options;
|
|
907
|
+
if (!allowHeaders || allowHeaders === "*" || allowHeaders.length === 0) {
|
|
908
|
+
const header = getRequestHeader(event, "access-control-request-headers");
|
|
909
|
+
return header ? {
|
|
910
|
+
"access-control-allow-headers": header,
|
|
911
|
+
vary: "access-control-request-headers"
|
|
912
|
+
} : {};
|
|
913
|
+
}
|
|
914
|
+
return {
|
|
915
|
+
"access-control-allow-headers": allowHeaders.join(","),
|
|
916
|
+
vary: "access-control-request-headers"
|
|
917
|
+
};
|
|
918
|
+
}
|
|
919
|
+
function createExposeHeaders(options) {
|
|
920
|
+
const { exposeHeaders } = options;
|
|
921
|
+
if (!exposeHeaders) {
|
|
922
|
+
return {};
|
|
923
|
+
}
|
|
924
|
+
if (exposeHeaders === "*") {
|
|
925
|
+
return { "access-control-expose-headers": exposeHeaders };
|
|
926
|
+
}
|
|
927
|
+
return { "access-control-expose-headers": exposeHeaders.join(",") };
|
|
928
|
+
}
|
|
929
|
+
function appendCorsPreflightHeaders(event, options) {
|
|
930
|
+
appendHeaders(event, createOriginHeaders(event, options));
|
|
931
|
+
appendHeaders(event, createCredentialsHeaders(options));
|
|
932
|
+
appendHeaders(event, createExposeHeaders(options));
|
|
933
|
+
appendHeaders(event, createMethodsHeaders(options));
|
|
934
|
+
appendHeaders(event, createAllowHeaderHeaders(event, options));
|
|
935
|
+
}
|
|
936
|
+
function appendCorsHeaders(event, options) {
|
|
937
|
+
appendHeaders(event, createOriginHeaders(event, options));
|
|
938
|
+
appendHeaders(event, createCredentialsHeaders(options));
|
|
939
|
+
appendHeaders(event, createExposeHeaders(options));
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
function handleCors(event, options) {
|
|
943
|
+
const _options = resolveCorsOptions(options);
|
|
944
|
+
if (isPreflightRequest(event)) {
|
|
945
|
+
appendCorsPreflightHeaders(event, options);
|
|
946
|
+
sendNoContent(event, _options.preflight.statusCode);
|
|
947
|
+
return true;
|
|
948
|
+
}
|
|
949
|
+
appendCorsHeaders(event, options);
|
|
950
|
+
return false;
|
|
951
|
+
}
|
|
952
|
+
|
|
731
953
|
class H3Headers {
|
|
732
954
|
constructor(init) {
|
|
733
955
|
if (!init) {
|
|
@@ -1177,4 +1399,4 @@ function createRouter(opts = {}) {
|
|
|
1177
1399
|
return router;
|
|
1178
1400
|
}
|
|
1179
1401
|
|
|
1180
|
-
export { H3Error, H3Event, H3Headers, H3Response, MIMES, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearSession, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestHeader, getRequestHeaders, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, handleCacheHeaders, isError, isEvent, isEventHandler, isMethod, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readMultipartFormData, readRawBody, sealSession, send, sendError, sendNoContent, sendProxy, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, toEventHandler, toNodeListener, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
|
|
1402
|
+
export { H3Error, H3Event, H3Headers, H3Response, MIMES, appendCorsHeaders, appendCorsPreflightHeaders, appendHeader, appendHeaders, appendResponseHeader, appendResponseHeaders, assertMethod, callNodeListener, clearSession, createApp, createAppEventHandler, createError, createEvent, createRouter, defaultContentType, defineEventHandler, defineLazyEventHandler, defineNodeListener, defineNodeMiddleware, deleteCookie, dynamicEventHandler, eventHandler, fetchWithEvent, fromNodeMiddleware, getCookie, getHeader, getHeaders, getMethod, getProxyRequestHeaders, getQuery, getRequestHeader, getRequestHeaders, getRequestHost, getRequestProtocol, getRequestURL, getResponseHeader, getResponseHeaders, getResponseStatus, getResponseStatusText, getRouterParam, getRouterParams, getSession, handleCacheHeaders, handleCors, isCorsOriginAllowed, isError, isEvent, isEventHandler, isMethod, isPreflightRequest, isStream, lazyEventHandler, parseCookies, promisifyNodeListener, proxyRequest, readBody, readMultipartFormData, readRawBody, sealSession, send, sendError, sendNoContent, sendProxy, sendRedirect, sendStream, setCookie, setHeader, setHeaders, setResponseHeader, setResponseHeaders, setResponseStatus, splitCookiesString, toEventHandler, toNodeListener, unsealSession, updateSession, use, useBase, useSession, writeEarlyHints };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "h3",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Tiny JavaScript Server",
|
|
5
5
|
"repository": "unjs/h3",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,39 +21,41 @@
|
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"cookie-es": "^0.5.0",
|
|
24
|
+
"defu": "^6.1.2",
|
|
24
25
|
"destr": "^1.2.2",
|
|
25
|
-
"iron-webcrypto": "^0.
|
|
26
|
+
"iron-webcrypto": "^0.5.0",
|
|
26
27
|
"radix3": "^1.0.0",
|
|
27
|
-
"ufo": "^1.
|
|
28
|
+
"ufo": "^1.1.1",
|
|
28
29
|
"uncrypto": "^0.1.2"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
|
-
"0x": "^5.
|
|
32
|
+
"0x": "^5.5.0",
|
|
32
33
|
"@types/express": "^4.17.17",
|
|
33
|
-
"@types/node": "^18.
|
|
34
|
+
"@types/node": "^18.15.0",
|
|
34
35
|
"@types/supertest": "^2.0.12",
|
|
35
|
-
"@vitest/coverage-c8": "^0.
|
|
36
|
+
"@vitest/coverage-c8": "^0.29.2",
|
|
36
37
|
"autocannon": "^7.10.0",
|
|
37
|
-
"changelogen": "^0.
|
|
38
|
+
"changelogen": "^0.5.1",
|
|
38
39
|
"connect": "^3.7.0",
|
|
39
|
-
"eslint": "^8.
|
|
40
|
+
"eslint": "^8.35.0",
|
|
40
41
|
"eslint-config-unjs": "^0.1.0",
|
|
41
42
|
"express": "^4.18.2",
|
|
42
43
|
"get-port": "^6.1.2",
|
|
43
|
-
"jiti": "^1.
|
|
44
|
-
"listhen": "^1.0.
|
|
45
|
-
"node-fetch-native": "^1.0.
|
|
44
|
+
"jiti": "^1.17.2",
|
|
45
|
+
"listhen": "^1.0.3",
|
|
46
|
+
"node-fetch-native": "^1.0.2",
|
|
46
47
|
"prettier": "^2.8.4",
|
|
47
48
|
"supertest": "^6.3.3",
|
|
48
49
|
"typescript": "^4.9.5",
|
|
49
|
-
"unbuild": "^1.1.
|
|
50
|
-
"vitest": "^0.
|
|
50
|
+
"unbuild": "^1.1.2",
|
|
51
|
+
"vitest": "^0.29.2"
|
|
51
52
|
},
|
|
52
|
-
"packageManager": "pnpm@7.
|
|
53
|
+
"packageManager": "pnpm@7.29.0",
|
|
53
54
|
"scripts": {
|
|
54
55
|
"build": "unbuild",
|
|
55
56
|
"dev": "vitest",
|
|
56
|
-
"lint": "eslint --ext ts
|
|
57
|
+
"lint": "eslint --cache --ext .ts,.js,.mjs,.cjs . && prettier -c src test playground",
|
|
58
|
+
"lint:fix": "eslint --cache --ext .ts,.js,.mjs,.cjs . --fix && prettier -c src test playground -w",
|
|
57
59
|
"play": "jiti ./playground/index.ts",
|
|
58
60
|
"profile": "0x -o -D .profile -P 'autocannon -c 100 -p 10 -d 40 http://localhost:$PORT' ./playground/server.cjs",
|
|
59
61
|
"release": "pnpm test && pnpm build && changelogen --release && pnpm publish && git push --follow-tags",
|