h3 1.15.4 → 1.15.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +30 -11
- package/dist/index.mjs +30 -11
- package/package.json +39 -36
package/dist/index.cjs
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
const ufo = require('ufo');
|
|
4
4
|
const cookieEs = require('cookie-es');
|
|
5
5
|
const radix3 = require('radix3');
|
|
6
|
-
const destr = require('destr');
|
|
7
6
|
const defu = require('defu');
|
|
7
|
+
const destr = require('destr');
|
|
8
8
|
const crypto = require('uncrypto');
|
|
9
9
|
const ironWebcrypto = require('iron-webcrypto');
|
|
10
10
|
const nodeMockHttp = require('node-mock-http');
|
|
@@ -418,7 +418,9 @@ function readRawBody(event, encoding = "utf8") {
|
|
|
418
418
|
});
|
|
419
419
|
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
|
|
420
420
|
}
|
|
421
|
-
if (!Number.parseInt(event.node.req.headers["content-length"] || "") &&
|
|
421
|
+
if (!Number.parseInt(event.node.req.headers["content-length"] || "") && !/\bchunked\b/i.test(
|
|
422
|
+
String(event.node.req.headers["transfer-encoding"] ?? "")
|
|
423
|
+
)) {
|
|
422
424
|
return Promise.resolve(void 0);
|
|
423
425
|
}
|
|
424
426
|
const promise = event.node.req[RawBodySymbol] = new Promise(
|
|
@@ -1440,11 +1442,16 @@ async function updateSession(event, config, update) {
|
|
|
1440
1442
|
async function sealSession(event, config) {
|
|
1441
1443
|
const sessionName = config.name || DEFAULT_NAME;
|
|
1442
1444
|
const session = event.context.sessions?.[sessionName] || await getSession(event, config);
|
|
1443
|
-
const sealed = await ironWebcrypto.seal(
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1445
|
+
const sealed = await ironWebcrypto.seal(
|
|
1446
|
+
config.crypto || crypto__default,
|
|
1447
|
+
session,
|
|
1448
|
+
config.password,
|
|
1449
|
+
{
|
|
1450
|
+
...ironWebcrypto.defaults,
|
|
1451
|
+
ttl: config.maxAge ? config.maxAge * 1e3 : 0,
|
|
1452
|
+
...config.seal
|
|
1453
|
+
}
|
|
1454
|
+
);
|
|
1448
1455
|
return sealed;
|
|
1449
1456
|
}
|
|
1450
1457
|
async function unsealSession(_event, config, sealed) {
|
|
@@ -1481,22 +1488,28 @@ function clearSession(event, config) {
|
|
|
1481
1488
|
function formatEventStreamMessage(message) {
|
|
1482
1489
|
let result = "";
|
|
1483
1490
|
if (message.id) {
|
|
1484
|
-
result += `id: ${message.id}
|
|
1491
|
+
result += `id: ${_sanitizeSingleLine(message.id)}
|
|
1485
1492
|
`;
|
|
1486
1493
|
}
|
|
1487
1494
|
if (message.event) {
|
|
1488
|
-
result += `event: ${message.event}
|
|
1495
|
+
result += `event: ${_sanitizeSingleLine(message.event)}
|
|
1489
1496
|
`;
|
|
1490
1497
|
}
|
|
1491
1498
|
if (typeof message.retry === "number" && Number.isInteger(message.retry)) {
|
|
1492
1499
|
result += `retry: ${message.retry}
|
|
1493
1500
|
`;
|
|
1494
1501
|
}
|
|
1495
|
-
|
|
1496
|
-
|
|
1502
|
+
const data = typeof message.data === "string" ? message.data : "";
|
|
1503
|
+
for (const line of data.split("\n")) {
|
|
1504
|
+
result += `data: ${line}
|
|
1497
1505
|
`;
|
|
1506
|
+
}
|
|
1507
|
+
result += "\n";
|
|
1498
1508
|
return result;
|
|
1499
1509
|
}
|
|
1510
|
+
function _sanitizeSingleLine(value) {
|
|
1511
|
+
return value.replace(/[\n\r]/g, "");
|
|
1512
|
+
}
|
|
1500
1513
|
function formatEventStreamMessages(messages) {
|
|
1501
1514
|
let result = "";
|
|
1502
1515
|
for (const msg of messages) {
|
|
@@ -1661,6 +1674,12 @@ async function serveStatic(event, options) {
|
|
|
1661
1674
|
const originalId = ufo.decodePath(
|
|
1662
1675
|
ufo.withLeadingSlash(ufo.withoutTrailingSlash(ufo.parseURL(event.path).pathname))
|
|
1663
1676
|
);
|
|
1677
|
+
if (originalId.includes("..")) {
|
|
1678
|
+
if (!options.fallthrough) {
|
|
1679
|
+
throw createError({ statusCode: 404 });
|
|
1680
|
+
}
|
|
1681
|
+
return false;
|
|
1682
|
+
}
|
|
1664
1683
|
const acceptEncodings = parseAcceptEncoding(
|
|
1665
1684
|
getRequestHeader(event, "accept-encoding"),
|
|
1666
1685
|
options.encodings
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { withoutTrailingSlash, withoutBase, getQuery as getQuery$1, decode, decodePath, withLeadingSlash, parseURL, joinURL } from 'ufo';
|
|
2
2
|
import { parse as parse$1, serialize, parseSetCookie } from 'cookie-es';
|
|
3
3
|
import { createRouter as createRouter$1, toRouteMatcher } from 'radix3';
|
|
4
|
-
import destr from 'destr';
|
|
5
4
|
import { defu } from 'defu';
|
|
5
|
+
import destr from 'destr';
|
|
6
6
|
import crypto from 'uncrypto';
|
|
7
7
|
import { seal, defaults, unseal } from 'iron-webcrypto';
|
|
8
8
|
import { IncomingMessage, ServerResponse } from 'node-mock-http';
|
|
@@ -411,7 +411,9 @@ function readRawBody(event, encoding = "utf8") {
|
|
|
411
411
|
});
|
|
412
412
|
return encoding ? promise2.then((buff) => buff.toString(encoding)) : promise2;
|
|
413
413
|
}
|
|
414
|
-
if (!Number.parseInt(event.node.req.headers["content-length"] || "") &&
|
|
414
|
+
if (!Number.parseInt(event.node.req.headers["content-length"] || "") && !/\bchunked\b/i.test(
|
|
415
|
+
String(event.node.req.headers["transfer-encoding"] ?? "")
|
|
416
|
+
)) {
|
|
415
417
|
return Promise.resolve(void 0);
|
|
416
418
|
}
|
|
417
419
|
const promise = event.node.req[RawBodySymbol] = new Promise(
|
|
@@ -1433,11 +1435,16 @@ async function updateSession(event, config, update) {
|
|
|
1433
1435
|
async function sealSession(event, config) {
|
|
1434
1436
|
const sessionName = config.name || DEFAULT_NAME;
|
|
1435
1437
|
const session = event.context.sessions?.[sessionName] || await getSession(event, config);
|
|
1436
|
-
const sealed = await seal(
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1438
|
+
const sealed = await seal(
|
|
1439
|
+
config.crypto || crypto,
|
|
1440
|
+
session,
|
|
1441
|
+
config.password,
|
|
1442
|
+
{
|
|
1443
|
+
...defaults,
|
|
1444
|
+
ttl: config.maxAge ? config.maxAge * 1e3 : 0,
|
|
1445
|
+
...config.seal
|
|
1446
|
+
}
|
|
1447
|
+
);
|
|
1441
1448
|
return sealed;
|
|
1442
1449
|
}
|
|
1443
1450
|
async function unsealSession(_event, config, sealed) {
|
|
@@ -1474,22 +1481,28 @@ function clearSession(event, config) {
|
|
|
1474
1481
|
function formatEventStreamMessage(message) {
|
|
1475
1482
|
let result = "";
|
|
1476
1483
|
if (message.id) {
|
|
1477
|
-
result += `id: ${message.id}
|
|
1484
|
+
result += `id: ${_sanitizeSingleLine(message.id)}
|
|
1478
1485
|
`;
|
|
1479
1486
|
}
|
|
1480
1487
|
if (message.event) {
|
|
1481
|
-
result += `event: ${message.event}
|
|
1488
|
+
result += `event: ${_sanitizeSingleLine(message.event)}
|
|
1482
1489
|
`;
|
|
1483
1490
|
}
|
|
1484
1491
|
if (typeof message.retry === "number" && Number.isInteger(message.retry)) {
|
|
1485
1492
|
result += `retry: ${message.retry}
|
|
1486
1493
|
`;
|
|
1487
1494
|
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1495
|
+
const data = typeof message.data === "string" ? message.data : "";
|
|
1496
|
+
for (const line of data.split("\n")) {
|
|
1497
|
+
result += `data: ${line}
|
|
1490
1498
|
`;
|
|
1499
|
+
}
|
|
1500
|
+
result += "\n";
|
|
1491
1501
|
return result;
|
|
1492
1502
|
}
|
|
1503
|
+
function _sanitizeSingleLine(value) {
|
|
1504
|
+
return value.replace(/[\n\r]/g, "");
|
|
1505
|
+
}
|
|
1493
1506
|
function formatEventStreamMessages(messages) {
|
|
1494
1507
|
let result = "";
|
|
1495
1508
|
for (const msg of messages) {
|
|
@@ -1654,6 +1667,12 @@ async function serveStatic(event, options) {
|
|
|
1654
1667
|
const originalId = decodePath(
|
|
1655
1668
|
withLeadingSlash(withoutTrailingSlash(parseURL(event.path).pathname))
|
|
1656
1669
|
);
|
|
1670
|
+
if (originalId.includes("..")) {
|
|
1671
|
+
if (!options.fallthrough) {
|
|
1672
|
+
throw createError({ statusCode: 404 });
|
|
1673
|
+
}
|
|
1674
|
+
return false;
|
|
1675
|
+
}
|
|
1657
1676
|
const acceptEncodings = parseAcceptEncoding(
|
|
1658
1677
|
getRequestHeader(event, "accept-encoding"),
|
|
1659
1678
|
options.encodings
|
package/package.json
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "h3",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.6",
|
|
4
4
|
"description": "Minimal H(TTP) framework built for high performance and portability.",
|
|
5
|
-
"repository": "h3js/h3",
|
|
6
5
|
"license": "MIT",
|
|
6
|
+
"repository": "h3js/h3",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
7
10
|
"sideEffects": false,
|
|
11
|
+
"main": "./dist/index.cjs",
|
|
12
|
+
"module": "./dist/index.mjs",
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
8
14
|
"exports": {
|
|
9
15
|
"./package.json": "./package.json",
|
|
10
16
|
".": {
|
|
@@ -13,24 +19,17 @@
|
|
|
13
19
|
"require": "./dist/index.cjs"
|
|
14
20
|
}
|
|
15
21
|
},
|
|
16
|
-
"main": "./dist/index.cjs",
|
|
17
|
-
"module": "./dist/index.mjs",
|
|
18
|
-
"types": "./dist/index.d.ts",
|
|
19
|
-
"files": [
|
|
20
|
-
"dist"
|
|
21
|
-
],
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "unbuild",
|
|
24
24
|
"dev": "vitest",
|
|
25
25
|
"lint": "eslint --cache . && prettier -c src test playground examples docs",
|
|
26
26
|
"lint:fix": "eslint --cache . --fix && prettier -c src test playground examples docs -w",
|
|
27
|
+
"prepack": "pnpm build",
|
|
27
28
|
"play": "listhen -w ./playground/app.ts",
|
|
28
29
|
"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
|
|
30
|
-
"test": "pnpm lint && vitest --run --coverage"
|
|
31
|
-
|
|
32
|
-
"resolutions": {
|
|
33
|
-
"h3": "^1.14.0"
|
|
30
|
+
"release": "pnpm test && pnpm build && changelogen --release --publish --publishTag 1x && git push --follow-tags",
|
|
31
|
+
"test": "pnpm lint && vitest --run --coverage && pnpm test:types",
|
|
32
|
+
"test:types": "tsgo --noEmit"
|
|
34
33
|
},
|
|
35
34
|
"dependencies": {
|
|
36
35
|
"cookie-es": "^1.2.2",
|
|
@@ -38,38 +37,42 @@
|
|
|
38
37
|
"defu": "^6.1.4",
|
|
39
38
|
"destr": "^2.0.5",
|
|
40
39
|
"iron-webcrypto": "^1.2.1",
|
|
41
|
-
"node-mock-http": "^1.0.
|
|
40
|
+
"node-mock-http": "^1.0.4",
|
|
42
41
|
"radix3": "^1.1.2",
|
|
43
|
-
"ufo": "^1.6.
|
|
42
|
+
"ufo": "^1.6.3",
|
|
44
43
|
"uncrypto": "^0.1.3"
|
|
45
44
|
},
|
|
46
45
|
"devDependencies": {
|
|
47
46
|
"0x": "^6.0.0",
|
|
48
|
-
"@types/express": "^5.0.
|
|
49
|
-
"@types/node": "^
|
|
50
|
-
"@types/supertest": "^
|
|
51
|
-
"@
|
|
47
|
+
"@types/express": "^5.0.6",
|
|
48
|
+
"@types/node": "^25.3.5",
|
|
49
|
+
"@types/supertest": "^7.2.0",
|
|
50
|
+
"@typescript/native-preview": "latest",
|
|
51
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
52
52
|
"autocannon": "^8.0.0",
|
|
53
|
-
"automd": "^0.4.
|
|
53
|
+
"automd": "^0.4.3",
|
|
54
54
|
"changelogen": "^0.6.2",
|
|
55
55
|
"connect": "^3.7.0",
|
|
56
|
-
"eslint": "^
|
|
57
|
-
"eslint-config-unjs": "^0.
|
|
58
|
-
"express": "^5.1
|
|
56
|
+
"eslint": "^10.0.3",
|
|
57
|
+
"eslint-config-unjs": "^0.6.2",
|
|
58
|
+
"express": "^5.2.1",
|
|
59
59
|
"get-port": "^7.1.0",
|
|
60
|
-
"h3": "^1.15.
|
|
61
|
-
"jiti": "^2.
|
|
60
|
+
"h3": "^1.15.5",
|
|
61
|
+
"jiti": "^2.6.1",
|
|
62
62
|
"listhen": "^1.9.0",
|
|
63
|
-
"node-fetch-native": "^1.6.
|
|
64
|
-
"prettier": "^3.
|
|
65
|
-
"react": "^19.
|
|
66
|
-
"react-dom": "^19.
|
|
67
|
-
"supertest": "^7.
|
|
68
|
-
"typescript": "^5.
|
|
69
|
-
"unbuild": "^3.6.
|
|
70
|
-
"undici": "^7.
|
|
71
|
-
"vitest": "^
|
|
72
|
-
"zod": "^4.
|
|
63
|
+
"node-fetch-native": "^1.6.7",
|
|
64
|
+
"prettier": "^3.8.1",
|
|
65
|
+
"react": "^19.2.4",
|
|
66
|
+
"react-dom": "^19.2.4",
|
|
67
|
+
"supertest": "^7.2.2",
|
|
68
|
+
"typescript": "^5.9.3",
|
|
69
|
+
"unbuild": "^3.6.1",
|
|
70
|
+
"undici": "^7.22.0",
|
|
71
|
+
"vitest": "^4.0.18",
|
|
72
|
+
"zod": "^4.3.6"
|
|
73
|
+
},
|
|
74
|
+
"resolutions": {
|
|
75
|
+
"h3": "^1.14.0"
|
|
73
76
|
},
|
|
74
|
-
"packageManager": "pnpm@10.
|
|
77
|
+
"packageManager": "pnpm@10.28.0"
|
|
75
78
|
}
|