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.
Files changed (145) hide show
  1. package/README.md +13 -14
  2. package/dist/cjs/compose.js +48 -0
  3. package/dist/cjs/context.js +147 -0
  4. package/dist/cjs/hono.js +152 -0
  5. package/dist/cjs/index.js +13 -0
  6. package/dist/cjs/middleware/basic-auth/index.js +48 -0
  7. package/dist/cjs/middleware/bearer-auth/index.js +57 -0
  8. package/dist/cjs/middleware/cache/index.js +32 -0
  9. package/dist/cjs/middleware/compress/index.js +19 -0
  10. package/dist/cjs/middleware/cors/index.js +75 -0
  11. package/dist/cjs/middleware/etag/index.js +27 -0
  12. package/dist/cjs/middleware/html/index.js +36 -0
  13. package/dist/cjs/middleware/jsx/index.js +193 -0
  14. package/dist/cjs/middleware/jsx/jsx-dev-runtime.js +10 -0
  15. package/dist/cjs/middleware/jsx/jsx-runtime.js +7 -0
  16. package/dist/cjs/middleware/jwt/index.js +63 -0
  17. package/dist/cjs/middleware/logger/index.js +49 -0
  18. package/dist/cjs/middleware/powered-by/index.js +10 -0
  19. package/dist/cjs/middleware/pretty-json/index.js +11 -0
  20. package/dist/cjs/middleware/serve-static/bun.js +41 -0
  21. package/dist/cjs/middleware/serve-static/index.js +5 -0
  22. package/dist/cjs/middleware/serve-static/serve-static.js +40 -0
  23. package/dist/cjs/middleware/validator/index.js +5 -0
  24. package/dist/cjs/middleware/validator/middleware.js +56 -0
  25. package/dist/cjs/middleware/validator/rule.js +66 -0
  26. package/dist/cjs/middleware/validator/sanitizer.js +6 -0
  27. package/dist/cjs/middleware/validator/validator.js +195 -0
  28. package/dist/cjs/request.js +120 -0
  29. package/dist/cjs/router/reg-exp-router/index.js +5 -0
  30. package/dist/cjs/router/reg-exp-router/node.js +108 -0
  31. package/dist/cjs/router/reg-exp-router/router.js +161 -0
  32. package/dist/cjs/router/reg-exp-router/trie.js +42 -0
  33. package/dist/cjs/router/smart-router/index.js +5 -0
  34. package/dist/cjs/router/smart-router/router.js +57 -0
  35. package/dist/cjs/router/static-router/index.js +5 -0
  36. package/dist/cjs/router/static-router/router.js +72 -0
  37. package/dist/cjs/router/trie-router/index.js +5 -0
  38. package/dist/cjs/router/trie-router/node.js +175 -0
  39. package/dist/cjs/router/trie-router/router.js +24 -0
  40. package/dist/cjs/router.js +9 -0
  41. package/dist/cjs/utils/body.js +18 -0
  42. package/dist/cjs/utils/buffer.js +39 -0
  43. package/dist/cjs/utils/cloudflare.js +39 -0
  44. package/dist/cjs/utils/cookie.js +40 -0
  45. package/dist/cjs/utils/crypto.js +53 -0
  46. package/dist/cjs/utils/encode.js +80 -0
  47. package/dist/cjs/utils/filepath.js +25 -0
  48. package/dist/cjs/utils/html.js +38 -0
  49. package/dist/cjs/utils/http-status.js +50 -0
  50. package/dist/cjs/utils/json.js +22 -0
  51. package/dist/cjs/utils/jwt/index.js +27 -0
  52. package/dist/cjs/utils/jwt/jwt.js +101 -0
  53. package/dist/cjs/utils/jwt/types.js +49 -0
  54. package/dist/cjs/utils/mime.js +92 -0
  55. package/dist/cjs/utils/url.js +94 -0
  56. package/dist/compose.d.ts +2 -2
  57. package/dist/compose.js +3 -7
  58. package/dist/context.d.ts +14 -9
  59. package/dist/context.js +55 -25
  60. package/dist/hono.d.ts +28 -27
  61. package/dist/hono.js +22 -23
  62. package/dist/index.js +3 -6
  63. package/dist/middleware/basic-auth/index.d.ts +2 -3
  64. package/dist/middleware/basic-auth/index.js +7 -11
  65. package/dist/middleware/bearer-auth/index.d.ts +2 -3
  66. package/dist/middleware/bearer-auth/index.js +4 -12
  67. package/dist/middleware/cache/index.d.ts +2 -3
  68. package/dist/middleware/cache/index.js +1 -5
  69. package/dist/middleware/compress/index.d.ts +2 -3
  70. package/dist/middleware/compress/index.js +1 -5
  71. package/dist/middleware/cors/index.d.ts +3 -4
  72. package/dist/middleware/cors/index.js +16 -6
  73. package/dist/middleware/etag/index.d.ts +2 -3
  74. package/dist/middleware/etag/index.js +3 -7
  75. package/dist/middleware/html/index.js +6 -11
  76. package/dist/middleware/jsx/index.js +9 -15
  77. package/dist/middleware/jsx/jsx-dev-runtime.js +3 -7
  78. package/dist/middleware/jsx/jsx-runtime.js +2 -7
  79. package/dist/middleware/jwt/index.d.ts +2 -3
  80. package/dist/middleware/jwt/index.js +3 -7
  81. package/dist/middleware/logger/index.d.ts +2 -3
  82. package/dist/middleware/logger/index.js +3 -7
  83. package/dist/middleware/powered-by/index.d.ts +2 -3
  84. package/dist/middleware/powered-by/index.js +1 -5
  85. package/dist/middleware/pretty-json/index.d.ts +2 -3
  86. package/dist/middleware/pretty-json/index.js +1 -5
  87. package/dist/middleware/serve-static/bun.d.ts +2 -3
  88. package/dist/middleware/serve-static/bun.js +18 -19
  89. package/dist/middleware/serve-static/index.js +1 -5
  90. package/dist/middleware/serve-static/module.d.mts +1 -1
  91. package/dist/middleware/serve-static/serve-static.d.ts +2 -3
  92. package/dist/middleware/serve-static/serve-static.js +7 -11
  93. package/dist/middleware/validator/index.d.ts +2 -0
  94. package/dist/middleware/validator/index.js +2 -0
  95. package/dist/middleware/validator/middleware.d.ts +21 -0
  96. package/dist/middleware/validator/middleware.js +52 -0
  97. package/dist/middleware/validator/rule.d.ts +21 -0
  98. package/dist/middleware/validator/rule.js +63 -0
  99. package/dist/middleware/validator/sanitizer.d.ts +3 -0
  100. package/dist/middleware/validator/sanitizer.js +3 -0
  101. package/dist/middleware/validator/validator.d.ts +75 -0
  102. package/dist/middleware/validator/validator.js +186 -0
  103. package/dist/request.d.ts +15 -5
  104. package/dist/request.js +58 -28
  105. package/dist/router/reg-exp-router/index.js +1 -5
  106. package/dist/router/reg-exp-router/node.d.ts +1 -3
  107. package/dist/router/reg-exp-router/node.js +21 -17
  108. package/dist/router/reg-exp-router/router.d.ts +3 -27
  109. package/dist/router/reg-exp-router/router.js +105 -315
  110. package/dist/router/reg-exp-router/trie.d.ts +0 -4
  111. package/dist/router/reg-exp-router/trie.js +4 -8
  112. package/dist/router/smart-router/index.d.ts +1 -0
  113. package/dist/router/smart-router/index.js +1 -0
  114. package/dist/router/smart-router/router.d.ts +9 -0
  115. package/dist/router/smart-router/router.js +53 -0
  116. package/dist/router/static-router/index.d.ts +1 -0
  117. package/dist/router/static-router/index.js +1 -0
  118. package/dist/router/static-router/router.d.ts +8 -0
  119. package/dist/router/static-router/router.js +68 -0
  120. package/dist/router/trie-router/index.js +1 -5
  121. package/dist/router/trie-router/node.js +7 -11
  122. package/dist/router/trie-router/router.js +11 -7
  123. package/dist/router.d.ts +3 -0
  124. package/dist/router.js +5 -5
  125. package/dist/utils/body.d.ts +2 -1
  126. package/dist/utils/body.js +1 -5
  127. package/dist/utils/buffer.d.ts +1 -1
  128. package/dist/utils/buffer.js +5 -11
  129. package/dist/utils/cloudflare.d.ts +1 -1
  130. package/dist/utils/cloudflare.js +1 -5
  131. package/dist/utils/cookie.js +2 -7
  132. package/dist/utils/crypto.js +8 -15
  133. package/dist/utils/encode.js +10 -20
  134. package/dist/utils/filepath.js +1 -5
  135. package/dist/utils/html.js +1 -5
  136. package/dist/utils/http-status.js +1 -5
  137. package/dist/utils/json.d.ts +1 -0
  138. package/dist/utils/json.js +18 -0
  139. package/dist/utils/jwt/index.js +1 -27
  140. package/dist/utils/jwt/jwt.js +22 -28
  141. package/dist/utils/jwt/types.js +8 -16
  142. package/dist/utils/mime.js +1 -5
  143. package/dist/utils/url.d.ts +1 -1
  144. package/dist/utils/url.js +18 -22
  145. package/package.json +122 -35
