hono 0.0.10 → 0.0.11

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 CHANGED
@@ -16,19 +16,21 @@ app.fire()
16
16
  ## Feature
17
17
 
18
18
  - Fast - the router is implemented with Trie-Tree structure.
19
- - Tiny - use only standard API.
20
19
  - Portable - zero dependencies.
21
20
  - Flexible - you can make your own middlewares.
22
- - Optimized - for Cloudflare Workers and Fastly Compute@Edge.
21
+ - Easy - simple API, builtin middleware, and TypeScript support.
22
+ - Optimized - for Cloudflare Workers or Fastly Compute@Edge.
23
23
 
24
24
  ## Benchmark
25
25
 
26
+ Hono is fastest!!
27
+
26
28
  ```
27
- hono x 813,001 ops/sec ±2.96% (75 runs sampled)
28
- itty-router x 160,415 ops/sec ±3.31% (85 runs sampled)
29
- sunder x 307,438 ops/sec ±4.77% (73 runs sampled)
29
+ hono x 758,264 ops/sec ±5.41% (75 runs sampled)
30
+ itty-router x 158,359 ops/sec ±3.21% (89 runs sampled)
31
+ sunder x 297,581 ops/sec ±4.74% (83 runs sampled)
30
32
  Fastest is hono
31
- ✨ Done in 37.03s.
33
+ ✨ Done in 42.84s.
32
34
  ```
33
35
 
34
36
  ## Install
@@ -45,8 +47,8 @@ $ npm install hono
45
47
 
46
48
  ## Methods
47
49
 
48
- - app.**HTTP_METHOD**(path, callback)
49
- - app.**all**(path, callback)
50
+ - app.**HTTP_METHOD**(path, handler)
51
+ - app.**all**(path, handler)
50
52
  - app.**route**(path)
51
53
  - app.**use**(path, middleware)
52
54
 
@@ -120,25 +122,25 @@ const { Hono, Middleware } = require('hono')
120
122
 
121
123
  ...
122
124
 
123
- app.use('*', Middleware.poweredBy)
125
+ app.use('*', Middleware.poweredBy())
126
+ app.use('*', Middleware.logger())
124
127
 
125
128
  ```
126
129
 
127
130
  ### Custom Middleware
128
131
 
129
132
  ```js
130
- const logger = async (c, next) => {
133
+ // Custom logger
134
+ app.use('*', async (c, next) => {
131
135
  console.log(`[${c.req.method}] ${c.req.url}`)
132
136
  await next()
133
- }
137
+ })
134
138
 
135
- const addHeader = async (c, next) => {
139
+ // Add custom header
140
+ app.use('/message/*', async (c, next) => {
136
141
  await next()
137
142
  await c.res.headers.add('x-message', 'This is middleware!')
138
- }
139
-
140
- app.use('*', logger)
141
- app.use('/message/*', addHeader)
143
+ })
142
144
 
143
145
  app.get('/message/hello', () => 'Hello Middleware!')
144
146
  ```
@@ -146,20 +148,18 @@ app.get('/message/hello', () => 'Hello Middleware!')
146
148
  ### Custom 404 Response
147
149
 
148
150
  ```js
149
- const customNotFound = async (c, next) => {
151
+ app.use('*', async (c, next) => {
150
152
  await next()
151
153
  if (c.res.status === 404) {
152
154
  c.res = new Response('Custom 404 Not Found', { status: 404 })
153
155
  }
154
- }
155
-
156
- app.use('*', customNotFound)
156
+ })
157
157
  ```
158
158
 
159
159
  ### Complex Pattern
160
160
 
161
161
  ```js
