hono 4.12.18 → 4.12.26

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.
Files changed (65) hide show
  1. package/dist/adapter/aws-lambda/handler.js +5 -3
  2. package/dist/adapter/bun/serve-static.js +1 -1
  3. package/dist/adapter/cloudflare-workers/serve-static.js +1 -1
  4. package/dist/adapter/deno/serve-static.js +1 -1
  5. package/dist/adapter/deno/websocket.js +5 -1
  6. package/dist/adapter/lambda-edge/handler.js +8 -2
  7. package/dist/cjs/adapter/aws-lambda/handler.js +5 -3
  8. package/dist/cjs/adapter/bun/serve-static.js +1 -1
  9. package/dist/cjs/adapter/cloudflare-workers/serve-static.js +1 -1
  10. package/dist/cjs/adapter/deno/serve-static.js +1 -1
  11. package/dist/cjs/adapter/deno/websocket.js +5 -1
  12. package/dist/cjs/adapter/lambda-edge/handler.js +8 -2
  13. package/dist/cjs/hono-base.js +9 -4
  14. package/dist/cjs/index.js +3 -0
  15. package/dist/cjs/middleware/bearer-auth/index.js +1 -1
  16. package/dist/cjs/middleware/cache/index.js +30 -25
  17. package/dist/cjs/middleware/compress/index.js +31 -5
  18. package/dist/cjs/middleware/cors/index.js +2 -5
  19. package/dist/cjs/middleware/ip-restriction/index.js +58 -28
  20. package/dist/cjs/middleware/jwk/jwk.js +1 -1
  21. package/dist/cjs/middleware/jwt/jwt.js +1 -1
  22. package/dist/cjs/middleware/language/language.js +10 -32
  23. package/dist/cjs/middleware/serve-static/index.js +1 -1
  24. package/dist/cjs/middleware/timing/timing.js +3 -1
  25. package/dist/cjs/request.js +15 -0
  26. package/dist/cjs/utils/compress.js +1 -1
  27. package/dist/cjs/utils/cookie.js +4 -4
  28. package/dist/cjs/utils/filepath.js +1 -1
  29. package/dist/cjs/utils/ipaddr.js +193 -10
  30. package/dist/cjs/utils/mime.js +15 -17
  31. package/dist/cjs/utils/stream.js +4 -2
  32. package/dist/hono-base.js +9 -4
  33. package/dist/index.js +2 -0
  34. package/dist/middleware/bearer-auth/index.js +1 -1
  35. package/dist/middleware/cache/index.js +30 -25
  36. package/dist/middleware/compress/index.js +30 -5
  37. package/dist/middleware/cors/index.js +2 -5
  38. package/dist/middleware/ip-restriction/index.js +60 -29
  39. package/dist/middleware/jwk/jwk.js +1 -1
  40. package/dist/middleware/jwt/jwt.js +1 -1
  41. package/dist/middleware/language/language.js +10 -32
  42. package/dist/middleware/serve-static/index.js +1 -1
  43. package/dist/middleware/timing/timing.js +3 -1
  44. package/dist/request.js +15 -0
  45. package/dist/tsconfig.build.tsbuildinfo +1 -1
  46. package/dist/types/adapter/aws-lambda/handler.d.ts +1 -1
  47. package/dist/types/adapter/bun/serve-static.d.ts +1 -1
  48. package/dist/types/adapter/cloudflare-workers/serve-static.d.ts +2 -2
  49. package/dist/types/adapter/deno/serve-static.d.ts +1 -1
  50. package/dist/types/index.d.ts +2 -1
  51. package/dist/types/jsx/base.d.ts +2 -2
  52. package/dist/types/jsx/index.d.ts +1 -1
  53. package/dist/types/middleware/bearer-auth/index.d.ts +6 -5
  54. package/dist/types/middleware/cache/index.d.ts +1 -1
  55. package/dist/types/middleware/compress/index.d.ts +13 -2
  56. package/dist/types/request.d.ts +13 -0
  57. package/dist/types/utils/ipaddr.d.ts +4 -0
  58. package/dist/types/utils/mime.d.ts +11 -11
  59. package/dist/utils/compress.js +1 -1
  60. package/dist/utils/cookie.js +4 -4
  61. package/dist/utils/filepath.js +1 -1
  62. package/dist/utils/ipaddr.js +192 -10
  63. package/dist/utils/mime.js +15 -17
  64. package/dist/utils/stream.js +4 -2
  65. package/package.json +22 -16
