hono 3.0.0 → 3.0.2

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.
package/README.md CHANGED
@@ -38,6 +38,12 @@ app.get('/', (c) => c.text('Hono!'))
38
38
  export default app
39
39
  ```
40
40
 
41
+ ## Quick Start
42
+
43
+ ```
44
+ npm create hono@latest my-app
45
+ ```
46
+
41
47
  ## Features
42
48
 
43
49
  - **Ultrafast** - The routers are really fast and smart. Not using linear loops. Fast.
@@ -89,7 +89,7 @@ class ClientRequestImpl {
89
89
  }
90
90
  methodUpperCase = this.method.toUpperCase();
91
91
  setBody = !(methodUpperCase === "GET" || methodUpperCase === "HEAD");
92
- return fetch(url, {
92
+ return (opt?.fetch || fetch)(url, {
93
93
  body: setBody ? this.rBody : void 0,
94
94
  method: methodUpperCase,
95
95
  headers
@@ -99,7 +99,7 @@ class ClientRequestImpl {
99
99
  this.method = method;
100
100
  }
101
101
  }
102
- const hc = (baseUrl) => createProxy(async (opts) => {
102
+ const hc = (baseUrl, options) => createProxy(async (opts) => {
103
103
  const parts = [...opts.path];
104
104
  let method = "";
105
105
  if (/^\$/.test(parts[parts.length - 1])) {
@@ -112,7 +112,9 @@ const hc = (baseUrl) => createProxy(async (opts) => {
112
112
  const url = (0, import_utils.mergePath)(baseUrl, path);
113
113
  const req = new ClientRequestImpl(url, method);
114
114
  if (method) {
115
- return req.fetch(opts.args[0], opts.args[1]);
115
+ options ?? (options = {});
116
+ const args = (0, import_utils.deepMerge)(options, { ...opts.args[1] ?? {} });
117
+ return req.fetch(opts.args[0], args);
116
118
  }
117
119
  return req;
118
120
  }, []);
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var utils_exports = {};
20
20
  __export(utils_exports, {
21
+ deepMerge: () => deepMerge,
21
22
  mergePath: () => mergePath,
22
23
  removeIndexString: () => removeIndexString,
23
24
  replaceUrlParam: () => replaceUrlParam
@@ -44,8 +45,27 @@ const removeIndexString = (urlSting) => {
44
45
  }
45
46
  return urlSting;
46
47
  };
48
+ function isObject(item) {
49
+ return typeof item === "object" && item !== null && !Array.isArray(item);
50
+ }
51
+ function deepMerge(target, source) {
52
+ if (!isObject(target) && !isObject(source)) {
53
+ return source;
54
+ }
55
+ const merged = { ...target };
56
+ for (const key in source) {
57
+ const value = source[key];
58
+ if (isObject(merged[key]) && isObject(value)) {
59
+ merged[key] = deepMerge(merged[key], value);
60
+ } else {
61
+ merged[key] = value;
62
+ }
63
+ }
64
+ return merged;
65
+ }
47
66
  // Annotate the CommonJS export names for ESM import in node:
48
67
  0 && (module.exports = {
68
+ deepMerge,
49
69
  mergePath,
50
70
  removeIndexString,
51
71
  replaceUrlParam
package/dist/cjs/hono.js CHANGED
@@ -63,7 +63,11 @@ class Hono extends defineDynamicClass() {
63
63
  return this.dispatch(request, executionCtx, Env);
64
64
  };
65
65
  this.request = async (input, requestInit) => {
66
- const req = input instanceof Request ? input : new Request(input, requestInit);
66
+ if (input instanceof Request) {
67
+ return await this.fetch(input);
68
+ }
69
+ const path = /^https?:\/\//.test(input) ? input : `http://localhost${(0, import_url.mergePath)("/", input)}`;
70
+ const req = new Request(path, requestInit);
67
71
  return await this.fetch(req);
68
72
  };
69
73
  const allMethods = [...import_router.METHODS, import_router.METHOD_NAME_ALL_LOWERCASE];
