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.
Files changed (101) hide show
  1. package/dist/adapter/aws-lambda/handler.js +0 -2
  2. package/dist/cjs/adapter/aws-lambda/handler.js +0 -8
  3. package/dist/cjs/helper/accepts/accepts.js +4 -26
  4. package/dist/cjs/helper/factory/index.js +6 -2
  5. package/dist/cjs/helper/proxy/index.js +75 -0
  6. package/dist/cjs/middleware/combine/index.js +10 -3
  7. package/dist/cjs/middleware/etag/digest.js +3 -8
  8. package/dist/cjs/middleware/etag/index.js +18 -2
  9. package/dist/cjs/middleware/jwk/index.js +28 -0
  10. package/dist/cjs/middleware/jwk/jwk.js +124 -0
  11. package/dist/cjs/middleware/language/index.js +36 -0
  12. package/dist/cjs/middleware/language/language.js +210 -0
  13. package/dist/cjs/middleware/logger/index.js +2 -3
  14. package/dist/cjs/request.js +1 -1
  15. package/dist/cjs/router/linear-router/router.js +3 -1
  16. package/dist/cjs/router/trie-router/node.js +24 -11
  17. package/dist/cjs/utils/accept.js +86 -0
  18. package/dist/cjs/utils/jwt/index.js +1 -1
  19. package/dist/cjs/utils/jwt/jwt.js +56 -3
  20. package/dist/cjs/utils/jwt/types.js +8 -0
  21. package/dist/cjs/utils/url.js +10 -25
  22. package/dist/helper/accepts/accepts.js +2 -23
  23. package/dist/helper/factory/index.js +6 -2
  24. package/dist/helper/proxy/index.js +52 -0
  25. package/dist/middleware/combine/index.js +10 -3
  26. package/dist/middleware/etag/digest.js +3 -8
  27. package/dist/middleware/etag/index.js +18 -2
  28. package/dist/middleware/jwk/index.js +5 -0
  29. package/dist/middleware/jwk/jwk.js +101 -0
  30. package/dist/middleware/language/index.js +15 -0
  31. package/dist/middleware/language/language.js +178 -0
  32. package/dist/middleware/logger/index.js +2 -3
  33. package/dist/request.js +1 -1
  34. package/dist/router/linear-router/router.js +3 -1
  35. package/dist/router/trie-router/node.js +24 -11
  36. package/dist/types/adapter/cloudflare-pages/handler.d.ts +1 -1
  37. package/dist/types/adapter/cloudflare-workers/websocket.d.ts +1 -1
  38. package/dist/types/adapter/lambda-edge/handler.d.ts +2 -2
  39. package/dist/types/client/types.d.ts +7 -8
  40. package/dist/types/compose.d.ts +11 -1
  41. package/dist/types/context.d.ts +31 -21
  42. package/dist/types/helper/accepts/accepts.d.ts +0 -1
  43. package/dist/types/helper/adapter/index.d.ts +2 -2
  44. package/dist/types/helper/conninfo/types.d.ts +2 -2
  45. package/dist/types/helper/css/common.d.ts +6 -1
  46. package/dist/types/helper/factory/index.d.ts +289 -12
  47. package/dist/types/helper/proxy/index.d.ts +54 -0
  48. package/dist/types/helper/ssg/ssg.d.ts +1 -1
  49. package/dist/types/helper/websocket/index.d.ts +1 -2
  50. package/dist/types/hono-base.d.ts +18 -15
  51. package/dist/types/hono.d.ts +1 -1
  52. package/dist/types/jsx/base.d.ts +4 -1
  53. package/dist/types/jsx/dom/hooks/index.d.ts +9 -3
  54. package/dist/types/jsx/dom/index.d.ts +28 -7
  55. package/dist/types/jsx/dom/intrinsic-element/components.d.ts +6 -6
  56. package/dist/types/jsx/dom/render.d.ts +28 -4
  57. package/dist/types/jsx/dom/server.d.ts +28 -7
  58. package/dist/types/jsx/hooks/index.d.ts +20 -5
  59. package/dist/types/jsx/index.d.ts +28 -7
  60. package/dist/types/jsx/intrinsic-element/components.d.ts +4 -4
  61. package/dist/types/jsx/intrinsic-elements.d.ts +46 -46
  62. package/dist/types/middleware/compress/index.d.ts +4 -1
  63. package/dist/types/middleware/etag/digest.d.ts +1 -1
  64. package/dist/types/middleware/etag/index.d.ts +4 -0
  65. package/dist/types/middleware/jwk/index.d.ts +1 -0
  66. package/dist/types/middleware/jwk/jwk.d.ts +40 -0
  67. package/dist/types/middleware/language/index.d.ts +7 -0
  68. package/dist/types/middleware/language/language.d.ts +102 -0
  69. package/dist/types/middleware/secure-headers/permissions-policy.d.ts +3 -3
  70. package/dist/types/middleware/secure-headers/secure-headers.d.ts +1 -1
  71. package/dist/types/preset/quick.d.ts +1 -1
  72. package/dist/types/preset/tiny.d.ts +1 -1
  73. package/dist/types/request.d.ts +5 -3
  74. package/dist/types/router/linear-router/router.d.ts +0 -1
  75. package/dist/types/router/pattern-router/router.d.ts +0 -1
  76. package/dist/types/router/reg-exp-router/node.d.ts +4 -2
  77. package/dist/types/router/reg-exp-router/router.d.ts +0 -1
  78. package/dist/types/router/reg-exp-router/trie.d.ts +5 -2
  79. package/dist/types/router/smart-router/router.d.ts +0 -1
  80. package/dist/types/router/trie-router/node.d.ts +6 -2
  81. package/dist/types/router/trie-router/router.d.ts +0 -1
  82. package/dist/types/router.d.ts +20 -2
  83. package/dist/types/types.d.ts +2002 -111
  84. package/dist/types/utils/accept.d.ts +11 -0
  85. package/dist/types/utils/cookie.d.ts +4 -4
  86. package/dist/types/utils/headers.d.ts +3 -3
  87. package/dist/types/utils/html.d.ts +6 -2
  88. package/dist/types/utils/jwt/index.d.ts +4 -0
  89. package/dist/types/utils/jwt/jws.d.ts +4 -1
  90. package/dist/types/utils/jwt/jwt.d.ts +8 -2
  91. package/dist/types/utils/jwt/types.d.ts +4 -0
  92. package/dist/types/utils/mime.d.ts +2 -2
  93. package/dist/types/utils/stream.d.ts +0 -4
  94. package/dist/types/utils/url.d.ts +16 -2
  95. package/dist/types/validator/validator.d.ts +18 -6
  96. package/dist/utils/accept.js +63 -0
  97. package/dist/utils/jwt/index.js +2 -2
  98. package/dist/utils/jwt/jwt.js +54 -2
  99. package/dist/utils/jwt/types.js +7 -0
  100. package/dist/utils/url.js +10 -25
  101. package/package.json +24 -3
