hono 3.5.8 → 3.6.0-rc.2
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/vercel/handler.js +11 -2
- package/dist/cjs/adapter/vercel/handler.js +11 -2
- package/dist/cjs/client/client.js +4 -1
- package/dist/cjs/context.js +16 -5
- package/dist/cjs/middleware/bearer-auth/index.js +1 -1
- package/dist/cjs/middleware/cors/index.js +2 -2
- package/dist/cjs/middleware/etag/index.js +1 -1
- package/dist/cjs/utils/cookie.js +45 -44
- package/dist/client/client.js +4 -1
- package/dist/context.js +16 -5
- package/dist/middleware/bearer-auth/index.js +1 -1
- package/dist/middleware/cors/index.js +2 -2
- package/dist/middleware/etag/index.js +1 -1
- package/dist/types/adapter/vercel/handler.d.ts +1 -1
- package/dist/types/client/types.d.ts +2 -0
- package/dist/types/context.d.ts +21 -1
- package/dist/types/helper/cookie/index.d.ts +2 -2
- package/dist/types/index.d.ts +1 -1
- package/dist/types/jsx/index.d.ts +3 -1
- package/dist/types/request.d.ts +28 -0
- package/dist/types/types.d.ts +64 -43
- package/dist/types/utils/cookie.d.ts +2 -2
- package/dist/utils/cookie.js +45 -44
- package/package.json +16 -12
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
// src/adapter/vercel/handler.ts
|
|
2
|
-
var handle = (app) => (req) => {
|
|
3
|
-
return app.fetch(
|
|
2
|
+
var handle = (app) => (req, requestContext) => {
|
|
3
|
+
return app.fetch(
|
|
4
|
+
req,
|
|
5
|
+
{},
|
|
6
|
+
{
|
|
7
|
+
waitUntil: requestContext?.waitUntil,
|
|
8
|
+
passThroughOnException: () => {
|
|
9
|
+
throw new Error("`passThroughOnException` is not implemented in the Vercel");
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
);
|
|
4
13
|
};
|
|
5
14
|
export {
|
|
6
15
|
handle
|
|
@@ -21,8 +21,17 @@ __export(handler_exports, {
|
|
|
21
21
|
handle: () => handle
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(handler_exports);
|
|
24
|
-
const handle = (app) => (req) => {
|
|
25
|
-
return app.fetch(
|
|
24
|
+
const handle = (app) => (req, requestContext) => {
|
|
25
|
+
return app.fetch(
|
|
26
|
+
req,
|
|
27
|
+
{},
|
|
28
|
+
{
|
|
29
|
+
waitUntil: requestContext?.waitUntil,
|
|
30
|
+
passThroughOnException: () => {
|
|
31
|
+
throw new Error("`passThroughOnException` is not implemented in the Vercel");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
);
|
|
26
35
|
};
|
|
27
36
|
// Annotate the CommonJS export names for ESM import in node:
|
|
28
37
|
0 && (module.exports = {
|
|
@@ -108,7 +108,7 @@ class ClientRequestImpl {
|
|
|
108
108
|
this.method = method;
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
|
-
const hc = (baseUrl, options) => createProxy(
|
|
111
|
+
const hc = (baseUrl, options) => createProxy((opts) => {
|
|
112
112
|
const parts = [...opts.path];
|
|
113
113
|
let method = "";
|
|
114
114
|
if (/^\$/.test(parts[parts.length - 1])) {
|
|
@@ -119,6 +119,9 @@ const hc = (baseUrl, options) => createProxy(async (opts) => {
|
|
|
119
119
|
}
|
|
120
120
|
const path = parts.join("/");
|
|
121
121
|
const url = (0, import_utils.mergePath)(baseUrl, path);
|
|
122
|
+
if (method === "url") {
|
|
123
|
+
return new URL(url);
|
|
124
|
+
}
|
|
122
125
|
const req = new ClientRequestImpl(url, method);
|
|
123
126
|
if (method) {
|
|
124
127
|
options ?? (options = {});
|
package/dist/cjs/context.js
CHANGED
|
@@ -26,13 +26,19 @@ var import_cookie = require("./utils/cookie");
|
|
|
26
26
|
class Context {
|
|
27
27
|
constructor(req, options) {
|
|
28
28
|
this.env = {};
|
|
29
|
+
this._var = {};
|
|
29
30
|
this.finalized = false;
|
|
30
31
|
this.error = void 0;
|
|
31
32
|
this._status = 200;
|
|
32
33
|
this._h = void 0;
|
|
33
34
|
this._pH = void 0;
|
|
34
35
|
this._init = true;
|
|
36
|
+
this._renderer = (content) => this.html(content);
|
|
35
37
|
this.notFoundHandler = () => new Response();
|
|
38
|
+
this.render = (...args) => this._renderer(...args);
|
|
39
|
+
this.setRenderer = (renderer) => {
|
|
40
|
+
this._renderer = renderer;
|
|
41
|
+
};
|
|
36
42
|
this.header = (name, value, options) => {
|
|
37
43
|
if (value === void 0) {
|
|
38
44
|
if (this._h) {
|
|
@@ -72,11 +78,11 @@ class Context {
|
|
|
72
78
|
this._status = status;
|
|
73
79
|
};
|
|
74
80
|
this.set = (key, value) => {
|
|
75
|
-
this.
|
|
76
|
-
this.
|
|
81
|
+
this._var ?? (this._var = {});
|
|
82
|
+
this._var[key] = value;
|
|
77
83
|
};
|
|
78
84
|
this.get = (key) => {
|
|
79
|
-
return this.
|
|
85
|
+
return this._var ? this._var[key] : void 0;
|
|
80
86
|
};
|
|
81
87
|
this.newResponse = (data, arg, headers) => {
|
|
82
88
|
if (this._init && !headers && !arg && this._status === 200) {
|
|
@@ -144,10 +150,12 @@ class Context {
|
|
|
144
150
|
return typeof arg === "number" ? this.newResponse(body, arg, headers) : this.newResponse(body, arg);
|
|
145
151
|
};
|
|
146
152
|
this.jsonT = (object, arg, headers) => {
|
|
153
|
+
const response = typeof arg === "number" ? this.json(object, arg, headers) : this.json(object, arg);
|
|
147
154
|
return {
|
|
148
|
-
response
|
|
155
|
+
response,
|
|
149
156
|
data: object,
|
|
150
|
-
format: "json"
|
|
157
|
+
format: "json",
|
|
158
|
+
status: response.status
|
|
151
159
|
};
|
|
152
160
|
};
|
|
153
161
|
this.html = (html, arg, headers) => {
|
|
@@ -205,6 +213,9 @@ class Context {
|
|
|
205
213
|
this._res = _res;
|
|
206
214
|
this.finalized = true;
|
|
207
215
|
}
|
|
216
|
+
get var() {
|
|
217
|
+
return { ...this._var };
|
|
218
|
+
}
|
|
208
219
|
get runtime() {
|
|
209
220
|
const global = globalThis;
|
|
210
221
|
if (global?.Deno !== void 0) {
|
|
@@ -37,7 +37,7 @@ const bearerAuth = (options) => {
|
|
|
37
37
|
}
|
|
38
38
|
const realm = options.realm?.replace(/"/g, '\\"');
|
|
39
39
|
return async (c, next) => {
|
|
40
|
-
const headerToken = c.req.
|
|
40
|
+
const headerToken = c.req.header("Authorization");
|
|
41
41
|
if (!headerToken) {
|
|
42
42
|
const res = new Response("Unauthorized", {
|
|
43
43
|
status: 401,
|
|
@@ -45,7 +45,7 @@ const cors = (options) => {
|
|
|
45
45
|
function set(key, value) {
|
|
46
46
|
c.res.headers.set(key, value);
|
|
47
47
|
}
|
|
48
|
-
const allowOrigin = findAllowOrigin(c.req.
|
|
48
|
+
const allowOrigin = findAllowOrigin(c.req.header("origin") || "");
|
|
49
49
|
if (allowOrigin) {
|
|
50
50
|
set("Access-Control-Allow-Origin", allowOrigin);
|
|
51
51
|
}
|
|
@@ -69,7 +69,7 @@ const cors = (options) => {
|
|
|
69
69
|
}
|
|
70
70
|
let headers = opts.allowHeaders;
|
|
71
71
|
if (!headers?.length) {
|
|
72
|
-
const requestHeaders = c.req.
|
|
72
|
+
const requestHeaders = c.req.header("Access-Control-Request-Headers");
|
|
73
73
|
if (requestHeaders) {
|
|
74
74
|
headers = requestHeaders.split(/\s*,\s*/);
|
|
75
75
|
}
|
|
@@ -37,7 +37,7 @@ const etag = (options) => {
|
|
|
37
37
|
const retainedHeaders = options?.retainedHeaders ?? RETAINED_304_HEADERS;
|
|
38
38
|
const weak = options?.weak ?? false;
|
|
39
39
|
return async (c, next) => {
|
|
40
|
-
const ifNoneMatch = c.req.
|
|
40
|
+
const ifNoneMatch = c.req.header("If-None-Match") ?? null;
|
|
41
41
|
await next();
|
|
42
42
|
const res = c.res;
|
|
43
43
|
let etag2 = res.headers.get("ETag");
|
package/dist/cjs/utils/cookie.js
CHANGED
|
@@ -25,59 +25,60 @@ __export(cookie_exports, {
|
|
|
25
25
|
});
|
|
26
26
|
module.exports = __toCommonJS(cookie_exports);
|
|
27
27
|
var import_url = require("./url");
|
|
28
|
+
const algorithm = { name: "HMAC", hash: "SHA-256" };
|
|
29
|
+
const getCryptoKey = async (secret) => {
|
|
30
|
+
const secretBuf = typeof secret === "string" ? new TextEncoder().encode(secret) : secret;
|
|
31
|
+
return await crypto.subtle.importKey("raw", secretBuf, algorithm, false, ["sign", "verify"]);
|
|
32
|
+
};
|
|
28
33
|
const makeSignature = async (value, secret) => {
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), algorithm, false, [
|
|
32
|
-
"sign",
|
|
33
|
-
"verify"
|
|
34
|
-
]);
|
|
35
|
-
const signature = await crypto.subtle.sign(algorithm.name, key, encoder.encode(value));
|
|
34
|
+
const key = await getCryptoKey(secret);
|
|
35
|
+
const signature = await crypto.subtle.sign(algorithm.name, key, new TextEncoder().encode(value));
|
|
36
36
|
return btoa(String.fromCharCode(...new Uint8Array(signature)));
|
|
37
37
|
};
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
const verifySignature = async (base64Signature, value, secret) => {
|
|
39
|
+
try {
|
|
40
|
+
const signatureBinStr = atob(base64Signature);
|
|
41
|
+
const signature = new Uint8Array(signatureBinStr.length);
|
|
42
|
+
for (let i = 0; i < signatureBinStr.length; i++)
|
|
43
|
+
signature[i] = signatureBinStr.charCodeAt(i);
|
|
44
|
+
return await crypto.subtle.verify(algorithm, secret, signature, new TextEncoder().encode(value));
|
|
45
|
+
} catch (e) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
44
48
|
};
|
|
49
|
+
const validCookieNameRegEx = /^[\w!#$%&'*.^`|~+-]+$/;
|
|
50
|
+
const validCookieValueRegEx = /^[ !#-:<-[\]-~]*$/;
|
|
45
51
|
const parse = (cookie, name) => {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
if (
|
|
51
|
-
return
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
52
|
+
const pairs = cookie.trim().split(";");
|
|
53
|
+
return pairs.reduce((parsedCookie, pairStr) => {
|
|
54
|
+
pairStr = pairStr.trim();
|
|
55
|
+
const valueStartPos = pairStr.indexOf("=");
|
|
56
|
+
if (valueStartPos === -1)
|
|
57
|
+
return parsedCookie;
|
|
58
|
+
const cookieName = pairStr.substring(0, valueStartPos).trim();
|
|
59
|
+
if (name && name !== cookieName || !validCookieNameRegEx.test(cookieName))
|
|
60
|
+
return parsedCookie;
|
|
61
|
+
let cookieValue = pairStr.substring(valueStartPos + 1).trim();
|
|
62
|
+
if (cookieValue.startsWith('"') && cookieValue.endsWith('"'))
|
|
63
|
+
cookieValue = cookieValue.slice(1, -1);
|
|
64
|
+
if (validCookieValueRegEx.test(cookieValue))
|
|
65
|
+
parsedCookie[cookieName] = (0, import_url.decodeURIComponent_)(cookieValue);
|
|
66
|
+
return parsedCookie;
|
|
67
|
+
}, {});
|
|
60
68
|
};
|
|
61
69
|
const parseSigned = async (cookie, secret, name) => {
|
|
62
70
|
const parsedCookie = {};
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
const
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
});
|
|
72
|
-
for (let [key, value] of signedCookies) {
|
|
73
|
-
value = (0, import_url.decodeURIComponent_)(value);
|
|
74
|
-
const signedPair = value.split(".");
|
|
75
|
-
const signatureToCompare = await makeSignature(signedPair[0], secret);
|
|
76
|
-
if (signedPair[1] !== signatureToCompare) {
|
|
77
|
-
parsedCookie[key] = false;
|
|
71
|
+
const secretKey = await getCryptoKey(secret);
|
|
72
|
+
for (const [key, value] of Object.entries(parse(cookie, name))) {
|
|
73
|
+
const signatureStartPos = value.lastIndexOf(".");
|
|
74
|
+
if (signatureStartPos < 1)
|
|
75
|
+
continue;
|
|
76
|
+
const signedValue = value.substring(0, signatureStartPos);
|
|
77
|
+
const signature = value.substring(signatureStartPos + 1);
|
|
78
|
+
if (signature.length !== 44 || !signature.endsWith("="))
|
|
78
79
|
continue;
|
|
79
|
-
|
|
80
|
-
parsedCookie[key] =
|
|
80
|
+
const isVerified = await verifySignature(signature, signedValue, secretKey);
|
|
81
|
+
parsedCookie[key] = isVerified ? signedValue : false;
|
|
81
82
|
}
|
|
82
83
|
return parsedCookie;
|
|
83
84
|
};
|
package/dist/client/client.js
CHANGED
|
@@ -86,7 +86,7 @@ var ClientRequestImpl = class {
|
|
|
86
86
|
this.method = method;
|
|
87
87
|
}
|
|
88
88
|
};
|
|
89
|
-
var hc = (baseUrl, options) => createProxy(
|
|
89
|
+
var hc = (baseUrl, options) => createProxy((opts) => {
|
|
90
90
|
const parts = [...opts.path];
|
|
91
91
|
let method = "";
|
|
92
92
|
if (/^\$/.test(parts[parts.length - 1])) {
|
|
@@ -97,6 +97,9 @@ var hc = (baseUrl, options) => createProxy(async (opts) => {
|
|
|
97
97
|
}
|
|
98
98
|
const path = parts.join("/");
|
|
99
99
|
const url = mergePath(baseUrl, path);
|
|
100
|
+
if (method === "url") {
|
|
101
|
+
return new URL(url);
|
|
102
|
+
}
|
|
100
103
|
const req = new ClientRequestImpl(url, method);
|
|
101
104
|
if (method) {
|
|
102
105
|
options ?? (options = {});
|
package/dist/context.js
CHANGED
|
@@ -4,13 +4,19 @@ import { serialize } from "./utils/cookie.js";
|
|
|
4
4
|
var Context = class {
|
|
5
5
|
constructor(req, options) {
|
|
6
6
|
this.env = {};
|
|
7
|
+
this._var = {};
|
|
7
8
|
this.finalized = false;
|
|
8
9
|
this.error = void 0;
|
|
9
10
|
this._status = 200;
|
|
10
11
|
this._h = void 0;
|
|
11
12
|
this._pH = void 0;
|
|
12
13
|
this._init = true;
|
|
14
|
+
this._renderer = (content) => this.html(content);
|
|
13
15
|
this.notFoundHandler = () => new Response();
|
|
16
|
+
this.render = (...args) => this._renderer(...args);
|
|
17
|
+
this.setRenderer = (renderer) => {
|
|
18
|
+
this._renderer = renderer;
|
|
19
|
+
};
|
|
14
20
|
this.header = (name, value, options) => {
|
|
15
21
|
if (value === void 0) {
|
|
16
22
|
if (this._h) {
|
|
@@ -50,11 +56,11 @@ var Context = class {
|
|
|
50
56
|
this._status = status;
|
|
51
57
|
};
|
|
52
58
|
this.set = (key, value) => {
|
|
53
|
-
this.
|
|
54
|
-
this.
|
|
59
|
+
this._var ?? (this._var = {});
|
|
60
|
+
this._var[key] = value;
|
|
55
61
|
};
|
|
56
62
|
this.get = (key) => {
|
|
57
|
-
return this.
|
|
63
|
+
return this._var ? this._var[key] : void 0;
|
|
58
64
|
};
|
|
59
65
|
this.newResponse = (data, arg, headers) => {
|
|
60
66
|
if (this._init && !headers && !arg && this._status === 200) {
|
|
@@ -122,10 +128,12 @@ var Context = class {
|
|
|
122
128
|
return typeof arg === "number" ? this.newResponse(body, arg, headers) : this.newResponse(body, arg);
|
|
123
129
|
};
|
|
124
130
|
this.jsonT = (object, arg, headers) => {
|
|
131
|
+
const response = typeof arg === "number" ? this.json(object, arg, headers) : this.json(object, arg);
|
|
125
132
|
return {
|
|
126
|
-
response
|
|
133
|
+
response,
|
|
127
134
|
data: object,
|
|
128
|
-
format: "json"
|
|
135
|
+
format: "json",
|
|
136
|
+
status: response.status
|
|
129
137
|
};
|
|
130
138
|
};
|
|
131
139
|
this.html = (html, arg, headers) => {
|
|
@@ -183,6 +191,9 @@ var Context = class {
|
|
|
183
191
|
this._res = _res;
|
|
184
192
|
this.finalized = true;
|
|
185
193
|
}
|
|
194
|
+
get var() {
|
|
195
|
+
return { ...this._var };
|
|
196
|
+
}
|
|
186
197
|
get runtime() {
|
|
187
198
|
const global = globalThis;
|
|
188
199
|
if (global?.Deno !== void 0) {
|
|
@@ -15,7 +15,7 @@ var bearerAuth = (options) => {
|
|
|
15
15
|
}
|
|
16
16
|
const realm = options.realm?.replace(/"/g, '\\"');
|
|
17
17
|
return async (c, next) => {
|
|
18
|
-
const headerToken = c.req.
|
|
18
|
+
const headerToken = c.req.header("Authorization");
|
|
19
19
|
if (!headerToken) {
|
|
20
20
|
const res = new Response("Unauthorized", {
|
|
21
21
|
status: 401,
|
|
@@ -23,7 +23,7 @@ var cors = (options) => {
|
|
|
23
23
|
function set(key, value) {
|
|
24
24
|
c.res.headers.set(key, value);
|
|
25
25
|
}
|
|
26
|
-
const allowOrigin = findAllowOrigin(c.req.
|
|
26
|
+
const allowOrigin = findAllowOrigin(c.req.header("origin") || "");
|
|
27
27
|
if (allowOrigin) {
|
|
28
28
|
set("Access-Control-Allow-Origin", allowOrigin);
|
|
29
29
|
}
|
|
@@ -47,7 +47,7 @@ var cors = (options) => {
|
|
|
47
47
|
}
|
|
48
48
|
let headers = opts.allowHeaders;
|
|
49
49
|
if (!headers?.length) {
|
|
50
|
-
const requestHeaders = c.req.
|
|
50
|
+
const requestHeaders = c.req.header("Access-Control-Request-Headers");
|
|
51
51
|
if (requestHeaders) {
|
|
52
52
|
headers = requestHeaders.split(/\s*,\s*/);
|
|
53
53
|
}
|
|
@@ -15,7 +15,7 @@ var etag = (options) => {
|
|
|
15
15
|
const retainedHeaders = options?.retainedHeaders ?? RETAINED_304_HEADERS;
|
|
16
16
|
const weak = options?.weak ?? false;
|
|
17
17
|
return async (c, next) => {
|
|
18
|
-
const ifNoneMatch = c.req.
|
|
18
|
+
const ifNoneMatch = c.req.header("If-None-Match") ?? null;
|
|
19
19
|
await next();
|
|
20
20
|
const res = c.res;
|
|
21
21
|
let etag2 = res.headers.get("ETag");
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { Hono } from '../../hono';
|
|
2
|
-
export declare const handle: (app: Hono<any, any, any>) => (req: Request) => Response | Promise<Response>;
|
|
2
|
+
export declare const handle: (app: Hono<any, any, any>) => (req: Request, requestContext: Omit<ExecutionContext, 'passThroughOnException'>) => Response | Promise<Response>;
|
|
@@ -10,6 +10,8 @@ declare type ClientRequest<S extends Schema> = {
|
|
|
10
10
|
input: infer R;
|
|
11
11
|
output: infer O;
|
|
12
12
|
} ? RemoveBlankRecord<R> extends never ? (args?: {}, options?: ClientRequestOptions) => Promise<ClientResponse<O>> : (args: Omit<R, 'header' | 'cookie'>, options?: ClientRequestOptions) => Promise<ClientResponse<O>> : never;
|
|
13
|
+
} & {
|
|
14
|
+
$url: () => URL;
|
|
13
15
|
};
|
|
14
16
|
declare type BlankRecordToNever<T> = T extends Record<infer R, unknown> ? R extends never ? never : T : never;
|
|
15
17
|
export interface ClientResponse<T> {
|
package/dist/types/context.d.ts
CHANGED
|
@@ -13,6 +13,12 @@ export interface ExecutionContext {
|
|
|
13
13
|
}
|
|
14
14
|
export interface ContextVariableMap {
|
|
15
15
|
}
|
|
16
|
+
export interface ContextRenderer {
|
|
17
|
+
}
|
|
18
|
+
interface DefaultRenderer {
|
|
19
|
+
(content: string): Response | Promise<Response>;
|
|
20
|
+
}
|
|
21
|
+
declare type Renderer = ContextRenderer extends Function ? ContextRenderer : DefaultRenderer;
|
|
16
22
|
interface Get<E extends Env> {
|
|
17
23
|
<Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
|
|
18
24
|
<Key extends keyof E['Variables']>(key: Key): E['Variables'][Key];
|
|
@@ -51,27 +57,41 @@ declare type ContextOptions<E extends Env> = {
|
|
|
51
57
|
export declare class Context<E extends Env = any, P extends string = any, I extends Input = {}> {
|
|
52
58
|
req: HonoRequest<P, I['out']>;
|
|
53
59
|
env: E['Bindings'];
|
|
60
|
+
private _var;
|
|
54
61
|
finalized: boolean;
|
|
55
62
|
error: Error | undefined;
|
|
56
63
|
private _status;
|
|
57
64
|
private _exCtx;
|
|
58
|
-
private _map;
|
|
59
65
|
private _h;
|
|
60
66
|
private _pH;
|
|
61
67
|
private _res;
|
|
62
68
|
private _init;
|
|
69
|
+
private _renderer;
|
|
63
70
|
private notFoundHandler;
|
|
64
71
|
constructor(req: HonoRequest<P, I['out']>, options?: ContextOptions<E>);
|
|
65
72
|
get event(): FetchEventLike;
|
|
66
73
|
get executionCtx(): ExecutionContext;
|
|
67
74
|
get res(): Response;
|
|
68
75
|
set res(_res: Response | undefined);
|
|
76
|
+
/**
|
|
77
|
+
* @experimental
|
|
78
|
+
* `c.render()` is an experimental feature.
|
|
79
|
+
* The API might be changed.
|
|
80
|
+
*/
|
|
81
|
+
render: Renderer;
|
|
82
|
+
/**
|
|
83
|
+
* @experimental
|
|
84
|
+
* `c.setRenderer()` is an experimental feature.
|
|
85
|
+
* The API might be changed.
|
|
86
|
+
*/
|
|
87
|
+
setRenderer: (renderer: Renderer) => void;
|
|
69
88
|
header: (name: string, value: string | undefined, options?: {
|
|
70
89
|
append?: boolean;
|
|
71
90
|
}) => void;
|
|
72
91
|
status: (status: StatusCode) => void;
|
|
73
92
|
set: Set<E>;
|
|
74
93
|
get: Get<E>;
|
|
94
|
+
get var(): Readonly<E['Variables']>;
|
|
75
95
|
newResponse: NewResponse;
|
|
76
96
|
body: BodyRespond;
|
|
77
97
|
text: TextRespond;
|
|
@@ -5,12 +5,12 @@ interface GetCookie {
|
|
|
5
5
|
(c: Context): Cookie;
|
|
6
6
|
}
|
|
7
7
|
interface GetSignedCookie {
|
|
8
|
-
(c: Context, secret: string, key: string): Promise<string | undefined | false>;
|
|
8
|
+
(c: Context, secret: string | BufferSource, key: string): Promise<string | undefined | false>;
|
|
9
9
|
(c: Context, secret: string): Promise<SignedCookie>;
|
|
10
10
|
}
|
|
11
11
|
export declare const getCookie: GetCookie;
|
|
12
12
|
export declare const getSignedCookie: GetSignedCookie;
|
|
13
13
|
export declare const setCookie: (c: Context, name: string, value: string, opt?: CookieOptions) => void;
|
|
14
|
-
export declare const setSignedCookie: (c: Context, name: string, value: string, secret: string, opt?: CookieOptions) => Promise<void>;
|
|
14
|
+
export declare const setSignedCookie: (c: Context, name: string, value: string, secret: string | BufferSource, opt?: CookieOptions) => Promise<void>;
|
|
15
15
|
export declare const deleteCookie: (c: Context, name: string, opt?: CookieOptions) => void;
|
|
16
16
|
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Hono } from './hono';
|
|
2
2
|
export type { Env, ErrorHandler, Handler, MiddlewareHandler, Next, NotFoundHandler, ValidationTargets, Input, Schema, ToSchema, TypedResponse, } from './types';
|
|
3
|
-
export type { Context, ContextVariableMap } from './context';
|
|
3
|
+
export type { Context, ContextVariableMap, ContextRenderer } from './context';
|
|
4
4
|
export type { HonoRequest } from './request';
|
|
5
5
|
export type { InferRequestType, InferResponseType, ClientRequestOptions } from './client';
|
|
6
6
|
export { Hono };
|
|
@@ -23,7 +23,9 @@ export declare class JSXNode implements HtmlEscaped {
|
|
|
23
23
|
}
|
|
24
24
|
export { jsxFn as jsx };
|
|
25
25
|
declare const jsxFn: (tag: string | Function, props: Props, ...children: (string | HtmlEscapedString)[]) => JSXNode;
|
|
26
|
-
declare type FC<T = Props> = (props: T
|
|
26
|
+
export declare type FC<T = Props> = (props: T & {
|
|
27
|
+
children?: Child;
|
|
28
|
+
}) => HtmlEscapedString;
|
|
27
29
|
export declare const memo: <T>(component: FC<T>, propsAreEqual?: (prevProps: Readonly<T>, nextProps: Readonly<T>) => boolean) => FC<T>;
|
|
28
30
|
export declare const Fragment: (props: {
|
|
29
31
|
key?: string;
|
package/dist/types/request.d.ts
CHANGED
|
@@ -58,12 +58,40 @@ export declare class HonoRequest<P extends string = '/', I extends Input['out']
|
|
|
58
58
|
valid<T extends keyof I & keyof ValidationTargets>(target: T): InputToDataByTarget<I, T>;
|
|
59
59
|
get url(): string;
|
|
60
60
|
get method(): string;
|
|
61
|
+
/** @deprecated
|
|
62
|
+
* Use `c.req.raw.headers` instead of `c.req.headers`. The `c.req.headers` will be removed in v4.
|
|
63
|
+
* Or you can get the header values with using `c.req.header`.
|
|
64
|
+
* @example
|
|
65
|
+
*
|
|
66
|
+
* app.get('/', (c) => {
|
|
67
|
+
* const userAgent = c.req.header('User-Agent')
|
|
68
|
+
* //...
|
|
69
|
+
* })
|
|
70
|
+
*/
|
|
61
71
|
get headers(): Headers;
|
|
72
|
+
/** @deprecated
|
|
73
|
+
* Use `c.req.raw.body` instead of `c.req.body`. The `c.req.body` will be removed in v4.
|
|
74
|
+
*/
|
|
62
75
|
get body(): ReadableStream<Uint8Array> | null;
|
|
76
|
+
/** @deprecated
|
|
77
|
+
* Use `c.req.raw.bodyUsed` instead of `c.req.bodyUsed`. The `c.req.bodyUsed` will be removed in v4.
|
|
78
|
+
*/
|
|
63
79
|
get bodyUsed(): boolean;
|
|
80
|
+
/** @deprecated
|
|
81
|
+
* Use `c.req.raw.integrity` instead of `c.req.integrity`. The `c.req.integrity` will be removed in v4.
|
|
82
|
+
*/
|
|
64
83
|
get integrity(): string;
|
|
84
|
+
/** @deprecated
|
|
85
|
+
* Use `c.req.raw.keepalive` instead of `c.req.keepalive`. The `c.req.keepalive` will be removed in v4.
|
|
86
|
+
*/
|
|
65
87
|
get keepalive(): boolean;
|
|
88
|
+
/** @deprecated
|
|
89
|
+
* Use `c.req.raw.referrer` instead of `c.req.referrer`. The `c.req.referrer` will be removed in v4.
|
|
90
|
+
*/
|
|
66
91
|
get referrer(): string;
|
|
92
|
+
/** @deprecated
|
|
93
|
+
* Use `c.req.raw.signal` instead of `c.req.signal`. The `c.req.signal` will be removed in v4.
|
|
94
|
+
*/
|
|
67
95
|
get signal(): AbortSignal;
|
|
68
96
|
}
|
|
69
97
|
export {};
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Context } from './context';
|
|
2
2
|
import type { Hono } from './hono';
|
|
3
|
+
import type { StatusCode } from './utils/http-status';
|
|
3
4
|
import type { UnionToIntersection } from './utils/types';
|
|
4
5
|
export declare type Bindings = Record<string, unknown>;
|
|
5
6
|
export declare type Variables = Record<string, unknown>;
|
|
@@ -17,63 +18,82 @@ export declare type Input = {
|
|
|
17
18
|
declare type HandlerResponse<O> = Response | TypedResponse<O> | Promise<Response | TypedResponse<O>>;
|
|
18
19
|
export declare type Handler<E extends Env = any, P extends string = any, I extends Input = Input, R extends HandlerResponse<any> = any> = (c: Context<E, P, I>, next: Next) => R;
|
|
19
20
|
export declare type MiddlewareHandler<E extends Env = any, P extends string = any, I extends Input = {}> = (c: Context<E, P, I>, next: Next) => Promise<Response | void>;
|
|
20
|
-
export declare type H<E extends Env = any, P extends string = any, I extends Input = {}, R extends HandlerResponse<any> = any> = Handler<
|
|
21
|
+
export declare type H<E extends Env = any, P extends string = any, I extends Input = {}, E2 extends Env = E, R extends HandlerResponse<any> = any> = Handler<E2, P, I, R> | MiddlewareHandler<E2, P, I>;
|
|
21
22
|
export declare type NotFoundHandler<E extends Env = any> = (c: Context<E>) => Response | Promise<Response>;
|
|
22
23
|
export declare type ErrorHandler<E extends Env = any> = (err: Error, c: Context<E>) => Response | Promise<Response>;
|
|
23
24
|
export interface HandlerInterface<E extends Env = Env, M extends string = any, S extends Schema = {}, BasePath extends string = '/'> {
|
|
24
|
-
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = {}, R extends HandlerResponse<any> = any>(
|
|
25
|
-
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any,
|
|
26
|
-
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2,
|
|
27
|
-
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I2 & I3,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
H<
|
|
25
|
+
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = {}, R extends HandlerResponse<any> = any, Temp extends Env = E>(handler: H<E, P, I, Temp, R>): Hono<E, S & ToSchema<M, P, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
26
|
+
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = {}, R extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = E, Temp extends Env = E & E2>(...handlers: [H<E2, P, I, E2, R>, H<E3, P, I, Temp, R>]): Hono<E, S & ToSchema<M, P, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
27
|
+
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, Temp extends Env = E & E2 & E3>(...handlers: [H<E2, P, I, E2, R>, H<E3, P, I2, E3, R>, H<E4, P, I3, Temp, R>]): Hono<E, S & ToSchema<M, P, I3['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
28
|
+
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, Temp extends Env = E & E2 & E3 & E4>(...handlers: [
|
|
29
|
+
H<E2, P, I, E2, R>,
|
|
30
|
+
H<E3, P, I2, E3, R>,
|
|
31
|
+
H<E4, P, I3, E4, R>,
|
|
32
|
+
H<E5, P, I3, Temp, R>
|
|
33
|
+
]): Hono<E, S & ToSchema<M, P, I4['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
34
|
+
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, Temp extends Env = E & E2 & E3 & E4 & E5>(...handlers: [
|
|
35
|
+
H<E2, P, I, E2, R>,
|
|
36
|
+
H<E3, P, I2, E3, R>,
|
|
37
|
+
H<E4, P, I3, E4, R>,
|
|
38
|
+
H<E5, P, I3, E5, R>,
|
|
39
|
+
H<E6, P, I3, Temp, R>
|
|
40
|
+
]): Hono<E, S & ToSchema<M, P, I5['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
41
|
+
<P extends string = ExtractKey<S> extends never ? BasePath : ExtractKey<S>, I extends Input = {}, R extends HandlerResponse<any> = any>(...handlers: H<E, P, I, E, R>[]): Hono<E, S & ToSchema<M, P, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
42
|
+
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}>(path: P): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
43
|
+
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, Temp extends Env = E>(path: P, handler: H<E, MergePath<BasePath, P>, I, Temp, R>): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
44
|
+
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, E2 extends Env = E, E3 extends Env = E, Temp extends Env = E & E2>(path: P, ...handlers: [
|
|
45
|
+
H<E2, MergePath<BasePath, P>, I, E2, R>,
|
|
46
|
+
H<E3, MergePath<BasePath, P>, I, Temp, R>
|
|
47
|
+
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
48
|
+
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, Temp extends Env = E & E2 & E3>(path: P, ...handlers: [
|
|
49
|
+
H<E2, MergePath<BasePath, P>, I, E2, R>,
|
|
50
|
+
H<E3, MergePath<BasePath, P>, I2, E3, R>,
|
|
51
|
+
H<E4, MergePath<BasePath, P>, I3, Temp, R>
|
|
35
52
|
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I3['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
36
|
-
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3>(path: P, ...handlers: [
|
|
37
|
-
H<
|
|
38
|
-
H<
|
|
39
|
-
H<
|
|
40
|
-
H<
|
|
53
|
+
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, Temp extends Env = E & E2 & E3 & E4>(path: P, ...handlers: [
|
|
54
|
+
H<E2, MergePath<BasePath, P>, I, E2, R>,
|
|
55
|
+
H<E3, MergePath<BasePath, P>, I2, E3, R>,
|
|
56
|
+
H<E4, MergePath<BasePath, P>, I3, E4, R>,
|
|
57
|
+
H<E5, MergePath<BasePath, P>, I4, Temp, R>
|
|
41
58
|
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I4['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
42
|
-
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I2 & I3, I5 extends Input = I & I2 & I3 & I4>(path: P, ...handlers: [
|
|
43
|
-
H<
|
|
44
|
-
H<
|
|
45
|
-
H<
|
|
46
|
-
H<
|
|
47
|
-
H<
|
|
59
|
+
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E, Temp extends Env = E & E2 & E3 & E4 & E5>(path: P, ...handlers: [
|
|
60
|
+
H<E2, MergePath<BasePath, P>, I, E2, R>,
|
|
61
|
+
H<E3, MergePath<BasePath, P>, I2, E3, R>,
|
|
62
|
+
H<E4, MergePath<BasePath, P>, I3, E4, R>,
|
|
63
|
+
H<E5, MergePath<BasePath, P>, I4, E5, R>,
|
|
64
|
+
H<E6, MergePath<BasePath, P>, I5, Temp, R>
|
|
48
65
|
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I5['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
49
|
-
<P extends string, I extends Input = {}, R extends HandlerResponse<any> = any>(path: P, ...handlers: H<E, MergePath<BasePath, P>, I, R>[]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
66
|
+
<P extends string, I extends Input = {}, R extends HandlerResponse<any> = any>(path: P, ...handlers: H<E, MergePath<BasePath, P>, I, E, R>[]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
50
67
|
}
|
|
51
68
|
export interface MiddlewareHandlerInterface<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'> {
|
|
52
69
|
(...handlers: MiddlewareHandler<E, MergePath<BasePath, ExtractKey<S>>>[]): Hono<E, S, BasePath>;
|
|
53
70
|
<P extends string>(path: P, ...handlers: MiddlewareHandler<E, MergePath<BasePath, P>>[]): Hono<E, S, BasePath>;
|
|
54
71
|
}
|
|
55
72
|
export interface OnHandlerInterface<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'> {
|
|
56
|
-
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = {}
|
|
57
|
-
|
|
58
|
-
H<
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, E2 extends Env = E, E3 extends Env = E>(method: M, path: P, ...handlers: [
|
|
74
|
+
H<E2, MergePath<BasePath, P>, I, E2, R>,
|
|
75
|
+
H<E3, MergePath<BasePath, P>, I, E & E2, R>
|
|
76
|
+
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
77
|
+
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E>(method: M, path: P, ...handlers: [
|
|
78
|
+
H<E2, MergePath<BasePath, P>, I, E2, R>,
|
|
79
|
+
H<E3, MergePath<BasePath, P>, I2, E3, R>,
|
|
80
|
+
H<E4, MergePath<BasePath, P>, I3, E & E2 & E3, R>
|
|
61
81
|
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I3['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
62
|
-
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I2 & I3>(method: M, path: P, ...handlers: [
|
|
63
|
-
H<
|
|
64
|
-
H<
|
|
65
|
-
H<
|
|
66
|
-
H<
|
|
82
|
+
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E>(method: M, path: P, ...handlers: [
|
|
83
|
+
H<E2, MergePath<BasePath, P>, I, E2, R>,
|
|
84
|
+
H<E3, MergePath<BasePath, P>, I2, E3, R>,
|
|
85
|
+
H<E4, MergePath<BasePath, P>, I3, E4, R>,
|
|
86
|
+
H<E5, MergePath<BasePath, P>, I4, E & E2 & E3 & E4, R>
|
|
67
87
|
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I4['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
68
|
-
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I2 & I3, I5 extends Input = I3 & I4>(method: M, path: P, ...handlers: [
|
|
69
|
-
H<
|
|
70
|
-
H<
|
|
71
|
-
H<
|
|
72
|
-
H<
|
|
73
|
-
H<
|
|
88
|
+
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = {}, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = E, E4 extends Env = E, E5 extends Env = E, E6 extends Env = E>(method: M, path: P, ...handlers: [
|
|
89
|
+
H<E2, MergePath<BasePath, P>, I, E2, R>,
|
|
90
|
+
H<E3, MergePath<BasePath, P>, I2, E3, R>,
|
|
91
|
+
H<E4, MergePath<BasePath, P>, I3, E4, R>,
|
|
92
|
+
H<E5, MergePath<BasePath, P>, I4, E5, R>,
|
|
93
|
+
H<E6, MergePath<BasePath, P>, I5, E & E2 & E3 & E4 & E5, R>
|
|
74
94
|
]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I5['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
75
|
-
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = {}>(method: M, path: P, ...handlers: H<E, MergePath<BasePath, P>, I, R>[]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
76
|
-
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}>(methods: string[], path: P, ...handlers: H<E, MergePath<BasePath, P>, I, R>[]): Hono<E, S & ToSchema<string, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
95
|
+
<M extends string, P extends string, R extends HandlerResponse<any> = any, I extends Input = {}>(method: M, path: P, ...handlers: H<E, MergePath<BasePath, P>, I, E, R>[]): Hono<E, S & ToSchema<M, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
96
|
+
<P extends string, R extends HandlerResponse<any> = any, I extends Input = {}>(methods: string[], path: P, ...handlers: H<E, MergePath<BasePath, P>, I, E, R>[]): Hono<E, S & ToSchema<string, MergePath<BasePath, P>, I['in'], MergeTypedResponseData<R>>, BasePath>;
|
|
77
97
|
}
|
|
78
98
|
declare type ExtractKey<S> = S extends Record<infer Key, unknown> ? Key extends string ? Key : never : string;
|
|
79
99
|
export declare type ToSchema<M extends string, P extends string, I extends Input['in'], O> = {
|
|
@@ -95,7 +115,7 @@ export declare type Schema = {
|
|
|
95
115
|
};
|
|
96
116
|
};
|
|
97
117
|
export declare type MergeSchemaPath<OrigSchema, SubPath extends string> = {
|
|
98
|
-
[K in keyof OrigSchema as `${SubPath
|
|
118
|
+
[K in keyof OrigSchema as `${MergePath<SubPath, K & string>}`]: OrigSchema[K];
|
|
99
119
|
};
|
|
100
120
|
export declare type AddParam<I, P extends string> = ParamKeys<P> extends never ? I : I & {
|
|
101
121
|
param: UnionToIntersection<ParamKeyToRecord<ParamKeys<P>>>;
|
|
@@ -106,6 +126,7 @@ export declare type TypedResponse<T = unknown> = {
|
|
|
106
126
|
response: Response | Promise<Response>;
|
|
107
127
|
data: T;
|
|
108
128
|
format: 'json';
|
|
129
|
+
status: StatusCode;
|
|
109
130
|
};
|
|
110
131
|
declare type ExtractResponseData<T> = T extends Promise<infer T2> ? T2 extends TypedResponse<infer U> ? U : never : T extends TypedResponse<infer U> ? U : never;
|
|
111
132
|
declare type MergeTypedResponseData<T> = UnionToIntersection<ExtractResponseData<T>>;
|
|
@@ -11,6 +11,6 @@ export declare type CookieOptions = {
|
|
|
11
11
|
sameSite?: 'Strict' | 'Lax' | 'None';
|
|
12
12
|
};
|
|
13
13
|
export declare const parse: (cookie: string, name?: string) => Cookie;
|
|
14
|
-
export declare const parseSigned: (cookie: string, secret: string, name?: string) => Promise<SignedCookie>;
|
|
14
|
+
export declare const parseSigned: (cookie: string, secret: string | BufferSource, name?: string) => Promise<SignedCookie>;
|
|
15
15
|
export declare const serialize: (name: string, value: string, opt?: CookieOptions) => string;
|
|
16
|
-
export declare const serializeSigned: (name: string, value: string, secret: string, opt?: CookieOptions) => Promise<string>;
|
|
16
|
+
export declare const serializeSigned: (name: string, value: string, secret: string | BufferSource, opt?: CookieOptions) => Promise<string>;
|
package/dist/utils/cookie.js
CHANGED
|
@@ -1,58 +1,59 @@
|
|
|
1
1
|
// src/utils/cookie.ts
|
|
2
2
|
import { decodeURIComponent_ } from "./url.js";
|
|
3
|
+
var algorithm = { name: "HMAC", hash: "SHA-256" };
|
|
4
|
+
var getCryptoKey = async (secret) => {
|
|
5
|
+
const secretBuf = typeof secret === "string" ? new TextEncoder().encode(secret) : secret;
|
|
6
|
+
return await crypto.subtle.importKey("raw", secretBuf, algorithm, false, ["sign", "verify"]);
|
|
7
|
+
};
|
|
3
8
|
var makeSignature = async (value, secret) => {
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const key = await crypto.subtle.importKey("raw", encoder.encode(secret), algorithm, false, [
|
|
7
|
-
"sign",
|
|
8
|
-
"verify"
|
|
9
|
-
]);
|
|
10
|
-
const signature = await crypto.subtle.sign(algorithm.name, key, encoder.encode(value));
|
|
9
|
+
const key = await getCryptoKey(secret);
|
|
10
|
+
const signature = await crypto.subtle.sign(algorithm.name, key, new TextEncoder().encode(value));
|
|
11
11
|
return btoa(String.fromCharCode(...new Uint8Array(signature)));
|
|
12
12
|
};
|
|
13
|
-
var
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
var verifySignature = async (base64Signature, value, secret) => {
|
|
14
|
+
try {
|
|
15
|
+
const signatureBinStr = atob(base64Signature);
|
|
16
|
+
const signature = new Uint8Array(signatureBinStr.length);
|
|
17
|
+
for (let i = 0; i < signatureBinStr.length; i++)
|
|
18
|
+
signature[i] = signatureBinStr.charCodeAt(i);
|
|
19
|
+
return await crypto.subtle.verify(algorithm, secret, signature, new TextEncoder().encode(value));
|
|
20
|
+
} catch (e) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
19
23
|
};
|
|
24
|
+
var validCookieNameRegEx = /^[\w!#$%&'*.^`|~+-]+$/;
|
|
25
|
+
var validCookieValueRegEx = /^[ !#-:<-[\]-~]*$/;
|
|
20
26
|
var parse = (cookie, name) => {
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
const pairs = cookie.trim().split(";");
|
|
28
|
+
return pairs.reduce((parsedCookie, pairStr) => {
|
|
29
|
+
pairStr = pairStr.trim();
|
|
30
|
+
const valueStartPos = pairStr.indexOf("=");
|
|
31
|
+
if (valueStartPos === -1)
|
|
32
|
+
return parsedCookie;
|
|
33
|
+
const cookieName = pairStr.substring(0, valueStartPos).trim();
|
|
34
|
+
if (name && name !== cookieName || !validCookieNameRegEx.test(cookieName))
|
|
35
|
+
return parsedCookie;
|
|
36
|
+
let cookieValue = pairStr.substring(valueStartPos + 1).trim();
|
|
37
|
+
if (cookieValue.startsWith('"') && cookieValue.endsWith('"'))
|
|
38
|
+
cookieValue = cookieValue.slice(1, -1);
|
|
39
|
+
if (validCookieValueRegEx.test(cookieValue))
|
|
40
|
+
parsedCookie[cookieName] = decodeURIComponent_(cookieValue);
|
|
41
|
+
return parsedCookie;
|
|
42
|
+
}, {});
|
|
35
43
|
};
|
|
36
44
|
var parseSigned = async (cookie, secret, name) => {
|
|
37
45
|
const parsedCookie = {};
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
if (
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
});
|
|
47
|
-
for (let [key, value] of signedCookies) {
|
|
48
|
-
value = decodeURIComponent_(value);
|
|
49
|
-
const signedPair = value.split(".");
|
|
50
|
-
const signatureToCompare = await makeSignature(signedPair[0], secret);
|
|
51
|
-
if (signedPair[1] !== signatureToCompare) {
|
|
52
|
-
parsedCookie[key] = false;
|
|
46
|
+
const secretKey = await getCryptoKey(secret);
|
|
47
|
+
for (const [key, value] of Object.entries(parse(cookie, name))) {
|
|
48
|
+
const signatureStartPos = value.lastIndexOf(".");
|
|
49
|
+
if (signatureStartPos < 1)
|
|
50
|
+
continue;
|
|
51
|
+
const signedValue = value.substring(0, signatureStartPos);
|
|
52
|
+
const signature = value.substring(signatureStartPos + 1);
|
|
53
|
+
if (signature.length !== 44 || !signature.endsWith("="))
|
|
53
54
|
continue;
|
|
54
|
-
|
|
55
|
-
parsedCookie[key] =
|
|
55
|
+
const isVerified = await verifySignature(signature, signedValue, secretKey);
|
|
56
|
+
parsedCookie[key] = isVerified ? signedValue : false;
|
|
56
57
|
}
|
|
57
58
|
return parsedCookie;
|
|
58
59
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.6.0-rc.2",
|
|
4
4
|
"description": "Ultrafast web framework for the Edges",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -10,15 +10,15 @@
|
|
|
10
10
|
"dist"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"test": "
|
|
13
|
+
"test": "tsc --noEmit && vitest --run",
|
|
14
14
|
"test:deno": "env NAME=Deno deno test --allow-read --allow-env runtime_tests/deno",
|
|
15
15
|
"test:bun": "env NAME=Bun bun test --jsx-import-source ../../src/jsx runtime_tests/bun/index.test.tsx",
|
|
16
16
|
"test:fastly": "jest --config ./runtime_tests/fastly/jest.config.js",
|
|
17
|
-
"test:lagon": "start-server-and-test \"lagon dev runtime_tests/lagon/index.ts -e runtime_tests/lagon/.env.lagon\" http://127.0.0.1:1234 \"yarn
|
|
18
|
-
"test:node": "env NAME=Node
|
|
19
|
-
"test:wrangler": "
|
|
20
|
-
"test:lambda": "env NAME=Node
|
|
21
|
-
"test:lambda-edge": "env NAME=Node
|
|
17
|
+
"test:lagon": "start-server-and-test \"lagon dev runtime_tests/lagon/index.ts -e runtime_tests/lagon/.env.lagon\" http://127.0.0.1:1234 \"yarn vitest --run runtime_tests/lagon/index.test.ts --config runtime_tests/lagon/vitest.config.ts\"",
|
|
18
|
+
"test:node": "env NAME=Node vitest --run --config ./runtime_tests/node/vitest.config.ts",
|
|
19
|
+
"test:wrangler": "vitest --run --config ./runtime_tests/wrangler/vitest.config.ts",
|
|
20
|
+
"test:lambda": "env NAME=Node vitest --run --config ./runtime_tests/lambda/vitest.config.ts",
|
|
21
|
+
"test:lambda-edge": "env NAME=Node vitest --run --config ./runtime_tests/lambda-edge/vitest.config.ts",
|
|
22
22
|
"test:all": "yarn test && yarn test:deno && yarn test:bun && yarn test:fastly && yarn test:lagon && yarn test:node && yarn test:wrangler && yarn test:lambda && yarn test:lambda-edge",
|
|
23
23
|
"lint": "eslint --ext js,ts src runtime_tests .eslintrc.cjs",
|
|
24
24
|
"lint:fix": "eslint --ext js,ts src runtime_tests .eslintrc.cjs --fix",
|
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
"build": "rimraf dist && tsx ./build.ts && yarn copy:package.cjs.json",
|
|
30
30
|
"postbuild": "publint",
|
|
31
31
|
"watch": "rimraf dist && tsx ./build.ts --watch && yarn copy:package.cjs.json",
|
|
32
|
+
"coverage": "vitest --run --coverage",
|
|
32
33
|
"prerelease": "yarn denoify && yarn test:deno && yarn build",
|
|
33
34
|
"release": "np"
|
|
34
35
|
},
|
|
@@ -386,6 +387,7 @@
|
|
|
386
387
|
"@types/supertest": "^2.0.12",
|
|
387
388
|
"@typescript-eslint/eslint-plugin": "^5.59.2",
|
|
388
389
|
"@typescript-eslint/parser": "^5.59.2",
|
|
390
|
+
"@vitest/coverage-v8": "^0.34.3",
|
|
389
391
|
"arg": "^5.0.2",
|
|
390
392
|
"crypto-js": "^4.1.1",
|
|
391
393
|
"denoify": "^1.1.1",
|
|
@@ -399,9 +401,8 @@
|
|
|
399
401
|
"eslint-plugin-import": "^2.27.5",
|
|
400
402
|
"eslint-plugin-node": "^11.1.0",
|
|
401
403
|
"form-data": "^4.0.0",
|
|
402
|
-
"jest": "^29.4
|
|
403
|
-
"jest-
|
|
404
|
-
"jest-preset-fastly-js-compute": "^0.6.1",
|
|
404
|
+
"jest": "^29.6.4",
|
|
405
|
+
"jest-preset-fastly-js-compute": "^1.3.0",
|
|
405
406
|
"msw": "^1.0.0",
|
|
406
407
|
"node-fetch": "2",
|
|
407
408
|
"np": "^7.7.0",
|
|
@@ -410,13 +411,16 @@
|
|
|
410
411
|
"rimraf": "^3.0.2",
|
|
411
412
|
"start-server-and-test": "^1.15.2",
|
|
412
413
|
"supertest": "^6.3.3",
|
|
413
|
-
"ts-jest": "^29.
|
|
414
|
+
"ts-jest": "^29.1.1",
|
|
414
415
|
"tsx": "^3.11.0",
|
|
415
416
|
"typescript": "^4.8.3",
|
|
417
|
+
"vitest": "^0.34.3",
|
|
418
|
+
"vitest-environment-miniflare": "^2.14.1",
|
|
416
419
|
"wrangler": "^2.12.0",
|
|
417
420
|
"zod": "^3.20.2"
|
|
418
421
|
},
|
|
419
422
|
"engines": {
|
|
420
423
|
"node": ">=16.0.0"
|
|
421
|
-
}
|
|
424
|
+
},
|
|
425
|
+
"dependencies": {}
|
|
422
426
|
}
|