hono 1.4.7 → 1.5.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 +42 -20
- package/dist/context.d.ts +4 -2
- package/dist/context.js +12 -3
- package/dist/hono.d.ts +1 -1
- package/dist/hono.js +5 -5
- package/dist/middleware/body-parse/index.d.ts +2 -2
- package/dist/middleware/cookie/index.d.ts +2 -2
- package/dist/middleware/serve-static/serve-static.d.ts +2 -1
- package/dist/middleware/serve-static/serve-static.js +1 -1
- package/dist/request.d.ts +19 -21
- package/dist/request.js +11 -11
- package/dist/router/reg-exp-router/router.d.ts +0 -1
- package/dist/router/reg-exp-router/router.js +1 -6
- package/dist/router/trie-router/node.js +1 -11
- package/dist/utils/cloudflare.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -483,10 +483,22 @@ app.use('/', async (c, next) => {
|
|
|
483
483
|
})
|
|
484
484
|
```
|
|
485
485
|
|
|
486
|
+
### c.executionCtx
|
|
487
|
+
|
|
488
|
+
```ts
|
|
489
|
+
// ExecutionContext object
|
|
490
|
+
app.get('/foo', async (c) => {
|
|
491
|
+
c.executionCtx.waitUntil(
|
|
492
|
+
c.env.KV.put(key, data)
|
|
493
|
+
)
|
|
494
|
+
...
|
|
495
|
+
})
|
|
496
|
+
```
|
|
497
|
+
|
|
486
498
|
### c.event
|
|
487
499
|
|
|
488
500
|
```ts
|
|
489
|
-
// FetchEvent object
|
|
501
|
+
// FetchEvent object (only set when using Service Worker syntax)
|
|
490
502
|
app.get('/foo', async (c) => {
|
|
491
503
|
c.event.waitUntil(
|
|
492
504
|
c.env.KV.put(key, data)
|
|
@@ -523,8 +535,8 @@ addEventListener('fetch', (event) => {
|
|
|
523
535
|
|
|
524
536
|
```ts
|
|
525
537
|
export default {
|
|
526
|
-
fetch(request: Request, env: Env,
|
|
527
|
-
return app.fetch(request, env,
|
|
538
|
+
fetch(request: Request, env: Env, ctx: ExecutionContext) {
|
|
539
|
+
return app.fetch(request, env, ctx)
|
|
528
540
|
},
|
|
529
541
|
}
|
|
530
542
|
```
|
|
@@ -556,9 +568,9 @@ import { RegExpRouter } from 'hono/router/reg-exp-router'
|
|
|
556
568
|
const app = new Hono({ router: new RegExpRouter() })
|
|
557
569
|
```
|
|
558
570
|
|
|
559
|
-
## Routing
|
|
571
|
+
## Routing priority
|
|
560
572
|
|
|
561
|
-
|
|
573
|
+
Handlers or middleware will be executed in registration order.
|
|
562
574
|
|
|
563
575
|
```ts
|
|
564
576
|
app.get('/book/a', (c) => c.text('a')) // a
|
|
@@ -566,27 +578,37 @@ app.get('/book/:slug', (c) => c.text('common')) // common
|
|
|
566
578
|
```
|
|
567
579
|
|
|
568
580
|
```http
|
|
569
|
-
GET /book/a ---> `a`
|
|
570
|
-
GET /book/b ---> `common`
|
|
581
|
+
GET /book/a ---> `a`
|
|
582
|
+
GET /book/b ---> `common`
|
|
571
583
|
```
|
|
572
584
|
|
|
573
|
-
|
|
585
|
+
When a handler is executed, the process will be stopped.
|
|
574
586
|
|
|
575
587
|
```ts
|
|
576
|
-
app.get('
|
|
577
|
-
app.get('/
|
|
578
|
-
app.get('/api/posts/:id', 'e') // score 3.3
|
|
579
|
-
app.get('/api/posts/123', 'f') // score 3.4
|
|
580
|
-
app.get('/*/*/:id', 'g') // score 3.5
|
|
581
|
-
app.get('/api/posts/*/comment', 'h') // score 4.6 - not match
|
|
582
|
-
app.get('*', 'a') // score 0.7
|
|
583
|
-
app.get('*', 'b') // score 0.8
|
|
588
|
+
app.get('*', (c) => c.text('common')) // common
|
|
589
|
+
app.get('/foo', (c) => c.text('foo')) // foo
|
|
584
590
|
```
|
|
585
591
|
|
|
586
|
-
```
|
|
587
|
-
GET /
|
|
588
|
-
|
|
589
|
-
|
|
592
|
+
```http
|
|
593
|
+
GET /foo ---> `common` // foo will not be dispatched
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
If you have the middleware that you want to execute, write the code above the handler.
|
|
597
|
+
|
|
598
|
+
```ts
|
|
599
|
+
app.use('*', logger())
|
|
600
|
+
app.get('/foo', (c) => c.text('foo'))
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
If you want a "_fallback_" handler, write the code below the other handler.
|
|
604
|
+
|
|
605
|
+
```ts
|
|
606
|
+
app.get('/foo', (c) => c.text('foo')) // foo
|
|
607
|
+
app.get('*', (c) => c.text('fallback')) // fallback
|
|
608
|
+
```
|
|
609
|
+
|
|
610
|
+
```http
|
|
611
|
+
GET /bar ---> `fallback`
|
|
590
612
|
```
|
|
591
613
|
|
|
592
614
|
## Cloudflare Workers with Hono
|
package/dist/context.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
2
|
import type { NotFoundHandler } from './hono';
|
|
3
|
+
import type { HonoRequest } from './request';
|
|
3
4
|
import type { StatusCode } from './utils/http-status';
|
|
4
5
|
declare type Headers = Record<string, string>;
|
|
5
6
|
export declare type Data = string | ArrayBuffer | ReadableStream;
|
|
6
7
|
export declare type Env = Record<string, any>;
|
|
7
8
|
export declare class Context<RequestParamKeyType extends string = string, E = Env> {
|
|
8
|
-
req:
|
|
9
|
+
req: HonoRequest<RequestParamKeyType>;
|
|
9
10
|
env: E;
|
|
10
11
|
event: FetchEvent | undefined;
|
|
12
|
+
executionCtx: ExecutionContext | undefined;
|
|
11
13
|
finalized: boolean;
|
|
12
14
|
private _status;
|
|
13
15
|
private _pretty;
|
|
@@ -17,7 +19,7 @@ export declare class Context<RequestParamKeyType extends string = string, E = En
|
|
|
17
19
|
private _res;
|
|
18
20
|
private notFoundHandler;
|
|
19
21
|
render: (content: string, params?: object, options?: object) => Response | Promise<Response>;
|
|
20
|
-
constructor(req: Request
|
|
22
|
+
constructor(req: HonoRequest | Request, env?: E | undefined, eventOrExecutionCtx?: FetchEvent | ExecutionContext | undefined, notFoundHandler?: NotFoundHandler);
|
|
21
23
|
get res(): Response;
|
|
22
24
|
set res(_res: Response);
|
|
23
25
|
header(name: string, value: string): void;
|
package/dist/context.js
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Context = void 0;
|
|
4
|
+
const request_1 = require("./request");
|
|
4
5
|
const url_1 = require("./utils/url");
|
|
5
6
|
class Context {
|
|
6
|
-
constructor(req, env = undefined,
|
|
7
|
+
constructor(req, env = undefined, eventOrExecutionCtx = undefined, notFoundHandler = () => new Response()) {
|
|
7
8
|
this._status = 200;
|
|
8
9
|
this._pretty = false;
|
|
9
10
|
this._prettySpace = 2;
|
|
10
|
-
|
|
11
|
+
if (req instanceof Request) {
|
|
12
|
+
this.req = (0, request_1.extendHonoRequest)(req);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
this.req = req;
|
|
16
|
+
}
|
|
11
17
|
if (env) {
|
|
12
18
|
this.env = env;
|
|
13
19
|
}
|
|
14
|
-
this.
|
|
20
|
+
this.executionCtx = eventOrExecutionCtx;
|
|
21
|
+
if (eventOrExecutionCtx && 'respondWith' in eventOrExecutionCtx) {
|
|
22
|
+
this.event = eventOrExecutionCtx;
|
|
23
|
+
}
|
|
15
24
|
this.notFoundHandler = notFoundHandler;
|
|
16
25
|
this.finalized = false;
|
|
17
26
|
}
|
package/dist/hono.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ export declare class Hono<E extends Env = Env, P extends string = '/'> extends H
|
|
|
48
48
|
private matchRoute;
|
|
49
49
|
private dispatch;
|
|
50
50
|
handleEvent(event: FetchEvent): Promise<Response>;
|
|
51
|
-
fetch(request: Request, env?: E,
|
|
51
|
+
fetch(request: Request, env?: E, executionCtx?: ExecutionContext): Promise<Response>;
|
|
52
52
|
request(input: RequestInfo, requestInit?: RequestInit): Promise<Response>;
|
|
53
53
|
fire(): void;
|
|
54
54
|
}
|
package/dist/hono.js
CHANGED
|
@@ -29,7 +29,6 @@ class Hono extends defineDynamicClass() {
|
|
|
29
29
|
const message = 'Internal Server Error';
|
|
30
30
|
return c.text(message, 500);
|
|
31
31
|
};
|
|
32
|
-
(0, request_1.extendRequestPrototype)(); // FIXME: should be executed at a better timing
|
|
33
32
|
const allMethods = [...methods, router_1.METHOD_NAME_ALL_LOWERCASE];
|
|
34
33
|
allMethods.map((method) => {
|
|
35
34
|
this[method] = (args1, ...args) => {
|
|
@@ -91,13 +90,14 @@ class Hono extends defineDynamicClass() {
|
|
|
91
90
|
matchRoute(method, path) {
|
|
92
91
|
return this.router.match(method, path);
|
|
93
92
|
}
|
|
94
|
-
async dispatch(request,
|
|
93
|
+
async dispatch(request, executionCtx, env) {
|
|
94
|
+
request = (0, request_1.extendHonoRequest)(request);
|
|
95
95
|
const path = (0, url_1.getPathFromURL)(request.url, this.strict);
|
|
96
96
|
const method = request.method;
|
|
97
97
|
const result = this.matchRoute(method, path);
|
|
98
98
|
request.paramData = result?.params;
|
|
99
99
|
const handlers = result ? result.handlers : [this.notFoundHandler];
|
|
100
|
-
const c = new context_1.Context(request, env,
|
|
100
|
+
const c = new context_1.Context(request, env, executionCtx, this.notFoundHandler);
|
|
101
101
|
const composed = (0, compose_1.compose)(handlers, this.errorHandler, this.notFoundHandler);
|
|
102
102
|
let context;
|
|
103
103
|
try {
|
|
@@ -117,8 +117,8 @@ class Hono extends defineDynamicClass() {
|
|
|
117
117
|
async handleEvent(event) {
|
|
118
118
|
return this.dispatch(event.request, event);
|
|
119
119
|
}
|
|
120
|
-
async fetch(request, env,
|
|
121
|
-
return this.dispatch(request,
|
|
120
|
+
async fetch(request, env, executionCtx) {
|
|
121
|
+
return this.dispatch(request, executionCtx, env);
|
|
122
122
|
}
|
|
123
123
|
request(input, requestInit) {
|
|
124
124
|
const req = input instanceof Request ? input : new Request(input, requestInit);
|
|
@@ -13,7 +13,7 @@ const serveStatic = (options = { root: '' }) => {
|
|
|
13
13
|
}
|
|
14
14
|
const url = new URL(c.req.url);
|
|
15
15
|
const path = (0, cloudflare_1.getKVFilePath)({
|
|
16
|
-
filename: url.pathname,
|
|
16
|
+
filename: options.path ?? url.pathname,
|
|
17
17
|
root: options.root,
|
|
18
18
|
defaultDocument: DEFAULT_DOCUMENT,
|
|
19
19
|
});
|
package/dist/request.d.ts
CHANGED
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
declare
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
};
|
|
20
|
-
}
|
|
1
|
+
export declare class HonoRequest<ParamKeyType extends string = string> extends Request {
|
|
2
|
+
param: {
|
|
3
|
+
(key: ParamKeyType): string;
|
|
4
|
+
(): Record<ParamKeyType, string>;
|
|
5
|
+
};
|
|
6
|
+
paramData?: Record<ParamKeyType, string>;
|
|
7
|
+
query: {
|
|
8
|
+
(key: string): string;
|
|
9
|
+
(): Record<string, string>;
|
|
10
|
+
};
|
|
11
|
+
queries: {
|
|
12
|
+
(key: string): string[];
|
|
13
|
+
(): Record<string, string[]>;
|
|
14
|
+
};
|
|
15
|
+
header: {
|
|
16
|
+
(name: string): string;
|
|
17
|
+
(): Record<string, string>;
|
|
18
|
+
};
|
|
21
19
|
}
|
|
22
|
-
export declare function
|
|
20
|
+
export declare function extendHonoRequest(request: HonoRequest): HonoRequest;
|
package/dist/request.js
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
Request.prototype.param = function (key) {
|
|
3
|
+
exports.extendHonoRequest = exports.HonoRequest = void 0;
|
|
4
|
+
class HonoRequest extends Request {
|
|
5
|
+
}
|
|
6
|
+
exports.HonoRequest = HonoRequest;
|
|
7
|
+
function extendHonoRequest(request) {
|
|
8
|
+
request.param = function (key) {
|
|
10
9
|
if (this.paramData) {
|
|
11
10
|
if (key) {
|
|
12
11
|
return this.paramData[key];
|
|
@@ -17,7 +16,7 @@ function extendRequestPrototype() {
|
|
|
17
16
|
}
|
|
18
17
|
return null;
|
|
19
18
|
};
|
|
20
|
-
|
|
19
|
+
request.header = function (name) {
|
|
21
20
|
if (name) {
|
|
22
21
|
return this.headers.get(name);
|
|
23
22
|
}
|
|
@@ -29,7 +28,7 @@ function extendRequestPrototype() {
|
|
|
29
28
|
return result;
|
|
30
29
|
}
|
|
31
30
|
};
|
|
32
|
-
|
|
31
|
+
request.query = function (key) {
|
|
33
32
|
const url = new URL(this.url);
|
|
34
33
|
if (key) {
|
|
35
34
|
return url.searchParams.get(key);
|
|
@@ -42,7 +41,7 @@ function extendRequestPrototype() {
|
|
|
42
41
|
return result;
|
|
43
42
|
}
|
|
44
43
|
};
|
|
45
|
-
|
|
44
|
+
request.queries = function (key) {
|
|
46
45
|
const url = new URL(this.url);
|
|
47
46
|
if (key) {
|
|
48
47
|
return url.searchParams.getAll(key);
|
|
@@ -55,5 +54,6 @@ function extendRequestPrototype() {
|
|
|
55
54
|
return result;
|
|
56
55
|
}
|
|
57
56
|
};
|
|
57
|
+
return request;
|
|
58
58
|
}
|
|
59
|
-
exports.
|
|
59
|
+
exports.extendHonoRequest = extendHonoRequest;
|
|
@@ -65,9 +65,7 @@ function compareRoute(a, b) {
|
|
|
65
65
|
return i === b.hint.regExpComponents.length || a.hint.endWithWildcard ? 1 : 0;
|
|
66
66
|
}
|
|
67
67
|
function compareHandler(a, b) {
|
|
68
|
-
return a.
|
|
69
|
-
? a.componentsLength - b.componentsLength
|
|
70
|
-
: a.index - b.index;
|
|
68
|
+
return a.index - b.index;
|
|
71
69
|
}
|
|
72
70
|
function getSortedHandlers(handlers) {
|
|
73
71
|
return [...handlers].sort(compareHandler).map((h) => h.handler);
|
|
@@ -158,7 +156,6 @@ class RegExpRouter {
|
|
|
158
156
|
const handlerWithSortIndex = {
|
|
159
157
|
index,
|
|
160
158
|
handler,
|
|
161
|
-
componentsLength: hint.components.length || 1,
|
|
162
159
|
};
|
|
163
160
|
for (let i = 0, len = routes.length; i < len; i++) {
|
|
164
161
|
if (routes[i].method === method && routes[i].path === path) {
|
|
@@ -318,9 +315,7 @@ class RegExpRouter {
|
|
|
318
315
|
}
|
|
319
316
|
}
|
|
320
317
|
if (routes[j].hint.components.length < routes[i].hint.components.length) {
|
|
321
|
-
const componentsLength = routes[j].hint.components.length || 1;
|
|
322
318
|
routes[j].middleware.push(...routes[i].handlers.map((h) => ({
|
|
323
|
-
componentsLength,
|
|
324
319
|
index: h.index,
|
|
325
320
|
handler: h.handler,
|
|
326
321
|
})));
|
|
@@ -66,18 +66,11 @@ class Node {
|
|
|
66
66
|
parentPatterns.push(...curNode.patterns);
|
|
67
67
|
curNode = curNode.children[p];
|
|
68
68
|
}
|
|
69
|
-
let score = 1;
|
|
70
|
-
if (path === '*') {
|
|
71
|
-
score = score + this.order * 0.01;
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
score = parts.length + this.order * 0.01;
|
|
75
|
-
}
|
|
76
69
|
if (!curNode.methods.length) {
|
|
77
70
|
curNode.methods = [];
|
|
78
71
|
}
|
|
79
72
|
const m = {};
|
|
80
|
-
const handlerSet = { handler: handler, name: this.name, score:
|
|
73
|
+
const handlerSet = { handler: handler, name: this.name, score: this.order };
|
|
81
74
|
m[method] = handlerSet;
|
|
82
75
|
curNode.methods.push(m);
|
|
83
76
|
return curNode;
|
|
@@ -90,9 +83,6 @@ class Node {
|
|
|
90
83
|
const handlerSet = m[method] || m[router_1.METHOD_NAME_ALL];
|
|
91
84
|
if (handlerSet !== undefined) {
|
|
92
85
|
const hs = { ...handlerSet };
|
|
93
|
-
if (wildcard) {
|
|
94
|
-
hs.score = handlerSet.score - 1;
|
|
95
|
-
}
|
|
96
86
|
handlerSets.push(hs);
|
|
97
87
|
return;
|
|
98
88
|
}
|
package/dist/utils/cloudflare.js
CHANGED
|
@@ -50,7 +50,7 @@ const getKVFilePath = (options) => {
|
|
|
50
50
|
filename = filename.concat('/' + defaultDocument);
|
|
51
51
|
}
|
|
52
52
|
// /foo.html => foo.html
|
|
53
|
-
filename = filename.replace(
|
|
53
|
+
filename = filename.replace(/^\.?\//, '');
|
|
54
54
|
// assets/ => assets
|
|
55
55
|
root = root.replace(/\/$/, '');
|
|
56
56
|
// ./assets/foo.html => assets/foo.html
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.2",
|
|
4
4
|
"description": "Ultrafast web framework for Cloudflare Workers.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
"form-data": "^4.0.0",
|
|
146
146
|
"graphql": "^16.4.0",
|
|
147
147
|
"jest": "27.5.1",
|
|
148
|
-
"jest-environment-miniflare": "^2.5.
|
|
148
|
+
"jest-environment-miniflare": "^2.5.1",
|
|
149
149
|
"mustache": "^4.2.0",
|
|
150
150
|
"prettier": "^2.6.2",
|
|
151
151
|
"prettier-plugin-md-nocjsp": "^1.2.0",
|