hono 4.6.20 → 4.7.1
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 +0 -2
- package/dist/cjs/adapter/aws-lambda/handler.js +0 -8
- package/dist/cjs/helper/accepts/accepts.js +4 -26
- package/dist/cjs/helper/factory/index.js +6 -2
- package/dist/cjs/helper/proxy/index.js +75 -0
- package/dist/cjs/middleware/combine/index.js +10 -3
- package/dist/cjs/middleware/etag/digest.js +3 -8
- package/dist/cjs/middleware/etag/index.js +18 -2
- package/dist/cjs/middleware/jwk/index.js +28 -0
- package/dist/cjs/middleware/jwk/jwk.js +124 -0
- package/dist/cjs/middleware/language/index.js +36 -0
- package/dist/cjs/middleware/language/language.js +210 -0
- package/dist/cjs/middleware/logger/index.js +2 -3
- package/dist/cjs/request.js +1 -1
- package/dist/cjs/router/linear-router/router.js +3 -1
- package/dist/cjs/router/trie-router/node.js +24 -11
- package/dist/cjs/utils/accept.js +86 -0
- package/dist/cjs/utils/jwt/index.js +1 -1
- package/dist/cjs/utils/jwt/jwt.js +56 -3
- package/dist/cjs/utils/jwt/types.js +8 -0
- package/dist/cjs/utils/url.js +10 -25
- package/dist/helper/accepts/accepts.js +2 -23
- package/dist/helper/factory/index.js +6 -2
- package/dist/helper/proxy/index.js +52 -0
- package/dist/middleware/combine/index.js +10 -3
- package/dist/middleware/etag/digest.js +3 -8
- package/dist/middleware/etag/index.js +18 -2
- package/dist/middleware/jwk/index.js +5 -0
- package/dist/middleware/jwk/jwk.js +101 -0
- package/dist/middleware/language/index.js +15 -0
- package/dist/middleware/language/language.js +178 -0
- package/dist/middleware/logger/index.js +2 -3
- package/dist/request.js +1 -1
- package/dist/router/linear-router/router.js +3 -1
- package/dist/router/trie-router/node.js +24 -11
- package/dist/types/adapter/cloudflare-pages/handler.d.ts +1 -1
- package/dist/types/adapter/cloudflare-workers/websocket.d.ts +1 -1
- package/dist/types/adapter/lambda-edge/handler.d.ts +2 -2
- package/dist/types/client/types.d.ts +7 -8
- package/dist/types/compose.d.ts +11 -1
- package/dist/types/context.d.ts +31 -21
- package/dist/types/helper/accepts/accepts.d.ts +0 -1
- package/dist/types/helper/adapter/index.d.ts +2 -2
- package/dist/types/helper/conninfo/types.d.ts +2 -2
- package/dist/types/helper/css/common.d.ts +6 -1
- package/dist/types/helper/factory/index.d.ts +289 -12
- package/dist/types/helper/proxy/index.d.ts +54 -0
- package/dist/types/helper/ssg/ssg.d.ts +1 -1
- package/dist/types/helper/websocket/index.d.ts +1 -2
- package/dist/types/hono-base.d.ts +18 -15
- package/dist/types/hono.d.ts +1 -1
- package/dist/types/jsx/base.d.ts +4 -1
- package/dist/types/jsx/dom/hooks/index.d.ts +9 -3
- package/dist/types/jsx/dom/index.d.ts +28 -7
- package/dist/types/jsx/dom/intrinsic-element/components.d.ts +6 -6
- package/dist/types/jsx/dom/render.d.ts +28 -4
- package/dist/types/jsx/dom/server.d.ts +28 -7
- package/dist/types/jsx/hooks/index.d.ts +20 -5
- package/dist/types/jsx/index.d.ts +28 -7
- package/dist/types/jsx/intrinsic-element/components.d.ts +4 -4
- package/dist/types/jsx/intrinsic-elements.d.ts +46 -46
- package/dist/types/middleware/compress/index.d.ts +4 -1
- package/dist/types/middleware/etag/digest.d.ts +1 -1
- package/dist/types/middleware/etag/index.d.ts +4 -0
- package/dist/types/middleware/jwk/index.d.ts +1 -0
- package/dist/types/middleware/jwk/jwk.d.ts +40 -0
- package/dist/types/middleware/language/index.d.ts +7 -0
- package/dist/types/middleware/language/language.d.ts +102 -0
- package/dist/types/middleware/secure-headers/permissions-policy.d.ts +3 -3
- package/dist/types/middleware/secure-headers/secure-headers.d.ts +1 -1
- package/dist/types/preset/quick.d.ts +1 -1
- package/dist/types/preset/tiny.d.ts +1 -1
- package/dist/types/request.d.ts +5 -3
- package/dist/types/router/linear-router/router.d.ts +0 -1
- package/dist/types/router/pattern-router/router.d.ts +0 -1
- package/dist/types/router/reg-exp-router/node.d.ts +4 -2
- package/dist/types/router/reg-exp-router/router.d.ts +0 -1
- package/dist/types/router/reg-exp-router/trie.d.ts +5 -2
- package/dist/types/router/smart-router/router.d.ts +0 -1
- package/dist/types/router/trie-router/node.d.ts +6 -2
- package/dist/types/router/trie-router/router.d.ts +0 -1
- package/dist/types/router.d.ts +20 -2
- package/dist/types/types.d.ts +2002 -111
- package/dist/types/utils/accept.d.ts +11 -0
- package/dist/types/utils/cookie.d.ts +4 -4
- package/dist/types/utils/headers.d.ts +3 -3
- package/dist/types/utils/html.d.ts +6 -2
- package/dist/types/utils/jwt/index.d.ts +4 -0
- package/dist/types/utils/jwt/jws.d.ts +4 -1
- package/dist/types/utils/jwt/jwt.d.ts +8 -2
- package/dist/types/utils/jwt/types.d.ts +4 -0
- package/dist/types/utils/mime.d.ts +2 -2
- package/dist/types/utils/stream.d.ts +0 -4
- package/dist/types/utils/url.d.ts +16 -2
- package/dist/types/validator/validator.d.ts +18 -6
- package/dist/utils/accept.js +63 -0
- package/dist/utils/jwt/index.js +2 -2
- package/dist/utils/jwt/jwt.js +54 -2
- package/dist/utils/jwt/types.js +7 -0
- package/dist/utils/url.js +10 -25
- package/package.json +24 -3
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// src/middleware/jwk/jwk.ts
|
|
2
|
+
import { getCookie, getSignedCookie } from "../../helper/cookie/index.js";
|
|
3
|
+
import { HTTPException } from "../../http-exception.js";
|
|
4
|
+
import { Jwt } from "../../utils/jwt/index.js";
|
|
5
|
+
import "../../context.js";
|
|
6
|
+
var jwk = (options, init) => {
|
|
7
|
+
if (!options || !(options.keys || options.jwks_uri)) {
|
|
8
|
+
throw new Error('JWK auth middleware requires options for either "keys" or "jwks_uri" or both');
|
|
9
|
+
}
|
|
10
|
+
if (!crypto.subtle || !crypto.subtle.importKey) {
|
|
11
|
+
throw new Error("`crypto.subtle.importKey` is undefined. JWK auth middleware requires it.");
|
|
12
|
+
}
|
|
13
|
+
return async function jwk2(ctx, next) {
|
|
14
|
+
const credentials = ctx.req.raw.headers.get("Authorization");
|
|
15
|
+
let token;
|
|
16
|
+
if (credentials) {
|
|
17
|
+
const parts = credentials.split(/\s+/);
|
|
18
|
+
if (parts.length !== 2) {
|
|
19
|
+
const errDescription = "invalid credentials structure";
|
|
20
|
+
throw new HTTPException(401, {
|
|
21
|
+
message: errDescription,
|
|
22
|
+
res: unauthorizedResponse({
|
|
23
|
+
ctx,
|
|
24
|
+
error: "invalid_request",
|
|
25
|
+
errDescription
|
|
26
|
+
})
|
|
27
|
+
});
|
|
28
|
+
} else {
|
|
29
|
+
token = parts[1];
|
|
30
|
+
}
|
|
31
|
+
} else if (options.cookie) {
|
|
32
|
+
if (typeof options.cookie == "string") {
|
|
33
|
+
token = getCookie(ctx, options.cookie);
|
|
34
|
+
} else if (options.cookie.secret) {
|
|
35
|
+
if (options.cookie.prefixOptions) {
|
|
36
|
+
token = await getSignedCookie(
|
|
37
|
+
ctx,
|
|
38
|
+
options.cookie.secret,
|
|
39
|
+
options.cookie.key,
|
|
40
|
+
options.cookie.prefixOptions
|
|
41
|
+
);
|
|
42
|
+
} else {
|
|
43
|
+
token = await getSignedCookie(ctx, options.cookie.secret, options.cookie.key);
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
if (options.cookie.prefixOptions) {
|
|
47
|
+
token = getCookie(ctx, options.cookie.key, options.cookie.prefixOptions);
|
|
48
|
+
} else {
|
|
49
|
+
token = getCookie(ctx, options.cookie.key);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (!token) {
|
|
54
|
+
const errDescription = "no authorization included in request";
|
|
55
|
+
throw new HTTPException(401, {
|
|
56
|
+
message: errDescription,
|
|
57
|
+
res: unauthorizedResponse({
|
|
58
|
+
ctx,
|
|
59
|
+
error: "invalid_request",
|
|
60
|
+
errDescription
|
|
61
|
+
})
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
let payload;
|
|
65
|
+
let cause;
|
|
66
|
+
try {
|
|
67
|
+
payload = await Jwt.verifyFromJwks(token, options, init);
|
|
68
|
+
} catch (e) {
|
|
69
|
+
cause = e;
|
|
70
|
+
}
|
|
71
|
+
if (!payload) {
|
|
72
|
+
if (cause instanceof Error && cause.constructor === Error) {
|
|
73
|
+
throw cause;
|
|
74
|
+
}
|
|
75
|
+
throw new HTTPException(401, {
|
|
76
|
+
message: "Unauthorized",
|
|
77
|
+
res: unauthorizedResponse({
|
|
78
|
+
ctx,
|
|
79
|
+
error: "invalid_token",
|
|
80
|
+
statusText: "Unauthorized",
|
|
81
|
+
errDescription: "token verification failure"
|
|
82
|
+
}),
|
|
83
|
+
cause
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
ctx.set("jwtPayload", payload);
|
|
87
|
+
await next();
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
function unauthorizedResponse(opts) {
|
|
91
|
+
return new Response("Unauthorized", {
|
|
92
|
+
status: 401,
|
|
93
|
+
statusText: opts.statusText,
|
|
94
|
+
headers: {
|
|
95
|
+
"WWW-Authenticate": `Bearer realm="${opts.ctx.req.url}",error="${opts.error}",error_description="${opts.errDescription}"`
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
export {
|
|
100
|
+
jwk
|
|
101
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// src/middleware/language/index.ts
|
|
2
|
+
import {
|
|
3
|
+
languageDetector,
|
|
4
|
+
detectFromCookie,
|
|
5
|
+
detectFromHeader,
|
|
6
|
+
detectFromPath,
|
|
7
|
+
detectFromQuery
|
|
8
|
+
} from "./language.js";
|
|
9
|
+
export {
|
|
10
|
+
detectFromCookie,
|
|
11
|
+
detectFromHeader,
|
|
12
|
+
detectFromPath,
|
|
13
|
+
detectFromQuery,
|
|
14
|
+
languageDetector
|
|
15
|
+
};
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// src/middleware/language/language.ts
|
|
2
|
+
import { setCookie, getCookie } from "../../helper/cookie/index.js";
|
|
3
|
+
import { parseAccept } from "../../utils/accept.js";
|
|
4
|
+
var DEFAULT_OPTIONS = {
|
|
5
|
+
order: ["querystring", "cookie", "header"],
|
|
6
|
+
lookupQueryString: "lang",
|
|
7
|
+
lookupCookie: "language",
|
|
8
|
+
lookupFromHeaderKey: "accept-language",
|
|
9
|
+
lookupFromPathIndex: 0,
|
|
10
|
+
caches: ["cookie"],
|
|
11
|
+
ignoreCase: true,
|
|
12
|
+
fallbackLanguage: "en",
|
|
13
|
+
supportedLanguages: ["en"],
|
|
14
|
+
cookieOptions: {
|
|
15
|
+
sameSite: "Strict",
|
|
16
|
+
secure: true,
|
|
17
|
+
maxAge: 365 * 24 * 60 * 60,
|
|
18
|
+
httpOnly: true
|
|
19
|
+
},
|
|
20
|
+
debug: false
|
|
21
|
+
};
|
|
22
|
+
function parseAcceptLanguage(header) {
|
|
23
|
+
return parseAccept(header).map(({ type, q }) => ({ lang: type, q }));
|
|
24
|
+
}
|
|
25
|
+
var normalizeLanguage = (lang, options) => {
|
|
26
|
+
if (!lang) {
|
|
27
|
+
return void 0;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
let normalizedLang = lang.trim();
|
|
31
|
+
if (options.convertDetectedLanguage) {
|
|
32
|
+
normalizedLang = options.convertDetectedLanguage(normalizedLang);
|
|
33
|
+
}
|
|
34
|
+
const compLang = options.ignoreCase ? normalizedLang.toLowerCase() : normalizedLang;
|
|
35
|
+
const compSupported = options.supportedLanguages.map(
|
|
36
|
+
(l) => options.ignoreCase ? l.toLowerCase() : l
|
|
37
|
+
);
|
|
38
|
+
const matchedLang = compSupported.find((l) => l === compLang);
|
|
39
|
+
return matchedLang ? options.supportedLanguages[compSupported.indexOf(matchedLang)] : void 0;
|
|
40
|
+
} catch {
|
|
41
|
+
return void 0;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
var detectFromQuery = (c, options) => {
|
|
45
|
+
try {
|
|
46
|
+
const query = c.req.query(options.lookupQueryString);
|
|
47
|
+
return normalizeLanguage(query, options);
|
|
48
|
+
} catch {
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var detectFromCookie = (c, options) => {
|
|
53
|
+
try {
|
|
54
|
+
const cookie = getCookie(c, options.lookupCookie);
|
|
55
|
+
return normalizeLanguage(cookie, options);
|
|
56
|
+
} catch {
|
|
57
|
+
return void 0;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
function detectFromHeader(c, options) {
|
|
61
|
+
try {
|
|
62
|
+
const acceptLanguage = c.req.header(options.lookupFromHeaderKey);
|
|
63
|
+
if (!acceptLanguage) {
|
|
64
|
+
return void 0;
|
|
65
|
+
}
|
|
66
|
+
const languages = parseAcceptLanguage(acceptLanguage);
|
|
67
|
+
for (const { lang } of languages) {
|
|
68
|
+
const normalizedLang = normalizeLanguage(lang, options);
|
|
69
|
+
if (normalizedLang) {
|
|
70
|
+
return normalizedLang;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return void 0;
|
|
74
|
+
} catch {
|
|
75
|
+
return void 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function detectFromPath(c, options) {
|
|
79
|
+
try {
|
|
80
|
+
const pathSegments = c.req.path.split("/").filter(Boolean);
|
|
81
|
+
const langSegment = pathSegments[options.lookupFromPathIndex];
|
|
82
|
+
return normalizeLanguage(langSegment, options);
|
|
83
|
+
} catch {
|
|
84
|
+
return void 0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
var detectors = {
|
|
88
|
+
querystring: detectFromQuery,
|
|
89
|
+
cookie: detectFromCookie,
|
|
90
|
+
header: detectFromHeader,
|
|
91
|
+
path: detectFromPath
|
|
92
|
+
};
|
|
93
|
+
function validateOptions(options) {
|
|
94
|
+
if (!options.supportedLanguages.includes(options.fallbackLanguage)) {
|
|
95
|
+
throw new Error("Fallback language must be included in supported languages");
|
|
96
|
+
}
|
|
97
|
+
if (options.lookupFromPathIndex < 0) {
|
|
98
|
+
throw new Error("Path index must be non-negative");
|
|
99
|
+
}
|
|
100
|
+
if (!options.order.every((detector) => Object.keys(detectors).includes(detector))) {
|
|
101
|
+
throw new Error("Invalid detector type in order array");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function cacheLanguage(c, language, options) {
|
|
105
|
+
if (!Array.isArray(options.caches) || !options.caches.includes("cookie")) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
setCookie(c, options.lookupCookie, language, options.cookieOptions);
|
|
110
|
+
} catch (error) {
|
|
111
|
+
if (options.debug) {
|
|
112
|
+
console.error("Failed to cache language:", error);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
var detectLanguage = (c, options) => {
|
|
117
|
+
let detectedLang;
|
|
118
|
+
for (const detectorName of options.order) {
|
|
119
|
+
const detector = detectors[detectorName];
|
|
120
|
+
if (!detector) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
detectedLang = detector(c, options);
|
|
125
|
+
if (detectedLang) {
|
|
126
|
+
if (options.debug) {
|
|
127
|
+
console.log(`Language detected from ${detectorName}: ${detectedLang}`);
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
} catch (error) {
|
|
132
|
+
if (options.debug) {
|
|
133
|
+
console.error(`Error in ${detectorName} detector:`, error);
|
|
134
|
+
}
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const finalLang = detectedLang || options.fallbackLanguage;
|
|
139
|
+
if (detectedLang && options.caches) {
|
|
140
|
+
cacheLanguage(c, finalLang, options);
|
|
141
|
+
}
|
|
142
|
+
return finalLang;
|
|
143
|
+
};
|
|
144
|
+
var languageDetector = (userOptions) => {
|
|
145
|
+
const options = {
|
|
146
|
+
...DEFAULT_OPTIONS,
|
|
147
|
+
...userOptions,
|
|
148
|
+
cookieOptions: {
|
|
149
|
+
...DEFAULT_OPTIONS.cookieOptions,
|
|
150
|
+
...userOptions.cookieOptions
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
validateOptions(options);
|
|
154
|
+
return async function languageDetector2(ctx, next) {
|
|
155
|
+
try {
|
|
156
|
+
const lang = detectLanguage(ctx, options);
|
|
157
|
+
ctx.set("language", lang);
|
|
158
|
+
} catch (error) {
|
|
159
|
+
if (options.debug) {
|
|
160
|
+
console.error("Language detection failed:", error);
|
|
161
|
+
}
|
|
162
|
+
ctx.set("language", options.fallbackLanguage);
|
|
163
|
+
}
|
|
164
|
+
await next();
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
export {
|
|
168
|
+
DEFAULT_OPTIONS,
|
|
169
|
+
detectFromCookie,
|
|
170
|
+
detectFromHeader,
|
|
171
|
+
detectFromPath,
|
|
172
|
+
detectFromQuery,
|
|
173
|
+
detectors,
|
|
174
|
+
languageDetector,
|
|
175
|
+
normalizeLanguage,
|
|
176
|
+
parseAcceptLanguage,
|
|
177
|
+
validateOptions
|
|
178
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
// src/middleware/logger/index.ts
|
|
2
2
|
import { getColorEnabled } from "../../utils/color.js";
|
|
3
|
-
import { getPath } from "../../utils/url.js";
|
|
4
3
|
var humanize = (times) => {
|
|
5
4
|
const [delimiter, separator] = [",", "."];
|
|
6
5
|
const orderTimes = times.map((v) => v.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1" + delimiter));
|
|
@@ -32,8 +31,8 @@ function log(fn, prefix, method, path, status = 0, elapsed) {
|
|
|
32
31
|
}
|
|
33
32
|
var logger = (fn = console.log) => {
|
|
34
33
|
return async function logger2(c, next) {
|
|
35
|
-
const { method } = c.req;
|
|
36
|
-
const path =
|
|
34
|
+
const { method, url } = c.req;
|
|
35
|
+
const path = url.slice(url.indexOf("/", 8));
|
|
37
36
|
log(fn, "<--" /* Incoming */, method, path);
|
|
38
37
|
const start = Date.now();
|
|
39
38
|
await next();
|
package/dist/request.js
CHANGED
|
@@ -66,7 +66,9 @@ var LinearRouter = class {
|
|
|
66
66
|
let value;
|
|
67
67
|
if (name.charCodeAt(name.length - 1) === 125) {
|
|
68
68
|
const openBracePos = name.indexOf("{");
|
|
69
|
-
const
|
|
69
|
+
const next = parts[j + 1];
|
|
70
|
+
const lookahead = next && next[1] !== ":" && next[1] !== "*" ? `(?=${next})` : "";
|
|
71
|
+
const pattern = name.slice(openBracePos + 1, -1) + lookahead;
|
|
70
72
|
const restPath = path.slice(pos + 1);
|
|
71
73
|
const match = new RegExp(pattern, "d").exec(restPath);
|
|
72
74
|
if (!match || match.indices[0][0] !== 0 || match.indices[0][1] === 0) {
|
|
@@ -25,21 +25,23 @@ var Node = class {
|
|
|
25
25
|
const possibleKeys = [];
|
|
26
26
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
27
27
|
const p = parts[i];
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
const nextP = parts[i + 1];
|
|
29
|
+
const pattern = getPattern(p, nextP);
|
|
30
|
+
const key = Array.isArray(pattern) ? pattern[0] : p;
|
|
31
|
+
if (Object.keys(curNode.#children).includes(key)) {
|
|
32
|
+
curNode = curNode.#children[key];
|
|
33
|
+
const pattern2 = getPattern(p, nextP);
|
|
31
34
|
if (pattern2) {
|
|
32
35
|
possibleKeys.push(pattern2[1]);
|
|
33
36
|
}
|
|
34
37
|
continue;
|
|
35
38
|
}
|
|
36
|
-
curNode.#children[
|
|
37
|
-
const pattern = getPattern(p);
|
|
39
|
+
curNode.#children[key] = new Node();
|
|
38
40
|
if (pattern) {
|
|
39
41
|
curNode.#patterns.push(pattern);
|
|
40
42
|
possibleKeys.push(pattern[1]);
|
|
41
43
|
}
|
|
42
|
-
curNode = curNode.#children[
|
|
44
|
+
curNode = curNode.#children[key];
|
|
43
45
|
}
|
|
44
46
|
const m = /* @__PURE__ */ Object.create(null);
|
|
45
47
|
const handlerSet = {
|
|
@@ -78,6 +80,7 @@ var Node = class {
|
|
|
78
80
|
const curNode = this;
|
|
79
81
|
let curNodes = [curNode];
|
|
80
82
|
const parts = splitPath(path);
|
|
83
|
+
const curNodesQueue = [];
|
|
81
84
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
82
85
|
const part = parts[i];
|
|
83
86
|
const isLast = i === len - 1;
|
|
@@ -105,6 +108,7 @@ var Node = class {
|
|
|
105
108
|
const astNode = node.#children["*"];
|
|
106
109
|
if (astNode) {
|
|
107
110
|
handlerSets.push(...this.#getHandlerSets(astNode, method, node.#params));
|
|
111
|
+
astNode.#params = params;
|
|
108
112
|
tempNodes.push(astNode);
|
|
109
113
|
}
|
|
110
114
|
continue;
|
|
@@ -115,10 +119,19 @@ var Node = class {
|
|
|
115
119
|
const [key, name, matcher] = pattern;
|
|
116
120
|
const child = node.#children[key];
|
|
117
121
|
const restPathString = parts.slice(i).join("/");
|
|
118
|
-
if (matcher instanceof RegExp
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
+
if (matcher instanceof RegExp) {
|
|
123
|
+
const m = matcher.exec(restPathString);
|
|
124
|
+
if (m) {
|
|
125
|
+
params[name] = m[0];
|
|
126
|
+
handlerSets.push(...this.#getHandlerSets(child, method, node.#params, params));
|
|
127
|
+
if (Object.keys(child.#children).length) {
|
|
128
|
+
child.#params = params;
|
|
129
|
+
const componentCount = m[0].match(/\//)?.length ?? 0;
|
|
130
|
+
const targetCurNodes = curNodesQueue[componentCount] ||= [];
|
|
131
|
+
targetCurNodes.push(child);
|
|
132
|
+
}
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
122
135
|
}
|
|
123
136
|
if (matcher === true || matcher.test(part)) {
|
|
124
137
|
params[name] = part;
|
|
@@ -136,7 +149,7 @@ var Node = class {
|
|
|
136
149
|
}
|
|
137
150
|
}
|
|
138
151
|
}
|
|
139
|
-
curNodes = tempNodes;
|
|
152
|
+
curNodes = tempNodes.concat(curNodesQueue.shift() ?? []);
|
|
140
153
|
}
|
|
141
154
|
if (handlerSets.length > 1) {
|
|
142
155
|
handlerSets.sort((a, b) => {
|
|
@@ -21,7 +21,7 @@ export declare function handleMiddleware<E extends Env = {}, P extends string =
|
|
|
21
21
|
Bindings: {
|
|
22
22
|
eventContext: EventContext;
|
|
23
23
|
};
|
|
24
|
-
}, P, I>): PagesFunction<E[
|
|
24
|
+
}, P, I>): PagesFunction<E["Bindings"]>;
|
|
25
25
|
/**
|
|
26
26
|
*
|
|
27
27
|
* @description `serveStatic()` is for advanced mode:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { UpgradeWebSocket, WSEvents } from '../../helper/websocket';
|
|
2
|
-
export declare const upgradeWebSocket: UpgradeWebSocket<WebSocket, any, Omit<WSEvents<WebSocket>,
|
|
2
|
+
export declare const upgradeWebSocket: UpgradeWebSocket<WebSocket, any, Omit<WSEvents<WebSocket>, "onOpen">>;
|
|
@@ -17,7 +17,7 @@ interface CloudFrontCustomOrigin {
|
|
|
17
17
|
sslProtocols: string[];
|
|
18
18
|
}
|
|
19
19
|
interface CloudFrontS3Origin {
|
|
20
|
-
authMethod:
|
|
20
|
+
authMethod: "origin-access-identity" | "none";
|
|
21
21
|
customHeaders: CloudFrontHeaders;
|
|
22
22
|
domainName: string;
|
|
23
23
|
path: string;
|
|
@@ -79,7 +79,7 @@ interface CloudFrontResult {
|
|
|
79
79
|
}[];
|
|
80
80
|
};
|
|
81
81
|
body?: string;
|
|
82
|
-
bodyEncoding?:
|
|
82
|
+
bodyEncoding?: "text" | "base64";
|
|
83
83
|
}
|
|
84
84
|
export declare const handle: (app: Hono<any>) => ((event: CloudFrontEdgeEvent, context?: CloudFrontContext, callback?: Callback) => Promise<CloudFrontResult>);
|
|
85
85
|
export declare const createBody: (method: string, requestBody: CloudFrontRequest["body"]) => string | Uint8Array | undefined;
|
|
@@ -3,7 +3,7 @@ import type { HonoBase } from '../hono-base';
|
|
|
3
3
|
import type { Endpoint, ResponseFormat, Schema } from '../types';
|
|
4
4
|
import type { StatusCode, SuccessStatusCode } from '../utils/http-status';
|
|
5
5
|
import type { HasRequiredKeys } from '../utils/types';
|
|
6
|
-
type HonoRequest = (typeof Hono.prototype)[
|
|
6
|
+
type HonoRequest = (typeof Hono.prototype)["request"];
|
|
7
7
|
export type ClientRequestOptions<T = unknown> = {
|
|
8
8
|
fetch?: typeof fetch | HonoRequest;
|
|
9
9
|
webSocket?: (...args: ConstructorParameters<typeof WebSocket>) => WebSocket;
|
|
@@ -40,14 +40,13 @@ export type ClientRequest<S extends Schema> = {
|
|
|
40
40
|
} ? {
|
|
41
41
|
query: Q;
|
|
42
42
|
} : {} : {}) => URL;
|
|
43
|
-
} & (S[
|
|
44
|
-
outputFormat:
|
|
45
|
-
} ? S[
|
|
43
|
+
} & (S["$get"] extends {
|
|
44
|
+
outputFormat: "ws";
|
|
45
|
+
} ? S["$get"] extends {
|
|
46
46
|
input: infer I;
|
|
47
47
|
} ? {
|
|
48
48
|
$ws: (args?: I) => WebSocket;
|
|
49
49
|
} : {} : {});
|
|
50
|
-
type BlankRecordToNever<T> = T extends any ? T extends null ? null : keyof T extends never ? never : T : never;
|
|
51
50
|
type ClientResponseOfEndpoint<T extends Endpoint = Endpoint> = T extends {
|
|
52
51
|
output: infer O;
|
|
53
52
|
outputFormat: infer F;
|
|
@@ -63,8 +62,8 @@ export interface ClientResponse<T, U extends number = StatusCode, F extends Resp
|
|
|
63
62
|
url: string;
|
|
64
63
|
redirect(url: string, status: number): Response;
|
|
65
64
|
clone(): Response;
|
|
66
|
-
json(): F extends
|
|
67
|
-
text(): F extends
|
|
65
|
+
json(): F extends "text" ? Promise<never> : F extends "json" ? Promise<T> : Promise<unknown>;
|
|
66
|
+
text(): F extends "text" ? (T extends string ? Promise<T> : Promise<never>) : Promise<string>;
|
|
68
67
|
blob(): Promise<Blob>;
|
|
69
68
|
formData(): Promise<FormData>;
|
|
70
69
|
arrayBuffer(): Promise<ArrayBuffer>;
|
|
@@ -93,7 +92,7 @@ export type InferRequestOptionsType<T> = T extends (args: any, options: infer R)
|
|
|
93
92
|
type PathToChain<Path extends string, E extends Schema, Original extends string = Path> = Path extends `/${infer P}` ? PathToChain<P, E, Path> : Path extends `${infer P}/${infer R}` ? {
|
|
94
93
|
[K in P]: PathToChain<R, E, Original>;
|
|
95
94
|
} : {
|
|
96
|
-
[K in Path extends
|
|
95
|
+
[K in Path extends "" ? "index" : Path]: ClientRequest<E extends Record<string, unknown> ? E[Original] : never>;
|
|
97
96
|
};
|
|
98
97
|
export type Client<T> = T extends HonoBase<any, infer S, any> ? S extends Record<infer K, Schema> ? K extends string ? PathToChain<K, S> : never : never : never;
|
|
99
98
|
export type Callback = (opts: CallbackOptions) => unknown;
|
package/dist/types/compose.d.ts
CHANGED
|
@@ -25,5 +25,15 @@ interface ComposeContext {
|
|
|
25
25
|
*
|
|
26
26
|
* @returns {(context: C, next?: Function) => Promise<C>} - A composed middleware function.
|
|
27
27
|
*/
|
|
28
|
-
export declare const compose: <C extends ComposeContext, E extends Env = Env>(middleware: [
|
|
28
|
+
export declare const compose: <C extends ComposeContext, E extends Env = Env>(middleware: [
|
|
29
|
+
[
|
|
30
|
+
Function,
|
|
31
|
+
unknown
|
|
32
|
+
],
|
|
33
|
+
unknown
|
|
34
|
+
][] | [
|
|
35
|
+
[
|
|
36
|
+
Function
|
|
37
|
+
]
|
|
38
|
+
][], onError?: ErrorHandler<E>, onNotFound?: NotFoundHandler<E>) => ((context: C, next?: Function) => Promise<C>);
|
|
29
39
|
export {};
|
package/dist/types/context.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ import type { ResponseHeader } from './utils/headers';
|
|
|
5
5
|
import type { ContentfulStatusCode, RedirectStatusCode, StatusCode } from './utils/http-status';
|
|
6
6
|
import type { BaseMime } from './utils/mime';
|
|
7
7
|
import type { InvalidJSONValue, IsAny, JSONParsed, JSONValue, SimplifyDeepArray } from './utils/types';
|
|
8
|
-
type HeaderRecord = Record<
|
|
8
|
+
type HeaderRecord = Record<"Content-Type", BaseMime> | Record<ResponseHeader, string | string[]> | Record<string, string | string[]>;
|
|
9
9
|
/**
|
|
10
|
-
* Data type can be a string, ArrayBuffer, or ReadableStream.
|
|
10
|
+
* Data type can be a string, ArrayBuffer, Uint8Array (buffer), or ReadableStream.
|
|
11
11
|
*/
|
|
12
|
-
export type Data = string | ArrayBuffer | ReadableStream;
|
|
12
|
+
export type Data = string | ArrayBuffer | ReadableStream | Uint8Array;
|
|
13
13
|
/**
|
|
14
14
|
* Interface for the execution context in a web worker or similar environment.
|
|
15
15
|
*/
|
|
@@ -52,7 +52,12 @@ export type Renderer = ContextRenderer extends Function ? ContextRenderer : Defa
|
|
|
52
52
|
/**
|
|
53
53
|
* Extracts the props for the renderer.
|
|
54
54
|
*/
|
|
55
|
-
export type PropsForRenderer = [
|
|
55
|
+
export type PropsForRenderer = [
|
|
56
|
+
...Required<Parameters<Renderer>>
|
|
57
|
+
] extends [
|
|
58
|
+
unknown,
|
|
59
|
+
infer Props
|
|
60
|
+
] ? Props : unknown;
|
|
56
61
|
export type Layout<T = Record<string, any>> = (props: T) => any;
|
|
57
62
|
/**
|
|
58
63
|
* Interface for getting context variables.
|
|
@@ -60,7 +65,7 @@ export type Layout<T = Record<string, any>> = (props: T) => any;
|
|
|
60
65
|
* @template E - Environment type.
|
|
61
66
|
*/
|
|
62
67
|
interface Get<E extends Env> {
|
|
63
|
-
<Key extends keyof E[
|
|
68
|
+
<Key extends keyof E["Variables"]>(key: Key): E["Variables"][Key];
|
|
64
69
|
<Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
|
|
65
70
|
}
|
|
66
71
|
/**
|
|
@@ -69,7 +74,7 @@ interface Get<E extends Env> {
|
|
|
69
74
|
* @template E - Environment type.
|
|
70
75
|
*/
|
|
71
76
|
interface Set<E extends Env> {
|
|
72
|
-
<Key extends keyof E[
|
|
77
|
+
<Key extends keyof E["Variables"]>(key: Key, value: E["Variables"][Key]): void;
|
|
73
78
|
<Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void;
|
|
74
79
|
}
|
|
75
80
|
/**
|
|
@@ -83,10 +88,10 @@ interface NewResponse {
|
|
|
83
88
|
* Interface for responding with a body.
|
|
84
89
|
*/
|
|
85
90
|
interface BodyRespond {
|
|
86
|
-
<U extends ContentfulStatusCode>(data: Data, status?: U, headers?: HeaderRecord): Response & TypedResponse<unknown, U,
|
|
87
|
-
<U extends StatusCode>(data: null, status?: U, headers?: HeaderRecord): Response & TypedResponse<null, U,
|
|
88
|
-
<U extends ContentfulStatusCode>(data: Data, init?: ResponseOrInit<U>): Response & TypedResponse<unknown, U,
|
|
89
|
-
<U extends StatusCode>(data: null, init?: ResponseOrInit<U>): Response & TypedResponse<null, U,
|
|
91
|
+
<U extends ContentfulStatusCode>(data: Data, status?: U, headers?: HeaderRecord): Response & TypedResponse<unknown, U, "body">;
|
|
92
|
+
<U extends StatusCode>(data: null, status?: U, headers?: HeaderRecord): Response & TypedResponse<null, U, "body">;
|
|
93
|
+
<U extends ContentfulStatusCode>(data: Data, init?: ResponseOrInit<U>): Response & TypedResponse<unknown, U, "body">;
|
|
94
|
+
<U extends StatusCode>(data: null, init?: ResponseOrInit<U>): Response & TypedResponse<null, U, "body">;
|
|
90
95
|
}
|
|
91
96
|
/**
|
|
92
97
|
* Interface for responding with text.
|
|
@@ -102,8 +107,8 @@ interface BodyRespond {
|
|
|
102
107
|
* @returns {Response & TypedResponse<T, U, 'text'>} - The response after rendering the text content, typed with the provided text and status code types.
|
|
103
108
|
*/
|
|
104
109
|
interface TextRespond {
|
|
105
|
-
<T extends string, U extends ContentfulStatusCode = ContentfulStatusCode>(text: T, status?: U, headers?: HeaderRecord): Response & TypedResponse<T, U,
|
|
106
|
-
<T extends string, U extends ContentfulStatusCode = ContentfulStatusCode>(text: T, init?: ResponseOrInit<U>): Response & TypedResponse<T, U,
|
|
110
|
+
<T extends string, U extends ContentfulStatusCode = ContentfulStatusCode>(text: T, status?: U, headers?: HeaderRecord): Response & TypedResponse<T, U, "text">;
|
|
111
|
+
<T extends string, U extends ContentfulStatusCode = ContentfulStatusCode>(text: T, init?: ResponseOrInit<U>): Response & TypedResponse<T, U, "text">;
|
|
107
112
|
}
|
|
108
113
|
/**
|
|
109
114
|
* Interface for responding with JSON.
|
|
@@ -128,7 +133,7 @@ interface JSONRespond {
|
|
|
128
133
|
*
|
|
129
134
|
* @returns {Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? (JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T>) : never, U, 'json'>} - The response after rendering the JSON object, typed with the provided object and status code types.
|
|
130
135
|
*/
|
|
131
|
-
type JSONRespondReturn<T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue, U extends ContentfulStatusCode> = Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T> : never, U,
|
|
136
|
+
type JSONRespondReturn<T extends JSONValue | SimplifyDeepArray<unknown> | InvalidJSONValue, U extends ContentfulStatusCode> = Response & TypedResponse<SimplifyDeepArray<T> extends JSONValue ? JSONValue extends SimplifyDeepArray<T> ? never : JSONParsed<T> : never, U, "json">;
|
|
132
137
|
/**
|
|
133
138
|
* Interface representing a function that responds with HTML content.
|
|
134
139
|
*
|
|
@@ -152,7 +157,7 @@ type ContextOptions<E extends Env> = {
|
|
|
152
157
|
/**
|
|
153
158
|
* Bindings for the environment.
|
|
154
159
|
*/
|
|
155
|
-
env: E[
|
|
160
|
+
env: E["Bindings"];
|
|
156
161
|
/**
|
|
157
162
|
* Execution context for the request.
|
|
158
163
|
*/
|
|
@@ -161,18 +166,24 @@ type ContextOptions<E extends Env> = {
|
|
|
161
166
|
* Handler for not found responses.
|
|
162
167
|
*/
|
|
163
168
|
notFoundHandler?: NotFoundHandler<E>;
|
|
164
|
-
matchResult?: Result<[
|
|
169
|
+
matchResult?: Result<[
|
|
170
|
+
H,
|
|
171
|
+
RouterRoute
|
|
172
|
+
]>;
|
|
165
173
|
path?: string;
|
|
166
174
|
};
|
|
167
175
|
interface SetHeadersOptions {
|
|
168
176
|
append?: boolean;
|
|
169
177
|
}
|
|
170
178
|
interface SetHeaders {
|
|
171
|
-
(name:
|
|
179
|
+
(name: "Content-Type", value?: BaseMime, options?: SetHeadersOptions): void;
|
|
172
180
|
(name: ResponseHeader, value?: string, options?: SetHeadersOptions): void;
|
|
173
181
|
(name: string, value?: string, options?: SetHeadersOptions): void;
|
|
174
182
|
}
|
|
175
|
-
type ResponseHeadersInit = [
|
|
183
|
+
type ResponseHeadersInit = [
|
|
184
|
+
string,
|
|
185
|
+
string
|
|
186
|
+
][] | Record<"Content-Type", BaseMime> | Record<ResponseHeader, string> | Record<string, string> | Headers;
|
|
176
187
|
interface ResponseInit<T extends StatusCode = StatusCode> {
|
|
177
188
|
headers?: ResponseHeadersInit;
|
|
178
189
|
status?: T;
|
|
@@ -181,7 +192,6 @@ interface ResponseInit<T extends StatusCode = StatusCode> {
|
|
|
181
192
|
type ResponseOrInit<T extends StatusCode = StatusCode> = ResponseInit<T> | Response;
|
|
182
193
|
export declare const TEXT_PLAIN = "text/plain; charset=UTF-8";
|
|
183
194
|
export declare class Context<E extends Env = any, P extends string = any, I extends Input = {}> {
|
|
184
|
-
#private;
|
|
185
195
|
/**
|
|
186
196
|
* `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.
|
|
187
197
|
*
|
|
@@ -195,7 +205,7 @@ export declare class Context<E extends Env = any, P extends string = any, I exte
|
|
|
195
205
|
* })
|
|
196
206
|
* ```
|
|
197
207
|
*/
|
|
198
|
-
env: E[
|
|
208
|
+
env: E["Bindings"];
|
|
199
209
|
finalized: boolean;
|
|
200
210
|
/**
|
|
201
211
|
* `.error` can get the error object from the middleware if the Handler throws an error.
|
|
@@ -223,7 +233,7 @@ export declare class Context<E extends Env = any, P extends string = any, I exte
|
|
|
223
233
|
/**
|
|
224
234
|
* `.req` is the instance of {@link HonoRequest}.
|
|
225
235
|
*/
|
|
226
|
-
get req(): HonoRequest<P, I[
|
|
236
|
+
get req(): HonoRequest<P, I["out"]>;
|
|
227
237
|
/**
|
|
228
238
|
* @see {@link https://hono.dev/docs/api/context#event}
|
|
229
239
|
* The FetchEvent associated with the current request.
|
|
@@ -363,7 +373,7 @@ export declare class Context<E extends Env = any, P extends string = any, I exte
|
|
|
363
373
|
* const result = c.var.client.oneMethod()
|
|
364
374
|
* ```
|
|
365
375
|
*/
|
|
366
|
-
get var(): Readonly<ContextVariableMap & (IsAny<E[
|
|
376
|
+
get var(): Readonly<ContextVariableMap & (IsAny<E["Variables"]> extends true ? Record<string, any> : E["Variables"])>;
|
|
367
377
|
newResponse: NewResponse;
|
|
368
378
|
/**
|
|
369
379
|
* `.body()` can return the HTTP response.
|
|
@@ -13,7 +13,6 @@ export interface acceptsConfig {
|
|
|
13
13
|
export interface acceptsOptions extends acceptsConfig {
|
|
14
14
|
match?: (accepts: Accept[], config: acceptsConfig) => string;
|
|
15
15
|
}
|
|
16
|
-
export declare const parseAccept: (acceptHeader: string) => Accept[];
|
|
17
16
|
export declare const defaultMatch: (accepts: Accept[], config: acceptsConfig) => string;
|
|
18
17
|
/**
|
|
19
18
|
* Match the accept header with the given options.
|