@@ -109,7 +109,9 @@ var EventProcessor = class {
109
109
  method
110
110
  };
111
111
  if (event.body) {
112
- requestInit.body = event.isBase64Encoded ? decodeBase64(event.body) : event.body;
112
+ const body = event.isBase64Encoded ? decodeBase64(event.body) : new TextEncoder().encode(event.body);
113
+ requestInit.body = body;
114
+ headers.set("content-length", body.length.toString());
113
115
  }
114
116
  return new Request(url, requestInit);
115
117
  }
@@ -281,7 +283,7 @@ var ALBProcessor = class extends EventProcessor {
281
283
  if (result.multiValueHeaders) {
282
284
  result.multiValueHeaders["set-cookie"] = cookies;
283
285
  } else {
284
- result.headers["set-cookie"] = cookies.join(", ");
286
+ result.headers["set-cookie"] = cookies[0];
285
287
  }
286
288
  }
287
289
  };
@@ -316,7 +318,7 @@ var LatticeV2Processor = class extends EventProcessor {
316
318
  setCookiesToResult(result, cookies) {
317
319
  result.headers = {
318
320
  ...result.headers,
319
- "set-cookie": cookies.join(", ")
321
+ "set-cookie": cookies
320
322
  };
321
323
  }
322
324
  };
@@ -2,7 +2,7 @@
2
2
  import { stat } from "node:fs/promises";
3
3
  import { join } from "node:path";
4
4
  import { serveStatic as baseServeStatic } from "../../middleware/serve-static/index.js";
