hono 4.1.7 → 4.2.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.
Files changed (59) hide show
  1. package/dist/cjs/helper/ssg/ssg.js +17 -14
  2. package/dist/cjs/jsx/dom/index.js +3 -0
  3. package/dist/cjs/jsx/hooks/index.js +4 -0
  4. package/dist/cjs/jsx/index.js +3 -0
  5. package/dist/cjs/middleware/basic-auth/index.js +22 -9
  6. package/dist/cjs/middleware/bearer-auth/index.js +4 -2
  7. package/dist/cjs/middleware/cache/index.js +22 -3
  8. package/dist/cjs/middleware/cors/index.js +1 -1
  9. package/dist/cjs/middleware/jwt/index.js +12 -6
  10. package/dist/cjs/middleware/method-override/index.js +106 -0
  11. package/dist/cjs/middleware/trailing-slash/index.js +49 -0
  12. package/dist/cjs/request.js +13 -4
  13. package/dist/cjs/test-utils/setup-vitest.js +5 -2
  14. package/dist/cjs/utils/jwt/index.js +2 -7
  15. package/dist/cjs/utils/jwt/jwa.js +43 -0
  16. package/dist/cjs/utils/jwt/jws.js +212 -0
  17. package/dist/cjs/utils/jwt/jwt.js +26 -72
  18. package/dist/cjs/utils/jwt/types.js +21 -8
  19. package/dist/cjs/utils/jwt/utf8.js +31 -0
  20. package/dist/cjs/validator/validator.js +2 -27
  21. package/dist/helper/ssg/ssg.js +16 -14
  22. package/dist/jsx/dom/index.js +3 -0
  23. package/dist/jsx/hooks/index.js +3 -0
  24. package/dist/jsx/index.js +3 -0
  25. package/dist/middleware/basic-auth/index.js +22 -9
  26. package/dist/middleware/bearer-auth/index.js +4 -2
  27. package/dist/middleware/cache/index.js +22 -3
  28. package/dist/middleware/cors/index.js +1 -1
  29. package/dist/middleware/jwt/index.js +12 -6
  30. package/dist/middleware/method-override/index.js +83 -0
  31. package/dist/middleware/trailing-slash/index.js +25 -0
  32. package/dist/request.js +13 -4
  33. package/dist/test-utils/setup-vitest.js +5 -2
  34. package/dist/types/helper/ssg/ssg.d.ts +3 -1
  35. package/dist/types/helper.d.ts +12 -0
  36. package/dist/types/jsx/dom/index.d.ts +3 -2
  37. package/dist/types/jsx/hooks/index.d.ts +1 -0
  38. package/dist/types/jsx/index.d.ts +3 -2
  39. package/dist/types/middleware/basic-auth/index.d.ts +9 -2
  40. package/dist/types/middleware/bearer-auth/index.d.ts +10 -2
  41. package/dist/types/middleware/cache/index.d.ts +1 -0
  42. package/dist/types/middleware/cors/index.d.ts +2 -1
  43. package/dist/types/middleware/jwt/index.d.ts +4 -3
  44. package/dist/types/middleware/method-override/index.d.ts +36 -0
  45. package/dist/types/middleware/trailing-slash/index.d.ts +13 -0
  46. package/dist/types/utils/jwt/index.d.ts +8 -1
  47. package/dist/types/utils/jwt/jwa.d.ts +16 -0
  48. package/dist/types/utils/jwt/jws.d.ts +4 -0
  49. package/dist/types/utils/jwt/jwt.d.ts +10 -5
  50. package/dist/types/utils/jwt/types.d.ts +30 -4
  51. package/dist/types/utils/jwt/utf8.d.ts +2 -0
  52. package/dist/utils/jwt/index.js +2 -1
  53. package/dist/utils/jwt/jwa.js +20 -0
  54. package/dist/utils/jwt/jws.js +188 -0
  55. package/dist/utils/jwt/jwt.js +24 -53
  56. package/dist/utils/jwt/types.js +19 -7
  57. package/dist/utils/jwt/utf8.js +7 -0
  58. package/dist/validator/validator.js +2 -27
  59. package/package.json +14 -1
