hono 3.2.3 → 3.2.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 +8 -10
- package/dist/cjs/adapter/aws-lambda/handler.js +8 -10
- package/dist/cjs/context.js +3 -3
- package/dist/cjs/hono-base.js +16 -13
- package/dist/cjs/http-exception.js +1 -2
- package/dist/cjs/middleware/jsx/index.js +12 -8
- package/dist/cjs/router/pattern-router/router.js +5 -4
- package/dist/cjs/router/reg-exp-router/router.js +13 -13
- package/dist/cjs/router/trie-router/node.js +1 -4
- package/dist/cjs/router.js +1 -1
- package/dist/cjs/utils/encode.js +5 -1
- package/dist/cjs/utils/url.js +2 -2
- package/dist/context.js +3 -3
- package/dist/hono-base.js +16 -13
- package/dist/http-exception.js +1 -2
- package/dist/middleware/jsx/index.js +12 -8
- package/dist/router/pattern-router/router.js +5 -4
- package/dist/router/reg-exp-router/router.js +13 -13
- package/dist/router/trie-router/node.js +1 -4
- package/dist/router.js +1 -1
- package/dist/types/context.d.ts +7 -5
- package/dist/types/hono-base.d.ts +6 -1
- package/dist/types/middleware/jsx/index.d.ts +3 -0
- package/dist/types/router/trie-router/node.d.ts +0 -1
- package/dist/types/router.d.ts +1 -1
- package/dist/types/utils/types.d.ts +3 -0
- package/dist/utils/encode.js +5 -1
- package/dist/utils/url.js +2 -2
- package/package.json +2 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// src/adapter/aws-lambda/handler.ts
|
|
2
2
|
import crypto from "crypto";
|
|
3
|
+
import { encodeBase64 } from "../../utils/encode.js";
|
|
3
4
|
globalThis.crypto = crypto;
|
|
4
5
|
var handle = (app) => {
|
|
5
6
|
return async (event) => {
|
|
@@ -11,7 +12,13 @@ var handle = (app) => {
|
|
|
11
12
|
var createResult = async (res) => {
|
|
12
13
|
const contentType = res.headers.get("content-type");
|
|
13
14
|
const isBase64Encoded = contentType && isContentTypeBinary(contentType) ? true : false;
|
|
14
|
-
|
|
15
|
+
let body;
|
|
16
|
+
if (isBase64Encoded) {
|
|
17
|
+
const buffer = await res.arrayBuffer();
|
|
18
|
+
body = encodeBase64(buffer);
|
|
19
|
+
} else {
|
|
20
|
+
body = await res.text();
|
|
21
|
+
}
|
|
15
22
|
const result = {
|
|
16
23
|
body,
|
|
17
24
|
headers: {},
|
|
@@ -54,15 +61,6 @@ var isProxyEvent = (event) => {
|
|
|
54
61
|
var isProxyEventV2 = (event) => {
|
|
55
62
|
return Object.prototype.hasOwnProperty.call(event, "rawPath");
|
|
56
63
|
};
|
|
57
|
-
var fromReadableToString = async (res) => {
|
|
58
|
-
const stream = res.body || new ReadableStream();
|
|
59
|
-
const decoder = new TextDecoder();
|
|
60
|
-
let string = "";
|
|
61
|
-
for await (const chunk of stream) {
|
|
62
|
-
string += decoder.decode(chunk);
|
|
63
|
-
}
|
|
64
|
-
return btoa(string);
|
|
65
|
-
};
|
|
66
64
|
var isContentTypeBinary = (contentType) => {
|
|
67
65
|
return !/^(text\/(plain|html|css|javascript|csv).*|application\/(.*json|.*xml).*|image\/svg\+xml)$/.test(
|
|
68
66
|
contentType
|
|
@@ -29,6 +29,7 @@ __export(handler_exports, {
|
|
|
29
29
|
});
|
|
30
30
|
module.exports = __toCommonJS(handler_exports);
|
|
31
31
|
var import_crypto = __toESM(require("crypto"), 1);
|
|
32
|
+
var import_encode = require("../../utils/encode");
|
|
32
33
|
globalThis.crypto = import_crypto.default;
|
|
33
34
|
const handle = (app) => {
|
|
34
35
|
return async (event) => {
|
|
@@ -40,7 +41,13 @@ const handle = (app) => {
|
|
|
40
41
|
const createResult = async (res) => {
|
|
41
42
|
const contentType = res.headers.get("content-type");
|
|
42
43
|
const isBase64Encoded = contentType && isContentTypeBinary(contentType) ? true : false;
|
|
43
|
-
|
|
44
|
+
let body;
|
|
45
|
+
if (isBase64Encoded) {
|
|
46
|
+
const buffer = await res.arrayBuffer();
|
|
47
|
+
body = (0, import_encode.encodeBase64)(buffer);
|
|
48
|
+
} else {
|
|
49
|
+
body = await res.text();
|
|
50
|
+
}
|
|
44
51
|
const result = {
|
|
45
52
|
body,
|
|
46
53
|
headers: {},
|
|
@@ -83,15 +90,6 @@ const isProxyEvent = (event) => {
|
|
|
83
90
|
const isProxyEventV2 = (event) => {
|
|
84
91
|
return Object.prototype.hasOwnProperty.call(event, "rawPath");
|
|
85
92
|
};
|
|
86
|
-
const fromReadableToString = async (res) => {
|
|
87
|
-
const stream = res.body || new ReadableStream();
|
|
88
|
-
const decoder = new TextDecoder();
|
|
89
|
-
let string = "";
|
|
90
|
-
for await (const chunk of stream) {
|
|
91
|
-
string += decoder.decode(chunk);
|
|
92
|
-
}
|
|
93
|
-
return btoa(string);
|
|
94
|
-
};
|
|
95
93
|
const isContentTypeBinary = (contentType) => {
|
|
96
94
|
return !/^(text\/(plain|html|css|javascript|csv).*|application\/(.*json|.*xml).*|image\/svg\+xml)$/.test(
|
|
97
95
|
contentType
|
package/dist/cjs/context.js
CHANGED
|
@@ -176,7 +176,7 @@ class Context {
|
|
|
176
176
|
if (options) {
|
|
177
177
|
this._exCtx = options.executionCtx;
|
|
178
178
|
this._path = options.path ?? "/";
|
|
179
|
-
this.
|
|
179
|
+
this._params = options.params;
|
|
180
180
|
this.env = options.env;
|
|
181
181
|
if (options.notFoundHandler) {
|
|
182
182
|
this.notFoundHandler = options.notFoundHandler;
|
|
@@ -187,9 +187,9 @@ class Context {
|
|
|
187
187
|
if (this._req) {
|
|
188
188
|
return this._req;
|
|
189
189
|
} else {
|
|
190
|
-
this._req = new import_request.HonoRequest(this.rawRequest, this._path, this.
|
|
190
|
+
this._req = new import_request.HonoRequest(this.rawRequest, this._path, this._params);
|
|
191
191
|
this.rawRequest = void 0;
|
|
192
|
-
this.
|
|
192
|
+
this._params = void 0;
|
|
193
193
|
return this._req;
|
|
194
194
|
}
|
|
195
195
|
}
|
package/dist/cjs/hono-base.js
CHANGED
|
@@ -49,11 +49,15 @@ class Hono extends defineDynamicClass() {
|
|
|
49
49
|
this.routes = [];
|
|
50
50
|
this.notFoundHandler = notFoundHandler;
|
|
51
51
|
this.errorHandler = errorHandler;
|
|
52
|
+
this.head = () => {
|
|
53
|
+
console.warn("`app.head()` is no longer used. `app.get()` implicitly handles the HEAD method.");
|
|
54
|
+
return this;
|
|
55
|
+
};
|
|
52
56
|
this.handleEvent = (event) => {
|
|
53
|
-
return this.dispatch(event.request, event);
|
|
57
|
+
return this.dispatch(event.request, event, void 0, event.request.method);
|
|
54
58
|
};
|
|
55
59
|
this.fetch = (request, Env, executionCtx) => {
|
|
56
|
-
return this.dispatch(request, executionCtx, Env);
|
|
60
|
+
return this.dispatch(request, executionCtx, Env, request.method);
|
|
57
61
|
};
|
|
58
62
|
this.request = async (input, requestInit) => {
|
|
59
63
|
if (input instanceof Request) {
|
|
@@ -191,7 +195,7 @@ class Hono extends defineDynamicClass() {
|
|
|
191
195
|
this.routes.push(r);
|
|
192
196
|
}
|
|
193
197
|
matchRoute(method, path) {
|
|
194
|
-
return this.router.match(method, path);
|
|
198
|
+
return this.router.match(method, path) || { handlers: [], params: {} };
|
|
195
199
|
}
|
|
196
200
|
handleError(err, c) {
|
|
197
201
|
if (err instanceof Error) {
|
|
@@ -199,23 +203,23 @@ class Hono extends defineDynamicClass() {
|
|
|
199
203
|
}
|
|
200
204
|
throw err;
|
|
201
205
|
}
|
|
202
|
-
dispatch(request,
|
|
206
|
+
dispatch(request, executionCtx, env, method) {
|
|
203
207
|
const path = this.getPath(request);
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
if (method === "HEAD") {
|
|
209
|
+
return (async () => new Response(null, await this.dispatch(request, executionCtx, env, "GET")))();
|
|
210
|
+
}
|
|
211
|
+
const { handlers, params } = this.matchRoute(method, path);
|
|
207
212
|
const c = new import_context.Context(request, {
|
|
208
213
|
env,
|
|
209
|
-
executionCtx
|
|
214
|
+
executionCtx,
|
|
210
215
|
notFoundHandler: this.notFoundHandler,
|
|
211
216
|
path,
|
|
212
|
-
|
|
217
|
+
params
|
|
213
218
|
});
|
|
214
|
-
if (
|
|
215
|
-
const handler = result.handlers[0];
|
|
219
|
+
if (handlers.length === 1) {
|
|
216
220
|
let res;
|
|
217
221
|
try {
|
|
218
|
-
res =
|
|
222
|
+
res = handlers[0](c, async () => {
|
|
219
223
|
});
|
|
220
224
|
if (!res) {
|
|
221
225
|
return this.notFoundHandler(c);
|
|
@@ -246,7 +250,6 @@ class Hono extends defineDynamicClass() {
|
|
|
246
250
|
return awaited;
|
|
247
251
|
})();
|
|
248
252
|
}
|
|
249
|
-
const handlers = result ? result.handlers : [this.notFoundHandler];
|
|
250
253
|
const composed = (0, import_compose.compose)(handlers, this.errorHandler, this.notFoundHandler);
|
|
251
254
|
return (async () => {
|
|
252
255
|
try {
|
|
@@ -104,19 +104,23 @@ class JSXNode {
|
|
|
104
104
|
buffer[0] += `<${tag}`;
|
|
105
105
|
const propsKeys = Object.keys(props || {});
|
|
106
106
|
for (let i = 0, len = propsKeys.length; i < len; i++) {
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
const key = propsKeys[i];
|
|
108
|
+
const v = props[key];
|
|
109
|
+
if (key === "style" && typeof v === "object") {
|
|
110
|
+
const styles = Object.keys(v).map((k) => `${k}:${v[k]}`).join(";").replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
111
|
+
buffer[0] += ` style="${styles}"`;
|
|
112
|
+
} else if (typeof v === "string") {
|
|
113
|
+
buffer[0] += ` ${key}="`;
|
|
110
114
|
(0, import_html.escapeToBuffer)(v, buffer);
|
|
111
115
|
buffer[0] += '"';
|
|
112
116
|
} else if (typeof v === "number") {
|
|
113
|
-
buffer[0] += ` ${
|
|
117
|
+
buffer[0] += ` ${key}="${v}"`;
|
|
114
118
|
} else if (v === null || v === void 0) {
|
|
115
|
-
} else if (typeof v === "boolean" && booleanAttributes.includes(
|
|
119
|
+
} else if (typeof v === "boolean" && booleanAttributes.includes(key)) {
|
|
116
120
|
if (v) {
|
|
117
|
-
buffer[0] += ` ${
|
|
121
|
+
buffer[0] += ` ${key}=""`;
|
|
118
122
|
}
|
|
119
|
-
} else if (
|
|
123
|
+
} else if (key === "dangerouslySetInnerHTML") {
|
|
120
124
|
if (children.length > 0) {
|
|
121
125
|
throw "Can only set one of `children` or `props.dangerouslySetInnerHTML`.";
|
|
122
126
|
}
|
|
@@ -124,7 +128,7 @@ class JSXNode {
|
|
|
124
128
|
escapedString.isEscaped = true;
|
|
125
129
|
children = [escapedString];
|
|
126
130
|
} else {
|
|
127
|
-
buffer[0] += ` ${
|
|
131
|
+
buffer[0] += ` ${key}="`;
|
|
128
132
|
(0, import_html.escapeToBuffer)(v.toString(), buffer);
|
|
129
133
|
buffer[0] += '"';
|
|
130
134
|
}
|
|
@@ -62,21 +62,22 @@ class PatternRouter {
|
|
|
62
62
|
}
|
|
63
63
|
match(method, path) {
|
|
64
64
|
const handlers = [];
|
|
65
|
-
|
|
65
|
+
const params = {};
|
|
66
66
|
for (const [pattern, routeMethod, handler] of this.routes) {
|
|
67
|
+
const isRegExp = pattern.source.charCodeAt(pattern.source.length - 1) === 36;
|
|
67
68
|
if (routeMethod === import_router.METHOD_NAME_ALL || routeMethod === method) {
|
|
68
69
|
const match = pattern.exec(path);
|
|
69
70
|
if (match) {
|
|
70
71
|
handlers.push(handler);
|
|
71
|
-
if (
|
|
72
|
-
|
|
72
|
+
if (isRegExp) {
|
|
73
|
+
Object.assign(params, match.groups);
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
78
|
return handlers.length ? {
|
|
78
79
|
handlers,
|
|
79
|
-
params
|
|
80
|
+
params
|
|
80
81
|
} : null;
|
|
81
82
|
}
|
|
82
83
|
}
|
|
@@ -39,18 +39,18 @@ function clearWildcardRegExpCache() {
|
|
|
39
39
|
}
|
|
40
40
|
function buildMatcherFromPreprocessedRoutes(routes) {
|
|
41
41
|
const trie = new import_trie.Trie();
|
|
42
|
-
const
|
|
42
|
+
const handlerData = [];
|
|
43
43
|
if (routes.length === 0) {
|
|
44
44
|
return nullMatcher;
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
const routesWithStaticPathFlag = routes.map((route) => [!/\*|\/:/.test(route[0]), ...route]).sort(
|
|
47
|
+
([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length
|
|
48
|
+
);
|
|
47
49
|
const staticMap = {};
|
|
48
|
-
for (let i = 0, j = -1, len =
|
|
49
|
-
const path =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
pathErrorCheckOnly = true;
|
|
53
|
-
staticMap[routes[i][0]] = { handlers: routes[i][1], params: emptyParam };
|
|
50
|
+
for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
|
|
51
|
+
const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];
|
|
52
|
+
if (pathErrorCheckOnly) {
|
|
53
|
+
staticMap[path] = { handlers, params: emptyParam };
|
|
54
54
|
} else {
|
|
55
55
|
j++;
|
|
56
56
|
}
|
|
@@ -63,11 +63,11 @@ function buildMatcherFromPreprocessedRoutes(routes) {
|
|
|
63
63
|
if (pathErrorCheckOnly) {
|
|
64
64
|
continue;
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
handlerData[j] = paramMap.length === 0 ? [{ handlers, params: emptyParam }, null] : [handlers, paramMap];
|
|
67
67
|
}
|
|
68
68
|
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
69
|
-
for (let i = 0, len =
|
|
70
|
-
const paramMap =
|
|
69
|
+
for (let i = 0, len = handlerData.length; i < len; i++) {
|
|
70
|
+
const paramMap = handlerData[i][1];
|
|
71
71
|
if (paramMap) {
|
|
72
72
|
for (let j = 0, len2 = paramMap.length; j < len2; j++) {
|
|
73
73
|
paramMap[j][1] = paramReplacementMap[paramMap[j][1]];
|
|
@@ -76,7 +76,7 @@ function buildMatcherFromPreprocessedRoutes(routes) {
|
|
|
76
76
|
}
|
|
77
77
|
const handlerMap = [];
|
|
78
78
|
for (const i in indexReplacementMap) {
|
|
79
|
-
handlerMap[i] =
|
|
79
|
+
handlerMap[i] = handlerData[indexReplacementMap[i]];
|
|
80
80
|
}
|
|
81
81
|
return [regexp, handlerMap, staticMap];
|
|
82
82
|
}
|
|
@@ -103,7 +103,7 @@ class RegExpRouter {
|
|
|
103
103
|
if (!middleware || !routes) {
|
|
104
104
|
throw new Error("Can not add a route since the matcher is already built.");
|
|
105
105
|
}
|
|
106
|
-
if (
|
|
106
|
+
if (methodNames.indexOf(method) === -1)
|
|
107
107
|
methodNames.push(method);
|
|
108
108
|
if (!middleware[method]) {
|
|
109
109
|
;
|
|
@@ -40,7 +40,6 @@ function findParam(node, name) {
|
|
|
40
40
|
class Node {
|
|
41
41
|
constructor(method, handler, children) {
|
|
42
42
|
this.order = 0;
|
|
43
|
-
this.shouldCapture = false;
|
|
44
43
|
this.children = children || {};
|
|
45
44
|
this.methods = [];
|
|
46
45
|
this.name = "";
|
|
@@ -72,7 +71,6 @@ class Node {
|
|
|
72
71
|
const pattern = (0, import_url.getPattern)(p);
|
|
73
72
|
if (pattern) {
|
|
74
73
|
if (typeof pattern === "object") {
|
|
75
|
-
this.shouldCapture = true;
|
|
76
74
|
for (let j = 0, len2 = parentPatterns.length; j < len2; j++) {
|
|
77
75
|
if (typeof parentPatterns[j] === "object" && parentPatterns[j][1] === pattern[1]) {
|
|
78
76
|
throw new Error(errorMessage(pattern[1]));
|
|
@@ -87,7 +85,6 @@ class Node {
|
|
|
87
85
|
}
|
|
88
86
|
parentPatterns.push(...curNode.patterns);
|
|
89
87
|
curNode = curNode.children[p];
|
|
90
|
-
curNode.shouldCapture = this.shouldCapture;
|
|
91
88
|
}
|
|
92
89
|
if (!curNode.methods.length) {
|
|
93
90
|
curNode.methods = [];
|
|
@@ -167,7 +164,7 @@ class Node {
|
|
|
167
164
|
if (typeof name === "string" && !matched) {
|
|
168
165
|
params[name] = part;
|
|
169
166
|
} else {
|
|
170
|
-
if (node.children[part]
|
|
167
|
+
if (node.children[part]) {
|
|
171
168
|
params[name] = part;
|
|
172
169
|
}
|
|
173
170
|
}
|
package/dist/cjs/router.js
CHANGED
|
@@ -26,7 +26,7 @@ __export(router_exports, {
|
|
|
26
26
|
module.exports = __toCommonJS(router_exports);
|
|
27
27
|
const METHOD_NAME_ALL = "ALL";
|
|
28
28
|
const METHOD_NAME_ALL_LOWERCASE = "all";
|
|
29
|
-
const METHODS = ["get", "post", "put", "delete", "
|
|
29
|
+
const METHODS = ["get", "post", "put", "delete", "options", "patch"];
|
|
30
30
|
class UnsupportedPathError extends Error {
|
|
31
31
|
}
|
|
32
32
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/cjs/utils/encode.js
CHANGED
|
@@ -29,7 +29,11 @@ const decodeBase64Url = (str) => {
|
|
|
29
29
|
};
|
|
30
30
|
const encodeBase64Url = (buf) => encodeBase64(buf).replace(/\/|\+/g, (m) => ({ "/": "_", "+": "-" })[m] ?? m);
|
|
31
31
|
const encodeBase64 = (buf) => {
|
|
32
|
-
|
|
32
|
+
let binary = "";
|
|
33
|
+
const bytes = new Uint8Array(buf);
|
|
34
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
35
|
+
binary += String.fromCharCode(bytes[i]);
|
|
36
|
+
}
|
|
33
37
|
return btoa(binary);
|
|
34
38
|
};
|
|
35
39
|
const decodeBase64 = (str) => {
|
package/dist/cjs/utils/url.js
CHANGED
|
@@ -128,10 +128,10 @@ const _decodeURI = (value) => {
|
|
|
128
128
|
if (!/[%+]/.test(value)) {
|
|
129
129
|
return value;
|
|
130
130
|
}
|
|
131
|
-
if (value.
|
|
131
|
+
if (value.indexOf("+") !== -1) {
|
|
132
132
|
value = value.replace(/\+/g, " ");
|
|
133
133
|
}
|
|
134
|
-
return value.
|
|
134
|
+
return value.indexOf("%") === -1 ? value : decodeURIComponent_(value);
|
|
135
135
|
};
|
|
136
136
|
const _getQueryParam = (url, key, multiple) => {
|
|
137
137
|
let encoded;
|
package/dist/context.js
CHANGED
|
@@ -154,7 +154,7 @@ var Context = class {
|
|
|
154
154
|
if (options) {
|
|
155
155
|
this._exCtx = options.executionCtx;
|
|
156
156
|
this._path = options.path ?? "/";
|
|
157
|
-
this.
|
|
157
|
+
this._params = options.params;
|
|
158
158
|
this.env = options.env;
|
|
159
159
|
if (options.notFoundHandler) {
|
|
160
160
|
this.notFoundHandler = options.notFoundHandler;
|
|
@@ -165,9 +165,9 @@ var Context = class {
|
|
|
165
165
|
if (this._req) {
|
|
166
166
|
return this._req;
|
|
167
167
|
} else {
|
|
168
|
-
this._req = new HonoRequest(this.rawRequest, this._path, this.
|
|
168
|
+
this._req = new HonoRequest(this.rawRequest, this._path, this._params);
|
|
169
169
|
this.rawRequest = void 0;
|
|
170
|
-
this.
|
|
170
|
+
this._params = void 0;
|
|
171
171
|
return this._req;
|
|
172
172
|
}
|
|
173
173
|
}
|
package/dist/hono-base.js
CHANGED
|
@@ -27,11 +27,15 @@ var Hono = class extends defineDynamicClass() {
|
|
|
27
27
|
this.routes = [];
|
|
28
28
|
this.notFoundHandler = notFoundHandler;
|
|
29
29
|
this.errorHandler = errorHandler;
|
|
30
|
+
this.head = () => {
|
|
31
|
+
console.warn("`app.head()` is no longer used. `app.get()` implicitly handles the HEAD method.");
|
|
32
|
+
return this;
|
|
33
|
+
};
|
|
30
34
|
this.handleEvent = (event) => {
|
|
31
|
-
return this.dispatch(event.request, event);
|
|
35
|
+
return this.dispatch(event.request, event, void 0, event.request.method);
|
|
32
36
|
};
|
|
33
37
|
this.fetch = (request, Env, executionCtx) => {
|
|
34
|
-
return this.dispatch(request, executionCtx, Env);
|
|
38
|
+
return this.dispatch(request, executionCtx, Env, request.method);
|
|
35
39
|
};
|
|
36
40
|
this.request = async (input, requestInit) => {
|
|
37
41
|
if (input instanceof Request) {
|
|
@@ -169,7 +173,7 @@ var Hono = class extends defineDynamicClass() {
|
|
|
169
173
|
this.routes.push(r);
|
|
170
174
|
}
|
|
171
175
|
matchRoute(method, path) {
|
|
172
|
-
return this.router.match(method, path);
|
|
176
|
+
return this.router.match(method, path) || { handlers: [], params: {} };
|
|
173
177
|
}
|
|
174
178
|
handleError(err, c) {
|
|
175
179
|
if (err instanceof Error) {
|
|
@@ -177,23 +181,23 @@ var Hono = class extends defineDynamicClass() {
|
|
|
177
181
|
}
|
|
178
182
|
throw err;
|
|
179
183
|
}
|
|
180
|
-
dispatch(request,
|
|
184
|
+
dispatch(request, executionCtx, env, method) {
|
|
181
185
|
const path = this.getPath(request);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
186
|
+
if (method === "HEAD") {
|
|
187
|
+
return (async () => new Response(null, await this.dispatch(request, executionCtx, env, "GET")))();
|
|
188
|
+
}
|
|
189
|
+
const { handlers, params } = this.matchRoute(method, path);
|
|
185
190
|
const c = new Context(request, {
|
|
186
191
|
env,
|
|
187
|
-
executionCtx
|
|
192
|
+
executionCtx,
|
|
188
193
|
notFoundHandler: this.notFoundHandler,
|
|
189
194
|
path,
|
|
190
|
-
|
|
195
|
+
params
|
|
191
196
|
});
|
|
192
|
-
if (
|
|
193
|
-
const handler = result.handlers[0];
|
|
197
|
+
if (handlers.length === 1) {
|
|
194
198
|
let res;
|
|
195
199
|
try {
|
|
196
|
-
res =
|
|
200
|
+
res = handlers[0](c, async () => {
|
|
197
201
|
});
|
|
198
202
|
if (!res) {
|
|
199
203
|
return this.notFoundHandler(c);
|
|
@@ -224,7 +228,6 @@ var Hono = class extends defineDynamicClass() {
|
|
|
224
228
|
return awaited;
|
|
225
229
|
})();
|
|
226
230
|
}
|
|
227
|
-
const handlers = result ? result.handlers : [this.notFoundHandler];
|
|
228
231
|
const composed = compose(handlers, this.errorHandler, this.notFoundHandler);
|
|
229
232
|
return (async () => {
|
|
230
233
|
try {
|
package/dist/http-exception.js
CHANGED
|
@@ -79,19 +79,23 @@ var JSXNode = class {
|
|
|
79
79
|
buffer[0] += `<${tag}`;
|
|
80
80
|
const propsKeys = Object.keys(props || {});
|
|
81
81
|
for (let i = 0, len = propsKeys.length; i < len; i++) {
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
const key = propsKeys[i];
|
|
83
|
+
const v = props[key];
|
|
84
|
+
if (key === "style" && typeof v === "object") {
|
|
85
|
+
const styles = Object.keys(v).map((k) => `${k}:${v[k]}`).join(";").replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`);
|
|
86
|
+
buffer[0] += ` style="${styles}"`;
|
|
87
|
+
} else if (typeof v === "string") {
|
|
88
|
+
buffer[0] += ` ${key}="`;
|
|
85
89
|
escapeToBuffer(v, buffer);
|
|
86
90
|
buffer[0] += '"';
|
|
87
91
|
} else if (typeof v === "number") {
|
|
88
|
-
buffer[0] += ` ${
|
|
92
|
+
buffer[0] += ` ${key}="${v}"`;
|
|
89
93
|
} else if (v === null || v === void 0) {
|
|
90
|
-
} else if (typeof v === "boolean" && booleanAttributes.includes(
|
|
94
|
+
} else if (typeof v === "boolean" && booleanAttributes.includes(key)) {
|
|
91
95
|
if (v) {
|
|
92
|
-
buffer[0] += ` ${
|
|
96
|
+
buffer[0] += ` ${key}=""`;
|
|
93
97
|
}
|
|
94
|
-
} else if (
|
|
98
|
+
} else if (key === "dangerouslySetInnerHTML") {
|
|
95
99
|
if (children.length > 0) {
|
|
96
100
|
throw "Can only set one of `children` or `props.dangerouslySetInnerHTML`.";
|
|
97
101
|
}
|
|
@@ -99,7 +103,7 @@ var JSXNode = class {
|
|
|
99
103
|
escapedString.isEscaped = true;
|
|
100
104
|
children = [escapedString];
|
|
101
105
|
} else {
|
|
102
|
-
buffer[0] += ` ${
|
|
106
|
+
buffer[0] += ` ${key}="`;
|
|
103
107
|
escapeToBuffer(v.toString(), buffer);
|
|
104
108
|
buffer[0] += '"';
|
|
105
109
|
}
|
|
@@ -40,21 +40,22 @@ var PatternRouter = class {
|
|
|
40
40
|
}
|
|
41
41
|
match(method, path) {
|
|
42
42
|
const handlers = [];
|
|
43
|
-
|
|
43
|
+
const params = {};
|
|
44
44
|
for (const [pattern, routeMethod, handler] of this.routes) {
|
|
45
|
+
const isRegExp = pattern.source.charCodeAt(pattern.source.length - 1) === 36;
|
|
45
46
|
if (routeMethod === METHOD_NAME_ALL || routeMethod === method) {
|
|
46
47
|
const match = pattern.exec(path);
|
|
47
48
|
if (match) {
|
|
48
49
|
handlers.push(handler);
|
|
49
|
-
if (
|
|
50
|
-
|
|
50
|
+
if (isRegExp) {
|
|
51
|
+
Object.assign(params, match.groups);
|
|
51
52
|
}
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
}
|
|
55
56
|
return handlers.length ? {
|
|
56
57
|
handlers,
|
|
57
|
-
params
|
|
58
|
+
params
|
|
58
59
|
} : null;
|
|
59
60
|
}
|
|
60
61
|
};
|
|
@@ -17,18 +17,18 @@ function clearWildcardRegExpCache() {
|
|
|
17
17
|
}
|
|
18
18
|
function buildMatcherFromPreprocessedRoutes(routes) {
|
|
19
19
|
const trie = new Trie();
|
|
20
|
-
const
|
|
20
|
+
const handlerData = [];
|
|
21
21
|
if (routes.length === 0) {
|
|
22
22
|
return nullMatcher;
|
|
23
23
|
}
|
|
24
|
-
|
|
24
|
+
const routesWithStaticPathFlag = routes.map((route) => [!/\*|\/:/.test(route[0]), ...route]).sort(
|
|
25
|
+
([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length
|
|
26
|
+
);
|
|
25
27
|
const staticMap = {};
|
|
26
|
-
for (let i = 0, j = -1, len =
|
|
27
|
-
const path =
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
pathErrorCheckOnly = true;
|
|
31
|
-
staticMap[routes[i][0]] = { handlers: routes[i][1], params: emptyParam };
|
|
28
|
+
for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {
|
|
29
|
+
const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];
|
|
30
|
+
if (pathErrorCheckOnly) {
|
|
31
|
+
staticMap[path] = { handlers, params: emptyParam };
|
|
32
32
|
} else {
|
|
33
33
|
j++;
|
|
34
34
|
}
|
|
@@ -41,11 +41,11 @@ function buildMatcherFromPreprocessedRoutes(routes) {
|
|
|
41
41
|
if (pathErrorCheckOnly) {
|
|
42
42
|
continue;
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
handlerData[j] = paramMap.length === 0 ? [{ handlers, params: emptyParam }, null] : [handlers, paramMap];
|
|
45
45
|
}
|
|
46
46
|
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
47
|
-
for (let i = 0, len =
|
|
48
|
-
const paramMap =
|
|
47
|
+
for (let i = 0, len = handlerData.length; i < len; i++) {
|
|
48
|
+
const paramMap = handlerData[i][1];
|
|
49
49
|
if (paramMap) {
|
|
50
50
|
for (let j = 0, len2 = paramMap.length; j < len2; j++) {
|
|
51
51
|
paramMap[j][1] = paramReplacementMap[paramMap[j][1]];
|
|
@@ -54,7 +54,7 @@ function buildMatcherFromPreprocessedRoutes(routes) {
|
|
|
54
54
|
}
|
|
55
55
|
const handlerMap = [];
|
|
56
56
|
for (const i in indexReplacementMap) {
|
|
57
|
-
handlerMap[i] =
|
|
57
|
+
handlerMap[i] = handlerData[indexReplacementMap[i]];
|
|
58
58
|
}
|
|
59
59
|
return [regexp, handlerMap, staticMap];
|
|
60
60
|
}
|
|
@@ -81,7 +81,7 @@ var RegExpRouter = class {
|
|
|
81
81
|
if (!middleware || !routes) {
|
|
82
82
|
throw new Error("Can not add a route since the matcher is already built.");
|
|
83
83
|
}
|
|
84
|
-
if (
|
|
84
|
+
if (methodNames.indexOf(method) === -1)
|
|
85
85
|
methodNames.push(method);
|
|
86
86
|
if (!middleware[method]) {
|
|
87
87
|
;
|
|
@@ -18,7 +18,6 @@ function findParam(node, name) {
|
|
|
18
18
|
var Node = class {
|
|
19
19
|
constructor(method, handler, children) {
|
|
20
20
|
this.order = 0;
|
|
21
|
-
this.shouldCapture = false;
|
|
22
21
|
this.children = children || {};
|
|
23
22
|
this.methods = [];
|
|
24
23
|
this.name = "";
|
|
@@ -50,7 +49,6 @@ var Node = class {
|
|
|
50
49
|
const pattern = getPattern(p);
|
|
51
50
|
if (pattern) {
|
|
52
51
|
if (typeof pattern === "object") {
|
|
53
|
-
this.shouldCapture = true;
|
|
54
52
|
for (let j = 0, len2 = parentPatterns.length; j < len2; j++) {
|
|
55
53
|
if (typeof parentPatterns[j] === "object" && parentPatterns[j][1] === pattern[1]) {
|
|
56
54
|
throw new Error(errorMessage(pattern[1]));
|
|
@@ -65,7 +63,6 @@ var Node = class {
|
|
|
65
63
|
}
|
|
66
64
|
parentPatterns.push(...curNode.patterns);
|
|
67
65
|
curNode = curNode.children[p];
|
|
68
|
-
curNode.shouldCapture = this.shouldCapture;
|
|
69
66
|
}
|
|
70
67
|
if (!curNode.methods.length) {
|
|
71
68
|
curNode.methods = [];
|
|
@@ -145,7 +142,7 @@ var Node = class {
|
|
|
145
142
|
if (typeof name === "string" && !matched) {
|
|
146
143
|
params[name] = part;
|
|
147
144
|
} else {
|
|
148
|
-
if (node.children[part]
|
|
145
|
+
if (node.children[part]) {
|
|
149
146
|
params[name] = part;
|
|
150
147
|
}
|
|
151
148
|
}
|
package/dist/router.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/router.ts
|
|
2
2
|
var METHOD_NAME_ALL = "ALL";
|
|
3
3
|
var METHOD_NAME_ALL_LOWERCASE = "all";
|
|
4
|
-
var METHODS = ["get", "post", "put", "delete", "
|
|
4
|
+
var METHODS = ["get", "post", "put", "delete", "options", "patch"];
|
|
5
5
|
var UnsupportedPathError = class extends Error {
|
|
6
6
|
};
|
|
7
7
|
export {
|
package/dist/types/context.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { TypedResponse } from './types';
|
|
|
3
3
|
import type { Env, NotFoundHandler, Input } from './types';
|
|
4
4
|
import type { CookieOptions } from './utils/cookie';
|
|
5
5
|
import type { StatusCode } from './utils/http-status';
|
|
6
|
-
import type { JSONValue } from './utils/types';
|
|
6
|
+
import type { JSONValue, InterfaceToType } from './utils/types';
|
|
7
7
|
declare type Runtime = 'node' | 'deno' | 'bun' | 'workerd' | 'fastly' | 'edge-light' | 'lagon' | 'other';
|
|
8
8
|
declare type HeaderRecord = Record<string, string | string[]>;
|
|
9
9
|
declare type Data = string | ArrayBuffer | ReadableStream;
|
|
@@ -36,8 +36,10 @@ interface JSONRespond {
|
|
|
36
36
|
<T = JSONValue>(object: T, init?: ResponseInit): Response;
|
|
37
37
|
}
|
|
38
38
|
interface JSONTRespond {
|
|
39
|
-
<T>(object: T extends JSONValue ? T : JSONValue, status?: StatusCode, headers?: HeaderRecord): TypedResponse<T extends JSONValue ?
|
|
40
|
-
<T>(object: T extends JSONValue ? T : JSONValue,
|
|
39
|
+
<T>(object: T extends JSONValue ? T : JSONValue, status?: StatusCode, headers?: HeaderRecord): TypedResponse<InterfaceToType<T> extends JSONValue ? JSONValue extends InterfaceToType<T> ? never : T : never>;
|
|
40
|
+
<T>(object: InterfaceToType<T> extends JSONValue ? T : JSONValue, status?: StatusCode, headers?: HeaderRecord): TypedResponse<InterfaceToType<T> extends JSONValue ? JSONValue extends InterfaceToType<T> ? never : T : never>;
|
|
41
|
+
<T>(object: T extends JSONValue ? T : JSONValue, init?: ResponseInit): TypedResponse<InterfaceToType<T> extends JSONValue ? JSONValue extends InterfaceToType<T> ? never : T : never>;
|
|
42
|
+
<T>(object: InterfaceToType<T> extends JSONValue ? T : JSONValue, init?: ResponseInit): TypedResponse<InterfaceToType<T> extends JSONValue ? JSONValue extends InterfaceToType<T> ? never : T : never>;
|
|
41
43
|
}
|
|
42
44
|
interface HTMLRespond {
|
|
43
45
|
(html: string, status?: StatusCode, headers?: HeaderRecord): Response;
|
|
@@ -48,7 +50,7 @@ declare type ContextOptions<E extends Env> = {
|
|
|
48
50
|
executionCtx?: FetchEvent | ExecutionContext | undefined;
|
|
49
51
|
notFoundHandler?: NotFoundHandler<E>;
|
|
50
52
|
path?: string;
|
|
51
|
-
|
|
53
|
+
params?: Record<string, string>;
|
|
52
54
|
};
|
|
53
55
|
export declare class Context<E extends Env = any, P extends string = any, I extends Input = {}> {
|
|
54
56
|
env: E['Bindings'];
|
|
@@ -64,7 +66,7 @@ export declare class Context<E extends Env = any, P extends string = any, I exte
|
|
|
64
66
|
private _pH;
|
|
65
67
|
private _res;
|
|
66
68
|
private _path;
|
|
67
|
-
private
|
|
69
|
+
private _params?;
|
|
68
70
|
private rawRequest?;
|
|
69
71
|
private notFoundHandler;
|
|
70
72
|
constructor(req: Request, options?: ContextOptions<E>);
|
|
@@ -14,7 +14,6 @@ declare const Hono_base: new <E_1 extends Env = Env, S_1 = {}, BasePath_1 extend
|
|
|
14
14
|
post: HandlerInterface<E_1, "post", S_1, BasePath_1>;
|
|
15
15
|
put: HandlerInterface<E_1, "put", S_1, BasePath_1>;
|
|
16
16
|
delete: HandlerInterface<E_1, "delete", S_1, BasePath_1>;
|
|
17
|
-
head: HandlerInterface<E_1, "head", S_1, BasePath_1>;
|
|
18
17
|
options: HandlerInterface<E_1, "options", S_1, BasePath_1>;
|
|
19
18
|
patch: HandlerInterface<E_1, "patch", S_1, BasePath_1>;
|
|
20
19
|
} & {
|
|
@@ -51,6 +50,12 @@ declare class Hono<E extends Env = Env, S = {}, BasePath extends string = '/'> e
|
|
|
51
50
|
*/
|
|
52
51
|
mount(path: string, applicationHandler: (request: Request, ...args: any) => Response | Promise<Response>, optionHandler?: (c: Context) => unknown): Hono<E, S, BasePath>;
|
|
53
52
|
get routerName(): string;
|
|
53
|
+
/**
|
|
54
|
+
* @deprecate
|
|
55
|
+
* `app.head()` is no longer used.
|
|
56
|
+
* `app.get()` implicitly handles the HEAD method.
|
|
57
|
+
*/
|
|
58
|
+
head: () => this;
|
|
54
59
|
private addRoute;
|
|
55
60
|
private matchRoute;
|
|
56
61
|
private handleError;
|
|
@@ -12,7 +12,6 @@ export declare class Node<T> {
|
|
|
12
12
|
order: number;
|
|
13
13
|
name: string;
|
|
14
14
|
handlerSetCache: Record<string, HandlerSet<T>[]>;
|
|
15
|
-
shouldCapture: boolean;
|
|
16
15
|
constructor(method?: string, handler?: T, children?: Record<string, Node<T>>);
|
|
17
16
|
insert(method: string, path: string, handler: T): Node<T>;
|
|
18
17
|
private gHSets;
|
package/dist/types/router.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export declare const METHOD_NAME_ALL: "ALL";
|
|
2
2
|
export declare const METHOD_NAME_ALL_LOWERCASE: "all";
|
|
3
|
-
export declare const METHODS: readonly ["get", "post", "put", "delete", "
|
|
3
|
+
export declare const METHODS: readonly ["get", "post", "put", "delete", "options", "patch"];
|
|
4
4
|
export interface Router<T> {
|
|
5
5
|
name: string;
|
|
6
6
|
add(method: string, path: string, handler: T): void;
|
|
@@ -9,3 +9,6 @@ export declare type JSONObject = {
|
|
|
9
9
|
[key: string]: JSONPrimitive | JSONArray | JSONObject;
|
|
10
10
|
};
|
|
11
11
|
export declare type JSONValue = JSONObject | JSONArray | JSONPrimitive;
|
|
12
|
+
export declare type InterfaceToType<T> = T extends Function ? T : {
|
|
13
|
+
[K in keyof T]: InterfaceToType<T[K]>;
|
|
14
|
+
};
|
package/dist/utils/encode.js
CHANGED
|
@@ -4,7 +4,11 @@ var decodeBase64Url = (str) => {
|
|
|
4
4
|
};
|
|
5
5
|
var encodeBase64Url = (buf) => encodeBase64(buf).replace(/\/|\+/g, (m) => ({ "/": "_", "+": "-" })[m] ?? m);
|
|
6
6
|
var encodeBase64 = (buf) => {
|
|
7
|
-
|
|
7
|
+
let binary = "";
|
|
8
|
+
const bytes = new Uint8Array(buf);
|
|
9
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
10
|
+
binary += String.fromCharCode(bytes[i]);
|
|
11
|
+
}
|
|
8
12
|
return btoa(binary);
|
|
9
13
|
};
|
|
10
14
|
var decodeBase64 = (str) => {
|
package/dist/utils/url.js
CHANGED
|
@@ -97,10 +97,10 @@ var _decodeURI = (value) => {
|
|
|
97
97
|
if (!/[%+]/.test(value)) {
|
|
98
98
|
return value;
|
|
99
99
|
}
|
|
100
|
-
if (value.
|
|
100
|
+
if (value.indexOf("+") !== -1) {
|
|
101
101
|
value = value.replace(/\+/g, " ");
|
|
102
102
|
}
|
|
103
|
-
return value.
|
|
103
|
+
return value.indexOf("%") === -1 ? value : decodeURIComponent_(value);
|
|
104
104
|
};
|
|
105
105
|
var _getQueryParam = (url, key, multiple) => {
|
|
106
106
|
let encoded;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.5",
|
|
4
4
|
"description": "Ultrafast web framework for the Edges",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"scripts": {
|
|
13
13
|
"test": "jest",
|
|
14
14
|
"test:deno": "env NAME=Deno deno test --allow-read --allow-env runtime_tests/deno",
|
|
15
|
-
"test:bun": "env NAME=Bun bun test --jsx-import-source ../../src/middleware/jsx
|
|
15
|
+
"test:bun": "env NAME=Bun bun test --jsx-import-source ../../src/middleware/jsx runtime_tests/bun/index.test.tsx",
|
|
16
16
|
"test:fastly": "jest --config ./runtime_tests/fastly/jest.config.js",
|
|
17
17
|
"test:lagon": "start-server-and-test \"lagon dev runtime_tests/lagon/index.ts\" http://127.0.0.1:1234 \"yarn jest runtime_tests/lagon/index.test.ts --testMatch '**/*.test.ts'\"",
|
|
18
18
|
"test:node": "env NAME=Node jest --config ./runtime_tests/node/jest.config.js",
|