hono 1.3.5 → 1.3.6
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 +13 -5
- package/dist/compose.js +13 -6
- package/dist/context.d.ts +1 -2
- package/dist/context.js +28 -12
- package/dist/hono.d.ts +8 -0
- package/dist/hono.js +24 -14
- package/dist/middleware/mustache/mustache.js +18 -11
- package/dist/middleware/serve-static/serve-static.js +11 -7
- package/dist/router/trie-router/index.js +5 -1
- package/dist/router/trie-router/node.js +12 -8
- package/dist/router/trie-router/router.js +8 -4
- package/dist/router.js +9 -4
- package/dist/utils/buffer.js +11 -5
- package/dist/utils/cloudflare.js +7 -2
- package/dist/utils/crypto.js +11 -5
- package/dist/utils/http-status.js +5 -1
- package/dist/utils/mime.js +5 -1
- package/dist/utils/url.js +13 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -137,15 +137,15 @@ npm install hono
|
|
|
137
137
|
|
|
138
138
|
An instance of `Hono` has these methods.
|
|
139
139
|
|
|
140
|
-
- app.**HTTP_METHOD**(\[
|
|
141
|
-
- app.**all**(\[
|
|
142
|
-
- app.**route**(
|
|
143
|
-
- app.**use**(\[
|
|
140
|
+
- app.**HTTP_METHOD**(\[パス,\]handler|middleware...)
|
|
141
|
+
- app.**all**(\[パス,\]handler|middleware...)
|
|
142
|
+
- app.**route**(パス, \[app\])
|
|
143
|
+
- app.**use**(\[パス,\]middleware)
|
|
144
144
|
- app.**notFound**(handler)
|
|
145
145
|
- app.**onError**(err, handler)
|
|
146
146
|
- app.**fire**()
|
|
147
147
|
- app.**fetch**(request, env, event)
|
|
148
|
-
- app.**request**(
|
|
148
|
+
- app.**request**(パス, options)
|
|
149
149
|
|
|
150
150
|
## Routing
|
|
151
151
|
|
|
@@ -354,6 +354,14 @@ app.get('/search', (c) => {
|
|
|
354
354
|
...
|
|
355
355
|
})
|
|
356
356
|
|
|
357
|
+
// Multiple query values
|
|
358
|
+
app.get('/search', (c) => {
|
|
359
|
+
const queries = c.req.queries('q')
|
|
360
|
+
// ---> GET search?q=foo&q=bar
|
|
361
|
+
// queries[0] => foo, queries[1] => bar
|
|
362
|
+
...
|
|
363
|
+
})
|
|
364
|
+
|
|
357
365
|
// Captured params
|
|
358
366
|
app.get('/entry/:id', (c) => {
|
|
359
367
|
const id = c.req.param('id')
|
package/dist/compose.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.compose = void 0;
|
|
4
|
+
const context_1 = require("./context");
|
|
2
5
|
// Based on the code in the MIT licensed `koa-compose` package.
|
|
3
|
-
|
|
6
|
+
const compose = (middleware, onError, onNotFound) => {
|
|
4
7
|
return async (context, next) => {
|
|
5
8
|
let index = -1;
|
|
6
9
|
return dispatch(0);
|
|
@@ -13,24 +16,27 @@ export const compose = (middleware, onError, onNotFound) => {
|
|
|
13
16
|
if (i === middleware.length)
|
|
14
17
|
handler = next;
|
|
15
18
|
if (handler === undefined) {
|
|
16
|
-
if (context instanceof Context && context.res ===
|
|
19
|
+
if (context instanceof context_1.Context && context.res.finalized === false) {
|
|
17
20
|
context.res = onNotFound(context);
|
|
21
|
+
context.res.finalized = true;
|
|
18
22
|
}
|
|
19
23
|
return Promise.resolve(context);
|
|
20
24
|
}
|
|
21
25
|
return Promise.resolve(handler(context, dispatch.bind(null, i + 1)))
|
|
22
26
|
.then(async (res) => {
|
|
23
27
|
// If handler return Response like `return c.text('foo')`
|
|
24
|
-
if (res && context instanceof Context) {
|
|
28
|
+
if (res && context instanceof context_1.Context) {
|
|
25
29
|
context.res = res;
|
|
26
|
-
|
|
30
|
+
context.res.finalized = true;
|
|
31
|
+
await dispatch(i + 1); // <--- Call next()
|
|
27
32
|
}
|
|
28
33
|
return context;
|
|
29
34
|
})
|
|
30
35
|
.catch((err) => {
|
|
31
|
-
if (onError && context instanceof Context) {
|
|
36
|
+
if (onError && context instanceof context_1.Context) {
|
|
32
37
|
if (err instanceof Error) {
|
|
33
38
|
context.res = onError(err, context);
|
|
39
|
+
context.res.finalized = true;
|
|
34
40
|
}
|
|
35
41
|
return context;
|
|
36
42
|
}
|
|
@@ -41,3 +47,4 @@ export const compose = (middleware, onError, onNotFound) => {
|
|
|
41
47
|
}
|
|
42
48
|
};
|
|
43
49
|
};
|
|
50
|
+
exports.compose = compose;
|
package/dist/context.d.ts
CHANGED
|
@@ -10,16 +10,15 @@ export declare class Context<RequestParamKeyType extends string = string, E = En
|
|
|
10
10
|
event: FetchEvent;
|
|
11
11
|
private _headers;
|
|
12
12
|
private _status;
|
|
13
|
-
private _statusText;
|
|
14
13
|
private _pretty;
|
|
15
14
|
private _prettySpace;
|
|
16
15
|
private _map;
|
|
17
16
|
render: (template: string, params?: object, options?: object) => Promise<Response>;
|
|
18
17
|
notFound: () => Response | Promise<Response>;
|
|
19
18
|
constructor(req: Request<RequestParamKeyType>, opts?: {
|
|
20
|
-
res: Response;
|
|
21
19
|
env: E;
|
|
22
20
|
event: FetchEvent;
|
|
21
|
+
res?: Response;
|
|
23
22
|
});
|
|
24
23
|
private initRequest;
|
|
25
24
|
header(name: string, value: string): void;
|
package/dist/context.js
CHANGED
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Context = void 0;
|
|
4
|
+
const url_1 = require("./utils/url");
|
|
5
|
+
class Context {
|
|
4
6
|
constructor(req, opts) {
|
|
5
|
-
this.res = undefined;
|
|
6
7
|
this._headers = {};
|
|
7
8
|
this._status = 200;
|
|
8
|
-
this._statusText = '';
|
|
9
9
|
this._pretty = false;
|
|
10
10
|
this._prettySpace = 2;
|
|
11
11
|
this.req = this.initRequest(req);
|
|
12
12
|
this._map = {};
|
|
13
13
|
Object.assign(this, opts);
|
|
14
|
+
if (!this.res) {
|
|
15
|
+
const res = new Response(null, { status: 404 });
|
|
16
|
+
res.finalized = false;
|
|
17
|
+
this.res = res;
|
|
18
|
+
}
|
|
14
19
|
}
|
|
15
20
|
initRequest(req) {
|
|
16
21
|
req.header = ((name) => {
|
|
@@ -32,8 +37,21 @@ export class Context {
|
|
|
32
37
|
}
|
|
33
38
|
else {
|
|
34
39
|
const result = {};
|
|
35
|
-
for (const
|
|
36
|
-
result[key] =
|
|
40
|
+
for (const key of url.searchParams.keys()) {
|
|
41
|
+
result[key] = url.searchParams.get(key);
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
req.queries = ((key) => {
|
|
47
|
+
const url = new URL(req.url);
|
|
48
|
+
if (key) {
|
|
49
|
+
return url.searchParams.getAll(key);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const result = {};
|
|
53
|
+
for (const key of url.searchParams.keys()) {
|
|
54
|
+
result[key] = url.searchParams.getAll(key);
|
|
37
55
|
}
|
|
38
56
|
return result;
|
|
39
57
|
}
|
|
@@ -48,7 +66,6 @@ export class Context {
|
|
|
48
66
|
}
|
|
49
67
|
status(status) {
|
|
50
68
|
this._status = status;
|
|
51
|
-
this._statusText = getStatusText(status);
|
|
52
69
|
}
|
|
53
70
|
set(key, value) {
|
|
54
71
|
this._map[key] = value;
|
|
@@ -62,9 +79,7 @@ export class Context {
|
|
|
62
79
|
}
|
|
63
80
|
newResponse(data, init = {}) {
|
|
64
81
|
init.status = init.status || this._status || 200;
|
|
65
|
-
init.
|
|
66
|
-
init.statusText || this._statusText || getStatusText(init.status);
|
|
67
|
-
init.headers = { ...this._headers, ...init.headers };
|
|
82
|
+
init.headers = Object.assign(Object.assign({}, this._headers), init.headers);
|
|
68
83
|
return new Response(data, init);
|
|
69
84
|
}
|
|
70
85
|
body(data, status = this._status, headers = this._headers) {
|
|
@@ -101,7 +116,7 @@ export class Context {
|
|
|
101
116
|
if (typeof location !== 'string') {
|
|
102
117
|
throw new TypeError('location must be a string!');
|
|
103
118
|
}
|
|
104
|
-
if (!isAbsoluteURL(location)) {
|
|
119
|
+
if (!(0, url_1.isAbsoluteURL)(location)) {
|
|
105
120
|
const url = new URL(this.req.url);
|
|
106
121
|
url.pathname = location;
|
|
107
122
|
location = url.toString();
|
|
@@ -114,3 +129,4 @@ export class Context {
|
|
|
114
129
|
});
|
|
115
130
|
}
|
|
116
131
|
}
|
|
132
|
+
exports.Context = Context;
|
package/dist/hono.d.ts
CHANGED
|
@@ -12,11 +12,18 @@ declare global {
|
|
|
12
12
|
(key: string): string;
|
|
13
13
|
(): Record<string, string>;
|
|
14
14
|
};
|
|
15
|
+
queries: {
|
|
16
|
+
(key: string): string[];
|
|
17
|
+
(): Record<string, string[]>;
|
|
18
|
+
};
|
|
15
19
|
header: {
|
|
16
20
|
(name: string): string;
|
|
17
21
|
(): Record<string, string>;
|
|
18
22
|
};
|
|
19
23
|
}
|
|
24
|
+
interface Response {
|
|
25
|
+
finalized: boolean;
|
|
26
|
+
}
|
|
20
27
|
}
|
|
21
28
|
export declare type Handler<RequestParamKeyType extends string = string, E = Env> = (c: Context<RequestParamKeyType, E>, next: Next) => Response | Promise<Response> | void | Promise<void>;
|
|
22
29
|
export declare type NotFoundHandler<E = Env> = (c: Context<string, E>) => Response;
|
|
@@ -54,6 +61,7 @@ export declare class Hono<E = Env, P extends string = '/'> extends Hono_base<E,
|
|
|
54
61
|
private _router;
|
|
55
62
|
private _tempPath;
|
|
56
63
|
private path;
|
|
64
|
+
private _cacheResponse;
|
|
57
65
|
routes: Route<E>[];
|
|
58
66
|
constructor(init?: Partial<Pick<Hono, 'routerClass' | 'strict'>>);
|
|
59
67
|
private notFoundHandler;
|
package/dist/hono.js
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Hono = void 0;
|
|
4
|
+
const compose_1 = require("./compose");
|
|
5
|
+
const context_1 = require("./context");
|
|
6
|
+
const router_1 = require("./router");
|
|
7
|
+
const router_2 = require("./router");
|
|
8
|
+
const trie_router_1 = require("./router/trie-router"); // Default Router
|
|
9
|
+
const url_1 = require("./utils/url");
|
|
7
10
|
const methods = ['get', 'post', 'put', 'delete', 'head', 'options', 'patch'];
|
|
8
11
|
function defineDynamicClass() {
|
|
9
12
|
return class {
|
|
10
13
|
};
|
|
11
14
|
}
|
|
12
|
-
|
|
15
|
+
class Hono extends defineDynamicClass() {
|
|
13
16
|
constructor(init = {}) {
|
|
14
17
|
super();
|
|
15
|
-
this.routerClass = TrieRouter;
|
|
18
|
+
this.routerClass = trie_router_1.TrieRouter;
|
|
16
19
|
this.strict = true; // strict routing - default is true
|
|
17
20
|
this.path = '/';
|
|
18
21
|
this.routes = [];
|
|
@@ -25,7 +28,7 @@ export class Hono extends defineDynamicClass() {
|
|
|
25
28
|
const message = 'Internal Server Error';
|
|
26
29
|
return c.text(message, 500);
|
|
27
30
|
};
|
|
28
|
-
const allMethods = [...methods, METHOD_NAME_ALL_LOWERCASE];
|
|
31
|
+
const allMethods = [...methods, router_2.METHOD_NAME_ALL_LOWERCASE];
|
|
29
32
|
allMethods.map((method) => {
|
|
30
33
|
this[method] = (args1, ...args) => {
|
|
31
34
|
if (typeof args1 === 'string') {
|
|
@@ -45,6 +48,8 @@ export class Hono extends defineDynamicClass() {
|
|
|
45
48
|
Object.assign(this, init);
|
|
46
49
|
this._router = new this.routerClass();
|
|
47
50
|
this._tempPath = null;
|
|
51
|
+
this._cacheResponse = new Response(null, { status: 404 });
|
|
52
|
+
this._cacheResponse.finalized = false;
|
|
48
53
|
}
|
|
49
54
|
route(path, app) {
|
|
50
55
|
this._tempPath = path;
|
|
@@ -64,7 +69,7 @@ export class Hono extends defineDynamicClass() {
|
|
|
64
69
|
handlers.unshift(arg1);
|
|
65
70
|
}
|
|
66
71
|
handlers.map((handler) => {
|
|
67
|
-
this.addRoute(METHOD_NAME_ALL, this.path, handler);
|
|
72
|
+
this.addRoute(router_1.METHOD_NAME_ALL, this.path, handler);
|
|
68
73
|
});
|
|
69
74
|
return this;
|
|
70
75
|
}
|
|
@@ -79,7 +84,7 @@ export class Hono extends defineDynamicClass() {
|
|
|
79
84
|
addRoute(method, path, handler) {
|
|
80
85
|
method = method.toUpperCase();
|
|
81
86
|
if (this._tempPath) {
|
|
82
|
-
path = mergePath(this._tempPath, path);
|
|
87
|
+
path = (0, url_1.mergePath)(this._tempPath, path);
|
|
83
88
|
}
|
|
84
89
|
this._router.add(method, path, handler);
|
|
85
90
|
const r = { path: path, method: method, handler: handler };
|
|
@@ -89,7 +94,7 @@ export class Hono extends defineDynamicClass() {
|
|
|
89
94
|
return this._router.match(method, path);
|
|
90
95
|
}
|
|
91
96
|
async dispatch(request, event, env) {
|
|
92
|
-
const path = getPathFromURL(request.url, { strict: this.strict });
|
|
97
|
+
const path = (0, url_1.getPathFromURL)(request.url, { strict: this.strict });
|
|
93
98
|
const method = request.method;
|
|
94
99
|
const result = await this.matchRoute(method, path);
|
|
95
100
|
request.param = ((key) => {
|
|
@@ -103,9 +108,13 @@ export class Hono extends defineDynamicClass() {
|
|
|
103
108
|
}
|
|
104
109
|
});
|
|
105
110
|
const handlers = result ? result.handlers : [this.notFoundHandler];
|
|
106
|
-
const c = new Context(request, {
|
|
111
|
+
const c = new context_1.Context(request, {
|
|
112
|
+
env: env,
|
|
113
|
+
event: event,
|
|
114
|
+
res: this._cacheResponse,
|
|
115
|
+
});
|
|
107
116
|
c.notFound = () => this.notFoundHandler(c);
|
|
108
|
-
const composed = compose(handlers, this.errorHandler, this.notFoundHandler);
|
|
117
|
+
const composed = (0, compose_1.compose)(handlers, this.errorHandler, this.notFoundHandler);
|
|
109
118
|
let context;
|
|
110
119
|
try {
|
|
111
120
|
context = await composed(c);
|
|
@@ -135,3 +144,4 @@ export class Hono extends defineDynamicClass() {
|
|
|
135
144
|
});
|
|
136
145
|
}
|
|
137
146
|
}
|
|
147
|
+
exports.Hono = Hono;
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.mustache = void 0;
|
|
7
|
+
const mustache_1 = __importDefault(require("mustache"));
|
|
8
|
+
const buffer_1 = require("../../utils/buffer");
|
|
9
|
+
const cloudflare_1 = require("../../utils/cloudflare");
|
|
4
10
|
const EXTENSION = '.mustache';
|
|
5
11
|
const DEFAULT_DOCUMENT = 'index.mustache';
|
|
6
|
-
|
|
12
|
+
const mustache = (init = { root: '' }) => {
|
|
7
13
|
const { root } = init;
|
|
8
14
|
return async (c, next) => {
|
|
9
15
|
c.render = async (filename, params = {}, options) => {
|
|
10
|
-
const path = getKVFilePath({
|
|
16
|
+
const path = (0, cloudflare_1.getKVFilePath)({
|
|
11
17
|
filename: `${filename}${EXTENSION}`,
|
|
12
18
|
root: root,
|
|
13
19
|
defaultDocument: DEFAULT_DOCUMENT,
|
|
@@ -16,30 +22,31 @@ export const mustache = (init = { root: '' }) => {
|
|
|
16
22
|
manifest: init.manifest,
|
|
17
23
|
namespace: init.namespace ? init.namespace : c.env ? c.env.__STATIC_CONTENT : undefined,
|
|
18
24
|
};
|
|
19
|
-
const buffer = await getContentFromKVAsset(path, kvAssetOptions);
|
|
25
|
+
const buffer = await (0, cloudflare_1.getContentFromKVAsset)(path, kvAssetOptions);
|
|
20
26
|
if (!buffer) {
|
|
21
27
|
throw new Error(`Template "${path}" is not found or blank.`);
|
|
22
28
|
}
|
|
23
|
-
const content = bufferToString(buffer);
|
|
29
|
+
const content = (0, buffer_1.bufferToString)(buffer);
|
|
24
30
|
const partialArgs = {};
|
|
25
31
|
if (options) {
|
|
26
32
|
const partials = options;
|
|
27
33
|
for (const key of Object.keys(partials)) {
|
|
28
|
-
const partialPath = getKVFilePath({
|
|
34
|
+
const partialPath = (0, cloudflare_1.getKVFilePath)({
|
|
29
35
|
filename: `${partials[key]}${EXTENSION}`,
|
|
30
36
|
root: root,
|
|
31
37
|
defaultDocument: DEFAULT_DOCUMENT,
|
|
32
38
|
});
|
|
33
|
-
const partialBuffer = await getContentFromKVAsset(partialPath, kvAssetOptions);
|
|
39
|
+
const partialBuffer = await (0, cloudflare_1.getContentFromKVAsset)(partialPath, kvAssetOptions);
|
|
34
40
|
if (!partialBuffer) {
|
|
35
41
|
throw new Error(`Partial Template "${partialPath}" is not found or blank.`);
|
|
36
42
|
}
|
|
37
|
-
partialArgs[key] = bufferToString(partialBuffer);
|
|
43
|
+
partialArgs[key] = (0, buffer_1.bufferToString)(partialBuffer);
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
|
-
const output =
|
|
46
|
+
const output = mustache_1.default.render(content, params, partialArgs);
|
|
41
47
|
return c.html(output);
|
|
42
48
|
};
|
|
43
49
|
await next();
|
|
44
50
|
};
|
|
45
51
|
};
|
|
52
|
+
exports.mustache = mustache;
|
|
@@ -1,25 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serveStatic = void 0;
|
|
4
|
+
const cloudflare_1 = require("../../utils/cloudflare");
|
|
5
|
+
const mime_1 = require("../../utils/mime");
|
|
3
6
|
const DEFAULT_DOCUMENT = 'index.html';
|
|
4
7
|
// This middleware is available only on Cloudflare Workers.
|
|
5
|
-
|
|
8
|
+
const serveStatic = (options = { root: '' }) => {
|
|
6
9
|
return async (c, next) => {
|
|
7
10
|
// Do nothing if Response is already set
|
|
8
|
-
if (c.res) {
|
|
11
|
+
if (c.res && c.res.finalized) {
|
|
9
12
|
await next();
|
|
10
13
|
}
|
|
11
14
|
const url = new URL(c.req.url);
|
|
12
|
-
const path = getKVFilePath({
|
|
15
|
+
const path = (0, cloudflare_1.getKVFilePath)({
|
|
13
16
|
filename: url.pathname,
|
|
14
17
|
root: options.root,
|
|
15
18
|
defaultDocument: DEFAULT_DOCUMENT,
|
|
16
19
|
});
|
|
17
|
-
const content = await getContentFromKVAsset(path, {
|
|
20
|
+
const content = await (0, cloudflare_1.getContentFromKVAsset)(path, {
|
|
18
21
|
manifest: options.manifest,
|
|
19
22
|
namespace: options.namespace ? options.namespace : c.env ? c.env.__STATIC_CONTENT : undefined,
|
|
20
23
|
});
|
|
21
24
|
if (content) {
|
|
22
|
-
const mimeType = getMimeType(path);
|
|
25
|
+
const mimeType = (0, mime_1.getMimeType)(path);
|
|
23
26
|
if (mimeType) {
|
|
24
27
|
c.header('Content-Type', mimeType);
|
|
25
28
|
}
|
|
@@ -32,3 +35,4 @@ export const serveStatic = (options = { root: '' }) => {
|
|
|
32
35
|
}
|
|
33
36
|
};
|
|
34
37
|
};
|
|
38
|
+
exports.serveStatic = serveStatic;
|
|
@@ -1 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TrieRouter = void 0;
|
|
4
|
+
var router_1 = require("./router");
|
|
5
|
+
Object.defineProperty(exports, "TrieRouter", { enumerable: true, get: function () { return router_1.TrieRouter; } });
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Node = void 0;
|
|
4
|
+
const router_1 = require("../../router");
|
|
5
|
+
const url_1 = require("../../utils/url");
|
|
3
6
|
function findParam(node, name) {
|
|
4
7
|
for (let i = 0, len = node.patterns.length; i < len; i++) {
|
|
5
8
|
if (typeof node.patterns[i] === 'object' && node.patterns[i][1] === name) {
|
|
@@ -14,7 +17,7 @@ function findParam(node, name) {
|
|
|
14
17
|
}
|
|
15
18
|
return false;
|
|
16
19
|
}
|
|
17
|
-
|
|
20
|
+
class Node {
|
|
18
21
|
constructor(method, handler, children) {
|
|
19
22
|
this.children = children || {};
|
|
20
23
|
this.methods = [];
|
|
@@ -28,7 +31,7 @@ export class Node {
|
|
|
28
31
|
insert(method, path, handler) {
|
|
29
32
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
30
33
|
let curNode = this;
|
|
31
|
-
const parts = splitPath(path);
|
|
34
|
+
const parts = (0, url_1.splitPath)(path);
|
|
32
35
|
const parentPatterns = [];
|
|
33
36
|
const errorMessage = (name) => {
|
|
34
37
|
return `Duplicate param name, use another name instead of '${name}' - ${method} ${path} <--- '${name}'`;
|
|
@@ -41,7 +44,7 @@ export class Node {
|
|
|
41
44
|
continue;
|
|
42
45
|
}
|
|
43
46
|
curNode.children[p] = new Node();
|
|
44
|
-
const pattern = getPattern(p);
|
|
47
|
+
const pattern = (0, url_1.getPattern)(p);
|
|
45
48
|
if (pattern) {
|
|
46
49
|
if (typeof pattern === 'object') {
|
|
47
50
|
for (let j = 0, len = parentPatterns.length; j < len; j++) {
|
|
@@ -75,7 +78,7 @@ export class Node {
|
|
|
75
78
|
handlers.push(handler);
|
|
76
79
|
return;
|
|
77
80
|
}
|
|
78
|
-
handler = m[METHOD_NAME_ALL];
|
|
81
|
+
handler = m[router_1.METHOD_NAME_ALL];
|
|
79
82
|
if (handler !== undefined) {
|
|
80
83
|
handlers.push(handler);
|
|
81
84
|
return;
|
|
@@ -139,7 +142,7 @@ export class Node {
|
|
|
139
142
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
140
143
|
const curNode = this;
|
|
141
144
|
let curNodes = [curNode];
|
|
142
|
-
const parts = splitPath(path);
|
|
145
|
+
const parts = (0, url_1.splitPath)(path);
|
|
143
146
|
for (let i = 0, len = parts.length; i < len; i++) {
|
|
144
147
|
const p = parts[i];
|
|
145
148
|
const isLast = i === len - 1;
|
|
@@ -157,6 +160,7 @@ export class Node {
|
|
|
157
160
|
}
|
|
158
161
|
if (handlers.length <= 0)
|
|
159
162
|
return null;
|
|
160
|
-
return new Result(handlers, params);
|
|
163
|
+
return new router_1.Result(handlers, params);
|
|
161
164
|
}
|
|
162
165
|
}
|
|
166
|
+
exports.Node = Node;
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TrieRouter = void 0;
|
|
4
|
+
const router_1 = require("../../router");
|
|
5
|
+
const node_1 = require("./node");
|
|
6
|
+
class TrieRouter extends router_1.Router {
|
|
4
7
|
constructor() {
|
|
5
8
|
super();
|
|
6
|
-
this.node = new Node();
|
|
9
|
+
this.node = new node_1.Node();
|
|
7
10
|
}
|
|
8
11
|
add(method, path, handler) {
|
|
9
12
|
this.node.insert(method, path, handler);
|
|
@@ -12,3 +15,4 @@ export class TrieRouter extends Router {
|
|
|
12
15
|
return this.node.search(method, path);
|
|
13
16
|
}
|
|
14
17
|
}
|
|
18
|
+
exports.TrieRouter = TrieRouter;
|
package/dist/router.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Result = exports.Router = exports.METHOD_NAME_ALL_LOWERCASE = exports.METHOD_NAME_ALL = void 0;
|
|
4
|
+
exports.METHOD_NAME_ALL = 'ALL';
|
|
5
|
+
exports.METHOD_NAME_ALL_LOWERCASE = 'all';
|
|
6
|
+
class Router {
|
|
4
7
|
}
|
|
5
|
-
|
|
8
|
+
exports.Router = Router;
|
|
9
|
+
class Result {
|
|
6
10
|
constructor(handlers, params) {
|
|
7
11
|
this.handlers = handlers;
|
|
8
12
|
this.params = params;
|
|
9
13
|
}
|
|
10
14
|
}
|
|
15
|
+
exports.Result = Result;
|
package/dist/utils/buffer.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.bufferToString = exports.timingSafeEqual = exports.equal = void 0;
|
|
4
|
+
const crypto_1 = require("./crypto");
|
|
5
|
+
const equal = (a, b) => {
|
|
3
6
|
if (a === b) {
|
|
4
7
|
return true;
|
|
5
8
|
}
|
|
@@ -16,18 +19,21 @@ export const equal = (a, b) => {
|
|
|
16
19
|
}
|
|
17
20
|
return true;
|
|
18
21
|
};
|
|
19
|
-
|
|
22
|
+
exports.equal = equal;
|
|
23
|
+
const timingSafeEqual = async (a, b, hashFunction) => {
|
|
20
24
|
if (!hashFunction) {
|
|
21
|
-
hashFunction = sha256;
|
|
25
|
+
hashFunction = crypto_1.sha256;
|
|
22
26
|
}
|
|
23
27
|
const sa = await hashFunction(a);
|
|
24
28
|
const sb = await hashFunction(b);
|
|
25
29
|
return sa === sb && a === b;
|
|
26
30
|
};
|
|
27
|
-
|
|
31
|
+
exports.timingSafeEqual = timingSafeEqual;
|
|
32
|
+
const bufferToString = (buffer) => {
|
|
28
33
|
if (buffer instanceof ArrayBuffer) {
|
|
29
34
|
const enc = new TextDecoder('utf-8');
|
|
30
35
|
return enc.decode(buffer);
|
|
31
36
|
}
|
|
32
37
|
return buffer;
|
|
33
38
|
};
|
|
39
|
+
exports.bufferToString = bufferToString;
|
package/dist/utils/cloudflare.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getKVFilePath = exports.getContentFromKVAsset = void 0;
|
|
4
|
+
const getContentFromKVAsset = async (path, options) => {
|
|
2
5
|
let ASSET_MANIFEST = {};
|
|
3
6
|
if (options && options.manifest) {
|
|
4
7
|
if (typeof options.manifest === 'string') {
|
|
@@ -33,7 +36,8 @@ export const getContentFromKVAsset = async (path, options) => {
|
|
|
33
36
|
}
|
|
34
37
|
return content;
|
|
35
38
|
};
|
|
36
|
-
|
|
39
|
+
exports.getContentFromKVAsset = getContentFromKVAsset;
|
|
40
|
+
const getKVFilePath = (options) => {
|
|
37
41
|
let filename = options.filename;
|
|
38
42
|
let root = options.root || '';
|
|
39
43
|
const defaultDocument = options.defaultDocument || 'index.html';
|
|
@@ -54,3 +58,4 @@ export const getKVFilePath = (options) => {
|
|
|
54
58
|
path = path.replace(/^\.?\//, '');
|
|
55
59
|
return path;
|
|
56
60
|
};
|
|
61
|
+
exports.getKVFilePath = getKVFilePath;
|
package/dist/utils/crypto.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createHash = exports.sha1 = exports.sha256 = void 0;
|
|
4
|
+
const sha256 = async (data) => {
|
|
2
5
|
const algorithm = { name: 'SHA-256', alias: 'sha256' };
|
|
3
|
-
const hash = await createHash(data, algorithm);
|
|
6
|
+
const hash = await (0, exports.createHash)(data, algorithm);
|
|
4
7
|
return hash;
|
|
5
8
|
};
|
|
6
|
-
|
|
9
|
+
exports.sha256 = sha256;
|
|
10
|
+
const sha1 = async (data) => {
|
|
7
11
|
const algorithm = { name: 'SHA-1', alias: 'sha1' };
|
|
8
|
-
const hash = await createHash(data, algorithm);
|
|
12
|
+
const hash = await (0, exports.createHash)(data, algorithm);
|
|
9
13
|
return hash;
|
|
10
14
|
};
|
|
11
|
-
|
|
15
|
+
exports.sha1 = sha1;
|
|
16
|
+
const createHash = async (data, algorithm) => {
|
|
12
17
|
if (crypto && crypto.subtle) {
|
|
13
18
|
const buffer = await crypto.subtle.digest({
|
|
14
19
|
name: algorithm.name,
|
|
@@ -19,3 +24,4 @@ export const createHash = async (data, algorithm) => {
|
|
|
19
24
|
return hash;
|
|
20
25
|
}
|
|
21
26
|
};
|
|
27
|
+
exports.createHash = createHash;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getStatusText = void 0;
|
|
4
|
+
const getStatusText = (statusCode) => {
|
|
2
5
|
const text = statuses[statusCode];
|
|
3
6
|
return text;
|
|
4
7
|
};
|
|
8
|
+
exports.getStatusText = getStatusText;
|
|
5
9
|
const statuses = {
|
|
6
10
|
100: 'Continue',
|
|
7
11
|
101: 'Switching Protocols',
|
package/dist/utils/mime.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMimeType = void 0;
|
|
4
|
+
const getMimeType = (filename) => {
|
|
2
5
|
const regexp = /\.([a-zA-Z0-9]+?)$/;
|
|
3
6
|
const match = filename.match(regexp);
|
|
4
7
|
if (!match)
|
|
@@ -9,6 +12,7 @@ export const getMimeType = (filename) => {
|
|
|
9
12
|
}
|
|
10
13
|
return mimeType;
|
|
11
14
|
};
|
|
15
|
+
exports.getMimeType = getMimeType;
|
|
12
16
|
const mimes = {
|
|
13
17
|
aac: 'audio/aac',
|
|
14
18
|
abw: 'application/x-abiword',
|
package/dist/utils/url.js
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mergePath = exports.isAbsoluteURL = exports.getPathFromURL = exports.getPattern = exports.splitPath = void 0;
|
|
1
4
|
const URL_REGEXP = /^https?:\/\/[a-zA-Z0-9\-\.:]+(\/?[^?#]*)/;
|
|
2
|
-
|
|
5
|
+
const splitPath = (path) => {
|
|
3
6
|
const paths = path.split(/\//); // faster than path.split('/')
|
|
4
7
|
if (paths[0] === '') {
|
|
5
8
|
paths.shift();
|
|
6
9
|
}
|
|
7
10
|
return paths;
|
|
8
11
|
};
|
|
12
|
+
exports.splitPath = splitPath;
|
|
9
13
|
const patternCache = {};
|
|
10
|
-
|
|
14
|
+
const getPattern = (label) => {
|
|
11
15
|
// * => wildcard
|
|
12
16
|
// :id{[0-9]+} => ([0-9]+)
|
|
13
17
|
// :id => (.+)
|
|
@@ -29,7 +33,8 @@ export const getPattern = (label) => {
|
|
|
29
33
|
}
|
|
30
34
|
return null;
|
|
31
35
|
};
|
|
32
|
-
|
|
36
|
+
exports.getPattern = getPattern;
|
|
37
|
+
const getPathFromURL = (url, params = { strict: true }) => {
|
|
33
38
|
// if strict routing is false => `/hello/hey/` and `/hello/hey` are treated the same
|
|
34
39
|
// default is true
|
|
35
40
|
if (params.strict === false && url.endsWith('/')) {
|
|
@@ -41,14 +46,16 @@ export const getPathFromURL = (url, params = { strict: true }) => {
|
|
|
41
46
|
}
|
|
42
47
|
return '';
|
|
43
48
|
};
|
|
44
|
-
|
|
49
|
+
exports.getPathFromURL = getPathFromURL;
|
|
50
|
+
const isAbsoluteURL = (url) => {
|
|
45
51
|
const match = url.match(URL_REGEXP);
|
|
46
52
|
if (match) {
|
|
47
53
|
return true;
|
|
48
54
|
}
|
|
49
55
|
return false;
|
|
50
56
|
};
|
|
51
|
-
|
|
57
|
+
exports.isAbsoluteURL = isAbsoluteURL;
|
|
58
|
+
const mergePath = (...paths) => {
|
|
52
59
|
let p = '';
|
|
53
60
|
let endsWithSlash = false;
|
|
54
61
|
for (let path of paths) {
|
|
@@ -75,3 +82,4 @@ export const mergePath = (...paths) => {
|
|
|
75
82
|
}
|
|
76
83
|
return p;
|
|
77
84
|
};
|
|
85
|
+
exports.mergePath = mergePath;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.6",
|
|
4
4
|
"description": "Ultrafast web framework for Cloudflare Workers.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"test": "jest",
|
|
12
12
|
"lint": "eslint --ext js,ts src .eslintrc.js",
|
|
13
13
|
"lint:fix": "eslint --ext js,ts src .eslintrc.js --fix",
|
|
14
|
-
"build": "rimraf dist && tsc --project tsconfig.build.json && tsc --project tsconfig.build.
|
|
14
|
+
"build": "rimraf dist && tsc --project tsconfig.build.esm.json && tsc --project tsconfig.build.json",
|
|
15
15
|
"watch": "tsc --project tsconfig.build.json -w",
|
|
16
16
|
"prepublishOnly": "yarn build"
|
|
17
17
|
},
|