hono 3.0.1 → 3.0.3
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 +7 -1
- package/dist/adapter/cloudflare-pages/handler.js +5 -2
- package/dist/adapter/nextjs/handler.js +4 -1
- package/dist/cjs/adapter/cloudflare-pages/handler.js +5 -2
- package/dist/cjs/adapter/nextjs/handler.js +4 -1
- package/dist/cjs/client/client.js +1 -1
- package/dist/cjs/hono.js +24 -8
- package/dist/cjs/utils/encode.js +8 -33
- package/dist/cjs/validator/validator.js +3 -2
- package/dist/client/client.js +1 -1
- package/dist/hono.js +24 -8
- package/dist/types/adapter/nextjs/handler.d.ts +1 -1
- package/dist/types/client/client.d.ts +1 -1
- package/dist/types/client/types.d.ts +5 -3
- package/dist/types/context.d.ts +2 -1
- package/dist/types/hono.d.ts +18 -16
- package/dist/types/index.d.ts +1 -0
- package/dist/types/types.d.ts +53 -24
- package/dist/types/utils/types.d.ts +12 -0
- package/dist/utils/encode.js +8 -33
- package/dist/validator/validator.js +3 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -38,12 +38,18 @@ 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.
|
|
44
50
|
- **Multi-runtime** - Works on Cloudflare Workers, Fastly Compute@Edge, Deno, Bun, Lagon, or Node.js. The same code runs on all platforms.
|
|
45
51
|
- **Batteries Included** - Hono has built-in middleware, custom middleware, and third-party middleware. Batteries included.
|
|
46
|
-
- **
|
|
52
|
+
- **Delightful DX** - First-class TypeScript support. Now, we've got "Types".
|
|
47
53
|
- **Small** - About 20kB. Zero-dependencies. Using only Web Standard API.
|
|
48
54
|
|
|
49
55
|
## Benchmarks
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// src/adapter/cloudflare-pages/handler.ts
|
|
2
2
|
import { Hono } from "../../hono.js";
|
|
3
|
-
var handle = (subApp, path
|
|
4
|
-
|
|
3
|
+
var handle = (subApp, path) => ({ request, env, waitUntil }) => {
|
|
4
|
+
const app = path ? new Hono().route(path, subApp) : subApp;
|
|
5
|
+
return app.fetch(request, env, { waitUntil, passThroughOnException: () => {
|
|
6
|
+
} });
|
|
7
|
+
};
|
|
5
8
|
export {
|
|
6
9
|
handle
|
|
7
10
|
};
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// src/adapter/nextjs/handler.ts
|
|
2
2
|
import { Hono } from "../../hono.js";
|
|
3
|
-
var handle = (subApp, path
|
|
3
|
+
var handle = (subApp, path) => (req) => {
|
|
4
|
+
const app = path ? new Hono().route(path, subApp) : subApp;
|
|
5
|
+
return app.fetch(req);
|
|
6
|
+
};
|
|
4
7
|
export {
|
|
5
8
|
handle
|
|
6
9
|
};
|
|
@@ -22,8 +22,11 @@ __export(handler_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(handler_exports);
|
|
24
24
|
var import_hono = require("../../hono");
|
|
25
|
-
const handle = (subApp, path
|
|
26
|
-
|
|
25
|
+
const handle = (subApp, path) => ({ request, env, waitUntil }) => {
|
|
26
|
+
const app = path ? new import_hono.Hono().route(path, subApp) : subApp;
|
|
27
|
+
return app.fetch(request, env, { waitUntil, passThroughOnException: () => {
|
|
28
|
+
} });
|
|
29
|
+
};
|
|
27
30
|
// Annotate the CommonJS export names for ESM import in node:
|
|
28
31
|
0 && (module.exports = {
|
|
29
32
|
handle
|
|
@@ -22,7 +22,10 @@ __export(handler_exports, {
|
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(handler_exports);
|
|
24
24
|
var import_hono = require("../../hono");
|
|
25
|
-
const handle = (subApp, path
|
|
25
|
+
const handle = (subApp, path) => (req) => {
|
|
26
|
+
const app = path ? new import_hono.Hono().route(path, subApp) : subApp;
|
|
27
|
+
return app.fetch(req);
|
|
28
|
+
};
|
|
26
29
|
// Annotate the CommonJS export names for ESM import in node:
|
|
27
30
|
0 && (module.exports = {
|
|
28
31
|
handle
|
|
@@ -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
|
package/dist/cjs/hono.js
CHANGED
|
@@ -51,7 +51,7 @@ class Hono extends defineDynamicClass() {
|
|
|
51
51
|
routers: [new import_reg_exp_router.RegExpRouter(), new import_trie_router.TrieRouter()]
|
|
52
52
|
});
|
|
53
53
|
this.strict = true;
|
|
54
|
-
this.
|
|
54
|
+
this.basePath = "";
|
|
55
55
|
this.path = "*";
|
|
56
56
|
this.routes = [];
|
|
57
57
|
this.notFoundHandler = notFoundHandler;
|
|
@@ -63,7 +63,15 @@ class Hono extends defineDynamicClass() {
|
|
|
63
63
|
return this.dispatch(request, executionCtx, Env);
|
|
64
64
|
};
|
|
65
65
|
this.request = async (input, requestInit) => {
|
|
66
|
-
|
|
66
|
+
if (input instanceof Request) {
|
|
67
|
+
if (requestInit !== void 0) {
|
|
68
|
+
input = new Request(input, requestInit);
|
|
69
|
+
}
|
|
70
|
+
return await this.fetch(input);
|
|
71
|
+
}
|
|
72
|
+
input = input.toString();
|
|
73
|
+
const path = /^https?:\/\//.test(input) ? input : `http://localhost${(0, import_url.mergePath)("/", input)}`;
|
|
74
|
+
const req = new Request(path, requestInit);
|
|
67
75
|
return await this.fetch(req);
|
|
68
76
|
};
|
|
69
77
|
const allMethods = [...import_router.METHODS, import_router.METHOD_NAME_ALL_LOWERCASE];
|
|
@@ -106,16 +114,24 @@ class Hono extends defineDynamicClass() {
|
|
|
106
114
|
};
|
|
107
115
|
Object.assign(this, init);
|
|
108
116
|
}
|
|
117
|
+
clone() {
|
|
118
|
+
const clone = new Hono({
|
|
119
|
+
router: this.router,
|
|
120
|
+
strict: this.strict
|
|
121
|
+
});
|
|
122
|
+
clone.routes = this.routes;
|
|
123
|
+
return clone;
|
|
124
|
+
}
|
|
109
125
|
route(path, app) {
|
|
110
|
-
|
|
126
|
+
const subApp = this.clone();
|
|
127
|
+
subApp.basePath = (0, import_url.mergePath)(this.basePath, path);
|
|
111
128
|
if (app) {
|
|
112
129
|
app.routes.map((r) => {
|
|
113
130
|
const handler = app.errorHandler === errorHandler ? r.handler : async (c, next) => (await (0, import_compose.compose)([r.handler], app.errorHandler)(c, next)).res;
|
|
114
|
-
|
|
131
|
+
subApp.addRoute(r.method, r.path, handler);
|
|
115
132
|
});
|
|
116
|
-
this._tempPath = "";
|
|
117
133
|
}
|
|
118
|
-
return
|
|
134
|
+
return subApp;
|
|
119
135
|
}
|
|
120
136
|
onError(handler) {
|
|
121
137
|
this.errorHandler = handler;
|
|
@@ -135,8 +151,8 @@ class Hono extends defineDynamicClass() {
|
|
|
135
151
|
}
|
|
136
152
|
addRoute(method, path, handler) {
|
|
137
153
|
method = method.toUpperCase();
|
|
138
|
-
if (this.
|
|
139
|
-
path = (0, import_url.mergePath)(this.
|
|
154
|
+
if (this.basePath) {
|
|
155
|
+
path = (0, import_url.mergePath)(this.basePath, path);
|
|
140
156
|
}
|
|
141
157
|
this.router.add(method, path, handler);
|
|
142
158
|
const r = { path, method, handler };
|
package/dist/cjs/utils/encode.js
CHANGED
|
@@ -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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
-
|
|
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.
|
|
44
|
+
value = await (0, import_body.parseBody)(c.req.raw.clone());
|
|
44
45
|
break;
|
|
45
46
|
case "query":
|
|
46
47
|
value = c.req.query();
|
package/dist/client/client.js
CHANGED
|
@@ -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
|
package/dist/hono.js
CHANGED
|
@@ -29,7 +29,7 @@ var Hono = class extends defineDynamicClass() {
|
|
|
29
29
|
routers: [new RegExpRouter(), new TrieRouter()]
|
|
30
30
|
});
|
|
31
31
|
this.strict = true;
|
|
32
|
-
this.
|
|
32
|
+
this.basePath = "";
|
|
33
33
|
this.path = "*";
|
|
34
34
|
this.routes = [];
|
|
35
35
|
this.notFoundHandler = notFoundHandler;
|
|
@@ -41,7 +41,15 @@ var Hono = class extends defineDynamicClass() {
|
|
|
41
41
|
return this.dispatch(request, executionCtx, Env);
|
|
42
42
|
};
|
|
43
43
|
this.request = async (input, requestInit) => {
|
|
44
|
-
|
|
44
|
+
if (input instanceof Request) {
|
|
45
|
+
if (requestInit !== void 0) {
|
|
46
|
+
input = new Request(input, requestInit);
|
|
47
|
+
}
|
|
48
|
+
return await this.fetch(input);
|
|
49
|
+
}
|
|
50
|
+
input = input.toString();
|
|
51
|
+
const path = /^https?:\/\//.test(input) ? input : `http://localhost${mergePath("/", input)}`;
|
|
52
|
+
const req = new Request(path, requestInit);
|
|
45
53
|
return await this.fetch(req);
|
|
46
54
|
};
|
|
47
55
|
const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE];
|
|
@@ -84,16 +92,24 @@ var Hono = class extends defineDynamicClass() {
|
|
|
84
92
|
};
|
|
85
93
|
Object.assign(this, init);
|
|
86
94
|
}
|
|
95
|
+
clone() {
|
|
96
|
+
const clone = new Hono({
|
|
97
|
+
router: this.router,
|
|
98
|
+
strict: this.strict
|
|
99
|
+
});
|
|
100
|
+
clone.routes = this.routes;
|
|
101
|
+
return clone;
|
|
102
|
+
}
|
|
87
103
|
route(path, app) {
|
|
88
|
-
|
|
104
|
+
const subApp = this.clone();
|
|
105
|
+
subApp.basePath = mergePath(this.basePath, path);
|
|
89
106
|
if (app) {
|
|
90
107
|
app.routes.map((r) => {
|
|
91
108
|
const handler = app.errorHandler === errorHandler ? r.handler : async (c, next) => (await compose([r.handler], app.errorHandler)(c, next)).res;
|
|
92
|
-
|
|
109
|
+
subApp.addRoute(r.method, r.path, handler);
|
|
93
110
|
});
|
|
94
|
-
this._tempPath = "";
|
|
95
111
|
}
|
|
96
|
-
return
|
|
112
|
+
return subApp;
|
|
97
113
|
}
|
|
98
114
|
onError(handler) {
|
|
99
115
|
this.errorHandler = handler;
|
|
@@ -113,8 +129,8 @@ var Hono = class extends defineDynamicClass() {
|
|
|
113
129
|
}
|
|
114
130
|
addRoute(method, path, handler) {
|
|
115
131
|
method = method.toUpperCase();
|
|
116
|
-
if (this.
|
|
117
|
-
path = mergePath(this.
|
|
132
|
+
if (this.basePath) {
|
|
133
|
+
path = mergePath(this.basePath, path);
|
|
118
134
|
}
|
|
119
135
|
this.router.add(method, path, handler);
|
|
120
136
|
const r = { path, method, handler };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Hono } from '../../hono';
|
|
2
2
|
import type { Env } from '../../types';
|
|
3
3
|
interface HandleInterface {
|
|
4
|
-
<E extends Env>(subApp: Hono<E>, path?: string): (req: Request) => Promise<Response>;
|
|
4
|
+
<E extends Env>(subApp: Hono<E>, path?: string): (req: Request) => Response | Promise<Response>;
|
|
5
5
|
}
|
|
6
6
|
export declare const handle: HandleInterface;
|
|
7
7
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Hono } from '../hono';
|
|
2
2
|
import type { UnionToIntersection } from '../utils/types';
|
|
3
3
|
import type { Client, RequestOptions } from './types';
|
|
4
|
-
export declare const hc: <T extends Hono<any,
|
|
4
|
+
export declare const hc: <T extends Hono<any, any, any>>(baseUrl: string, options?: RequestOptions) => UnionToIntersection<Client<T>>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Hono } from '../hono';
|
|
2
2
|
import type { ValidationTargets } from '../types';
|
|
3
|
+
import type { RemoveBlankRecord } from '../utils/types';
|
|
3
4
|
declare type MethodName = `$${string}`;
|
|
4
5
|
declare type Endpoint = Record<MethodName, Data>;
|
|
5
6
|
declare type Data = {
|
|
@@ -10,25 +11,26 @@ declare type Data = {
|
|
|
10
11
|
};
|
|
11
12
|
export declare type RequestOptions = {
|
|
12
13
|
headers?: Record<string, string>;
|
|
14
|
+
fetch?: typeof fetch;
|
|
13
15
|
};
|
|
14
16
|
declare type ClientRequest<S extends Data> = {
|
|
15
17
|
[M in keyof S]: S[M] extends {
|
|
16
18
|
input: infer R;
|
|
17
19
|
output: infer O;
|
|
18
|
-
} ? (args?: R, options?: RequestOptions) => Promise<ClientResponse<O>> : never;
|
|
20
|
+
} ? RemoveBlankRecord<R> extends never ? (args?: {}, options?: RequestOptions) => Promise<ClientResponse<O>> : (args: R, options?: RequestOptions) => Promise<ClientResponse<O>> : never;
|
|
19
21
|
};
|
|
20
22
|
export interface ClientResponse<T> extends Response {
|
|
21
23
|
json(): Promise<T>;
|
|
22
24
|
}
|
|
23
25
|
export declare type Fetch<T> = (args?: InferRequestType<T>, opt?: RequestOptions) => Promise<ClientResponse<InferResponseType<T>>>;
|
|
24
|
-
export declare type InferResponseType<T> = T extends () => Promise<ClientResponse<infer O>> ? O : never;
|
|
26
|
+
export declare type InferResponseType<T> = T extends (args: any | undefined) => Promise<ClientResponse<infer O>> ? O : never;
|
|
25
27
|
export declare type InferRequestType<T> = T extends (args: infer R) => Promise<ClientResponse<unknown>> ? NonNullable<R> : never;
|
|
26
28
|
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}` ? {
|
|
27
29
|
[K in P]: PathToChain<R, E, Original>;
|
|
28
30
|
} : {
|
|
29
31
|
[K in Path extends '' ? 'index' : Path]: ClientRequest<E extends Record<string, unknown> ? E[Original] : never>;
|
|
30
32
|
};
|
|
31
|
-
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;
|
|
33
|
+
export declare type Client<T> = T extends Hono<any, infer S, any> ? S extends Record<infer K, Endpoint> ? K extends string ? PathToChain<K, S> : never : never : never;
|
|
32
34
|
export declare type Callback = (opts: CallbackOptions) => unknown;
|
|
33
35
|
interface CallbackOptions {
|
|
34
36
|
path: string[];
|
package/dist/types/context.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { TypedResponse } from './types';
|
|
|
3
3
|
import type { Env, NotFoundHandler, Input } from './types';
|
|
4
4
|
import type { CookieOptions } from './utils/cookie';
|
|
5
5
|
import type { StatusCode } from './utils/http-status';
|
|
6
|
+
import type { PrettyJSON, JSONValue } from './utils/types';
|
|
6
7
|
declare type Runtime = 'node' | 'deno' | 'bun' | 'workerd' | 'fastly' | 'edge-light' | 'lagon' | 'other';
|
|
7
8
|
declare type HeaderRecord = Record<string, string | string[]>;
|
|
8
9
|
declare type Data = string | ArrayBuffer | ReadableStream;
|
|
@@ -52,7 +53,7 @@ export declare class Context<E extends Env = any, P extends string = any, I exte
|
|
|
52
53
|
body: (data: Data | null, status?: StatusCode, headers?: HeaderRecord) => Response;
|
|
53
54
|
text: (text: string, status?: StatusCode, headers?: HeaderRecord) => Response;
|
|
54
55
|
json: <T = object>(object: T, status?: StatusCode, headers?: HeaderRecord) => Response;
|
|
55
|
-
jsonT: <T
|
|
56
|
+
jsonT: <T>(object: T extends JSONValue ? T : JSONValue, status?: StatusCode, headers?: HeaderRecord) => TypedResponse<T extends JSONValue ? JSONValue extends T ? never : PrettyJSON<T> : never>;
|
|
56
57
|
html: (html: string, status?: StatusCode, headers?: HeaderRecord) => Response;
|
|
57
58
|
redirect: (location: string, status?: StatusCode) => Response;
|
|
58
59
|
cookie: (name: string, value: string, opt?: CookieOptions) => void;
|
package/dist/types/hono.d.ts
CHANGED
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
import type { ExecutionContext } from './context';
|
|
2
2
|
import type { Router } from './router';
|
|
3
|
-
import type { Env, ErrorHandler, H, HandlerInterface, MiddlewareHandlerInterface, NotFoundHandler, OnHandlerInterface,
|
|
3
|
+
import type { Env, ErrorHandler, H, HandlerInterface, MiddlewareHandlerInterface, NotFoundHandler, OnHandlerInterface, MergePath, MergeSchemaPath } from './types';
|
|
4
|
+
import type { RemoveBlankRecord } from './utils/types';
|
|
4
5
|
interface RouterRoute {
|
|
5
6
|
path: string;
|
|
6
7
|
method: string;
|
|
7
8
|
handler: H;
|
|
8
9
|
}
|
|
9
|
-
declare const Hono_base: new <E_1 extends Env = Env, S_1 = {}>() => {
|
|
10
|
-
all: HandlerInterface<E_1, "all", S_1>;
|
|
11
|
-
get: HandlerInterface<E_1, "get", S_1>;
|
|
12
|
-
post: HandlerInterface<E_1, "post", S_1>;
|
|
13
|
-
put: HandlerInterface<E_1, "put", S_1>;
|
|
14
|
-
delete: HandlerInterface<E_1, "delete", S_1>;
|
|
15
|
-
head: HandlerInterface<E_1, "head", S_1>;
|
|
16
|
-
options: HandlerInterface<E_1, "options", S_1>;
|
|
17
|
-
patch: HandlerInterface<E_1, "patch", S_1>;
|
|
10
|
+
declare const Hono_base: new <E_1 extends Env = Env, S_1 = {}, BasePath_1 extends string = "">() => {
|
|
11
|
+
all: HandlerInterface<E_1, "all", S_1, BasePath_1>;
|
|
12
|
+
get: HandlerInterface<E_1, "get", S_1, BasePath_1>;
|
|
13
|
+
post: HandlerInterface<E_1, "post", S_1, BasePath_1>;
|
|
14
|
+
put: HandlerInterface<E_1, "put", S_1, BasePath_1>;
|
|
15
|
+
delete: HandlerInterface<E_1, "delete", S_1, BasePath_1>;
|
|
16
|
+
head: HandlerInterface<E_1, "head", S_1, BasePath_1>;
|
|
17
|
+
options: HandlerInterface<E_1, "options", S_1, BasePath_1>;
|
|
18
|
+
patch: HandlerInterface<E_1, "patch", S_1, BasePath_1>;
|
|
18
19
|
} & {
|
|
19
|
-
on: OnHandlerInterface<E_1, S_1>;
|
|
20
|
+
on: OnHandlerInterface<E_1, S_1, BasePath_1>;
|
|
20
21
|
} & {
|
|
21
|
-
use: MiddlewareHandlerInterface<E_1, S_1>;
|
|
22
|
+
use: MiddlewareHandlerInterface<E_1, S_1, BasePath_1>;
|
|
22
23
|
};
|
|
23
|
-
export declare class Hono<E extends Env = Env, S = {}> extends Hono_base<E, S> {
|
|
24
|
+
export declare class Hono<E extends Env = Env, S = {}, BasePath extends string = ''> extends Hono_base<E, S, BasePath> {
|
|
24
25
|
readonly router: Router<H>;
|
|
25
26
|
readonly strict: boolean;
|
|
26
|
-
private
|
|
27
|
+
private basePath;
|
|
27
28
|
private path;
|
|
28
29
|
routes: RouterRoute[];
|
|
29
30
|
constructor(init?: Partial<Pick<Hono, 'router' | 'strict'>>);
|
|
31
|
+
private clone;
|
|
30
32
|
private notFoundHandler;
|
|
31
33
|
private errorHandler;
|
|
32
|
-
route<SubPath extends string, SubSchema>(path: SubPath, app?: Hono<
|
|
34
|
+
route<SubPath extends string, SubEnv extends Env, SubSchema>(path: SubPath, app?: Hono<SubEnv, SubSchema>): Hono<E, RemoveBlankRecord<MergeSchemaPath<SubSchema, SubPath> | S>, MergePath<BasePath, SubPath>>;
|
|
33
35
|
onError(handler: ErrorHandler<E>): this;
|
|
34
36
|
notFound(handler: NotFoundHandler<E>): this;
|
|
35
37
|
showRoutes(): void;
|
|
@@ -39,6 +41,6 @@ export declare class Hono<E extends Env = Env, S = {}> extends Hono_base<E, S> {
|
|
|
39
41
|
private dispatch;
|
|
40
42
|
handleEvent: (event: FetchEvent) => Response | Promise<Response>;
|
|
41
43
|
fetch: (request: Request, Env?: E['Bindings'] | {}, executionCtx?: ExecutionContext) => Response | Promise<Response>;
|
|
42
|
-
request: (input: Request | string, requestInit?: RequestInit) => Promise<Response>;
|
|
44
|
+
request: (input: Request | string | URL, requestInit?: RequestInit) => Promise<Response>;
|
|
43
45
|
}
|
|
44
46
|
export {};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -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;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Context } from './context';
|
|
2
2
|
import type { Hono } from './hono';
|
|
3
|
-
import type { UnionToIntersection } from './utils/types';
|
|
3
|
+
import type { UnionToIntersection, RemoveBlankRecord } from './utils/types';
|
|
4
4
|
export declare type Bindings = Record<string, unknown>;
|
|
5
5
|
export declare type Variables = Record<string, unknown>;
|
|
6
6
|
export declare type Env = {
|
|
@@ -14,40 +14,70 @@ export declare type MiddlewareHandler<E extends Env = any, P extends string = an
|
|
|
14
14
|
export declare type H<E extends Env = any, P extends string = any, I extends Input = {}, O = {}> = Handler<E, P, I, O> | MiddlewareHandler<E, P, I>;
|
|
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
|
-
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
|
|
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
|
|
17
|
+
export interface HandlerInterface<E extends Env = Env, M extends string = any, S = {}, BasePath extends string = ''> {
|
|
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
|
|
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
|
|
33
|
-
<I = {}, O = {}>(...handlers: Handler<E, ExtractKey<S>, I, O>[]): Hono<E, S
|
|
34
|
-
<P extends string, O = {}, I = {}>(path: P, ...handlers: [H<E, P, I, O>, H<E, P, I, O>]): Hono<E, S
|
|
35
|
-
<P extends string, O = {}, I = {}, I2 = I, I3 = I & I2>(path: P, ...handlers: [
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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, MergePath<BasePath, P>, I, O>>>;
|
|
35
|
+
<P extends string, O = {}, I = {}, I2 = I, I3 = I & I2>(path: P, ...handlers: [
|
|
36
|
+
H<E, MergePath<BasePath, P>, I, O>,
|
|
37
|
+
H<E, MergePath<BasePath, P>, I2, O>,
|
|
38
|
+
H<E, MergePath<BasePath, P>, I3, O>
|
|
39
|
+
]): Hono<E, RemoveBlankRecord<S | Schema<M, MergePath<BasePath, P>, I3, O>>>;
|
|
40
|
+
<P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3>(path: P, ...handlers: [
|
|
41
|
+
H<E, MergePath<BasePath, P>, I, O>,
|
|
42
|
+
H<E, MergePath<BasePath, P>, I2, O>,
|
|
43
|
+
H<E, MergePath<BasePath, P>, I3, O>,
|
|
44
|
+
H<E, MergePath<BasePath, P>, I4, O>
|
|
45
|
+
]): Hono<E, RemoveBlankRecord<S | Schema<M, MergePath<BasePath, P>, I4, O>>>;
|
|
46
|
+
<P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3, I5 = I3 & I4>(path: P, ...handlers: [
|
|
47
|
+
H<E, MergePath<BasePath, P>, I, O>,
|
|
48
|
+
H<E, MergePath<BasePath, P>, I2, O>,
|
|
49
|
+
H<E, MergePath<BasePath, P>, I3, O>,
|
|
50
|
+
H<E, MergePath<BasePath, P>, I4, O>,
|
|
51
|
+
H<E, MergePath<BasePath, P>, I5, O>
|
|
52
|
+
]): Hono<E, RemoveBlankRecord<S | Schema<M, MergePath<BasePath, P>, I5, O>>>;
|
|
53
|
+
<P extends string, I = {}, O = {}>(path: P, ...handlers: H<E, MergePath<BasePath, P>, I, O>[]): Hono<E, RemoveBlankRecord<S | Schema<M, MergePath<BasePath, P>, I, O>>>;
|
|
39
54
|
}
|
|
40
|
-
export interface MiddlewareHandlerInterface<E extends Env = Env, S = {}> {
|
|
41
|
-
(...handlers: MiddlewareHandler<E, ExtractKey<S
|
|
42
|
-
<P extends string>(path: P, ...handlers: MiddlewareHandler<E, P
|
|
55
|
+
export interface MiddlewareHandlerInterface<E extends Env = Env, S = {}, BasePath extends string = ''> {
|
|
56
|
+
(...handlers: MiddlewareHandler<E, MergePath<BasePath, ExtractKey<S>>>[]): Hono<E, S, BasePath>;
|
|
57
|
+
<P extends string>(path: P, ...handlers: MiddlewareHandler<E, MergePath<BasePath, P>>[]): Hono<E, S, BasePath>;
|
|
43
58
|
}
|
|
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,
|
|
46
|
-
<M extends string, P extends string, O = {}, I = {}, I2 = I, I3 = I & I2>(method: M, path: P, ...handlers: [
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
59
|
+
export interface OnHandlerInterface<E extends Env = Env, S = {}, BasePath extends string = ''> {
|
|
60
|
+
<M extends string, P extends string, O = {}, I = {}>(method: M, path: P, ...handlers: [H<E, MergePath<BasePath, P>, I, O>, H<E, MergePath<BasePath, P>, I, O>]): Hono<E, RemoveBlankRecord<S | Schema<M, MergePath<BasePath, P>, I, O>>, BasePath>;
|
|
61
|
+
<M extends string, P extends string, O = {}, I = {}, I2 = I, I3 = I & I2>(method: M, path: P, ...handlers: [
|
|
62
|
+
H<E, MergePath<BasePath, P>, I, O>,
|
|
63
|
+
H<E, MergePath<BasePath, P>, I2, O>,
|
|
64
|
+
H<E, MergePath<BasePath, P>, I3, O>
|
|
65
|
+
]): Hono<E, RemoveBlankRecord<S | Schema<M, MergePath<BasePath, P>, I3, O>>, BasePath>;
|
|
66
|
+
<M extends string, P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3>(method: M, path: P, ...handlers: [
|
|
67
|
+
H<E, MergePath<BasePath, P>, I, O>,
|
|
68
|
+
H<E, MergePath<BasePath, P>, I2, O>,
|
|
69
|
+
H<E, MergePath<BasePath, P>, I3, O>,
|
|
70
|
+
H<E, MergePath<BasePath, P>, I4, O>
|
|
71
|
+
]): Hono<E, RemoveBlankRecord<S | Schema<M, MergePath<BasePath, P>, I4, O>>, BasePath>;
|
|
72
|
+
<M extends string, P extends string, O = {}, I = {}, I2 = I, I3 = I & I2, I4 = I2 & I3, I5 = I3 & I4>(method: M, path: P, ...handlers: [
|
|
73
|
+
H<E, MergePath<BasePath, P>, I, O>,
|
|
74
|
+
H<E, MergePath<BasePath, P>, I2, O>,
|
|
75
|
+
H<E, MergePath<BasePath, P>, I3, O>,
|
|
76
|
+
H<E, MergePath<BasePath, P>, I4, O>,
|
|
77
|
+
H<E, MergePath<BasePath, P>, I5, O>
|
|
78
|
+
]): Hono<E, S | Schema<M, MergePath<BasePath, P>, I5, O>, BasePath>;
|
|
79
|
+
<M extends string, P extends string, O extends {} = {}, I = {}>(method: M, path: P, ...handlers: H<E, MergePath<BasePath, P>, I, O>[]): Hono<E, RemoveBlankRecord<S | Schema<M, MergePath<BasePath, P>, I, O>>, BasePath>;
|
|
80
|
+
<P extends string, O extends {} = {}, I = {}>(methods: string[], path: P, ...handlers: H<E, MergePath<BasePath, P>, I, O>[]): Hono<E, RemoveBlankRecord<S | Schema<string, MergePath<BasePath, P>, I, O>>, BasePath>;
|
|
51
81
|
}
|
|
52
82
|
declare type ExtractKey<S> = S extends Record<infer Key, unknown> ? Key extends string ? Key : never : string;
|
|
53
83
|
export declare type Schema<M extends string, P extends string, I extends Input, O> = {
|
|
@@ -65,7 +95,7 @@ export declare type AddDollar<T> = T extends Record<infer K, infer R> ? K extend
|
|
|
65
95
|
[MethodName in `$${Lowercase<K>}`]: R;
|
|
66
96
|
} : never : never;
|
|
67
97
|
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}
|
|
98
|
+
export declare type MergePath<A extends string, B extends string> = A extends '' ? B : A extends `${infer P}/` ? B extends `/${infer Q}` ? `${P}/${Q}` : `${P}/${B}` : B extends `/${infer Q}` ? `${A}/${Q}` : `${A}/${B}`;
|
|
69
99
|
export declare type TypedResponse<T = unknown> = {
|
|
70
100
|
response: Response | Promise<Response>;
|
|
71
101
|
data: T;
|
|
@@ -89,5 +119,4 @@ export declare type InputToDataByTarget<T extends Input, Target extends keyof Va
|
|
|
89
119
|
export declare type RemoveQuestion<T> = T extends `${infer R}?` ? R : T;
|
|
90
120
|
export declare type UndefinedIfHavingQuestion<T> = T extends `${infer _}?` ? string | undefined : string;
|
|
91
121
|
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;
|
|
93
122
|
export {};
|
|
@@ -2,3 +2,15 @@ export declare type Expect<T extends true> = T;
|
|
|
2
2
|
export declare type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
|
|
3
3
|
export declare type NotEqual<X, Y> = true extends Equal<X, Y> ? false : true;
|
|
4
4
|
export declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
5
|
+
export declare type RemoveBlankRecord<T> = T extends Record<infer K, unknown> ? K extends string ? T : never : never;
|
|
6
|
+
export declare type JSONPrimitive = string | boolean | number | null | undefined;
|
|
7
|
+
export declare type JSONArray = (JSONPrimitive | JSONObject | JSONArray)[];
|
|
8
|
+
export declare type JSONObject = {
|
|
9
|
+
[key: string]: JSONPrimitive | JSONArray | JSONObject;
|
|
10
|
+
};
|
|
11
|
+
export declare type JSONValue = JSONObject | JSONArray | JSONPrimitive;
|
|
12
|
+
declare type TrueAndFalseToBoolean<T> = T extends true ? boolean : T extends false ? boolean : T;
|
|
13
|
+
export declare type PrettyJSON<T> = T extends JSONPrimitive ? TrueAndFalseToBoolean<T> : T extends JSONArray ? PrettyJSON<T[number]> : T extends JSONObject ? {
|
|
14
|
+
[K in keyof T]: PrettyJSON<T[K]>;
|
|
15
|
+
} : never;
|
|
16
|
+
export {};
|
package/dist/utils/encode.js
CHANGED
|
@@ -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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
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.
|
|
22
|
+
value = await parseBody(c.req.raw.clone());
|
|
22
23
|
break;
|
|
23
24
|
case "query":
|
|
24
25
|
value = c.req.query();
|