hono 4.9.12 → 4.10.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.
@@ -21,20 +21,38 @@ __export(proxy_exports, {
21
21
  proxy: () => proxy
22
22
  });
23
23
  module.exports = __toCommonJS(proxy_exports);
24
+ var import_http_exception = require("../../http-exception");
24
25
  const hopByHopHeaders = [
25
26
  "connection",
26
27
  "keep-alive",
27
28
  "proxy-authenticate",
28
29
  "proxy-authorization",
29
30
  "te",
30
- "trailers",
31
- "transfer-encoding"
31
+ "trailer",
32
+ "transfer-encoding",
33
+ "upgrade"
32
34
  ];
33
- const buildRequestInitFromRequest = (request) => {
35
+ const ALLOWED_TOKEN_PATTERN = /^[!#$%&'*+\-.0-9A-Z^_`a-z|~]+$/;
36
+ const buildRequestInitFromRequest = (request, strictConnectionProcessing) => {
34
37
  if (!request) {
35
38
  return {};
36
39
  }
37
40
  const headers = new Headers(request.headers);
41
+ if (strictConnectionProcessing) {
42
+ const connectionValue = headers.get("connection");
43
+ if (connectionValue) {
44
+ const headerNames = connectionValue.split(",").map((h) => h.trim());
45
+ const invalidHeaders = headerNames.filter((h) => !ALLOWED_TOKEN_PATTERN.test(h));
46
+ if (invalidHeaders.length > 0) {
47
+ throw new import_http_exception.HTTPException(400, {
48
+ message: `Invalid Connection header value: ${invalidHeaders.join(", ")}`
49
+ });
50
+ }
51
+ headerNames.forEach((headerName) => {
52
+ headers.delete(headerName);
53
+ });
54
+ }
55
+ }
38
56
  hopByHopHeaders.forEach((header) => {
39
57
  headers.delete(header);
40
58
  });
@@ -62,9 +80,14 @@ const preprocessRequestInit = (requestInit) => {
62
80
  return requestInit;
63
81
  };
64
82
  const proxy = async (input, proxyInit) => {
65
- const { raw, customFetch, ...requestInit } = proxyInit instanceof Request ? { raw: proxyInit } : proxyInit ?? {};
83
+ const {
84
+ raw,
85
+ customFetch,
86
+ strictConnectionProcessing = false,
87
+ ...requestInit
88
+ } = proxyInit instanceof Request ? { raw: proxyInit } : proxyInit ?? {};
66
89
  const req = new Request(input, {
67
- ...buildRequestInitFromRequest(raw),
90
+ ...buildRequestInitFromRequest(raw, strictConnectionProcessing),
68
91
  ...preprocessRequestInit(requestInit)
69
92
  });
70
93
  req.headers.delete("accept-encoding");
@@ -23,6 +23,7 @@ __export(ssg_exports, {
23
23
  combineAfterResponseHooks: () => combineAfterResponseHooks,
24
24
  combineBeforeRequestHooks: () => combineBeforeRequestHooks,
25
25
  defaultExtensionMap: () => defaultExtensionMap,
26
+ defaultPlugin: () => defaultPlugin,
26
27
  fetchRoutesContent: () => fetchRoutesContent,
27
28
  saveContentToFile: () => saveContentToFile,
28
29
  toSSG: () => toSSG
@@ -213,11 +214,19 @@ const saveContentToFile = async (data, fsModule, outDir, extensionMap) => {
213
214
  }
214
215
  return filePath;
215
216
  };
217
+ const defaultPlugin = {
218
+ afterResponseHook: (res) => {
219
+ if (res.status !== 200) {
220
+ return false;
221
+ }
222
+ return res;
223
+ }
224
+ };
216
225
  const toSSG = async (app, fs, options) => {
217
226
  let result;
218
227
  const getInfoPromises = [];
219
228
  const savePromises = [];
220
- const plugins = options?.plugins || [];
229
+ const plugins = options?.plugins || [defaultPlugin];
221
230
  const beforeRequestHooks = [];
222
231
  const afterResponseHooks = [];
223
232
  const afterGenerateHooks = [];
@@ -310,6 +319,7 @@ const toSSG = async (app, fs, options) => {
310
319
  combineAfterResponseHooks,
311
320
  combineBeforeRequestHooks,
312
321
  defaultExtensionMap,
322
+ defaultPlugin,
313
323
  fetchRoutesContent,
314
324
  saveContentToFile,
315
325
  toSSG
@@ -18,9 +18,11 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var request_exports = {};
20
20
  __export(request_exports, {
21
- HonoRequest: () => HonoRequest
21
+ HonoRequest: () => HonoRequest,
22
+ cloneRawRequest: () => cloneRawRequest
22
23
  });
23
24
  module.exports = __toCommonJS(request_exports);
25
+ var import_http_exception = require("./http-exception");
24
26
  var import_constants = require("./request/constants");
25
27
  var import_body = require("./utils/body");
26
28
  var import_url = require("./utils/url");
@@ -133,7 +135,34 @@ class HonoRequest {
133
135
  return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
134
136
  }
135
137
  }
138
+ const cloneRawRequest = async (req) => {
139
+ if (!req.raw.bodyUsed) {
140
+ return req.raw.clone();
141
+ }
142
+ const cacheKey = Object.keys(req.bodyCache)[0];
143
+ if (!cacheKey) {
144
+ throw new import_http_exception.HTTPException(500, {
145
+ message: "Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly."
146
+ });
147
+ }
148
+ const requestInit = {
149
+ body: await req[cacheKey](),
150
+ cache: req.raw.cache,
151
+ credentials: req.raw.credentials,
152
+ headers: req.header(),
153
+ integrity: req.raw.integrity,
154
+ keepalive: req.raw.keepalive,
155
+ method: req.method,
156
+ mode: req.raw.mode,
157
+ redirect: req.raw.redirect,
158
+ referrer: req.raw.referrer,
159
+ referrerPolicy: req.raw.referrerPolicy,
160
+ signal: req.raw.signal
161
+ };
162
+ return new Request(req.url, requestInit);
163
+ };
136
164
  // Annotate the CommonJS export names for ESM import in node:
137
165
  0 && (module.exports = {
138
- HonoRequest
166
+ HonoRequest,
167
+ cloneRawRequest
139
168
  });
@@ -100,7 +100,7 @@ const validator = (target, validationFunc) => {
100
100
  return res;
101
101
  }
102
102
  c.req.addValidatedData(target, res);
103
- await next();
103
+ return await next();
104
104
  };
105
105
  };
106
106
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,18 +1,36 @@
1
1
  // src/helper/proxy/index.ts
2
+ import { HTTPException } from "../../http-exception.js";
2
3
  var hopByHopHeaders = [
3
4
  "connection",
4
5
  "keep-alive",
5
6
  "proxy-authenticate",
6
7
  "proxy-authorization",
7
8
  "te",
8
- "trailers",
9
- "transfer-encoding"
9
+ "trailer",
10
+ "transfer-encoding",
11
+ "upgrade"
10
12
  ];
11
- var buildRequestInitFromRequest = (request) => {
13
+ var ALLOWED_TOKEN_PATTERN = /^[!#$%&'*+\-.0-9A-Z^_`a-z|~]+$/;
14
+ var buildRequestInitFromRequest = (request, strictConnectionProcessing) => {
12
15
  if (!request) {
13
16
  return {};
14
17
  }
15
18
  const headers = new Headers(request.headers);
19
+ if (strictConnectionProcessing) {
20
+ const connectionValue = headers.get("connection");
21
+ if (connectionValue) {
22
+ const headerNames = connectionValue.split(",").map((h) => h.trim());
23
+ const invalidHeaders = headerNames.filter((h) => !ALLOWED_TOKEN_PATTERN.test(h));
24
+ if (invalidHeaders.length > 0) {
25
+ throw new HTTPException(400, {
26
+ message: `Invalid Connection header value: ${invalidHeaders.join(", ")}`
27
+ });
28
+ }
29
+ headerNames.forEach((headerName) => {
30
+ headers.delete(headerName);
31
+ });
32
+ }
33
+ }
16
34
  hopByHopHeaders.forEach((header) => {
17
35
  headers.delete(header);
18
36
  });
@@ -40,9 +58,14 @@ var preprocessRequestInit = (requestInit) => {
40
58
  return requestInit;
41
59
  };
42
60
  var proxy = async (input, proxyInit) => {
43
- const { raw, customFetch, ...requestInit } = proxyInit instanceof Request ? { raw: proxyInit } : proxyInit ?? {};
61
+ const {
62
+ raw,
63
+ customFetch,
64
+ strictConnectionProcessing = false,
65
+ ...requestInit
66
+ } = proxyInit instanceof Request ? { raw: proxyInit } : proxyInit ?? {};
44
67
  const req = new Request(input, {
45
- ...buildRequestInitFromRequest(raw),
68
+ ...buildRequestInitFromRequest(raw, strictConnectionProcessing),
46
69
  ...preprocessRequestInit(requestInit)
47
70
  });
48
71
  req.headers.delete("accept-encoding");
@@ -184,11 +184,19 @@ var saveContentToFile = async (data, fsModule, outDir, extensionMap) => {
184
184
  }
185
185
  return filePath;
186
186
  };
187
+ var defaultPlugin = {
188
+ afterResponseHook: (res) => {
189
+ if (res.status !== 200) {
190
+ return false;
191
+ }
192
+ return res;
193
+ }
194
+ };
187
195
  var toSSG = async (app, fs, options) => {
188
196
  let result;
189
197
  const getInfoPromises = [];
190
198
  const savePromises = [];
191
- const plugins = options?.plugins || [];
199
+ const plugins = options?.plugins || [defaultPlugin];
192
200
  const beforeRequestHooks = [];
193
201
  const afterResponseHooks = [];
194
202
  const afterGenerateHooks = [];
@@ -280,6 +288,7 @@ export {
280
288
  combineAfterResponseHooks,
281
289
  combineBeforeRequestHooks,
282
290
  defaultExtensionMap,
291
+ defaultPlugin,
283
292
  fetchRoutesContent,
284
293
  saveContentToFile,
285
294
  toSSG
package/dist/request.js CHANGED
@@ -1,4 +1,5 @@
1
1
  // src/request.ts
2
+ import { HTTPException } from "./http-exception.js";
2
3
  import { GET_MATCH_RESULT } from "./request/constants.js";
3
4
  import { parseBody } from "./utils/body.js";
4
5
  import { decodeURIComponent_, getQueryParam, getQueryParams, tryDecode } from "./utils/url.js";
@@ -111,6 +112,33 @@ var HonoRequest = class {
111
112
  return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;
112
113
  }
113
114
  };
115
+ var cloneRawRequest = async (req) => {
116
+ if (!req.raw.bodyUsed) {
117
+ return req.raw.clone();
118
+ }
119
+ const cacheKey = Object.keys(req.bodyCache)[0];
120
+ if (!cacheKey) {
121
+ throw new HTTPException(500, {
122
+ message: "Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly."
123
+ });
124
+ }
125
+ const requestInit = {
126
+ body: await req[cacheKey](),
127
+ cache: req.raw.cache,
128
+ credentials: req.raw.credentials,
129
+ headers: req.header(),
130
+ integrity: req.raw.integrity,
131
+ keepalive: req.raw.keepalive,
132
+ method: req.method,
133
+ mode: req.raw.mode,
134
+ redirect: req.raw.redirect,
135
+ referrer: req.raw.referrer,
136
+ referrerPolicy: req.raw.referrerPolicy,
137
+ signal: req.raw.signal
138
+ };
139
+ return new Request(req.url, requestInit);
140
+ };
114
141
  export {
115
- HonoRequest
142
+ HonoRequest,
143
+ cloneRawRequest
116
144
  };
@@ -344,12 +344,12 @@ export declare class Factory<E extends Env = Env, P extends string = string> {
344
344
  defaultAppOptions?: HonoOptions<E>;
345
345
  });
346
346
  createApp: (options?: HonoOptions<E>) => Hono<E>;
347
- createMiddleware: <I extends Input = {}>(middleware: MiddlewareHandler<E, P, I>) => MiddlewareHandler<E, P, I>;
347
+ createMiddleware: <I extends Input = {}, R extends HandlerResponse<any> | void = void>(middleware: MiddlewareHandler<E, P, I, R extends void ? Response : R>) => MiddlewareHandler<E, P, I, R extends void ? Response : R>;
348
348
  createHandlers: CreateHandlersInterface<E, P>;
349
349
  }
350
350
  export declare const createFactory: <E extends Env = Env, P extends string = string>(init?: {
351
351
  initApp?: InitApp<E>;
352
352
  defaultAppOptions?: HonoOptions<E>;
353
353
  }) => Factory<E, P>;
354
- export declare const createMiddleware: <E extends Env = any, P extends string = string, I extends Input = {}>(middleware: MiddlewareHandler<E, P, I>) => MiddlewareHandler<E, P, I>;
354
+ export declare const createMiddleware: <E extends Env = any, P extends string = string, I extends Input = {}, R extends HandlerResponse<any> | void = void>(middleware: MiddlewareHandler<E, P, I, R extends void ? Response : R>) => MiddlewareHandler<E, P, I, R extends void ? Response : R>;
355
355
  export {};
@@ -10,6 +10,18 @@ interface ProxyRequestInit extends Omit<RequestInit, "headers"> {
10
10
  string
11
11
  ][] | Record<RequestHeader, string | undefined> | Record<string, string | undefined>;
12
12
  customFetch?: (request: Request) => Promise<Response>;
13
+ /**
14
+ * Enable strict RFC 9110 compliance for Connection header processing.
15
+ *
16
+ * - `false` (default): Ignores Connection header to prevent potential
17
+ * Hop-by-Hop Header Injection attacks. Recommended for untrusted clients.
18
+ * - `true`: Processes Connection header per RFC 9110 and removes listed headers.
19
+ * Only use in trusted environments.
20
+ *
21
+ * @default false
22
+ * @see https://datatracker.ietf.org/doc/html/rfc9110#section-7.6.1
23
+ */
24
+ strictConnectionProcessing?: boolean;
13
25
  }
14
26
  interface ProxyFetch {
15
27
  (input: string | URL | Request, init?: ProxyRequestInit): Promise<Response>;
@@ -49,6 +61,14 @@ interface ProxyFetch {
49
61
  * },
50
62
  * })
51
63
  * })
64
+ *
65
+ * // Strict RFC compliance mode (use only in trusted environments)
66
+ * app.get('/internal-proxy/:path', (c) => {
67
+ * return proxy(`http://${internalServer}/${c.req.param('path')}`, {
68
+ * ...c.req,
69
+ * strictConnectionProcessing: true,
70
+ * })
71
+ * })
52
72
  * ```
53
73
  */
54
74
  export declare const proxy: ProxyFetch;
@@ -83,6 +83,14 @@ export interface ToSSGInterface {
83
83
  export interface ToSSGAdaptorInterface<E extends Env = Env, S extends Schema = {}, BasePath extends string = "/"> {
84
84
  (app: Hono<E, S, BasePath>, options?: ToSSGOptions): Promise<ToSSGResult>;
85
85
  }
86
+ /**
87
+ * The default plugin that defines the recommended behavior.
88
+ *
89
+ * @experimental
90
+ * `defaultPlugin` is an experimental feature.
91
+ * The API might be changed.
92
+ */
93
+ export declare const defaultPlugin: SSGPlugin;
86
94
  /**
87
95
  * @experimental
88
96
  * `toSSG` is an experimental feature.
@@ -283,4 +283,36 @@ export declare class HonoRequest<P extends string = "/", I extends Input["out"]
283
283
  */
284
284
  get routePath(): string;
285
285
  }
286
+ /**
287
+ * Clones a HonoRequest's underlying raw Request object.
288
+ *
289
+ * This utility handles both consumed and unconsumed request bodies:
290
+ * - If the request body hasn't been consumed, it uses the native `clone()` method
291
+ * - If the request body has been consumed, it reconstructs a new Request using cached body data
292
+ *
293
+ * This is particularly useful when you need to:
294
+ * - Process the same request body multiple times
295
+ * - Pass requests to external services after validation
296
+ *
297
+ * @param req - The HonoRequest object to clone
298
+ * @returns A Promise that resolves to a new Request object with the same properties
299
+ * @throws {HTTPException} If the request body was consumed directly via `req.raw`
300
+ * without using HonoRequest methods (e.g., `req.json()`, `req.text()`), making it
301
+ * impossible to reconstruct the body from cache
302
+ *
303
+ * @example
304
+ * ```ts
305
+ * // Clone after consuming the body (e.g., after validation)
306
+ * app.post('/forward',
307
+ * validator('json', (data) => data),
308
+ * async (c) => {
309
+ * const validated = c.req.valid('json')
310
+ * // Body has been consumed, but cloneRawRequest still works
311
+ * const clonedReq = await cloneRawRequest(c.req)
312
+ * return fetch('http://backend-service.com', clonedReq)
313
+ * }
314
+ * )
315
+ * ```
316
+ */
317
+ export declare const cloneRawRequest: (req: HonoRequest) => Promise<Request>;
286
318
  export {};
@@ -31,8 +31,8 @@ export interface RouterRoute {
31
31
  }
32
32
  export type HandlerResponse<O> = Response | TypedResponse<O> | Promise<Response | TypedResponse<O>>;
33
33
  export type Handler<E extends Env = any, P extends string = any, I extends Input = BlankInput, R extends HandlerResponse<any> = any> = (c: Context<E, P, I>, next: Next) => R;
34
- export type MiddlewareHandler<E extends Env = any, P extends string = string, I extends Input = {}> = (c: Context<E, P, I>, next: Next) => Promise<Response | void>;
35
- export type H<E extends Env = any, P extends string = any, I extends Input = BlankInput, R extends HandlerResponse<any> = any> = Handler<E, P, I, R> | MiddlewareHandler<E, P, I>;
34
+ export type MiddlewareHandler<E extends Env = any, P extends string = string, I extends Input = {}, R extends HandlerResponse<any> = Response> = (c: Context<E, P, I>, next: Next) => Promise<R | void>;
35
+ export type H<E extends Env = any, P extends string = any, I extends Input = BlankInput, R extends HandlerResponse<any> = any> = Handler<E, P, I, R> | MiddlewareHandler<E, P, I, R>;
36
36
  export type NotFoundHandler<E extends Env = any> = (c: Context<E>) => Response | Promise<Response>;
37
37
  export interface HTTPResponseError extends Error {
38
38
  getResponse: () => Response;
@@ -46,14 +46,14 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
46
46
  <P extends string = ExtractStringKey<S> extends never ? BasePath : ExtractStringKey<S>, I extends Input = BlankInput, I2 extends Input = I, R extends HandlerResponse<any> = any, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
47
47
  E,
48
48
  E2
49
- ]>>(...handlers: [
50
- H<E2, P, I>,
49
+ ]>, M1 extends H<E2, P, any> = H<E2, P, any>>(...handlers: [
50
+ H<E2, P, I> & M1,
51
51
  H<E3, P, I2, R>
52
52
  ]): HonoBase<IntersectNonAnyTypes<[
53
53
  E,
54
54
  E2,
55
55
  E3
56
- ]>, S & ToSchema<M, P, I2, MergeTypedResponse<R>>, BasePath>;
56
+ ]>, S & ToSchema<M, P, I2, MergeTypedResponse<R> | MergeMiddlewareResponse<M1>>, BasePath>;
57
57
  <P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, E2 extends Env = E>(path: P, handler: H<E2, MergedPath, I, R>): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath>;
58
58
  <P extends string = ExtractStringKey<S> extends never ? BasePath : ExtractStringKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
59
59
  E,
@@ -62,23 +62,23 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
62
62
  E,
63
63
  E2,
64
64
  E3
65
- ]>>(...handlers: [
66
- H<E2, P, I>,
67
- H<E3, P, I2>,
65
+ ]>, M1 extends H<E2, P, any> = H<E2, P, any>, M2 extends H<E3, P, any> = H<E3, P, any>>(...handlers: [
66
+ H<E2, P, I> & M1,
67
+ H<E3, P, I2> & M2,
68
68
  H<E4, P, I3, R>
69
69
  ]): HonoBase<IntersectNonAnyTypes<[
70
70
  E,
71
71
  E2,
72
72
  E3,
73
73
  E4
74
- ]>, S & ToSchema<M, P, I3, MergeTypedResponse<R>>, BasePath>;
74
+ ]>, S & ToSchema<M, P, I3, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2>>, BasePath>;
75
75
  <P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
76
76
  E,
77
77
  E2
78
- ]>>(path: P, ...handlers: [
79
- H<E2, MergedPath, I>,
78
+ ]>, M1 extends H<E2, MergedPath, any> = H<E2, MergedPath, any>>(path: P, ...handlers: [
79
+ H<E2, MergedPath, I> & M1,
80
80
  H<E3, MergedPath, I2, R>
81
- ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I2, MergeTypedResponse<R>>, BasePath>;
81
+ ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I2, MergeTypedResponse<R> | MergeMiddlewareResponse<M1>>, BasePath>;
82
82
  <P extends string = ExtractStringKey<S> extends never ? BasePath : ExtractStringKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
83
83
  E,
84
84
  E2
@@ -91,10 +91,10 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
91
91
  E2,
92
92
  E3,
93
93
  E4
94
- ]>>(...handlers: [
95
- H<E2, P, I>,
96
- H<E3, P, I2>,
97
- H<E4, P, I3>,
94
+ ]>, M1 extends H<E2, P, any> = H<E2, P, any>, M2 extends H<E3, P, any> = H<E3, P, any>, M3 extends H<E4, P, any> = H<E4, P, any>>(...handlers: [
95
+ H<E2, P, I> & M1,
96
+ H<E3, P, I2> & M2,
97
+ H<E4, P, I3> & M3,
98
98
  H<E5, P, I4, R>
99
99
  ]): HonoBase<IntersectNonAnyTypes<[
100
100
  E,
@@ -102,7 +102,7 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
102
102
  E3,
103
103
  E4,
104
104
  E5
105
- ]>, S & ToSchema<M, P, I4, MergeTypedResponse<R>>, BasePath>;
105
+ ]>, S & ToSchema<M, P, I4, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3>>, BasePath>;
106
106
  <P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
107
107
  E,
108
108
  E2
@@ -110,11 +110,11 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
110
110
  E,
111
111
  E2,
112
112
  E3
113
- ]>>(path: P, ...handlers: [
114
- H<E2, MergedPath, I>,
115
- H<E3, MergedPath, I2>,
113
+ ]>, M1 extends H<E2, MergedPath, any> = H<E2, MergedPath, any>, M2 extends H<E3, MergedPath, any> = H<E3, MergedPath, any>>(path: P, ...handlers: [
114
+ H<E2, MergedPath, I> & M1,
115
+ H<E3, MergedPath, I2> & M2,
116
116
  H<E4, MergedPath, I3, R>
117
- ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I3, MergeTypedResponse<R>>, BasePath>;
117
+ ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I3, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2>>, BasePath>;
118
118
  <P extends string = ExtractStringKey<S> extends never ? BasePath : ExtractStringKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
119
119
  E,
120
120
  E2
@@ -133,11 +133,11 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
133
133
  E3,
134
134
  E4,
135
135
  E5
136
- ]>>(...handlers: [
137
- H<E2, P, I>,
138
- H<E3, P, I2>,
139
- H<E4, P, I3>,
140
- H<E5, P, I4>,
136
+ ]>, M1 extends H<E2, P, any> = H<E2, P, any>, M2 extends H<E3, P, any> = H<E3, P, any>, M3 extends H<E4, P, any> = H<E4, P, any>, M4 extends H<E5, P, any> = H<E5, P, any>>(...handlers: [
137
+ H<E2, P, I> & M1,
138
+ H<E3, P, I2> & M2,
139
+ H<E4, P, I3> & M3,
140
+ H<E5, P, I4> & M4,
141
141
  H<E6, P, I5, R>
142
142
  ]): HonoBase<IntersectNonAnyTypes<[
143
143
  E,
@@ -146,7 +146,7 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
146
146
  E4,
147
147
  E5,
148
148
  E6
149
- ]>, S & ToSchema<M, P, I5, MergeTypedResponse<R>>, BasePath>;
149
+ ]>, S & ToSchema<M, P, I5, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4>>, BasePath>;
150
150
  <P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
151
151
  E,
152
152
  E2
@@ -159,12 +159,12 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
159
159
  E2,
160
160
  E3,
161
161
  E4
162
- ]>>(path: P, ...handlers: [
163
- H<E2, MergedPath, I>,
164
- H<E3, MergedPath, I2>,
165
- H<E4, MergedPath, I3>,
162
+ ]>, M1 extends H<E2, MergedPath, any> = H<E2, MergedPath, any>, M2 extends H<E3, MergedPath, any> = H<E3, MergedPath, any>, M3 extends H<E4, MergedPath, any> = H<E4, MergedPath, any>>(path: P, ...handlers: [
163
+ H<E2, MergedPath, I> & M1,
164
+ H<E3, MergedPath, I2> & M2,
165
+ H<E4, MergedPath, I3> & M3,
166
166
  H<E5, MergedPath, I4, R>
167
- ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I4, MergeTypedResponse<R>>, BasePath>;
167
+ ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I4, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3>>, BasePath>;
168
168
  <P extends string = ExtractStringKey<S> extends never ? BasePath : ExtractStringKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
169
169
  E,
170
170
  E2
@@ -190,12 +190,12 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
190
190
  E4,
191
191
  E5,
192
192
  E6
193
- ]>>(...handlers: [
194
- H<E2, P, I>,
195
- H<E3, P, I2>,
196
- H<E4, P, I3>,
197
- H<E5, P, I4>,
198
- H<E6, P, I5>,
193
+ ]>, M1 extends H<E2, P, any> = H<E2, P, any>, M2 extends H<E3, P, any> = H<E3, P, any>, M3 extends H<E4, P, any> = H<E4, P, any>, M4 extends H<E5, P, any> = H<E5, P, any>, M5 extends H<E6, P, any> = H<E6, P, any>>(...handlers: [
194
+ H<E2, P, I> & M1,
195
+ H<E3, P, I2> & M2,
196
+ H<E4, P, I3> & M3,
197
+ H<E5, P, I4> & M4,
198
+ H<E6, P, I5> & M5,
199
199
  H<E7, P, I6, R>
200
200
  ]): HonoBase<IntersectNonAnyTypes<[
201
201
  E,
@@ -205,7 +205,7 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
205
205
  E5,
206
206
  E6,
207
207
  E7
208
- ]>, S & ToSchema<M, P, I6, MergeTypedResponse<R>>, BasePath>;
208
+ ]>, S & ToSchema<M, P, I6, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5>>, BasePath>;
209
209
  <P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
210
210
  E,
211
211
  E2
@@ -224,13 +224,13 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
224
224
  E3,
225
225
  E4,
226
226
  E5
227
- ]>>(path: P, ...handlers: [
228
- H<E2, MergedPath, I>,
229
- H<E3, MergedPath, I2>,
230
- H<E4, MergedPath, I3>,
231
- H<E5, MergedPath, I4>,
227
+ ]>, M1 extends H<E2, MergedPath, any> = H<E2, MergedPath, any>, M2 extends H<E3, MergedPath, any> = H<E3, MergedPath, any>, M3 extends H<E4, MergedPath, any> = H<E4, MergedPath, any>, M4 extends H<E5, MergedPath, any> = H<E5, MergedPath, any>>(path: P, ...handlers: [
228
+ H<E2, MergedPath, I> & M1,
229
+ H<E3, MergedPath, I2> & M2,
230
+ H<E4, MergedPath, I3> & M3,
231
+ H<E5, MergedPath, I4> & M4,
232
232
  H<E6, MergedPath, I5, R>
233
- ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I5, MergeTypedResponse<R>>, BasePath>;
233
+ ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I5, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4>>, BasePath>;
234
234
  <P extends string = ExtractStringKey<S> extends never ? BasePath : ExtractStringKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
235
235
  E,
236
236
  E2
@@ -264,13 +264,13 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
264
264
  E5,
265
265
  E6,
266
266
  E7
267
- ]>>(...handlers: [
268
- H<E2, P, I>,
269
- H<E3, P, I2>,
270
- H<E4, P, I3>,
271
- H<E5, P, I4>,
272
- H<E6, P, I5>,
273
- H<E7, P, I6>,
267
+ ]>, M1 extends H<E2, P, any> = H<E2, P, any>, M2 extends H<E3, P, any> = H<E3, P, any>, M3 extends H<E4, P, any> = H<E4, P, any>, M4 extends H<E5, P, any> = H<E5, P, any>, M5 extends H<E6, P, any> = H<E6, P, any>, M6 extends H<E7, P, any> = H<E7, P, any>>(...handlers: [
268
+ H<E2, P, I> & M1,
269
+ H<E3, P, I2> & M2,
270
+ H<E4, P, I3> & M3,
271
+ H<E5, P, I4> & M4,
272
+ H<E6, P, I5> & M5,
273
+ H<E7, P, I6> & M6,
274
274
  H<E8, P, I7, R>
275
275
  ]): HonoBase<IntersectNonAnyTypes<[
276
276
  E,
@@ -281,7 +281,7 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
281
281
  E6,
282
282
  E7,
283
283
  E8
284
- ]>, S & ToSchema<M, P, I7, MergeTypedResponse<R>>, BasePath>;
284
+ ]>, S & ToSchema<M, P, I7, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6>>, BasePath>;
285
285
  <P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
286
286
  E,
287
287
  E2
@@ -307,14 +307,14 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
307
307
  E4,
308
308
  E5,
309
309
  E6
310
- ]>>(path: P, ...handlers: [
311
- H<E2, MergedPath, I>,
312
- H<E3, MergedPath, I2>,
313
- H<E4, MergedPath, I3>,
314
- H<E5, MergedPath, I4>,
315
- H<E6, MergedPath, I5>,
310
+ ]>, M1 extends H<E2, MergedPath, any> = H<E2, MergedPath, any>, M2 extends H<E3, MergedPath, any> = H<E3, MergedPath, any>, M3 extends H<E4, MergedPath, any> = H<E4, MergedPath, any>, M4 extends H<E5, MergedPath, any> = H<E5, MergedPath, any>, M5 extends H<E6, MergedPath, any> = H<E6, MergedPath, any>>(path: P, ...handlers: [
311
+ H<E2, MergedPath, I> & M1,
312
+ H<E3, MergedPath, I2> & M2,
313
+ H<E4, MergedPath, I3> & M3,
314
+ H<E5, MergedPath, I4> & M4,
315
+ H<E6, MergedPath, I5> & M5,
316
316
  H<E7, MergedPath, I6, R>
317
- ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I6, MergeTypedResponse<R>>, BasePath>;
317
+ ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I6, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5>>, BasePath>;
318
318
  <P extends string = ExtractStringKey<S> extends never ? BasePath : ExtractStringKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
319
319
  E,
320
320
  E2
@@ -357,14 +357,14 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
357
357
  E6,
358
358
  E7,
359
359
  E8
360
- ]>>(...handlers: [
361
- H<E2, P, I>,
362
- H<E3, P, I2>,
363
- H<E4, P, I3>,
364
- H<E5, P, I4>,
365
- H<E6, P, I5>,
366
- H<E7, P, I6>,
367
- H<E8, P, I7>,
360
+ ]>, M1 extends H<E2, P, any> = H<E2, P, any>, M2 extends H<E3, P, any> = H<E3, P, any>, M3 extends H<E4, P, any> = H<E4, P, any>, M4 extends H<E5, P, any> = H<E5, P, any>, M5 extends H<E6, P, any> = H<E6, P, any>, M6 extends H<E7, P, any> = H<E7, P, any>, M7 extends H<E8, P, any> = H<E8, P, any>>(...handlers: [
361
+ H<E2, P, I> & M1,
362
+ H<E3, P, I2> & M2,
363
+ H<E4, P, I3> & M3,
364
+ H<E5, P, I4> & M4,
365
+ H<E6, P, I5> & M5,
366
+ H<E7, P, I6> & M6,
367
+ H<E8, P, I7> & M7,
368
368
  H<E9, P, I8, R>
369
369
  ]): HonoBase<IntersectNonAnyTypes<[
370
370
  E,
@@ -376,7 +376,7 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
376
376
  E7,
377
377
  E8,
378
378
  E9
379
- ]>, S & ToSchema<M, P, I8, MergeTypedResponse<R>>, BasePath>;
379
+ ]>, S & ToSchema<M, P, I8, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7>>, BasePath>;
380
380
  <P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
381
381
  E,
382
382
  E2
@@ -410,15 +410,15 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
410
410
  E5,
411
411
  E6,
412
412
  E7
413
- ]>>(path: P, ...handlers: [
414
- H<E2, MergedPath, I>,
415
- H<E3, MergedPath, I2>,
416
- H<E4, MergedPath, I3>,
417
- H<E5, MergedPath, I4>,
418
- H<E6, MergedPath, I5>,
419
- H<E7, MergedPath, I6>,
413
+ ]>, M1 extends H<E2, MergedPath, any> = H<E2, MergedPath, any>, M2 extends H<E3, MergedPath, any> = H<E3, MergedPath, any>, M3 extends H<E4, MergedPath, any> = H<E4, MergedPath, any>, M4 extends H<E5, MergedPath, any> = H<E5, MergedPath, any>, M5 extends H<E6, MergedPath, any> = H<E6, MergedPath, any>, M6 extends H<E7, MergedPath, any> = H<E7, MergedPath, any>>(path: P, ...handlers: [
414
+ H<E2, MergedPath, I> & M1,
415
+ H<E3, MergedPath, I2> & M2,
416
+ H<E4, MergedPath, I3> & M3,
417
+ H<E5, MergedPath, I4> & M4,
418
+ H<E6, MergedPath, I5> & M5,
419
+ H<E7, MergedPath, I6> & M6,
420
420
  H<E8, MergedPath, I7, R>
421
- ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I7, MergeTypedResponse<R>>, BasePath>;
421
+ ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I7, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6>>, BasePath>;
422
422
  <P extends string = ExtractStringKey<S> extends never ? BasePath : ExtractStringKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
423
423
  E,
424
424
  E2
@@ -471,15 +471,15 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
471
471
  E7,
472
472
  E8,
473
473
  E9
474
- ]>>(...handlers: [
475
- H<E2, P, I>,
476
- H<E3, P, I2>,
477
- H<E4, P, I3>,
478
- H<E5, P, I4>,
479
- H<E6, P, I5>,
480
- H<E7, P, I6>,
481
- H<E8, P, I7>,
482
- H<E9, P, I8>,
474
+ ]>, M1 extends H<E2, P, any> = H<E2, P, any>, M2 extends H<E3, P, any> = H<E3, P, any>, M3 extends H<E4, P, any> = H<E4, P, any>, M4 extends H<E5, P, any> = H<E5, P, any>, M5 extends H<E6, P, any> = H<E6, P, any>, M6 extends H<E7, P, any> = H<E7, P, any>, M7 extends H<E8, P, any> = H<E8, P, any>, M8 extends H<E9, P, any> = H<E9, P, any>>(...handlers: [
475
+ H<E2, P, I> & M1,
476
+ H<E3, P, I2> & M2,
477
+ H<E4, P, I3> & M3,
478
+ H<E5, P, I4> & M4,
479
+ H<E6, P, I5> & M5,
480
+ H<E7, P, I6> & M6,
481
+ H<E8, P, I7> & M7,
482
+ H<E9, P, I8> & M8,
483
483
  H<E10, P, I9, R>
484
484
  ]): HonoBase<IntersectNonAnyTypes<[
485
485
  E,
@@ -492,7 +492,7 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
492
492
  E8,
493
493
  E9,
494
494
  E10
495
- ]>, S & ToSchema<M, P, I9, MergeTypedResponse<R>>, BasePath>;
495
+ ]>, S & ToSchema<M, P, I9, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8>>, BasePath>;
496
496
  <P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
497
497
  E,
498
498
  E2
@@ -535,16 +535,16 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
535
535
  E6,
536
536
  E7,
537
537
  E8
538
- ]>>(path: P, ...handlers: [
539
- H<E2, MergedPath, I>,
540
- H<E3, MergedPath, I2>,
541
- H<E4, MergedPath, I3>,
542
- H<E5, MergedPath, I4>,
543
- H<E6, MergedPath, I5>,
544
- H<E7, MergedPath, I6>,
545
- H<E8, MergedPath, I7>,
538
+ ]>, M1 extends H<E2, MergedPath, any> = H<E2, MergedPath, any>, M2 extends H<E3, MergedPath, any> = H<E3, MergedPath, any>, M3 extends H<E4, MergedPath, any> = H<E4, MergedPath, any>, M4 extends H<E5, MergedPath, any> = H<E5, MergedPath, any>, M5 extends H<E6, MergedPath, any> = H<E6, MergedPath, any>, M6 extends H<E7, MergedPath, any> = H<E7, MergedPath, any>, M7 extends H<E8, MergedPath, any> = H<E8, MergedPath, any>>(path: P, ...handlers: [
539
+ H<E2, MergedPath, I> & M1,
540
+ H<E3, MergedPath, I2> & M2,
541
+ H<E4, MergedPath, I3> & M3,
542
+ H<E5, MergedPath, I4> & M4,
543
+ H<E6, MergedPath, I5> & M5,
544
+ H<E7, MergedPath, I6> & M6,
545
+ H<E8, MergedPath, I7> & M7,
546
546
  H<E9, MergedPath, I8, R>
547
- ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I8, MergeTypedResponse<R>>, BasePath>;
547
+ ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I8, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7>>, BasePath>;
548
548
  <P extends string = ExtractStringKey<S> extends never ? BasePath : ExtractStringKey<S>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
549
549
  E,
550
550
  E2
@@ -608,16 +608,16 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
608
608
  E8,
609
609
  E9,
610
610
  E10
611
- ]>>(...handlers: [
612
- H<E2, P, I>,
613
- H<E3, P, I2>,
614
- H<E4, P, I3>,
615
- H<E5, P, I4>,
616
- H<E6, P, I5>,
617
- H<E7, P, I6>,
618
- H<E8, P, I7>,
619
- H<E9, P, I8>,
620
- H<E10, P, I9>,
611
+ ]>, M1 extends H<E2, P, any> = H<E2, P, any>, M2 extends H<E3, P, any> = H<E3, P, any>, M3 extends H<E4, P, any> = H<E4, P, any>, M4 extends H<E5, P, any> = H<E5, P, any>, M5 extends H<E6, P, any> = H<E6, P, any>, M6 extends H<E7, P, any> = H<E7, P, any>, M7 extends H<E8, P, any> = H<E8, P, any>, M8 extends H<E9, P, any> = H<E9, P, any>, M9 extends H<E10, P, any> = H<E10, P, any>>(...handlers: [
612
+ H<E2, P, I> & M1,
613
+ H<E3, P, I2> & M2,
614
+ H<E4, P, I3> & M3,
615
+ H<E5, P, I4> & M4,
616
+ H<E6, P, I5> & M5,
617
+ H<E7, P, I6> & M6,
618
+ H<E8, P, I7> & M7,
619
+ H<E9, P, I8> & M8,
620
+ H<E10, P, I9> & M9,
621
621
  H<E11, P, I10, R>
622
622
  ]): HonoBase<IntersectNonAnyTypes<[
623
623
  E,
@@ -631,7 +631,7 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
631
631
  E9,
632
632
  E10,
633
633
  E11
634
- ]>, S & ToSchema<M, P, I10, MergeTypedResponse<R>>, BasePath>;
634
+ ]>, S & ToSchema<M, P, I10, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8> | MergeMiddlewareResponse<M9>>, BasePath>;
635
635
  <P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
636
636
  E,
637
637
  E2
@@ -684,17 +684,17 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
684
684
  E7,
685
685
  E8,
686
686
  E9
687
- ]>>(path: P, ...handlers: [
688
- H<E2, MergedPath, I>,
689
- H<E3, MergedPath, I2>,
690
- H<E4, MergedPath, I3>,
691
- H<E5, MergedPath, I4>,
692
- H<E6, MergedPath, I5>,
693
- H<E7, MergedPath, I6>,
694
- H<E8, MergedPath, I7>,
695
- H<E9, MergedPath, I8>,
687
+ ]>, M1 extends H<E2, MergedPath, any> = H<E2, MergedPath, any>, M2 extends H<E3, MergedPath, any> = H<E3, MergedPath, any>, M3 extends H<E4, MergedPath, any> = H<E4, MergedPath, any>, M4 extends H<E5, MergedPath, any> = H<E5, MergedPath, any>, M5 extends H<E6, MergedPath, any> = H<E6, MergedPath, any>, M6 extends H<E7, MergedPath, any> = H<E7, MergedPath, any>, M7 extends H<E8, MergedPath, any> = H<E8, MergedPath, any>, M8 extends H<E9, MergedPath, any> = H<E9, MergedPath, any>>(path: P, ...handlers: [
688
+ H<E2, MergedPath, I> & M1,
689
+ H<E3, MergedPath, I2> & M2,
690
+ H<E4, MergedPath, I3> & M3,
691
+ H<E5, MergedPath, I4> & M4,
692
+ H<E6, MergedPath, I5> & M5,
693
+ H<E7, MergedPath, I6> & M6,
694
+ H<E8, MergedPath, I7> & M7,
695
+ H<E9, MergedPath, I8> & M8,
696
696
  H<E10, MergedPath, I9, R>
697
- ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I9, MergeTypedResponse<R>>, BasePath>;
697
+ ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I9, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8>>, BasePath>;
698
698
  <P extends string, MergedPath extends MergePath<BasePath, P>, R extends HandlerResponse<any> = any, I extends Input = BlankInput, I2 extends Input = I, I3 extends Input = I & I2, I4 extends Input = I & I2 & I3, I5 extends Input = I & I2 & I3 & I4, I6 extends Input = I & I2 & I3 & I4 & I5, I7 extends Input = I & I2 & I3 & I4 & I5 & I6, I8 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7, I9 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8, I10 extends Input = I & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9, E2 extends Env = E, E3 extends Env = IntersectNonAnyTypes<[
699
699
  E,
700
700
  E2
@@ -758,18 +758,18 @@ export interface HandlerInterface<E extends Env = Env, M extends string = string
758
758
  E8,
759
759
  E9,
760
760
  E10
761
- ]>>(path: P, ...handlers: [
762
- H<E2, MergedPath, I>,
763
- H<E3, MergedPath, I2>,
764
- H<E4, MergedPath, I3>,
765
- H<E5, MergedPath, I4>,
766
- H<E6, MergedPath, I5>,
767
- H<E7, MergedPath, I6>,
768
- H<E8, MergedPath, I7>,
769
- H<E9, MergedPath, I8>,
770
- H<E10, MergedPath, I9>,
761
+ ]>, M1 extends H<E2, MergedPath, any> = H<E2, MergedPath, any>, M2 extends H<E3, MergedPath, any> = H<E3, MergedPath, any>, M3 extends H<E4, MergedPath, any> = H<E4, MergedPath, any>, M4 extends H<E5, MergedPath, any> = H<E5, MergedPath, any>, M5 extends H<E6, MergedPath, any> = H<E6, MergedPath, any>, M6 extends H<E7, MergedPath, any> = H<E7, MergedPath, any>, M7 extends H<E8, MergedPath, any> = H<E8, MergedPath, any>, M8 extends H<E9, MergedPath, any> = H<E9, MergedPath, any>, M9 extends H<E10, MergedPath, any> = H<E10, MergedPath, any>>(path: P, ...handlers: [
762
+ H<E2, MergedPath, I> & M1,
763
+ H<E3, MergedPath, I2> & M2,
764
+ H<E4, MergedPath, I3> & M3,
765
+ H<E5, MergedPath, I4> & M4,
766
+ H<E6, MergedPath, I5> & M5,
767
+ H<E7, MergedPath, I6> & M6,
768
+ H<E8, MergedPath, I7> & M7,
769
+ H<E9, MergedPath, I8> & M8,
770
+ H<E10, MergedPath, I9> & M9,
771
771
  H<E11, MergedPath, I10, R>
772
- ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I10, MergeTypedResponse<R>>, BasePath>;
772
+ ]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I10, MergeTypedResponse<R> | MergeMiddlewareResponse<M1> | MergeMiddlewareResponse<M2> | MergeMiddlewareResponse<M3> | MergeMiddlewareResponse<M4> | MergeMiddlewareResponse<M5> | MergeMiddlewareResponse<M6> | MergeMiddlewareResponse<M7> | MergeMiddlewareResponse<M8> | MergeMiddlewareResponse<M9>>, BasePath>;
773
773
  <P extends string = ExtractStringKey<S> extends never ? BasePath : ExtractStringKey<S>, I extends Input = BlankInput, R extends HandlerResponse<any> = any>(...handlers: H<E, P, I, R>[]): HonoBase<E, S & ToSchema<M, P, I, MergeTypedResponse<R>>, BasePath>;
774
774
  <P extends string, I extends Input = BlankInput, R extends HandlerResponse<any> = any>(path: P, ...handlers: H<E, MergePath<BasePath, P>, I, R>[]): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath>;
775
775
  <P extends string, R extends HandlerResponse<any> = any, I extends Input = BlankInput>(path: P): HonoBase<E, S & ToSchema<M, MergePath<BasePath, P>, I, MergeTypedResponse<R>>, BasePath>;
@@ -794,7 +794,7 @@ export interface MiddlewareHandlerInterface<E extends Env = Env, S extends Schem
794
794
  E2,
795
795
  E3
796
796
  ]>, S, BasePath>;
797
- <P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E>(path: P, handler: MiddlewareHandler<E2, MergedPath>): HonoBase<IntersectNonAnyTypes<[
797
+ <P extends string, MergedPath extends MergePath<BasePath, P>, E2 extends Env = E>(path: P, handler: MiddlewareHandler<E2, MergedPath, any, any>): HonoBase<IntersectNonAnyTypes<[
798
798
  E,
799
799
  E2
800
800
  ]>, ChangePathOfSchema<S, MergedPath>, BasePath>;
@@ -806,9 +806,9 @@ export interface MiddlewareHandlerInterface<E extends Env = Env, S extends Schem
806
806
  E2,
807
807
  E3
808
808
  ]>, P extends string = MergePath<BasePath, ExtractStringKey<S>>>(...handlers: [
809
- MiddlewareHandler<E2, P>,
810
- MiddlewareHandler<E3, P>,
811
- MiddlewareHandler<E4, P>
809
+ MiddlewareHandler<E2, P, any, any>,
810
+ MiddlewareHandler<E3, P, any, any>,
811
+ MiddlewareHandler<E4, P, any, any>
812
812
  ]): HonoBase<IntersectNonAnyTypes<[
813
813
  E,
814
814
  E2,
@@ -2399,6 +2399,8 @@ export type TypedResponse<T = unknown, U extends StatusCode = StatusCode, F exte
2399
2399
  _format: F;
2400
2400
  };
2401
2401
  type MergeTypedResponse<T> = T extends Promise<infer T2> ? T2 extends TypedResponse ? T2 : TypedResponse : T extends TypedResponse ? T : TypedResponse;
2402
+ type MergeTypedResponseStrict<T> = T extends Promise<infer T2> ? T2 extends TypedResponse ? T2 : never : T extends TypedResponse ? T : never;
2403
+ type MergeMiddlewareResponse<T> = MergeTypedResponseStrict<ExtractHandlerResponse<T>>;
2402
2404
  export type FormValue = string | Blob;
2403
2405
  export type ParsedFormValue = string | File;
2404
2406
  export type ValidationTargets<T extends FormValue = ParsedFormValue, P extends string = string> = {
@@ -2419,6 +2421,14 @@ export type InputToDataByTarget<T extends Input["out"], Target extends keyof Val
2419
2421
  } ? R : never;
2420
2422
  export type RemoveQuestion<T> = T extends `${infer R}?` ? R : T;
2421
2423
  export type ExtractSchema<T> = UnionToIntersection<T extends HonoBase<infer _, infer S, any> ? S : never>;
2424
+ export type ExtractSchemaForStatusCode<T, Status extends number> = {
2425
+ [Path in keyof ExtractSchema<T>]: {
2426
+ [Method in keyof ExtractSchema<T>[Path]]: Extract<ExtractSchema<T>[Path][Method], {
2427
+ status: Status;
2428
+ }>;
2429
+ };
2430
+ };
2431
+ export type ExtractHandlerResponse<T> = T extends (c: any, next: any) => Promise<infer R> ? Exclude<R, void> extends never ? never : Exclude<R, void> extends Response | TypedResponse<any, any, any> ? Exclude<R, void> : never : T extends (c: any, next: any) => infer R ? R extends Response | TypedResponse<any, any, any> ? R : never : never;
2422
2432
  type ProcessHead<T> = IfAnyThenEmptyObject<T extends Env ? (Env extends T ? {} : T) : T>;
2423
2433
  export type IntersectNonAnyTypes<T extends any[]> = T extends [
2424
2434
  infer Head,
@@ -2,25 +2,26 @@ import type { Context } from '../context';
2
2
  import type { Env, MiddlewareHandler, TypedResponse, ValidationTargets } from '../types';
3
3
  type ValidationTargetKeysWithBody = "form" | "json";
4
4
  type ValidationTargetByMethod<M> = M extends "get" | "head" ? Exclude<keyof ValidationTargets, ValidationTargetKeysWithBody> : keyof ValidationTargets;
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
- type ExcludeResponseType<T> = T extends Response & TypedResponse<any> ? never : T;
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 {
5
+ export type ValidationFunction<InputType, OutputType, E extends Env = {}, P extends string = string> = (value: InputType, c: Context<E, P>) => OutputType | TypedResponse | Promise<OutputType> | Promise<TypedResponse>;
6
+ export type ExtractValidationResponse<VF> = VF extends (value: any, c: any) => infer R ? R extends Promise<infer PR> ? PR extends TypedResponse<infer T, infer S, infer F> ? TypedResponse<T, S, F> : PR extends Response ? PR : PR extends undefined ? never : never : R extends TypedResponse<infer T, infer S, infer F> ? TypedResponse<T, S, F> : R extends Response ? R : R extends undefined ? never : never : never;
7
+ export declare const validator: <InputType, P extends string, M extends string, U extends ValidationTargetByMethod<M>, P2 extends string = P, VF extends (value: unknown extends InputType ? ValidationTargets[U] : InputType, c: Context<any, P2>) => any = (value: unknown extends InputType ? ValidationTargets[U] : InputType, c: Context<any, P2>) => any, V extends {
8
8
  in: {
9
- [K in U]: K extends "json" ? unknown extends InputType ? OutputTypeExcludeResponseType : InputType : {
10
- [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2];
9
+ [K in U]: K extends "json" ? unknown extends InputType ? ExtractValidatorOutput<VF> : InputType : {
10
+ [K2 in keyof ExtractValidatorOutput<VF>]: ValidationTargets[K][K2];
11
11
  };
12
12
  };
13
13
  out: {
14
- [K in U]: OutputTypeExcludeResponseType;
14
+ [K in U]: ExtractValidatorOutput<VF>;
15
15
  };
16
16
  } = {
17
17
  in: {
18
- [K in U]: K extends "json" ? unknown extends InputType ? OutputTypeExcludeResponseType : InputType : {
19
- [K2 in keyof OutputTypeExcludeResponseType]: ValidationTargets[K][K2];
18
+ [K in U]: K extends "json" ? unknown extends InputType ? ExtractValidatorOutput<VF> : InputType : {
19
+ [K2 in keyof ExtractValidatorOutput<VF>]: ValidationTargets[K][K2];
20
20
  };
21
21
  };
22
22
  out: {
23
- [K in U]: OutputTypeExcludeResponseType;
23
+ [K in U]: ExtractValidatorOutput<VF>;
24
24
  };
25
- }, E extends Env = any>(target: U, validationFunc: ValidationFunction<unknown extends InputType ? ValidationTargets[U] : InputType, OutputType, E, P2>) => MiddlewareHandler<E, P, V>;
25
+ }, E extends Env = any>(target: U, validationFunc: VF) => MiddlewareHandler<E, P, V, ExtractValidationResponse<VF>>;
26
+ export type ExtractValidatorOutput<VF> = VF extends (value: any, c: any) => infer R ? R extends Promise<infer PR> ? PR extends Response | TypedResponse<any, any, any> ? never : PR : R extends Response | TypedResponse<any, any, any> ? never : R : never;
26
27
  export {};
@@ -78,7 +78,7 @@ var validator = (target, validationFunc) => {
78
78
  return res;
79
79
  }
80
80
  c.req.addValidatedData(target, res);
81
- await next();
81
+ return await next();
82
82
  };
83
83
  };
84
84
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.9.12",
3
+ "version": "4.10.1",
4
4
  "description": "Web framework built on Web Standards",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",