@@ -31,36 +31,18 @@ const encodeBase64 = (str) => {
31
31
  if (str === null) {
32
32
  throw new TypeError('1st argument of "encodeBase64" should not be null.');
33
33
  }
34
- try {
35
- const encoder = new TextEncoder();
36
- const bytes = encoder.encode(str);
37
- return btoa(String.fromCharCode(...bytes));
38
- } catch {
39
- }
40
- try {
41
- return Buffer.from(str).toString("base64");
42
- } catch (e) {
43
- console.error('Error: If you want to do "encodeBase64", polyfill "buffer" module.');
44
- throw e;
45
- }
34
+ const encoder = new TextEncoder();
35
+ const bytes = encoder.encode(str);
36
+ return btoa(String.fromCharCode(...bytes));
46
37
  };
47
38
  const decodeBase64 = (str) => {
48
39
  if (str === null) {
49
40
  throw new TypeError('1st argument of "decodeBase64" should not be null.');
50
41
  }
51
- try {
52
- const text = atob(str);
53
- const bytes = new Uint8Array(text.split("").map((c) => c.charCodeAt(0)));
54
- const decoder = new TextDecoder();
55
- return decoder.decode(bytes);
56
- } catch {
57
- }
58
- try {
59
- return Buffer.from(str, "base64").toString();
60
- } catch (e) {
61
- console.error('Error: If you want to do "decodeBase64", polyfill "buffer" module.');
62
- throw e;
63
- }
42
+ const text = atob(str);
43
+ const bytes = new Uint8Array(text.split("").map((c) => c.charCodeAt(0)));
44
+ const decoder = new TextDecoder();
45
+ return decoder.decode(bytes);
64
46
  };
