hono 1.4.5 → 1.5.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 +31 -17
- package/dist/compose.js +1 -1
- package/dist/context.d.ts +3 -2
- package/dist/hono.d.ts +1 -1
- package/dist/middleware/html/index.d.ts +5 -0
- package/dist/middleware/html/index.js +32 -0
- package/dist/middleware/jsx/index.d.ts +16 -0
- package/dist/middleware/jsx/index.js +82 -0
- package/dist/middleware/mustache/module.d.mts +1 -1
- package/dist/middleware/mustache/mustache.d.ts +3 -2
- package/dist/router/reg-exp-router/router.d.ts +0 -1
- package/dist/router/reg-exp-router/router.js +1 -6
- package/dist/router/trie-router/node.js +1 -11
- package/dist/utils/crypto.d.ts +1 -0
- package/dist/utils/crypto.js +7 -1
- package/dist/utils/html.d.ts +4 -0
- package/dist/utils/html.js +15 -0
- package/package.json +9 -1
package/README.md
CHANGED
|
@@ -73,6 +73,8 @@ Built-in middleware make _"**Write Less, do more**"_ in reality. You can use a l
|
|
|
73
73
|
- [CORS](https://github.com/honojs/hono/tree/master/src/middleware/cors/)
|
|
74
74
|
- [ETag](https://github.com/honojs/hono/tree/master/src/middleware/etag/)
|
|
75
75
|
- [GraphQL Server](https://github.com/honojs/hono/tree/master/src/middleware/graphql-server/)
|
|
76
|
+
- [html](https://github.com/honojs/hono/tree/master/src/middleware/html/)
|
|
77
|
+
- [JSX](https://github.com/honojs/hono/tree/master/src/middleware/jsx/)
|
|
76
78
|
- [JWT Authentication](https://github.com/honojs/hono/tree/master/src/middleware/jwt/)
|
|
77
79
|
- [Logger](https://github.com/honojs/hono/tree/master/src/middleware/logger/)
|
|
78
80
|
- [Mustache template engine](https://github.com/honojs/hono/tree/master/src/middleware/mustache/) (Only for Cloudflare Workers)
|
|
@@ -495,6 +497,8 @@ app.get('/foo', async (c) => {
|
|
|
495
497
|
|
|
496
498
|
### c.env
|
|
497
499
|
|
|
500
|
+
Environment variables, secrets, and KV namespaces are known as bindings. Regardless of type, bindings are always available as global variables and can be accessed via the context `c.env.BINDING_KEY`.
|
|
501
|
+
|
|
498
502
|
```ts
|
|
499
503
|
// Environment object for Cloudflare Workers
|
|
500
504
|
app.get('*', async c => {
|
|
@@ -552,9 +556,9 @@ import { RegExpRouter } from 'hono/router/reg-exp-router'
|
|
|
552
556
|
const app = new Hono({ router: new RegExpRouter() })
|
|
553
557
|
```
|
|
554
558
|
|
|
555
|
-
## Routing
|
|
559
|
+
## Routing priority
|
|
556
560
|
|
|
557
|
-
|
|
561
|
+
Handlers or middleware will be executed in registration order.
|
|
558
562
|
|
|
559
563
|
```ts
|
|
560
564
|
app.get('/book/a', (c) => c.text('a')) // a
|
|
@@ -562,27 +566,37 @@ app.get('/book/:slug', (c) => c.text('common')) // common
|
|
|
562
566
|
```
|
|
563
567
|
|
|
564
568
|
```http
|
|
565
|
-
GET /book/a ---> `a`
|
|
566
|
-
GET /book/b ---> `common`
|
|
569
|
+
GET /book/a ---> `a`
|
|
570
|
+
GET /book/b ---> `common`
|
|
567
571
|
```
|
|
568
572
|
|
|
569
|
-
|
|
573
|
+
When a handler is executed, the process will be stopped.
|
|
570
574
|
|
|
571
575
|
```ts
|
|
572
|
-
app.get('
|
|
573
|
-
app.get('/
|
|
574
|
-
app.get('/api/posts/:id', 'e') // score 3.3
|
|
575
|
-
app.get('/api/posts/123', 'f') // score 3.4
|
|
576
|
-
app.get('/*/*/:id', 'g') // score 3.5
|
|
577
|
-
app.get('/api/posts/*/comment', 'h') // score 4.6 - not match
|
|
578
|
-
app.get('*', 'a') // score 0.7
|
|
579
|
-
app.get('*', 'b') // score 0.8
|
|
576
|
+
app.get('*', (c) => c.text('common')) // common
|
|
577
|
+
app.get('/foo', (c) => c.text('foo')) // foo
|
|
580
578
|
```
|
|
581
579
|
|
|
582
|
-
```
|
|
583
|
-
GET /
|
|
584
|
-
|
|
585
|
-
|
|
580
|
+
```http
|
|
581
|
+
GET /foo ---> `common` // foo will not be dispatched
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
If you have the middleware that you want to execute, write the code above the handler.
|
|
585
|
+
|
|
586
|
+
```ts
|
|
587
|
+
app.use('*', logger())
|
|
588
|
+
app.get('/foo', (c) => c.text('foo'))
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
If you want a "_fallback_" handler, write the code below the other handler.
|
|
592
|
+
|
|
593
|
+
```ts
|
|
594
|
+
app.get('/foo', (c) => c.text('foo')) // foo
|
|
595
|
+
app.get('*', (c) => c.text('fallback')) // fallback
|
|
596
|
+
```
|
|
597
|
+
|
|
598
|
+
```http
|
|
599
|
+
GET /bar ---> `fallback`
|
|
586
600
|
```
|
|
587
601
|
|
|
588
602
|
## Cloudflare Workers with Hono
|
package/dist/compose.js
CHANGED
|
@@ -17,7 +17,7 @@ const compose = (middleware, onError, onNotFound) => {
|
|
|
17
17
|
handler = next;
|
|
18
18
|
if (!handler) {
|
|
19
19
|
if (context instanceof context_1.Context && context.finalized === false && onNotFound) {
|
|
20
|
-
context.res = onNotFound(context);
|
|
20
|
+
context.res = await onNotFound(context);
|
|
21
21
|
}
|
|
22
22
|
return Promise.resolve(context);
|
|
23
23
|
}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
+
import type { NotFoundHandler } from './hono';
|
|
2
3
|
import type { StatusCode } from './utils/http-status';
|
|
3
4
|
declare type Headers = Record<string, string>;
|
|
4
5
|
export declare type Data = string | ArrayBuffer | ReadableStream;
|
|
@@ -15,8 +16,8 @@ export declare class Context<RequestParamKeyType extends string = string, E = En
|
|
|
15
16
|
private _headers;
|
|
16
17
|
private _res;
|
|
17
18
|
private notFoundHandler;
|
|
18
|
-
render: (
|
|
19
|
-
constructor(req: Request<RequestParamKeyType>, env?: E | undefined, event?: FetchEvent | undefined, notFoundHandler?:
|
|
19
|
+
render: (content: string, params?: object, options?: object) => Response | Promise<Response>;
|
|
20
|
+
constructor(req: Request<RequestParamKeyType>, env?: E | undefined, event?: FetchEvent | undefined, notFoundHandler?: NotFoundHandler);
|
|
20
21
|
get res(): Response;
|
|
21
22
|
set res(_res: Response);
|
|
22
23
|
header(name: string, value: string): void;
|
package/dist/hono.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Context } from './context';
|
|
|
3
3
|
import type { Env } from './context';
|
|
4
4
|
import type { Router } from './router';
|
|
5
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>;
|
|
6
|
-
export declare type NotFoundHandler<E = Env> = (c: Context<string, E>) => Response
|
|
6
|
+
export declare type NotFoundHandler<E = Env> = (c: Context<string, E>) => Response | Promise<Response>;
|
|
7
7
|
export declare type ErrorHandler<E = Env> = (err: Error, c: Context<string, E>) => Response;
|
|
8
8
|
export declare type Next = () => Promise<void>;
|
|
9
9
|
declare type ParamKeyName<NameWithPattern> = NameWithPattern extends `${infer Name}{${infer _Pattern}` ? Name : NameWithPattern;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.html = exports.raw = void 0;
|
|
4
|
+
const html_1 = require("../../utils/html");
|
|
5
|
+
const raw = (value) => {
|
|
6
|
+
const escapedString = new String(value);
|
|
7
|
+
escapedString.isEscaped = true;
|
|
8
|
+
return escapedString;
|
|
9
|
+
};
|
|
10
|
+
exports.raw = raw;
|
|
11
|
+
const html = (strings, ...values) => {
|
|
12
|
+
let result = '';
|
|
13
|
+
for (let i = 0, len = strings.length - 1; i < len; i++) {
|
|
14
|
+
result += strings[i];
|
|
15
|
+
const children = values[i] instanceof Array ? values[i].flat(Infinity) : [values[i]];
|
|
16
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
17
|
+
const child = children[i];
|
|
18
|
+
if (typeof child === 'boolean' || child === null || child === undefined) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
else if (typeof child === 'object' && child.isEscaped) {
|
|
22
|
+
result += child;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
result += (0, html_1.escape)(child.toString());
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
result += strings[strings.length - 1];
|
|
30
|
+
return (0, exports.raw)(result);
|
|
31
|
+
};
|
|
32
|
+
exports.html = html;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { HtmlEscapedString } from '../../utils/html';
|
|
2
|
+
declare global {
|
|
3
|
+
namespace jsx.JSX {
|
|
4
|
+
interface IntrinsicElements {
|
|
5
|
+
[tagName: string]: Record<string, any>;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export declare const jsx: (tag: string | Function, props: Record<string, any>, ...children: (string | HtmlEscapedString)[]) => HtmlEscapedString;
|
|
10
|
+
declare type FC<T = Record<string, any>> = (props: T) => HtmlEscapedString;
|
|
11
|
+
export declare const memo: <T>(component: FC<T>, propsAreEqual?: (prevProps: Readonly<T>, nextProps: Readonly<T>) => boolean) => FC<T>;
|
|
12
|
+
export declare const Fragment: (props: {
|
|
13
|
+
key?: string;
|
|
14
|
+
children?: any;
|
|
15
|
+
}) => HtmlEscapedString;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Fragment = exports.memo = exports.jsx = void 0;
|
|
4
|
+
const html_1 = require("../../utils/html");
|
|
5
|
+
const jsx = (tag, props, ...children) => {
|
|
6
|
+
if (typeof tag === 'function') {
|
|
7
|
+
return tag.call(null, { ...props, children: children.length <= 1 ? children[0] : children });
|
|
8
|
+
}
|
|
9
|
+
let result = tag !== '' ? `<${tag}` : '';
|
|
10
|
+
const propsKeys = Object.keys(props || {});
|
|
11
|
+
for (let i = 0, len = propsKeys.length; i < len; i++) {
|
|
12
|
+
const v = props[propsKeys[i]];
|
|
13
|
+
if (propsKeys[i] === 'dangerouslySetInnerHTML') {
|
|
14
|
+
if (children.length > 0) {
|
|
15
|
+
throw 'Can only set one of `children` or `props.dangerouslySetInnerHTML`.';
|
|
16
|
+
}
|
|
17
|
+
const escapedString = new String(v.__html);
|
|
18
|
+
escapedString.isEscaped = true;
|
|
19
|
+
children = [escapedString];
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
else if (v === null || v === undefined) {
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
result += ` ${propsKeys[i]}="${(0, html_1.escape)(v.toString())}"`;
|
|
26
|
+
}
|
|
27
|
+
if (tag !== '') {
|
|
28
|
+
result += '>';
|
|
29
|
+
}
|
|
30
|
+
const flattenChildren = children.flat(Infinity);
|
|
31
|
+
for (let i = 0, len = flattenChildren.length; i < len; i++) {
|
|
32
|
+
const child = flattenChildren[i];
|
|
33
|
+
if (typeof child === 'boolean' || child === null || child === undefined) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
else if (typeof child === 'object' && child.isEscaped) {
|
|
37
|
+
result += child;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
result += (0, html_1.escape)(child.toString());
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (tag !== '') {
|
|
44
|
+
result += `</${tag}>`;
|
|
45
|
+
}
|
|
46
|
+
const escapedString = new String(result);
|
|
47
|
+
escapedString.isEscaped = true;
|
|
48
|
+
return escapedString;
|
|
49
|
+
};
|
|
50
|
+
exports.jsx = jsx;
|
|
51
|
+
const shallowEqual = (a, b) => {
|
|
52
|
+
if (a === b) {
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
const aKeys = Object.keys(a);
|
|
56
|
+
const bKeys = Object.keys(b);
|
|
57
|
+
if (aKeys.length !== bKeys.length) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
for (let i = 0, len = aKeys.length; i < len; i++) {
|
|
61
|
+
if (a[aKeys[i]] !== b[aKeys[i]]) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return true;
|
|
66
|
+
};
|
|
67
|
+
const memo = (component, propsAreEqual = shallowEqual) => {
|
|
68
|
+
let computed = undefined;
|
|
69
|
+
let prevProps = undefined;
|
|
70
|
+
return ((props) => {
|
|
71
|
+
if (prevProps && !propsAreEqual(prevProps, props)) {
|
|
72
|
+
computed = undefined;
|
|
73
|
+
}
|
|
74
|
+
prevProps = props;
|
|
75
|
+
return (computed || (computed = component(props)));
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
exports.memo = memo;
|
|
79
|
+
const Fragment = (props) => {
|
|
80
|
+
return (0, exports.jsx)('', {}, ...(props.children || []));
|
|
81
|
+
};
|
|
82
|
+
exports.Fragment = Fragment;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { MustacheOptions } from './mustache';
|
|
2
|
-
declare const module: (options?: MustacheOptions) => import("../../
|
|
2
|
+
declare const module: (options?: MustacheOptions) => (c: import("../../context").Context<string, import("../../context").Env>, next: import("../../hono").Next) => Promise<void>;
|
|
3
3
|
export { module as mustache };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/// <reference types="@cloudflare/workers-types" />
|
|
2
|
-
import type {
|
|
2
|
+
import type { Context } from '../../context';
|
|
3
|
+
import type { Next } from '../../hono';
|
|
3
4
|
export declare type MustacheOptions = {
|
|
4
5
|
root: string;
|
|
5
6
|
manifest?: object | string;
|
|
6
7
|
namespace?: KVNamespace;
|
|
7
8
|
};
|
|
8
|
-
export declare const mustache: (init?: MustacheOptions) =>
|
|
9
|
+
export declare const mustache: (init?: MustacheOptions) => (c: Context, next: Next) => Promise<void>;
|
|
@@ -65,9 +65,7 @@ function compareRoute(a, b) {
|
|
|
65
65
|
return i === b.hint.regExpComponents.length || a.hint.endWithWildcard ? 1 : 0;
|
|
66
66
|
}
|
|
67
67
|
function compareHandler(a, b) {
|
|
68
|
-
return a.
|
|
69
|
-
? a.componentsLength - b.componentsLength
|
|
70
|
-
: a.index - b.index;
|
|
68
|
+
return a.index - b.index;
|
|
71
69
|
}
|
|
72
70
|
function getSortedHandlers(handlers) {
|
|
73
71
|
return [...handlers].sort(compareHandler).map((h) => h.handler);
|
|
@@ -158,7 +156,6 @@ class RegExpRouter {
|
|
|
158
156
|
const handlerWithSortIndex = {
|
|
159
157
|
index,
|
|
160
158
|
handler,
|
|
161
|
-
componentsLength: hint.components.length || 1,
|
|
162
159
|
};
|
|
163
160
|
for (let i = 0, len = routes.length; i < len; i++) {
|
|
164
161
|
if (routes[i].method === method && routes[i].path === path) {
|
|
@@ -318,9 +315,7 @@ class RegExpRouter {
|
|
|
318
315
|
}
|
|
319
316
|
}
|
|
320
317
|
if (routes[j].hint.components.length < routes[i].hint.components.length) {
|
|
321
|
-
const componentsLength = routes[j].hint.components.length || 1;
|
|
322
318
|
routes[j].middleware.push(...routes[i].handlers.map((h) => ({
|
|
323
|
-
componentsLength,
|
|
324
319
|
index: h.index,
|
|
325
320
|
handler: h.handler,
|
|
326
321
|
})));
|
|
@@ -66,18 +66,11 @@ class Node {
|
|
|
66
66
|
parentPatterns.push(...curNode.patterns);
|
|
67
67
|
curNode = curNode.children[p];
|
|
68
68
|
}
|
|
69
|
-
let score = 1;
|
|
70
|
-
if (path === '*') {
|
|
71
|
-
score = score + this.order * 0.01;
|
|
72
|
-
}
|
|
73
|
-
else {
|
|
74
|
-
score = parts.length + this.order * 0.01;
|
|
75
|
-
}
|
|
76
69
|
if (!curNode.methods.length) {
|
|
77
70
|
curNode.methods = [];
|
|
78
71
|
}
|
|
79
72
|
const m = {};
|
|
80
|
-
const handlerSet = { handler: handler, name: this.name, score:
|
|
73
|
+
const handlerSet = { handler: handler, name: this.name, score: this.order };
|
|
81
74
|
m[method] = handlerSet;
|
|
82
75
|
curNode.methods.push(m);
|
|
83
76
|
return curNode;
|
|
@@ -90,9 +83,6 @@ class Node {
|
|
|
90
83
|
const handlerSet = m[method] || m[router_1.METHOD_NAME_ALL];
|
|
91
84
|
if (handlerSet !== undefined) {
|
|
92
85
|
const hs = { ...handlerSet };
|
|
93
|
-
if (wildcard) {
|
|
94
|
-
hs.score = handlerSet.score - 1;
|
|
95
|
-
}
|
|
96
86
|
handlerSets.push(hs);
|
|
97
87
|
return;
|
|
98
88
|
}
|
package/dist/utils/crypto.d.ts
CHANGED
|
@@ -5,5 +5,6 @@ declare type Algorithm = {
|
|
|
5
5
|
declare type Data = string | object | boolean;
|
|
6
6
|
export declare const sha256: (data: Data) => Promise<string | null>;
|
|
7
7
|
export declare const sha1: (data: Data) => Promise<string | null>;
|
|
8
|
+
export declare const md5: (data: Data) => Promise<string | null>;
|
|
8
9
|
export declare const createHash: (data: Data, algorithm: Algorithm) => Promise<string | null>;
|
|
9
10
|
export {};
|
package/dist/utils/crypto.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createHash = exports.sha1 = exports.sha256 = void 0;
|
|
3
|
+
exports.createHash = exports.md5 = exports.sha1 = exports.sha256 = void 0;
|
|
4
4
|
const sha256 = async (data) => {
|
|
5
5
|
const algorithm = { name: 'SHA-256', alias: 'sha256' };
|
|
6
6
|
const hash = await (0, exports.createHash)(data, algorithm);
|
|
@@ -13,6 +13,12 @@ const sha1 = async (data) => {
|
|
|
13
13
|
return hash;
|
|
14
14
|
};
|
|
15
15
|
exports.sha1 = sha1;
|
|
16
|
+
const md5 = async (data) => {
|
|
17
|
+
const algorithm = { name: 'MD5', alias: 'md5' };
|
|
18
|
+
const hash = await (0, exports.createHash)(data, algorithm);
|
|
19
|
+
return hash;
|
|
20
|
+
};
|
|
21
|
+
exports.md5 = md5;
|
|
16
22
|
const createHash = async (data, algorithm) => {
|
|
17
23
|
if (crypto && crypto.subtle) {
|
|
18
24
|
const buffer = await crypto.subtle.digest({
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.escape = void 0;
|
|
4
|
+
const entityMap = {
|
|
5
|
+
'&': '&',
|
|
6
|
+
'<': '<',
|
|
7
|
+
'>': '>',
|
|
8
|
+
'"': '"',
|
|
9
|
+
};
|
|
10
|
+
const escapeRe = new RegExp(`[${Object.keys(entityMap).join('')}]`, 'g');
|
|
11
|
+
const replaceFn = (m) => entityMap[m];
|
|
12
|
+
const escape = (str) => {
|
|
13
|
+
return str.replace(escapeRe, replaceFn);
|
|
14
|
+
};
|
|
15
|
+
exports.escape = escape;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hono",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Ultrafast web framework for Cloudflare Workers.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
"./cors": "./dist/middleware/cors/index.js",
|
|
25
25
|
"./etag": "./dist/middleware/etag/index.js",
|
|
26
26
|
"./graphql-server": "./dist/middleware/graphql-server/index.js",
|
|
27
|
+
"./html": "./dist/middleware/html/index.js",
|
|
28
|
+
"./jsx": "./dist/middleware/jsx/index.js",
|
|
27
29
|
"./jwt": "./dist/middleware/jwt/index.js",
|
|
28
30
|
"./logger": "./dist/middleware/logger/index.js",
|
|
29
31
|
"./mustache": "./dist/middleware/mustache/index.js",
|
|
@@ -60,6 +62,12 @@
|
|
|
60
62
|
"graphql-server": [
|
|
61
63
|
"./dist/middleware/graphql-server"
|
|
62
64
|
],
|
|
65
|
+
"html": [
|
|
66
|
+
"./dist/middleware/html"
|
|
67
|
+
],
|
|
68
|
+
"jsx": [
|
|
69
|
+
"./dist/middleware/jsx"
|
|
70
|
+
],
|
|
63
71
|
"jwt": [
|
|
64
72
|
"./dist/middleware/jwt"
|
|
65
73
|
],
|