@@ -0,0 +1,11 @@
1
+ export interface Accept {
2
+ type: string;
3
+ params: Record<string, string>;
4
+ q: number;
5
+ }
6
+ /**
7
+ * Parse an Accept header into an array of objects with type, parameters, and quality score.
8
+ * @param acceptHeader The Accept header string
9
+ * @returns An array of parsed Accept values
10
+ */
11
+ export declare const parseAccept: (acceptHeader: string) => Accept[];
@@ -16,7 +16,7 @@ type SecureCookieConstraint = {
16
16
  };
17
17
  type HostCookieConstraint = {
18
18
  secure: true;
19
- path: '/';
19
+ path: "/";
20
20
  domain?: undefined;
21
21
  };
22
22
  export type CookieOptions = {
@@ -27,12 +27,12 @@ export type CookieOptions = {
27
27
  path?: string;
28
28
  secure?: boolean;
29
29
  signingSecret?: string;
30
- sameSite?: 'Strict' | 'Lax' | 'None' | 'strict' | 'lax' | 'none';
30
+ sameSite?: "Strict" | "Lax" | "None" | "strict" | "lax" | "none";
31
31
  partitioned?: boolean;
32
- priority?: 'Low' | 'Medium' | 'High';
32
+ priority?: "Low" | "Medium" | "High";
33
33
  prefix?: CookiePrefixOptions;
34
34
  } & PartitionedCookieConstraint;
35
- export type CookiePrefixOptions = 'host' | 'secure';
35
+ export type CookiePrefixOptions = "host" | "secure";
36
36
  export type CookieConstraint<Name> = Name extends `__Secure-${string}` ? CookieOptions & SecureCookieConstraint : Name extends `__Host-${string}` ? CookieOptions & HostCookieConstraint : CookieOptions;
37
37
  export declare const parse: (cookie: string, name?: string) => Cookie;
38
38
  export declare const parseSigned: (cookie: string, secret: string | BufferSource, name?: string) => Promise<SignedCookie>;
@@ -2,7 +2,7 @@
2
2
  * @module
3
3
  * HTTP Headers utility.
4
4
  */
5
- export type RequestHeader = 'A-IM' | 'Accept' | 'Accept-Additions' | 'Accept-CH' | 'Accept-Charset' | 'Accept-Datetime' | 'Accept-Encoding' | 'Accept-Features' | 'Accept-Language' | 'Accept-Patch' | 'Accept-Post' | 'Accept-Ranges' | 'Accept-Signature' | 'Access-Control' | 'Access-Control-Allow-Credentials' | 'Access-Control-Allow-Headers' | 'Access-Control-Allow-Methods' | 'Access-Control-Allow-Origin' | 'Access-Control-Expose-Headers' | 'Access-Control-Max-Age' | 'Access-Control-Request-Headers' | 'Access-Control-Request-Method' | 'Age' | 'Allow' | 'ALPN' | 'Alt-Svc' | 'Alt-Used' | 'Alternates' | 'AMP-Cache-Transform' | 'Apply-To-Redirect-Ref' | 'Authentication-Control' | 'Authentication-Info' | 'Authorization' | 'Available-Dictionary' | 'C-Ext' | 'C-Man' | 'C-Opt' | 'C-PEP' | 'C-PEP-Info' | 'Cache-Control' | 'Cache-Status' | 'Cal-Managed-ID' | 'CalDAV-Timezones' | 'Capsule-Protocol' | 'CDN-Cache-Control' | 'CDN-Loop' | 'Cert-Not-After' | 'Cert-Not-Before' | 'Clear-Site-Data' | 'Client-Cert' | 'Client-Cert-Chain' | 'Close' | 'CMCD-Object' | 'CMCD-Request' | 'CMCD-Session' | 'CMCD-Status' | 'CMSD-Dynamic' | 'CMSD-Static' | 'Concealed-Auth-Export' | 'Configuration-Context' | 'Connection' | 'Content-Base' | 'Content-Digest' | 'Content-Disposition' | 'Content-Encoding' | 'Content-ID' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-MD5' | 'Content-Range' | 'Content-Script-Type' | 'Content-Security-Policy' | 'Content-Security-Policy-Report-Only' | 'Content-Style-Type' | 'Content-Type' | 'Content-Version' | 'Cookie' | 'Cookie2' | 'Cross-Origin-Embedder-Policy' | 'Cross-Origin-Embedder-Policy-Report-Only' | 'Cross-Origin-Opener-Policy' | 'Cross-Origin-Opener-Policy-Report-Only' | 'Cross-Origin-Resource-Policy' | 'CTA-Common-Access-Token' | 'DASL' | 'Date' | 'DAV' | 'Default-Style' | 'Delta-Base' | 'Deprecation' | 'Depth' | 'Derived-From' | 'Destination' | 'Differential-ID' | 'Dictionary-ID' | 'Digest' | 'DPoP' | 'DPoP-Nonce' | 'Early-Data' | 'EDIINT-Features' | 'ETag' | 'Expect' | 'Expect-CT' | 'Expires' | 'Ext' | 'Forwarded' | 'From' | 'GetProfile' | 'Hobareg' | 'Host' | 'HTTP2-Settings' | 'If' | 'If-Match' | 'If-Modified-Since' | 'If-None-Match' | 'If-Range' | 'If-Schedule-Tag-Match' | 'If-Unmodified-Since' | 'IM' | 'Include-Referred-Token-Binding-ID' | 'Isolation' | 'Keep-Alive' | 'Label' | 'Last-Event-ID' | 'Last-Modified' | 'Link' | 'Link-Template' | 'Location' | 'Lock-Token' | 'Man' | 'Max-Forwards' | 'Memento-Datetime' | 'Meter' | 'Method-Check' | 'Method-Check-Expires' | 'MIME-Version' | 'Negotiate' | 'NEL' | 'OData-EntityId' | 'OData-Isolation' | 'OData-MaxVersion' | 'OData-Version' | 'Opt' | 'Optional-WWW-Authenticate' | 'Ordering-Type' | 'Origin' | 'Origin-Agent-Cluster' | 'OSCORE' | 'OSLC-Core-Version' | 'Overwrite' | 'P3P' | 'PEP' | 'PEP-Info' | 'Permissions-Policy' | 'PICS-Label' | 'Ping-From' | 'Ping-To' | 'Position' | 'Pragma' | 'Prefer' | 'Preference-Applied' | 'Priority' | 'ProfileObject' | 'Protocol' | 'Protocol-Info' | 'Protocol-Query' | 'Protocol-Request' | 'Proxy-Authenticate' | 'Proxy-Authentication-Info' | 'Proxy-Authorization' | 'Proxy-Features' | 'Proxy-Instruction' | 'Proxy-Status' | 'Public' | 'Public-Key-Pins' | 'Public-Key-Pins-Report-Only' | 'Range' | 'Redirect-Ref' | 'Referer' | 'Referer-Root' | 'Referrer-Policy' | 'Refresh' | 'Repeatability-Client-ID' | 'Repeatability-First-Sent' | 'Repeatability-Request-ID' | 'Repeatability-Result' | 'Replay-Nonce' | 'Reporting-Endpoints' | 'Repr-Digest' | 'Retry-After' | 'Safe' | 'Schedule-Reply' | 'Schedule-Tag' | 'Sec-GPC' | 'Sec-Purpose' | 'Sec-Token-Binding' | 'Sec-WebSocket-Accept' | 'Sec-WebSocket-Extensions' | 'Sec-WebSocket-Key' | 'Sec-WebSocket-Protocol' | 'Sec-WebSocket-Version' | 'Security-Scheme' | 'Server' | 'Server-Timing' | 'Set-Cookie' | 'Set-Cookie2' | 'SetProfile' | 'Signature' | 'Signature-Input' | 'SLUG' | 'SoapAction' | 'Status-URI' | 'Strict-Transport-Security' | 'Sunset' | 'Surrogate-Capability' | 'Surrogate-Control' | 'TCN' | 'TE' | 'Timeout' | 'Timing-Allow-Origin' | 'Topic' | 'Traceparent' | 'Tracestate' | 'Trailer' | 'Transfer-Encoding' | 'TTL' | 'Upgrade' | 'Urgency' | 'URI' | 'Use-As-Dictionary' | 'User-Agent' | 'Variant-Vary' | 'Vary' | 'Via' | 'Want-Content-Digest' | 'Want-Digest' | 'Want-Repr-Digest' | 'Warning' | 'WWW-Authenticate' | 'X-Content-Type-Options' | 'X-Frame-Options';
6
- export type ResponseHeader = 'Access-Control-Allow-Credentials' | 'Access-Control-Allow-Headers' | 'Access-Control-Allow-Methods' | 'Access-Control-Allow-Origin' | 'Access-Control-Expose-Headers' | 'Access-Control-Max-Age' | 'Age' | 'Allow' | 'Cache-Control' | 'Clear-Site-Data' | 'Content-Disposition' | 'Content-Encoding' | 'Content-Language' | 'Content-Length' | 'Content-Location' | 'Content-Range' | 'Content-Security-Policy' | 'Content-Security-Policy-Report-Only' | 'Content-Type' | 'Cookie' | 'Cross-Origin-Embedder-Policy' | 'Cross-Origin-Opener-Policy' | 'Cross-Origin-Resource-Policy' | 'Date' | 'ETag' | 'Expires' | 'Last-Modified' | 'Location' | 'Permissions-Policy' | 'Pragma' | 'Retry-After' | 'Save-Data' | 'Sec-CH-Prefers-Color-Scheme' | 'Sec-CH-Prefers-Reduced-Motion' | 'Sec-CH-UA' | 'Sec-CH-UA-Arch' | 'Sec-CH-UA-Bitness' | 'Sec-CH-UA-Form-Factor' | 'Sec-CH-UA-Full-Version' | 'Sec-CH-UA-Full-Version-List' | 'Sec-CH-UA-Mobile' | 'Sec-CH-UA-Model' | 'Sec-CH-UA-Platform' | 'Sec-CH-UA-Platform-Version' | 'Sec-CH-UA-WoW64' | 'Sec-Fetch-Dest' | 'Sec-Fetch-Mode' | 'Sec-Fetch-Site' | 'Sec-Fetch-User' | 'Sec-GPC' | 'Server' | 'Server-Timing' | 'Service-Worker-Navigation-Preload' | 'Set-Cookie' | 'Strict-Transport-Security' | 'Timing-Allow-Origin' | 'Trailer' | 'Transfer-Encoding' | 'Upgrade' | 'Vary' | 'WWW-Authenticate' | 'Warning' | 'X-Content-Type-Options' | 'X-DNS-Prefetch-Control' | 'X-Frame-Options' | 'X-Permitted-Cross-Domain-Policies' | 'X-Powered-By' | 'X-Robots-Tag' | 'X-XSS-Protection';
7
- export type AcceptHeader = 'Accept' | 'Accept-Charset' | 'Accept-Encoding' | 'Accept-Language' | 'Accept-Patch' | 'Accept-Post' | 'Accept-Ranges';
5
+ export type RequestHeader = "A-IM" | "Accept" | "Accept-Additions" | "Accept-CH" | "Accept-Charset" | "Accept-Datetime" | "Accept-Encoding" | "Accept-Features" | "Accept-Language" | "Accept-Patch" | "Accept-Post" | "Accept-Ranges" | "Accept-Signature" | "Access-Control" | "Access-Control-Allow-Credentials" | "Access-Control-Allow-Headers" | "Access-Control-Allow-Methods" | "Access-Control-Allow-Origin" | "Access-Control-Expose-Headers" | "Access-Control-Max-Age" | "Access-Control-Request-Headers" | "Access-Control-Request-Method" | "Age" | "Allow" | "ALPN" | "Alt-Svc" | "Alt-Used" | "Alternates" | "AMP-Cache-Transform" | "Apply-To-Redirect-Ref" | "Authentication-Control" | "Authentication-Info" | "Authorization" | "Available-Dictionary" | "C-Ext" | "C-Man" | "C-Opt" | "C-PEP" | "C-PEP-Info" | "Cache-Control" | "Cache-Status" | "Cal-Managed-ID" | "CalDAV-Timezones" | "Capsule-Protocol" | "CDN-Cache-Control" | "CDN-Loop" | "Cert-Not-After" | "Cert-Not-Before" | "Clear-Site-Data" | "Client-Cert" | "Client-Cert-Chain" | "Close" | "CMCD-Object" | "CMCD-Request" | "CMCD-Session" | "CMCD-Status" | "CMSD-Dynamic" | "CMSD-Static" | "Concealed-Auth-Export" | "Configuration-Context" | "Connection" | "Content-Base" | "Content-Digest" | "Content-Disposition" | "Content-Encoding" | "Content-ID" | "Content-Language" | "Content-Length" | "Content-Location" | "Content-MD5" | "Content-Range" | "Content-Script-Type" | "Content-Security-Policy" | "Content-Security-Policy-Report-Only" | "Content-Style-Type" | "Content-Type" | "Content-Version" | "Cookie" | "Cookie2" | "Cross-Origin-Embedder-Policy" | "Cross-Origin-Embedder-Policy-Report-Only" | "Cross-Origin-Opener-Policy" | "Cross-Origin-Opener-Policy-Report-Only" | "Cross-Origin-Resource-Policy" | "CTA-Common-Access-Token" | "DASL" | "Date" | "DAV" | "Default-Style" | "Delta-Base" | "Deprecation" | "Depth" | "Derived-From" | "Destination" | "Differential-ID" | "Dictionary-ID" | "Digest" | "DPoP" | "DPoP-Nonce" | "Early-Data" | "EDIINT-Features" | "ETag" | "Expect" | "Expect-CT" | "Expires" | "Ext" | "Forwarded" | "From" | "GetProfile" | "Hobareg" | "Host" | "HTTP2-Settings" | "If" | "If-Match" | "If-Modified-Since" | "If-None-Match" | "If-Range" | "If-Schedule-Tag-Match" | "If-Unmodified-Since" | "IM" | "Include-Referred-Token-Binding-ID" | "Isolation" | "Keep-Alive" | "Label" | "Last-Event-ID" | "Last-Modified" | "Link" | "Link-Template" | "Location" | "Lock-Token" | "Man" | "Max-Forwards" | "Memento-Datetime" | "Meter" | "Method-Check" | "Method-Check-Expires" | "MIME-Version" | "Negotiate" | "NEL" | "OData-EntityId" | "OData-Isolation" | "OData-MaxVersion" | "OData-Version" | "Opt" | "Optional-WWW-Authenticate" | "Ordering-Type" | "Origin" | "Origin-Agent-Cluster" | "OSCORE" | "OSLC-Core-Version" | "Overwrite" | "P3P" | "PEP" | "PEP-Info" | "Permissions-Policy" | "PICS-Label" | "Ping-From" | "Ping-To" | "Position" | "Pragma" | "Prefer" | "Preference-Applied" | "Priority" | "ProfileObject" | "Protocol" | "Protocol-Info" | "Protocol-Query" | "Protocol-Request" | "Proxy-Authenticate" | "Proxy-Authentication-Info" | "Proxy-Authorization" | "Proxy-Features" | "Proxy-Instruction" | "Proxy-Status" | "Public" | "Public-Key-Pins" | "Public-Key-Pins-Report-Only" | "Range" | "Redirect-Ref" | "Referer" | "Referer-Root" | "Referrer-Policy" | "Refresh" | "Repeatability-Client-ID" | "Repeatability-First-Sent" | "Repeatability-Request-ID" | "Repeatability-Result" | "Replay-Nonce" | "Reporting-Endpoints" | "Repr-Digest" | "Retry-After" | "Safe" | "Schedule-Reply" | "Schedule-Tag" | "Sec-GPC" | "Sec-Purpose" | "Sec-Token-Binding" | "Sec-WebSocket-Accept" | "Sec-WebSocket-Extensions" | "Sec-WebSocket-Key" | "Sec-WebSocket-Protocol" | "Sec-WebSocket-Version" | "Security-Scheme" | "Server" | "Server-Timing" | "Set-Cookie" | "Set-Cookie2" | "SetProfile" | "Signature" | "Signature-Input" | "SLUG" | "SoapAction" | "Status-URI" | "Strict-Transport-Security" | "Sunset" | "Surrogate-Capability" | "Surrogate-Control" | "TCN" | "TE" | "Timeout" | "Timing-Allow-Origin" | "Topic" | "Traceparent" | "Tracestate" | "Trailer" | "Transfer-Encoding" | "TTL" | "Upgrade" | "Urgency" | "URI" | "Use-As-Dictionary" | "User-Agent" | "Variant-Vary" | "Vary" | "Via" | "Want-Content-Digest" | "Want-Digest" | "Want-Repr-Digest" | "Warning" | "WWW-Authenticate" | "X-Content-Type-Options" | "X-Frame-Options";
6
+ export type ResponseHeader = "Access-Control-Allow-Credentials" | "Access-Control-Allow-Headers" | "Access-Control-Allow-Methods" | "Access-Control-Allow-Origin" | "Access-Control-Expose-Headers" | "Access-Control-Max-Age" | "Age" | "Allow" | "Cache-Control" | "Clear-Site-Data" | "Content-Disposition" | "Content-Encoding" | "Content-Language" | "Content-Length" | "Content-Location" | "Content-Range" | "Content-Security-Policy" | "Content-Security-Policy-Report-Only" | "Content-Type" | "Cookie" | "Cross-Origin-Embedder-Policy" | "Cross-Origin-Opener-Policy" | "Cross-Origin-Resource-Policy" | "Date" | "ETag" | "Expires" | "Last-Modified" | "Location" | "Permissions-Policy" | "Pragma" | "Retry-After" | "Save-Data" | "Sec-CH-Prefers-Color-Scheme" | "Sec-CH-Prefers-Reduced-Motion" | "Sec-CH-UA" | "Sec-CH-UA-Arch" | "Sec-CH-UA-Bitness" | "Sec-CH-UA-Form-Factor" | "Sec-CH-UA-Full-Version" | "Sec-CH-UA-Full-Version-List" | "Sec-CH-UA-Mobile" | "Sec-CH-UA-Model" | "Sec-CH-UA-Platform" | "Sec-CH-UA-Platform-Version" | "Sec-CH-UA-WoW64" | "Sec-Fetch-Dest" | "Sec-Fetch-Mode" | "Sec-Fetch-Site" | "Sec-Fetch-User" | "Sec-GPC" | "Server" | "Server-Timing" | "Service-Worker-Navigation-Preload" | "Set-Cookie" | "Strict-Transport-Security" | "Timing-Allow-Origin" | "Trailer" | "Transfer-Encoding" | "Upgrade" | "Vary" | "WWW-Authenticate" | "Warning" | "X-Content-Type-Options" | "X-DNS-Prefetch-Control" | "X-Frame-Options" | "X-Permitted-Cross-Domain-Policies" | "X-Powered-By" | "X-Robots-Tag" | "X-XSS-Protection";
7
+ export type AcceptHeader = "Accept" | "Accept-Charset" | "Accept-Encoding" | "Accept-Language" | "Accept-Patch" | "Accept-Post" | "Accept-Ranges";
8
8
  export type CustomHeader = string & {};
@@ -8,7 +8,9 @@ export declare const HtmlEscapedCallbackPhase: {
8
8
  readonly Stream: 3;
9
9
  };
10
10
  type HtmlEscapedCallbackOpts = {
11
- buffer?: [string];
11
+ buffer?: [
12
+ string
13
+ ];
12
14
  phase: (typeof HtmlEscapedCallbackPhase)[keyof typeof HtmlEscapedCallbackPhase];
13
15
  context: Readonly<object>;
14
16
  };
@@ -40,5 +42,7 @@ export declare const raw: (value: unknown, callbacks?: HtmlEscapedCallback[]) =>
40
42
  export declare const stringBufferToString: (buffer: StringBuffer, callbacks: HtmlEscapedCallback[] | undefined) => Promise<HtmlEscapedString>;
41
43
  export declare const escapeToBuffer: (str: string, buffer: StringBuffer) => void;
42
44
  export declare const resolveCallbackSync: (str: string | HtmlEscapedString) => string;
43
- export declare const resolveCallback: (str: string | HtmlEscapedString | Promise<string>, phase: (typeof HtmlEscapedCallbackPhase)[keyof typeof HtmlEscapedCallbackPhase], preserveCallbacks: boolean, context: object, buffer?: [string]) => Promise<string>;
45
+ export declare const resolveCallback: (str: string | HtmlEscapedString | Promise<string>, phase: (typeof HtmlEscapedCallbackPhase)[keyof typeof HtmlEscapedCallbackPhase], preserveCallbacks: boolean, context: object, buffer?: [
46
+ string
47
+ ]) => Promise<string>;
44
48
  export {};
@@ -9,4 +9,8 @@ export declare const Jwt: {
9
9
  header: import("./jwt").TokenHeader;
10
10
  payload: import("./types").JWTPayload;
11
11
  };
12
+ verifyFromJwks: (token: string, options: {
13
+ keys?: import("./jws").HonoJsonWebKey[] | (() => Promise<import("./jws").HonoJsonWebKey[]>);
14
+ jwks_uri?: string;
15
+ }, init?: RequestInit) => Promise<import("./types").JWTPayload>;
12
16
  };
