hono 4.0.10 → 4.1.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 (109) hide show
  1. package/dist/adapter/aws-lambda/handler.js +1 -1
  2. package/dist/adapter/bun/index.js +2 -0
  3. package/dist/adapter/bun/websocket.js +77 -0
  4. package/dist/adapter/cloudflare-workers/index.js +3 -1
  5. package/dist/adapter/cloudflare-workers/websocket.js +57 -0
  6. package/dist/adapter/deno/index.js +3 -1
  7. package/dist/adapter/deno/websocket.js +29 -0
  8. package/dist/adapter/lambda-edge/handler.js +1 -1
  9. package/dist/cjs/adapter/aws-lambda/handler.js +1 -1
  10. package/dist/cjs/adapter/bun/index.js +3 -0
  11. package/dist/cjs/adapter/bun/websocket.js +98 -0
  12. package/dist/cjs/adapter/cloudflare-workers/index.js +5 -2
  13. package/dist/cjs/adapter/cloudflare-workers/websocket.js +80 -0
  14. package/dist/cjs/adapter/deno/index.js +5 -2
  15. package/dist/cjs/adapter/deno/websocket.js +52 -0
  16. package/dist/cjs/adapter/lambda-edge/handler.js +1 -1
  17. package/dist/cjs/client/client.js +68 -61
  18. package/dist/cjs/context.js +164 -188
  19. package/dist/cjs/helper/adapter/index.js +1 -1
  20. package/dist/cjs/helper/cookie/index.js +48 -8
  21. package/dist/cjs/helper/dev/index.js +3 -4
  22. package/dist/cjs/helper/factory/index.js +1 -3
  23. package/dist/cjs/helper/ssg/index.js +9 -159
  24. package/dist/cjs/helper/ssg/middleware.js +57 -0
  25. package/dist/cjs/helper/ssg/ssg.js +212 -0
  26. package/dist/cjs/helper/websocket/index.js +32 -0
  27. package/dist/cjs/helper.js +1 -0
  28. package/dist/cjs/hono-base.js +46 -65
  29. package/dist/cjs/http-exception.js +3 -1
  30. package/dist/cjs/jsx/base.js +7 -2
  31. package/dist/cjs/jsx/components.js +1 -1
  32. package/dist/cjs/jsx/dom/index.js +45 -3
  33. package/dist/cjs/jsx/dom/render.js +6 -6
  34. package/dist/cjs/jsx/hooks/index.js +25 -16
  35. package/dist/cjs/jsx/index.js +34 -2
  36. package/dist/cjs/middleware/body-limit/index.js +80 -0
  37. package/dist/cjs/middleware/logger/index.js +9 -7
  38. package/dist/cjs/request.js +29 -48
  39. package/dist/cjs/router/linear-router/router.js +3 -5
  40. package/dist/cjs/router/pattern-router/router.js +2 -4
  41. package/dist/cjs/router/reg-exp-router/node.js +3 -3
  42. package/dist/cjs/router/reg-exp-router/router.js +11 -12
  43. package/dist/cjs/router/reg-exp-router/trie.js +2 -4
  44. package/dist/cjs/router/smart-router/router.js +3 -3
  45. package/dist/cjs/router/trie-router/node.js +6 -2
  46. package/dist/cjs/router/trie-router/router.js +2 -1
  47. package/dist/cjs/test-utils/setup-vitest.js +2 -0
  48. package/dist/cjs/utils/color.js +32 -0
  49. package/dist/cjs/utils/concurrent.js +62 -0
  50. package/dist/cjs/utils/cookie.js +28 -1
  51. package/dist/cjs/utils/stream.js +5 -1
  52. package/dist/cjs/utils/url.js +2 -2
  53. package/dist/client/client.js +68 -61
  54. package/dist/context.js +164 -189
  55. package/dist/helper/adapter/index.js +1 -1
  56. package/dist/helper/cookie/index.js +48 -8
  57. package/dist/helper/dev/index.js +3 -4
  58. package/dist/helper/factory/index.js +1 -3
  59. package/dist/helper/ssg/index.js +3 -151
  60. package/dist/helper/ssg/middleware.js +29 -0
  61. package/dist/helper/ssg/ssg.js +187 -0
  62. package/dist/helper/websocket/index.js +9 -0
  63. package/dist/helper.js +1 -0
  64. package/dist/hono-base.js +45 -65
  65. package/dist/http-exception.js +3 -1
  66. package/dist/jsx/base.js +7 -2
  67. package/dist/jsx/components.js +1 -1
  68. package/dist/jsx/dom/index.js +44 -4
  69. package/dist/jsx/dom/render.js +6 -6
  70. package/dist/jsx/hooks/index.js +23 -16
  71. package/dist/jsx/index.js +34 -3
  72. package/dist/middleware/body-limit/index.js +57 -0
  73. package/dist/middleware/logger/index.js +9 -7
  74. package/dist/request.js +29 -49
  75. package/dist/router/linear-router/router.js +3 -5
  76. package/dist/router/pattern-router/router.js +2 -4
  77. package/dist/router/reg-exp-router/node.js +3 -3
  78. package/dist/router/reg-exp-router/router.js +11 -12
  79. package/dist/router/reg-exp-router/trie.js +2 -4
  80. package/dist/router/smart-router/router.js +3 -3
  81. package/dist/router/trie-router/node.js +6 -2
  82. package/dist/router/trie-router/router.js +2 -1
  83. package/dist/test-utils/setup-vitest.js +2 -0
  84. package/dist/types/adapter/bun/index.d.ts +1 -0
  85. package/dist/types/adapter/bun/websocket.d.ts +26 -0
  86. package/dist/types/adapter/cloudflare-workers/index.d.ts +1 -0
  87. package/dist/types/adapter/cloudflare-workers/websocket.d.ts +2 -0
  88. package/dist/types/adapter/deno/index.d.ts +1 -0
  89. package/dist/types/adapter/deno/websocket.d.ts +2 -0
  90. package/dist/types/client/types.d.ts +9 -0
  91. package/dist/types/helper/cookie/index.d.ts +3 -1
  92. package/dist/types/helper/ssg/index.d.ts +2 -105
  93. package/dist/types/helper/ssg/middleware.d.ts +38 -0
  94. package/dist/types/helper/ssg/ssg.d.ts +70 -0
  95. package/dist/types/helper/websocket/index.d.ts +34 -0
  96. package/dist/types/http-exception.d.ts +1 -0
  97. package/dist/types/jsx/dom/index.d.ts +40 -7
  98. package/dist/types/jsx/hooks/index.d.ts +2 -0
  99. package/dist/types/jsx/index.d.ts +41 -5
  100. package/dist/types/middleware/body-limit/index.d.ts +28 -0
  101. package/dist/types/utils/color.d.ts +1 -0
  102. package/dist/types/utils/concurrent.d.ts +7 -0
  103. package/dist/types/utils/cookie.d.ts +2 -0
  104. package/dist/utils/color.js +9 -0
  105. package/dist/utils/concurrent.js +39 -0
  106. package/dist/utils/cookie.js +28 -1
  107. package/dist/utils/stream.js +5 -1
  108. package/dist/utils/url.js +2 -2
  109. package/package.json +18 -2