5
- var serveStatic = (options) => {
5
+ var serveStatic = (options = {}) => {
6
6
  return async function serveStatic2(c, next) {
7
7
  const getContent = async (path) => {
8
8
  const file = Bun.file(path);
@@ -1,7 +1,7 @@
1
1
  // src/adapter/cloudflare-workers/serve-static.ts
2
2
  import { serveStatic as baseServeStatic } from "../../middleware/serve-static/index.js";
3
3
  import { getContentFromKVAsset } from "./utils.js";
4
- var serveStatic = (options) => {
4
+ var serveStatic = (options = {}) => {
5
5
  return async function serveStatic2(c, next) {
6
6
  const getContent = async (path) => {
7
7
  return getContentFromKVAsset(path, {
@@ -2,7 +2,7 @@
2
2
  import { join } from "node:path";
3
3
  import { serveStatic as baseServeStatic } from "../../middleware/serve-static/index.js";
4
4
  var { open, lstatSync, errors } = Deno;
5
- var serveStatic = (options) => {
5
+ var serveStatic = (options = {}) => {
6
6
  return async function serveStatic2(c, next) {
7
7
  const getContent = async (path) => {
8
8
  try {
@@ -4,7 +4,11 @@ var upgradeWebSocket = defineWebSocketHelper(async (c, events, options) => {
4
4
  if (c.req.header("upgrade") !== "websocket") {
5
5
  return;
6
6
  }
7
- const { response, socket } = Deno.upgradeWebSocket(c.req.raw, options ?? {});
7
+ const subprotocol = c.req.header("sec-websocket-protocol")?.split(",")[0]?.trim();
8
+ const { response, socket } = Deno.upgradeWebSocket(c.req.raw, {
9
+ ...subprotocol ? { protocol: subprotocol } : {},
10
+ ...options
11
+ });
8
12
  const wsContext = new WSContext({
9
13
  close: (code, reason) => socket.close(code, reason),
10
14
  get protocol() {
@@ -45,11 +45,17 @@ var createRequest = (event) => {
45
45
  const url = queryString ? `${urlPath}?${queryString}` : urlPath;
46
46
  const headers = new Headers();
47
47
  Object.entries(event.Records[0].cf.request.headers).forEach(([k, v]) => {
48
- v.forEach((header) => headers.set(k, header.value));
48
+ v.forEach((header) => headers.append(k, header.value));
49
49
  });
50
50
  const requestBody = event.Records[0].cf.request.body;
51
51
  const method = event.Records[0].cf.request.method;
52
- const body = createBody(method, requestBody);
52
+ const rawBody = createBody(method, requestBody);
53
+ let body = rawBody;
54
+ if (rawBody !== void 0) {
55
+ const bytes = typeof rawBody === "string" ? new TextEncoder().encode(rawBody) : rawBody;
56
+ body = bytes;
57
+ headers.set("content-length", bytes.length.toString());
58
+ }
53
59
  return new Request(url, {
54
60
  headers,
55
61
  method,
@@ -139,7 +139,9 @@ class EventProcessor {
139
139
  method
140
140
  };
141
141
  if (event.body) {
142
- requestInit.body = event.isBase64Encoded ? (0, import_encode.decodeBase64)(event.body) : event.body;
142
+ const body = event.isBase64Encoded ? (0, import_encode.decodeBase64)(event.body) : new TextEncoder().encode(event.body);
143
+ requestInit.body = body;
144
+ headers.set("content-length", body.length.toString());
143
145
  }
144
146
  return new Request(url, requestInit);
145
147
  }
@@ -311,7 +313,7 @@ class ALBProcessor extends EventProcessor {
311
313
  if (result.multiValueHeaders) {
312
314
  result.multiValueHeaders["set-cookie"] = cookies;
313
315
  } else {
314
- result.headers["set-cookie"] = cookies.join(", ");
316
+ result.headers["set-cookie"] = cookies[0];
315
317
  }
316
318
  }
317
319
  }
@@ -346,7 +348,7 @@ class LatticeV2Processor extends EventProcessor {
346
348
  setCookiesToResult(result, cookies) {
347
349
  result.headers = {
348
350
  ...result.headers,
349
- "set-cookie": cookies.join(", ")
351
+ "set-cookie": cookies
350
352
  };
351
353
  }
352
354
  }
@@ -23,7 +23,7 @@ module.exports = __toCommonJS(serve_static_exports);
23
23
  var import_promises = require("node:fs/promises");
24
24
  var import_node_path = require("node:path");
25
25
  var import_serve_static = require("../../middleware/serve-static");
26
- const serveStatic = (options) => {
26
+ const serveStatic = (options = {}) => {
27
27
  return async function serveStatic2(c, next) {
28
28
  const getContent = async (path) => {
29
29
  const file = Bun.file(path);
@@ -22,7 +22,7 @@ __export(serve_static_exports, {
22
22
  module.exports = __toCommonJS(serve_static_exports);
23
23
  var import_serve_static = require("../../middleware/serve-static");
24
24
  var import_utils = require("./utils");
25
- const serveStatic = (options) => {
25
+ const serveStatic = (options = {}) => {
26
26
  return async function serveStatic2(c, next) {
27
27
  const getContent = async (path) => {
28
28
  return (0, import_utils.getContentFromKVAsset)(path, {
@@ -23,7 +23,7 @@ module.exports = __toCommonJS(serve_static_exports);
23
23
  var import_node_path = require("node:path");
24
24
  var import_serve_static = require("../../middleware/serve-static");
25
25
  const { open, lstatSync, errors } = Deno;
26
- const serveStatic = (options) => {
26
+ const serveStatic = (options = {}) => {
27
27
  return async function serveStatic2(c, next) {
28
28
  const getContent = async (path) => {
29
29
  try {
@@ -25,7 +25,11 @@ const upgradeWebSocket = (0, import_websocket.defineWebSocketHelper)(async (c, e
25
25
  if (c.req.header("upgrade") !== "websocket") {
26
26
  return;
27
27
  }
28
- const { response, socket } = Deno.upgradeWebSocket(c.req.raw, options ?? {});
28
+ const subprotocol = c.req.header("sec-websocket-protocol")?.split(",")[0]?.trim();
29
+ const { response, socket } = Deno.upgradeWebSocket(c.req.raw, {
30
+ ...subprotocol ? { protocol: subprotocol } : {},
31
+ ...options
32
+ });
29
33
  const wsContext = new import_websocket.WSContext({
30
34
  close: (code, reason) => socket.close(code, reason),
31
35
  get protocol() {
@@ -78,11 +78,17 @@ const createRequest = (event) => {
78
78
  const url = queryString ? `${urlPath}?${queryString}` : urlPath;
79
79
  const headers = new Headers();
80
80
  Object.entries(event.Records[0].cf.request.headers).forEach(([k, v]) => {
81
- v.forEach((header) => headers.set(k, header.value));
81
+ v.forEach((header) => headers.append(k, header.value));
82
82
  });
83
83
  const requestBody = event.Records[0].cf.request.body;
84
84
  const method = event.Records[0].cf.request.method;
85
- const body = createBody(method, requestBody);
85
+ const rawBody = createBody(method, requestBody);
86
+ let body = rawBody;
87
+ if (rawBody !== void 0) {
88
+ const bytes = typeof rawBody === "string" ? new TextEncoder().encode(rawBody) : rawBody;
89
+ body = bytes;
90
+ headers.set("content-length", bytes.length.toString());
91
+ }
86
92
  return new Request(url, {
87
93
  headers,
88
94
  method,
@@ -139,7 +139,7 @@ class Hono {
139
139
  handler = async (c, next) => (await (0, import_compose.compose)([], app.errorHandler)(c, () => r.handler(c, next))).res;
140
140
  handler[import_constants.COMPOSED_HANDLER] = r.handler;
141
141
  }
142
- subApp.#addRoute(r.method, r.path, handler);
142
+ subApp.#addRoute(r.method, r.path, handler, r.basePath);
143
143
  });
144
144
  return this;
145
145
  }
@@ -263,7 +263,7 @@ class Hono {
263
263
  const pathPrefixLength = mergedPath === "/" ? 0 : mergedPath.length;
264
264
  return (request) => {
265
265
  const url = new URL(request.url);
266
- url.pathname = url.pathname.slice(pathPrefixLength) || "/";
266
+ url.pathname = this.getPath(request).slice(pathPrefixLength) || "/";
267
267
  return new Request(url, request);
268
268
  };
269
269
  })();
@@ -277,10 +277,15 @@ class Hono {
277
277
  this.#addRoute(import_router.METHOD_NAME_ALL, (0, import_url.mergePath)(path, "*"), handler);
278
278
  return this;
279
279
  }
280
- #addRoute(method, path, handler) {
280
+ #addRoute(method, path, handler, baseRoutePath) {
281
281
  method = method.toUpperCase();
282
282
  path = (0, import_url.mergePath)(this._basePath, path);
283
- const r = { basePath: this._basePath, path, method, handler };
283
+ const r = {
284
+ basePath: baseRoutePath !== void 0 ? (0, import_url.mergePath)(this._basePath, baseRoutePath) : this._basePath,
285
+ path,
286
+ method,
287
+ handler
288
+ };
284
289
  this.router.add(method, path, [handler, r]);
285
290
  this.routes.push(r);
286
291
  }
package/dist/cjs/index.js CHANGED
@@ -17,11 +17,14 @@ var __copyProps = (to, from, except, desc) => {
17
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
18
  var index_exports = {};
19
19
  __export(index_exports, {
20
+ Context: () => import_context.Context,
20
21
  Hono: () => import_hono.Hono
21
22
  });
22
23
  module.exports = __toCommonJS(index_exports);
23
24
  var import_hono = require("./hono");
25
+ var import_context = require("./context");
24
26
  // Annotate the CommonJS export names for ESM import in node:
25
27
  0 && (module.exports = {
28
+ Context,
26
29
  Hono
27
30
  });
@@ -27,7 +27,7 @@ const PREFIX = "Bearer";
27
27
  const HEADER = "Authorization";
28
28
  const bearerAuth = (options) => {
29
29
  if (!("token" in options || "verifyToken" in options)) {
30
- throw new Error('bearer auth middleware requires options for "token"');
30
+ throw new Error('bearer auth middleware requires options for "token" or "verifyToken"');
31
31
  }
32
32
  if (!options.realm) {
33
33
  options.realm = "";
@@ -21,19 +21,14 @@ __export(cache_exports, {
21
21
  });
22
22
  module.exports = __toCommonJS(cache_exports);
23
23
  const defaultCacheableStatusCodes = [200];
24
- const shouldSkipCache = (res) => {
25
- if (res.headers.has("Vary")) {
26
- return true;
24
+ const shouldSkipCacheControl = (cacheControl) => !!cacheControl && /(?:^|,\s*)(?:private|no-(?:store|cache))(?:\s*(?:=|,|$))/i.test(cacheControl);
25
+ const parseVaryDirectives = (vary) => {
26
+ if (vary == null) {
27
+ return [];
27
28
  }
28
- const cacheControl = res.headers.get("Cache-Control");
29
- if (cacheControl && /(?:^|,\s*)(?:private|no-(?:store|cache))(?:\s*(?:=|,|$))/i.test(cacheControl)) {
30
- return true;
31
- }
32
- if (res.headers.has("Set-Cookie")) {
33
- return true;
34
- }
35
- return false;
29
+ return (Array.isArray(vary) ? vary : vary.split(",")).map((directive) => directive.trim().toLowerCase()).filter(Boolean);
36
30
  };
31
+ const shouldSkipCache = (res, optionsVaryDirectives, responseVary) => responseVary.length && (!optionsVaryDirectives || responseVary.some((name) => !optionsVaryDirectives.has(name))) || shouldSkipCacheControl(res.headers.get("Cache-Control")) || res.headers.has("Set-Cookie");
37
32
  const cache = (options) => {
38
33
  if (!globalThis.caches) {
39
34
  if (options.onCacheNotAvailable === false) {
@@ -48,8 +43,9 @@ const cache = (options) => {
48
43
  options.wait = false;
49
44
  }
50
45
  const cacheControlDirectives = options.cacheControl?.split(",").map((directive) => directive.toLowerCase());
51
- const varyDirectives = Array.isArray(options.vary) ? options.vary : options.vary?.split(",").map((directive) => directive.trim());
52
- if (options.vary?.includes("*")) {
46
+ const optionsVaryList = parseVaryDirectives(options.vary);
47
+ const varyDirectives = optionsVaryList.length ? new Set(optionsVaryList) : void 0;
48
+ if (varyDirectives?.has("*")) {
53
49
  throw new Error(
54
50
  'Middleware vary configuration cannot include "*", as it disallows effective caching.'
55
51
  );
@@ -57,7 +53,7 @@ const cache = (options) => {
57
53
  const cacheableStatusCodes = new Set(
58
54
  options.cacheableStatusCodes ?? defaultCacheableStatusCodes
59
55
  );
60
- const addHeader = (c) => {
56
+ const addHeader = (c, responseVary) => {
61
57
  if (cacheControlDirectives) {
62
58
  const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0]) ?? [];
63
59
  for (const directive of cacheControlDirectives) {
@@ -69,16 +65,18 @@ const cache = (options) => {
69
65
  }
70
66
  }
71
67
  if (varyDirectives) {
72
- const existingDirectives = c.res.headers.get("Vary")?.split(",").map((d) => d.trim()) ?? [];
73
- const vary = Array.from(
74
- new Set(
75
- [...existingDirectives, ...varyDirectives].map((directive) => directive.toLowerCase())
76
- )
77
- ).sort();
78
- if (vary.includes("*")) {
79
- c.header("Vary", "*");
68
+ if (responseVary.length === 0) {
69
+ c.header("Vary", Array.from(varyDirectives).join(", "));
80
70
  } else {
81
- c.header("Vary", vary.join(", "));
71
+ const merged = new Set(varyDirectives);
72
+ for (const directive of responseVary) {
73
+ merged.add(directive);
74
+ }
75
+ if (merged.has("*")) {
76
+ c.header("Vary", "*");
77
+ } else {
78
+ c.header("Vary", Array.from(merged).join(", "));
79
+ }
82
80
  }
83
81
  }
84
82
  };
@@ -91,6 +89,12 @@ const cache = (options) => {
91
89
  if (options.keyGenerator) {
92
90
  key = await options.keyGenerator(c);
93
91
  }
92
+ if (varyDirectives) {
93
+ for (const directive of varyDirectives) {
94
+ const value = c.req.raw.headers.get(directive) ?? "";
95
+ key += `::${directive}=${encodeURIComponent(value)}`;
96
+ }
97
+ }
94
98
  const cacheName = typeof options.cacheName === "function" ? await options.cacheName(c) : options.cacheName;
95
99
  const cache3 = await caches.open(cacheName);
96
100
  const response = await cache3.match(key);
@@ -101,8 +105,9 @@ const cache = (options) => {
101
105
  if (!cacheableStatusCodes.has(c.res.status)) {
102
106
  return;
103
107
  }
104
- addHeader(c);
105
- if (shouldSkipCache(c.res)) {
108
+ const responseVary = parseVaryDirectives(c.res.headers.get("Vary"));
109
+ addHeader(c, responseVary);
110
+ if (shouldSkipCache(c.res, varyDirectives, responseVary)) {
106
111
  return;
107
112
  }
108
113
  const res = c.res.clone();
@@ -17,14 +17,43 @@ var __copyProps = (to, from, except, desc) => {
17
17
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
18
  var compress_exports = {};
19
19
  __export(compress_exports, {
20
+ COMPRESSIBLE_CONTENT_TYPE_REGEX: () => import_compress.COMPRESSIBLE_CONTENT_TYPE_REGEX,
20
21
  compress: () => compress
21
22
  });
22
23
  module.exports = __toCommonJS(compress_exports);
24
+ var import_accept = require("../../utils/accept");
23
25
  var import_compress = require("../../utils/compress");
24
26
  const ENCODING_TYPES = ["gzip", "deflate"];
25
27
  const cacheControlNoTransformRegExp = /(?:^|,)\s*?no-transform\s*?(?:,|$)/i;
28
+ const selectEncoding = (header, candidates) => {
29
+ if (header === void 0) {
30
+ return void 0;
31
+ }
32
+ const accepts = (0, import_accept.parseAccept)(header);
33
+ const wildcardQ = accepts.find((a) => a.type === "*")?.q;
34
+ let best;
35
+ for (const enc of candidates) {
36
+ const explicit = accepts.find((a) => a.type.toLowerCase() === enc);
37
+ const q = explicit ? explicit.q : wildcardQ ?? 0;
38
+ if (q === 1) {
39
+ return enc;
40
+ } else if (q > 0 && (!best || q > best.q)) {
41
+ best = { encoding: enc, q };
42
+ }
43
+ }
44
+ return best?.encoding;
45
+ };
26
46
  const compress = (options) => {
27
47
  const threshold = options?.threshold ?? 1024;
48
+ const candidates = options?.encoding ? [options.encoding] : ENCODING_TYPES;
49
+ const contentTypeFilter = options?.contentTypeFilter ?? import_compress.COMPRESSIBLE_CONTENT_TYPE_REGEX;
50
+ const shouldCompress = typeof contentTypeFilter === "function" ? (res) => {
51
+ const type = res.headers.get("Content-Type");
52
+ return type && contentTypeFilter(type);
53
+ } : (res) => {
54
+ const type = res.headers.get("Content-Type");
55
+ return type && contentTypeFilter.test(type);
56
+ };
28
57
  return async function compress2(ctx, next) {
29
58
  await next();
30
59
  const contentLength = ctx.res.headers.get("Content-Length");
@@ -37,7 +66,7 @@ const compress = (options) => {
37
66
  return;
38
67
  }
39
68
  const accepted = ctx.req.header("Accept-Encoding");
40
- const encoding = options?.encoding ?? ENCODING_TYPES.find((encoding2) => accepted?.includes(encoding2));
69
+ const encoding = selectEncoding(accepted, candidates);
41
70
  if (!encoding || !ctx.res.body) {
42
71
  return;
43
72
  }
@@ -51,15 +80,12 @@ const compress = (options) => {
51
80
  }
52
81
  };
53
82
  };
54
- const shouldCompress = (res) => {
55
- const type = res.headers.get("Content-Type");
56
- return type && import_compress.COMPRESSIBLE_CONTENT_TYPE_REGEX.test(type);
57
- };
58
83
  const shouldTransform = (res) => {
59
84
  const cacheControl = res.headers.get("Cache-Control");
60
85
  return !cacheControl || !cacheControlNoTransformRegExp.test(cacheControl);
61
86
  };
62
87
  // Annotate the CommonJS export names for ESM import in node:
63
88
  0 && (module.exports = {
89
+ COMPRESSIBLE_CONTENT_TYPE_REGEX,
64
90
  compress
65
91
  });
@@ -31,9 +31,6 @@ const cors = (options) => {
31
31
  const findAllowOrigin = ((optsOrigin) => {
32
32
  if (typeof optsOrigin === "string") {
33
33
  if (optsOrigin === "*") {
34
- if (opts.credentials) {
35
- return (origin) => origin || null;
36
- }
37
34
  return () => optsOrigin;
38
35
  } else {
39
36
  return (origin) => optsOrigin === origin ? origin : null;
@@ -68,7 +65,7 @@ const cors = (options) => {
68
65
  set("Access-Control-Expose-Headers", opts.exposeHeaders.join(","));
69
66
  }
70
67
  if (c.req.method === "OPTIONS") {
71
- if (opts.origin !== "*" || opts.credentials) {
68
+ if (opts.origin !== "*") {
72
69
  set("Vary", "Origin");
73
70
  }
74
71
  if (opts.maxAge != null) {
@@ -98,7 +95,7 @@ const cors = (options) => {
98
95
  });
99
96
  }
100
97
  await next();
101
- if (opts.origin !== "*" || opts.credentials) {
98
+ if (opts.origin !== "*") {
102
99
  c.header("Vary", "Origin", { append: true });
103
100
  }
104
101
  };
@@ -22,11 +22,45 @@ __export(ip_restriction_exports, {
22
22
  module.exports = __toCommonJS(ip_restriction_exports);
23
23
  var import_http_exception = require("../../http-exception");
24
24
  var import_ipaddr = require("../../utils/ipaddr");
25
- const IS_CIDR_NOTATION_REGEX = /\/[0-9]{0,3}$/;
25
+ const IS_CIDR_NOTATION_REGEX = /\/[^/]*$/;
26
+ const parseCidrPrefix = (rule, prefix, max) => {
27
+ if (!/^[0-9]{1,3}$/.test(prefix)) {
28
+ throw new TypeError(`Invalid rule: ${rule}`);
29
+ }
30
+ const parsedPrefix = parseInt(prefix);
31
+ if (parsedPrefix > max) {
32
+ throw new TypeError(`Invalid rule: ${rule}`);
33
+ }
34
+ return parsedPrefix;
35
+ };
26
36
  const buildMatcher = (rules) => {
27
37
  const functionRules = [];
28
38
  const staticRules = /* @__PURE__ */ new Set();
39
+ const staticIPv4Rules = /* @__PURE__ */ new Set();
40
+ const staticIPv6Rules = /* @__PURE__ */ new Set();
29
41
  const cidrRules = [];
42
+ const registerStaticRule = (rule) => {
43
+ const type = (0, import_ipaddr.distinctRemoteAddr)(rule);
44
+ if (type === void 0) {
45
+ throw new TypeError(`Invalid rule: ${rule}`);
46
+ }
47
+ if (type === "IPv4") {
48
+ const ipv4binary = (0, import_ipaddr.convertIPv4ToBinary)(rule);
49
+ staticRules.add(rule);
50
+ staticRules.add(`::ffff:${rule}`);
51
+ staticIPv4Rules.add(ipv4binary);
52
+ staticIPv6Rules.add(0xffffn << 32n | ipv4binary);
53
+ } else {
54
+ const ipv6binary = (0, import_ipaddr.convertIPv6ToBinary)(rule);
55
+ const ipv6Addr = (0, import_ipaddr.convertIPv6BinaryToString)(ipv6binary);
56
+ staticRules.add(ipv6Addr);
57
+ staticIPv6Rules.add(ipv6binary);
58
+ if ((0, import_ipaddr.isIPv4MappedIPv6)(ipv6binary)) {
59
+ staticRules.add(ipv6Addr.substring(7));
60
+ staticIPv4Rules.add((0, import_ipaddr.convertIPv4MappedIPv6ToIPv4)(ipv6binary));
61
+ }
62
+ }
63
+ };
30
64
  for (let rule of rules) {
31
65
  if (rule === "*") {
32
66
  return () => true;
@@ -36,17 +70,17 @@ const buildMatcher = (rules) => {
36
70
  if (IS_CIDR_NOTATION_REGEX.test(rule)) {
37
71
  const separatedRule = rule.split("/");
38
72
  const addrStr = separatedRule[0];
39
- const type2 = (0, import_ipaddr.distinctRemoteAddr)(addrStr);
40
- if (type2 === void 0) {
73
+ const type = (0, import_ipaddr.distinctRemoteAddr)(addrStr);
74
+ if (type === void 0) {
41
75
  throw new TypeError(`Invalid rule: ${rule}`);
42
76
  }
43
- let isIPv4 = type2 === "IPv4";
44
- let prefix = parseInt(separatedRule[1]);
77
+ let isIPv4 = type === "IPv4";
78
+ let prefix = parseCidrPrefix(rule, separatedRule[1], isIPv4 ? 32 : 128);
45
79
  if (isIPv4 ? prefix === 32 : prefix === 128) {
46
80
  rule = addrStr;
47
81
  } else {
48
82
  let addr = (isIPv4 ? import_ipaddr.convertIPv4ToBinary : import_ipaddr.convertIPv6ToBinary)(addrStr);
49
- if (type2 === "IPv6" && (0, import_ipaddr.isIPv4MappedIPv6)(addr) && prefix >= 96) {
83
+ if (type === "IPv6" && (0, import_ipaddr.isIPv4MappedIPv6)(addr) && prefix >= 96) {
50
84
  isIPv4 = true;
51
85
  addr = (0, import_ipaddr.convertIPv4MappedIPv6ToIPv4)(addr);
52
86
  prefix -= 96;
@@ -56,21 +90,7 @@ const buildMatcher = (rules) => {
56
90
  continue;
57
91
  }
58
92
  }
59
- const type = (0, import_ipaddr.distinctRemoteAddr)(rule);
60
- if (type === void 0) {
61
- throw new TypeError(`Invalid rule: ${rule}`);
62
- }
63
- if (type === "IPv4") {
64
- staticRules.add(rule);
65
- staticRules.add(`::ffff:${rule}`);
66
- } else {
67
- const ipv6binary = (0, import_ipaddr.convertIPv6ToBinary)(rule);
68
- const ipv6Addr = (0, import_ipaddr.convertIPv6BinaryToString)(ipv6binary);
69
- staticRules.add(ipv6Addr);
70
- if ((0, import_ipaddr.isIPv4MappedIPv6)(ipv6binary)) {
71
- staticRules.add(ipv6Addr.substring(7));
72
- }
73
- }
93
+ registerStaticRule(rule);
74
94
  }
75
95
  }
76
96
  return (remote) => {
@@ -79,6 +99,9 @@ const buildMatcher = (rules) => {
79
99
  }
80
100
  const remoteAddr = remote.binaryAddr ||= (remote.isIPv4 ? import_ipaddr.convertIPv4ToBinary : import_ipaddr.convertIPv6ToBinary)(remote.addr);
81
101
  const remoteIPv4Addr = remote.isIPv4 || (0, import_ipaddr.isIPv4MappedIPv6)(remoteAddr) ? remote.isIPv4 ? remoteAddr : (0, import_ipaddr.convertIPv4MappedIPv6ToIPv4)(remoteAddr) : void 0;
102
+ if ((remote.isIPv4 ? staticIPv4Rules : staticIPv6Rules).has(remoteAddr)) {
103
+ return true;
104
+ }
82
105
  for (const [isIPv4, addr, mask] of cidrRules) {
83
106
  if (isIPv4) {
84
107
  if (remoteIPv4Addr === void 0) {
@@ -121,14 +144,21 @@ const ipRestriction = (getIP, { denyList = [], allowList = [] }, onError) => {
121
144
  }
122
145
  const type = typeof connInfo !== "string" && connInfo.remote.addressType || (0, import_ipaddr.distinctRemoteAddr)(addr);
123
146
  const remoteData = { addr, type, isIPv4: type === "IPv4" };
124
- if (denyMatcher(remoteData)) {
125
- if (onError) {
126
- return onError({ addr, type }, c);
147
+ try {
148
+ if (denyMatcher(remoteData)) {
149
+ if (onError) {
150
+ return onError({ addr, type }, c);
151
+ }
152
+ throw blockError(c);
127
153
  }
128
- throw blockError(c);
129
- }
130
- if (allowMatcher(remoteData)) {
131
- return await next();
154
+ if (allowMatcher(remoteData)) {
155
+ return await next();
156
+ }
157
+ } catch (e) {
158
+ if (e instanceof TypeError && e.code === import_ipaddr.INVALID_IP_ADDRESS_ERROR_CODE) {
159
+ throw blockError(c);
160
+ }
161
+ throw e;
132
162
  }
133
163
  if (allowLength === 0) {
134
164
  return await next();
@@ -38,7 +38,7 @@ const jwk = (options, init) => {
38
38
  let token;
39
39
  if (credentials) {
40
40
  const parts = credentials.split(/\s+/);
41
- if (parts.length !== 2) {
41
+ if (parts.length !== 2 || parts[0].toLowerCase() !== "bearer") {
42
42
  const errDescription = "invalid credentials structure";
43
43
  throw new import_http_exception.HTTPException(401, {
44
44
  message: errDescription,
@@ -45,7 +45,7 @@ const jwt = (options) => {
45
45
  let token;
46
46
  if (credentials) {
47
47
  const parts = credentials.split(/\s+/);
48
- if (parts.length !== 2) {
48
+ if (parts.length !== 2 || parts[0].toLowerCase() !== "bearer") {
49
49
  const errDescription = "invalid credentials structure";
50
50
  throw new import_http_exception.HTTPException(401, {
51
51
  message: errDescription,