@@ -4,6 +4,9 @@
4
4
  * https://datatracker.ietf.org/doc/html/rfc7515
5
5
  */
6
6
  import type { SignatureAlgorithm } from './jwa';
7
- export type SignatureKey = string | JsonWebKey | CryptoKey;
7
+ export interface HonoJsonWebKey extends JsonWebKey {
8
+ kid?: string;
9
+ }
10
+ export type SignatureKey = string | HonoJsonWebKey | CryptoKey;
8
11
  export declare function signing(privateKey: SignatureKey, alg: SignatureAlgorithm, data: BufferSource): Promise<ArrayBuffer>;
9
12
  export declare function verifying(publicKey: SignatureKey, alg: SignatureAlgorithm, signature: BufferSource, data: BufferSource): Promise<boolean>;
@@ -4,16 +4,22 @@
4
4
  * https://datatracker.ietf.org/doc/html/rfc7519
5
5
  */
6
6
  import type { SignatureAlgorithm } from './jwa';
7
- import type { SignatureKey } from './jws';
7
+ import type { HonoJsonWebKey, SignatureKey } from './jws';
8
8
  import type { JWTPayload } from './types';
9
9
  export interface TokenHeader {
10
10
  alg: SignatureAlgorithm;
11
- typ?: 'JWT';
11
+ typ?: "JWT";
12
+ kid?: string;
12
13
  }
