hono 2.1.4 → 2.2.1
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 -14
- package/dist/cjs/compose.js +48 -0
- package/dist/cjs/context.js +147 -0
- package/dist/cjs/hono.js +152 -0
- package/dist/cjs/index.js +13 -0
- package/dist/cjs/middleware/basic-auth/index.js +48 -0
- package/dist/cjs/middleware/bearer-auth/index.js +57 -0
- package/dist/cjs/middleware/cache/index.js +32 -0
- package/dist/cjs/middleware/compress/index.js +19 -0
- package/dist/cjs/middleware/cors/index.js +75 -0
- package/dist/cjs/middleware/etag/index.js +27 -0
- package/dist/cjs/middleware/html/index.js +36 -0
- package/dist/cjs/middleware/jsx/index.js +193 -0
- package/dist/cjs/middleware/jsx/jsx-dev-runtime.js +10 -0
- package/dist/cjs/middleware/jsx/jsx-runtime.js +7 -0
- package/dist/cjs/middleware/jwt/index.js +63 -0
- package/dist/cjs/middleware/logger/index.js +49 -0
- package/dist/cjs/middleware/powered-by/index.js +10 -0
- package/dist/cjs/middleware/pretty-json/index.js +11 -0
- package/dist/cjs/middleware/serve-static/bun.js +41 -0
- package/dist/cjs/middleware/serve-static/index.js +5 -0
- package/dist/cjs/middleware/serve-static/serve-static.js +40 -0
- package/dist/cjs/middleware/validator/index.js +5 -0
- package/dist/cjs/middleware/validator/middleware.js +56 -0
- package/dist/cjs/middleware/validator/rule.js +66 -0
- package/dist/cjs/middleware/validator/sanitizer.js +6 -0
- package/dist/cjs/middleware/validator/validator.js +195 -0
- package/dist/cjs/request.js +120 -0
- package/dist/cjs/router/reg-exp-router/index.js +5 -0
- package/dist/cjs/router/reg-exp-router/node.js +108 -0
- package/dist/cjs/router/reg-exp-router/router.js +161 -0
- package/dist/cjs/router/reg-exp-router/trie.js +42 -0
- package/dist/cjs/router/smart-router/index.js +5 -0
- package/dist/cjs/router/smart-router/router.js +57 -0
- package/dist/cjs/router/static-router/index.js +5 -0
- package/dist/cjs/router/static-router/router.js +72 -0
- package/dist/cjs/router/trie-router/index.js +5 -0
- package/dist/cjs/router/trie-router/node.js +175 -0
- package/dist/cjs/router/trie-router/router.js +24 -0
- package/dist/cjs/router.js +9 -0
- package/dist/cjs/utils/body.js +18 -0
- package/dist/cjs/utils/buffer.js +39 -0
- package/dist/cjs/utils/cloudflare.js +39 -0
- package/dist/cjs/utils/cookie.js +40 -0
- package/dist/cjs/utils/crypto.js +53 -0
- package/dist/cjs/utils/encode.js +80 -0
- package/dist/cjs/utils/filepath.js +25 -0
- package/dist/cjs/utils/html.js +38 -0
- package/dist/cjs/utils/http-status.js +50 -0
- package/dist/cjs/utils/json.js +22 -0
- package/dist/cjs/utils/jwt/index.js +27 -0
- package/dist/cjs/utils/jwt/jwt.js +101 -0
- package/dist/cjs/utils/jwt/types.js +49 -0
- package/dist/cjs/utils/mime.js +92 -0
- package/dist/cjs/utils/url.js +94 -0
- package/dist/compose.d.ts +2 -2
- package/dist/compose.js +3 -7
- package/dist/context.d.ts +14 -9
- package/dist/context.js +55 -25
- package/dist/hono.d.ts +28 -27
- package/dist/hono.js +22 -23
- package/dist/index.js +3 -6
- package/dist/middleware/basic-auth/index.d.ts +2 -3
- package/dist/middleware/basic-auth/index.js +7 -11
- package/dist/middleware/bearer-auth/index.d.ts +2 -3
- package/dist/middleware/bearer-auth/index.js +4 -12
- package/dist/middleware/cache/index.d.ts +2 -3
- package/dist/middleware/cache/index.js +1 -5
- package/dist/middleware/compress/index.d.ts +2 -3
- package/dist/middleware/compress/index.js +1 -5
- package/dist/middleware/cors/index.d.ts +3 -4
- package/dist/middleware/cors/index.js +16 -6
- package/dist/middleware/etag/index.d.ts +2 -3
- package/dist/middleware/etag/index.js +3 -7
- package/dist/middleware/html/index.js +6 -11
- package/dist/middleware/jsx/index.js +9 -15
- package/dist/middleware/jsx/jsx-dev-runtime.js +3 -7
- package/dist/middleware/jsx/jsx-runtime.js +2 -7
- package/dist/middleware/jwt/index.d.ts +2 -3
- package/dist/middleware/jwt/index.js +3 -7
- package/dist/middleware/logger/index.d.ts +2 -3
- package/dist/middleware/logger/index.js +3 -7
- package/dist/middleware/powered-by/index.d.ts +2 -3
- package/dist/middleware/powered-by/index.js +1 -5
- package/dist/middleware/pretty-json/index.d.ts +2 -3
- package/dist/middleware/pretty-json/index.js +1 -5
- package/dist/middleware/serve-static/bun.d.ts +2 -3
- package/dist/middleware/serve-static/bun.js +18 -19
- package/dist/middleware/serve-static/index.js +1 -5
- package/dist/middleware/serve-static/module.d.mts +1 -1
- package/dist/middleware/serve-static/serve-static.d.ts +2 -3
- package/dist/middleware/serve-static/serve-static.js +7 -11
- package/dist/middleware/validator/index.d.ts +2 -0
- package/dist/middleware/validator/index.js +2 -0
- package/dist/middleware/validator/middleware.d.ts +21 -0
- package/dist/middleware/validator/middleware.js +52 -0
- package/dist/middleware/validator/rule.d.ts +21 -0
- package/dist/middleware/validator/rule.js +63 -0
- package/dist/middleware/validator/sanitizer.d.ts +3 -0
- package/dist/middleware/validator/sanitizer.js +3 -0
- package/dist/middleware/validator/validator.d.ts +75 -0
- package/dist/middleware/validator/validator.js +186 -0
- package/dist/request.d.ts +15 -5
- package/dist/request.js +58 -28
- package/dist/router/reg-exp-router/index.js +1 -5
- package/dist/router/reg-exp-router/node.d.ts +1 -3
- package/dist/router/reg-exp-router/node.js +21 -17
- package/dist/router/reg-exp-router/router.d.ts +3 -27
- package/dist/router/reg-exp-router/router.js +105 -315
- package/dist/router/reg-exp-router/trie.d.ts +0 -4
- package/dist/router/reg-exp-router/trie.js +4 -8
- package/dist/router/smart-router/index.d.ts +1 -0
- package/dist/router/smart-router/index.js +1 -0
- package/dist/router/smart-router/router.d.ts +9 -0
- package/dist/router/smart-router/router.js +53 -0
- package/dist/router/static-router/index.d.ts +1 -0
- package/dist/router/static-router/index.js +1 -0
- package/dist/router/static-router/router.d.ts +8 -0
- package/dist/router/static-router/router.js +68 -0
- package/dist/router/trie-router/index.js +1 -5
- package/dist/router/trie-router/node.js +7 -11
- package/dist/router/trie-router/router.js +11 -7
- package/dist/router.d.ts +3 -0
- package/dist/router.js +5 -5
- package/dist/utils/body.d.ts +2 -1
- package/dist/utils/body.js +1 -5
- package/dist/utils/buffer.d.ts +1 -1
- package/dist/utils/buffer.js +5 -11
- package/dist/utils/cloudflare.d.ts +1 -1
- package/dist/utils/cloudflare.js +1 -5
- package/dist/utils/cookie.js +2 -7
- package/dist/utils/crypto.js +8 -15
- package/dist/utils/encode.js +10 -20
- package/dist/utils/filepath.js +1 -5
- package/dist/utils/html.js +1 -5
- package/dist/utils/http-status.js +1 -5
- package/dist/utils/json.d.ts +1 -0
- package/dist/utils/json.js +18 -0
- package/dist/utils/jwt/index.js +1 -27
- package/dist/utils/jwt/jwt.js +22 -28
- package/dist/utils/jwt/types.js +8 -16
- package/dist/utils/mime.js +1 -5
- package/dist/utils/url.d.ts +1 -1
- package/dist/utils/url.js +18 -22
- package/package.json +122 -35
|
@@ -1,90 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const
|
|
1
|
+
import { METHOD_NAME_ALL, METHODS, UnsupportedPathError } from '../../router';
|
|
2
|
+
import { checkOptionalParameter } from '../../utils/url';
|
|
3
|
+
import { PATH_ERROR } from './node';
|
|
4
|
+
import { Trie } from './trie';
|
|
5
|
+
const METHOD_NAMES = [METHOD_NAME_ALL, ...METHODS].map((method) => method.toUpperCase());
|
|
6
6
|
const emptyParam = {};
|
|
7
7
|
const nullMatcher = [/^$/, []];
|
|
8
|
-
function
|
|
9
|
-
|
|
10
|
-
let componentsLength = components.length;
|
|
11
|
-
const paramIndexList = [];
|
|
12
|
-
const regExpComponents = [];
|
|
13
|
-
const namedParams = [];
|
|
14
|
-
for (let i = 0, len = components.length; i < len; i++) {
|
|
15
|
-
if (i === len - 1 && components[i] === '/*') {
|
|
16
|
-
componentsLength--;
|
|
17
|
-
break;
|
|
18
|
-
}
|
|
19
|
-
const m = components[i].match(/^\/:(\w+)({[^}]+})?/);
|
|
20
|
-
if (m) {
|
|
21
|
-
namedParams.push([i, m[1], m[2] || '[^/]+']);
|
|
22
|
-
regExpComponents[i] = m[2] || true;
|
|
23
|
-
}
|
|
24
|
-
else if (components[i] === '/*') {
|
|
25
|
-
regExpComponents[i] = true;
|
|
26
|
-
}
|
|
27
|
-
else {
|
|
28
|
-
regExpComponents[i] = components[i];
|
|
29
|
-
}
|
|
30
|
-
if (/\/(?::|\*)/.test(components[i])) {
|
|
31
|
-
paramIndexList.push(i);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return {
|
|
35
|
-
components,
|
|
36
|
-
regExpComponents,
|
|
37
|
-
componentsLength,
|
|
38
|
-
endWithWildcard: path.endsWith('*'),
|
|
39
|
-
paramIndexList,
|
|
40
|
-
namedParams,
|
|
41
|
-
maybeHandler: true,
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
function compareRoute(a, b) {
|
|
45
|
-
if (a.path === '*') {
|
|
46
|
-
return 1;
|
|
47
|
-
}
|
|
48
|
-
let i = 0;
|
|
49
|
-
const len = a.hint.regExpComponents.length;
|
|
50
|
-
for (; i < len; i++) {
|
|
51
|
-
if (a.hint.regExpComponents[i] !== b.hint.regExpComponents[i]) {
|
|
52
|
-
if (a.hint.regExpComponents[i] === true) {
|
|
53
|
-
break;
|
|
54
|
-
}
|
|
55
|
-
return 0;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
// may be ambiguous
|
|
59
|
-
for (; i < len; i++) {
|
|
60
|
-
if (a.hint.regExpComponents[i] !== true &&
|
|
61
|
-
a.hint.regExpComponents[i] !== b.hint.regExpComponents[i]) {
|
|
62
|
-
return 2;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
return i === b.hint.regExpComponents.length || a.hint.endWithWildcard ? 1 : 0;
|
|
66
|
-
}
|
|
67
|
-
function compareHandler(a, b) {
|
|
68
|
-
return a.index - b.index;
|
|
69
|
-
}
|
|
70
|
-
function getSortedHandlers(handlers) {
|
|
71
|
-
return [...handlers].sort(compareHandler).map((h) => h.handler);
|
|
8
|
+
function buildWildcardRegExp(path) {
|
|
9
|
+
return new RegExp(path === '*' ? '' : `^${path.replace(/\/\*/, '(?:|/.*)')}$`);
|
|
72
10
|
}
|
|
73
|
-
function buildMatcherFromPreprocessedRoutes(routes
|
|
74
|
-
const trie = new
|
|
11
|
+
function buildMatcherFromPreprocessedRoutes(routes) {
|
|
12
|
+
const trie = new Trie();
|
|
75
13
|
const handlers = [];
|
|
76
14
|
if (routes.length === 0) {
|
|
77
15
|
return nullMatcher;
|
|
78
16
|
}
|
|
79
17
|
for (let i = 0, len = routes.length; i < len; i++) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
Object.keys(paramMap).length !== 0 ? paramMap : null,
|
|
84
|
-
];
|
|
85
|
-
if (!hasAmbiguous) {
|
|
86
|
-
handlers[i][0] = getSortedHandlers(handlers[i][0]);
|
|
18
|
+
let paramMap;
|
|
19
|
+
try {
|
|
20
|
+
paramMap = trie.insert(routes[i][0], i);
|
|
87
21
|
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
throw e === PATH_ERROR ? new UnsupportedPathError(routes[i][0]) : e;
|
|
24
|
+
}
|
|
25
|
+
handlers[i] = [routes[i][1], paramMap.length !== 0 ? paramMap : null];
|
|
88
26
|
}
|
|
89
27
|
const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();
|
|
90
28
|
for (let i = 0, len = handlers.length; i < len; i++) {
|
|
@@ -92,12 +30,6 @@ function buildMatcherFromPreprocessedRoutes(routes, hasAmbiguous = false) {
|
|
|
92
30
|
if (paramMap) {
|
|
93
31
|
for (let j = 0, len = paramMap.length; j < len; j++) {
|
|
94
32
|
paramMap[j][1] = paramReplacementMap[paramMap[j][1]];
|
|
95
|
-
const aliasTo = routes[i].paramAliasMap[paramMap[j][0]];
|
|
96
|
-
if (aliasTo) {
|
|
97
|
-
for (let k = 0, len = aliasTo.length; k < len; k++) {
|
|
98
|
-
paramMap.push([aliasTo[k], paramMap[j][1]]);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
33
|
}
|
|
102
34
|
}
|
|
103
35
|
}
|
|
@@ -108,260 +40,118 @@ function buildMatcherFromPreprocessedRoutes(routes, hasAmbiguous = false) {
|
|
|
108
40
|
}
|
|
109
41
|
return [regexp, handlerMap];
|
|
110
42
|
}
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return false;
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
nameMap[name] = index;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
const paramAliasMap = route.paramAliasMap;
|
|
125
|
-
const paramAliasMapKeys = Object.keys(paramAliasMap);
|
|
126
|
-
for (let k = 0, len = paramAliasMapKeys.length; k < len; k++) {
|
|
127
|
-
const aliasFrom = paramAliasMapKeys[k];
|
|
128
|
-
for (let l = 0, len = paramAliasMap[aliasFrom].length; l < len; l++) {
|
|
129
|
-
const aliasTo = paramAliasMap[aliasFrom][l];
|
|
130
|
-
const index = nameMap[aliasFrom];
|
|
131
|
-
if (aliasTo in nameMap && index !== nameMap[aliasTo]) {
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
|
-
else {
|
|
135
|
-
nameMap[aliasTo] = index;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
43
|
+
function findMiddleware(middleware, path) {
|
|
44
|
+
if (!middleware) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {
|
|
48
|
+
if (buildWildcardRegExp(k).test(path)) {
|
|
49
|
+
return [...middleware[k]];
|
|
138
50
|
}
|
|
139
51
|
}
|
|
140
|
-
return
|
|
52
|
+
return undefined;
|
|
141
53
|
}
|
|
142
|
-
class RegExpRouter {
|
|
54
|
+
export class RegExpRouter {
|
|
143
55
|
constructor() {
|
|
144
|
-
this.
|
|
56
|
+
this.middleware = { [METHOD_NAME_ALL]: {} };
|
|
57
|
+
this.routes = { [METHOD_NAME_ALL]: {} };
|
|
145
58
|
}
|
|
146
59
|
add(method, path, handler) {
|
|
147
|
-
|
|
60
|
+
var _a, _b;
|
|
61
|
+
const { middleware, routes } = this;
|
|
62
|
+
if (!middleware || !routes) {
|
|
148
63
|
throw new Error('Can not add a route since the matcher is already built.');
|
|
149
64
|
}
|
|
150
|
-
this.routeData.index++;
|
|
151
|
-
const { index, routes, methods } = this.routeData;
|
|
152
65
|
if (path === '/*') {
|
|
153
66
|
path = '*';
|
|
154
67
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
68
|
+
if (/\*$/.test(path)) {
|
|
69
|
+
middleware[method] || (middleware[method] = {});
|
|
70
|
+
const re = buildWildcardRegExp(path);
|
|
71
|
+
(_a = middleware[method])[path] || (_a[path] = findMiddleware(middleware[METHOD_NAME_ALL], path) || []);
|
|
72
|
+
Object.keys(middleware).forEach((m) => {
|
|
73
|
+
if (method === METHOD_NAME_ALL || method === m) {
|
|
74
|
+
Object.keys(middleware[m]).forEach((p) => {
|
|
75
|
+
;
|
|
76
|
+
(path === '*' || path === p) && middleware[m][p].push(handler);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
Object.keys(routes).forEach((m) => {
|
|
81
|
+
if (method === METHOD_NAME_ALL || method === m) {
|
|
82
|
+
Object.keys(routes[m]).forEach((p) => (path === '*' || re.test(p)) && routes[m][p].push(handler));
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const paths = checkOptionalParameter(path) || [path];
|
|
88
|
+
for (let i = 0, len = paths.length; i < len; i++) {
|
|
89
|
+
const path = paths[i];
|
|
90
|
+
routes[method] || (routes[method] = {});
|
|
91
|
+
(_b = routes[method])[path] || (_b[path] = [
|
|
92
|
+
...(routes[METHOD_NAME_ALL][path] ||
|
|
93
|
+
findMiddleware(middleware[method], path) ||
|
|
94
|
+
findMiddleware(middleware[METHOD_NAME_ALL], path) ||
|
|
95
|
+
[]),
|
|
96
|
+
]);
|
|
97
|
+
Object.keys(routes).forEach((m) => {
|
|
98
|
+
;
|
|
99
|
+
(method === METHOD_NAME_ALL || method === m) &&
|
|
100
|
+
routes[m][path] &&
|
|
101
|
+
routes[m][path].push(handler);
|
|
102
|
+
});
|
|
165
103
|
}
|
|
166
|
-
methods.add(method);
|
|
167
|
-
routes.push({
|
|
168
|
-
method,
|
|
169
|
-
path,
|
|
170
|
-
hint,
|
|
171
|
-
handlers: [handlerWithSortIndex],
|
|
172
|
-
middleware: [],
|
|
173
|
-
paramAliasMap: {},
|
|
174
|
-
});
|
|
175
104
|
}
|
|
176
105
|
match(method, path) {
|
|
177
|
-
const
|
|
178
|
-
this.match =
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
if (!match) {
|
|
184
|
-
// do not support secondary matchers here.
|
|
185
|
-
return null;
|
|
186
|
-
}
|
|
187
|
-
const params = {};
|
|
188
|
-
const handlers = new Set();
|
|
189
|
-
let regExpSrc = matcher[0].source;
|
|
190
|
-
while (match) {
|
|
191
|
-
let index = match.indexOf('', 1);
|
|
192
|
-
for (;;) {
|
|
193
|
-
const [handler, paramMap] = matcher[1][index];
|
|
194
|
-
if (paramMap) {
|
|
195
|
-
for (let i = 0, len = paramMap.length; i < len; i++) {
|
|
196
|
-
params[paramMap[i][0]] = match[paramMap[i][1]];
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
for (let i = 0, len = handler.length; i < len; i++) {
|
|
200
|
-
handlers.add(handler[i]);
|
|
201
|
-
}
|
|
202
|
-
const newIndex = match.indexOf('', index + 1);
|
|
203
|
-
if (newIndex === -1) {
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
index = newIndex;
|
|
207
|
-
}
|
|
208
|
-
regExpSrc = regExpSrc.replace(new RegExp(`((?:(?:\\(\\?:|.)*?\\([^)]*\\)){${index - 1}}.*?)\\(\\)`), '$1(^)');
|
|
209
|
-
match = path.match(new RegExp(regExpSrc));
|
|
210
|
-
}
|
|
211
|
-
return { handlers: getSortedHandlers(handlers.values()), params };
|
|
106
|
+
const matchers = this.buildAllMatchers();
|
|
107
|
+
this.match = (method, path) => {
|
|
108
|
+
const matcher = matchers[method];
|
|
109
|
+
const match = path.match(matcher[0]);
|
|
110
|
+
if (!match) {
|
|
111
|
+
return null;
|
|
212
112
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
const index = match.indexOf('', 1);
|
|
227
|
-
const [handlers, paramMap] = matcher[1][index];
|
|
228
|
-
if (!paramMap) {
|
|
229
|
-
return { handlers, params: emptyParam };
|
|
230
|
-
}
|
|
231
|
-
const params = {};
|
|
232
|
-
for (let i = 0, len = paramMap.length; i < len; i++) {
|
|
233
|
-
params[paramMap[i][0]] = match[paramMap[i][1]];
|
|
234
|
-
}
|
|
235
|
-
return { handlers, params };
|
|
236
|
-
};
|
|
113
|
+
const index = match.indexOf('', 1);
|
|
114
|
+
const [handlers, paramMap] = matcher[1][index];
|
|
115
|
+
if (!paramMap) {
|
|
116
|
+
return { handlers, params: emptyParam };
|
|
117
|
+
}
|
|
118
|
+
const params = {};
|
|
119
|
+
for (let i = 0, len = paramMap.length; i < len; i++) {
|
|
120
|
+
params[paramMap[i][0]] = match[paramMap[i][1]];
|
|
121
|
+
}
|
|
122
|
+
return { handlers, params };
|
|
123
|
+
};
|
|
237
124
|
return this.match(method, path);
|
|
238
125
|
}
|
|
239
126
|
buildAllMatchers() {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
this.routeData.routes.sort(({ hint: a }, { hint: b }) => {
|
|
244
|
-
if (a.componentsLength !== b.componentsLength) {
|
|
245
|
-
return a.componentsLength - b.componentsLength;
|
|
246
|
-
}
|
|
247
|
-
for (let i = 0, len = Math.min(a.paramIndexList.length, b.paramIndexList.length) + 1; i < len; i++) {
|
|
248
|
-
if (a.paramIndexList[i] !== b.paramIndexList[i]) {
|
|
249
|
-
if (a.paramIndexList[i] === undefined) {
|
|
250
|
-
return -1;
|
|
251
|
-
}
|
|
252
|
-
else if (b.paramIndexList[i] === undefined) {
|
|
253
|
-
return 1;
|
|
254
|
-
}
|
|
255
|
-
else {
|
|
256
|
-
return a.paramIndexList[i] - b.paramIndexList[i];
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
if (a.endWithWildcard !== b.endWithWildcard) {
|
|
261
|
-
return a.endWithWildcard ? -1 : 1;
|
|
262
|
-
}
|
|
263
|
-
return 0;
|
|
127
|
+
const matchers = {};
|
|
128
|
+
METHOD_NAMES.forEach((method) => {
|
|
129
|
+
matchers[method] = this.buildMatcher(method) || matchers[METHOD_NAME_ALL];
|
|
264
130
|
});
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
this.routeData.methods.forEach((method) => {
|
|
269
|
-
let _hasAmbiguous;
|
|
270
|
-
[primaryMatchers[method], secondaryMatchers[method], _hasAmbiguous] =
|
|
271
|
-
this.buildMatcher(method);
|
|
272
|
-
hasAmbiguous = hasAmbiguous || _hasAmbiguous;
|
|
273
|
-
});
|
|
274
|
-
if (hasAmbiguous) {
|
|
275
|
-
// rebuild all matchers with ambiguous flag
|
|
276
|
-
this.routeData.methods.forEach((method) => {
|
|
277
|
-
;
|
|
278
|
-
[primaryMatchers[method], secondaryMatchers[method]] = this.buildMatcher(method, hasAmbiguous);
|
|
279
|
-
});
|
|
280
|
-
}
|
|
281
|
-
primaryMatchers[router_1.METHOD_NAME_ALL] || (primaryMatchers[router_1.METHOD_NAME_ALL] = nullMatcher);
|
|
282
|
-
secondaryMatchers[router_1.METHOD_NAME_ALL] || (secondaryMatchers[router_1.METHOD_NAME_ALL] = []);
|
|
283
|
-
delete this.routeData; // to reduce memory usage
|
|
284
|
-
return [primaryMatchers, secondaryMatchers, hasAmbiguous];
|
|
131
|
+
// Release cache
|
|
132
|
+
this.middleware = this.routes = undefined;
|
|
133
|
+
return matchers;
|
|
285
134
|
}
|
|
286
|
-
buildMatcher(method
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
// preprocess routes
|
|
297
|
-
for (let i = 0, len = routes.length; i < len; i++) {
|
|
298
|
-
for (let j = i + 1; j < len; j++) {
|
|
299
|
-
const compareResult = compareRoute(routes[i], routes[j]);
|
|
300
|
-
// i includes j
|
|
301
|
-
if (compareResult === 1) {
|
|
302
|
-
const components = routes[j].hint.components;
|
|
303
|
-
const namedParams = routes[i].hint.namedParams;
|
|
304
|
-
for (let k = 0, len = namedParams.length; k < len; k++) {
|
|
305
|
-
const c = components[namedParams[k][0]];
|
|
306
|
-
const m = c.match(/^\/:(\w+)({[^}]+})?/);
|
|
307
|
-
if (m && namedParams[k][1] === m[1]) {
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
if (m) {
|
|
311
|
-
(_a = routes[j].paramAliasMap)[_b = m[1]] || (_a[_b] = []);
|
|
312
|
-
routes[j].paramAliasMap[m[1]].push(namedParams[k][1]);
|
|
313
|
-
}
|
|
314
|
-
else {
|
|
315
|
-
components[namedParams[k][0]] = `/:${namedParams[k][1]}{${c.substring(1)}}`;
|
|
316
|
-
routes[j].hint.namedParams.push([
|
|
317
|
-
namedParams[k][0],
|
|
318
|
-
namedParams[k][1],
|
|
319
|
-
c.substring(1),
|
|
320
|
-
]);
|
|
321
|
-
routes[j].path = components.join('');
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
if (routes[j].hint.components.length < routes[i].hint.components.length) {
|
|
325
|
-
routes[j].middleware.push(...routes[i].handlers.map((h) => ({
|
|
326
|
-
index: h.index,
|
|
327
|
-
handler: h.handler,
|
|
328
|
-
})));
|
|
329
|
-
}
|
|
330
|
-
else {
|
|
331
|
-
routes[j].middleware.push(...routes[i].handlers);
|
|
332
|
-
}
|
|
333
|
-
routes[i].hint.maybeHandler = false;
|
|
334
|
-
}
|
|
335
|
-
else if (compareResult === 2) {
|
|
336
|
-
// ambiguous
|
|
337
|
-
hasAmbiguous = true;
|
|
338
|
-
if (!verifyDuplicateParam([routes[i], routes[j]])) {
|
|
339
|
-
throw new Error('Duplicate param name');
|
|
340
|
-
}
|
|
341
|
-
}
|
|
135
|
+
buildMatcher(method) {
|
|
136
|
+
const routes = [];
|
|
137
|
+
let hasOwnRoute = method === METHOD_NAME_ALL;
|
|
138
|
+
[this.middleware, this.routes].forEach((r) => {
|
|
139
|
+
const ownRoute = r[method]
|
|
140
|
+
? Object.keys(r[method]).map((path) => [path, r[method][path]])
|
|
141
|
+
: [];
|
|
142
|
+
if (ownRoute.length !== 0) {
|
|
143
|
+
hasOwnRoute || (hasOwnRoute = true);
|
|
144
|
+
routes.push(...ownRoute);
|
|
342
145
|
}
|
|
343
|
-
if (
|
|
344
|
-
|
|
146
|
+
else if (method !== METHOD_NAME_ALL) {
|
|
147
|
+
routes.push(...Object.keys(r[METHOD_NAME_ALL]).map((path) => [path, r[METHOD_NAME_ALL][path]]));
|
|
345
148
|
}
|
|
149
|
+
});
|
|
150
|
+
if (!hasOwnRoute) {
|
|
151
|
+
return null;
|
|
346
152
|
}
|
|
347
|
-
|
|
348
|
-
return
|
|
349
|
-
}
|
|
350
|
-
const primaryRoutes = [];
|
|
351
|
-
const secondaryRoutes = [];
|
|
352
|
-
for (let i = 0, len = routes.length; i < len; i++) {
|
|
353
|
-
if (routes[i].hint.maybeHandler || !routes[i].hint.endWithWildcard) {
|
|
354
|
-
primaryRoutes.push(routes[i]);
|
|
355
|
-
}
|
|
356
|
-
else {
|
|
357
|
-
secondaryRoutes.push(routes[i]);
|
|
358
|
-
}
|
|
153
|
+
else {
|
|
154
|
+
return buildMatcherFromPreprocessedRoutes(routes);
|
|
359
155
|
}
|
|
360
|
-
return [
|
|
361
|
-
buildMatcherFromPreprocessedRoutes(primaryRoutes, hasAmbiguous),
|
|
362
|
-
[buildMatcherFromPreprocessedRoutes(secondaryRoutes, hasAmbiguous)],
|
|
363
|
-
hasAmbiguous,
|
|
364
|
-
];
|
|
365
156
|
}
|
|
366
157
|
}
|
|
367
|
-
exports.RegExpRouter = RegExpRouter;
|
|
@@ -2,13 +2,9 @@ import type { ParamMap, Context } from './node';
|
|
|
2
2
|
import { Node } from './node';
|
|
3
3
|
export type { ParamMap } from './node';
|
|
4
4
|
export declare type ReplacementMap = number[];
|
|
5
|
-
interface InitOptions {
|
|
6
|
-
reverse: boolean;
|
|
7
|
-
}
|
|
8
5
|
export declare class Trie {
|
|
9
6
|
context: Context;
|
|
10
7
|
root: Node;
|
|
11
|
-
constructor({ reverse }?: InitOptions);
|
|
12
8
|
insert(path: string, index: number): ParamMap;
|
|
13
9
|
buildRegExp(): [RegExp, ReplacementMap, ReplacementMap];
|
|
14
10
|
}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const node_1 = require("./node");
|
|
5
|
-
class Trie {
|
|
6
|
-
constructor({ reverse } = { reverse: false }) {
|
|
1
|
+
import { Node } from './node';
|
|
2
|
+
export class Trie {
|
|
3
|
+
constructor() {
|
|
7
4
|
this.context = { varIndex: 0 };
|
|
8
|
-
this.root = new
|
|
5
|
+
this.root = new Node();
|
|
9
6
|
}
|
|
10
7
|
insert(path, index) {
|
|
11
8
|
const paramMap = [];
|
|
@@ -39,4 +36,3 @@ class Trie {
|
|
|
39
36
|
return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];
|
|
40
37
|
}
|
|
41
38
|
}
|
|
42
|
-
exports.Trie = Trie;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SmartRouter } from './router';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { SmartRouter } from './router';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Router, Result } from '../../router';
|
|
2
|
+
export declare class SmartRouter<T> implements Router<T> {
|
|
3
|
+
routers: Router<T>[];
|
|
4
|
+
routes?: [string, string, T][];
|
|
5
|
+
constructor(init: Pick<SmartRouter<T>, 'routers'>);
|
|
6
|
+
add(method: string, path: string, handler: T): void;
|
|
7
|
+
match(method: string, path: string): Result<T> | null;
|
|
8
|
+
get activeRouter(): Router<T>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { UnsupportedPathError } from '../../router';
|
|
2
|
+
export class SmartRouter {
|
|
3
|
+
constructor(init) {
|
|
4
|
+
this.routers = [];
|
|
5
|
+
this.routes = [];
|
|
6
|
+
Object.assign(this, init);
|
|
7
|
+
}
|
|
8
|
+
add(method, path, handler) {
|
|
9
|
+
if (!this.routes) {
|
|
10
|
+
throw new Error('Can not add a route since the matcher is already built.');
|
|
11
|
+
}
|
|
12
|
+
this.routes.push([method, path, handler]);
|
|
13
|
+
}
|
|
14
|
+
match(method, path) {
|
|
15
|
+
if (!this.routes) {
|
|
16
|
+
throw new Error('Fatal error');
|
|
17
|
+
}
|
|
18
|
+
const { routers, routes } = this;
|
|
19
|
+
const len = routers.length;
|
|
20
|
+
let i = 0;
|
|
21
|
+
let res;
|
|
22
|
+
for (; i < len; i++) {
|
|
23
|
+
const router = routers[i];
|
|
24
|
+
try {
|
|
25
|
+
routes.forEach((args) => {
|
|
26
|
+
router.add(...args);
|
|
27
|
+
});
|
|
28
|
+
res = router.match(method, path);
|
|
29
|
+
}
|
|
30
|
+
catch (e) {
|
|
31
|
+
if (e instanceof UnsupportedPathError) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
throw e;
|
|
35
|
+
}
|
|
36
|
+
this.match = router.match.bind(router);
|
|
37
|
+
this.routers = [router];
|
|
38
|
+
this.routes = undefined;
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
if (i === len) {
|
|
42
|
+
// not found
|
|
43
|
+
throw new Error('Fatal error');
|
|
44
|
+
}
|
|
45
|
+
return res || null;
|
|
46
|
+
}
|
|
47
|
+
get activeRouter() {
|
|
48
|
+
if (this.routes || this.routers.length !== 1) {
|
|
49
|
+
throw new Error('No active router has been determined yet.');
|
|
50
|
+
}
|
|
51
|
+
return this.routers[0];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { StaticRouter } from './router';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { StaticRouter } from './router';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Router, Result } from '../../router';
|
|
2
|
+
export declare class StaticRouter<T> implements Router<T> {
|
|
3
|
+
middleware: Record<string, Result<T>>;
|
|
4
|
+
routes: Record<string, Record<string, Result<T>>>;
|
|
5
|
+
constructor();
|
|
6
|
+
add(method: string, path: string, handler: T): void;
|
|
7
|
+
match(method: string, path: string): Result<T> | null;
|
|
8
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { METHOD_NAME_ALL, METHODS, UnsupportedPathError } from '../../router';
|
|
2
|
+
export class StaticRouter {
|
|
3
|
+
constructor() {
|
|
4
|
+
this.middleware = {};
|
|
5
|
+
this.routes = {};
|
|
6
|
+
[METHOD_NAME_ALL, ...METHODS].forEach((method) => {
|
|
7
|
+
this.routes[method.toUpperCase()] = {};
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
add(method, path, handler) {
|
|
11
|
+
var _a;
|
|
12
|
+
const { middleware, routes } = this;
|
|
13
|
+
if (path === '/*') {
|
|
14
|
+
path = '*';
|
|
15
|
+
}
|
|
16
|
+
if (path === '*') {
|
|
17
|
+
if (method === METHOD_NAME_ALL) {
|
|
18
|
+
middleware[METHOD_NAME_ALL] || (middleware[METHOD_NAME_ALL] = { handlers: [], params: {} });
|
|
19
|
+
Object.keys(middleware).forEach((m) => {
|
|
20
|
+
middleware[m].handlers.push(handler);
|
|
21
|
+
});
|
|
22
|
+
Object.keys(routes).forEach((m) => {
|
|
23
|
+
Object.values(routes[m]).forEach((matchRes) => matchRes.handlers.push(handler));
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
middleware[method] || (middleware[method] = {
|
|
28
|
+
handlers: [...(middleware[METHOD_NAME_ALL]?.handlers || [])],
|
|
29
|
+
params: {},
|
|
30
|
+
});
|
|
31
|
+
middleware[method].handlers.push(handler);
|
|
32
|
+
if (routes[method]) {
|
|
33
|
+
Object.values(routes[method]).forEach((matchRes) => matchRes.handlers.push(handler));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (/\*|\/:/.test(path)) {
|
|
39
|
+
throw new UnsupportedPathError(path);
|
|
40
|
+
}
|
|
41
|
+
(_a = routes[method])[path] || (_a[path] = {
|
|
42
|
+
handlers: [
|
|
43
|
+
...(routes[METHOD_NAME_ALL][path]?.handlers ||
|
|
44
|
+
middleware[method]?.handlers ||
|
|
45
|
+
middleware[METHOD_NAME_ALL]?.handlers ||
|
|
46
|
+
[]),
|
|
47
|
+
],
|
|
48
|
+
params: {},
|
|
49
|
+
});
|
|
50
|
+
if (method === METHOD_NAME_ALL) {
|
|
51
|
+
Object.keys(routes).forEach((m) => {
|
|
52
|
+
routes[m][path]?.handlers?.push(handler);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
routes[method][path].handlers.push(handler);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
match(method, path) {
|
|
60
|
+
const { routes, middleware } = this;
|
|
61
|
+
this.match = (method, path) => routes[method][path] ||
|
|
62
|
+
routes[METHOD_NAME_ALL][path] ||
|
|
63
|
+
middleware[method] ||
|
|
64
|
+
middleware[METHOD_NAME_ALL] ||
|
|
65
|
+
null;
|
|
66
|
+
return this.match(method, path);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
@@ -1,5 +1 @@
|
|
|
1
|
-
|
|
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
|
+
export { TrieRouter } from './router';
|