@@ -0,0 +1,212 @@
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 jws_exports = {};
20
+ __export(jws_exports, {
21
+ signing: () => signing,
22
+ verifying: () => verifying
23
+ });
24
+ module.exports = __toCommonJS(jws_exports);
25
+ var import_helper = require("../../helper");
26
+ var import_encode = require("../encode");
27
+ var import_types = require("./types");
28
+ var import_types2 = require("./types");
29
+ var import_utf8 = require("./utf8");
30
+ async function signing(privateKey, alg, data) {
31
+ const algorithm = getKeyAlgorithm(alg);
32
+ const cryptoKey = await importPrivateKey(privateKey, algorithm);
33
+ return await crypto.subtle.sign(algorithm, cryptoKey, data);
34
+ }
35
+ async function verifying(publicKey, alg, signature, data) {
36
+ const algorithm = getKeyAlgorithm(alg);
37
+ const cryptoKey = await importPublicKey(publicKey, algorithm);
38
+ return await crypto.subtle.verify(algorithm, cryptoKey, signature, data);
39
+ }
40
+ function pemToBinary(pem) {
41
+ return (0, import_encode.decodeBase64)(pem.replace(/-+(BEGIN|END).*/g, "").replace(/\s/g, ""));
42
+ }
43
+ async function importPrivateKey(key, alg) {
44
+ if (!crypto.subtle || !crypto.subtle.importKey) {
45
+ throw new Error("`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.");
46
+ }
47
+ if (isCryptoKey(key)) {
48
+ if (key.type !== "private") {
49
+ throw new Error(`unexpected non private key: CryptoKey.type is ${key.type}`);
50
+ }
51
+ return key;
52
+ }
53
+ const usages = [import_types2.CryptoKeyUsage.Sign];
54
+ if (typeof key === "object") {
55
+ return await crypto.subtle.importKey("jwk", key, alg, false, usages);
56
+ }
57
+ if (key.includes("PRIVATE")) {
58
+ return await crypto.subtle.importKey("pkcs8", pemToBinary(key), alg, false, usages);
59
+ }
60
+ return await crypto.subtle.importKey("raw", import_utf8.utf8Encoder.encode(key), alg, false, usages);
61
+ }
62
+ async function importPublicKey(key, alg) {
63
+ if (!crypto.subtle || !crypto.subtle.importKey) {
64
+ throw new Error("`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.");
65
+ }
66
+ if (isCryptoKey(key)) {
67
+ if (key.type === "public" || key.type === "secret") {
68
+ return key;
69
+ }
70
+ key = await exportPublicJwkFrom(key);
71
+ }
72
+ if (typeof key === "string" && key.includes("PRIVATE")) {
73
+ const privateKey = await crypto.subtle.importKey("pkcs8", pemToBinary(key), alg, true, [
74
+ import_types2.CryptoKeyUsage.Sign
75
+ ]);
76
+ key = await exportPublicJwkFrom(privateKey);
77
+ }
78
+ const usages = [import_types2.CryptoKeyUsage.Verify];
79
+ if (typeof key === "object") {
80
+ return await crypto.subtle.importKey("jwk", key, alg, false, usages);
81
+ }
82
+ if (key.includes("PUBLIC")) {
83
+ return await crypto.subtle.importKey("spki", pemToBinary(key), alg, false, usages);
84
+ }
85
+ return await crypto.subtle.importKey("raw", import_utf8.utf8Encoder.encode(key), alg, false, usages);
86
+ }
87
+ async function exportPublicJwkFrom(privateKey) {
88
+ if (privateKey.type !== "private") {
89
+ throw new Error(`unexpected key type: ${privateKey.type}`);
90
+ }
91
+ if (!privateKey.extractable) {
92
+ throw new Error("unexpected private key is unextractable");
93
+ }
94
+ const jwk = await crypto.subtle.exportKey("jwk", privateKey);
95
+ const { kty } = jwk;
96
+ const { alg, e, n } = jwk;
97
+ const { crv, x, y } = jwk;
98
+ return { kty, alg, e, n, crv, x, y, key_ops: [import_types2.CryptoKeyUsage.Verify] };
99
+ }
100
+ function getKeyAlgorithm(name) {
101
+ switch (name) {
102
+ case "HS256":
103
+ return {
104
+ name: "HMAC",
105
+ hash: {
106
+ name: "SHA-256"
107
+ }
108
+ };
109
+ case "HS384":
110
+ return {
111
+ name: "HMAC",
112
+ hash: {
113
+ name: "SHA-384"
114
+ }
115
+ };
116
+ case "HS512":
117
+ return {
118
+ name: "HMAC",
119
+ hash: {
120
+ name: "SHA-512"
121
+ }
122
+ };
123
+ case "RS256":
124
+ return {
125
+ name: "RSASSA-PKCS1-v1_5",
126
+ hash: {
127
+ name: "SHA-256"
128
+ }
129
+ };
130
+ case "RS384":
131
+ return {
132
+ name: "RSASSA-PKCS1-v1_5",
133
+ hash: {
134
+ name: "SHA-384"
135
+ }
136
+ };
137
+ case "RS512":
138
+ return {
139
+ name: "RSASSA-PKCS1-v1_5",
140
+ hash: {
141
+ name: "SHA-512"
142
+ }
143
+ };
144
+ case "PS256":
145
+ return {
146
+ name: "RSA-PSS",
147
+ hash: {
148
+ name: "SHA-256"
149
+ },
150
+ saltLength: 32
151
+ };
152
+ case "PS384":
153
+ return {
154
+ name: "RSA-PSS",
155
+ hash: {
156
+ name: "SHA-384"
157
+ },
158
+ saltLength: 48
159
+ };
160
+ case "PS512":
161
+ return {
162
+ name: "RSA-PSS",
163
+ hash: {
164
+ name: "SHA-512"
165
+ },
166
+ saltLength: 64
167
+ };
168
+ case "ES256":
169
+ return {
170
+ name: "ECDSA",
171
+ hash: {
172
+ name: "SHA-256"
173
+ },
174
+ namedCurve: "P-256"
175
+ };
176
+ case "ES384":
177
+ return {
178
+ name: "ECDSA",
179
+ hash: {
180
+ name: "SHA-384"
181
+ },
182
+ namedCurve: "P-384"
183
+ };
184
+ case "ES512":
185
+ return {
186
+ name: "ECDSA",
187
+ hash: {
188
+ name: "SHA-512"
189
+ },
190
+ namedCurve: "P-521"
191
+ };
192
+ case "EdDSA":
193
+ return {
194
+ name: "Ed25519",
195
+ namedCurve: "Ed25519"
196
+ };
197
+ default:
198
+ throw new import_types.JwtAlgorithmNotImplemented(name);
199
+ }
200
+ }
201
+ function isCryptoKey(key) {
202
+ const runtime = (0, import_helper.getRuntimeKey)();
203
+ if (runtime === "node" && !!crypto.webcrypto) {
204
+ return key instanceof crypto.webcrypto.CryptoKey;
205
+ }
206
+ return key instanceof CryptoKey;
207
+ }
208
+ // Annotate the CommonJS export names for ESM import in node:
209
+ 0 && (module.exports = {
210
+ signing,
211
+ verifying
212
+ });
@@ -19,91 +19,40 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var jwt_exports = {};
20
20
  __export(jwt_exports, {
21
21
  decode: () => decode,
22
+ isTokenHeader: () => isTokenHeader,
22
23
  sign: () => sign,
23
24
  verify: () => verify
24
25
  });