13
14
  export declare function isTokenHeader(obj: unknown): obj is TokenHeader;
14
15
  export declare const sign: (payload: JWTPayload, privateKey: SignatureKey, alg?: SignatureAlgorithm) => Promise<string>;
15
16
  export declare const verify: (token: string, publicKey: SignatureKey, alg?: SignatureAlgorithm) => Promise<JWTPayload>;
17
+ export declare const verifyFromJwks: (token: string, options: {
18
+ keys?: HonoJsonWebKey[] | (() => Promise<HonoJsonWebKey[]>);
19
+ jwks_uri?: string;
20
+ }, init?: RequestInit) => Promise<JWTPayload>;
16
21
  export declare const decode: (token: string) => {
17
22
  header: TokenHeader;
18
23
  payload: JWTPayload;
19
24
  };
25
+ export declare const decodeHeader: (token: string) => TokenHeader;
@@ -20,6 +20,9 @@ export declare class JwtTokenIssuedAt extends Error {
20
20
  export declare class JwtHeaderInvalid extends Error {
21
21
  constructor(header: object);
22
22
  }
23
+ export declare class JwtHeaderRequiresKid extends Error {
24
+ constructor(header: object);
25
+ }
23
26
  export declare class JwtTokenSignatureMismatched extends Error {
24
27
  constructor(token: string);
25
28
  }
@@ -51,3 +54,4 @@ export type JWTPayload = {
51
54
  */
52
55
  iat?: number;
53
56
  };
57
+ export type { HonoJsonWebKey } from './jws';
@@ -61,8 +61,8 @@ declare const _baseMimes: {
61
61
  readonly xhtml: "application/xhtml+xml";
62
62
  readonly xml: "application/xml";
63
63
  readonly zip: "application/zip";
64
- readonly '3gp': "video/3gpp";
65
- readonly '3g2': "video/3gpp2";
64
+ readonly "3gp": "video/3gpp";
65
+ readonly "3g2": "video/3gpp2";
66
66
  readonly gltf: "model/gltf+json";
67
67
  readonly glb: "model/gltf-binary";
68
68
  };
@@ -3,10 +3,6 @@
3
3
  * Stream utility.
4
4
  */
5
5
  export declare class StreamingApi {
6
- private writer;
7
- private encoder;
8
- private writable;
9
- private abortSubscribers;
10
6
  responseReadable: ReadableStream;
11
7
  /**
12
8
  * Whether the stream has been aborted.
@@ -2,15 +2,29 @@
2
2
  * @module
3
3
  * URL utility.
4
4
  */
5
- export type Pattern = readonly [string, string, RegExp | true] | '*';
5
+ export type Pattern = readonly [
6
+ string,
7
+ string,
8
+ RegExp | true
9
+ ] | "*";
6
10
  export declare const splitPath: (path: string) => string[];
7
11
  export declare const splitRoutingPath: (routePath: string) => string[];
8
- export declare const getPattern: (label: string) => Pattern | null;
12
+ export declare const getPattern: (label: string, next?: string) => Pattern | null;
9
13
  type Decoder = (str: string) => string;
10
14
  export declare const tryDecode: (str: string, decoder: Decoder) => string;
11
15
  export declare const getPath: (request: Request) => string;
12
16
  export declare const getQueryStrings: (url: string) => string;
13
17
  export declare const getPathNoStrict: (request: Request) => string;
18
+ /**
19
+ * Merge paths.
20
+ * @param {string[]} ...paths - The paths to merge.
21
+ * @returns {string} The merged path.
22
+ * @example
23
+ * mergePath('/api', '/users') // '/api/users'
24
+ * mergePath('/api/', '/users') // '/api/users'
25
+ * mergePath('/api', '/') // '/api'
26
+ * mergePath('/api/', '/') // '/api/'
27
+ */
14
28
  export declare const mergePath: (...paths: string[]) => string;
15
29
  export declare const checkOptionalParameter: (path: string) => string[] | null;
16
30
  export declare const getQueryParam: (url: string, key?: string) => string | undefined | Record<string, string>;
@@ -1,14 +1,26 @@
1
1
  import type { Context } from '../context';
2
2
  import type { Env, MiddlewareHandler, TypedResponse, ValidationTargets } from '../types';
3
- type ValidationTargetKeysWithBody = 'form' | 'json';
4
- type ValidationTargetByMethod<M> = M extends 'get' | 'head' ? Exclude<keyof ValidationTargets, ValidationTargetKeysWithBody> : keyof ValidationTargets;
3
+ type ValidationTargetKeysWithBody = "form" | "json";
4
+ type ValidationTargetByMethod<M> = M extends "get" | "head" ? Exclude<keyof ValidationTargets, ValidationTargetKeysWithBody> : keyof ValidationTargets;
5
5
  export type ValidationFunction<InputType, OutputType, E extends Env = {}, P extends string = string> = (value: InputType, c: Context<E, P>) => OutputType | Response | Promise<OutputType> | Promise<Response>;
6
6
  type ExcludeResponseType<T> = T extends Response & TypedResponse<any> ? never : T;
7
7
  export declare const validator: <InputType, P extends string, M extends string, U extends ValidationTargetByMethod<M>, OutputType = ValidationTargets[U], OutputTypeExcludeResponseType = ExcludeResponseType<OutputType>, P2 extends string = P, V extends {
8
- in: { [K in U]: K extends "json" ? unknown extends InputType ? OutputTypeExcludeResponseType : InputType : { [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2]; }; };
9
- out: { [K in U]: OutputTypeExcludeResponseType; };
8
+ in: {
9
+ [K in U]: K extends "json" ? unknown extends InputType ? OutputTypeExcludeResponseType : InputType : {
10
+ [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2];
11
+ };
12
+ };
13
+ out: {
14
+ [K in U]: OutputTypeExcludeResponseType;
15
+ };
10
16
  } = {
11
- in: { [K in U]: K extends "json" ? unknown extends InputType ? OutputTypeExcludeResponseType : InputType : { [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2]; }; };
12
- out: { [K in U]: OutputTypeExcludeResponseType; };
17
+ in: {
18
+ [K in U]: K extends "json" ? unknown extends InputType ? OutputTypeExcludeResponseType : InputType : {
19
+ [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2];
20
+ };
21
+ };
22
+ out: {
23
+ [K in U]: OutputTypeExcludeResponseType;
24
+ };
13
25
  }, E extends Env = any>(target: U, validationFunc: ValidationFunction<unknown extends InputType ? ValidationTargets[U] : InputType, OutputType, E, P2>) => MiddlewareHandler<E, P, V>;
14
26
  export {};
@@ -0,0 +1,63 @@
1
+ // src/utils/accept.ts
2
+ var parseAccept = (acceptHeader) => {
3
+ if (!acceptHeader) {
4
+ return [];
5
+ }
6
+ const acceptValues = acceptHeader.split(",").map((value, index) => ({ value, index }));
7
+ return acceptValues.map(parseAcceptValue).filter((item) => Boolean(item)).sort(sortByQualityAndIndex).map(({ type, params, q }) => ({ type, params, q }));
8
+ };
9
+ var parseAcceptValueRegex = /;(?=(?:(?:[^"]*"){2})*[^"]*$)/;
10
+ var parseAcceptValue = ({ value, index }) => {
11
+ const parts = value.trim().split(parseAcceptValueRegex).map((s) => s.trim());
12
+ const type = parts[0];
13
+ if (!type) {
14
+ return null;
15
+ }
16
+ const params = parseParams(parts.slice(1));
17
+ const q = parseQuality(params.q);
18
+ return { type, params, q, index };
19
+ };
20
+ var parseParams = (paramParts) => {
21
+ return paramParts.reduce((acc, param) => {
22
+ const [key, val] = param.split("=").map((s) => s.trim());
23
+ if (key && val) {
24
+ acc[key] = val;
25
+ }
26
+ return acc;
27
+ }, {});
28
+ };
29
+ var parseQuality = (qVal) => {
30
+ if (qVal === void 0) {
31
+ return 1;
32
+ }
33
+ if (qVal === "") {
34
+ return 1;
35
+ }
36
+ if (qVal === "NaN") {
37
+ return 0;
38
+ }
39
+ const num = Number(qVal);
40
+ if (num === Infinity) {
41
+ return 1;
42
+ }
43
+ if (num === -Infinity) {
44
+ return 0;
45
+ }
46
+ if (Number.isNaN(num)) {
47
+ return 1;
48
+ }
49
+ if (num < 0 || num > 1) {
50
+ return 1;
51
+ }
52
+ return num;
53
+ };
54
+ var sortByQualityAndIndex = (a, b) => {
55
+ const qDiff = b.q - a.q;
56
+ if (qDiff !== 0) {
57
+ return qDiff;
58
+ }
59
+ return a.index - b.index;
60
+ };
61
+ export {
62
+ parseAccept
63
+ };
@@ -1,6 +1,6 @@
1
1
  // src/utils/jwt/index.ts
2
- import { decode, sign, verify } from "./jwt.js";
3
- var Jwt = { sign, verify, decode };
2
+ import { decode, sign, verify, verifyFromJwks } from "./jwt.js";
3
+ var Jwt = { sign, verify, decode, verifyFromJwks };
4
4
  export {
5
5
  Jwt
6
6
  };
@@ -4,6 +4,7 @@ import { AlgorithmTypes } from "./jwa.js";
4
4
  import { signing, verifying } from "./jws.js";
5
5
  import {
6
6
  JwtHeaderInvalid,
7
+ JwtHeaderRequiresKid,
7
8
  JwtTokenExpired,
8
9
  JwtTokenInvalid,
9
10
  JwtTokenIssuedAt,
@@ -23,7 +24,13 @@ function isTokenHeader(obj) {
23
24
  }
24
25
  var sign = async (payload, privateKey, alg = "HS256") => {
25
26
  const encodedPayload = encodeJwtPart(payload);
26
- const encodedHeader = encodeJwtPart({ alg, typ: "JWT" });
27
+ let encodedHeader;
28
+ if (typeof privateKey === "object" && "alg" in privateKey) {
29
+ alg = privateKey.alg;
30
+ encodedHeader = encodeJwtPart({ alg, typ: "JWT", kid: privateKey.kid });
31
+ } else {
32
+ encodedHeader = encodeJwtPart({ alg, typ: "JWT" });
33
+ }
27
34
  const partialToken = `${encodedHeader}.${encodedPayload}`;
28
35
  const signaturePart = await signing(privateKey, alg, utf8Encoder.encode(partialToken));
29
36
  const signature = encodeSignaturePart(signaturePart);
@@ -60,6 +67,41 @@ var verify = async (token, publicKey, alg = "HS256") => {
60
67
  }
61
68
  return payload;
62
69
  };
70
+ var verifyFromJwks = async (token, options, init) => {
71
+ const header = decodeHeader(token);
72
+ if (!isTokenHeader(header)) {
73
+ throw new JwtHeaderInvalid(header);
74
+ }
75
+ if (!header.kid) {
76
+ throw new JwtHeaderRequiresKid(header);
77
+ }
78
+ let keys = typeof options.keys === "function" ? await options.keys() : options.keys;
79
+ if (options.jwks_uri) {
80
+ const response = await fetch(options.jwks_uri, init);
81
+ if (!response.ok) {
82
+ throw new Error(`failed to fetch JWKS from ${options.jwks_uri}`);
83
+ }
84
+ const data = await response.json();
85
+ if (!data.keys) {
86
+ throw new Error('invalid JWKS response. "keys" field is missing');
87
+ }
88
+ if (!Array.isArray(data.keys)) {
89
+ throw new Error('invalid JWKS response. "keys" field is not an array');
90
+ }
91
+ if (keys) {
92
+ keys.push(...data.keys);
93
+ } else {
94
+ keys = data.keys;
95
+ }
96
+ } else if (!keys) {
97
+ throw new Error('verifyFromJwks requires options for either "keys" or "jwks_uri" or both');
98
+ }
99
+ const matchingKey = keys.find((key) => key.kid === header.kid);
100
+ if (!matchingKey) {
101
+ throw new JwtTokenInvalid(token);
102
+ }
103
+ return await verify(token, matchingKey, matchingKey.alg);
104
+ };
63
105
  var decode = (token) => {
64
106
  try {
65
107
  const [h, p] = token.split(".");
@@ -73,9 +115,19 @@ var decode = (token) => {
73
115
  throw new JwtTokenInvalid(token);
74
116
  }
75
117
  };
118
+ var decodeHeader = (token) => {
119
+ try {
120
+ const [h] = token.split(".");
121
+ return decodeJwtPart(h);
122
+ } catch {
123
+ throw new JwtTokenInvalid(token);
124
+ }
125
+ };
76
126
  export {
77
127
  decode,
128
+ decodeHeader,
78
129
  isTokenHeader,
79
130
  sign,
80
- verify
131
+ verify,
132
+ verifyFromJwks
81
133
  };
@@ -35,6 +35,12 @@ var JwtHeaderInvalid = class extends Error {
35
35
  this.name = "JwtHeaderInvalid";
36
36
  }
37
37
  };
38
+ var JwtHeaderRequiresKid = class extends Error {
39
+ constructor(header) {
40
+ super(`required "kid" in jwt header: ${JSON.stringify(header)}`);
41
+ this.name = "JwtHeaderRequiresKid";
42
+ }
43
+ };
38
44
  var JwtTokenSignatureMismatched = class extends Error {
39
45
  constructor(token) {
40
46
  super(`token(${token}) signature mismatched`);
@@ -56,6 +62,7 @@ export {
56
62
  CryptoKeyUsage,
57
63
  JwtAlgorithmNotImplemented,
58
64
  JwtHeaderInvalid,
65
+ JwtHeaderRequiresKid,
59
66
  JwtTokenExpired,
60
67
  JwtTokenInvalid,
61
68
  JwtTokenIssuedAt,
package/dist/utils/url.js CHANGED
@@ -33,20 +33,21 @@ var replaceGroupMarks = (paths, groups) => {
33
33
  return paths;
34
34
  };
35
35
  var patternCache = {};
36
- var getPattern = (label) => {
36
+ var getPattern = (label, next) => {
37
37
  if (label === "*") {
38
38
  return "*";
39
39
  }
40
40
  const match = label.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);
41
41
  if (match) {
42
- if (!patternCache[label]) {
42
+ const cacheKey = `${label}#${next}`;
43
+ if (!patternCache[cacheKey]) {
43
44
  if (match[2]) {
44
- patternCache[label] = [label, match[1], new RegExp("^" + match[2] + "$")];
45
+ patternCache[cacheKey] = next && next[0] !== ":" && next[0] !== "*" ? [cacheKey, match[1], new RegExp(`^${match[2]}(?=/${next})`)] : [label, match[1], new RegExp(`^${match[2]}$`)];
45
46
  } else {
46
- patternCache[label] = [label, match[1], true];
47
+ patternCache[cacheKey] = [label, match[1], true];
47
48
  }
48
49
  }
49
- return patternCache[label];
50
+ return patternCache[cacheKey];
50
51
  }
51
52
  return null;
52
53
  };
@@ -88,27 +89,11 @@ var getPathNoStrict = (request) => {
88
89
  const result = getPath(request);
89
90
  return result.length > 1 && result.at(-1) === "/" ? result.slice(0, -1) : result;
90
91
  };
91
- var mergePath = (...paths) => {
92
- let p = "";
93
- let endsWithSlash = false;
94
- for (let path of paths) {
95
- if (p.at(-1) === "/") {
96
- p = p.slice(0, -1);
97
- endsWithSlash = true;
98
- }
99
- if (path[0] !== "/") {
100
- path = `/${path}`;
101
- }
102
- if (path === "/" && endsWithSlash) {
103
- p = `${p}/`;
104
- } else if (path !== "/") {
105
- p = `${p}${path}`;
106
- }
107
- if (path === "/" && p === "") {
108
- p = "/";
109
- }
92
+ var mergePath = (base, sub, ...rest) => {
93
+ if (rest.length) {
94
+ sub = mergePath(sub, ...rest);
110
95
  }
111
- return p;
96
+ return `${base?.[0] === "/" ? "" : "/"}${base}${sub === "/" ? "" : `${base?.at(-1) === "/" ? "" : "/"}${sub?.[0] === "/" ? sub.slice(1) : sub}`}`;
112
97
  };
113
98
  var checkOptionalParameter = (path) => {
114
99
  if (!path.match(/\:.+\?$/)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.6.20",
3
+ "version": "4.7.1",
4
4
  "description": "Web framework built on Web Standards",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",
@@ -204,6 +204,11 @@
204
204
  "import": "./dist/middleware/jwt/index.js",
205
205
  "require": "./dist/cjs/middleware/jwt/index.js"
206
206
  },
207
+ "./jwk": {
208
+ "types": "./dist/types/middleware/jwk/index.d.ts",
209
+ "import": "./dist/middleware/jwk/index.js",
210
+ "require": "./dist/cjs/middleware/jwk/index.js"
211
+ },
207
212
  "./timeout": {
208
213
  "types": "./dist/types/middleware/timeout/index.d.ts",
209
214
  "import": "./dist/middleware/timeout/index.js",
@@ -239,6 +244,11 @@
239
244
  "import": "./dist/middleware/request-id/index.js",
240
245
  "require": "./dist/cjs/middleware/request-id/index.js"
241
246
  },
247
+ "./language": {
248
+ "types": "./dist/types/middleware/language/index.d.ts",
249
+ "import": "./dist/middleware/language/index.js",
250
+ "require": "./dist/cjs/middleware/language/index.js"
251
+ },
242
252
  "./secure-headers": {
243
253
  "types": "./dist/types/middleware/secure-headers/index.d.ts",
244
254
  "import": "./dist/middleware/secure-headers/index.js",
@@ -388,6 +398,11 @@
388
398
  "types": "./dist/types/helper/conninfo/index.d.ts",
389
399
  "import": "./dist/helper/conninfo/index.js",
390
400
  "require": "./dist/cjs/helper/conninfo/index.js"
401
+ },
402
+ "./proxy": {
403
+ "types": "./dist/types/helper/proxy/index.d.ts",
404
+ "import": "./dist/helper/proxy/index.js",
405
+ "require": "./dist/cjs/helper/proxy/index.js"
391
406
  }
392
407
  },
393
408
  "typesVersions": {
@@ -506,6 +521,9 @@
506
521
  "request-id": [
507
522
  "./dist/types/middleware/request-id"
508
523
  ],
524
+ "language": [
525
+ "./dist/types/middleware/language"
526
+ ],
509
527
  "streaming": [
510
528
  "./dist/types/helper/streaming"
511
529
  ],
@@ -595,6 +613,9 @@
595
613
  ],
596
614
  "conninfo": [
597
615
  "./dist/types/helper/conninfo"
616
+ ],
617
+ "proxy": [
618
+ "./dist/types/helper/proxy"
598
619
  ]
599
620
  }
600
621
  },
@@ -632,7 +653,7 @@
632
653
  "@types/jsdom": "^21.1.7",
633
654
  "@types/node": "20.11.4",
634
655
  "@types/supertest": "^2.0.16",
635
- "@vitest/coverage-v8": "^2.0.5",
656
+ "@vitest/coverage-v8": "^3.0.5",
636
657
  "arg": "^5.0.2",
637
658
  "bun-types": "^1.1.39",
638
659
  "esbuild": "^0.15.18",
@@ -646,7 +667,7 @@
646
667
  "supertest": "^6.3.4",
647
668
  "typescript": "^5.3.3",
648
669
  "vite-plugin-fastly-js-compute": "^0.4.2",
649
- "vitest": "^2.0.5",
670
+ "vitest": "^3.0.5",
650
671
  "wrangler": "3.58.0",
651
672
  "ws": "^8.18.0",
652
673
  "zod": "^3.23.8"