@@ -1,3 +1,4 @@
1
+ import type { UpgradedWebSocketResponseInputJSONType } from '../helper/websocket';
1
2
  import type { Hono } from '../hono';
2
3
  import type { Schema } from '../types';
3
4
  import type { HasRequiredKeys } from '../utils/types';
@@ -22,6 +23,14 @@ export type ClientRequest<S extends Schema> = {
22
23
  } ? {
23
24
  param: P;
24
25
  } : {} : {}) => URL;
26
+ } & {
27
+ $ws: S['$get'] extends {
28
+ input: {
29
+ json: UpgradedWebSocketResponseInputJSONType;
30
+ };
31
+ } ? S['$get'] extends {
32
+ input: infer I;
33
+ } ? (args?: Omit<I, 'json'>) => WebSocket : never : never;
25
34
  };
26
35
  type BlankRecordToNever<T> = T extends any ? (keyof T extends never ? never : T) : never;
27
36
  export interface ClientResponse<T> {
@@ -1,12 +1,14 @@
1
1
  import type { Context } from '../../context';
2
- import type { CookieOptions, Cookie, SignedCookie } from '../../utils/cookie';
2
+ import type { CookieOptions, Cookie, SignedCookie, CookiePrefixOptions } from '../../utils/cookie';
3
3
  interface GetCookie {
4
4
  (c: Context, key: string): string | undefined;
5
5
  (c: Context): Cookie;
6
+ (c: Context, key: string, prefixOptions: CookiePrefixOptions): string | undefined;
6
7
  }
7
8
  interface GetSignedCookie {
8
9
  (c: Context, secret: string | BufferSource, key: string): Promise<string | undefined | false>;
9
10
  (c: Context, secret: string): Promise<SignedCookie>;
11
+ (c: Context, secret: string | BufferSource, key: string, prefixOptions: CookiePrefixOptions): Promise<string | undefined | false>;
10
12
  }
11
13
  export declare const getCookie: GetCookie;
12
14
  export declare const getSignedCookie: GetSignedCookie;
@@ -1,105 +1,2 @@
1
- import type { Context } from '../../context';
2
- import type { Hono } from '../../hono';
3
- import type { Env, MiddlewareHandler, Schema } from '../../types';
4
- export declare const SSG_DISABLED_RESPONSE: Response;
5
- /**
6
- * @experimental
7
- * `FileSystemModule` is an experimental feature.
8
- * The API might be changed.
9
- */
10
- export interface FileSystemModule {
11
- writeFile(path: string, data: string | Uint8Array): Promise<void>;
12
- mkdir(path: string, options: {
13
- recursive: boolean;
14
- }): Promise<void | string>;
15
- }
16
- /**
17
- * @experimental
18
- * `ToSSGResult` is an experimental feature.
19
- * The API might be changed.
20
- */
21
- export interface ToSSGResult {
22
- success: boolean;
23
- files: string[];
24
- error?: Error;
25
- }
26
- interface SSGParam {
27
- [key: string]: string;
28
- }
29
- type SSGParams = SSGParam[];
30
- interface SSGParamsMiddleware {
31
- <E extends Env = Env>(generateParams: (c: Context<E>) => SSGParams | Promise<SSGParams>): MiddlewareHandler<E>;
32
- <E extends Env = Env>(params: SSGParams): MiddlewareHandler<E>;
33
- }
34
- /**
35
- * Define SSG Route
36
- */
37
- export declare const ssgParams: SSGParamsMiddleware;
38
- export type BeforeRequestHook = (req: Request) => Request | false;
39
- export type AfterResponseHook = (res: Response) => Response | false;
40
- export type AfterGenerateHook = (result: ToSSGResult) => void | Promise<void>;
41
- export interface ToSSGOptions {
42
- dir?: string;
43
- beforeRequestHook?: BeforeRequestHook;
44
- afterResponseHook?: AfterResponseHook;
45
- afterGenerateHook?: AfterGenerateHook;
46
- }
47
- /**
48
- * @experimental
49
- * `fetchRoutesContent` is an experimental feature.
50
- * The API might be changed.
51
- */
52
- export declare const fetchRoutesContent: <E extends Env = Env, S extends Schema = {}, BasePath extends string = "/">(app: Hono<E, S, BasePath>, beforeRequestHook?: BeforeRequestHook, afterResponseHook?: AfterResponseHook) => Promise<Map<string, {
53
- content: string | ArrayBuffer;
54
- mimeType: string;
55
- }>>;
56
- /**
57
- * @experimental
58
- * `saveContentToFiles` is an experimental feature.
59
- * The API might be changed.
60
- */
61
- export declare const saveContentToFiles: (htmlMap: Map<string, {
62
- content: string | ArrayBuffer;
63
- mimeType: string;
64
- }>, fsModule: FileSystemModule, outDir: string) => Promise<string[]>;
65
- /**
66
- * @experimental
67
- * `ToSSGInterface` is an experimental feature.
68
- * The API might be changed.
69
- */
70
- export interface ToSSGInterface {
71
- (app: Hono<any, any, any>, fsModule: FileSystemModule, options?: ToSSGOptions): Promise<ToSSGResult>;
72
- }
73
- /**
74
- * @experimental
75
- * `ToSSGAdaptorInterface` is an experimental feature.
76
- * The API might be changed.
77
- */
78
- export interface ToSSGAdaptorInterface<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'> {
79
- (app: Hono<E, S, BasePath>, options?: ToSSGOptions): Promise<ToSSGResult>;
80
- }
81
- /**
82
- * @experimental
83
- * `toSSG` is an experimental feature.
84
- * The API might be changed.
85
- */
86
- export declare const toSSG: ToSSGInterface;
87
- /**
88
- * @experimental
89
- * `isSSGContext` is an experimental feature.
90
- * The API might be changed.
91
- */
92
- export declare const isSSGContext: (c: Context) => boolean;
93
- /**
94
- * @experimental
95
- * `disableSSG` is an experimental feature.
96
- * The API might be changed.
97
- */
98
- export declare const disableSSG: () => MiddlewareHandler;
99
- /**
100
- * @experimental
101
- * `onlySSG` is an experimental feature.
102
- * The API might be changed.
103
- */
104
- export declare const onlySSG: () => MiddlewareHandler;
105
- export {};
1
+ export * from './ssg';
2
+ export { SSG_DISABLED_RESPONSE, ssgParams, isSSGContext, disableSSG, onlySSG } from './middleware';
@@ -0,0 +1,38 @@
1
+ import type { Context } from '../../context';
2
+ import type { Env, MiddlewareHandler } from '../../types';
3
+ export declare const SSG_CONTEXT = "HONO_SSG_CONTEXT";
4
+ export declare const SSG_DISABLED_RESPONSE: Response;
5
+ interface SSGParam {
6
+ [key: string]: string;
7
+ }
8
+ export type SSGParams = SSGParam[];
9
+ interface SSGParamsMiddleware {
10
+ <E extends Env = Env>(generateParams: (c: Context<E>) => SSGParams | Promise<SSGParams>): MiddlewareHandler<E>;
11
+ <E extends Env = Env>(params: SSGParams): MiddlewareHandler<E>;
12
+ }
13
+ export type AddedSSGDataRequest = Request & {
14
+ ssgParams?: SSGParams;
15
+ };
16
+ /**
17
+ * Define SSG Route
18
+ */
19
+ export declare const ssgParams: SSGParamsMiddleware;
20
+ /**
21
+ * @experimental
22
+ * `isSSGContext` is an experimental feature.
23
+ * The API might be changed.
24
+ */
25
+ export declare const isSSGContext: (c: Context) => boolean;
26
+ /**
27
+ * @experimental
28
+ * `disableSSG` is an experimental feature.
29
+ * The API might be changed.
30
+ */
31
+ export declare const disableSSG: () => MiddlewareHandler;
32
+ /**
33
+ * @experimental
34
+ * `onlySSG` is an experimental feature.
35
+ * The API might be changed.
36
+ */
37
+ export declare const onlySSG: () => MiddlewareHandler;
38
+ export {};
@@ -0,0 +1,70 @@
1
+ import type { Hono } from '../../hono';
2
+ import type { Env, Schema } from '../../types';
3
+ /**
4
+ * @experimental
5
+ * `FileSystemModule` is an experimental feature.
6
+ * The API might be changed.
7
+ */
8
+ export interface FileSystemModule {
9
+ writeFile(path: string, data: string | Uint8Array): Promise<void>;
10
+ mkdir(path: string, options: {
11
+ recursive: boolean;
12
+ }): Promise<void | string>;
13
+ }
14
+ /**
15
+ * @experimental
16
+ * `ToSSGResult` is an experimental feature.
17
+ * The API might be changed.
18
+ */
19
+ export interface ToSSGResult {
20
+ success: boolean;
21
+ files: string[];
22
+ error?: Error;
23
+ }
24
+ export type BeforeRequestHook = (req: Request) => Request | false;
25
+ export type AfterResponseHook = (res: Response) => Response | false;
26
+ export type AfterGenerateHook = (result: ToSSGResult) => void | Promise<void>;
27
+ export interface ToSSGOptions {
28
+ dir?: string;
29
+ beforeRequestHook?: BeforeRequestHook;
30
+ afterResponseHook?: AfterResponseHook;
31
+ afterGenerateHook?: AfterGenerateHook;
32
+ concurrency?: number;
33
+ }
34
+ /**
35
+ * @experimental
36
+ * `fetchRoutesContent` is an experimental feature.
37
+ * The API might be changed.
38
+ */
39
+ export declare const fetchRoutesContent: <E extends Env = Env, S extends Schema = {}, BasePath extends string = "/">(app: Hono<E, S, BasePath>, beforeRequestHook?: BeforeRequestHook, afterResponseHook?: AfterResponseHook, concurrency?: number) => Generator<Promise<Generator<Promise<{
40
+ routePath: string;
41
+ mimeType: string;
42
+ content: string | ArrayBuffer;
43
+ } | undefined>> | undefined>>;
44
+ export declare const saveContentToFile: (data: Promise<{
45
+ routePath: string;
46
+ content: string | ArrayBuffer;
47
+ mimeType: string;
48
+ } | undefined>, fsModule: FileSystemModule, outDir: string) => Promise<string | undefined>;
49
+ /**
50
+ * @experimental
51
+ * `ToSSGInterface` is an experimental feature.
52
+ * The API might be changed.
53
+ */
54
+ export interface ToSSGInterface {
55
+ (app: Hono<any, any, any>, fsModule: FileSystemModule, options?: ToSSGOptions): Promise<ToSSGResult>;
56
+ }
57
+ /**
58
+ * @experimental
59
+ * `ToSSGAdaptorInterface` is an experimental feature.
60
+ * The API might be changed.
61
+ */
62
+ export interface ToSSGAdaptorInterface<E extends Env = Env, S extends Schema = {}, BasePath extends string = '/'> {
63
+ (app: Hono<E, S, BasePath>, options?: ToSSGOptions): Promise<ToSSGResult>;
64
+ }
65
+ /**
66
+ * @experimental
67
+ * `toSSG` is an experimental feature.
68
+ * The API might be changed.
69
+ */
70
+ export declare const toSSG: ToSSGInterface;
@@ -0,0 +1,34 @@
1
+ import type { Context } from '../../context';
2
+ import type { MiddlewareHandler } from '../../types';
3
+ /**
4
+ * WebSocket Event Listeners type
5
+ */
6
+ export interface WSEvents {
7
+ onOpen?: (evt: Event, ws: WSContext) => void;
8
+ onMessage?: (evt: MessageEvent<WSMessageReceive>, ws: WSContext) => void;
9
+ onClose?: (evt: CloseEvent, ws: WSContext) => void;
10
+ onError?: (evt: Event, ws: WSContext) => void;
11
+ }
12
+ export type UpgradedWebSocketResponseInputJSONType = '__websocket' | undefined;
13
+ /**
14
+ * Upgrade WebSocket Type
15
+ */
16
+ export type UpgradeWebSocket = (createEvents: (c: Context) => WSEvents | Promise<WSEvents>) => MiddlewareHandler<any, string, {
17
+ in: {
18
+ json: UpgradedWebSocketResponseInputJSONType;
19
+ };
20
+ }>;
21
+ export type WSReadyState = 0 | 1 | 2 | 3;
22
+ export type WSContext = {
23
+ send(source: string | ArrayBuffer | Uint8Array, options?: {
24
+ compress: boolean;
25
+ }): void;
26
+ raw?: unknown;
27
+ binaryType: BinaryType;
28
+ readyState: WSReadyState;
29
+ url: URL | null;
30
+ protocol: string | null;
31
+ close(code?: number, reason?: string): void;
32
+ };
33
+ export type WSMessageReceive = string | Blob | ArrayBufferLike;
34
+ export declare const createWSMessageEvent: (source: WSMessageReceive) => MessageEvent<WSMessageReceive>;
@@ -2,6 +2,7 @@ import type { StatusCode } from './utils/http-status';
2
2
  type HTTPExceptionOptions = {
3
3
  res?: Response;
4
4
  message?: string;
5
+ cause?: unknown;
5
6
  };