25
26
  module.exports = __toCommonJS(jwt_exports);
26
27
  var import_encode = require("../../utils/encode");
28
+ var import_jwa = require("./jwa");
29
+ var import_jws = require("./jws");
27
30
  var import_types = require("./types");
28
31
  var import_types2 = require("./types");
29
- var CryptoKeyFormat = /* @__PURE__ */ ((CryptoKeyFormat2) => {
30
- CryptoKeyFormat2["RAW"] = "raw";
31
- CryptoKeyFormat2["PKCS8"] = "pkcs8";
32
- CryptoKeyFormat2["SPKI"] = "spki";
33
- CryptoKeyFormat2["JWK"] = "jwk";
34
- return CryptoKeyFormat2;
35
- })(CryptoKeyFormat || {});
36
- var CryptoKeyUsage = /* @__PURE__ */ ((CryptoKeyUsage2) => {
37
- CryptoKeyUsage2["Ecrypt"] = "encrypt";
38
- CryptoKeyUsage2["Decrypt"] = "decrypt";
39
- CryptoKeyUsage2["Sign"] = "sign";
40
- CryptoKeyUsage2["Verify"] = "verify";
41
- CryptoKeyUsage2["Deriverkey"] = "deriveKey";
42
- CryptoKeyUsage2["DeriveBits"] = "deriveBits";
43
- CryptoKeyUsage2["WrapKey"] = "wrapKey";
44
- CryptoKeyUsage2["UnwrapKey"] = "unwrapKey";
45
- return CryptoKeyUsage2;
46
- })(CryptoKeyUsage || {});
47
- const utf8Encoder = new TextEncoder();
48
- const utf8Decoder = new TextDecoder();
49
- const encodeJwtPart = (part) => (0, import_encode.encodeBase64Url)(utf8Encoder.encode(JSON.stringify(part))).replace(/=/g, "");
32
+ var import_utf8 = require("./utf8");
33
+ const encodeJwtPart = (part) => (0, import_encode.encodeBase64Url)(import_utf8.utf8Encoder.encode(JSON.stringify(part))).replace(/=/g, "");
50
34
  const encodeSignaturePart = (buf) => (0, import_encode.encodeBase64Url)(buf).replace(/=/g, "");