162
- // Log response time
162
+ // Output response time
163
163
  app.use('*', async (c, next) => {
164
164
  await next()
165
165
  const responseTime = await c.res.headers.get('X-Response-Time')
@@ -180,38 +180,41 @@ app.use('*', async (c, next) => {
180
180
  ### req
181
181
 
182
182
  ```js
183
+
184
+ // Get Request object
183
185
  app.get('/hello', (c) => {
184
186
  const userAgent = c.req.headers.get('User-Agent')
185
187
  ...
186
188
  })
189
+
190
+ // Query params
191
+ app.get('/search', (c) => {
192
+ const query = c.req.query('q')
193
+ ...
194
+ })
195
+
196
+ // Captured params
197
+ app.get('/entry/:id', (c) => {
198
+ const id = c.req.params('id')
199
+ ...
200
+ })
187
201
  ```
188
202
 
189
203
  ### res
190
204
 
191
205
  ```js
206
+ // Response object
192
207
  app.use('/', (c, next) => {
193
208
  next()
194
209
  c.res.headers.append('X-Debug', 'Debug message')
195
210
  })
196
211
  ```
197
212
 
198
- ## Request
199
-
200
- ### query
213
+ ### text
201
214
 
202
215
  ```js
203
- app.get('/search', (c) => {
204
- const query = c.req.query('q')
205
- ...
206
- })
207
- ```
208
-
209
- ### params
210
-
211
- ```js
212
- app.get('/entry/:id', (c) => {
213
- const id = c.req.params('id')
214
- ...
216
+ app.get('/say', (c) => {
217
+ return c.text('Hello!')
215
218
  })
216
219
  ```
217
220
 
@@ -219,7 +222,7 @@ app.get('/entry/:id', (c) => {
219
222
 
220
223
  Create your first Cloudflare Workers with Hono from scratch.
221
224
 
222
- ### Demo
225
+ ### How to setup
223
226
 
224
227
  ![Demo](https://user-images.githubusercontent.com/10682/147877447-ff5907cd-49be-4976-b3b4-5df2ac6dfda4.gif)
225
228
 
@@ -0,0 +1 @@
1
+ export declare const compose: (middleware: any) => (context: any, next?: Function) => any;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compose = void 0;
4
+ // Based on the code in the MIT licensed `koa-compose` package.
5
+ const compose = (middleware) => {
6
+ return function (context, next) {
7
+ let index = -1;
8
+ return dispatch(0);
9
+ function dispatch(i) {
10
+ if (i <= index)
11
+ return Promise.reject(new Error('next() called multiple times'));
12
+ index = i;
13
+ let fn = middleware[i];
14
+ if (i === middleware.length)
15
+ fn = next;
16
+ if (!fn)
17
+ return Promise.resolve();
18
+ try {
19
+ return Promise.resolve(fn(context, dispatch.bind(null, i + 1)));
20
+ }
21
+ catch (err) {
22
+ return Promise.reject(err);
23
+ }
24
+ }
25
+ };
26
+ };
27
+ exports.compose = compose;
package/dist/hono.d.ts ADDED
@@ -0,0 +1,47 @@
1
+ /// <reference types="@cloudflare/workers-types" />
2
+ import { Node, Result } from './node';
3
+ import { Middleware } from './middleware';
4
+ export { Middleware };
5
+ declare global {
6
+ interface Request {
7
+ params: (key: string) => any;
8
+ query: (key: string) => string | null;
9
+ }
10
+ }
11
+ export declare class Context {
12
+ req: Request;
13
+ res: Response;
14
+ constructor(req: Request, res: Response);
15
+ newResponse(body?: BodyInit | null | undefined, init?: ResponseInit | undefined): Response;
16
+ text(body: string): Response;
17
+ }
18
+ declare type Handler = (c: Context, next?: Function) => Response | Promise<Response>;
19
+ declare type MiddlwareHandler = (c: Context, next: Function) => Promise<void>;
20
+ export declare class Router<T> {
21
+ node: Node<T>;
22
+ constructor();
23
+ add(method: string, path: string, handler: T): void;
24
+ match(method: string, path: string): Result<T> | null;
25
+ }
26
+ export declare class Hono {
27
+ router: Router<Handler[]>;
28
+ middlewareRouters: Router<MiddlwareHandler>[];
29
+ tempPath: string;
30
+ constructor();
31
+ get(arg: string | Handler, ...args: Handler[]): Hono;
32
+ post(arg: string | Handler, ...args: Handler[]): Hono;
33
+ put(arg: string | Handler, ...args: Handler[]): Hono;
34
+ head(arg: string | Handler, ...args: Handler[]): Hono;
35
+ delete(arg: string | Handler, ...args: Handler[]): Hono;
36
+ options(arg: string | Handler, ...args: Handler[]): Hono;
37
+ patch(arg: string | Handler, ...args: Handler[]): Hono;
38
+ all(arg: string | Handler, ...args: Handler[]): Hono;
39
+ route(path: string): Hono;
40
+ use(path: string, middleware: MiddlwareHandler): void;
41
+ addRoute(method: string, arg: string | Handler, ...args: Handler[]): Hono;
42
+ matchRoute(method: string, path: string): Promise<Result<Handler[]>>;
43
+ dispatch(request: Request, response?: Response): Promise<Response>;
44
+ handleEvent(event: FetchEvent): Promise<Response>;
45
+ fire(): void;
46
+ notFound(): Response;
47
+ }
package/dist/hono.js ADDED
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Hono = exports.Router = exports.Context = exports.Middleware = void 0;
4
+ const node_1 = require("./node");
5
+ const compose_1 = require("./compose");
6
+ const util_1 = require("./util");
7
+ const middleware_1 = require("./middleware");
8
+ Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return middleware_1.Middleware; } });
9
+ const METHOD_NAME_OF_ALL = 'ALL';
10
+ class Context {
11
+ constructor(req, res) {
12
+ this.req = req;
13
+ this.res = res;
14
+ }
15
+ newResponse(body, init) {
16
+ return new Response(body, init);
17
+ }
18
+ text(body) {
19
+ return this.newResponse(body, {
20
+ status: 200,
21
+ headers: {
22
+ 'Content-Type': 'text/plain',
23
+ },
24
+ });
25
+ }
26
+ }
27
+ exports.Context = Context;
28
+ class Router {
29
+ constructor() {
30
+ this.node = new node_1.Node();
31
+ }
32
+ add(method, path, handler) {
33
+ this.node.insert(method, path, handler);
34
+ }
35
+ match(method, path) {
36
+ return this.node.search(method, path);
37
+ }
38
+ }
39
+ exports.Router = Router;
40
+ class Hono {
41
+ constructor() {
42
+ this.router = new Router();
43
+ this.middlewareRouters = [];
44
+ this.tempPath = '/';
45
+ }
46
+ /* HTTP METHODS */
47
+ get(arg, ...args) {
48
+ return this.addRoute('get', arg, ...args);
49
+ }
50
+ post(arg, ...args) {
51
+ return this.addRoute('post', arg, ...args);
52
+ }
53
+ put(arg, ...args) {
54
+ return this.addRoute('put', arg, ...args);
55
+ }
56
+ head(arg, ...args) {
57
+ return this.addRoute('head', arg, ...args);
58
+ }
59
+ delete(arg, ...args) {
60
+ return this.addRoute('delete', arg, ...args);
61
+ }
62
+ options(arg, ...args) {
63
+ return this.addRoute('options', arg, ...args);
64
+ }
65
+ patch(arg, ...args) {
66
+ return this.addRoute('patch', arg, ...args);
67
+ }
68
+ /*
69
+ trace
70
+ copy
71
+ lock
72
+ purge
73
+ unlock
74
+ report
75
+ checkout
76
+ merge
77
+ notify
78
+ subscribe
79
+ unsubscribe
80
+ search
81
+ connect
82
+ */
83
+ all(arg, ...args) {
84
+ return this.addRoute('all', arg, ...args);
85
+ }
86
+ route(path) {
87
+ this.tempPath = path;
88
+ return this;
89
+ }
90
+ use(path, middleware) {
91
+ if (middleware.constructor.name !== 'AsyncFunction') {
92
+ throw new TypeError('middleware must be a async function!');
93
+ }
94
+ const router = new Router();
95
+ router.add(METHOD_NAME_OF_ALL, path, middleware);
96
+ this.middlewareRouters.push(router);
97
+ }
98
+ // addRoute('get', '/', handler)
99
+ addRoute(method, arg, ...args) {
100
+ method = method.toUpperCase();
101
+ if (typeof arg === 'string') {
102
+ this.router.add(method, arg, args);
103
+ }
104
+ else {
105
+ args.unshift(arg);
106
+ this.router.add(method, this.tempPath, args);
107
+ }
108
+ return this;
109
+ }
110
+ async matchRoute(method, path) {
111
+ return this.router.match(method, path);
112
+ }
113
+ async dispatch(request, response) {
114
+ const [method, path] = [request.method, (0, util_1.getPathFromURL)(request.url)];
115
+ const result = await this.matchRoute(method, path);
116
+ request.params = (key) => {
117
+ if (result) {
118
+ return result.params[key];
119
+ }
120
+ return '';
121
+ };
122
+ let handler = result ? result.handler[0] : this.notFound; // XXX
123
+ const middleware = [];
124
+ for (const mr of this.middlewareRouters) {
125
+ const mwResult = mr.match(METHOD_NAME_OF_ALL, path);
126
+ if (mwResult) {
127
+ middleware.push(mwResult.handler);
128
+ }
129
+ }
130
+ let wrappedHandler = async (context, next) => {
131
+ context.res = await handler(context);
132
+ await next();
133
+ };
134
+ middleware.push(middleware_1.Middleware.defaultFilter);
135
+ middleware.push(wrappedHandler);
136
+ const composed = (0, compose_1.compose)(middleware);
137
+ const c = new Context(request, response);
138
+ await composed(c);
139
+ return c.res;
140
+ }
141
+ async handleEvent(event) {
142
+ return this.dispatch(event.request);
143
+ }
144
+ fire() {
145
+ addEventListener('fetch', (event) => {
146
+ event.respondWith(this.handleEvent(event));
147
+ });
148
+ }
149
+ notFound() {
150
+ return new Response('Not Found', { status: 404 });
151
+ }
152
+ }
153
+ exports.Hono = Hono;
@@ -0,0 +1 @@
1
+ export { Hono, Middleware, Context } from './hono';
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Context = exports.Middleware = exports.Hono = void 0;
4
+ var hono_1 = require("./hono");
5
+ Object.defineProperty(exports, "Hono", { enumerable: true, get: function () { return hono_1.Hono; } });
6
+ Object.defineProperty(exports, "Middleware", { enumerable: true, get: function () { return hono_1.Middleware; } });
7
+ Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return hono_1.Context; } });
@@ -0,0 +1 @@
1
+ export declare const methods: string[];
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.methods = void 0;
4
+ exports.methods = [
5
+ 'get',
6
+ 'post',
7
+ 'put',
8
+ 'head',
9
+ 'delete',
10
+ 'options',
11
+ 'trace',
12
+ 'copy',
13
+ 'lock',
14
+ 'mkcol',
15
+ 'move',
16
+ 'patch',
17
+ 'purge',
18
+ 'propfind',
19
+ 'proppatch',
20
+ 'unlock',
21
+ 'report',
22
+ 'mkactivity',
23
+ 'checkout',
24
+ 'merge',
25
+ 'm-search',
26
+ 'notify',
27
+ 'subscribe',
28
+ 'unsubscribe',
29
+ 'search',
30
+ 'connect',
31
+ ];
@@ -0,0 +1,2 @@
1
+ import { Context } from '../hono';
2
+ export declare const defaultFilter: (c: Context, next: Function) => Promise<void>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.defaultFilter = void 0;
4
+ const defaultFilter = async (c, next) => {
5
+ c.req.query = (key) => {
6
+ const url = new URL(c.req.url);
7
+ return url.searchParams.get(key);
8
+ };
9
+ await next();
10
+ };
11
+ exports.defaultFilter = defaultFilter;
@@ -0,0 +1,5 @@
1
+ import { Context } from '../../hono';
2
+ export declare const logger: (fn?: {
3
+ (...data: any[]): void;
4
+ (...data: any[]): void;
5
+ }) => (c: Context, next: Function) => Promise<void>;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logger = void 0;
4
+ const util_1 = require("../../util");
5
+ const humanize = (n, opts) => {
6
+ const options = opts || {};
7
+ const d = options.delimiter || ',';
8
+ const s = options.separator || '.';
9
+ n = n.toString().split('.');
10
+ n[0] = n[0].replace(/(\d)(?=(\d\d\d)+(?!\d))/g, '$1' + d);
11
+ return n.join(s);
12
+ };
13
+ const time = (start) => {
14
+ const delta = Date.now() - start;
15
+ return humanize([delta < 10000 ? delta + 'ms' : Math.round(delta / 1000) + 's']);
16
+ };
17
+ const LogPrefix = {
18
+ Outgoing: '-->',
19
+ Incoming: '<--',
20
+ Error: 'xxx',
21
+ };
22
+ const colorStatus = (status = 0) => {
23
+ const out = {
24
+ 7: `\x1b[35m${status}\x1b[0m`,
25
+ 5: `\x1b[31m${status}\x1b[0m`,
26
+ 4: `\x1b[33m${status}\x1b[0m`,
27
+ 3: `\x1b[36m${status}\x1b[0m`,
28
+ 2: `\x1b[32m${status}\x1b[0m`,
29
+ 1: `\x1b[32m${status}\x1b[0m`,
30
+ 0: `\x1b[33m${status}\x1b[0m`,
31
+ };
32
+ return out[(status / 100) | 0];
33
+ };
34
+ function log(fn, prefix, method, path, status, elasped) {
35
+ const out = prefix === LogPrefix.Incoming
36
+ ? ` ${prefix} ${method} ${path}`
37
+ : ` ${prefix} ${method} ${path} ${colorStatus(status)} ${elasped}`;
38
+ fn(out);
39
+ }
40
+ const logger = (fn = console.log) => {
41
+ return async (c, next) => {
42
+ const { method } = c.req;
43
+ const path = (0, util_1.getPathFromURL)(c.req.url);
44
+ log(fn, LogPrefix.Incoming, method, path);
45
+ const start = Date.now();
46
+ try {
47
+ await next();
48
+ }
49
+ catch (e) {
50
+ log(fn, LogPrefix.Error, method, path, c.res.status || 500, time(start));
51
+ throw e;
52
+ }
53
+ log(fn, LogPrefix.Outgoing, method, path, c.res.status, time(start));
54
+ };
55
+ };
56
+ exports.logger = logger;
@@ -0,0 +1,2 @@
1
+ import { Context } from '../../hono';
2
+ export declare const poweredBy: () => (c: Context, next: Function) => Promise<void>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.poweredBy = void 0;
4
+ const poweredBy = () => {
5
+ return async (c, next) => {
6
+ await next();
7
+ // await c.res.headers.append('X-Powered-By', 'Hono')
8
+ c.res.headers.append('X-Powered-By', 'Hono');
9
+ };
10
+ };
11
+ exports.poweredBy = poweredBy;
@@ -0,0 +1,8 @@
1
+ export declare class Middleware {
2
+ static defaultFilter: (c: import("./hono").Context, next: Function) => Promise<void>;
3
+ static poweredBy: () => (c: import("./hono").Context, next: Function) => Promise<void>;
4
+ static logger: (fn?: {
5
+ (...data: any[]): void;
6
+ (...data: any[]): void;
7
+ }) => (c: import("./hono").Context, next: Function) => Promise<void>;
8
+ }
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Middleware = void 0;
4
+ const defaultFilter_1 = require("./middleware/defaultFilter");
5
+ const poweredBy_1 = require("./middleware/poweredBy/poweredBy");
6
+ const logger_1 = require("./middleware/logger/logger");
7
+ class Middleware {
8
+ }
9
+ exports.Middleware = Middleware;
10
+ Middleware.defaultFilter = defaultFilter_1.defaultFilter;
11
+ Middleware.poweredBy = poweredBy_1.poweredBy;
12
+ Middleware.logger = logger_1.logger;
package/dist/node.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ export declare class Result<T> {
2
+ handler: T;
3
+ params: {
4
+ [key: string]: string;
5
+ };
6
+ constructor(handler: T, params: {
7
+ [key: string]: string;
8
+ });
9
+ }
10
+ export declare class Node<T> {
11
+ method: {
12
+ [key: string]: T;
13
+ };
14
+ handler: T;
15
+ children: {
16
+ [key: string]: Node<T>;
17
+ };
18
+ middlewares: [];
19
+ constructor(method?: string, handler?: any, children?: {
20
+ [key: string]: Node<T>;
21
+ });
22
+ insert(method: string, path: string, handler: T): Node<T>;
23
+ search(method: string, path: string): Result<T>;
24
+ }
package/dist/node.js ADDED
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Node = exports.Result = void 0;
4
+ const util_1 = require("./util");
5
+ const METHOD_NAME_OF_ALL = 'ALL';
6
+ class Result {
7
+ constructor(handler, params) {
8
+ this.handler = handler;
9
+ this.params = params;
10
+ }
11
+ }
12
+ exports.Result = Result;
13
+ const noRoute = () => {
14
+ return null;
15
+ };
16
+ class Node {
17
+ constructor(method, handler, children) {
18
+ this.children = children || {};
19
+ this.method = {};
20
+ if (method && handler) {
21
+ this.method[method] = handler;
22
+ }
23
+ this.middlewares = [];
24
+ }
25
+ insert(method, path, handler) {
26
+ let curNode = this;
27
+ const parts = (0, util_1.splitPath)(path);
28
+ for (let i = 0, len = parts.length; i < len; i++) {
29
+ const p = parts[i];
30
+ if (Object.keys(curNode.children).includes(p)) {
31
+ curNode = curNode.children[p];
32
+ continue;
33
+ }
34
+ curNode.children[p] = new Node();
35
+ curNode = curNode.children[p];
36
+ }
37
+ curNode.method[method] = handler;
38
+ return curNode;
39
+ }
40
+ search(method, path) {
41
+ let curNode = this;
42
+ const params = {};
43
+ let parts = (0, util_1.splitPath)(path);
44
+ for (let i = 0, len = parts.length; i < len; i++) {
45
+ const p = parts[i];
46
+ // '*' => match any path
47
+ if (curNode.children['*']) {
48
+ const astNode = curNode.children['*'];
49
+ if (Object.keys(astNode.children).length === 0) {
50
+ curNode = astNode;
51
+ break;
52
+ }
53
+ }
54
+ const nextNode = curNode.children[p];
55
+ if (nextNode) {
56
+ curNode = nextNode;
57
+ // '/hello/*' => match '/hello'
58
+ if (!(i == len - 1 && nextNode.children['*'])) {
59
+ continue;
60
+ }
61
+ }
62
+ let isWildcard = false;
63
+ let isParamMatch = false;
64
+ const keys = Object.keys(curNode.children);
65
+ for (let j = 0, len = keys.length; j < len; j++) {
66
+ const key = keys[j];
67
+ // Wildcard
68
+ // '/hello/*/foo' => match /hello/bar/foo
69
+ if (key === '*') {
70
+ curNode = curNode.children['*'];
71
+ isWildcard = true;
72
+ break;
73
+ }
74
+ const pattern = (0, util_1.getPattern)(key);
75
+ // Named match
76
+ if (pattern) {
77
+ const match = p.match(new RegExp(pattern[1]));
78
+ if (match) {
79
+ const k = pattern[0];
80
+ params[k] = match[1];
81
+ curNode = curNode.children[key];
82
+ isParamMatch = true;
83
+ break;
84
+ }
85
+ return noRoute();
86
+ }
87
+ }
88
+ if (isWildcard && i === len - 1) {
89
+ break;
90
+ }
91
+ if (isWildcard === false && isParamMatch === false) {
92
+ return noRoute();
93
+ }
94
+ }
95
+ const handler = curNode.method[METHOD_NAME_OF_ALL] || curNode.method[method];
96
+ if (!handler) {
97
+ return noRoute();
98
+ }
99
+ return new Result(handler, params);
100
+ }
101
+ }
102
+ exports.Node = Node;