6
7
  /**
7
8
  * `HTTPException` must be used when a fatal error such as authentication failure occurs.
@@ -1,9 +1,42 @@
1
- export { useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, } from '../hooks';
1
+ import type { Props, Child, JSXNode } from '../base';
2
+ import { memo, isValidElement } from '../base';
3
+ import { useContext } from '../context';
4
+ import { useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, useReducer, useDebugValue } from '../hooks';
5
+ import { Suspense, ErrorBoundary } from './components';
6
+ import { createContext } from './context';
2
7
  export { render } from './render';
3
- export { Suspense, ErrorBoundary } from './components';
4
- export { useContext } from '../context';
8
+ declare const createElement: (tag: string | ((props: Props) => JSXNode), props: Props, ...children: Child[]) => JSXNode;
9
+ declare const cloneElement: <T extends JSXNode | JSX.Element>(element: T, props: Props, ...children: Child[]) => T;
10
+ export { createElement as jsx, useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, useReducer, useDebugValue, Suspense, ErrorBoundary, createContext, useContext, memo, isValidElement, createElement, cloneElement, };
11
+ declare const _default: {
12
+ useState: <T>(initialState: T | (() => T)) => [T, (newState: T | ((currentState: T) => T)) => void];
13
+ useEffect: (effect: () => void | (() => void), deps?: readonly unknown[] | undefined) => void;
14
+ useRef: <T_1>(initialValue: T_1 | null) => import("../hooks").RefObject<T_1>;
15
+ useCallback: <T_2 extends (...args: unknown[]) => unknown>(callback: T_2, deps: readonly unknown[]) => T_2;
16
+ use: <T_3>(promise: Promise<T_3>) => T_3;
17
+ startTransition: (callback: () => void) => void;
18
+ useTransition: () => [boolean, (callback: () => void) => void];
19
+ useDeferredValue: <T_4>(value: T_4) => T_4;
20
+ startViewTransition: (callback: () => void) => void;
21
+ useViewTransition: () => [boolean, (callback: () => void) => void];
22
+ useMemo: <T_5>(factory: () => T_5, deps: readonly unknown[]) => T_5;
23
+ useLayoutEffect: (effect: () => void | (() => void), deps?: readonly unknown[] | undefined) => void;
24
+ useReducer: <T_6, A>(reducer: (state: T_6, action: A) => T_6, initialArg: T_6, init?: ((initialState: T_6) => T_6) | undefined) => [T_6, (action: A) => void];
25
+ useDebugValue: (value: unknown, formatter?: ((value: unknown) => string) | undefined) => void;
26
+ Suspense: import("../base").FC<import("..").PropsWithChildren<{
27
+ fallback: any;
28
+ }>>;
29
+ ErrorBoundary: import("../base").FC<import("..").PropsWithChildren<{
30
+ fallback?: Child | undefined;
31
+ fallbackRender?: import("../components").FallbackRender | undefined;
32
+ onError?: import("../components").ErrorHandler | undefined;
33
+ }>>;
34
+ createContext: <T_7>(defaultValue: T_7) => import("../context").Context<T_7>;
35
+ useContext: <T_8>(context: import("../context").Context<T_8>) => T_8;
36
+ memo: <T_9>(component: import("../base").FC<T_9>, propsAreEqual?: (prevProps: Readonly<T_9>, nextProps: Readonly<T_9>) => boolean) => import("../base").FC<T_9>;
37
+ isValidElement: (element: unknown) => element is JSXNode;
38
+ createElement: (tag: string | ((props: Props) => JSXNode), props: Props, ...children: Child[]) => JSXNode;
39
+ cloneElement: <T_10 extends JSXNode | JSX.Element>(element: T_10, props: Props, ...children: Child[]) => T_10;
40
+ };
41
+ export default _default;
5
42
  export type { Context } from '../context';
6
- export { createContext } from './context';
7
- export { memo, isValidElement } from '../base';
8
- import type { Props, Child, JSXNode } from '../base';
9
- export declare const cloneElement: <T extends JSXNode | JSX.Element>(element: T, props: Props, ...children: Child[]) => T;
@@ -15,6 +15,7 @@ export declare const startTransition: (callback: () => void) => void;
15
15
  export declare const useTransition: () => [boolean, (callback: () => void) => void];
16
16
  export declare const useDeferredValue: <T>(value: T) => T;
17
17
  export declare const useState: <T>(initialState: T | (() => T)) => [T, UpdateStateFunction<T>];
18
+ export declare const useReducer: <T, A>(reducer: (state: T, action: A) => T, initialArg: T, init?: ((initialState: T) => T) | undefined) => [T, (action: A) => void];
18
19
  export declare const useEffect: (effect: () => void | (() => void), deps?: readonly unknown[]) => void;
19
20
  export declare const useLayoutEffect: (effect: () => void | (() => void), deps?: readonly unknown[]) => void;
20
21
  export declare const useCallback: <T extends (...args: unknown[]) => unknown>(callback: T, deps: readonly unknown[]) => T;
@@ -24,4 +25,5 @@ export type RefObject<T> = {
24
25
  export declare const useRef: <T>(initialValue: T | null) => RefObject<T>;
25
26
  export declare const use: <T>(promise: Promise<T>) => T;
26
27
  export declare const useMemo: <T>(factory: () => T, deps: readonly unknown[]) => T;
28
+ export declare const useDebugValue: (value: unknown, formatter?: ((value: unknown) => string) | undefined) => void;
27
29
  export {};
@@ -1,6 +1,42 @@
1
- export { jsx, memo, Fragment, isValidElement, cloneElement } from './base';
2
- export { ErrorBoundary } from './components';
3
- export { Suspense } from './streaming';
4
- export { useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, } from './hooks';
5
- export { createContext, useContext } from './context';
1
+ import { jsx, memo, Fragment, isValidElement, cloneElement } from './base';
2
+ import { ErrorBoundary } from './components';
3
+ import { createContext, useContext } from './context';
4
+ import { useState, useEffect, useRef, useCallback, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, useReducer, useDebugValue } from './hooks';
5
+ import { Suspense } from './streaming';
6
+ export { jsx, memo, Fragment, isValidElement, jsx as createElement, cloneElement, ErrorBoundary, createContext, useContext, useState, useEffect, useRef, useCallback, useReducer, useDebugValue, use, startTransition, useTransition, useDeferredValue, startViewTransition, useViewTransition, useMemo, useLayoutEffect, Suspense, };
7
+ declare const _default: {
8
+ memo: <T>(component: import("./base").FC<T>, propsAreEqual?: (prevProps: Readonly<T>, nextProps: Readonly<T>) => boolean) => import("./base").FC<T>;
9
+ Fragment: ({ children, }: {
10
+ key?: string | undefined;
11
+ children?: import("../utils/html").HtmlEscapedString | import("./base").Child | undefined;
12
+ }) => import("../utils/html").HtmlEscapedString;
13
+ isValidElement: (element: unknown) => element is import("./base").JSXNode;
14
+ createElement: (tag: string | Function, props: import("./base").Props, ...children: (string | import("../utils/html").HtmlEscapedString)[]) => import("./base").JSXNode;
15
+ cloneElement: <T_1 extends import("./base").JSXNode | JSX.Element>(element: T_1, props: Partial<import("./base").Props>, ...children: import("./base").Child[]) => T_1;
16
+ ErrorBoundary: import("./base").FC<import("./types").PropsWithChildren<{
17
+ fallback?: import("./base").Child | undefined;
18
+ fallbackRender?: import("./components").FallbackRender | undefined;
19
+ onError?: import("./components").ErrorHandler | undefined;
20
+ }>>;
21
+ createContext: <T_2>(defaultValue: T_2) => import("./context").Context<T_2>;
22
+ useContext: <T_3>(context: import("./context").Context<T_3>) => T_3;
23
+ useState: <T_4>(initialState: T_4 | (() => T_4)) => [T_4, (newState: T_4 | ((currentState: T_4) => T_4)) => void];
24
+ useEffect: (effect: () => void | (() => void), deps?: readonly unknown[] | undefined) => void;
25
+ useRef: <T_5>(initialValue: T_5 | null) => import("./hooks").RefObject<T_5>;
26
+ useCallback: <T_6 extends (...args: unknown[]) => unknown>(callback: T_6, deps: readonly unknown[]) => T_6;
27
+ useReducer: <T_7, A>(reducer: (state: T_7, action: A) => T_7, initialArg: T_7, init?: ((initialState: T_7) => T_7) | undefined) => [T_7, (action: A) => void];
28
+ useDebugValue: (value: unknown, formatter?: ((value: unknown) => string) | undefined) => void;
29
+ use: <T_8>(promise: Promise<T_8>) => T_8;
30
+ startTransition: (callback: () => void) => void;
31
+ useTransition: () => [boolean, (callback: () => void) => void];
32
+ useDeferredValue: <T_9>(value: T_9) => T_9;
33
+ startViewTransition: (callback: () => void) => void;
34
+ useViewTransition: () => [boolean, (callback: () => void) => void];
35
+ useMemo: <T_10>(factory: () => T_10, deps: readonly unknown[]) => T_10;
36
+ useLayoutEffect: (effect: () => void | (() => void), deps?: readonly unknown[] | undefined) => void;
37
+ Suspense: import("./base").FC<import("./types").PropsWithChildren<{
38
+ fallback: any;
39
+ }>>;
40
+ };
41
+ export default _default;
6
42
  export * from './types';
@@ -0,0 +1,28 @@
1
+ import type { Context } from '../../context';
2
+ import type { MiddlewareHandler } from '../../types';
3
+ type OnError = (c: Context) => Response | Promise<Response>;
4
+ type BodyLimitOptions = {
5
+ maxSize: number;
6
+ onError?: OnError;
7
+ };
8
+ /**
9
+ * Body Limit Middleware
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * app.post(
14
+ * '/hello',
15
+ * bodyLimit({
16
+ * maxSize: 100 * 1024, // 100kb
17
+ * onError: (c) => {
18
+ * return c.text('overflow :(', 413)
19
+ * }
20
+ * }),
21
+ * (c) => {
22
+ * return c.text('pass :)')
23
+ * }
24
+ * )
25
+ * ```
26
+ */
27
+ export declare const bodyLimit: (options: BodyLimitOptions) => MiddlewareHandler;
28
+ export {};
@@ -0,0 +1 @@
1
+ export declare function getColorEnabled(): boolean;
@@ -0,0 +1,7 @@
1
+ export interface Pool {
2
+ run<T>(fn: () => T): Promise<T>;
3
+ }
4
+ export declare const createPool: ({ concurrency, interval, }?: {
5
+ concurrency?: number | undefined;
6
+ interval?: number | undefined;
7
+ }) => Pool;
@@ -10,7 +10,9 @@ export type CookieOptions = {
10
10
  signingSecret?: string;
11
11
  sameSite?: 'Strict' | 'Lax' | 'None';
12
12
  partitioned?: boolean;
13
+ prefix?: CookiePrefixOptions;
13
14
  };
