hono 1.4.2 → 1.4.5
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 +8 -8
- package/dist/compose.js +2 -5
- package/dist/context.d.ts +9 -10
- package/dist/context.js +38 -82
- package/dist/hono.d.ts +2 -25
- package/dist/hono.js +10 -21
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/middleware/basic-auth/index.js +1 -2
- package/dist/middleware/bearer-auth/index.d.ts +8 -0
- package/dist/middleware/bearer-auth/index.js +61 -0
- package/dist/middleware/cors/index.js +8 -6
- package/dist/middleware/graphql-server/index.js +6 -8
- package/dist/middleware/jwt/index.js +3 -3
- package/dist/middleware/serve-static/serve-static.js +1 -1
- package/dist/request.d.ts +22 -0
- package/dist/request.js +59 -0
- package/dist/router/trie-router/node.d.ts +1 -1
- package/dist/router/trie-router/node.js +57 -69
- package/dist/utils/encode.js +2 -2
- package/dist/utils/url.d.ts +1 -5
- package/dist/utils/url.js +6 -8
- package/package.json +6 -2
- package/dist/response.d.ts +0 -25
- package/dist/response.js +0 -35
package/README.md
CHANGED
|
@@ -38,13 +38,13 @@ app.fire()
|
|
|
38
38
|
**Hono is fastest**, compared to other routers for Cloudflare Workers.
|
|
39
39
|
|
|
40
40
|
```plain
|
|
41
|
-
hono - trie-router(default) x
|
|
42
|
-
hono - regexp-router x
|
|
43
|
-
itty-router x
|
|
44
|
-
sunder x
|
|
45
|
-
worktop x
|
|
41
|
+
hono - trie-router(default) x 389,510 ops/sec ±3.16% (85 runs sampled)
|
|
42
|
+
hono - regexp-router x 452,290 ops/sec ±2.64% (84 runs sampled)
|
|
43
|
+
itty-router x 206,013 ops/sec ±3.39% (90 runs sampled)
|
|
44
|
+
sunder x 323,131 ops/sec ±0.75% (97 runs sampled)
|
|
45
|
+
worktop x 191,218 ops/sec ±2.70% (91 runs sampled)
|
|
46
46
|
Fastest is hono - regexp-router
|
|
47
|
-
✨ Done in
|
|
47
|
+
✨ Done in 43.56s.
|
|
48
48
|
```
|
|
49
49
|
|
|
50
50
|
## Why so fast?
|
|
@@ -98,7 +98,7 @@ import { basicAuth } from 'hono/basic-auth'
|
|
|
98
98
|
|
|
99
99
|
const v1 = new Hono()
|
|
100
100
|
v1.get('/posts', (c) => {
|
|
101
|
-
return c.text('list
|
|
101
|
+
return c.text('list posts')
|
|
102
102
|
})
|
|
103
103
|
.post(basicAuth({ username, password }), (c) => {
|
|
104
104
|
return c.text('created!', 201)
|
|
@@ -644,7 +644,7 @@ npx wrangler publish ./src/index.ts
|
|
|
644
644
|
|
|
645
645
|
You can start making your Cloudflare Workers application with [the starter template](https://github.com/honojs/hono-minimal). It is really minimal using TypeScript, esbuild, Miniflare, and Jest.
|
|
646
646
|
|
|
647
|
-
To generate a project
|
|
647
|
+
To generate a project skeleton, run this command.
|
|
648
648
|
|
|
649
649
|
```
|
|
650
650
|
npx create-cloudflare my-app https://github.com/honojs/hono-minimal
|
package/dist/compose.js
CHANGED
|
@@ -16,18 +16,16 @@ const compose = (middleware, onError, onNotFound) => {
|
|
|
16
16
|
if (i === middleware.length && next)
|
|
17
17
|
handler = next;
|
|
18
18
|
if (!handler) {
|
|
19
|
-
if (context instanceof context_1.Context && context.
|
|
19
|
+
if (context instanceof context_1.Context && context.finalized === false && onNotFound) {
|
|
20
20
|
context.res = onNotFound(context);
|
|
21
|
-
context.res._finalized = true;
|
|
22
21
|
}
|
|
23
22
|
return Promise.resolve(context);
|
|
24
23
|
}
|
|
25
|
-
return Promise.resolve(handler(context, dispatch
|
|
24
|
+
return Promise.resolve(handler(context, () => dispatch(i + 1)))
|
|
26
25
|
.then(async (res) => {
|
|
27
26
|
// If handler return Response like `return c.text('foo')`
|
|
28
27
|
if (res && context instanceof context_1.Context) {
|
|
29
28
|
context.res = res;
|
|
30
|
-
context.res._finalized = true;
|
|
31
29
|
}
|
|
32
30
|
return context;
|
|
33
31
|
})
|
|
@@ -35,7 +33,6 @@ const compose = (middleware, onError, onNotFound) => {
|
|
|
35
33
|
if (context instanceof context_1.Context && onError) {
|
|
36
34
|
if (err instanceof Error) {
|
|
37
35
|
context.res = onError(err, context);
|
|
38
|
-
context.res._finalized = true;
|
|
39
36
|
}
|
|
40
37
|
return context;
|
|
41
38
|
}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,36 +1,35 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import { HonoResponse } from './response';
|
|
3
2
|
import type { StatusCode } from './utils/http-status';
|
|
4
3
|
declare type Headers = Record<string, string>;
|
|
5
4
|
export declare type Data = string | ArrayBuffer | ReadableStream;
|
|
6
5
|
export declare type Env = Record<string, any>;
|
|
7
6
|
export declare class Context<RequestParamKeyType extends string = string, E = Env> {
|
|
8
7
|
req: Request<RequestParamKeyType>;
|
|
9
|
-
res: Response;
|
|
10
8
|
env: E;
|
|
11
9
|
event: FetchEvent | undefined;
|
|
10
|
+
finalized: boolean;
|
|
12
11
|
private _status;
|
|
13
12
|
private _pretty;
|
|
14
13
|
private _prettySpace;
|
|
15
14
|
private _map;
|
|
15
|
+
private _headers;
|
|
16
|
+
private _res;
|
|
17
|
+
private notFoundHandler;
|
|
16
18
|
render: (template: string, params?: object, options?: object) => Promise<Response>;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
event?: FetchEvent;
|
|
21
|
-
res?: Response | HonoResponse;
|
|
22
|
-
});
|
|
23
|
-
private initRequest;
|
|
19
|
+
constructor(req: Request<RequestParamKeyType>, env?: E | undefined, event?: FetchEvent | undefined, notFoundHandler?: (c: Context<string, E>) => Response);
|
|
20
|
+
get res(): Response;
|
|
21
|
+
set res(_res: Response);
|
|
24
22
|
header(name: string, value: string): void;
|
|
25
23
|
status(status: StatusCode): void;
|
|
26
24
|
set(key: string, value: any): void;
|
|
27
25
|
get(key: string): any;
|
|
28
26
|
pretty(prettyJSON: boolean, space?: number): void;
|
|
29
|
-
newResponse(data: Data | null,
|
|
27
|
+
newResponse(data: Data | null, status: StatusCode, headers?: Headers): Response;
|
|
30
28
|
body(data: Data | null, status?: StatusCode, headers?: Headers): Response;
|
|
31
29
|
text(text: string, status?: StatusCode, headers?: Headers): Response;
|
|
32
30
|
json(object: object, status?: StatusCode, headers?: Headers): Response;
|
|
33
31
|
html(html: string, status?: StatusCode, headers?: Headers): Response;
|
|
34
32
|
redirect(location: string, status?: StatusCode): Response;
|
|
33
|
+
notFound(): Response | Promise<Response>;
|
|
35
34
|
}
|
|
36
35
|
export {};
|
package/dist/context.js
CHANGED
|
@@ -1,109 +1,71 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Context = void 0;
|
|
4
|
-
const response_1 = require("./response");
|
|
5
4
|
const url_1 = require("./utils/url");
|
|
6
5
|
class Context {
|
|
7
|
-
constructor(req,
|
|
8
|
-
env: {},
|
|
9
|
-
event: undefined,
|
|
10
|
-
res: undefined,
|
|
11
|
-
}) {
|
|
6
|
+
constructor(req, env = undefined, event = undefined, notFoundHandler = () => new Response()) {
|
|
12
7
|
this._status = 200;
|
|
13
8
|
this._pretty = false;
|
|
14
9
|
this._prettySpace = 2;
|
|
15
|
-
this.req =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (!this.res) {
|
|
19
|
-
const res = new response_1.HonoResponse(null, { status: 404 });
|
|
20
|
-
res._finalized = false;
|
|
21
|
-
this.res = res;
|
|
10
|
+
this.req = req;
|
|
11
|
+
if (env) {
|
|
12
|
+
this.env = env;
|
|
22
13
|
}
|
|
14
|
+
this.event = event;
|
|
15
|
+
this.notFoundHandler = notFoundHandler;
|
|
16
|
+
this.finalized = false;
|
|
23
17
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const result = {};
|
|
31
|
-
for (const [key, value] of req.headers) {
|
|
32
|
-
result[key] = value;
|
|
33
|
-
}
|
|
34
|
-
return result;
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
req.query = ((key) => {
|
|
38
|
-
const url = new URL(req.url);
|
|
39
|
-
if (key) {
|
|
40
|
-
return url.searchParams.get(key);
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
const result = {};
|
|
44
|
-
for (const key of url.searchParams.keys()) {
|
|
45
|
-
result[key] = url.searchParams.get(key) || '';
|
|
46
|
-
}
|
|
47
|
-
return result;
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
req.queries = ((key) => {
|
|
51
|
-
const url = new URL(req.url);
|
|
52
|
-
if (key) {
|
|
53
|
-
return url.searchParams.getAll(key);
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
const result = {};
|
|
57
|
-
for (const key of url.searchParams.keys()) {
|
|
58
|
-
result[key] = url.searchParams.getAll(key);
|
|
59
|
-
}
|
|
60
|
-
return result;
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
return req;
|
|
18
|
+
get res() {
|
|
19
|
+
return (this._res || (this._res = new Response()));
|
|
20
|
+
}
|
|
21
|
+
set res(_res) {
|
|
22
|
+
this._res = _res;
|
|
23
|
+
this.finalized = true;
|
|
64
24
|
}
|
|
65
25
|
header(name, value) {
|
|
66
|
-
this.
|
|
26
|
+
this._headers || (this._headers = {});
|
|
27
|
+
this._headers[name] = value;
|
|
28
|
+
if (this.finalized) {
|
|
29
|
+
this.res.headers.set(name, value);
|
|
30
|
+
}
|
|
67
31
|
}
|
|
68
32
|
status(status) {
|
|
69
33
|
this._status = status;
|
|
70
34
|
}
|
|
71
35
|
set(key, value) {
|
|
36
|
+
this._map || (this._map = {});
|
|
72
37
|
this._map[key] = value;
|
|
73
38
|
}
|
|
74
39
|
get(key) {
|
|
40
|
+
if (!this._map) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
75
43
|
return this._map[key];
|
|
76
44
|
}
|
|
77
45
|
pretty(prettyJSON, space = 2) {
|
|
78
46
|
this._pretty = prettyJSON;
|
|
79
47
|
this._prettySpace = space;
|
|
80
48
|
}
|
|
81
|
-
newResponse(data,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
49
|
+
newResponse(data, status, headers = {}) {
|
|
50
|
+
const _headers = { ...this._headers, ...headers };
|
|
51
|
+
if (this._res) {
|
|
52
|
+
this._res.headers.forEach((v, k) => {
|
|
53
|
+
_headers[k] = v;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return new Response(data, {
|
|
57
|
+
status: status || this._status || 200,
|
|
58
|
+
headers: _headers,
|
|
86
59
|
});
|
|
87
|
-
init.headers = Object.assign(headers, init.headers);
|
|
88
|
-
return new Response(data, init);
|
|
89
60
|
}
|
|
90
61
|
body(data, status = this._status, headers = {}) {
|
|
91
|
-
return this.newResponse(data,
|
|
92
|
-
status: status,
|
|
93
|
-
headers: headers,
|
|
94
|
-
});
|
|
62
|
+
return this.newResponse(data, status, headers);
|
|
95
63
|
}
|
|
96
64
|
text(text, status = this._status, headers = {}) {
|
|
97
|
-
if (typeof text !== 'string') {
|
|
98
|
-
throw new TypeError('text method arg must be a string!');
|
|
99
|
-
}
|
|
100
65
|
headers['Content-Type'] || (headers['Content-Type'] = 'text/plain; charset=UTF-8');
|
|
101
66
|
return this.body(text, status, headers);
|
|
102
67
|
}
|
|
103
68
|
json(object, status = this._status, headers = {}) {
|
|
104
|
-
if (typeof object !== 'object') {
|
|
105
|
-
throw new TypeError('json method arg must be an object!');
|
|
106
|
-
}
|
|
107
69
|
const body = this._pretty
|
|
108
70
|
? JSON.stringify(object, null, this._prettySpace)
|
|
109
71
|
: JSON.stringify(object);
|
|
@@ -111,27 +73,21 @@ class Context {
|
|
|
111
73
|
return this.body(body, status, headers);
|
|
112
74
|
}
|
|
113
75
|
html(html, status = this._status, headers = {}) {
|
|
114
|
-
if (typeof html !== 'string') {
|
|
115
|
-
throw new TypeError('html method arg must be a string!');
|
|
116
|
-
}
|
|
117
76
|
headers['Content-Type'] || (headers['Content-Type'] = 'text/html; charset=UTF-8');
|
|
118
77
|
return this.body(html, status, headers);
|
|
119
78
|
}
|
|
120
79
|
redirect(location, status = 302) {
|
|
121
|
-
if (typeof location !== 'string') {
|
|
122
|
-
throw new TypeError('location must be a string!');
|
|
123
|
-
}
|
|
124
80
|
if (!(0, url_1.isAbsoluteURL)(location)) {
|
|
125
81
|
const url = new URL(this.req.url);
|
|
126
82
|
url.pathname = location;
|
|
127
83
|
location = url.toString();
|
|
128
84
|
}
|
|
129
|
-
return this.newResponse(null, {
|
|
130
|
-
|
|
131
|
-
headers: {
|
|
132
|
-
Location: location,
|
|
133
|
-
},
|
|
85
|
+
return this.newResponse(null, status, {
|
|
86
|
+
Location: location,
|
|
134
87
|
});
|
|
135
88
|
}
|
|
89
|
+
notFound() {
|
|
90
|
+
return this.notFoundHandler(this);
|
|
91
|
+
}
|
|
136
92
|
}
|
|
137
93
|
exports.Context = Context;
|
package/dist/hono.d.ts
CHANGED
|
@@ -2,29 +2,6 @@
|
|
|
2
2
|
import { Context } from './context';
|
|
3
3
|
import type { Env } from './context';
|
|
4
4
|
import type { Router } from './router';
|
|
5
|
-
declare global {
|
|
6
|
-
interface Request<ParamKeyType extends string = string> {
|
|
7
|
-
param: {
|
|
8
|
-
(key: ParamKeyType): string;
|
|
9
|
-
(): Record<ParamKeyType, string>;
|
|
10
|
-
};
|
|
11
|
-
query: {
|
|
12
|
-
(key: string): string;
|
|
13
|
-
(): Record<string, string>;
|
|
14
|
-
};
|
|
15
|
-
queries: {
|
|
16
|
-
(key: string): string[];
|
|
17
|
-
(): Record<string, string[]>;
|
|
18
|
-
};
|
|
19
|
-
header: {
|
|
20
|
-
(name: string): string;
|
|
21
|
-
(): Record<string, string>;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
interface Response {
|
|
25
|
-
_finalized: boolean;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
5
|
export declare type Handler<RequestParamKeyType extends string = string, E = Env> = (c: Context<RequestParamKeyType, E>, next: Next) => Response | Promise<Response> | Promise<void> | Promise<Response | undefined>;
|
|
29
6
|
export declare type NotFoundHandler<E = Env> = (c: Context<string, E>) => Response;
|
|
30
7
|
export declare type ErrorHandler<E = Env> = (err: Error, c: Context<string, E>) => Response;
|
|
@@ -32,7 +9,7 @@ export declare type Next = () => Promise<void>;
|
|
|
32
9
|
declare type ParamKeyName<NameWithPattern> = NameWithPattern extends `${infer Name}{${infer _Pattern}` ? Name : NameWithPattern;
|
|
33
10
|
declare type ParamKey<Component> = Component extends `:${infer NameWithPattern}` ? ParamKeyName<NameWithPattern> : never;
|
|
34
11
|
declare type ParamKeys<Path> = Path extends `${infer Component}/${infer Rest}` ? ParamKey<Component> | ParamKeys<Rest> : ParamKey<Path>;
|
|
35
|
-
interface HandlerInterface<T extends string, E = Env, U = Hono<E, T>> {
|
|
12
|
+
interface HandlerInterface<T extends string, E extends Env = Env, U = Hono<E, T>> {
|
|
36
13
|
<Path extends string>(path: Path, ...handlers: Handler<ParamKeys<Path> extends never ? string : ParamKeys<Path>, E>[]): U;
|
|
37
14
|
(path: string, ...handlers: Handler<string, E>[]): U;
|
|
38
15
|
<Path extends string>(...handlers: Handler<ParamKeys<Path> extends never ? string : ParamKeys<Path>, E>[]): U;
|
|
@@ -53,7 +30,7 @@ declare const Hono_base: new <E_1 extends Env, T extends string, U>() => {
|
|
|
53
30
|
options: HandlerInterface<T, E_1, U>;
|
|
54
31
|
patch: HandlerInterface<T, E_1, U>;
|
|
55
32
|
};
|
|
56
|
-
export declare class Hono<E = Env, P extends string = '/'> extends Hono_base<E, P, Hono<E, P>> {
|
|
33
|
+
export declare class Hono<E extends Env = Env, P extends string = '/'> extends Hono_base<E, P, Hono<E, P>> {
|
|
57
34
|
readonly router: Router<Handler<string, E>>;
|
|
58
35
|
readonly strict: boolean;
|
|
59
36
|
private _tempPath;
|
package/dist/hono.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Hono = void 0;
|
|
4
4
|
const compose_1 = require("./compose");
|
|
5
5
|
const context_1 = require("./context");
|
|
6
|
+
const request_1 = require("./request");
|
|
6
7
|
const router_1 = require("./router");
|
|
7
8
|
const trie_router_1 = require("./router/trie-router"); // Default Router
|
|
8
9
|
const url_1 = require("./utils/url");
|
|
@@ -28,6 +29,7 @@ class Hono extends defineDynamicClass() {
|
|
|
28
29
|
const message = 'Internal Server Error';
|
|
29
30
|
return c.text(message, 500);
|
|
30
31
|
};
|
|
32
|
+
(0, request_1.extendRequestPrototype)(); // FIXME: should be executed at a better timing
|
|
31
33
|
const allMethods = [...methods, router_1.METHOD_NAME_ALL_LOWERCASE];
|
|
32
34
|
allMethods.map((method) => {
|
|
33
35
|
this[method] = (args1, ...args) => {
|
|
@@ -86,34 +88,23 @@ class Hono extends defineDynamicClass() {
|
|
|
86
88
|
const r = { path: path, method: method, handler: handler };
|
|
87
89
|
this.routes.push(r);
|
|
88
90
|
}
|
|
89
|
-
|
|
91
|
+
matchRoute(method, path) {
|
|
90
92
|
return this.router.match(method, path);
|
|
91
93
|
}
|
|
92
94
|
async dispatch(request, event, env) {
|
|
93
|
-
const path = (0, url_1.getPathFromURL)(request.url,
|
|
95
|
+
const path = (0, url_1.getPathFromURL)(request.url, this.strict);
|
|
94
96
|
const method = request.method;
|
|
95
|
-
const result =
|
|
96
|
-
request.
|
|
97
|
-
if (result) {
|
|
98
|
-
if (key) {
|
|
99
|
-
return result.params[key];
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
return result.params;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return null;
|
|
106
|
-
});
|
|
97
|
+
const result = this.matchRoute(method, path);
|
|
98
|
+
request.paramData = result?.params;
|
|
107
99
|
const handlers = result ? result.handlers : [this.notFoundHandler];
|
|
108
|
-
const c = new context_1.Context(request,
|
|
109
|
-
env: env,
|
|
110
|
-
event: event,
|
|
111
|
-
});
|
|
112
|
-
c.notFound = () => this.notFoundHandler(c);
|
|
100
|
+
const c = new context_1.Context(request, env, event, this.notFoundHandler);
|
|
113
101
|
const composed = (0, compose_1.compose)(handlers, this.errorHandler, this.notFoundHandler);
|
|
114
102
|
let context;
|
|
115
103
|
try {
|
|
116
104
|
context = await composed(c);
|
|
105
|
+
if (!context.finalized) {
|
|
106
|
+
throw new Error('Context is not finalized. You may forget returning Response object or `await next()`');
|
|
107
|
+
}
|
|
117
108
|
}
|
|
118
109
|
catch (err) {
|
|
119
110
|
if (err instanceof Error) {
|
|
@@ -121,8 +112,6 @@ class Hono extends defineDynamicClass() {
|
|
|
121
112
|
}
|
|
122
113
|
throw err;
|
|
123
114
|
}
|
|
124
|
-
if (!context.res)
|
|
125
|
-
return context.notFound();
|
|
126
115
|
return context.res;
|
|
127
116
|
}
|
|
128
117
|
async handleEvent(event) {
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
|
|
3
|
+
/// <reference path="./request.ts" /> Import "declare global" for the Request interface.
|
|
2
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
5
|
exports.Context = exports.Hono = void 0;
|
|
4
6
|
var hono_1 = require("./hono");
|
|
@@ -34,7 +34,6 @@ const basicAuth = (options, ...users) => {
|
|
|
34
34
|
}
|
|
35
35
|
users.unshift({ username: options.username, password: options.password });
|
|
36
36
|
return async (ctx, next) => {
|
|
37
|
-
var _a;
|
|
38
37
|
const requestUser = auth(ctx.req);
|
|
39
38
|
if (requestUser) {
|
|
40
39
|
for (const user of users) {
|
|
@@ -50,7 +49,7 @@ const basicAuth = (options, ...users) => {
|
|
|
50
49
|
ctx.res = new Response('Unauthorized', {
|
|
51
50
|
status: 401,
|
|
52
51
|
headers: {
|
|
53
|
-
'WWW-Authenticate': 'Basic realm="' +
|
|
52
|
+
'WWW-Authenticate': 'Basic realm="' + options.realm?.replace(/"/g, '\\"') + '"',
|
|
54
53
|
},
|
|
55
54
|
});
|
|
56
55
|
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Context } from '../../context';
|
|
2
|
+
import type { Next } from '../../hono';
|
|
3
|
+
export declare const bearerAuth: (options: {
|
|
4
|
+
token: string;
|
|
5
|
+
realm?: string;
|
|
6
|
+
prefix?: string;
|
|
7
|
+
hashFunction?: Function;
|
|
8
|
+
}) => (c: Context, next: Next) => Promise<void>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bearerAuth = void 0;
|
|
4
|
+
const buffer_1 = require("../../utils/buffer");
|
|
5
|
+
const TOKEN_STRINGS = '[A-Za-z0-9._~+/-]+=*';
|
|
6
|
+
const PREFIX = 'Bearer';
|
|
7
|
+
const bearerAuth = (options) => {
|
|
8
|
+
if (!options.token) {
|
|
9
|
+
throw new Error('bearer auth middleware requires options for "token"');
|
|
10
|
+
}
|
|
11
|
+
if (!options.realm) {
|
|
12
|
+
options.realm = '';
|
|
13
|
+
}
|
|
14
|
+
if (!options.prefix) {
|
|
15
|
+
options.prefix = PREFIX;
|
|
16
|
+
}
|
|
17
|
+
const realm = options.realm?.replace(/"/g, '\\"');
|
|
18
|
+
return async (c, next) => {
|
|
19
|
+
const headerToken = c.req.headers.get('Authorization');
|
|
20
|
+
if (!headerToken) {
|
|
21
|
+
// No Authorization header
|
|
22
|
+
c.res = new Response('Unauthorized', {
|
|
23
|
+
status: 401,
|
|
24
|
+
headers: {
|
|
25
|
+
'WWW-Authenticate': `${options.prefix} realm="` + realm + '"',
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
const regexp = new RegExp('^' + options.prefix + ' +(' + TOKEN_STRINGS + ') *$');
|
|
31
|
+
const match = regexp.exec(headerToken);
|
|
32
|
+
if (!match) {
|
|
33
|
+
// Invalid Request
|
|
34
|
+
c.res = new Response('Bad Request', {
|
|
35
|
+
status: 400,
|
|
36
|
+
headers: {
|
|
37
|
+
'WWW-Authenticate': `${options.prefix} error="invalid_request"`,
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const equal = await (0, buffer_1.timingSafeEqual)(options.token, match[1], options.hashFunction);
|
|
43
|
+
if (!equal) {
|
|
44
|
+
// Invalid Token
|
|
45
|
+
c.res = new Response('Unauthorized', {
|
|
46
|
+
status: 401,
|
|
47
|
+
headers: {
|
|
48
|
+
'WWW-Authenticate': `${options.prefix} error="invalid_token"`,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
// Authorize OK
|
|
54
|
+
await next();
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
exports.bearerAuth = bearerAuth;
|
|
@@ -8,9 +8,11 @@ const cors = (options) => {
|
|
|
8
8
|
allowHeaders: [],
|
|
9
9
|
exposeHeaders: [],
|
|
10
10
|
};
|
|
11
|
-
const opts =
|
|
11
|
+
const opts = {
|
|
12
|
+
...defaults,
|
|
13
|
+
...options,
|
|
14
|
+
};
|
|
12
15
|
return async (c, next) => {
|
|
13
|
-
var _a, _b;
|
|
14
16
|
await next();
|
|
15
17
|
function set(key, value) {
|
|
16
18
|
c.res.headers.append(key, value);
|
|
@@ -24,7 +26,7 @@ const cors = (options) => {
|
|
|
24
26
|
if (opts.credentials) {
|
|
25
27
|
set('Access-Control-Allow-Credentials', 'true');
|
|
26
28
|
}
|
|
27
|
-
if (
|
|
29
|
+
if (opts.exposeHeaders?.length) {
|
|
28
30
|
set('Access-Control-Expose-Headers', opts.exposeHeaders.join(','));
|
|
29
31
|
}
|
|
30
32
|
if (c.req.method === 'OPTIONS') {
|
|
@@ -32,17 +34,17 @@ const cors = (options) => {
|
|
|
32
34
|
if (opts.maxAge != null) {
|
|
33
35
|
set('Access-Control-Max-Age', opts.maxAge.toString());
|
|
34
36
|
}
|
|
35
|
-
if (
|
|
37
|
+
if (opts.allowMethods?.length) {
|
|
36
38
|
set('Access-Control-Allow-Methods', opts.allowMethods.join(','));
|
|
37
39
|
}
|
|
38
40
|
let headers = opts.allowHeaders;
|
|
39
|
-
if (!
|
|
41
|
+
if (!headers?.length) {
|
|
40
42
|
const requestHeaders = c.req.headers.get('Access-Control-Request-Headers');
|
|
41
43
|
if (requestHeaders) {
|
|
42
44
|
headers = requestHeaders.split(/\s*,\s*/);
|
|
43
45
|
}
|
|
44
46
|
}
|
|
45
|
-
if (headers
|
|
47
|
+
if (headers?.length) {
|
|
46
48
|
set('Access-Control-Allow-Headers', headers.join(','));
|
|
47
49
|
set('Vary', 'Access-Control-Request-Headers');
|
|
48
50
|
}
|
|
@@ -6,11 +6,10 @@ exports.errorMessages = exports.getGraphQLParams = exports.graphqlServer = void
|
|
|
6
6
|
const graphql_1 = require("graphql");
|
|
7
7
|
const parse_body_1 = require("./parse-body");
|
|
8
8
|
const graphqlServer = (options) => {
|
|
9
|
-
var _a, _b;
|
|
10
9
|
const schema = options.schema;
|
|
11
10
|
const rootValue = options.rootValue;
|
|
12
|
-
const pretty =
|
|
13
|
-
const validationRules =
|
|
11
|
+
const pretty = options.pretty ?? false;
|
|
12
|
+
const validationRules = options.validationRules ?? [];
|
|
14
13
|
// const showGraphiQL = options.graphiql ?? false
|
|
15
14
|
return async (c, next) => {
|
|
16
15
|
// GraphQL HTTP only supports GET and POST methods.
|
|
@@ -122,21 +121,20 @@ const graphqlServer = (options) => {
|
|
|
122
121
|
};
|
|
123
122
|
exports.graphqlServer = graphqlServer;
|
|
124
123
|
const getGraphQLParams = async (request) => {
|
|
125
|
-
var _a, _b, _c;
|
|
126
124
|
const urlData = new URLSearchParams(request.url.split('?')[1]);
|
|
127
125
|
const bodyData = await (0, parse_body_1.parseBody)(request);
|
|
128
126
|
// GraphQL Query string.
|
|
129
|
-
let query =
|
|
127
|
+
let query = urlData.get('query') ?? bodyData.query;
|
|
130
128
|
if (typeof query !== 'string') {
|
|
131
129
|
query = null;
|
|
132
130
|
}
|
|
133
131
|
// Parse the variables if needed.
|
|
134
|
-
let variables = (
|
|
132
|
+
let variables = (urlData.get('variables') ?? bodyData.variables);
|
|
135
133
|
if (typeof variables === 'string') {
|
|
136
134
|
try {
|
|
137
135
|
variables = JSON.parse(variables);
|
|
138
136
|
}
|
|
139
|
-
catch
|
|
137
|
+
catch {
|
|
140
138
|
throw Error('Variables are invalid JSON.');
|
|
141
139
|
}
|
|
142
140
|
}
|
|
@@ -144,7 +142,7 @@ const getGraphQLParams = async (request) => {
|
|
|
144
142
|
variables = null;
|
|
145
143
|
}
|
|
146
144
|
// Name of GraphQL operation to execute.
|
|
147
|
-
let operationName =
|
|
145
|
+
let operationName = urlData.get('operationName') ?? bodyData.operationName;
|
|
148
146
|
if (typeof operationName !== 'string') {
|
|
149
147
|
operationName = null;
|
|
150
148
|
}
|
|
@@ -12,7 +12,7 @@ const jwt = (options) => {
|
|
|
12
12
|
ctx.res = new Response('Unauthorized', {
|
|
13
13
|
status: 401,
|
|
14
14
|
headers: {
|
|
15
|
-
'WWW-Authenticate':
|
|
15
|
+
'WWW-Authenticate': `Bearer realm="${ctx.req.url}",error="invalid_request",error_description="no authorization included in request"`,
|
|
16
16
|
},
|
|
17
17
|
});
|
|
18
18
|
return;
|
|
@@ -22,7 +22,7 @@ const jwt = (options) => {
|
|
|
22
22
|
ctx.res = new Response('Unauthorized', {
|
|
23
23
|
status: 401,
|
|
24
24
|
headers: {
|
|
25
|
-
'WWW-Authenticate':
|
|
25
|
+
'WWW-Authenticate': `Bearer realm="${ctx.req.url}",error="invalid_request",error_description="no authorization included in request"`,
|
|
26
26
|
},
|
|
27
27
|
});
|
|
28
28
|
return;
|
|
@@ -40,7 +40,7 @@ const jwt = (options) => {
|
|
|
40
40
|
status: 401,
|
|
41
41
|
statusText: msg,
|
|
42
42
|
headers: {
|
|
43
|
-
'WWW-Authenticate':
|
|
43
|
+
'WWW-Authenticate': `Bearer realm="${ctx.req.url}",error="invalid_token",error_description="token verification failure"`,
|
|
44
44
|
},
|
|
45
45
|
});
|
|
46
46
|
return;
|
|
@@ -8,7 +8,7 @@ const DEFAULT_DOCUMENT = 'index.html';
|
|
|
8
8
|
const serveStatic = (options = { root: '' }) => {
|
|
9
9
|
return async (c, next) => {
|
|
10
10
|
// Do nothing if Response is already set
|
|
11
|
-
if (c.res && c.
|
|
11
|
+
if (c.res && c.finalized) {
|
|
12
12
|
await next();
|
|
13
13
|
}
|
|
14
14
|
const url = new URL(c.req.url);
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Request<ParamKeyType extends string = string> {
|
|
3
|
+
param: {
|
|
4
|
+
(key: ParamKeyType): string;
|
|
5
|
+
(): Record<ParamKeyType, string>;
|
|
6
|
+
};
|
|
7
|
+
paramData?: Record<ParamKeyType, string>;
|
|
8
|
+
query: {
|
|
9
|
+
(key: string): string;
|
|
10
|
+
(): Record<string, string>;
|
|
11
|
+
};
|
|
12
|
+
queries: {
|
|
13
|
+
(key: string): string[];
|
|
14
|
+
(): Record<string, string[]>;
|
|
15
|
+
};
|
|
16
|
+
header: {
|
|
17
|
+
(name: string): string;
|
|
18
|
+
(): Record<string, string>;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export declare function extendRequestPrototype(): void;
|
package/dist/request.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extendRequestPrototype = void 0;
|
|
4
|
+
function extendRequestPrototype() {
|
|
5
|
+
if (!!Request.prototype.param) {
|
|
6
|
+
// already extended
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
Request.prototype.param = function (key) {
|
|
10
|
+
if (this.paramData) {
|
|
11
|
+
if (key) {
|
|
12
|
+
return this.paramData[key];
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
return this.paramData;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
Request.prototype.header = function (name) {
|
|
21
|
+
if (name) {
|
|
22
|
+
return this.headers.get(name);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const result = {};
|
|
26
|
+
for (const [key, value] of this.headers) {
|
|
27
|
+
result[key] = value;
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
Request.prototype.query = function (key) {
|
|
33
|
+
const url = new URL(this.url);
|
|
34
|
+
if (key) {
|
|
35
|
+
return url.searchParams.get(key);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const result = {};
|
|
39
|
+
for (const key of url.searchParams.keys()) {
|
|
40
|
+
result[key] = url.searchParams.get(key) || '';
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
Request.prototype.queries = function (key) {
|
|
46
|
+
const url = new URL(this.url);
|
|
47
|
+
if (key) {
|
|
48
|
+
return url.searchParams.getAll(key);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
const result = {};
|
|
52
|
+
for (const key of url.searchParams.keys()) {
|
|
53
|
+
result[key] = url.searchParams.getAll(key);
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
exports.extendRequestPrototype = extendRequestPrototype;
|
|
@@ -11,10 +11,10 @@ export declare class Node<T> {
|
|
|
11
11
|
patterns: Pattern[];
|
|
12
12
|
order: number;
|
|
13
13
|
name: string;
|
|
14
|
+
handlerSetCache: Record<string, HandlerSet<T>[]>;
|
|
14
15
|
constructor(method?: string, handler?: T, children?: Record<string, Node<T>>);
|
|
15
16
|
insert(method: string, path: string, handler: T): Node<T>;
|
|
16
17
|
private getHandlerSets;
|
|
17
|
-
private next;
|
|
18
18
|
search(method: string, path: string): Result<T> | null;
|
|
19
19
|
}
|
|
20
20
|
export {};
|
|
@@ -28,6 +28,7 @@ class Node {
|
|
|
28
28
|
this.methods = [m];
|
|
29
29
|
}
|
|
30
30
|
this.patterns = [];
|
|
31
|
+
this.handlerSetCache = {};
|
|
31
32
|
}
|
|
32
33
|
insert(method, path, handler) {
|
|
33
34
|
this.name = `${method} ${path}`;
|
|
@@ -82,89 +83,76 @@ class Node {
|
|
|
82
83
|
return curNode;
|
|
83
84
|
}
|
|
84
85
|
getHandlerSets(node, method, wildcard) {
|
|
85
|
-
|
|
86
|
-
node.
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
91
|
-
hs
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
});
|
|
97
|
-
return handlerSets;
|
|
98
|
-
}
|
|
99
|
-
next(node, part, method, isLast) {
|
|
100
|
-
const handlerSets = [];
|
|
101
|
-
const nextNodes = [];
|
|
102
|
-
const params = {};
|
|
103
|
-
for (let j = 0, len = node.patterns.length; j < len; j++) {
|
|
104
|
-
const pattern = node.patterns[j];
|
|
105
|
-
// Wildcard
|
|
106
|
-
// '/hello/*/foo' => match /hello/bar/foo
|
|
107
|
-
if (pattern === '*') {
|
|
108
|
-
const astNode = node.children['*'];
|
|
109
|
-
if (astNode) {
|
|
110
|
-
handlerSets.push(...this.getHandlerSets(astNode, method));
|
|
111
|
-
nextNodes.push(astNode);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
if (part === '')
|
|
115
|
-
continue;
|
|
116
|
-
// Named match
|
|
117
|
-
// `/posts/:id` => match /posts/123
|
|
118
|
-
const [key, name, matcher] = pattern;
|
|
119
|
-
if (matcher === true || (matcher instanceof RegExp && matcher.test(part))) {
|
|
120
|
-
if (typeof key === 'string') {
|
|
121
|
-
if (isLast === true) {
|
|
122
|
-
handlerSets.push(...this.getHandlerSets(node.children[key], method));
|
|
86
|
+
var _a, _b;
|
|
87
|
+
return ((_a = node.handlerSetCache)[_b = `${method}:${wildcard ? '1' : '0'}`] || (_a[_b] = (() => {
|
|
88
|
+
const handlerSets = [];
|
|
89
|
+
node.methods.map((m) => {
|
|
90
|
+
const handlerSet = m[method] || m[router_1.METHOD_NAME_ALL];
|
|
91
|
+
if (handlerSet !== undefined) {
|
|
92
|
+
const hs = { ...handlerSet };
|
|
93
|
+
if (wildcard) {
|
|
94
|
+
hs.score = handlerSet.score - 1;
|
|
123
95
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (typeof name === 'string') {
|
|
127
|
-
params[name] = part;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
const nextNode = node.children[part];
|
|
132
|
-
if (nextNode) {
|
|
133
|
-
if (isLast === true) {
|
|
134
|
-
// '/hello/*' => match '/hello'
|
|
135
|
-
if (nextNode.children['*']) {
|
|
136
|
-
handlerSets.push(...this.getHandlerSets(nextNode.children['*'], method, true));
|
|
96
|
+
handlerSets.push(hs);
|
|
97
|
+
return;
|
|
137
98
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
}
|
|
142
|
-
const next = {
|
|
143
|
-
nodes: nextNodes,
|
|
144
|
-
handlerSets: handlerSets,
|
|
145
|
-
params: params,
|
|
146
|
-
};
|
|
147
|
-
return next;
|
|
99
|
+
});
|
|
100
|
+
return handlerSets;
|
|
101
|
+
})()));
|
|
148
102
|
}
|
|
149
103
|
search(method, path) {
|
|
150
104
|
const handlerSets = [];
|
|
151
|
-
|
|
105
|
+
const params = {};
|
|
152
106
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
153
107
|
const curNode = this;
|
|
154
108
|
let curNodes = [curNode];
|
|
155
109
|
const parts = (0, url_1.splitPath)(path);
|
|
156
110
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
157
|
-
const
|
|
111
|
+
const part = parts[i];
|
|
158
112
|
const isLast = i === len - 1;
|
|
159
113
|
const tempNodes = [];
|
|
160
114
|
for (let j = 0, len2 = curNodes.length; j < len2; j++) {
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
115
|
+
const node = curNodes[j];
|
|
116
|
+
for (let k = 0, len3 = node.patterns.length; k < len3; k++) {
|
|
117
|
+
const pattern = node.patterns[k];
|
|
118
|
+
// Wildcard
|
|
119
|
+
// '/hello/*/foo' => match /hello/bar/foo
|
|
120
|
+
if (pattern === '*') {
|
|
121
|
+
const astNode = node.children['*'];
|
|
122
|
+
if (astNode) {
|
|
123
|
+
handlerSets.push(...this.getHandlerSets(astNode, method));
|
|
124
|
+
tempNodes.push(astNode);
|
|
125
|
+
}
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (part === '')
|
|
129
|
+
continue;
|
|
130
|
+
// Named match
|
|
131
|
+
// `/posts/:id` => match /posts/123
|
|
132
|
+
const [key, name, matcher] = pattern;
|
|
133
|
+
if (matcher === true || (matcher instanceof RegExp && matcher.test(part))) {
|
|
134
|
+
if (typeof key === 'string') {
|
|
135
|
+
if (isLast === true) {
|
|
136
|
+
handlerSets.push(...this.getHandlerSets(node.children[key], method));
|
|
137
|
+
}
|
|
138
|
+
tempNodes.push(node.children[key]);
|
|
139
|
+
}
|
|
140
|
+
if (typeof name === 'string') {
|
|
141
|
+
params[name] = part;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const nextNode = node.children[part];
|
|
146
|
+
if (nextNode) {
|
|
147
|
+
if (isLast === true) {
|
|
148
|
+
// '/hello/*' => match '/hello'
|
|
149
|
+
if (nextNode.children['*']) {
|
|
150
|
+
handlerSets.push(...this.getHandlerSets(nextNode.children['*'], method, true));
|
|
151
|
+
}
|
|
152
|
+
handlerSets.push(...this.getHandlerSets(nextNode, method));
|
|
153
|
+
}
|
|
154
|
+
tempNodes.push(nextNode);
|
|
164
155
|
}
|
|
165
|
-
handlerSets.push(...res.handlerSets);
|
|
166
|
-
params = Object.assign(params, res.params);
|
|
167
|
-
tempNodes.push(...res.nodes);
|
|
168
156
|
}
|
|
169
157
|
curNodes = tempNodes;
|
|
170
158
|
}
|
package/dist/utils/encode.js
CHANGED
|
@@ -10,7 +10,7 @@ const encodeBase64 = (str) => {
|
|
|
10
10
|
const bytes = encoder.encode(str);
|
|
11
11
|
return btoa(String.fromCharCode(...bytes));
|
|
12
12
|
}
|
|
13
|
-
catch
|
|
13
|
+
catch { }
|
|
14
14
|
try {
|
|
15
15
|
return Buffer.from(str).toString('base64');
|
|
16
16
|
}
|
|
@@ -30,7 +30,7 @@ const decodeBase64 = (str) => {
|
|
|
30
30
|
const decoder = new TextDecoder();
|
|
31
31
|
return decoder.decode(bytes);
|
|
32
32
|
}
|
|
33
|
-
catch
|
|
33
|
+
catch { }
|
|
34
34
|
try {
|
|
35
35
|
return Buffer.from(str, 'base64').toString();
|
|
36
36
|
}
|
package/dist/utils/url.d.ts
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
export declare type Pattern = readonly [string, string, RegExp | true] | '*';
|
|
2
2
|
export declare const splitPath: (path: string) => string[];
|
|
3
3
|
export declare const getPattern: (label: string) => Pattern | null;
|
|
4
|
-
declare
|
|
5
|
-
strict: boolean;
|
|
6
|
-
};
|
|
7
|
-
export declare const getPathFromURL: (url: string, params?: Params) => string;
|
|
4
|
+
export declare const getPathFromURL: (url: string, strict?: boolean) => string;
|
|
8
5
|
export declare const isAbsoluteURL: (url: string) => boolean;
|
|
9
6
|
export declare const mergePath: (...paths: string[]) => string;
|
|
10
|
-
export {};
|
package/dist/utils/url.js
CHANGED
|
@@ -34,17 +34,15 @@ const getPattern = (label) => {
|
|
|
34
34
|
return null;
|
|
35
35
|
};
|
|
36
36
|
exports.getPattern = getPattern;
|
|
37
|
-
const getPathFromURL = (url,
|
|
37
|
+
const getPathFromURL = (url, strict = true) => {
|
|
38
|
+
const queryIndex = url.indexOf('?');
|
|
39
|
+
const result = url.substring(url.indexOf('/', 8), queryIndex === -1 ? url.length : queryIndex);
|
|
38
40
|
// if strict routing is false => `/hello/hey/` and `/hello/hey` are treated the same
|
|
39
41
|
// default is true
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
+
if (strict === false && result.endsWith('/')) {
|
|
43
|
+
return result.slice(0, -1);
|
|
42
44
|
}
|
|
43
|
-
|
|
44
|
-
if (match) {
|
|
45
|
-
return match[1];
|
|
46
|
-
}
|
|
47
|
-
return '';
|
|
45
|
+
return result;
|
|
48
46
|
};
|
|
49
47
|
exports.getPathFromURL = getPathFromURL;
|
|
50
48
|
const isAbsoluteURL = (url) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.5",
|
|
4
4
|
"description": "Ultrafast web framework for Cloudflare Workers.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"exports": {
|
|
19
19
|
".": "./dist/index.js",
|
|
20
20
|
"./basic-auth": "./dist/middleware/basic-auth/index.js",
|
|
21
|
+
"./bearer-auth": "./dist/middleware/bearer-auth/index.js",
|
|
21
22
|
"./body-parse": "./dist/middleware/body-parse/index.js",
|
|
22
23
|
"./cookie": "./dist/middleware/cookie/index.js",
|
|
23
24
|
"./cors": "./dist/middleware/cors/index.js",
|
|
@@ -41,6 +42,9 @@
|
|
|
41
42
|
"basic-auth": [
|
|
42
43
|
"./dist/middleware/basic-auth"
|
|
43
44
|
],
|
|
45
|
+
"bearer-auth": [
|
|
46
|
+
"./dist/middleware/bearer-auth"
|
|
47
|
+
],
|
|
44
48
|
"body-parse": [
|
|
45
49
|
"./dist/middleware/body-parse"
|
|
46
50
|
],
|
|
@@ -133,7 +137,7 @@
|
|
|
133
137
|
"form-data": "^4.0.0",
|
|
134
138
|
"graphql": "^16.4.0",
|
|
135
139
|
"jest": "27.5.1",
|
|
136
|
-
"jest-environment-miniflare": "^2.
|
|
140
|
+
"jest-environment-miniflare": "^2.5.0",
|
|
137
141
|
"mustache": "^4.2.0",
|
|
138
142
|
"prettier": "^2.6.2",
|
|
139
143
|
"prettier-plugin-md-nocjsp": "^1.2.0",
|
package/dist/response.d.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { Data } from './context';
|
|
2
|
-
export declare class HonoResponse implements Response {
|
|
3
|
-
headers: Headers;
|
|
4
|
-
ok: boolean;
|
|
5
|
-
redirected: boolean;
|
|
6
|
-
status: number;
|
|
7
|
-
statusText: string;
|
|
8
|
-
type: ResponseType;
|
|
9
|
-
url: string;
|
|
10
|
-
_finalized: boolean;
|
|
11
|
-
constructor(_data: Data | null, init: ResponseInit);
|
|
12
|
-
clone(): Response;
|
|
13
|
-
body: ReadableStream<Uint8Array> | null;
|
|
14
|
-
bodyUsed: boolean;
|
|
15
|
-
arrayBuffer(): Promise<ArrayBuffer>;
|
|
16
|
-
arrayBuffer(): Promise<ArrayBuffer>;
|
|
17
|
-
blob(): Promise<Blob>;
|
|
18
|
-
blob(): Promise<Blob>;
|
|
19
|
-
formData(): Promise<FormData>;
|
|
20
|
-
formData(): Promise<FormData>;
|
|
21
|
-
json(): Promise<any>;
|
|
22
|
-
json<T>(): Promise<T>;
|
|
23
|
-
text(): Promise<string>;
|
|
24
|
-
text(): Promise<string>;
|
|
25
|
-
}
|
package/dist/response.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
This Response object is for better performance.
|
|
4
|
-
This object is used in a Context before the Handler dispatches.
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.HonoResponse = void 0;
|
|
8
|
-
const errorMessage = 'Response is not finalized';
|
|
9
|
-
class HonoResponse {
|
|
10
|
-
constructor(_data, init) {
|
|
11
|
-
var _a;
|
|
12
|
-
this.headers = new Headers(init.headers);
|
|
13
|
-
this.status = (_a = init.status) !== null && _a !== void 0 ? _a : 404;
|
|
14
|
-
this._finalized = false;
|
|
15
|
-
}
|
|
16
|
-
clone() {
|
|
17
|
-
throw new Error(errorMessage);
|
|
18
|
-
}
|
|
19
|
-
arrayBuffer() {
|
|
20
|
-
throw new Error(errorMessage);
|
|
21
|
-
}
|
|
22
|
-
blob() {
|
|
23
|
-
throw new Error(errorMessage);
|
|
24
|
-
}
|
|
25
|
-
formData() {
|
|
26
|
-
throw new Error(errorMessage);
|
|
27
|
-
}
|
|
28
|
-
json() {
|
|
29
|
-
throw new Error(errorMessage);
|
|
30
|
-
}
|
|
31
|
-
text() {
|
|
32
|
-
throw new Error(errorMessage);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
exports.HonoResponse = HonoResponse;
|