hono 4.12.3 → 4.12.5
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/adapter/aws-lambda/handler.js +1 -1
- package/dist/cjs/adapter/aws-lambda/handler.js +1 -1
- package/dist/cjs/helper/streaming/sse.js +5 -0
- package/dist/cjs/jsx/streaming.js +13 -3
- package/dist/cjs/middleware/serve-static/index.js +2 -1
- package/dist/cjs/utils/cookie.js +5 -0
- package/dist/cjs/utils/jwt/jwt.js +11 -5
- package/dist/cjs/utils/url.js +4 -2
- package/dist/helper/streaming/sse.js +5 -0
- package/dist/jsx/streaming.js +13 -3
- package/dist/middleware/serve-static/index.js +2 -1
- package/dist/types/adapter/aws-lambda/handler.d.ts +1 -1
- package/dist/types/client/types.d.ts +2 -2
- package/dist/types/request.d.ts +1 -1
- package/dist/types/utils/url.d.ts +10 -0
- package/dist/utils/cookie.js +5 -0
- package/dist/utils/jwt/jwt.js +11 -5
- package/dist/utils/url.js +2 -1
- package/package.json +3 -3
|
@@ -137,7 +137,7 @@ var EventProcessor = class {
|
|
|
137
137
|
}
|
|
138
138
|
return result;
|
|
139
139
|
}
|
|
140
|
-
setCookies(
|
|
140
|
+
setCookies(_event, res, result) {
|
|
141
141
|
if (res.headers.has("set-cookie")) {
|
|
142
142
|
const cookies = res.headers.getSetCookie ? res.headers.getSetCookie() : Array.from(res.headers.entries()).filter(([k]) => k === "set-cookie").map(([, v]) => v);
|
|
143
143
|
if (Array.isArray(cookies)) {
|
|
@@ -168,7 +168,7 @@ class EventProcessor {
|
|
|
168
168
|
}
|
|
169
169
|
return result;
|
|
170
170
|
}
|
|
171
|
-
setCookies(
|
|
171
|
+
setCookies(_event, res, result) {
|
|
172
172
|
if (res.headers.has("set-cookie")) {
|
|
173
173
|
const cookies = res.headers.getSetCookie ? res.headers.getSetCookie() : Array.from(res.headers.entries()).filter(([k]) => k === "set-cookie").map(([, v]) => v);
|
|
174
174
|
if (Array.isArray(cookies)) {
|
|
@@ -34,6 +34,11 @@ class SSEStreamingApi extends import_stream.StreamingApi {
|
|
|
34
34
|
const dataLines = data.split(/\r\n|\r|\n/).map((line) => {
|
|
35
35
|
return `data: ${line}`;
|
|
36
36
|
}).join("\n");
|
|
37
|
+
for (const key of ["event", "id", "retry"]) {
|
|
38
|
+
if (message[key] && /[\r\n]/.test(message[key])) {
|
|
39
|
+
throw new Error(`${key} must not contain "\\r" or "\\n"`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
37
42
|
const sseData = [
|
|
38
43
|
message.event && `event: ${message.event}`,
|
|
39
44
|
dataLines,
|
|
@@ -113,6 +113,7 @@ d.replaceWith(c.content)
|
|
|
113
113
|
Suspense[import_constants.DOM_RENDERER] = import_components2.Suspense;
|
|
114
114
|
const textEncoder = new TextEncoder();
|
|
115
115
|
const renderToReadableStream = (content, onError = console.trace) => {
|
|
116
|
+
let cancelled = false;
|
|
116
117
|
const reader = new ReadableStream({
|
|
117
118
|
async start(controller) {
|
|
118
119
|
try {
|
|
@@ -126,7 +127,9 @@ const renderToReadableStream = (content, onError = console.trace) => {
|
|
|
126
127
|
true,
|
|
127
128
|
context
|
|
128
129
|
);
|
|
129
|
-
|
|
130
|
+
if (!cancelled) {
|
|
131
|
+
controller.enqueue(textEncoder.encode(resolved));
|
|
132
|
+
}
|
|
130
133
|
let resolvedCount = 0;
|
|
131
134
|
const callbacks = [];
|
|
132
135
|
const then = (promise) => {
|
|
@@ -144,7 +147,9 @@ const renderToReadableStream = (content, onError = console.trace) => {
|
|
|
144
147
|
);
|
|
145
148
|
res.callbacks?.map((c) => c({ phase: import_html2.HtmlEscapedCallbackPhase.Stream, context })).filter(Boolean).forEach(then);
|
|
146
149
|
resolvedCount++;
|
|
147
|
-
|
|
150
|
+
if (!cancelled) {
|
|
151
|
+
controller.enqueue(textEncoder.encode(res));
|
|
152
|
+
}
|
|
148
153
|
})
|
|
149
154
|
);
|
|
150
155
|
};
|
|
@@ -155,7 +160,12 @@ const renderToReadableStream = (content, onError = console.trace) => {
|
|
|
155
160
|
} catch (e) {
|
|
156
161
|
onError(e);
|
|
157
162
|
}
|
|
158
|
-
|
|
163
|
+
if (!cancelled) {
|
|
164
|
+
controller.close();
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
cancel() {
|
|
168
|
+
cancelled = true;
|
|
159
169
|
}
|
|
160
170
|
});
|
|
161
171
|
return reader;
|
|
@@ -23,6 +23,7 @@ __export(serve_static_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(serve_static_exports);
|
|
24
24
|
var import_compress = require("../../utils/compress");
|
|
25
25
|
var import_mime = require("../../utils/mime");
|
|
26
|
+
var import_url = require("../../utils/url");
|
|
26
27
|
var import_path = require("./path");
|
|
27
28
|
const ENCODINGS = {
|
|
28
29
|
br: ".br",
|
|
@@ -44,7 +45,7 @@ const serveStatic = (options) => {
|
|
|
44
45
|
filename = options.path;
|
|
45
46
|
} else {
|
|
46
47
|
try {
|
|
47
|
-
filename =
|
|
48
|
+
filename = (0, import_url.tryDecodeURI)(c.req.path);
|
|
48
49
|
if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
|
|
49
50
|
throw new Error();
|
|
50
51
|
}
|
package/dist/cjs/utils/cookie.js
CHANGED
|
@@ -112,6 +112,11 @@ const _serialize = (name, value, opt = {}) => {
|
|
|
112
112
|
throw new Error("__Host- Cookie must not have Domain attributes");
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
|
+
for (const key of ["domain", "path"]) {
|
|
116
|
+
if (opt[key] && /[;\r\n]/.test(opt[key])) {
|
|
117
|
+
throw new Error(`${key} must not contain ";", "\\r", or "\\n"`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
115
120
|
if (opt && typeof opt.maxAge === "number" && opt.maxAge >= 0) {
|
|
116
121
|
if (opt.maxAge > 3456e4) {
|
|
117
122
|
throw new Error(
|
|
@@ -177,10 +177,13 @@ const verifyWithJwks = async (token, options, init) => {
|
|
|
177
177
|
});
|
|
178
178
|
};
|
|
179
179
|
const decode = (token) => {
|
|
180
|
+
const parts = token.split(".");
|
|
181
|
+
if (parts.length !== 3) {
|
|
182
|
+
throw new import_types.JwtTokenInvalid(token);
|
|
183
|
+
}
|
|
180
184
|
try {
|
|
181
|
-
const
|
|
182
|
-
const
|
|
183
|
-
const payload = decodeJwtPart(p);
|
|
185
|
+
const header = decodeJwtPart(parts[0]);
|
|
186
|
+
const payload = decodeJwtPart(parts[1]);
|
|
184
187
|
return {
|
|
185
188
|
header,
|
|
186
189
|
payload
|
|
@@ -190,9 +193,12 @@ const decode = (token) => {
|
|
|
190
193
|
}
|
|
191
194
|
};
|
|
192
195
|
const decodeHeader = (token) => {
|
|
196
|
+
const parts = token.split(".");
|
|
197
|
+
if (parts.length !== 3) {
|
|
198
|
+
throw new import_types.JwtTokenInvalid(token);
|
|
199
|
+
}
|
|
193
200
|
try {
|
|
194
|
-
|
|
195
|
-
return decodeJwtPart(h);
|
|
201
|
+
return decodeJwtPart(parts[0]);
|
|
196
202
|
} catch {
|
|
197
203
|
throw new import_types.JwtTokenInvalid(token);
|
|
198
204
|
}
|
package/dist/cjs/utils/url.js
CHANGED
|
@@ -29,7 +29,8 @@ __export(url_exports, {
|
|
|
29
29
|
mergePath: () => mergePath,
|
|
30
30
|
splitPath: () => splitPath,
|
|
31
31
|
splitRoutingPath: () => splitRoutingPath,
|
|
32
|
-
tryDecode: () => tryDecode
|
|
32
|
+
tryDecode: () => tryDecode,
|
|
33
|
+
tryDecodeURI: () => tryDecodeURI
|
|
33
34
|
});
|
|
34
35
|
module.exports = __toCommonJS(url_exports);
|
|
35
36
|
const splitPath = (path) => {
|
|
@@ -251,5 +252,6 @@ const decodeURIComponent_ = decodeURIComponent;
|
|
|
251
252
|
mergePath,
|
|
252
253
|
splitPath,
|
|
253
254
|
splitRoutingPath,
|
|
254
|
-
tryDecode
|
|
255
|
+
tryDecode,
|
|
256
|
+
tryDecodeURI
|
|
255
257
|
});
|
|
@@ -11,6 +11,11 @@ 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", "retry"]) {
|
|
15
|
+
if (message[key] && /[\r\n]/.test(message[key])) {
|
|
16
|
+
throw new Error(`${key} must not contain "\\r" or "\\n"`);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
14
19
|
const sseData = [
|
|
15
20
|
message.event && `event: ${message.event}`,
|
|
16
21
|
dataLines,
|
package/dist/jsx/streaming.js
CHANGED
|
@@ -89,6 +89,7 @@ d.replaceWith(c.content)
|
|
|
89
89
|
Suspense[DOM_RENDERER] = SuspenseDomRenderer;
|
|
90
90
|
var textEncoder = new TextEncoder();
|
|
91
91
|
var renderToReadableStream = (content, onError = console.trace) => {
|
|
92
|
+
let cancelled = false;
|
|
92
93
|
const reader = new ReadableStream({
|
|
93
94
|
async start(controller) {
|
|
94
95
|
try {
|
|
@@ -102,7 +103,9 @@ var renderToReadableStream = (content, onError = console.trace) => {
|
|
|
102
103
|
true,
|
|
103
104
|
context
|
|
104
105
|
);
|
|
105
|
-
|
|
106
|
+
if (!cancelled) {
|
|
107
|
+
controller.enqueue(textEncoder.encode(resolved));
|
|
108
|
+
}
|
|
106
109
|
let resolvedCount = 0;
|
|
107
110
|
const callbacks = [];
|
|
108
111
|
const then = (promise) => {
|
|
@@ -120,7 +123,9 @@ var renderToReadableStream = (content, onError = console.trace) => {
|
|
|
120
123
|
);
|
|
121
124
|
res.callbacks?.map((c) => c({ phase: HtmlEscapedCallbackPhase.Stream, context })).filter(Boolean).forEach(then);
|
|
122
125
|
resolvedCount++;
|
|
123
|
-
|
|
126
|
+
if (!cancelled) {
|
|
127
|
+
controller.enqueue(textEncoder.encode(res));
|
|
128
|
+
}
|
|
124
129
|
})
|
|
125
130
|
);
|
|
126
131
|
};
|
|
@@ -131,7 +136,12 @@ var renderToReadableStream = (content, onError = console.trace) => {
|
|
|
131
136
|
} catch (e) {
|
|
132
137
|
onError(e);
|
|
133
138
|
}
|
|
134
|
-
|
|
139
|
+
if (!cancelled) {
|
|
140
|
+
controller.close();
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
cancel() {
|
|
144
|
+
cancelled = true;
|
|
135
145
|
}
|
|
136
146
|
});
|
|
137
147
|
return reader;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// src/middleware/serve-static/index.ts
|
|
2
2
|
import { COMPRESSIBLE_CONTENT_TYPE_REGEX } from "../../utils/compress.js";
|
|
3
3
|
import { getMimeType } from "../../utils/mime.js";
|
|
4
|
+
import { tryDecodeURI } from "../../utils/url.js";
|
|
4
5
|
import { defaultJoin } from "./path.js";
|
|
5
6
|
var ENCODINGS = {
|
|
6
7
|
br: ".br",
|
|
@@ -22,7 +23,7 @@ var serveStatic = (options) => {
|
|
|
22
23
|
filename = options.path;
|
|
23
24
|
} else {
|
|
24
25
|
try {
|
|
25
|
-
filename =
|
|
26
|
+
filename = tryDecodeURI(c.req.path);
|
|
26
27
|
if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
|
|
27
28
|
throw new Error();
|
|
28
29
|
}
|
|
@@ -138,7 +138,7 @@ export declare abstract class EventProcessor<E extends LambdaEvent> {
|
|
|
138
138
|
protected getDomainName(event: E): string | undefined;
|
|
139
139
|
createRequest(event: E): Request;
|
|
140
140
|
createResult(event: E, res: Response, options: Pick<HandleOptions, 'isContentTypeBinary'>): Promise<APIGatewayProxyResult>;
|
|
141
|
-
setCookies(
|
|
141
|
+
setCookies(_event: E, res: Response, result: APIGatewayProxyResult): void;
|
|
142
142
|
}
|
|
143
143
|
export declare class EventV2Processor extends EventProcessor<APIGatewayProxyEventV2> {
|
|
144
144
|
protected getPath(event: APIGatewayProxyEventV2): string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Hono } from '../hono';
|
|
2
2
|
import type { HonoBase } from '../hono-base';
|
|
3
3
|
import type { METHODS, METHOD_NAME_ALL_LOWERCASE } from '../router';
|
|
4
|
-
import type { Endpoint, KnownResponseFormat, ResponseFormat, Schema } from '../types';
|
|
4
|
+
import type { Endpoint, ExtractSchema, KnownResponseFormat, ResponseFormat, Schema } from '../types';
|
|
5
5
|
import type { StatusCode, SuccessStatusCode } from '../utils/http-status';
|
|
6
6
|
import type { HasRequiredKeys } from '../utils/types';
|
|
7
7
|
/**
|
|
@@ -205,5 +205,5 @@ type ModSchema<D, Def extends GlobalResponseDefinition> = {
|
|
|
205
205
|
[M in keyof D[K]]: ModRoute<D[K][M], Def>;
|
|
206
206
|
};
|
|
207
207
|
};
|
|
208
|
-
export type ApplyGlobalResponse<App, Def extends GlobalResponseDefinition> = App extends HonoBase<infer E, infer
|
|
208
|
+
export type ApplyGlobalResponse<App, Def extends GlobalResponseDefinition> = App extends HonoBase<infer E, infer _ extends Schema, infer B> ? ModSchema<ExtractSchema<App>, Def> extends infer S extends Schema ? Hono<E, S, B> : never : never;
|
|
209
209
|
export {};
|
package/dist/types/request.d.ts
CHANGED
|
@@ -59,7 +59,7 @@ export declare class HonoRequest<P extends string = '/', I extends Input['out']
|
|
|
59
59
|
* const { id, comment_id } = c.req.param()
|
|
60
60
|
* ```
|
|
61
61
|
*/
|
|
62
|
-
param<P2 extends ParamKeys<P> = ParamKeys<P>>(key: P2 extends `${infer _}?` ? never : P2): string;
|
|
62
|
+
param<P2 extends ParamKeys<P> = ParamKeys<P>>(key: string extends P ? never : P2 extends `${infer _}?` ? never : P2): string;
|
|
63
63
|
param<P2 extends RemoveQuestion<ParamKeys<P>> = RemoveQuestion<ParamKeys<P>>>(key: P2): string | undefined;
|
|
64
64
|
param(key: string): string | undefined;
|
|
65
65
|
param<P2 extends string = P>(): Simplify<UnionToIntersection<ParamKeyToRecord<ParamKeys<P2>>>>;
|
|
@@ -8,6 +8,16 @@ export declare const splitRoutingPath: (routePath: string) => string[];
|
|
|
8
8
|
export declare const getPattern: (label: string, next?: string) => Pattern | null;
|
|
9
9
|
type Decoder = (str: string) => string;
|
|
10
10
|
export declare const tryDecode: (str: string, decoder: Decoder) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Try to apply decodeURI() to given string.
|
|
13
|
+
* If it fails, skip invalid percent encoding or invalid UTF-8 sequences, and apply decodeURI() to the rest as much as possible.
|
|
14
|
+
* @param str The string to decode.
|
|
15
|
+
* @returns The decoded string that sometimes contains undecodable percent encoding.
|
|
16
|
+
* @example
|
|
17
|
+
* tryDecodeURI('Hello%20World') // 'Hello World'
|
|
18
|
+
* tryDecodeURI('Hello%20World/%A4%A2') // 'Hello World/%A4%A2'
|
|
19
|
+
*/
|
|
20
|
+
export declare const tryDecodeURI: (str: string) => string;
|
|
11
21
|
export declare const getPath: (request: Request) => string;
|
|
12
22
|
export declare const getQueryStrings: (url: string) => string;
|
|
13
23
|
export declare const getPathNoStrict: (request: Request) => string;
|
package/dist/utils/cookie.js
CHANGED
|
@@ -87,6 +87,11 @@ var _serialize = (name, value, opt = {}) => {
|
|
|
87
87
|
throw new Error("__Host- Cookie must not have Domain attributes");
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
+
for (const key of ["domain", "path"]) {
|
|
91
|
+
if (opt[key] && /[;\r\n]/.test(opt[key])) {
|
|
92
|
+
throw new Error(`${key} must not contain ";", "\\r", or "\\n"`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
90
95
|
if (opt && typeof opt.maxAge === "number" && opt.maxAge >= 0) {
|
|
91
96
|
if (opt.maxAge > 3456e4) {
|
|
92
97
|
throw new Error(
|
package/dist/utils/jwt/jwt.js
CHANGED
|
@@ -165,10 +165,13 @@ var verifyWithJwks = async (token, options, init) => {
|
|
|
165
165
|
});
|
|
166
166
|
};
|
|
167
167
|
var decode = (token) => {
|
|
168
|
+
const parts = token.split(".");
|
|
169
|
+
if (parts.length !== 3) {
|
|
170
|
+
throw new JwtTokenInvalid(token);
|
|
171
|
+
}
|
|
168
172
|
try {
|
|
169
|
-
const
|
|
170
|
-
const
|
|
171
|
-
const payload = decodeJwtPart(p);
|
|
173
|
+
const header = decodeJwtPart(parts[0]);
|
|
174
|
+
const payload = decodeJwtPart(parts[1]);
|
|
172
175
|
return {
|
|
173
176
|
header,
|
|
174
177
|
payload
|
|
@@ -178,9 +181,12 @@ var decode = (token) => {
|
|
|
178
181
|
}
|
|
179
182
|
};
|
|
180
183
|
var decodeHeader = (token) => {
|
|
184
|
+
const parts = token.split(".");
|
|
185
|
+
if (parts.length !== 3) {
|
|
186
|
+
throw new JwtTokenInvalid(token);
|
|
187
|
+
}
|
|
181
188
|
try {
|
|
182
|
-
|
|
183
|
-
return decodeJwtPart(h);
|
|
189
|
+
return decodeJwtPart(parts[0]);
|
|
184
190
|
} catch {
|
|
185
191
|
throw new JwtTokenInvalid(token);
|
|
186
192
|
}
|
package/dist/utils/url.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "4.12.
|
|
3
|
+
"version": "4.12.5",
|
|
4
4
|
"description": "Web framework built on Web Standards",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -656,7 +656,7 @@
|
|
|
656
656
|
"nodejs"
|
|
657
657
|
],
|
|
658
658
|
"devDependencies": {
|
|
659
|
-
"@hono/eslint-config": "^2.0
|
|
659
|
+
"@hono/eslint-config": "^2.1.0",
|
|
660
660
|
"@hono/node-server": "^1.13.5",
|
|
661
661
|
"@types/glob": "^9.0.0",
|
|
662
662
|
"@types/jsdom": "^21.1.7",
|
|
@@ -667,7 +667,7 @@
|
|
|
667
667
|
"bun-types": "^1.2.20",
|
|
668
668
|
"editorconfig-checker": "6.1.1",
|
|
669
669
|
"esbuild": "^0.27.1",
|
|
670
|
-
"eslint": "9.39.
|
|
670
|
+
"eslint": "^9.39.3",
|
|
671
671
|
"glob": "^11.0.0",
|
|
672
672
|
"jsdom": "22.1.0",
|
|
673
673
|
"msw": "^2.6.0",
|