15
+ export type CookiePrefixOptions = 'host' | 'secure';
14
16
  export declare const parse: (cookie: string, name?: string) => Cookie;
15
17
  export declare const parseSigned: (cookie: string, secret: string | BufferSource, name?: string) => Promise<SignedCookie>;
16
18
  export declare const serialize: (name: string, value: string, opt?: CookieOptions) => string;
@@ -0,0 +1,9 @@
1
+ // src/utils/color.ts
2
+ function getColorEnabled() {
3
+ const { process, Deno } = globalThis;
4
+ const isNoColor = typeof process !== "undefined" ? "NO_COLOR" in process?.env : typeof Deno?.noColor === "boolean" ? Deno.noColor : false;
5
+ return !isNoColor;
6
+ }
7
+ export {
8
+ getColorEnabled
9
+ };
@@ -0,0 +1,39 @@
1
+ // src/utils/concurrent.ts
2
+ var DEFAULT_CONCURRENCY = 1024;
3
+ var createPool = ({
4
+ concurrency,
5
+ interval
6
+ } = {}) => {
7
+ concurrency ||= DEFAULT_CONCURRENCY;
8
+ if (concurrency === Infinity) {
9
+ return {
10
+ run: async (fn) => fn()
11
+ };
12
+ }
13
+ const pool = /* @__PURE__ */ new Set();
14
+ const run = async (fn, promise, resolve) => {
15
+ if (pool.size >= concurrency) {
16
+ promise ||= new Promise((r) => resolve = r);
17
+ setTimeout(() => run(fn, promise, resolve));
18
+ return promise;
19
+ }
20
+ const marker = {};
21
+ pool.add(marker);
22
+ const result = await fn();
23
+ if (interval) {
24
+ setTimeout(() => pool.delete(marker), interval);
25
+ } else {
26
+ pool.delete(marker);
27
+ }
28
+ if (resolve) {
29
+ resolve(result);
30
+ return promise;
31
+ } else {
32
+ return result;
33
+ }
34
+ };
35
+ return { run };
36
+ };
37
+ export {
38
+ createPool
39
+ };
@@ -66,16 +66,40 @@ var parseSigned = async (cookie, secret, name) => {
66
66
  };