@@ -1,90 +1,28 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RegExpRouter = void 0;
4
- const router_1 = require("../../router");
5
- const trie_1 = require("./trie");
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 initHint(path) {
9
- const components = path.match(/\/(?::\w+{[^}]+}|[^\/]*)/g) || [];
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, hasAmbiguous = false) {
74
- const trie = new trie_1.Trie({ reverse: hasAmbiguous });
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
- const paramMap = trie.insert(routes[i].path, i);
81
- handlers[i] = [
82
- [...routes[i].middleware, ...routes[i].handlers],
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 verifyDuplicateParam(routes) {
112
- const nameMap = {};
113
- for (let i = 0, len = routes.length; i < len; i++) {
114
- const route = routes[i];
115
- for (let k = 0, len = route.hint.namedParams.length; k < len; k++) {
116
- const [index, name] = route.hint.namedParams[k];
117
- if (name in nameMap && index !== nameMap[name]) {
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 true;
52
+ return undefined;
141
53
  }
142
- class RegExpRouter {
54
+ export class RegExpRouter {
143
55
  constructor() {
144
- this.routeData = { index: 0, routes: [], methods: new Set() };
56
+ this.middleware = { [METHOD_NAME_ALL]: {} };
57
+ this.routes = { [METHOD_NAME_ALL]: {} };
145
58
  }
146
59
  add(method, path, handler) {
147
- if (!this.routeData) {
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
- const hint = initHint(path);
156
- const handlerWithSortIndex = {
157
- index,
158
- handler,
159
- };
160
- for (let i = 0, len = routes.length; i < len; i++) {
161
- if (routes[i].method === method && routes[i].path === path) {
162
- routes[i].handlers.push(handlerWithSortIndex);
163
- return;
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 [primaryMatchers, secondaryMatchers, hasAmbiguous] = this.buildAllMatchers();
178
- this.match = hasAmbiguous
179
- ? (method, path) => {
180
- const matcher = (primaryMatchers[method] ||
181
- primaryMatchers[router_1.METHOD_NAME_ALL]);
182
- let match = path.match(matcher[0]);
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
- : (method, path) => {
214
- let matcher = (primaryMatchers[method] || primaryMatchers[router_1.METHOD_NAME_ALL]);
215
- let match = path.match(matcher[0]);
216
- if (!match) {
217
- const matchers = secondaryMatchers[method] || secondaryMatchers[router_1.METHOD_NAME_ALL];
218
- for (let i = 0, len = matchers.length; i < len && !match; i++) {
219
- matcher = matchers[i];
220
- match = path.match(matcher[0]);
221
- }
222
- if (!match) {
223
- return null;
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
- if (!this.routeData) {
241
- throw new Error('Can not call the buildAllMatchers since the matcher is already built.');
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
- const primaryMatchers = {};
266
- const secondaryMatchers = {};
267
- let hasAmbiguous = false;
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, hasAmbiguous = false) {
287
- var _a, _b;
288
- const targetMethods = new Set([method, router_1.METHOD_NAME_ALL]);
289
- // @ts-ignore
290
- const routes = this.routeData.routes.filter(({ method }) => targetMethods.has(method));
291
- // Reset temporary data per method
292
- for (let i = 0, len = routes.length; i < len; i++) {
293
- routes[i].middleware = [];
294
- routes[i].paramAliasMap = {};
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 (!verifyDuplicateParam([routes[i]])) {
344
- throw new Error('Duplicate param name');
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
- if (hasAmbiguous) {
348
- return [buildMatcherFromPreprocessedRoutes(routes, hasAmbiguous), [], hasAmbiguous];
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
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Trie = void 0;
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 node_1.Node({ reverse });
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
- "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
+ export { TrieRouter } from './router';