65
47
  const encodeBase64URL = (str) => {
66
48
  return encodeBase64(str).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
@@ -83,14 +65,7 @@ const utf8ToUint8Array = (str) => {
83
65
  return encoder.encode(str);
84
66
  };
85
67
  const arrayBufferToBase64 = async (buf) => {
86
- if (typeof btoa === "function") {
87
- return btoa(String.fromCharCode(...new Uint8Array(buf)));
88
- }
89
- try {
90
- return Buffer.from(String.fromCharCode(...new Uint8Array(buf))).toString("base64");
91
- } catch (e) {
92
- }
93
- return "";
68
+ return btoa(String.fromCharCode(...new Uint8Array(buf)));
94
69
  };
95
70
  const arrayBufferToBase64URL = async (buf) => {
96
71
  return (await arrayBufferToBase64(buf)).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
@@ -21,13 +21,14 @@ __export(validator_exports, {
21
21
  validator: () => validator
22
22
  });
23
23
  module.exports = __toCommonJS(validator_exports);
24
+ var import_body = require("../utils/body");
24
25
  const validator = (target, validationFunc) => {
25
26
  return async (c, next) => {
26
27
  let value = {};
27
28
  switch (target) {
28
29
  case "json":
29
30
  try {
30
- value = await c.req.json();
31
+ value = await c.req.raw.clone().json();
31
32
  } catch {
32
33
  console.error("Error: Malformed JSON in request body");
33
34
  return c.json(
@@ -40,7 +41,7 @@ const validator = (target, validationFunc) => {
40
41
  }
41
42
  break;
42
43
  case "form":
43
- value = await c.req.parseBody();
44
+ value = await (0, import_body.parseBody)(c.req.raw.clone());
44
45
  break;
45
46
  case "query":
46
47
  value = c.req.query();
@@ -1,5 +1,5 @@
1
1
  // src/client/client.ts
2
- import { replaceUrlParam, mergePath, removeIndexString } from "./utils.js";
2
+ import { replaceUrlParam, mergePath, removeIndexString, deepMerge } from "./utils.js";
3
3
  var createProxy = (callback, path) => {
4
4
  const proxy = new Proxy(() => {
5
5
  }, {
@@ -67,7 +67,7 @@ var ClientRequestImpl = class {
67
67
  }
68
68
  methodUpperCase = this.method.toUpperCase();
69
69
  setBody = !(methodUpperCase === "GET" || methodUpperCase === "HEAD");
70
- return fetch(url, {
70
+ return (opt?.fetch || fetch)(url, {
71
71
  body: setBody ? this.rBody : void 0,
72
72
  method: methodUpperCase,
73
73
  headers
@@ -77,7 +77,7 @@ var ClientRequestImpl = class {
77
77
  this.method = method;
78
78
  }
79
79
  };
80
- var hc = (baseUrl) => createProxy(async (opts) => {
80
+ var hc = (baseUrl, options) => createProxy(async (opts) => {
81
81
  const parts = [...opts.path];
82
82
  let method = "";
83
83
  if (/^\$/.test(parts[parts.length - 1])) {
@@ -90,7 +90,9 @@ var hc = (baseUrl) => createProxy(async (opts) => {
90
90
  const url = mergePath(baseUrl, path);
91
91
  const req = new ClientRequestImpl(url, method);
92
92
  if (method) {
93
- return req.fetch(opts.args[0], opts.args[1]);
93
+ options ?? (options = {});
94
+ const args = deepMerge(options, { ...opts.args[1] ?? {} });
95
+ return req.fetch(opts.args[0], args);
94
96
  }
95
97
  return req;
96
98
  }, []);
@@ -20,7 +20,26 @@ var removeIndexString = (urlSting) => {
20
20
  }
21
21
  return urlSting;
22
22
  };
23
+ function isObject(item) {
24
+ return typeof item === "object" && item !== null && !Array.isArray(item);
25
+ }
26
+ function deepMerge(target, source) {
27
+ if (!isObject(target) && !isObject(source)) {
28
+ return source;
29
+ }
30
+ const merged = { ...target };
31
+ for (const key in source) {
32
+ const value = source[key];
33
+ if (isObject(merged[key]) && isObject(value)) {
34
+ merged[key] = deepMerge(merged[key], value);
35
+ } else {
36
+ merged[key] = value;
37
+ }
38
+ }
39
+ return merged;
40
+ }
23
41
  export {
42
+ deepMerge,
24
43
  mergePath,
25
44
  removeIndexString,
26
45
  replaceUrlParam
package/dist/hono.js CHANGED
@@ -41,7 +41,11 @@ var Hono = class extends defineDynamicClass() {
41
41
  return this.dispatch(request, executionCtx, Env);
42
42
  };
43
43
  this.request = async (input, requestInit) => {
44
- const req = input instanceof Request ? input : new Request(input, requestInit);
44
+ if (input instanceof Request) {
45
+ return await this.fetch(input);
46
+ }
47
+ const path = /^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`;
48
+ const req = new Request(path, requestInit);
45
49
  return await this.fetch(req);
46
50
  };
47
51
  const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE];
@@ -1,4 +1,4 @@
1
1
  import type { Hono } from '../hono';
2
2
  import type { UnionToIntersection } from '../utils/types';
3
- import type { Client } from './types';
4
- export declare const hc: <T extends Hono<import("../types").Env, {}>>(baseUrl: string) => UnionToIntersection<Client<T>>;
3
+ import type { Client, RequestOptions } from './types';
4
+ export declare const hc: <T extends Hono<any, {}>>(baseUrl: string, options?: RequestOptions) => UnionToIntersection<Client<T>>;
@@ -1,5 +1,5 @@
1
1
  import type { Hono } from '../hono';
2
- import type { ValidationTargets, Env } from '../types';
2
+ import type { ValidationTargets } from '../types';
3
3
  declare type MethodName = `$${string}`;
4
4
  declare type Endpoint = Record<MethodName, Data>;
5
5
  declare type Data = {
@@ -8,19 +8,20 @@ declare type Data = {
8
8
  };
9
9
  output: {};
10
10
  };
11
- export declare type RequestOption = {
11
+ export declare type RequestOptions = {
12
12
  headers?: Record<string, string>;
13
+ fetch?: typeof fetch;
13
14
  };
14
15
  declare type ClientRequest<S extends Data> = {
15
16
  [M in keyof S]: S[M] extends {
16
17
  input: infer R;
17
18
  output: infer O;
18
- } ? (args?: R, options?: RequestOption) => Promise<ClientResponse<O>> : never;
19
+ } ? (args?: R, options?: RequestOptions) => Promise<ClientResponse<O>> : never;
19
20
  };
20
21
  export interface ClientResponse<T> extends Response {
21
22
  json(): Promise<T>;
22
23
  }
23
- export declare type Fetch<T> = (args?: InferRequestType<T>, opt?: RequestOption) => Promise<ClientResponse<InferResponseType<T>>>;
24
+ export declare type Fetch<T> = (args?: InferRequestType<T>, opt?: RequestOptions) => Promise<ClientResponse<InferResponseType<T>>>;
24
25
  export declare type InferResponseType<T> = T extends () => Promise<ClientResponse<infer O>> ? O : never;
25
26
  export declare type InferRequestType<T> = T extends (args: infer R) => Promise<ClientResponse<unknown>> ? NonNullable<R> : never;
26
27
  declare type PathToChain<Path extends string, E extends Endpoint, Original extends string = ''> = Path extends `/${infer P}` ? PathToChain<P, E, Path> : Path extends `${infer P}/${infer R}` ? {
@@ -28,10 +29,13 @@ declare type PathToChain<Path extends string, E extends Endpoint, Original exten
28
29
  } : {
29
30
  [K in Path extends '' ? 'index' : Path]: ClientRequest<E extends Record<string, unknown> ? E[Original] : never>;
30
31
  };
31
- export declare type Client<T> = T extends Hono<Env, infer S> ? S extends Record<infer K, Endpoint> ? K extends string ? PathToChain<K, S> : never : never : never;
32
+ export declare type Client<T> = T extends Hono<any, infer S> ? S extends Record<infer K, Endpoint> ? K extends string ? PathToChain<K, S> : never : never : never;
32
33
  export declare type Callback = (opts: CallbackOptions) => unknown;
33
34
  interface CallbackOptions {
34
35
  path: string[];
35
36
  args: any[];
36
37
  }
38
+ export declare type ObjectType<T = unknown> = {
39
+ [key: string]: T;
40
+ };
37
41
  export {};
@@ -1,3 +1,4 @@
1
1
  export declare const mergePath: (base: string, path: string) => string;
2
2
  export declare const replaceUrlParam: (urlString: string, params: Record<string, string>) => string;
3
3
  export declare const removeIndexString: (urlSting: string) => string;
4
+ export declare function deepMerge<T>(target: T, source: Record<string, unknown>): T;
@@ -1,6 +1,6 @@
1
1
  import type { ExecutionContext } from './context';
2
2
  import type { Router } from './router';
3
- import type { Env, ErrorHandler, H, HandlerInterface, MiddlewareHandlerInterface, NotFoundHandler, OnHandlerInterface } from './types';
3
+ import type { Env, ErrorHandler, H, HandlerInterface, MiddlewareHandlerInterface, NotFoundHandler, OnHandlerInterface, MergeSchemaPath, RemoveBlankRecord } from './types';
4
4
  interface RouterRoute {
5
5
  path: string;
6
6
  method: string;
@@ -29,7 +29,7 @@ export declare class Hono<E extends Env = Env, S = {}> extends Hono_base<E, S> {
29
29
  constructor(init?: Partial<Pick<Hono, 'router' | 'strict'>>);
30
30
  private notFoundHandler;
31
31
  private errorHandler;
32
- route(path: string, app?: Hono<any, any>): this;
32
+ route<SubPath extends string, SubEnv extends Env, SubSchema>(path: SubPath, app?: Hono<SubEnv, SubSchema>): Hono<E, RemoveBlankRecord<MergeSchemaPath<SubSchema, SubPath> | S>>;
33
33
  onError(handler: ErrorHandler<E>): this;
34
34
  notFound(handler: NotFoundHandler<E>): this;
35
35
  showRoutes(): void;
@@ -1,6 +1,7 @@
1
1
  import { Hono } from './hono';
2
2
  export type { Env, ErrorHandler, Handler, MiddlewareHandler, Next, NotFoundHandler, ValidationTargets, } from './types';
3
3
  export type { Context, ContextVariableMap } from './context';
4
+ export type { HonoRequest } from './request';
4
5
  declare module './hono' {
5
6
  interface Hono {
6
7
  fire(): void;
@@ -15,39 +15,39 @@ export declare type H<E extends Env = any, P extends string = any, I extends Inp
15
15
  export declare type NotFoundHandler<E extends Env = any> = (c: Context<E>) => Response | Promise<Response>;
16
16
  export declare type ErrorHandler<E extends Env = any> = (err: Error, c: Context<E>) => Response;
17
17
  export interface HandlerInterface<E extends Env = Env, M extends string = any, S = {}> {
18
- <I = {}, O = {}>(...handlers: [H<E, ExtractKey<S>, I, O>, H<E, ExtractKey<S>, I, O>]): Hono<E, S & Schema<M, ExtractKey<S>, I, O>>;
19
- <P extends string, O = {}, I = {}, I2 = I, I3 = I & I2>(...handlers: [H<E, ExtractKey<S>, I, O>, H<E, ExtractKey<S>, I2, O>, H<E, ExtractKey<S>, I3, O>]): Hono<E, S & Schema<M, ExtractKey<S>, I3, O>>;
18
+ <I = {}, O = {}>(...handlers: [H<E, ExtractKey<S>, I, O>, H<E, ExtractKey<S>, I, O>]): Hono<E, RemoveBlankRecord<S | Schema<M, ExtractKey<S>, I, O>>>;
19
+ <P extends string, O = {}, I = {}, I2 = I, I3 = I & I2>(...handlers: [H<E, ExtractKey<S>, I, O>, H<E, ExtractKey<S>, I2, O>, H<E, ExtractKey<S>, I3, O>]): Hono<E, RemoveBlankRecord<S | Schema<M, ExtractKey<S>, I3, O>>>;
20
20
  <P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3>(...handlers: [
21
21
  H<E, ExtractKey<S>, I, O>,
22
22
  H<E, ExtractKey<S>, I2, O>,
23
23
  H<E, ExtractKey<S>, I3, O>,
24
24
  H<E, ExtractKey<S>, I4, O>
25
- ]): Hono<E, S & Schema<M, ExtractKey<S>, I4, O>>;
25
+ ]): Hono<E, RemoveBlankRecord<S | Schema<M, ExtractKey<S>, I4, O>>>;
26
26
  <P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3, I5 = I3 & I4>(...handlers: [
27
27
  H<E, ExtractKey<S>, I, O>,
28
28
  H<E, ExtractKey<S>, I2, O>,
29
29
  H<E, ExtractKey<S>, I3, O>,
30
30
  H<E, ExtractKey<S>, I4, O>,
31
31
  H<E, ExtractKey<S>, I5, O>
32
- ]): Hono<E, S & Schema<M, ExtractKey<S>, I5, O>>;
33
- <I = {}, O = {}>(...handlers: Handler<E, ExtractKey<S>, I, O>[]): Hono<E, S & Schema<M, ExtractKey<S>, I, O>>;
34
- <P extends string, O = {}, I = {}>(path: P, ...handlers: [H<E, P, I, O>, H<E, P, I, O>]): Hono<E, S & Schema<M, P, I, O>>;
35
- <P extends string, O = {}, I = {}, I2 = I, I3 = I & I2>(path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>]): Hono<E, S & Schema<M, P, I3, O>>;
36
- <P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3>(path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>, H<E, P, I4, O>]): Hono<E, S & Schema<M, P, I4, O>>;
37
- <P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3, I5 = I3 & I4>(path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>, H<E, P, I4, O>, H<E, P, I5, O>]): Hono<E, S & Schema<M, P, I5, O>>;
38
- <P extends string, I = {}, O = {}>(path: P, ...handlers: H<E, P, I, O>[]): Hono<E, S & Schema<M, P, I, O>>;
32
+ ]): Hono<E, RemoveBlankRecord<S | Schema<M, ExtractKey<S>, I5, O>>>;
33
+ <I = {}, O = {}>(...handlers: Handler<E, ExtractKey<S>, I, O>[]): Hono<E, RemoveBlankRecord<S | Schema<M, ExtractKey<S>, I, O>>>;
34
+ <P extends string, O = {}, I = {}>(path: P, ...handlers: [H<E, P, I, O>, H<E, P, I, O>]): Hono<E, RemoveBlankRecord<S | Schema<M, P, I, O>>>;
35
+ <P extends string, O = {}, I = {}, I2 = I, I3 = I & I2>(path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>]): Hono<E, RemoveBlankRecord<S | Schema<M, P, I3, O>>>;
36
+ <P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3>(path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>, H<E, P, I4, O>]): Hono<E, RemoveBlankRecord<S | Schema<M, P, I4, O>>>;
37
+ <P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3, I5 = I3 & I4>(path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>, H<E, P, I4, O>, H<E, P, I5, O>]): Hono<E, RemoveBlankRecord<S | Schema<M, P, I5, O>>>;
38
+ <P extends string, I = {}, O = {}>(path: P, ...handlers: H<E, P, I, O>[]): Hono<E, RemoveBlankRecord<S | Schema<M, P, I, O>>>;
39
39
  }
40
40
  export interface MiddlewareHandlerInterface<E extends Env = Env, S = {}> {
41
41
  (...handlers: MiddlewareHandler<E, ExtractKey<S>>[]): Hono<E, S>;
42
42
  <P extends string>(path: P, ...handlers: MiddlewareHandler<E, P>[]): Hono<E, S>;
43
43
  }
44
44
  export interface OnHandlerInterface<E extends Env = Env, S = {}> {
45
- <M extends string, P extends string, O = {}, I = {}>(method: M, path: P, ...handlers: [H<E, P, I, O>, H<E, P, I, O>]): Hono<E, S & Schema<M, P, I, O>>;
46
- <M extends string, P extends string, O = {}, I = {}, I2 = I, I3 = I & I2>(method: M, path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>]): Hono<E, S & Schema<M, P, I3, O>>;
47
- <M extends string, P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3>(method: M, path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>, H<E, P, I4, O>]): Hono<E, S & Schema<M, P, I4, O>>;
48
- <M extends string, P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3, I5 = I3 & I4>(method: M, path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>, H<E, P, I4, O>, H<E, P, I5, O>]): Hono<E, S & Schema<M, P, I5, O>>;
49
- <M extends string, P extends string, O extends {} = {}, I = {}>(method: M, path: P, ...handlers: H<E, P, I, O>[]): Hono<E, S & Schema<M, P, I, O>>;
50
- <P extends string, O extends {} = {}, I = {}>(methods: string[], path: P, ...handlers: H<E, P, I, O>[]): Hono<E, S & Schema<string, P, I, O>>;
45
+ <M extends string, P extends string, O = {}, I = {}>(method: M, path: P, ...handlers: [H<E, P, I, O>, H<E, P, I, O>]): Hono<E, RemoveBlankRecord<S | Schema<M, P, I, O>>>;
46
+ <M extends string, P extends string, O = {}, I = {}, I2 = I, I3 = I & I2>(method: M, path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>]): Hono<E, RemoveBlankRecord<S | Schema<M, P, I3, O>>>;
47
+ <M extends string, P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3>(method: M, path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>, H<E, P, I4, O>]): Hono<E, RemoveBlankRecord<S | Schema<M, P, I4, O>>>;
48
+ <M extends string, P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3, I5 = I3 & I4>(method: M, path: P, ...handlers: [H<E, P, I, O>, H<E, P, I2, O>, H<E, P, I3, O>, H<E, P, I4, O>, H<E, P, I5, O>]): Hono<E, S | Schema<M, P, I5, O>>;
49
+ <M extends string, P extends string, O extends {} = {}, I = {}>(method: M, path: P, ...handlers: H<E, P, I, O>[]): Hono<E, RemoveBlankRecord<S | Schema<M, P, I, O>>>;
50
+ <P extends string, O extends {} = {}, I = {}>(methods: string[], path: P, ...handlers: H<E, P, I, O>[]): Hono<E, RemoveBlankRecord<S | Schema<string, P, I, O>>>;
51
51
  }
52
52
  declare type ExtractKey<S> = S extends Record<infer Key, unknown> ? Key extends string ? Key : never : string;
53
53
  export declare type Schema<M extends string, P extends string, I extends Input, O> = {
@@ -64,6 +64,8 @@ export declare type AddParam<I, P extends string> = ParamKeys<P> extends never ?
64
64
  export declare type AddDollar<T> = T extends Record<infer K, infer R> ? K extends string ? {
65
65
  [MethodName in `$${Lowercase<K>}`]: R;
66
66
  } : never : never;
67
+ export declare type MergeSchemaPath<S, P extends string> = S extends Record<infer Key, infer T> ? Key extends string ? Record<MergePath<P, Key>, T> : never : never;
68
+ export declare type MergePath<A extends string, B extends string> = A extends `${infer P}/` ? `${P}${B}` : `${A}${B}`;
67
69
  export declare type TypedResponse<T = unknown> = {
68
70
  response: Response | Promise<Response>;
69
71
  data: T;
@@ -87,4 +89,5 @@ export declare type InputToDataByTarget<T extends Input, Target extends keyof Va
87
89
  export declare type RemoveQuestion<T> = T extends `${infer R}?` ? R : T;
88
90
  export declare type UndefinedIfHavingQuestion<T> = T extends `${infer _}?` ? string | undefined : string;
89
91
  export declare type ExtractSchema<T> = T extends Hono<infer _, infer S> ? S : never;
92
+ export declare type RemoveBlankRecord<T> = T extends Record<infer K, unknown> ? K extends string ? T : never : never;
90
93
  export {};
@@ -3,36 +3,18 @@ var encodeBase64 = (str) => {
3
3
  if (str === null) {
4
4
  throw new TypeError('1st argument of "encodeBase64" should not be null.');
5
5
  }
6
- try {
7
- const encoder = new TextEncoder();
8
- const bytes = encoder.encode(str);
9
- return btoa(String.fromCharCode(...bytes));
10
- } catch {
11
- }
12
- try {
13
- return Buffer.from(str).toString("base64");
14
- } catch (e) {
15
- console.error('Error: If you want to do "encodeBase64", polyfill "buffer" module.');
16
- throw e;
17
- }
6
+ const encoder = new TextEncoder();
7
+ const bytes = encoder.encode(str);
8
+ return btoa(String.fromCharCode(...bytes));
18
9
  };
19
10
  var decodeBase64 = (str) => {
20
11
  if (str === null) {
21
12
  throw new TypeError('1st argument of "decodeBase64" should not be null.');
22
13
  }
23
- try {
24
- const text = atob(str);
25
- const bytes = new Uint8Array(text.split("").map((c) => c.charCodeAt(0)));
26
- const decoder = new TextDecoder();
27
- return decoder.decode(bytes);
28
- } catch {
29
- }
30
- try {
31
- return Buffer.from(str, "base64").toString();
32
- } catch (e) {
33
- console.error('Error: If you want to do "decodeBase64", polyfill "buffer" module.');
34
- throw e;
35
- }
14
+ const text = atob(str);
15
+ const bytes = new Uint8Array(text.split("").map((c) => c.charCodeAt(0)));
16
+ const decoder = new TextDecoder();
17
+ return decoder.decode(bytes);
36
18
  };
37
19
  var encodeBase64URL = (str) => {
38
20
  return encodeBase64(str).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
@@ -55,14 +37,7 @@ var utf8ToUint8Array = (str) => {
55
37
  return encoder.encode(str);
56
38
  };
57
39
  var arrayBufferToBase64 = async (buf) => {
58
- if (typeof btoa === "function") {
59
- return btoa(String.fromCharCode(...new Uint8Array(buf)));
60
- }
61
- try {
62
- return Buffer.from(String.fromCharCode(...new Uint8Array(buf))).toString("base64");
63
- } catch (e) {
64
- }
65
- return "";
40
+ return btoa(String.fromCharCode(...new Uint8Array(buf)));
66
41
  };
67
42
  var arrayBufferToBase64URL = async (buf) => {
68
43
  return (await arrayBufferToBase64(buf)).replace(/=/g, "").replace(/\+/g, "-").replace(/\//g, "_");
@@ -1,11 +1,12 @@
1
1
  // src/validator/validator.ts
2
+ import { parseBody } from "../utils/body.js";
2
3
  var validator = (target, validationFunc) => {
3
4
  return async (c, next) => {
4
5
  let value = {};
5
6
  switch (target) {
6
7
  case "json":
7
8
  try {
8
- value = await c.req.json();
9
+ value = await c.req.raw.clone().json();
9
10
  } catch {
10
11
  console.error("Error: Malformed JSON in request body");
11
12
  return c.json(
@@ -18,7 +19,7 @@ var validator = (target, validationFunc) => {
18
19
  }
19
20
  break;
20
21
  case "form":
21
- value = await c.req.parseBody();
22
+ value = await parseBody(c.req.raw.clone());
22
23
  break;
23
24
  case "query":
24
25
  value = c.req.query();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "3.0.0",
3
+ "version": "3.0.2",
4
4
  "description": "Ultrafast web framework for the Edge",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",