67
67
  var _serialize = (name, value, opt = {}) => {
68
68
  let cookie = `${name}=${value}`;
69
+ if (name.startsWith("__Secure-") && !opt.secure) {
70
+ throw new Error("__Secure- Cookie must have Secure attributes");
71
+ }
72
+ if (name.startsWith("__Host-")) {
73
+ if (!opt.secure) {
74
+ throw new Error("__Host- Cookie must have Secure attributes");
75
+ }
76
+ if (opt.path !== "/") {
77
+ throw new Error('__Host- Cookie must have Path attributes with "/"');
78
+ }
79
+ if (opt.domain) {
80
+ throw new Error("__Host- Cookie must not have Domain attributes");
81
+ }
82
+ }
69
83
  if (opt && typeof opt.maxAge === "number" && opt.maxAge >= 0) {
84
+ if (opt.maxAge > 3456e4) {
85
+ throw new Error(
86
+ "Cookies Max-Age SHOULD NOT be greater than 400 days (34560000 seconds) in duration."
87
+ );
88
+ }
70
89
  cookie += `; Max-Age=${Math.floor(opt.maxAge)}`;
71
90
  }
72
- if (opt.domain) {
91
+ if (opt.domain && opt.prefix !== "host") {
73
92
  cookie += `; Domain=${opt.domain}`;
74
93
  }
75
94
  if (opt.path) {
76
95
  cookie += `; Path=${opt.path}`;
77
96
  }
78
97
  if (opt.expires) {
98
+ if (opt.expires.getTime() - Date.now() > 3456e7) {
99
+ throw new Error(
100
+ "Cookies Expires SHOULD NOT be greater than 400 days (34560000 seconds) in the future."
101
+ );
102
+ }
79
103
  cookie += `; Expires=${opt.expires.toUTCString()}`;
80
104
  }
81
105
  if (opt.httpOnly) {
@@ -88,6 +112,9 @@ var _serialize = (name, value, opt = {}) => {
88
112
  cookie += `; SameSite=${opt.sameSite}`;
89
113
  }
90
114
  if (opt.partitioned) {
115
+ if (!opt.secure) {
116
+ throw new Error("Partitioned Cookie must have Secure attributes");
117
+ }
91
118
  cookie += "; Partitioned";
92
119
  }
93
120
  return cookie;
@@ -1,7 +1,11 @@
1
1
  // src/utils/stream.ts
2
2
  var StreamingApi = class {
3
+ writer;
4
+ encoder;
5
+ writable;
6
+ abortSubscribers = [];
7
+ responseReadable;
3
8
  constructor(writable, _readable) {
4
- this.abortSubscribers = [];
5
9
  this.writable = writable;
6
10
  this.writer = writable.getWriter();
7
11
  this.encoder = new TextEncoder();
package/dist/utils/url.js CHANGED
@@ -144,7 +144,7 @@ var _getQueryParam = (url, key, multiple) => {
144
144
  }
145
145
  }
146
146
  const results = {};
147
- encoded ?? (encoded = /[%+]/.test(url));
147
+ encoded ??= /[%+]/.test(url);
148
148
  let keyIndex = url.indexOf("?", 8);
149
149
  while (keyIndex !== -1) {
150
150
  const nextKeyIndex = url.indexOf("&", keyIndex + 1);
@@ -179,7 +179,7 @@ var _getQueryParam = (url, key, multiple) => {
179
179
  ;
180
180
  results[name].push(value);
181
181
  } else {
182
- results[name] ?? (results[name] = value);
182
+ results[name] ??= value;
183
183
  }
184
184
  }
185
185
  return key ? results[key] : results;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.0.10",
3
+ "version": "4.1.0",
4
4
  "description": "Ultrafast web framework for the Edges",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",
@@ -74,6 +74,11 @@
74
74
  "import": "./dist/middleware/bearer-auth/index.js",
75
75
  "require": "./dist/cjs/middleware/bearer-auth/index.js"
76
76
  },
77
+ "./body-limit": {
78
+ "types": "./dist/types/middleware/body-limit/index.d.ts",
79
+ "import": "./dist/middleware/body-limit/index.js",
80
+ "require": "./dist/cjs/middleware/body-limit/index.js"
81
+ },
77
82
  "./cache": {
78
83
  "types": "./dist/types/middleware/cache/index.d.ts",
79
84
  "import": "./dist/middleware/cache/index.js",
@@ -313,6 +318,11 @@
313
318
  "types": "./dist/types/helper/dev/index.d.ts",
314
319
  "import": "./dist/helper/dev/index.js",
315
320
  "require": "./dist/cjs/helper/dev/index.js"
321
+ },
322
+ "./ws": {
323
+ "types": "./dist/types/helper/websocket/index.d.ts",
324
+ "import": "./dist/helper/websocket/index.js",
325
+ "require": "./dist/cjs/helper/websocket/index.js"
316
326
  }
317
327
  },
318
328
  "typesVersions": {
@@ -338,6 +348,9 @@
338
348
  "bearer-auth": [
339
349
  "./dist/types/middleware/bearer-auth"
340
350
  ],
351
+ "body-limit": [
352
+ "./dist/types/middleware/body-limit"
353
+ ],
341
354
  "cache": [
342
355
  "./dist/types/middleware/cache"
343
356
  ],
@@ -475,6 +488,9 @@
475
488
  ],
476
489
  "dev": [
477
490
  "./dist/types/helper/dev"
491
+ ],
492
+ "ws": [
493
+ "./dist/types/helper/websocket"
478
494
  ]
479
495
  }
480
496
  },
@@ -508,7 +524,7 @@
508
524
  "devDependencies": {
509
525
  "@cloudflare/workers-types": "^4.20231121.0",
510
526
  "@hono/eslint-config": "^0.0.4",
511
- "@hono/node-server": "^1.3.3",
527
+ "@hono/node-server": "^1.8.2",
512
528
  "@types/crypto-js": "^4.1.1",
513
529
  "@types/glob": "^8.0.0",
514
530
  "@types/jsdom": "^21.1.4",