hono 2.0.7 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -6
- package/dist/compose.d.ts +1 -1
- package/dist/compose.js +19 -16
- package/dist/context.d.ts +13 -8
- package/dist/context.js +7 -7
- package/dist/hono.d.ts +19 -11
- package/dist/hono.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/middleware/compress/index.d.ts +1 -1
- package/dist/middleware/cors/index.d.ts +1 -1
- package/dist/middleware/etag/index.js +1 -3
- package/dist/middleware/serve-static/module.d.mts +1 -3
- package/dist/request.d.ts +2 -3
- package/dist/request.js +7 -2
- package/dist/router/trie-router/node.js +15 -8
- package/dist/utils/body.d.ts +1 -2
- package/dist/utils/body.js +9 -22
- package/dist/utils/buffer.d.ts +1 -1
- package/dist/utils/cloudflare.d.ts +1 -1
- package/dist/utils/crypto.d.ts +1 -1
- package/dist/utils/crypto.js +9 -0
- package/dist/utils/mime.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
[](https://github.com/honojs/hono/pulse)
|
|
22
22
|
[](https://github.com/honojs/hono/commits/main)
|
|
23
23
|
[](https://doc.deno.land/https/deno.land/x/hono/mod.ts)
|
|
24
|
+
[](https://discord.gg/KVYKWmfD)
|
|
24
25
|
|
|
25
26
|
Hono - _**[炎] means flame🔥 in Japanese**_ - is a small, simple, and ultrafast web framework for Cloudflare Workers, Deno, Bun, and others.
|
|
26
27
|
|
|
@@ -46,13 +47,13 @@ export default app
|
|
|
46
47
|
**Hono is fastest**, compared to other routers for Cloudflare Workers.
|
|
47
48
|
|
|
48
49
|
```plain
|
|
49
|
-
hono - trie-router(default) x
|
|
50
|
-
hono - regexp-router x
|
|
51
|
-
itty-router x
|
|
52
|
-
sunder x
|
|
53
|
-
worktop x
|
|
50
|
+
hono - trie-router(default) x 437,354 ops/sec ±4.58% (83 runs sampled)
|
|
51
|
+
hono - regexp-router x 535,157 ops/sec ±3.46% (83 runs sampled)
|
|
52
|
+
itty-router x 203,092 ops/sec ±3.64% (89 runs sampled)
|
|
53
|
+
sunder x 308,252 ops/sec ±2.17% (91 runs sampled)
|
|
54
|
+
worktop x 190,764 ops/sec ±3.11% (86 runs sampled)
|
|
54
55
|
Fastest is hono - regexp-router
|
|
55
|
-
✨ Done in
|
|
56
|
+
✨ Done in 38.26s.
|
|
56
57
|
```
|
|
57
58
|
|
|
58
59
|
## Documentation
|
|
@@ -63,6 +64,10 @@ The documentation is available on [honojs.dev](https://honojs.dev).
|
|
|
63
64
|
|
|
64
65
|
Migration guide is available on [docs/MIGRATION.md](docs/MIGRATION.md).
|
|
65
66
|
|
|
67
|
+
## Communication
|
|
68
|
+
|
|
69
|
+
[Twitter](https://twitter.com/honojs) and [Discord channel](https://discord.gg/KVYKWmfD) are available.
|
|
70
|
+
|
|
66
71
|
## Contributing
|
|
67
72
|
|
|
68
73
|
Contributions Welcome! You can contribute in the following ways.
|
package/dist/compose.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { ErrorHandler, NotFoundHandler } from './hono';
|
|
2
|
-
export declare const compose: <C>(middleware: Function[], onError?: ErrorHandler, onNotFound?: NotFoundHandler) => (context: C, next?: Function) => Promise<C>;
|
|
2
|
+
export declare const compose: <C>(middleware: Function[], onError?: ErrorHandler<import("./hono").Environment> | undefined, onNotFound?: NotFoundHandler<import("./hono").Environment> | undefined) => (context: C, next?: Function | undefined) => Promise<C>;
|
package/dist/compose.js
CHANGED
|
@@ -4,42 +4,45 @@ exports.compose = void 0;
|
|
|
4
4
|
const context_1 = require("./context");
|
|
5
5
|
// Based on the code in the MIT licensed `koa-compose` package.
|
|
6
6
|
const compose = (middleware, onError, onNotFound) => {
|
|
7
|
+
const middlewareLength = middleware.length;
|
|
7
8
|
return (context, next) => {
|
|
8
9
|
let index = -1;
|
|
9
10
|
return dispatch(0);
|
|
10
11
|
async function dispatch(i) {
|
|
11
12
|
if (i <= index) {
|
|
12
|
-
|
|
13
|
+
throw new Error('next() called multiple times');
|
|
13
14
|
}
|
|
14
15
|
let handler = middleware[i];
|
|
15
16
|
index = i;
|
|
16
|
-
if (i ===
|
|
17
|
+
if (i === middlewareLength && next)
|
|
17
18
|
handler = next;
|
|
18
19
|
if (!handler) {
|
|
19
20
|
if (context instanceof context_1.HonoContext && context.finalized === false && onNotFound) {
|
|
20
21
|
context.res = await onNotFound(context);
|
|
21
22
|
}
|
|
22
|
-
return Promise.resolve(context);
|
|
23
|
-
}
|
|
24
|
-
return Promise.resolve(handler(context, () => dispatch(i + 1)))
|
|
25
|
-
.then((res) => {
|
|
26
|
-
// If handler return Response like `return c.text('foo')`
|
|
27
|
-
if (res && context instanceof context_1.HonoContext) {
|
|
28
|
-
context.res = res;
|
|
29
|
-
}
|
|
30
23
|
return context;
|
|
31
|
-
}
|
|
32
|
-
|
|
24
|
+
}
|
|
25
|
+
let res;
|
|
26
|
+
let isError = false;
|
|
27
|
+
try {
|
|
28
|
+
const tmp = handler(context, () => dispatch(i + 1));
|
|
29
|
+
res = tmp instanceof Promise ? await tmp : tmp;
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
33
32
|
if (context instanceof context_1.HonoContext && onError) {
|
|
34
33
|
if (err instanceof Error) {
|
|
35
|
-
|
|
34
|
+
isError = true;
|
|
35
|
+
res = onError(err, context);
|
|
36
36
|
}
|
|
37
|
-
return context;
|
|
38
37
|
}
|
|
39
|
-
|
|
38
|
+
if (!res) {
|
|
40
39
|
throw err;
|
|
41
40
|
}
|
|
42
|
-
}
|
|
41
|
+
}
|
|
42
|
+
if (res && context instanceof context_1.HonoContext && (!context.finalized || isError)) {
|
|
43
|
+
context.res = res;
|
|
44
|
+
}
|
|
45
|
+
return context;
|
|
43
46
|
}
|
|
44
47
|
};
|
|
45
48
|
};
|
package/dist/context.d.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import type {
|
|
2
|
+
import type { Environment, NotFoundHandler, ContextVariableMap, Bindings } from './hono';
|
|
3
3
|
import type { CookieOptions } from './utils/cookie';
|
|
4
4
|
import type { StatusCode } from './utils/http-status';
|
|
5
5
|
declare type Headers = Record<string, string>;
|
|
6
6
|
export declare type Data = string | ArrayBuffer | ReadableStream;
|
|
7
|
-
|
|
8
|
-
export interface Context<RequestParamKeyType extends string = string, E = Env> {
|
|
7
|
+
export interface Context<RequestParamKeyType extends string = string, E extends Partial<Environment> = Environment> {
|
|
9
8
|
req: Request<RequestParamKeyType>;
|
|
10
|
-
env: E;
|
|
9
|
+
env: E['Bindings'] | Bindings;
|
|
11
10
|
event: FetchEvent;
|
|
12
11
|
executionCtx: ExecutionContext;
|
|
13
12
|
finalized: boolean;
|
|
@@ -17,10 +16,12 @@ export interface Context<RequestParamKeyType extends string = string, E = Env> {
|
|
|
17
16
|
status: (status: StatusCode) => void;
|
|
18
17
|
set: {
|
|
19
18
|
<Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void;
|
|
19
|
+
<Key extends keyof E['Variables']>(key: Key, value: E['Variables'][Key]): void;
|
|
20
20
|
(key: string, value: any): void;
|
|
21
21
|
};
|
|
22
22
|
get: {
|
|
23
23
|
<Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
|
|
24
|
+
<Key extends keyof E['Variables']>(key: Key): E['Variables'][Key];
|
|
24
25
|
<T = any>(key: string): T;
|
|
25
26
|
};
|
|
26
27
|
pretty: (prettyJSON: boolean, space?: number) => void;
|
|
@@ -33,9 +34,9 @@ export interface Context<RequestParamKeyType extends string = string, E = Env> {
|
|
|
33
34
|
cookie: (name: string, value: string, options?: CookieOptions) => void;
|
|
34
35
|
notFound: () => Response | Promise<Response>;
|
|
35
36
|
}
|
|
36
|
-
export declare class HonoContext<RequestParamKeyType extends string = string, E =
|
|
37
|
+
export declare class HonoContext<RequestParamKeyType extends string = string, E extends Partial<Environment> = Environment> implements Context<RequestParamKeyType, E> {
|
|
37
38
|
req: Request<RequestParamKeyType>;
|
|
38
|
-
env:
|
|
39
|
+
env: Environment['Bindings'];
|
|
39
40
|
finalized: boolean;
|
|
40
41
|
_status: StatusCode;
|
|
41
42
|
private _executionCtx;
|
|
@@ -45,15 +46,19 @@ export declare class HonoContext<RequestParamKeyType extends string = string, E
|
|
|
45
46
|
private _headers;
|
|
46
47
|
private _res;
|
|
47
48
|
private notFoundHandler;
|
|
48
|
-
constructor(req: Request, env?: E | undefined, executionCtx?: FetchEvent | ExecutionContext | undefined, notFoundHandler?: NotFoundHandler);
|
|
49
|
+
constructor(req: Request, env?: E['Bindings'] | undefined, executionCtx?: FetchEvent | ExecutionContext | undefined, notFoundHandler?: NotFoundHandler);
|
|
49
50
|
get event(): FetchEvent;
|
|
50
51
|
get executionCtx(): ExecutionContext;
|
|
51
52
|
get res(): Response;
|
|
52
53
|
set res(_res: Response);
|
|
53
54
|
header(name: string, value: string): void;
|
|
54
55
|
status(status: StatusCode): void;
|
|
56
|
+
set<Key extends keyof ContextVariableMap>(key: Key, value: ContextVariableMap[Key]): void;
|
|
57
|
+
set<Key extends keyof E['Variables']>(key: Key, value: E['Variables'][Key]): void;
|
|
55
58
|
set(key: string, value: any): void;
|
|
56
|
-
get(key:
|
|
59
|
+
get<Key extends keyof ContextVariableMap>(key: Key): ContextVariableMap[Key];
|
|
60
|
+
get<Key extends keyof E['Variables']>(key: Key): E['Variables'][Key];
|
|
61
|
+
get<T = any>(key: string): T;
|
|
57
62
|
pretty(prettyJSON: boolean, space?: number): void;
|
|
58
63
|
newResponse(data: Data | null, status: StatusCode, headers?: Headers): Response;
|
|
59
64
|
body(data: Data | null, status?: StatusCode, headers?: Headers): Response;
|
package/dist/context.js
CHANGED
|
@@ -39,7 +39,7 @@ class HonoContext {
|
|
|
39
39
|
}
|
|
40
40
|
header(name, value) {
|
|
41
41
|
this._headers || (this._headers = {});
|
|
42
|
-
this._headers[name] = value;
|
|
42
|
+
this._headers[name.toLowerCase()] = value;
|
|
43
43
|
if (this.finalized) {
|
|
44
44
|
this.res.headers.set(name, value);
|
|
45
45
|
}
|
|
@@ -62,7 +62,7 @@ class HonoContext {
|
|
|
62
62
|
this._prettySpace = space;
|
|
63
63
|
}
|
|
64
64
|
newResponse(data, status, headers = {}) {
|
|
65
|
-
const _headers = { ...this._headers
|
|
65
|
+
const _headers = { ...this._headers };
|
|
66
66
|
if (this._res) {
|
|
67
67
|
this._res.headers.forEach((v, k) => {
|
|
68
68
|
_headers[k] = v;
|
|
@@ -70,25 +70,25 @@ class HonoContext {
|
|
|
70
70
|
}
|
|
71
71
|
return new Response(data, {
|
|
72
72
|
status: status || this._status || 200,
|
|
73
|
-
headers: _headers,
|
|
73
|
+
headers: { ..._headers, ...headers },
|
|
74
74
|
});
|
|
75
75
|
}
|
|
76
76
|
body(data, status = this._status, headers = {}) {
|
|
77
77
|
return this.newResponse(data, status, headers);
|
|
78
78
|
}
|
|
79
79
|
text(text, status = this._status, headers = {}) {
|
|
80
|
-
headers['
|
|
80
|
+
headers['content-type'] = 'text/plain; charset=UTF-8';
|
|
81
81
|
return this.body(text, status, headers);
|
|
82
82
|
}
|
|
83
83
|
json(object, status = this._status, headers = {}) {
|
|
84
84
|
const body = this._pretty
|
|
85
85
|
? JSON.stringify(object, null, this._prettySpace)
|
|
86
86
|
: JSON.stringify(object);
|
|
87
|
-
headers['
|
|
87
|
+
headers['content-type'] = 'application/json; charset=UTF-8';
|
|
88
88
|
return this.body(body, status, headers);
|
|
89
89
|
}
|
|
90
90
|
html(html, status = this._status, headers = {}) {
|
|
91
|
-
headers['
|
|
91
|
+
headers['content-type'] = 'text/html; charset=UTF-8';
|
|
92
92
|
return this.body(html, status, headers);
|
|
93
93
|
}
|
|
94
94
|
redirect(location, status = 302) {
|
|
@@ -103,7 +103,7 @@ class HonoContext {
|
|
|
103
103
|
}
|
|
104
104
|
cookie(name, value, opt) {
|
|
105
105
|
const cookie = (0, cookie_1.serialize)(name, value, opt);
|
|
106
|
-
this.header('
|
|
106
|
+
this.header('set-cookie', cookie);
|
|
107
107
|
}
|
|
108
108
|
notFound() {
|
|
109
109
|
return this.notFoundHandler(this);
|
package/dist/hono.d.ts
CHANGED
|
@@ -3,26 +3,31 @@ import type { Context } from './context';
|
|
|
3
3
|
import type { Router } from './router';
|
|
4
4
|
export interface ContextVariableMap {
|
|
5
5
|
}
|
|
6
|
-
declare type
|
|
7
|
-
export declare type
|
|
8
|
-
export declare type
|
|
9
|
-
|
|
6
|
+
export declare type Bindings = Record<string, any>;
|
|
7
|
+
export declare type Variables = Record<string, any>;
|
|
8
|
+
export declare type Environment = {
|
|
9
|
+
Bindings: Bindings;
|
|
10
|
+
Variables: Variables;
|
|
11
|
+
};
|
|
12
|
+
export declare type Handler<RequestParamKeyType extends string = string, E extends Partial<Environment> = Environment> = (c: Context<RequestParamKeyType, E>, next: Next) => Response | Promise<Response> | Promise<void> | Promise<Response | undefined>;
|
|
13
|
+
export declare type NotFoundHandler<E extends Partial<Environment> = Environment> = (c: Context<string, E>) => Response | Promise<Response>;
|
|
14
|
+
export declare type ErrorHandler<E extends Partial<Environment> = Environment> = (err: Error, c: Context<string, E>) => Response;
|
|
10
15
|
export declare type Next = () => Promise<void>;
|
|
11
16
|
declare type ParamKeyName<NameWithPattern> = NameWithPattern extends `${infer Name}{${infer _Pattern}` ? Name : NameWithPattern;
|
|
12
17
|
declare type ParamKey<Component> = Component extends `:${infer NameWithPattern}` ? ParamKeyName<NameWithPattern> : never;
|
|
13
18
|
declare type ParamKeys<Path> = Path extends `${infer Component}/${infer Rest}` ? ParamKey<Component> | ParamKeys<Rest> : ParamKey<Path>;
|
|
14
|
-
interface HandlerInterface<T extends string, E extends
|
|
19
|
+
interface HandlerInterface<T extends string, E extends Partial<Environment> = Environment, U = Hono<E, T>> {
|
|
15
20
|
<Path extends string>(path: Path, ...handlers: Handler<ParamKeys<Path> extends never ? string : ParamKeys<Path>, E>[]): U;
|
|
16
21
|
(path: string, ...handlers: Handler<string, E>[]): U;
|
|
17
22
|
<Path extends string>(...handlers: Handler<ParamKeys<Path> extends never ? string : ParamKeys<Path>, E>[]): U;
|
|
18
23
|
(...handlers: Handler<string, E>[]): U;
|
|
19
24
|
}
|
|
20
|
-
interface Route<E extends
|
|
25
|
+
interface Route<E extends Partial<Environment> = Environment> {
|
|
21
26
|
path: string;
|
|
22
27
|
method: string;
|
|
23
28
|
handler: Handler<string, E>;
|
|
24
29
|
}
|
|
25
|
-
declare const Hono_base: new <E_1 extends
|
|
30
|
+
declare const Hono_base: new <E_1 extends Partial<Environment> = Environment, T extends string = string, U = Hono<Environment, "/">>() => {
|
|
26
31
|
all: HandlerInterface<T, E_1, U>;
|
|
27
32
|
get: HandlerInterface<T, E_1, U>;
|
|
28
33
|
post: HandlerInterface<T, E_1, U>;
|
|
@@ -32,7 +37,10 @@ declare const Hono_base: new <E_1 extends Env, T extends string, U>() => {
|
|
|
32
37
|
options: HandlerInterface<T, E_1, U>;
|
|
33
38
|
patch: HandlerInterface<T, E_1, U>;
|
|
34
39
|
};
|
|
35
|
-
export declare class Hono<E extends
|
|
40
|
+
export declare class Hono<E extends {
|
|
41
|
+
Bindings?: Bindings;
|
|
42
|
+
Variables?: Variables;
|
|
43
|
+
} = Environment, P extends string = '/'> extends Hono_base<E, P, Hono<E, P>> {
|
|
36
44
|
readonly router: Router<Handler<string, E>>;
|
|
37
45
|
readonly strict: boolean;
|
|
38
46
|
private _tempPath;
|
|
@@ -44,13 +52,13 @@ export declare class Hono<E extends Env = Env, P extends string = '/'> extends H
|
|
|
44
52
|
route(path: string, app?: Hono<any>): Hono<E, P>;
|
|
45
53
|
use(path: string, ...middleware: Handler<string, E>[]): Hono<E, P>;
|
|
46
54
|
use(...middleware: Handler<string, E>[]): Hono<E, P>;
|
|
47
|
-
onError(handler: ErrorHandler
|
|
48
|
-
notFound(handler: NotFoundHandler
|
|
55
|
+
onError(handler: ErrorHandler): Hono<E, P>;
|
|
56
|
+
notFound(handler: NotFoundHandler): Hono<E, P>;
|
|
49
57
|
private addRoute;
|
|
50
58
|
private matchRoute;
|
|
51
59
|
private dispatch;
|
|
52
60
|
handleEvent(event: FetchEvent): Promise<Response>;
|
|
53
|
-
fetch: (request: Request,
|
|
61
|
+
fetch: (request: Request, Environment?: E["Bindings"] | undefined, executionCtx?: ExecutionContext | undefined) => Promise<Response>;
|
|
54
62
|
request(input: RequestInfo, requestInit?: RequestInit): Promise<Response>;
|
|
55
63
|
}
|
|
56
64
|
export {};
|
package/dist/hono.js
CHANGED
|
@@ -29,8 +29,8 @@ class Hono extends defineDynamicClass() {
|
|
|
29
29
|
const message = 'Internal Server Error';
|
|
30
30
|
return c.text(message, 500);
|
|
31
31
|
};
|
|
32
|
-
this.fetch = (request,
|
|
33
|
-
return this.dispatch(request, executionCtx,
|
|
32
|
+
this.fetch = (request, Environment, executionCtx) => {
|
|
33
|
+
return this.dispatch(request, executionCtx, Environment);
|
|
34
34
|
};
|
|
35
35
|
(0, request_1.extendRequestPrototype)();
|
|
36
36
|
const allMethods = [...methods, router_1.METHOD_NAME_ALL_LOWERCASE];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference path="request.d.ts" />
|
|
2
2
|
import { Hono } from './hono';
|
|
3
|
-
export type { Handler, Next } from './hono';
|
|
3
|
+
export type { Handler, Next, ContextVariableMap } from './hono';
|
|
4
4
|
export type { Context } from './context';
|
|
5
5
|
declare module './hono' {
|
|
6
6
|
interface Hono {
|
|
@@ -4,5 +4,5 @@ declare type EncodingType = 'gzip' | 'deflate';
|
|
|
4
4
|
interface CompressionOptions {
|
|
5
5
|
encoding?: EncodingType;
|
|
6
6
|
}
|
|
7
|
-
export declare const compress: (options?: CompressionOptions) => (ctx: Context, next: Next) => Promise<void>;
|
|
7
|
+
export declare const compress: (options?: CompressionOptions | undefined) => (ctx: Context, next: Next) => Promise<void>;
|
|
8
8
|
export {};
|
|
@@ -8,5 +8,5 @@ declare type CORSOptions = {
|
|
|
8
8
|
credentials?: boolean;
|
|
9
9
|
exposeHeaders?: string[];
|
|
10
10
|
};
|
|
11
|
-
export declare const cors: (options?: CORSOptions) => (c: Context, next: Next) => Promise<void>;
|
|
11
|
+
export declare const cors: (options?: CORSOptions | undefined) => (c: Context, next: Next) => Promise<void>;
|
|
12
12
|
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.etag = void 0;
|
|
4
|
-
const body_1 = require("../../utils/body");
|
|
5
4
|
const crypto_1 = require("../../utils/crypto");
|
|
6
5
|
const etag = (options = { weak: false }) => {
|
|
7
6
|
return async (c, next) => {
|
|
@@ -9,8 +8,7 @@ const etag = (options = { weak: false }) => {
|
|
|
9
8
|
await next();
|
|
10
9
|
const res = c.res;
|
|
11
10
|
const clone = res.clone();
|
|
12
|
-
const
|
|
13
|
-
const hash = await (0, crypto_1.sha1)(body);
|
|
11
|
+
const hash = await (0, crypto_1.sha1)(res.body || '');
|
|
14
12
|
const etag = options.weak ? `W/"${hash}"` : `"${hash}"`;
|
|
15
13
|
if (ifNoneMatch && ifNoneMatch === etag) {
|
|
16
14
|
await clone.blob(); // Force using body
|
|
@@ -1,5 +1,3 @@
|
|
|
1
1
|
import type { ServeStaticOptions } from './serve-static';
|
|
2
|
-
declare const module: (options?: ServeStaticOptions) => import("../../hono").Handler<string,
|
|
3
|
-
[x: string]: any;
|
|
4
|
-
}>;
|
|
2
|
+
declare const module: (options?: ServeStaticOptions) => import("../../hono").Handler<string, import("../../hono").Environment>;
|
|
5
3
|
export { module as serveStatic };
|
package/dist/request.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import type { Body } from './utils/body';
|
|
2
1
|
import type { Cookie } from './utils/cookie';
|
|
3
2
|
declare global {
|
|
4
3
|
interface Request<ParamKeyType extends string = string> {
|
|
@@ -23,9 +22,9 @@ declare global {
|
|
|
23
22
|
(name: string): string;
|
|
24
23
|
(): Cookie;
|
|
25
24
|
};
|
|
26
|
-
parsedBody?: Promise<
|
|
25
|
+
parsedBody?: Promise<Record<string, string | File>>;
|
|
27
26
|
parseBody: {
|
|
28
|
-
(): Promise<
|
|
27
|
+
(): Promise<Record<string, string | File>>;
|
|
29
28
|
};
|
|
30
29
|
}
|
|
31
30
|
}
|
package/dist/request.js
CHANGED
|
@@ -69,10 +69,15 @@ function extendRequestPrototype() {
|
|
|
69
69
|
}
|
|
70
70
|
};
|
|
71
71
|
Request.prototype.parseBody = function () {
|
|
72
|
+
let body;
|
|
72
73
|
if (!this.parsedBody) {
|
|
73
|
-
|
|
74
|
+
body = (0, body_1.parseBody)(this);
|
|
75
|
+
this.parsedBody = body;
|
|
74
76
|
}
|
|
75
|
-
|
|
77
|
+
else {
|
|
78
|
+
body = this.parsedBody;
|
|
79
|
+
}
|
|
80
|
+
return body;
|
|
76
81
|
};
|
|
77
82
|
}
|
|
78
83
|
exports.extendRequestPrototype = extendRequestPrototype;
|
|
@@ -80,14 +80,13 @@ class Node {
|
|
|
80
80
|
var _a, _b;
|
|
81
81
|
return ((_a = node.handlerSetCache)[_b = `${method}:${wildcard ? '1' : '0'}`] || (_a[_b] = (() => {
|
|
82
82
|
const handlerSets = [];
|
|
83
|
-
node.methods.
|
|
83
|
+
for (let i = 0, len = node.methods.length; i < len; i++) {
|
|
84
|
+
const m = node.methods[i];
|
|
84
85
|
const handlerSet = m[method] || m[router_1.METHOD_NAME_ALL];
|
|
85
86
|
if (handlerSet !== undefined) {
|
|
86
|
-
|
|
87
|
-
handlerSets.push(hs);
|
|
88
|
-
return;
|
|
87
|
+
handlerSets.push(handlerSet);
|
|
89
88
|
}
|
|
90
|
-
}
|
|
89
|
+
}
|
|
91
90
|
return handlerSets;
|
|
92
91
|
})()));
|
|
93
92
|
}
|
|
@@ -115,7 +114,9 @@ class Node {
|
|
|
115
114
|
handlerSets.push(...this.getHandlerSets(nextNode, method));
|
|
116
115
|
matched = true;
|
|
117
116
|
}
|
|
118
|
-
|
|
117
|
+
else {
|
|
118
|
+
tempNodes.push(nextNode);
|
|
119
|
+
}
|
|
119
120
|
}
|
|
120
121
|
for (let k = 0, len3 = node.patterns.length; k < len3; k++) {
|
|
121
122
|
const pattern = node.patterns[k];
|
|
@@ -139,7 +140,9 @@ class Node {
|
|
|
139
140
|
if (isLast === true) {
|
|
140
141
|
handlerSets.push(...this.getHandlerSets(node.children[key], method));
|
|
141
142
|
}
|
|
142
|
-
|
|
143
|
+
else {
|
|
144
|
+
tempNodes.push(node.children[key]);
|
|
145
|
+
}
|
|
143
146
|
}
|
|
144
147
|
// '/book/a' => not-slug
|
|
145
148
|
// '/book/:slug' => slug
|
|
@@ -148,13 +151,17 @@ class Node {
|
|
|
148
151
|
if (typeof name === 'string' && !matched) {
|
|
149
152
|
params[name] = part;
|
|
150
153
|
}
|
|
154
|
+
break;
|
|
151
155
|
}
|
|
152
156
|
}
|
|
153
157
|
}
|
|
154
158
|
curNodes = tempNodes;
|
|
155
159
|
}
|
|
156
|
-
|
|
160
|
+
const len = handlerSets.length;
|
|
161
|
+
if (len === 0)
|
|
157
162
|
return null;
|
|
163
|
+
if (len === 1)
|
|
164
|
+
return { handlers: [handlerSets[0].handler], params };
|
|
158
165
|
const handlers = handlerSets
|
|
159
166
|
.sort((a, b) => {
|
|
160
167
|
return a.score - b.score;
|
package/dist/utils/body.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export declare
|
|
2
|
-
export declare const parseBody: (r: Request | Response) => Promise<Body>;
|
|
1
|
+
export declare function parseBody(r: Request | Response): Promise<Record<string, string | File>>;
|
package/dist/utils/body.js
CHANGED
|
@@ -1,31 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.parseBody = void 0;
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
catch { } // Do nothing
|
|
12
|
-
return body;
|
|
13
|
-
}
|
|
14
|
-
else if (contentType.includes('application/text')) {
|
|
15
|
-
return await r.text();
|
|
16
|
-
}
|
|
17
|
-
else if (contentType.startsWith('text')) {
|
|
18
|
-
return await r.text();
|
|
19
|
-
}
|
|
20
|
-
else if (contentType.includes('form')) {
|
|
4
|
+
async function parseBody(r) {
|
|
5
|
+
let body = {};
|
|
6
|
+
const contentType = r.headers.get('Content-Type');
|
|
7
|
+
if (contentType &&
|
|
8
|
+
(contentType.startsWith('multipart/form-data') ||
|
|
9
|
+
contentType === 'application/x-www-form-urlencoded')) {
|
|
21
10
|
const form = {};
|
|
22
|
-
|
|
11
|
+
body = [...(await r.formData())].reduce((acc, cur) => {
|
|
23
12
|
acc[cur[0]] = cur[1];
|
|
24
13
|
return acc;
|
|
25
14
|
}, form);
|
|
26
|
-
return data;
|
|
27
15
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
};
|
|
16
|
+
return body;
|
|
17
|
+
}
|
|
31
18
|
exports.parseBody = parseBody;
|
package/dist/utils/buffer.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export declare const equal: (a: ArrayBuffer, b: ArrayBuffer) => boolean;
|
|
2
|
-
export declare const timingSafeEqual: (a: string | object | boolean, b: string | object | boolean, hashFunction?: Function) => Promise<boolean>;
|
|
2
|
+
export declare const timingSafeEqual: (a: string | object | boolean, b: string | object | boolean, hashFunction?: Function | undefined) => Promise<boolean>;
|
|
3
3
|
export declare const bufferToString: (buffer: ArrayBuffer) => string;
|
|
@@ -3,4 +3,4 @@ export declare type KVAssetOptions = {
|
|
|
3
3
|
manifest?: object | string;
|
|
4
4
|
namespace?: KVNamespace;
|
|
5
5
|
};
|
|
6
|
-
export declare const getContentFromKVAsset: (path: string, options?: KVAssetOptions) => Promise<ArrayBuffer | null>;
|
|
6
|
+
export declare const getContentFromKVAsset: (path: string, options?: KVAssetOptions | undefined) => Promise<ArrayBuffer | null>;
|
package/dist/utils/crypto.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ declare type Algorithm = {
|
|
|
2
2
|
name: string;
|
|
3
3
|
alias: string;
|
|
4
4
|
};
|
|
5
|
-
declare type Data = string | boolean | number | object | ArrayBufferView | ArrayBuffer;
|
|
5
|
+
declare type Data = string | boolean | number | object | ArrayBufferView | ArrayBuffer | ReadableStream;
|
|
6
6
|
export declare const sha256: (data: Data) => Promise<string | null>;
|
|
7
7
|
export declare const sha1: (data: Data) => Promise<string | null>;
|
|
8
8
|
export declare const md5: (data: Data) => Promise<string | null>;
|
package/dist/utils/crypto.js
CHANGED
|
@@ -21,6 +21,15 @@ const md5 = async (data) => {
|
|
|
21
21
|
exports.md5 = md5;
|
|
22
22
|
const createHash = async (data, algorithm) => {
|
|
23
23
|
let sourceBuffer;
|
|
24
|
+
if (data instanceof ReadableStream) {
|
|
25
|
+
let body = '';
|
|
26
|
+
const reader = data.getReader();
|
|
27
|
+
await reader?.read().then(async (chuck) => {
|
|
28
|
+
const value = await (0, exports.createHash)(chuck.value || '', algorithm);
|
|
29
|
+
body += value;
|
|
30
|
+
});
|
|
31
|
+
return body;
|
|
32
|
+
}
|
|
24
33
|
if (ArrayBuffer.isView(data) || data instanceof ArrayBuffer) {
|
|
25
34
|
sourceBuffer = data;
|
|
26
35
|
}
|
package/dist/utils/mime.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Ultrafast web framework for Cloudflare Workers.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"eslint-plugin-node": "^11.1.0",
|
|
156
156
|
"form-data": "^4.0.0",
|
|
157
157
|
"jest": "27.5.1",
|
|
158
|
-
"jest-environment-miniflare": "^2.
|
|
158
|
+
"jest-environment-miniflare": "^2.7.0",
|
|
159
159
|
"np": "^7.6.2",
|
|
160
160
|
"prettier": "^2.6.2",
|
|
161
161
|
"rimraf": "^3.0.2",
|