51
- const decodeJwtPart = (part) => JSON.parse(utf8Decoder.decode((0, import_encode.decodeBase64Url)(part)));
52
- const param = (name) => {
53
- switch (name.toUpperCase()) {
54
- case "HS256":
55
- return {
56
- name: "HMAC",
57
- hash: {
58
- name: "SHA-256"
59
- }
60
- };
61
- case "HS384":
62
- return {
63
- name: "HMAC",
64
- hash: {
65
- name: "SHA-384"
66
- }
67
- };
68
- case "HS512":
69
- return {
70
- name: "HMAC",
71
- hash: {
72
- name: "SHA-512"
73
- }
74
- };
75
- default:
76
- throw new import_types2.JwtAlgorithmNotImplemented(name);
77
- }
78
- };
79
- const signing = async (data, secret, alg = "HS256") => {
80
- if (!crypto.subtle || !crypto.subtle.importKey) {
81
- throw new Error("`crypto.subtle.importKey` is undefined. JWT auth middleware requires it.");
82
- }
83
- const utf8Encoder2 = new TextEncoder();
84
- const cryptoKey = await crypto.subtle.importKey(
85
- "raw" /* RAW */,
86
- utf8Encoder2.encode(secret),
87
- param(alg),
88
- false,
89
- ["sign" /* Sign */]
90
- );
91
- return await crypto.subtle.sign(param(alg), cryptoKey, utf8Encoder2.encode(data));
92
- };
93
- const sign = async (payload, secret, alg = "HS256") => {
35
+ const decodeJwtPart = (part) => JSON.parse(import_utf8.utf8Decoder.decode((0, import_encode.decodeBase64Url)(part)));
36
+ function isTokenHeader(obj) {
37
+ return typeof obj === "object" && obj !== null && "alg" in obj && Object.values(import_jwa.AlgorithmTypes).includes(obj.alg) && "typ" in obj && obj.typ === "JWT";
38
+ }
39
+ const sign = async (payload, privateKey, alg = "HS256") => {
94
40
  const encodedPayload = encodeJwtPart(payload);
95
41
  const encodedHeader = encodeJwtPart({ alg, typ: "JWT" });
96
42
  const partialToken = `${encodedHeader}.${encodedPayload}`;
97
- const signaturePart = await signing(partialToken, secret, alg);
43
+ const signaturePart = await (0, import_jws.signing)(privateKey, alg, import_utf8.utf8Encoder.encode(partialToken));
98
44
  const signature = encodeSignaturePart(signaturePart);
99
45
  return `${partialToken}.${signature}`;
100
46
  };
101
- const verify = async (token, secret, alg = "HS256") => {
47
+ const verify = async (token, publicKey, alg = "HS256") => {
102
48
  const tokenParts = token.split(".");
103
49
  if (tokenParts.length !== 3) {
104
50
  throw new import_types2.JwtTokenInvalid(token);
105
51
  }
106
- const { payload } = decode(token);
52
+ const { header, payload } = decode(token);
53
+ if (!isTokenHeader(header)) {
54
+ throw new import_types.JwtHeaderInvalid(header);
55
+ }
107
56
  const now = Math.floor(Date.now() / 1e3);
108
57
  if (payload.nbf && payload.nbf > now) {
109
58
  throw new import_types2.JwtTokenNotBefore(token);
@@ -112,12 +61,16 @@ const verify = async (token, secret, alg = "HS256") => {
112
61
  throw new import_types2.JwtTokenExpired(token);
113
62
  }
114
63
  if (payload.iat && now < payload.iat) {
115
- throw new import_types.JwtTokenIssuedAt(now, payload.iat);
64
+ throw new import_types2.JwtTokenIssuedAt(now, payload.iat);
116
65
  }
117
- const signaturePart = tokenParts.slice(0, 2).join(".");
118
- const signature = await signing(signaturePart, secret, alg);
119
- const encodedSignature = encodeSignaturePart(signature);
120
- if (encodedSignature !== tokenParts[2]) {
66
+ const headerPayload = token.substring(0, token.lastIndexOf("."));
67
+ const verified = await (0, import_jws.verifying)(
68
+ publicKey,
69
+ alg,
70
+ (0, import_encode.decodeBase64Url)(tokenParts[2]),
71
+ import_utf8.utf8Encoder.encode(headerPayload)
72
+ );
73
+ if (!verified) {
121
74
  throw new import_types2.JwtTokenSignatureMismatched(token);
122
75
  }
123
76
  return payload;
@@ -138,6 +91,7 @@ const decode = (token) => {
138
91
  // Annotate the CommonJS export names for ESM import in node:
139
92
  0 && (module.exports = {
140
93
  decode,
94
+ isTokenHeader,
141
95
  sign,
142
96
  verify
143
97
  });
@@ -18,8 +18,9 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var types_exports = {};
20
20
  __export(types_exports, {
21
- AlgorithmTypes: () => AlgorithmTypes,
21
+ CryptoKeyUsage: () => CryptoKeyUsage,
22
22
  JwtAlgorithmNotImplemented: () => JwtAlgorithmNotImplemented,
23
+ JwtHeaderInvalid: () => JwtHeaderInvalid,
23
24
  JwtTokenExpired: () => JwtTokenExpired,
24
25
  JwtTokenInvalid: () => JwtTokenInvalid,
25
26
  JwtTokenIssuedAt: () => JwtTokenIssuedAt,
@@ -57,22 +58,34 @@ class JwtTokenIssuedAt extends Error {
57
58
  this.name = "JwtTokenIssuedAt";
58
59
  }
59
60
  }
61
+ class JwtHeaderInvalid extends Error {
62
+ constructor(header) {
63
+ super(`jwt header is invalid: ${JSON.stringify(header)}`);
64
+ this.name = "JwtHeaderInvalid";
65
+ }
66
+ }
60
67
  class JwtTokenSignatureMismatched extends Error {
61
68
  constructor(token) {
62
69
  super(`token(${token}) signature mismatched`);
63
70
  this.name = "JwtTokenSignatureMismatched";
64
71
  }
65
72
  }
66
- var AlgorithmTypes = /* @__PURE__ */ ((AlgorithmTypes2) => {
67
- AlgorithmTypes2["HS256"] = "HS256";
68
- AlgorithmTypes2["HS384"] = "HS384";
69
- AlgorithmTypes2["HS512"] = "HS512";
70
- return AlgorithmTypes2;
71
- })(AlgorithmTypes || {});
73
+ var CryptoKeyUsage = /* @__PURE__ */ ((CryptoKeyUsage2) => {
74
+ CryptoKeyUsage2["Encrypt"] = "encrypt";
75
+ CryptoKeyUsage2["Decrypt"] = "decrypt";
76
+ CryptoKeyUsage2["Sign"] = "sign";
77
+ CryptoKeyUsage2["Verify"] = "verify";
78
+ CryptoKeyUsage2["DeriveKey"] = "deriveKey";
79
+ CryptoKeyUsage2["DeriveBits"] = "deriveBits";
80
+ CryptoKeyUsage2["WrapKey"] = "wrapKey";
81
+ CryptoKeyUsage2["UnwrapKey"] = "unwrapKey";
82
+ return CryptoKeyUsage2;
83
+ })(CryptoKeyUsage || {});
72
84
  // Annotate the CommonJS export names for ESM import in node:
73
85
  0 && (module.exports = {
74
- AlgorithmTypes,
86
+ CryptoKeyUsage,
75
87
  JwtAlgorithmNotImplemented,
88
+ JwtHeaderInvalid,
76
89
  JwtTokenExpired,
77
90
  JwtTokenInvalid,
78
91
  JwtTokenIssuedAt,
@@ -0,0 +1,31 @@
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 utf8_exports = {};
20
+ __export(utf8_exports, {
21
+ utf8Decoder: () => utf8Decoder,
22
+ utf8Encoder: () => utf8Encoder
23
+ });
24
+ module.exports = __toCommonJS(utf8_exports);
25
+ const utf8Encoder = new TextEncoder();
26
+ const utf8Decoder = new TextDecoder();
27
+ // Annotate the CommonJS export names for ESM import in node:
28
+ 0 && (module.exports = {
29
+ utf8Decoder,
30
+ utf8Encoder
31
+ });
@@ -28,30 +28,14 @@ const validator = (target, validationFunc) => {
28
28
  return async (c, next) => {
29
29
  let value = {};
30
30
  const contentType = c.req.header("Content-Type");
31
- const bodyTypes = ["text", "arrayBuffer", "blob"];
32
31
  switch (target) {
33
32
  case "json":
34
33
  if (!contentType || !contentType.startsWith("application/json")) {
35
34
  const message = `Invalid HTTP header: Content-Type=${contentType}`;
36
35
  throw new import_http_exception.HTTPException(400, { message });
37
36
  }
38
- if (c.req.bodyCache.json) {
39
- value = await c.req.bodyCache.json;
40
- break;
41
- }
42
37
  try {
43
- let arrayBuffer = void 0;
44
- for (const type of bodyTypes) {
45
- const body = c.req.bodyCache[type];
46
- if (body) {
47
- arrayBuffer = await new Response(await body).arrayBuffer();
48
- break;
49
- }
50
- }
51
- arrayBuffer ??= await c.req.raw.arrayBuffer();
52
- value = await new Response(arrayBuffer).json();
53
- c.req.bodyCache.json = value;
54
- c.req.bodyCache.arrayBuffer = arrayBuffer;
38
+ value = await c.req.json();
55
39
  } catch {
56
40
  const message = "Malformed JSON in request body";
57
41
  throw new import_http_exception.HTTPException(400, { message });
@@ -66,15 +50,7 @@ const validator = (target, validationFunc) => {
66
50
  break;
67
51
  }
68
52
  try {
69
- let arrayBuffer = void 0;
70
- for (const type of bodyTypes) {
71
- const body = c.req.bodyCache[type];
72
- if (body) {
73
- arrayBuffer = await new Response(await body).arrayBuffer();
74
- break;
75
- }
76
- }
77
- arrayBuffer ??= await c.req.arrayBuffer();
53
+ const arrayBuffer = await c.req.arrayBuffer();
78
54
  const formData = await (0, import_buffer.bufferToFormData)(arrayBuffer, contentType);
79
55
  const form = {};
80
56
  formData.forEach((value2, key) => {
@@ -82,7 +58,6 @@ const validator = (target, validationFunc) => {
82
58
  });
83
59
  value = form;
84
60
  c.req.bodyCache.formData = formData;
85
- c.req.bodyCache.arrayBuffer = arrayBuffer;
86
61
  } catch (e) {
87
62
  let message = "Malformed FormData request.";
88
63
  message += e instanceof Error ? ` ${e.message}` : ` ${String(e)}`;
@@ -5,8 +5,8 @@ import { getExtension } from "../../utils/mime.js";
5
5
  import { SSG_DISABLED_RESPONSE, SSG_CONTEXT } from "./middleware.js";
6
6
  import { joinPaths, dirname, filterStaticGenerateRoutes } from "./utils.js";
7
7
  var DEFAULT_CONCURRENCY = 2;
8
- var generateFilePath = (routePath, outDir, mimeType) => {
9
- const extension = determineExtension(mimeType);
8
+ var generateFilePath = (routePath, outDir, mimeType, extensionMap) => {
9
+ const extension = determineExtension(mimeType, extensionMap);
10
10
  if (routePath.endsWith(`.${extension}`)) {
11
11
  return joinPaths(outDir, routePath);
12
12
  }
@@ -32,17 +32,18 @@ var parseResponseContent = async (response) => {
32
32
  );
33
33
  }
34
34
  };
35
- var determineExtension = (mimeType) => {
36
- switch (mimeType) {
37
- case "text/html":
38
- return "html";
39
- case "text/xml":
40
- case "application/xml":
41
- return "xml";
42
- default: {
43
- return getExtension(mimeType) || "html";
44
- }
35
+ var defaultExtensionMap = {
36
+ "text/html": "html",
37
+ "text/xml": "xml",
38
+ "application/xml": "xml",
39
+ "application/yaml": "yaml"
40
+ };
41
+ var determineExtension = (mimeType, userExtensionMap) => {
42
+ const extensionMap = userExtensionMap || defaultExtensionMap;
43
+ if (mimeType in extensionMap) {
44
+ return extensionMap[mimeType];
45
45
  }
46
+ return getExtension(mimeType) || "html";
46
47
  };
47
48
  var fetchRoutesContent = function* (app, beforeRequestHook, afterResponseHook, concurrency) {
48
49
  const baseURL = "http://localhost";
@@ -119,13 +120,13 @@ var isDynamicRoute = (path) => {
119
120
  return path.split("/").some((segment) => segment.startsWith(":") || segment.includes("*"));
120
121
  };
121
122
  var createdDirs = /* @__PURE__ */ new Set();
122
- var saveContentToFile = async (data, fsModule, outDir) => {
123
+ var saveContentToFile = async (data, fsModule, outDir, extensionMap) => {
123
124
  const awaitedData = await data;
124
125
  if (!awaitedData) {
125
126
  return;
126
127
  }
127
128
  const { routePath, content, mimeType } = awaitedData;
128
- const filePath = generateFilePath(routePath, outDir, mimeType);
129
+ const filePath = generateFilePath(routePath, outDir, mimeType, extensionMap);
129
130
  const dirPath = dirname(filePath);
130
131
  if (!createdDirs.has(dirPath)) {
131
132
  await fsModule.mkdir(dirPath, { recursive: true });
@@ -182,6 +183,7 @@ var toSSG = async (app, fs, options) => {
182
183
  return result;
183
184
  };
184
185
  export {
186
+ defaultExtensionMap,
185
187
  fetchRoutesContent,
186
188
  saveContentToFile,
187
189
  toSSG
@@ -15,6 +15,7 @@ import {
15
15
  useMemo,
16
16
  useLayoutEffect,
17
17
  useReducer,
18
+ useId,
18
19
  useDebugValue
19
20
  } from "../hooks/index.js";
20
21
  import { Suspense, ErrorBoundary } from "./components.js";
@@ -55,6 +56,7 @@ var dom_default = {
55
56
  useMemo,
56
57
  useLayoutEffect,
57
58
  useReducer,
59
+ useId,
58
60
  useDebugValue,
59
61
  Suspense,
60
62
  ErrorBoundary,
@@ -84,6 +86,7 @@ export {
84
86
  useDebugValue,
85
87
  useDeferredValue,
86
88
  useEffect,
89
+ useId,
87
90
  useLayoutEffect,
88
91
  useMemo,
89
92
  useReducer,
@@ -258,6 +258,8 @@ var useMemo = (factory, deps) => {
258
258
  }
259
259
  return memoArray[hookIndex][0];
260
260
  };
261
+ var idCounter = 0;
262
+ var useId = () => useMemo(() => `:r${(idCounter++).toString(32)}:`, []);
261
263
  var useDebugValue = (_value, _formatter) => {
262
264
  };
263
265
  export {
@@ -269,6 +271,7 @@ export {
269
271
  useDebugValue,
270
272
  useDeferredValue,
271
273
  useEffect,
274
+ useId,
272
275
  useLayoutEffect,
273
276
  useMemo,
274
277
  useReducer,
package/dist/jsx/index.js CHANGED
@@ -16,6 +16,7 @@ import {
16
16
  useMemo,
17
17
  useLayoutEffect,
18
18
  useReducer,
19
+ useId,
19
20
  useDebugValue
20
21
  } from "./hooks/index.js";
21
22
  import { Suspense } from "./streaming.js";
@@ -34,6 +35,7 @@ var jsx_default = {
34
35
  useRef,
35
36
  useCallback,
36
37
  useReducer,
38
+ useId,
37
39
  useDebugValue,
38
40
  use,
39
41
  startTransition,
@@ -64,6 +66,7 @@ export {
64
66
  useDebugValue,
65
67
  useDeferredValue,
66
68
  useEffect,
69
+ useId,
67
70
  useLayoutEffect,
68
71
  useMemo,
69
72
  useReducer,
@@ -21,25 +21,38 @@ var auth = (req) => {
21
21
  return { username: userPass[1], password: userPass[2] };
22
22
  };
23
23
  var basicAuth = (options, ...users) => {
24
- if (!options) {
25
- throw new Error('basic auth middleware requires options for "username and password"');
24
+ const usernamePasswordInOptions = "username" in options && "password" in options;
25
+ const verifyUserInOptions = "verifyUser" in options;
26
+ if (!(usernamePasswordInOptions || verifyUserInOptions)) {
27
+ throw new Error(
28
+ 'basic auth middleware requires options for "username and password" or "verifyUser"'
29
+ );
26
30
  }
27
31
  if (!options.realm) {
28
32
  options.realm = "Secure Area";
29
33
  }
30
- users.unshift({ username: options.username, password: options.password });
34
+ if (usernamePasswordInOptions) {
35
+ users.unshift({ username: options.username, password: options.password });
36
+ }
31
37
  return async function basicAuth2(ctx, next) {
32
38
  const requestUser = auth(ctx.req);
33
39
  if (requestUser) {
34
- for (const user of users) {
35
- const [usernameEqual, passwordEqual] = await Promise.all([
36
- timingSafeEqual(user.username, requestUser.username, options.hashFunction),
37
- timingSafeEqual(user.password, requestUser.password, options.hashFunction)
38
- ]);
39
- if (usernameEqual && passwordEqual) {
40
+ if (verifyUserInOptions) {
41
+ if (await options.verifyUser(requestUser.username, requestUser.password, ctx)) {
40
42
  await next();
41
43
  return;
42
44
  }
45
+ } else {
46
+ for (const user of users) {
47
+ const [usernameEqual, passwordEqual] = await Promise.all([
48
+ timingSafeEqual(user.username, requestUser.username, options.hashFunction),
49
+ timingSafeEqual(user.password, requestUser.password, options.hashFunction)
50
+ ]);
51
+ if (usernameEqual && passwordEqual) {
52
+ await next();
53
+ return;
54
+ }
55
+ }
43
56
  }
44
57
  }
45
58
  const res = new Response("Unauthorized", {