hono 4.12.29 → 4.12.31
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/cjs/client/utils.js +1 -1
- package/dist/cjs/helper/streaming/sse.js +4 -3
- package/dist/cjs/middleware/cache/index.js +1 -1
- package/dist/cjs/middleware/compress/index.js +2 -1
- package/dist/cjs/middleware/method-override/index.js +5 -3
- package/dist/cjs/request.js +7 -2
- package/dist/cjs/utils/body.js +6 -0
- package/dist/client/utils.js +1 -1
- package/dist/helper/streaming/sse.js +4 -3
- package/dist/middleware/cache/index.js +1 -1
- package/dist/middleware/compress/index.js +2 -1
- package/dist/middleware/method-override/index.js +5 -3
- package/dist/request.js +7 -2
- package/dist/types/helper/websocket/index.d.ts +1 -1
- package/dist/types/middleware/combine/index.d.ts +1 -1
- package/dist/utils/body.js +6 -0
- package/package.json +3 -3
package/dist/cjs/client/utils.js
CHANGED
|
@@ -36,7 +36,7 @@ const mergePath = (base, path) => {
|
|
|
36
36
|
};
|
|
37
37
|
const replaceUrlParam = (urlString, params) => {
|
|
38
38
|
for (const [k, v] of Object.entries(params)) {
|
|
39
|
-
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??");
|
|
39
|
+
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??(?=/|$)");
|
|
40
40
|
urlString = urlString.replace(reg, v ? `/${v}` : "");
|
|
41
41
|
}
|
|
42
42
|
return urlString;
|
|
@@ -33,8 +33,9 @@ class SSEStreamingApi extends import_stream.StreamingApi {
|
|
|
33
33
|
const dataLines = data.split(/\r\n|\r|\n/).map((line) => {
|
|
34
34
|
return `data: ${line}`;
|
|
35
35
|
}).join("\n");
|
|
36
|
-
for (const key of ["event", "id"
|
|
37
|
-
|
|
36
|
+
for (const key of ["event", "id"]) {
|
|
37
|
+
const value = message[key];
|
|
38
|
+
if (value && /[\r\n]/.test(value)) {
|
|
38
39
|
throw new Error(`${key} must not contain "\\r" or "\\n"`);
|
|
39
40
|
}
|
|
40
41
|
}
|
|
@@ -42,7 +43,7 @@ class SSEStreamingApi extends import_stream.StreamingApi {
|
|
|
42
43
|
message.event && `event: ${message.event}`,
|
|
43
44
|
dataLines,
|
|
44
45
|
message.id && `id: ${message.id}`,
|
|
45
|
-
message.retry && `retry: ${message.retry}`
|
|
46
|
+
message.retry !== void 0 && `retry: ${message.retry}`
|
|
46
47
|
].filter(Boolean).join("\n") + "\n\n";
|
|
47
48
|
await this.write(sseData);
|
|
48
49
|
}
|
|
@@ -55,7 +55,7 @@ const cache = (options) => {
|
|
|
55
55
|
);
|
|
56
56
|
const addHeader = (c, responseVary) => {
|
|
57
57
|
if (cacheControlDirectives) {
|
|
58
|
-
const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0]) ?? [];
|
|
58
|
+
const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0].toLowerCase()) ?? [];
|
|
59
59
|
for (const directive of cacheControlDirectives) {
|
|
60
60
|
let [name, value] = directive.trim().split("=", 2);
|
|
61
61
|
name = name.toLowerCase();
|
|
@@ -57,7 +57,8 @@ const compress = (options) => {
|
|
|
57
57
|
return async function compress2(ctx, next) {
|
|
58
58
|
await next();
|
|
59
59
|
const contentLength = ctx.res.headers.get("Content-Length");
|
|
60
|
-
if (ctx.res.
|
|
60
|
+
if (ctx.res.status === 206 || // partial content, Content-Range refers to the uncompressed bytes
|
|
61
|
+
ctx.res.headers.has("Content-Encoding") || // already encoded
|
|
61
62
|
ctx.res.headers.has("Transfer-Encoding") || // already encoded or chunked
|
|
62
63
|
ctx.req.method === "HEAD" || // HEAD request
|
|
63
64
|
contentLength && Number(contentLength) < threshold || // content-length below threshold
|
|
@@ -80,11 +80,13 @@ const methodOverride = (options) => async function methodOverride2(c, next) {
|
|
|
80
80
|
if (method) {
|
|
81
81
|
const url = new URL(c.req.url);
|
|
82
82
|
url.searchParams.delete(queryName);
|
|
83
|
-
const
|
|
83
|
+
const requestInit = {
|
|
84
84
|
body: c.req.raw.body,
|
|
85
85
|
headers: c.req.raw.headers,
|
|
86
|
-
method
|
|
87
|
-
|
|
86
|
+
method,
|
|
87
|
+
duplex: c.req.raw.body ? "half" : void 0
|
|
88
|
+
};
|
|
89
|
+
const request = new Request(url.toString(), requestInit);
|
|
88
90
|
return app.fetch(request, c.env, getExecutionCtx(c));
|
|
89
91
|
}
|
|
90
92
|
}
|
package/dist/cjs/request.js
CHANGED
|
@@ -316,11 +316,16 @@ const cloneRawRequest = async (req) => {
|
|
|
316
316
|
message: "Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly."
|
|
317
317
|
});
|
|
318
318
|
}
|
|
319
|
+
const body = await req[cacheKey]();
|
|
320
|
+
const headers = req.header();
|
|
321
|
+
if (body instanceof FormData) {
|
|
322
|
+
delete headers["content-type"];
|
|
323
|
+
}
|
|
319
324
|
const requestInit = {
|
|
320
|
-
body
|
|
325
|
+
body,
|
|
321
326
|
cache: req.raw.cache,
|
|
322
327
|
credentials: req.raw.credentials,
|
|
323
|
-
headers
|
|
328
|
+
headers,
|
|
324
329
|
integrity: req.raw.integrity,
|
|
325
330
|
keepalive: req.raw.keepalive,
|
|
326
331
|
method: req.method,
|
package/dist/cjs/utils/body.js
CHANGED
|
@@ -33,6 +33,12 @@ const parseBody = async (request, options = /* @__PURE__ */ Object.create(null))
|
|
|
33
33
|
return {};
|
|
34
34
|
};
|
|
35
35
|
async function parseFormData(request, options) {
|
|
36
|
+
if (!isRawRequest(request) && request.bodyCache.formData) {
|
|
37
|
+
return convertFormDataToBodyData(
|
|
38
|
+
await request.bodyCache.formData,
|
|
39
|
+
options
|
|
40
|
+
);
|
|
41
|
+
}
|
|
36
42
|
const headers = isRawRequest(request) ? request.headers : request.raw.headers;
|
|
37
43
|
const arrayBuffer = await request.arrayBuffer();
|
|
38
44
|
const formDataPromise = (0, import_buffer.bufferToFormData)(arrayBuffer, headers.get("Content-Type") || "");
|
package/dist/client/utils.js
CHANGED
|
@@ -8,7 +8,7 @@ var mergePath = (base, path) => {
|
|
|
8
8
|
};
|
|
9
9
|
var replaceUrlParam = (urlString, params) => {
|
|
10
10
|
for (const [k, v] of Object.entries(params)) {
|
|
11
|
-
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??");
|
|
11
|
+
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??(?=/|$)");
|
|
12
12
|
urlString = urlString.replace(reg, v ? `/${v}` : "");
|
|
13
13
|
}
|
|
14
14
|
return urlString;
|
|
@@ -11,8 +11,9 @@ var SSEStreamingApi = class extends StreamingApi {
|
|
|
11
11
|
const dataLines = data.split(/\r\n|\r|\n/).map((line) => {
|
|
12
12
|
return `data: ${line}`;
|
|
13
13
|
}).join("\n");
|
|
14
|
-
for (const key of ["event", "id"
|
|
15
|
-
|
|
14
|
+
for (const key of ["event", "id"]) {
|
|
15
|
+
const value = message[key];
|
|
16
|
+
if (value && /[\r\n]/.test(value)) {
|
|
16
17
|
throw new Error(`${key} must not contain "\\r" or "\\n"`);
|
|
17
18
|
}
|
|
18
19
|
}
|
|
@@ -20,7 +21,7 @@ var SSEStreamingApi = class extends StreamingApi {
|
|
|
20
21
|
message.event && `event: ${message.event}`,
|
|
21
22
|
dataLines,
|
|
22
23
|
message.id && `id: ${message.id}`,
|
|
23
|
-
message.retry && `retry: ${message.retry}`
|
|
24
|
+
message.retry !== void 0 && `retry: ${message.retry}`
|
|
24
25
|
].filter(Boolean).join("\n") + "\n\n";
|
|
25
26
|
await this.write(sseData);
|
|
26
27
|
}
|
|
@@ -34,7 +34,7 @@ var cache = (options) => {
|
|
|
34
34
|
);
|
|
35
35
|
const addHeader = (c, responseVary) => {
|
|
36
36
|
if (cacheControlDirectives) {
|
|
37
|
-
const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0]) ?? [];
|
|
37
|
+
const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0].toLowerCase()) ?? [];
|
|
38
38
|
for (const directive of cacheControlDirectives) {
|
|
39
39
|
let [name, value] = directive.trim().split("=", 2);
|
|
40
40
|
name = name.toLowerCase();
|
|
@@ -35,7 +35,8 @@ var compress = (options) => {
|
|
|
35
35
|
return async function compress2(ctx, next) {
|
|
36
36
|
await next();
|
|
37
37
|
const contentLength = ctx.res.headers.get("Content-Length");
|
|
38
|
-
if (ctx.res.
|
|
38
|
+
if (ctx.res.status === 206 || // partial content, Content-Range refers to the uncompressed bytes
|
|
39
|
+
ctx.res.headers.has("Content-Encoding") || // already encoded
|
|
39
40
|
ctx.res.headers.has("Transfer-Encoding") || // already encoded or chunked
|
|
40
41
|
ctx.req.method === "HEAD" || // HEAD request
|
|
41
42
|
contentLength && Number(contentLength) < threshold || // content-length below threshold
|
|
@@ -59,11 +59,13 @@ var methodOverride = (options) => async function methodOverride2(c, next) {
|
|
|
59
59
|
if (method) {
|
|
60
60
|
const url = new URL(c.req.url);
|
|
61
61
|
url.searchParams.delete(queryName);
|
|
62
|
-
const
|
|
62
|
+
const requestInit = {
|
|
63
63
|
body: c.req.raw.body,
|
|
64
64
|
headers: c.req.raw.headers,
|
|
65
|
-
method
|
|
66
|
-
|
|
65
|
+
method,
|
|
66
|
+
duplex: c.req.raw.body ? "half" : void 0
|
|
67
|
+
};
|
|
68
|
+
const request = new Request(url.toString(), requestInit);
|
|
67
69
|
return app.fetch(request, c.env, getExecutionCtx(c));
|
|
68
70
|
}
|
|
69
71
|
}
|
package/dist/request.js
CHANGED
|
@@ -294,11 +294,16 @@ var cloneRawRequest = async (req) => {
|
|
|
294
294
|
message: "Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly."
|
|
295
295
|
});
|
|
296
296
|
}
|
|
297
|
+
const body = await req[cacheKey]();
|
|
298
|
+
const headers = req.header();
|
|
299
|
+
if (body instanceof FormData) {
|
|
300
|
+
delete headers["content-type"];
|
|
301
|
+
}
|
|
297
302
|
const requestInit = {
|
|
298
|
-
body
|
|
303
|
+
body,
|
|
299
304
|
cache: req.raw.cache,
|
|
300
305
|
credentials: req.raw.credentials,
|
|
301
|
-
headers
|
|
306
|
+
headers,
|
|
302
307
|
integrity: req.raw.integrity,
|
|
303
308
|
keepalive: req.raw.keepalive,
|
|
304
309
|
method: req.method,
|
|
@@ -31,7 +31,7 @@ export type WSReadyState = 0 | 1 | 2 | 3;
|
|
|
31
31
|
* An argument for WSContext class
|
|
32
32
|
*/
|
|
33
33
|
export interface WSContextInit<T = unknown> {
|
|
34
|
-
send(data: string | ArrayBuffer | Uint8Array
|
|
34
|
+
send(data: string | ArrayBuffer | Uint8Array<ArrayBuffer>, options: SendOptions): void;
|
|
35
35
|
close(code?: number, reason?: string): void;
|
|
36
36
|
raw?: T;
|
|
37
37
|
readyState: WSReadyState;
|
|
@@ -71,7 +71,7 @@ export declare const every: (...middleware: (MiddlewareHandler | Condition)[]) =
|
|
|
71
71
|
* @example
|
|
72
72
|
* ```ts
|
|
73
73
|
* import { except } from 'hono/combine'
|
|
74
|
-
* import { bearerAuth } from 'hono/bearer-auth
|
|
74
|
+
* import { bearerAuth } from 'hono/bearer-auth'
|
|
75
75
|
*
|
|
76
76
|
* // If client is accessing public API, then skip authentication.
|
|
77
77
|
* // Otherwise, require a valid token.
|
package/dist/utils/body.js
CHANGED
|
@@ -12,6 +12,12 @@ var parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) =
|
|
|
12
12
|
return {};
|
|
13
13
|
};
|
|
14
14
|
async function parseFormData(request, options) {
|
|
15
|
+
if (!isRawRequest(request) && request.bodyCache.formData) {
|
|
16
|
+
return convertFormDataToBodyData(
|
|
17
|
+
await request.bodyCache.formData,
|
|
18
|
+
options
|
|
19
|
+
);
|
|
20
|
+
}
|
|
15
21
|
const headers = isRawRequest(request) ? request.headers : request.raw.headers;
|
|
16
22
|
const arrayBuffer = await request.arrayBuffer();
|
|
17
23
|
const formDataPromise = bufferToFormData(arrayBuffer, headers.get("Content-Type") || "");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "4.12.
|
|
3
|
+
"version": "4.12.31",
|
|
4
4
|
"description": "Web framework built on Web Standards",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -666,7 +666,7 @@
|
|
|
666
666
|
"nodejs"
|
|
667
667
|
],
|
|
668
668
|
"devDependencies": {
|
|
669
|
-
"@hono/eslint-config": "^2.1.
|
|
669
|
+
"@hono/eslint-config": "^2.1.1",
|
|
670
670
|
"@hono/node-server": "^2.0.2",
|
|
671
671
|
"@types/jsdom": "^21.1.7",
|
|
672
672
|
"@types/node": "^24.3.0",
|
|
@@ -684,7 +684,7 @@
|
|
|
684
684
|
"pkg-pr-new": "^0.0.53",
|
|
685
685
|
"prettier": "3.7.4",
|
|
686
686
|
"publint": "0.3.15",
|
|
687
|
-
"typescript": "^
|
|
687
|
+
"typescript": "^6.0.3",
|
|
688
688
|
"undici": "^6.27.0",
|
|
689
689
|
"vite-plugin-fastly-js-compute": "^0.4.2",
|
|
690
690
|
"vitest": "^4.1.9",
|