@ndiinginc/router 4.14.1 → 4.16.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/package.json +1 -1
- package/src/app.js +21 -17
- package/src/index.js +0 -9
- package/src/middleware/cors.js +1 -0
- package/src/node.js +18 -25
- package/src/response.js +27 -17
- package/src/router.js +84 -75
package/package.json
CHANGED
package/src/app.js
CHANGED
|
@@ -2,12 +2,9 @@ const http = require("http");
|
|
|
2
2
|
const { Router } = require("./router");
|
|
3
3
|
const { Request } = require("./request");
|
|
4
4
|
const { Response } = require("./response");
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
IncomingMessage: Request,
|
|
9
|
-
ServerResponse: Response,
|
|
10
|
-
};
|
|
5
|
+
const { json } = require("./middleware/json");
|
|
6
|
+
const { cors } = require("./middleware/cors");
|
|
7
|
+
const { urlencoded } = require("./middleware/urlencoded");
|
|
11
8
|
|
|
12
9
|
class App extends Router {
|
|
13
10
|
/**
|
|
@@ -28,7 +25,6 @@ class App extends Router {
|
|
|
28
25
|
const promise = handlerPromise().catch((error) => {
|
|
29
26
|
if (!req.controller.signal.aborted) {
|
|
30
27
|
req.controller.abort(error);
|
|
31
|
-
} else {
|
|
32
28
|
}
|
|
33
29
|
});
|
|
34
30
|
try {
|
|
@@ -40,10 +36,10 @@ class App extends Router {
|
|
|
40
36
|
}
|
|
41
37
|
|
|
42
38
|
/**
|
|
43
|
-
* @param {Response} res
|
|
44
39
|
* @param {Error} err
|
|
40
|
+
* @param {Response} res
|
|
45
41
|
*/
|
|
46
|
-
fallback(
|
|
42
|
+
fallback(err, res) {
|
|
47
43
|
if (!res.writableEnded) {
|
|
48
44
|
if (!err) {
|
|
49
45
|
res.statusCode = 404;
|
|
@@ -65,12 +61,12 @@ class App extends Router {
|
|
|
65
61
|
* @param {Response} res
|
|
66
62
|
*/
|
|
67
63
|
async handle(req, res) {
|
|
68
|
-
const
|
|
69
|
-
req.params =
|
|
64
|
+
const result = this.find(req.method, req.path);
|
|
65
|
+
req.params = result.params;
|
|
70
66
|
let err;
|
|
71
67
|
try {
|
|
72
68
|
const handlerPromise = async () => {
|
|
73
|
-
for (const handler of handlers) {
|
|
69
|
+
for (const handler of result.handlers) {
|
|
74
70
|
if (res.writableEnded) break;
|
|
75
71
|
await handler(req, res);
|
|
76
72
|
}
|
|
@@ -83,7 +79,7 @@ class App extends Router {
|
|
|
83
79
|
} catch (error) {
|
|
84
80
|
err = error;
|
|
85
81
|
try {
|
|
86
|
-
for (const handler of errorHandlers) {
|
|
82
|
+
for (const handler of result.errorHandlers) {
|
|
87
83
|
if (res.writableEnded) break;
|
|
88
84
|
await handler(err, req, res);
|
|
89
85
|
}
|
|
@@ -91,7 +87,7 @@ class App extends Router {
|
|
|
91
87
|
err = new Error(error.message, { cause: err });
|
|
92
88
|
}
|
|
93
89
|
}
|
|
94
|
-
this.fallback(
|
|
90
|
+
this.fallback(err, res);
|
|
95
91
|
}
|
|
96
92
|
|
|
97
93
|
/**
|
|
@@ -99,13 +95,21 @@ class App extends Router {
|
|
|
99
95
|
* @returns {import('http').Server}
|
|
100
96
|
*/
|
|
101
97
|
listen(...args) {
|
|
102
|
-
const
|
|
103
|
-
|
|
98
|
+
const server = http.createServer(
|
|
99
|
+
{
|
|
100
|
+
IncomingMessage: Request,
|
|
101
|
+
ServerResponse: Response,
|
|
102
|
+
},
|
|
103
|
+
(req, res) => this.handle(req, res),
|
|
104
|
+
);
|
|
104
105
|
server.listen(...args);
|
|
105
106
|
return server;
|
|
106
107
|
}
|
|
107
108
|
}
|
|
108
109
|
|
|
109
|
-
App.
|
|
110
|
+
App.Router = Router;
|
|
111
|
+
App.json = json;
|
|
112
|
+
App.cors = cors;
|
|
113
|
+
App.urlencoded = urlencoded;
|
|
110
114
|
|
|
111
115
|
exports.App = App;
|
package/src/index.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
require("./polyfill");
|
|
2
2
|
const { App } = require("./app");
|
|
3
|
-
const { Router } = require("./router");
|
|
4
|
-
const { json } = require("./middleware/json");
|
|
5
|
-
const { cors } = require("./middleware/cors");
|
|
6
|
-
const { urlencoded } = require("./middleware/urlencoded");
|
|
7
|
-
|
|
8
|
-
App.Router = Router;
|
|
9
|
-
App.json = json;
|
|
10
|
-
App.cors = cors;
|
|
11
|
-
App.urlencoded = urlencoded;
|
|
12
3
|
|
|
13
4
|
module.exports = App;
|
package/src/middleware/cors.js
CHANGED
package/src/node.js
CHANGED
|
@@ -1,20 +1,17 @@
|
|
|
1
1
|
class Node {
|
|
2
2
|
/**
|
|
3
|
-
* @param {String}
|
|
3
|
+
* @param {String} prefix
|
|
4
4
|
*/
|
|
5
|
-
constructor(
|
|
6
|
-
this.
|
|
7
|
-
if (
|
|
5
|
+
constructor(prefix = "") {
|
|
6
|
+
this.prefix = prefix;
|
|
7
|
+
if (prefix.startsWith(":")) {
|
|
8
8
|
/**@type {String}*/
|
|
9
|
-
this.name =
|
|
9
|
+
this.name = prefix.slice(1);
|
|
10
10
|
}
|
|
11
|
-
|
|
12
11
|
/**@type {Map<string,Node>}*/
|
|
13
12
|
this.children = new Map();
|
|
14
|
-
|
|
15
13
|
/**@type {Map<string,Node>}*/
|
|
16
14
|
this.params = new Map();
|
|
17
|
-
|
|
18
15
|
/**@type {Node}*/
|
|
19
16
|
this.wildcard = null;
|
|
20
17
|
/**@type {Map<string,Function[]>}*/
|
|
@@ -22,29 +19,25 @@ class Node {
|
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
/**
|
|
25
|
-
* @param {String}
|
|
22
|
+
* @param {String} prefix
|
|
26
23
|
* @returns {Node}
|
|
27
24
|
*/
|
|
28
|
-
add(
|
|
29
|
-
if (
|
|
25
|
+
add(prefix) {
|
|
26
|
+
if (prefix === "*") {
|
|
30
27
|
if (!this.wildcard) this.wildcard = new Node("*");
|
|
31
28
|
return this.wildcard;
|
|
32
29
|
}
|
|
33
|
-
if (
|
|
34
|
-
return this.params.getOrInsertComputed(
|
|
35
|
-
return new Node(segment);
|
|
36
|
-
});
|
|
30
|
+
if (prefix.startsWith(":")) {
|
|
31
|
+
return this.params.getOrInsertComputed(prefix, (prefix) => new Node(prefix));
|
|
37
32
|
}
|
|
38
|
-
return this.children.getOrInsertComputed(
|
|
39
|
-
return new Node(segment);
|
|
40
|
-
});
|
|
33
|
+
return this.children.getOrInsertComputed(prefix, (prefix) => new Node(prefix));
|
|
41
34
|
}
|
|
42
35
|
|
|
43
36
|
/**
|
|
44
|
-
* @param {String}
|
|
37
|
+
* @param {String} prefix
|
|
45
38
|
*/
|
|
46
|
-
remove(
|
|
47
|
-
this.children.delete(
|
|
39
|
+
remove(prefix) {
|
|
40
|
+
this.children.delete(prefix);
|
|
48
41
|
}
|
|
49
42
|
|
|
50
43
|
/**
|
|
@@ -63,11 +56,11 @@ class Node {
|
|
|
63
56
|
if (node.wildcard) {
|
|
64
57
|
this.add("*").merge(node.wildcard, offset);
|
|
65
58
|
}
|
|
66
|
-
for (const [
|
|
67
|
-
this.add(
|
|
59
|
+
for (const [prefix, child] of node.params) {
|
|
60
|
+
this.add(prefix).merge(child, offset);
|
|
68
61
|
}
|
|
69
|
-
for (const [
|
|
70
|
-
this.add(
|
|
62
|
+
for (const [prefix, child] of node.children) {
|
|
63
|
+
this.add(prefix).merge(child, offset);
|
|
71
64
|
}
|
|
72
65
|
}
|
|
73
66
|
|
package/src/response.js
CHANGED
|
@@ -1,31 +1,41 @@
|
|
|
1
1
|
const http = require("http");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
2
4
|
|
|
3
5
|
class Response extends http.ServerResponse {
|
|
4
|
-
/**
|
|
5
|
-
* @param {Number} code
|
|
6
|
-
* @returns {Response}
|
|
7
|
-
*/
|
|
8
6
|
status(code) {
|
|
9
7
|
this.statusCode = code;
|
|
10
8
|
return this;
|
|
11
9
|
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @param {String} chunk
|
|
15
|
-
*/
|
|
16
10
|
send(chunk) {
|
|
17
|
-
|
|
18
|
-
this.end(chunk
|
|
11
|
+
this.setHeader("Content-Type", "text/plain; charset=utf-8");
|
|
12
|
+
this.end(chunk);
|
|
19
13
|
}
|
|
20
14
|
|
|
21
|
-
/**
|
|
22
|
-
* @param {Object} value
|
|
23
|
-
*/
|
|
24
15
|
json(value) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
16
|
+
this.setHeader("Content-Type", "application/json; charset=utf-8");
|
|
17
|
+
this.end(JSON.stringify(value));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
download(filepath, filename) {
|
|
21
|
+
fs.stat(filepath, (err, stats) => {
|
|
22
|
+
if (err || !stats.isFile()) {
|
|
23
|
+
this.statusCode = 404;
|
|
24
|
+
return this.end();
|
|
25
|
+
}
|
|
26
|
+
filename=filename||path.basename(filepath)
|
|
27
|
+
this.setHeader("Content-Type", "application/octet-stream");
|
|
28
|
+
this.setHeader("Content-Disposition", `attachment; filename="${filename}"`);
|
|
29
|
+
this.setHeader("Content-Length", stats.size);
|
|
30
|
+
const stream = fs.createReadStream(filepath);
|
|
31
|
+
stream.on("error", (err) => {
|
|
32
|
+
if (!this.headersSent) {
|
|
33
|
+
this.statusCode = 500;
|
|
34
|
+
this.end();
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
stream.pipe(this);
|
|
38
|
+
});
|
|
29
39
|
}
|
|
30
40
|
}
|
|
31
41
|
exports.Response = Response;
|
package/src/router.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
const { decodeParam } = require("./util");
|
|
2
2
|
const { Node } = require("./node");
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* @callback Callback
|
|
6
|
+
* @param {import('./request').Request} req
|
|
7
|
+
* @param {import('./response').Response} res
|
|
8
|
+
*/
|
|
9
|
+
|
|
4
10
|
/**
|
|
5
11
|
* @typedef {Object} Options
|
|
6
12
|
* @property {Number} [requestTimeout=0]
|
|
@@ -12,7 +18,6 @@ class Router {
|
|
|
12
18
|
*/
|
|
13
19
|
constructor(options = {}) {
|
|
14
20
|
this.requestTimeout = options.requestTimeout ?? 0;
|
|
15
|
-
|
|
16
21
|
this.root = new Node();
|
|
17
22
|
this.seq = 0;
|
|
18
23
|
}
|
|
@@ -36,45 +41,42 @@ class Router {
|
|
|
36
41
|
* @returns
|
|
37
42
|
*/
|
|
38
43
|
walk(path, node) {
|
|
39
|
-
for (const [
|
|
40
|
-
const lcp = this.lcp(
|
|
44
|
+
for (const [prefix, child] of node.children) {
|
|
45
|
+
const lcp = this.lcp(prefix, path);
|
|
41
46
|
if (lcp === 0) continue;
|
|
42
|
-
if (lcp ===
|
|
47
|
+
if (lcp === prefix.length) {
|
|
43
48
|
if (lcp === path.length) return child;
|
|
44
49
|
return this.walk(path.slice(lcp), child);
|
|
45
50
|
}
|
|
46
|
-
const newNode = new Node(
|
|
47
|
-
newNode.add(
|
|
51
|
+
const newNode = new Node(prefix.slice(0, lcp));
|
|
52
|
+
newNode.add(prefix.slice(lcp)).merge(child);
|
|
48
53
|
const rest = path.slice(lcp);
|
|
49
54
|
if (rest.length) newNode.add(rest);
|
|
50
|
-
node.add(newNode.
|
|
51
|
-
node.remove(
|
|
55
|
+
node.add(newNode.prefix).merge(newNode);
|
|
56
|
+
node.remove(prefix);
|
|
52
57
|
}
|
|
53
58
|
return node.add(path);
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
/**
|
|
57
62
|
* @param {String} method
|
|
58
|
-
* @param {String|
|
|
59
|
-
* @param {
|
|
63
|
+
* @param {String|Callback} path
|
|
64
|
+
* @param {Callback[]} handlers
|
|
60
65
|
*/
|
|
61
66
|
add(method, path, ...handlers) {
|
|
62
67
|
if (typeof path === "function") {
|
|
63
68
|
handlers = [path, ...handlers];
|
|
64
69
|
path = null;
|
|
65
70
|
}
|
|
66
|
-
|
|
67
71
|
let node = this.root;
|
|
68
|
-
let params = [];
|
|
69
72
|
if (path) {
|
|
70
73
|
let i = 0;
|
|
71
74
|
while (i < path.length) {
|
|
72
75
|
if (path[i] === ":") {
|
|
73
76
|
let j = i + 1;
|
|
74
77
|
while (j < path.length && path[j] !== "/") j++;
|
|
75
|
-
let
|
|
76
|
-
node = node.add(
|
|
77
|
-
params.push(segment.slice(1));
|
|
78
|
+
let prefix = path.slice(i, j);
|
|
79
|
+
node = node.add(prefix);
|
|
78
80
|
i = j;
|
|
79
81
|
} else if (path[i] === "*") {
|
|
80
82
|
let j = i + 1;
|
|
@@ -101,8 +103,8 @@ class Router {
|
|
|
101
103
|
}
|
|
102
104
|
|
|
103
105
|
/**
|
|
104
|
-
* @param {String|
|
|
105
|
-
* @param {
|
|
106
|
+
* @param {String|Callback} path
|
|
107
|
+
* @param {Callback[]} handlers
|
|
106
108
|
* @returns {this}
|
|
107
109
|
*/
|
|
108
110
|
use(path, ...handlers) {
|
|
@@ -111,8 +113,8 @@ class Router {
|
|
|
111
113
|
}
|
|
112
114
|
|
|
113
115
|
/**
|
|
114
|
-
* @param {String|
|
|
115
|
-
* @param {
|
|
116
|
+
* @param {String|Callback} path
|
|
117
|
+
* @param {Callback[]} handlers
|
|
116
118
|
* @returns {this}
|
|
117
119
|
*/
|
|
118
120
|
get(path, ...handlers) {
|
|
@@ -121,8 +123,8 @@ class Router {
|
|
|
121
123
|
}
|
|
122
124
|
|
|
123
125
|
/**
|
|
124
|
-
* @param {String|
|
|
125
|
-
* @param {
|
|
126
|
+
* @param {String|Callback} path
|
|
127
|
+
* @param {Callback[]} handlers
|
|
126
128
|
* @returns {this}
|
|
127
129
|
*/
|
|
128
130
|
query(path, ...handlers) {
|
|
@@ -131,8 +133,8 @@ class Router {
|
|
|
131
133
|
}
|
|
132
134
|
|
|
133
135
|
/**
|
|
134
|
-
* @param {String|
|
|
135
|
-
* @param {
|
|
136
|
+
* @param {String|Callback} path
|
|
137
|
+
* @param {Callback[]} handlers
|
|
136
138
|
* @returns {this}
|
|
137
139
|
*/
|
|
138
140
|
head(path, ...handlers) {
|
|
@@ -141,8 +143,8 @@ class Router {
|
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
/**
|
|
144
|
-
* @param {String|
|
|
145
|
-
* @param {
|
|
146
|
+
* @param {String|Callback} path
|
|
147
|
+
* @param {Callback[]} handlers
|
|
146
148
|
* @returns {this}
|
|
147
149
|
*/
|
|
148
150
|
options(path, ...handlers) {
|
|
@@ -151,8 +153,8 @@ class Router {
|
|
|
151
153
|
}
|
|
152
154
|
|
|
153
155
|
/**
|
|
154
|
-
* @param {String|
|
|
155
|
-
* @param {
|
|
156
|
+
* @param {String|Callback} path
|
|
157
|
+
* @param {Callback[]} handlers
|
|
156
158
|
* @returns {this}
|
|
157
159
|
*/
|
|
158
160
|
trace(path, ...handlers) {
|
|
@@ -161,8 +163,8 @@ class Router {
|
|
|
161
163
|
}
|
|
162
164
|
|
|
163
165
|
/**
|
|
164
|
-
* @param {String|
|
|
165
|
-
* @param {
|
|
166
|
+
* @param {String|Callback} path
|
|
167
|
+
* @param {Callback[]} handlers
|
|
166
168
|
* @returns {this}
|
|
167
169
|
*/
|
|
168
170
|
put(path, ...handlers) {
|
|
@@ -171,8 +173,8 @@ class Router {
|
|
|
171
173
|
}
|
|
172
174
|
|
|
173
175
|
/**
|
|
174
|
-
* @param {String|
|
|
175
|
-
* @param {
|
|
176
|
+
* @param {String|Callback} path
|
|
177
|
+
* @param {Callback[]} handlers
|
|
176
178
|
* @returns {this}
|
|
177
179
|
*/
|
|
178
180
|
delete(path, ...handlers) {
|
|
@@ -181,8 +183,8 @@ class Router {
|
|
|
181
183
|
}
|
|
182
184
|
|
|
183
185
|
/**
|
|
184
|
-
* @param {String|
|
|
185
|
-
* @param {
|
|
186
|
+
* @param {String|Callback} path
|
|
187
|
+
* @param {Callback[]} handlers
|
|
186
188
|
* @returns {this}
|
|
187
189
|
*/
|
|
188
190
|
post(path, ...handlers) {
|
|
@@ -191,8 +193,8 @@ class Router {
|
|
|
191
193
|
}
|
|
192
194
|
|
|
193
195
|
/**
|
|
194
|
-
* @param {String|
|
|
195
|
-
* @param {
|
|
196
|
+
* @param {String|Callback} path
|
|
197
|
+
* @param {Callback[]} handlers
|
|
196
198
|
* @returns {this}
|
|
197
199
|
*/
|
|
198
200
|
patch(path, ...handlers) {
|
|
@@ -201,8 +203,8 @@ class Router {
|
|
|
201
203
|
}
|
|
202
204
|
|
|
203
205
|
/**
|
|
204
|
-
* @param {String|
|
|
205
|
-
* @param {
|
|
206
|
+
* @param {String|Callback} path
|
|
207
|
+
* @param {Callback[]} handlers
|
|
206
208
|
* @returns {this}
|
|
207
209
|
*/
|
|
208
210
|
connect(path, ...handlers) {
|
|
@@ -226,95 +228,102 @@ class Router {
|
|
|
226
228
|
return { nodes, params, matched: true };
|
|
227
229
|
}
|
|
228
230
|
if (nodes.length > state.nodes.length) {
|
|
229
|
-
state.nodes=nodes.slice()
|
|
230
|
-
params={...params}
|
|
231
|
+
state.nodes = nodes.slice();
|
|
232
|
+
state.params = { ...params };
|
|
231
233
|
}
|
|
232
234
|
nodes.pop();
|
|
233
235
|
return { nodes: state.nodes, params: state.params, matched: false };
|
|
234
236
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
237
|
+
if (node.children.size) {
|
|
238
|
+
for (const [prefix, child] of node.children) {
|
|
239
|
+
if (path.startsWith(prefix)) {
|
|
240
|
+
const res = this.search(method, path.slice(prefix.length), child, nodes, params, state);
|
|
241
|
+
if (res.matched) return res;
|
|
242
|
+
}
|
|
239
243
|
}
|
|
240
244
|
}
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
if (node.params.size) {
|
|
246
|
+
for (const [, child] of node.params) {
|
|
247
|
+
const index = path.indexOf("/");
|
|
248
|
+
const value = index === -1 ? path : path.slice(0, index);
|
|
249
|
+
if (value.length) {
|
|
250
|
+
const rest = index === -1 ? "" : path.slice(index);
|
|
251
|
+
const next = { ...params, [child.name]: value };
|
|
252
|
+
const result = this.search(method, rest, child, nodes, next, state);
|
|
253
|
+
if (result.matched) return result;
|
|
254
|
+
}
|
|
249
255
|
}
|
|
250
256
|
}
|
|
251
257
|
if (node.wildcard && (node.wildcard.handlers.get(method) || node.wildcard.handlers.get("ALL"))) {
|
|
252
258
|
nodes.push(node.wildcard);
|
|
253
|
-
return {
|
|
254
|
-
nodes,
|
|
255
|
-
params: { ...params, wildcard: path },
|
|
256
|
-
matched: true,
|
|
257
|
-
};
|
|
259
|
+
return { nodes, params: { ...params, wildcard: path }, matched: true };
|
|
258
260
|
}
|
|
259
261
|
if (nodes.length > state.nodes.length) {
|
|
260
|
-
state.nodes=nodes.slice()
|
|
261
|
-
params={...params}
|
|
262
|
+
state.nodes = nodes.slice();
|
|
263
|
+
state.params = { ...params };
|
|
262
264
|
}
|
|
263
265
|
nodes.pop();
|
|
264
266
|
return { nodes: state.nodes, params: state.params, matched: false };
|
|
265
267
|
}
|
|
266
268
|
|
|
267
269
|
/**
|
|
268
|
-
* @param {Node}
|
|
270
|
+
* @param {Node} node
|
|
269
271
|
* @param {String} method
|
|
270
272
|
* @param {Object} handlers
|
|
271
273
|
*/
|
|
272
|
-
collectHandler(
|
|
273
|
-
if (
|
|
274
|
-
for (const entry of
|
|
274
|
+
collectHandler(node, method, handlers) {
|
|
275
|
+
if (node.handlers.has(method)) {
|
|
276
|
+
for (const entry of node.handlers.get(method)) {
|
|
275
277
|
handlers[entry.seq] = entry.handler;
|
|
276
278
|
}
|
|
277
279
|
}
|
|
278
280
|
}
|
|
279
281
|
|
|
280
282
|
/**
|
|
281
|
-
* @param {Node}
|
|
283
|
+
* @param {Node} node
|
|
282
284
|
* @param {Object} handlers
|
|
283
285
|
* @param {Object} errorHandlers
|
|
284
286
|
*/
|
|
285
|
-
collectMiddleware(
|
|
286
|
-
this.collectHandler(
|
|
287
|
-
this.collectHandler(
|
|
287
|
+
collectMiddleware(node, handlers, errorHandlers) {
|
|
288
|
+
this.collectHandler(node, "ALL", handlers);
|
|
289
|
+
this.collectHandler(node, "CATCH", errorHandlers);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
decodeParams(obj) {
|
|
293
|
+
const params = Object.create(null);
|
|
294
|
+
const keys = Object.keys(obj);
|
|
295
|
+
if (keys.length) {
|
|
296
|
+
for (const key of keys) {
|
|
297
|
+
params[key] = decodeParam(obj[key]);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return params;
|
|
288
301
|
}
|
|
289
302
|
|
|
290
303
|
/**
|
|
291
304
|
* @param {String} method
|
|
292
305
|
* @param {String} path
|
|
293
|
-
* @returns {{
|
|
306
|
+
* @returns {{params: Object;handlers: any[];errorHandlers: any[];}}
|
|
294
307
|
*/
|
|
295
308
|
find(method, path) {
|
|
296
309
|
let res = this.search(method, path);
|
|
297
|
-
|
|
298
310
|
if (!res.matched && path.length > 1) {
|
|
299
311
|
const alt = path.endsWith("/") ? path.slice(0, -1) : path + "/";
|
|
300
312
|
res = this.search(method, alt);
|
|
301
313
|
}
|
|
302
314
|
const handlers = {};
|
|
303
315
|
const errorHandlers = {};
|
|
304
|
-
for (const r of res.nodes) {
|
|
305
|
-
this.collectMiddleware(r, handlers, errorHandlers);
|
|
306
|
-
}
|
|
307
316
|
if (res.matched) {
|
|
308
317
|
this.collectHandler(res.nodes.at(-1), method, handlers);
|
|
309
318
|
}
|
|
319
|
+
for (const node of res.nodes) {
|
|
320
|
+
this.collectMiddleware(node, handlers, errorHandlers);
|
|
321
|
+
}
|
|
310
322
|
return {
|
|
311
|
-
|
|
312
|
-
params: res.params,
|
|
313
|
-
paramsLength: Object.keys(res.params).length,
|
|
323
|
+
params: this.decodeParams(res.params),
|
|
314
324
|
handlers: Object.values(handlers),
|
|
315
325
|
errorHandlers: Object.values(errorHandlers),
|
|
316
326
|
};
|
|
317
327
|
}
|
|
318
|
-
|
|
319
328
|
}
|
|
320
329
|
exports.Router = Router;
|