hono 4.6.19 → 4.7.0
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/lambda-edge/handler.js +6 -2
- package/dist/cjs/adapter/lambda-edge/handler.js +6 -2
- 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/helper/streaming/sse.js +8 -5
- package/dist/cjs/helper/streaming/stream.js +8 -5
- package/dist/cjs/helper/streaming/utils.js +36 -0
- package/dist/cjs/middleware/etag/digest.js +2 -7
- package/dist/cjs/middleware/etag/index.js +7 -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 +6 -5
- 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/helper/streaming/sse.js +8 -5
- package/dist/helper/streaming/stream.js +8 -5
- package/dist/helper/streaming/utils.js +13 -0
- package/dist/middleware/etag/digest.js +2 -7
- package/dist/middleware/etag/index.js +7 -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/client/types.d.ts +1 -2
- package/dist/types/context.d.ts +2 -2
- package/dist/types/helper/accepts/accepts.d.ts +0 -1
- package/dist/types/helper/adapter/index.d.ts +1 -1
- package/dist/types/helper/factory/index.d.ts +4 -1
- package/dist/types/helper/proxy/index.d.ts +54 -0
- package/dist/types/helper/streaming/utils.d.ts +1 -0
- 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/utils/accept.d.ts +11 -0
- 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 +7 -1
- package/dist/types/utils/jwt/types.d.ts +4 -0
- package/dist/types/utils/url.d.ts +1 -1
- 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 +6 -5
- package/package.json +26 -5
- package/perf-measures/bundle-check/generated/.gitkeep +0 -0
- package/perf-measures/type-check/generated/.gitkeep +0 -0
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var language_exports = {};
|
|
20
|
+
__export(language_exports, {
|
|
21
|
+
DEFAULT_OPTIONS: () => DEFAULT_OPTIONS,
|
|
22
|
+
detectFromCookie: () => detectFromCookie,
|
|
23
|
+
detectFromHeader: () => detectFromHeader,
|
|
24
|
+
detectFromPath: () => detectFromPath,
|
|
25
|
+
detectFromQuery: () => detectFromQuery,
|
|
26
|
+
detectors: () => detectors,
|
|
27
|
+
languageDetector: () => languageDetector,
|
|
28
|
+
normalizeLanguage: () => normalizeLanguage,
|
|
29
|
+
parseAcceptLanguage: () => parseAcceptLanguage,
|
|
30
|
+
validateOptions: () => validateOptions
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(language_exports);
|
|
33
|
+
var import_cookie = require("../../helper/cookie");
|
|
34
|
+
var import_accept = require("../../utils/accept");
|
|
35
|
+
const DEFAULT_OPTIONS = {
|
|
36
|
+
order: ["querystring", "cookie", "header"],
|
|
37
|
+
lookupQueryString: "lang",
|
|
38
|
+
lookupCookie: "language",
|
|
39
|
+
lookupFromHeaderKey: "accept-language",
|
|
40
|
+
lookupFromPathIndex: 0,
|
|
41
|
+
caches: ["cookie"],
|
|
42
|
+
ignoreCase: true,
|
|
43
|
+
fallbackLanguage: "en",
|
|
44
|
+
supportedLanguages: ["en"],
|
|
45
|
+
cookieOptions: {
|
|
46
|
+
sameSite: "Strict",
|
|
47
|
+
secure: true,
|
|
48
|
+
maxAge: 365 * 24 * 60 * 60,
|
|
49
|
+
httpOnly: true
|
|
50
|
+
},
|
|
51
|
+
debug: false
|
|
52
|
+
};
|
|
53
|
+
function parseAcceptLanguage(header) {
|
|
54
|
+
return (0, import_accept.parseAccept)(header).map(({ type, q }) => ({ lang: type, q }));
|
|
55
|
+
}
|
|
56
|
+
const normalizeLanguage = (lang, options) => {
|
|
57
|
+
if (!lang) {
|
|
58
|
+
return void 0;
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
let normalizedLang = lang.trim();
|
|
62
|
+
if (options.convertDetectedLanguage) {
|
|
63
|
+
normalizedLang = options.convertDetectedLanguage(normalizedLang);
|
|
64
|
+
}
|
|
65
|
+
const compLang = options.ignoreCase ? normalizedLang.toLowerCase() : normalizedLang;
|
|
66
|
+
const compSupported = options.supportedLanguages.map(
|
|
67
|
+
(l) => options.ignoreCase ? l.toLowerCase() : l
|
|
68
|
+
);
|
|
69
|
+
const matchedLang = compSupported.find((l) => l === compLang);
|
|
70
|
+
return matchedLang ? options.supportedLanguages[compSupported.indexOf(matchedLang)] : void 0;
|
|
71
|
+
} catch {
|
|
72
|
+
return void 0;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const detectFromQuery = (c, options) => {
|
|
76
|
+
try {
|
|
77
|
+
const query = c.req.query(options.lookupQueryString);
|
|
78
|
+
return normalizeLanguage(query, options);
|
|
79
|
+
} catch {
|
|
80
|
+
return void 0;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const detectFromCookie = (c, options) => {
|
|
84
|
+
try {
|
|
85
|
+
const cookie = (0, import_cookie.getCookie)(c, options.lookupCookie);
|
|
86
|
+
return normalizeLanguage(cookie, options);
|
|
87
|
+
} catch {
|
|
88
|
+
return void 0;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
function detectFromHeader(c, options) {
|
|
92
|
+
try {
|
|
93
|
+
const acceptLanguage = c.req.header(options.lookupFromHeaderKey);
|
|
94
|
+
if (!acceptLanguage) {
|
|
95
|
+
return void 0;
|
|
96
|
+
}
|
|
97
|
+
const languages = parseAcceptLanguage(acceptLanguage);
|
|
98
|
+
for (const { lang } of languages) {
|
|
99
|
+
const normalizedLang = normalizeLanguage(lang, options);
|
|
100
|
+
if (normalizedLang) {
|
|
101
|
+
return normalizedLang;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return void 0;
|
|
105
|
+
} catch {
|
|
106
|
+
return void 0;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function detectFromPath(c, options) {
|
|
110
|
+
try {
|
|
111
|
+
const pathSegments = c.req.path.split("/").filter(Boolean);
|
|
112
|
+
const langSegment = pathSegments[options.lookupFromPathIndex];
|
|
113
|
+
return normalizeLanguage(langSegment, options);
|
|
114
|
+
} catch {
|
|
115
|
+
return void 0;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const detectors = {
|
|
119
|
+
querystring: detectFromQuery,
|
|
120
|
+
cookie: detectFromCookie,
|
|
121
|
+
header: detectFromHeader,
|
|
122
|
+
path: detectFromPath
|
|
123
|
+
};
|
|
124
|
+
function validateOptions(options) {
|
|
125
|
+
if (!options.supportedLanguages.includes(options.fallbackLanguage)) {
|
|
126
|
+
throw new Error("Fallback language must be included in supported languages");
|
|
127
|
+
}
|
|
128
|
+
if (options.lookupFromPathIndex < 0) {
|
|
129
|
+
throw new Error("Path index must be non-negative");
|
|
130
|
+
}
|
|
131
|
+
if (!options.order.every((detector) => Object.keys(detectors).includes(detector))) {
|
|
132
|
+
throw new Error("Invalid detector type in order array");
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
function cacheLanguage(c, language, options) {
|
|
136
|
+
if (!Array.isArray(options.caches) || !options.caches.includes("cookie")) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
try {
|
|
140
|
+
(0, import_cookie.setCookie)(c, options.lookupCookie, language, options.cookieOptions);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
if (options.debug) {
|
|
143
|
+
console.error("Failed to cache language:", error);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const detectLanguage = (c, options) => {
|
|
148
|
+
let detectedLang;
|
|
149
|
+
for (const detectorName of options.order) {
|
|
150
|
+
const detector = detectors[detectorName];
|
|
151
|
+
if (!detector) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
detectedLang = detector(c, options);
|
|
156
|
+
if (detectedLang) {
|
|
157
|
+
if (options.debug) {
|
|
158
|
+
console.log(`Language detected from ${detectorName}: ${detectedLang}`);
|
|
159
|
+
}
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
} catch (error) {
|
|
163
|
+
if (options.debug) {
|
|
164
|
+
console.error(`Error in ${detectorName} detector:`, error);
|
|
165
|
+
}
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const finalLang = detectedLang || options.fallbackLanguage;
|
|
170
|
+
if (detectedLang && options.caches) {
|
|
171
|
+
cacheLanguage(c, finalLang, options);
|
|
172
|
+
}
|
|
173
|
+
return finalLang;
|
|
174
|
+
};
|
|
175
|
+
const languageDetector = (userOptions) => {
|
|
176
|
+
const options = {
|
|
177
|
+
...DEFAULT_OPTIONS,
|
|
178
|
+
...userOptions,
|
|
179
|
+
cookieOptions: {
|
|
180
|
+
...DEFAULT_OPTIONS.cookieOptions,
|
|
181
|
+
...userOptions.cookieOptions
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
validateOptions(options);
|
|
185
|
+
return async function languageDetector2(ctx, next) {
|
|
186
|
+
try {
|
|
187
|
+
const lang = detectLanguage(ctx, options);
|
|
188
|
+
ctx.set("language", lang);
|
|
189
|
+
} catch (error) {
|
|
190
|
+
if (options.debug) {
|
|
191
|
+
console.error("Language detection failed:", error);
|
|
192
|
+
}
|
|
193
|
+
ctx.set("language", options.fallbackLanguage);
|
|
194
|
+
}
|
|
195
|
+
await next();
|
|
196
|
+
};
|
|
197
|
+
};
|
|
198
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
199
|
+
0 && (module.exports = {
|
|
200
|
+
DEFAULT_OPTIONS,
|
|
201
|
+
detectFromCookie,
|
|
202
|
+
detectFromHeader,
|
|
203
|
+
detectFromPath,
|
|
204
|
+
detectFromQuery,
|
|
205
|
+
detectors,
|
|
206
|
+
languageDetector,
|
|
207
|
+
normalizeLanguage,
|
|
208
|
+
parseAcceptLanguage,
|
|
209
|
+
validateOptions
|
|
210
|
+
});
|
|
@@ -22,7 +22,6 @@ __export(logger_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(logger_exports);
|
|
24
24
|
var import_color = require("../../utils/color");
|
|
25
|
-
var import_url = require("../../utils/url");
|
|
26
25
|
var LogPrefix = /* @__PURE__ */ ((LogPrefix2) => {
|
|
27
26
|
LogPrefix2["Outgoing"] = "-->";
|
|
28
27
|
LogPrefix2["Incoming"] = "<--";
|
|
@@ -60,8 +59,8 @@ function log(fn, prefix, method, path, status = 0, elapsed) {
|
|
|
60
59
|
}
|
|
61
60
|
const logger = (fn = console.log) => {
|
|
62
61
|
return async function logger2(c, next) {
|
|
63
|
-
const { method } = c.req;
|
|
64
|
-
const path = (
|
|
62
|
+
const { method, url } = c.req;
|
|
63
|
+
const path = url.slice(url.indexOf("/", 8));
|
|
65
64
|
log(fn, "<--" /* Incoming */, method, path);
|
|
66
65
|
const start = Date.now();
|
|
67
66
|
await next();
|
package/dist/cjs/request.js
CHANGED
|
@@ -88,7 +88,9 @@ class LinearRouter {
|
|
|
88
88
|
let value;
|
|
89
89
|
if (name.charCodeAt(name.length - 1) === 125) {
|
|
90
90
|
const openBracePos = name.indexOf("{");
|
|
91
|
-
const
|
|
91
|
+
const next = parts[j + 1];
|
|
92
|
+
const lookahead = next && next[1] !== ":" && next[1] !== "*" ? `(?=${next})` : "";
|
|
93
|
+
const pattern = name.slice(openBracePos + 1, -1) + lookahead;
|
|
92
94
|
const restPath = path.slice(pos + 1);
|
|
93
95
|
const match = new RegExp(pattern, "d").exec(restPath);
|
|
94
96
|
if (!match || match.indices[0][0] !== 0 || match.indices[0][1] === 0) {
|
|
@@ -47,21 +47,23 @@ class Node {
|
|
|
47
47
|
const possibleKeys = [];
|
|
48
48
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
49
49
|
const p = parts[i];
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const nextP = parts[i + 1];
|
|
51
|
+
const pattern = (0, import_url.getPattern)(p, nextP);
|
|
52
|
+
const key = Array.isArray(pattern) ? pattern[0] : p;
|
|
53
|
+
if (Object.keys(curNode.#children).includes(key)) {
|
|
54
|
+
curNode = curNode.#children[key];
|
|
55
|
+
const pattern2 = (0, import_url.getPattern)(p, nextP);
|
|
53
56
|
if (pattern2) {
|
|
54
57
|
possibleKeys.push(pattern2[1]);
|
|
55
58
|
}
|
|
56
59
|
continue;
|
|
57
60
|
}
|
|
58
|
-
curNode.#children[
|
|
59
|
-
const pattern = (0, import_url.getPattern)(p);
|
|
61
|
+
curNode.#children[key] = new Node();
|
|
60
62
|
if (pattern) {
|
|
61
63
|
curNode.#patterns.push(pattern);
|
|
62
64
|
possibleKeys.push(pattern[1]);
|
|
63
65
|
}
|
|
64
|
-
curNode = curNode.#children[
|
|
66
|
+
curNode = curNode.#children[key];
|
|
65
67
|
}
|
|
66
68
|
const m = /* @__PURE__ */ Object.create(null);
|
|
67
69
|
const handlerSet = {
|
|
@@ -100,6 +102,7 @@ class Node {
|
|
|
100
102
|
const curNode = this;
|
|
101
103
|
let curNodes = [curNode];
|
|
102
104
|
const parts = (0, import_url.splitPath)(path);
|
|
105
|
+
const curNodesQueue = [];
|
|
103
106
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
104
107
|
const part = parts[i];
|
|
105
108
|
const isLast = i === len - 1;
|
|
@@ -127,6 +130,7 @@ class Node {
|
|
|
127
130
|
const astNode = node.#children["*"];
|
|
128
131
|
if (astNode) {
|
|
129
132
|
handlerSets.push(...this.#getHandlerSets(astNode, method, node.#params));
|
|
133
|
+
astNode.#params = params;
|
|
130
134
|
tempNodes.push(astNode);
|
|
131
135
|
}
|
|
132
136
|
continue;
|
|
@@ -137,10 +141,19 @@ class Node {
|
|
|
137
141
|
const [key, name, matcher] = pattern;
|
|
138
142
|
const child = node.#children[key];
|
|
139
143
|
const restPathString = parts.slice(i).join("/");
|
|
140
|
-
if (matcher instanceof RegExp
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
+
if (matcher instanceof RegExp) {
|
|
145
|
+
const m = matcher.exec(restPathString);
|
|
146
|
+
if (m) {
|
|
147
|
+
params[name] = m[0];
|
|
148
|
+
handlerSets.push(...this.#getHandlerSets(child, method, node.#params, params));
|
|
149
|
+
if (Object.keys(child.#children).length) {
|
|
150
|
+
child.#params = params;
|
|
151
|
+
const componentCount = m[0].match(/\//)?.length ?? 0;
|
|
152
|
+
const targetCurNodes = curNodesQueue[componentCount] ||= [];
|
|
153
|
+
targetCurNodes.push(child);
|
|
154
|
+
}
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
144
157
|
}
|
|
145
158
|
if (matcher === true || matcher.test(part)) {
|
|
146
159
|
params[name] = part;
|
|
@@ -158,7 +171,7 @@ class Node {
|
|
|
158
171
|
}
|
|
159
172
|
}
|
|
160
173
|
}
|
|
161
|
-
curNodes = tempNodes;
|
|
174
|
+
curNodes = tempNodes.concat(curNodesQueue.shift() ?? []);
|
|
162
175
|
}
|
|
163
176
|
if (handlerSets.length > 1) {
|
|
164
177
|
handlerSets.sort((a, b) => {
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var accept_exports = {};
|
|
20
|
+
__export(accept_exports, {
|
|
21
|
+
parseAccept: () => parseAccept
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(accept_exports);
|
|
24
|
+
const parseAccept = (acceptHeader) => {
|
|
25
|
+
if (!acceptHeader) {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
const acceptValues = acceptHeader.split(",").map((value, index) => ({ value, index }));
|
|
29
|
+
return acceptValues.map(parseAcceptValue).filter((item) => Boolean(item)).sort(sortByQualityAndIndex).map(({ type, params, q }) => ({ type, params, q }));
|
|
30
|
+
};
|
|
31
|
+
const parseAcceptValueRegex = /;(?=(?:(?:[^"]*"){2})*[^"]*$)/;
|
|
32
|
+
const parseAcceptValue = ({ value, index }) => {
|
|
33
|
+
const parts = value.trim().split(parseAcceptValueRegex).map((s) => s.trim());
|
|
34
|
+
const type = parts[0];
|
|
35
|
+
if (!type) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const params = parseParams(parts.slice(1));
|
|
39
|
+
const q = parseQuality(params.q);
|
|
40
|
+
return { type, params, q, index };
|
|
41
|
+
};
|
|
42
|
+
const parseParams = (paramParts) => {
|
|
43
|
+
return paramParts.reduce((acc, param) => {
|
|
44
|
+
const [key, val] = param.split("=").map((s) => s.trim());
|
|
45
|
+
if (key && val) {
|
|
46
|
+
acc[key] = val;
|
|
47
|
+
}
|
|
48
|
+
return acc;
|
|
49
|
+
}, {});
|
|
50
|
+
};
|
|
51
|
+
const parseQuality = (qVal) => {
|
|
52
|
+
if (qVal === void 0) {
|
|
53
|
+
return 1;
|
|
54
|
+
}
|
|
55
|
+
if (qVal === "") {
|
|
56
|
+
return 1;
|
|
57
|
+
}
|
|
58
|
+
if (qVal === "NaN") {
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
const num = Number(qVal);
|
|
62
|
+
if (num === Infinity) {
|
|
63
|
+
return 1;
|
|
64
|
+
}
|
|
65
|
+
if (num === -Infinity) {
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
if (Number.isNaN(num)) {
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
if (num < 0 || num > 1) {
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
return num;
|
|
75
|
+
};
|
|
76
|
+
const sortByQualityAndIndex = (a, b) => {
|
|
77
|
+
const qDiff = b.q - a.q;
|
|
78
|
+
if (qDiff !== 0) {
|
|
79
|
+
return qDiff;
|
|
80
|
+
}
|
|
81
|
+
return a.index - b.index;
|
|
82
|
+
};
|
|
83
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
84
|
+
0 && (module.exports = {
|
|
85
|
+
parseAccept
|
|
86
|
+
});
|
|
@@ -22,7 +22,7 @@ __export(jwt_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(jwt_exports);
|
|
24
24
|
var import_jwt = require("./jwt");
|
|
25
|
-
const Jwt = { sign: import_jwt.sign, verify: import_jwt.verify, decode: import_jwt.decode };
|
|
25
|
+
const Jwt = { sign: import_jwt.sign, verify: import_jwt.verify, decode: import_jwt.decode, verifyFromJwks: import_jwt.verifyFromJwks };
|
|
26
26
|
// Annotate the CommonJS export names for ESM import in node:
|
|
27
27
|
0 && (module.exports = {
|
|
28
28
|
Jwt
|
|
@@ -19,9 +19,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
19
19
|
var jwt_exports = {};
|
|
20
20
|
__export(jwt_exports, {
|
|
21
21
|
decode: () => decode,
|
|
22
|
+
decodeHeader: () => decodeHeader,
|
|
22
23
|
isTokenHeader: () => isTokenHeader,
|
|
23
24
|
sign: () => sign,
|
|
24
|
-
verify: () => verify
|
|
25
|
+
verify: () => verify,
|
|
26
|
+
verifyFromJwks: () => verifyFromJwks
|
|
25
27
|
});
|
|
26
28
|
module.exports = __toCommonJS(jwt_exports);
|
|
27
29
|
var import_encode = require("../../utils/encode");
|
|
@@ -41,7 +43,13 @@ function isTokenHeader(obj) {
|
|
|
41
43
|
}
|
|
42
44
|
const sign = async (payload, privateKey, alg = "HS256") => {
|
|
43
45
|
const encodedPayload = encodeJwtPart(payload);
|
|
44
|
-
|
|
46
|
+
let encodedHeader;
|
|
47
|
+
if (typeof privateKey === "object" && "alg" in privateKey) {
|
|
48
|
+
alg = privateKey.alg;
|
|
49
|
+
encodedHeader = encodeJwtPart({ alg, typ: "JWT", kid: privateKey.kid });
|
|
50
|
+
} else {
|
|
51
|
+
encodedHeader = encodeJwtPart({ alg, typ: "JWT" });
|
|
52
|
+
}
|
|
45
53
|
const partialToken = `${encodedHeader}.${encodedPayload}`;
|
|
46
54
|
const signaturePart = await (0, import_jws.signing)(privateKey, alg, import_utf8.utf8Encoder.encode(partialToken));
|
|
47
55
|
const signature = encodeSignaturePart(signaturePart);
|
|
@@ -78,6 +86,41 @@ const verify = async (token, publicKey, alg = "HS256") => {
|
|
|
78
86
|
}
|
|
79
87
|
return payload;
|
|
80
88
|
};
|
|
89
|
+
const verifyFromJwks = async (token, options, init) => {
|
|
90
|
+
const header = decodeHeader(token);
|
|
91
|
+
if (!isTokenHeader(header)) {
|
|
92
|
+
throw new import_types.JwtHeaderInvalid(header);
|
|
93
|
+
}
|
|
94
|
+
if (!header.kid) {
|
|
95
|
+
throw new import_types.JwtHeaderRequiresKid(header);
|
|
96
|
+
}
|
|
97
|
+
let keys = typeof options.keys === "function" ? await options.keys() : options.keys;
|
|
98
|
+
if (options.jwks_uri) {
|
|
99
|
+
const response = await fetch(options.jwks_uri, init);
|
|
100
|
+
if (!response.ok) {
|
|
101
|
+
throw new Error(`failed to fetch JWKS from ${options.jwks_uri}`);
|
|
102
|
+
}
|
|
103
|
+
const data = await response.json();
|
|
104
|
+
if (!data.keys) {
|
|
105
|
+
throw new Error('invalid JWKS response. "keys" field is missing');
|
|
106
|
+
}
|
|
107
|
+
if (!Array.isArray(data.keys)) {
|
|
108
|
+
throw new Error('invalid JWKS response. "keys" field is not an array');
|
|
109
|
+
}
|
|
110
|
+
if (keys) {
|
|
111
|
+
keys.push(...data.keys);
|
|
112
|
+
} else {
|
|
113
|
+
keys = data.keys;
|
|
114
|
+
}
|
|
115
|
+
} else if (!keys) {
|
|
116
|
+
throw new Error('verifyFromJwks requires options for either "keys" or "jwks_uri" or both');
|
|
117
|
+
}
|
|
118
|
+
const matchingKey = keys.find((key) => key.kid === header.kid);
|
|
119
|
+
if (!matchingKey) {
|
|
120
|
+
throw new import_types.JwtTokenInvalid(token);
|
|
121
|
+
}
|
|
122
|
+
return await verify(token, matchingKey, matchingKey.alg);
|
|
123
|
+
};
|
|
81
124
|
const decode = (token) => {
|
|
82
125
|
try {
|
|
83
126
|
const [h, p] = token.split(".");
|
|
@@ -91,10 +134,20 @@ const decode = (token) => {
|
|
|
91
134
|
throw new import_types.JwtTokenInvalid(token);
|
|
92
135
|
}
|
|
93
136
|
};
|
|
137
|
+
const decodeHeader = (token) => {
|
|
138
|
+
try {
|
|
139
|
+
const [h] = token.split(".");
|
|
140
|
+
return decodeJwtPart(h);
|
|
141
|
+
} catch {
|
|
142
|
+
throw new import_types.JwtTokenInvalid(token);
|
|
143
|
+
}
|
|
144
|
+
};
|
|
94
145
|
// Annotate the CommonJS export names for ESM import in node:
|
|
95
146
|
0 && (module.exports = {
|
|
96
147
|
decode,
|
|
148
|
+
decodeHeader,
|
|
97
149
|
isTokenHeader,
|
|
98
150
|
sign,
|
|
99
|
-
verify
|
|
151
|
+
verify,
|
|
152
|
+
verifyFromJwks
|
|
100
153
|
});
|
|
@@ -21,6 +21,7 @@ __export(types_exports, {
|
|
|
21
21
|
CryptoKeyUsage: () => CryptoKeyUsage,
|
|
22
22
|
JwtAlgorithmNotImplemented: () => JwtAlgorithmNotImplemented,
|
|
23
23
|
JwtHeaderInvalid: () => JwtHeaderInvalid,
|
|
24
|
+
JwtHeaderRequiresKid: () => JwtHeaderRequiresKid,
|
|
24
25
|
JwtTokenExpired: () => JwtTokenExpired,
|
|
25
26
|
JwtTokenInvalid: () => JwtTokenInvalid,
|
|
26
27
|
JwtTokenIssuedAt: () => JwtTokenIssuedAt,
|
|
@@ -64,6 +65,12 @@ class JwtHeaderInvalid extends Error {
|
|
|
64
65
|
this.name = "JwtHeaderInvalid";
|
|
65
66
|
}
|
|
66
67
|
}
|
|
68
|
+
class JwtHeaderRequiresKid extends Error {
|
|
69
|
+
constructor(header) {
|
|
70
|
+
super(`required "kid" in jwt header: ${JSON.stringify(header)}`);
|
|
71
|
+
this.name = "JwtHeaderRequiresKid";
|
|
72
|
+
}
|
|
73
|
+
}
|
|
67
74
|
class JwtTokenSignatureMismatched extends Error {
|
|
68
75
|
constructor(token) {
|
|
69
76
|
super(`token(${token}) signature mismatched`);
|
|
@@ -86,6 +93,7 @@ var CryptoKeyUsage = /* @__PURE__ */ ((CryptoKeyUsage2) => {
|
|
|
86
93
|
CryptoKeyUsage,
|
|
87
94
|
JwtAlgorithmNotImplemented,
|
|
88
95
|
JwtHeaderInvalid,
|
|
96
|
+
JwtHeaderRequiresKid,
|
|
89
97
|
JwtTokenExpired,
|
|
90
98
|
JwtTokenInvalid,
|
|
91
99
|
JwtTokenIssuedAt,
|
package/dist/cjs/utils/url.js
CHANGED
|
@@ -66,20 +66,21 @@ const replaceGroupMarks = (paths, groups) => {
|
|
|
66
66
|
return paths;
|
|
67
67
|
};
|
|
68
68
|
const patternCache = {};
|
|
69
|
-
const getPattern = (label) => {
|
|
69
|
+
const getPattern = (label, next) => {
|
|
70
70
|
if (label === "*") {
|
|
71
71
|
return "*";
|
|
72
72
|
}
|
|
73
73
|
const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
|
|
74
74
|
if (match) {
|
|
75
|
-
|
|
75
|
+
const cacheKey = `${label}#${next}`;
|
|
76
|
+
if (!patternCache[cacheKey]) {
|
|
76
77
|
if (match[2]) {
|
|
77
|
-
patternCache[
|
|
78
|
+
patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match[1], new RegExp(`^${match[2]}(?=/${next})`)] : [label, match[1], new RegExp(`^${match[2]}$`)];
|
|
78
79
|
} else {
|
|
79
|
-
patternCache[
|
|
80
|
+
patternCache[cacheKey] = [label, match[1], true];
|
|
80
81
|
}
|
|
81
82
|
}
|
|
82
|
-
return patternCache[
|
|
83
|
+
return patternCache[cacheKey];
|
|
83
84
|
}
|
|
84
85
|
return null;
|
|
85
86
|
};
|
|
@@ -1,25 +1,5 @@
|
|
|
1
1
|
// src/helper/accepts/accepts.ts
|
|
2
|
-
|
|
3
|
-
const accepts2 = acceptHeader.split(",");
|
|
4
|
-
return accepts2.map((accept) => {
|
|
5
|
-
const parts = accept.trim().split(";");
|
|
6
|
-
const type = parts[0];
|
|
7
|
-
const params = parts.slice(1);
|
|
8
|
-
const q = params.find((param) => param.startsWith("q="));
|
|
9
|
-
const paramsObject = params.reduce((acc, param) => {
|
|
10
|
-
const keyValue = param.split("=");
|
|
11
|
-
const key = keyValue[0].trim();
|
|
12
|
-
const value = keyValue[1].trim();
|
|
13
|
-
acc[key] = value;
|
|
14
|
-
return acc;
|
|
15
|
-
}, {});
|
|
16
|
-
return {
|
|
17
|
-
type,
|
|
18
|
-
params: paramsObject,
|
|
19
|
-
q: q ? parseFloat(q.split("=")[1]) : 1
|
|
20
|
-
};
|
|
21
|
-
});
|
|
22
|
-
};
|
|
2
|
+
import { parseAccept } from "../../utils/accept.js";
|
|
23
3
|
var defaultMatch = (accepts2, config) => {
|
|
24
4
|
const { supports, default: defaultSupport } = config;
|
|
25
5
|
const accept = accepts2.sort((a, b) => b.q - a.q).find((accept2) => supports.includes(accept2.type));
|
|
@@ -36,6 +16,5 @@ var accepts = (c, options) => {
|
|
|
36
16
|
};
|
|
37
17
|
export {
|
|
38
18
|
accepts,
|
|
39
|
-
defaultMatch
|
|
40
|
-
parseAccept
|
|
19
|
+
defaultMatch
|
|
41
20
|
};
|
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
import { Hono } from "../../hono.js";
|
|
3
3
|
var Factory = class {
|
|
4
4
|
initApp;
|
|
5
|
+
#defaultAppOptions;
|
|
5
6
|
constructor(init) {
|
|
6
7
|
this.initApp = init?.initApp;
|
|
8
|
+
this.#defaultAppOptions = init?.defaultAppOptions;
|
|
7
9
|
}
|
|
8
|
-
createApp = () => {
|
|
9
|
-
const app = new Hono(
|
|
10
|
+
createApp = (options) => {
|
|
11
|
+
const app = new Hono(
|
|
12
|
+
options && this.#defaultAppOptions ? { ...this.#defaultAppOptions, ...options } : options ?? this.#defaultAppOptions
|
|
13
|
+
);
|
|
10
14
|
if (this.initApp) {
|
|
11
15
|
this.initApp(app);
|
|
12
16
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// src/helper/proxy/index.ts
|
|
2
|
+
var hopByHopHeaders = [
|
|
3
|
+
"connection",
|
|
4
|
+
"keep-alive",
|
|
5
|
+
"proxy-authenticate",
|
|
6
|
+
"proxy-authorization",
|
|
7
|
+
"te",
|
|
8
|
+
"trailers",
|
|
9
|
+
"transfer-encoding"
|
|
10
|
+
];
|
|
11
|
+
var buildRequestInitFromRequest = (request) => {
|
|
12
|
+
if (!request) {
|
|
13
|
+
return {};
|
|
14
|
+
}
|
|
15
|
+
const headers = new Headers(request.headers);
|
|
16
|
+
hopByHopHeaders.forEach((header) => {
|
|
17
|
+
headers.delete(header);
|
|
18
|
+
});
|
|
19
|
+
return {
|
|
20
|
+
method: request.method,
|
|
21
|
+
body: request.body,
|
|
22
|
+
duplex: request.body ? "half" : void 0,
|
|
23
|
+
headers
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
var proxy = async (input, proxyInit) => {
|
|
27
|
+
const { raw, ...requestInit } = proxyInit ?? {};
|
|
28
|
+
const req = new Request(
|
|
29
|
+
input,
|
|
30
|
+
{
|
|
31
|
+
...buildRequestInitFromRequest(raw),
|
|
32
|
+
...requestInit
|
|
33
|
+
}
|
|
34
|
+
);
|
|
35
|
+
req.headers.delete("accept-encoding");
|
|
36
|
+
const res = await fetch(req);
|
|
37
|
+
const resHeaders = new Headers(res.headers);
|
|
38
|
+
hopByHopHeaders.forEach((header) => {
|
|
39
|
+
resHeaders.delete(header);
|
|
40
|
+
});
|
|
41
|
+
if (resHeaders.has("content-encoding")) {
|
|
42
|
+
resHeaders.delete("content-encoding");
|
|
43
|
+
resHeaders.delete("content-length");
|
|
44
|
+
}
|
|
45
|
+
return new Response(res.body, {
|
|
46
|
+
...res,
|
|
47
|
+
headers: resHeaders
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
export {
|
|
51
|
+
proxy
|
|
52
|
+
};
|