@e22m4u/js-trie-router 0.3.2 → 0.3.4
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/dist/cjs/index.cjs +17 -16
- package/package.json +7 -7
- package/src/hooks/hook-invoker.d.ts +2 -2
- package/src/hooks/hook-invoker.js +2 -2
- package/src/hooks/hook-invoker.spec.js +58 -41
- package/src/hooks/hook-registry.d.ts +52 -7
- package/src/hooks/hook-registry.js +4 -4
- package/src/hooks/hook-registry.spec.js +14 -14
- package/src/route-registry.js +4 -1
- package/src/route.js +3 -3
- package/src/route.spec.js +13 -13
- package/src/trie-router.d.ts +27 -3
- package/src/trie-router.js +6 -6
- package/src/trie-router.spec.js +2 -2
package/dist/cjs/index.cjs
CHANGED
|
@@ -39,7 +39,6 @@ __export(index_exports, {
|
|
|
39
39
|
ErrorSender: () => ErrorSender,
|
|
40
40
|
HookInvoker: () => HookInvoker,
|
|
41
41
|
HookRegistry: () => HookRegistry,
|
|
42
|
-
HookType: () => HookType,
|
|
43
42
|
HttpMethod: () => HttpMethod,
|
|
44
43
|
METHODS_WITH_BODY: () => METHODS_WITH_BODY,
|
|
45
44
|
QueryParser: () => QueryParser,
|
|
@@ -47,6 +46,7 @@ __export(index_exports, {
|
|
|
47
46
|
RequestParser: () => RequestParser,
|
|
48
47
|
Route: () => Route,
|
|
49
48
|
RouteRegistry: () => RouteRegistry,
|
|
49
|
+
RouterHookType: () => RouterHookType,
|
|
50
50
|
RouterOptions: () => RouterOptions,
|
|
51
51
|
TrieRouter: () => TrieRouter,
|
|
52
52
|
UNPARSABLE_MEDIA_TYPES: () => UNPARSABLE_MEDIA_TYPES,
|
|
@@ -70,6 +70,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
70
70
|
|
|
71
71
|
// src/route.js
|
|
72
72
|
var import_js_format14 = require("@e22m4u/js-format");
|
|
73
|
+
var import_js_debug = require("@e22m4u/js-debug");
|
|
73
74
|
|
|
74
75
|
// src/hooks/hook-invoker.js
|
|
75
76
|
var import_js_format13 = require("@e22m4u/js-format");
|
|
@@ -635,7 +636,7 @@ __name(getRequestPathname, "getRequestPathname");
|
|
|
635
636
|
|
|
636
637
|
// src/hooks/hook-registry.js
|
|
637
638
|
var import_js_format12 = require("@e22m4u/js-format");
|
|
638
|
-
var
|
|
639
|
+
var RouterHookType = {
|
|
639
640
|
PRE_HANDLER: "preHandler",
|
|
640
641
|
POST_HANDLER: "postHandler"
|
|
641
642
|
};
|
|
@@ -657,7 +658,7 @@ var _HookRegistry = class _HookRegistry {
|
|
|
657
658
|
addHook(type, hook) {
|
|
658
659
|
if (!type || typeof type !== "string")
|
|
659
660
|
throw new import_js_format12.Errorf("The hook type is required, but %v was given.", type);
|
|
660
|
-
if (!Object.values(
|
|
661
|
+
if (!Object.values(RouterHookType).includes(type))
|
|
661
662
|
throw new import_js_format12.Errorf("The hook type %v is not supported.", type);
|
|
662
663
|
if (!hook || typeof hook !== "function")
|
|
663
664
|
throw new import_js_format12.Errorf(
|
|
@@ -680,7 +681,7 @@ var _HookRegistry = class _HookRegistry {
|
|
|
680
681
|
hasHook(type, hook) {
|
|
681
682
|
if (!type || typeof type !== "string")
|
|
682
683
|
throw new import_js_format12.Errorf("The hook type is required, but %v was given.", type);
|
|
683
|
-
if (!Object.values(
|
|
684
|
+
if (!Object.values(RouterHookType).includes(type))
|
|
684
685
|
throw new import_js_format12.Errorf("The hook type %v is not supported.", type);
|
|
685
686
|
if (!hook || typeof hook !== "function")
|
|
686
687
|
throw new import_js_format12.Errorf(
|
|
@@ -700,7 +701,7 @@ var _HookRegistry = class _HookRegistry {
|
|
|
700
701
|
getHooks(type) {
|
|
701
702
|
if (!type || typeof type !== "string")
|
|
702
703
|
throw new import_js_format12.Errorf("The hook type is required, but %v was given.", type);
|
|
703
|
-
if (!Object.values(
|
|
704
|
+
if (!Object.values(RouterHookType).includes(type))
|
|
704
705
|
throw new import_js_format12.Errorf("The hook type %v is not supported.", type);
|
|
705
706
|
return this._hooks.get(type) || [];
|
|
706
707
|
}
|
|
@@ -749,7 +750,7 @@ var _HookInvoker = class _HookInvoker extends DebuggableService {
|
|
|
749
750
|
'The parameter "hookType" of the HookInvoker.invokeAndContinueUntilValueReceived should be a non-empty String, but %v was given.',
|
|
750
751
|
hookType
|
|
751
752
|
);
|
|
752
|
-
if (!Object.values(
|
|
753
|
+
if (!Object.values(RouterHookType).includes(hookType))
|
|
753
754
|
throw new import_js_format13.Errorf("The hook type %v is not supported.", hookType);
|
|
754
755
|
if (!response || typeof response !== "object" || Array.isArray(response) || typeof response.headersSent !== "boolean") {
|
|
755
756
|
throw new import_js_format13.Errorf(
|
|
@@ -788,7 +789,6 @@ __name(_HookInvoker, "HookInvoker");
|
|
|
788
789
|
var HookInvoker = _HookInvoker;
|
|
789
790
|
|
|
790
791
|
// src/route.js
|
|
791
|
-
var import_js_debug = require("@e22m4u/js-debug");
|
|
792
792
|
var HttpMethod = {
|
|
793
793
|
GET: "GET",
|
|
794
794
|
POST: "POST",
|
|
@@ -894,13 +894,13 @@ var _Route = class _Route extends import_js_debug.Debuggable {
|
|
|
894
894
|
if (routeDef.preHandler != null) {
|
|
895
895
|
const preHandlerHooks = Array.isArray(routeDef.preHandler) ? routeDef.preHandler : [routeDef.preHandler];
|
|
896
896
|
preHandlerHooks.forEach((hook) => {
|
|
897
|
-
this._hookRegistry.addHook(
|
|
897
|
+
this._hookRegistry.addHook(RouterHookType.PRE_HANDLER, hook);
|
|
898
898
|
});
|
|
899
899
|
}
|
|
900
900
|
if (routeDef.postHandler != null) {
|
|
901
901
|
const postHandlerHooks = Array.isArray(routeDef.postHandler) ? routeDef.postHandler : [routeDef.postHandler];
|
|
902
902
|
postHandlerHooks.forEach((hook) => {
|
|
903
|
-
this._hookRegistry.addHook(
|
|
903
|
+
this._hookRegistry.addHook(RouterHookType.POST_HANDLER, hook);
|
|
904
904
|
});
|
|
905
905
|
}
|
|
906
906
|
this.ctorDebug("A new route %s %v was created.", this._method, this._path);
|
|
@@ -1393,7 +1393,8 @@ var _RouteRegistry = class _RouteRegistry extends DebuggableService {
|
|
|
1393
1393
|
req.method.toUpperCase(),
|
|
1394
1394
|
requestPath
|
|
1395
1395
|
);
|
|
1396
|
-
const
|
|
1396
|
+
const rawTriePath = `${req.method.toUpperCase()}/${requestPath}`;
|
|
1397
|
+
const triePath = rawTriePath.replace(/\/+/, "/");
|
|
1397
1398
|
const resolved = this._trie.match(triePath);
|
|
1398
1399
|
if (resolved) {
|
|
1399
1400
|
const route = resolved.value;
|
|
@@ -1638,7 +1639,7 @@ var _TrieRouter = class _TrieRouter extends DebuggableService {
|
|
|
1638
1639
|
const hookInvoker = this.getService(HookInvoker);
|
|
1639
1640
|
data = hookInvoker.invokeAndContinueUntilValueReceived(
|
|
1640
1641
|
route,
|
|
1641
|
-
|
|
1642
|
+
RouterHookType.PRE_HANDLER,
|
|
1642
1643
|
res,
|
|
1643
1644
|
context
|
|
1644
1645
|
);
|
|
@@ -1648,7 +1649,7 @@ var _TrieRouter = class _TrieRouter extends DebuggableService {
|
|
|
1648
1649
|
if (isPromise(data)) data = await data;
|
|
1649
1650
|
let postHandlerData = hookInvoker.invokeAndContinueUntilValueReceived(
|
|
1650
1651
|
route,
|
|
1651
|
-
|
|
1652
|
+
RouterHookType.POST_HANDLER,
|
|
1652
1653
|
res,
|
|
1653
1654
|
context,
|
|
1654
1655
|
data
|
|
@@ -1672,20 +1673,20 @@ var _TrieRouter = class _TrieRouter extends DebuggableService {
|
|
|
1672
1673
|
* Example:
|
|
1673
1674
|
* ```
|
|
1674
1675
|
* import {TrieRouter} from '@e22m4u/js-trie-router';
|
|
1675
|
-
* import {
|
|
1676
|
+
* import {RouterHookType} from '@e22m4u/js-trie-router';
|
|
1676
1677
|
*
|
|
1677
1678
|
* // Router instance.
|
|
1678
1679
|
* const router = new TrieRouter();
|
|
1679
1680
|
*
|
|
1680
1681
|
* // Adds the "preHandler" hook for each route.
|
|
1681
1682
|
* router.addHook(
|
|
1682
|
-
*
|
|
1683
|
+
* RouterHookType.PRE_HANDLER,
|
|
1683
1684
|
* ctx => { ... },
|
|
1684
1685
|
* );
|
|
1685
1686
|
*
|
|
1686
1687
|
* // Adds the "postHandler" hook for each route.
|
|
1687
1688
|
* router.addHook(
|
|
1688
|
-
*
|
|
1689
|
+
* RouterHookType.POST_HANDLER,
|
|
1689
1690
|
* ctx => { ... },
|
|
1690
1691
|
* );
|
|
1691
1692
|
* ```
|
|
@@ -1711,7 +1712,6 @@ var TrieRouter = _TrieRouter;
|
|
|
1711
1712
|
ErrorSender,
|
|
1712
1713
|
HookInvoker,
|
|
1713
1714
|
HookRegistry,
|
|
1714
|
-
HookType,
|
|
1715
1715
|
HttpMethod,
|
|
1716
1716
|
METHODS_WITH_BODY,
|
|
1717
1717
|
QueryParser,
|
|
@@ -1719,6 +1719,7 @@ var TrieRouter = _TrieRouter;
|
|
|
1719
1719
|
RequestParser,
|
|
1720
1720
|
Route,
|
|
1721
1721
|
RouteRegistry,
|
|
1722
|
+
RouterHookType,
|
|
1722
1723
|
RouterOptions,
|
|
1723
1724
|
TrieRouter,
|
|
1724
1725
|
UNPARSABLE_MEDIA_TYPES,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@e22m4u/js-trie-router",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"description": "HTTP маршрутизатор для Node.js на основе префиксного дерева",
|
|
5
5
|
"author": "Mikhail Evstropov <e22m4u@yandex.ru>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"prepare": "husky"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@e22m4u/js-debug": "~0.3.
|
|
41
|
+
"@e22m4u/js-debug": "~0.3.2",
|
|
42
42
|
"@e22m4u/js-format": "~0.2.0",
|
|
43
43
|
"@e22m4u/js-path-trie": "~0.0.12",
|
|
44
|
-
"@e22m4u/js-service": "~0.4.
|
|
44
|
+
"@e22m4u/js-service": "~0.4.4",
|
|
45
45
|
"debug": "~4.4.3",
|
|
46
46
|
"http-errors": "~2.0.0",
|
|
47
47
|
"statuses": "~2.0.2"
|
|
@@ -49,16 +49,16 @@
|
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@commitlint/cli": "~20.1.0",
|
|
51
51
|
"@commitlint/config-conventional": "~20.0.0",
|
|
52
|
-
"@eslint/js": "~9.
|
|
52
|
+
"@eslint/js": "~9.38.0",
|
|
53
53
|
"@types/chai-as-promised": "~8.0.2",
|
|
54
54
|
"c8": "~10.1.3",
|
|
55
55
|
"chai": "~6.2.0",
|
|
56
56
|
"chai-as-promised": "~8.0.2",
|
|
57
|
-
"esbuild": "~0.25.
|
|
58
|
-
"eslint": "~9.
|
|
57
|
+
"esbuild": "~0.25.11",
|
|
58
|
+
"eslint": "~9.38.0",
|
|
59
59
|
"eslint-config-prettier": "~10.1.8",
|
|
60
60
|
"eslint-plugin-chai-expect": "~3.1.0",
|
|
61
|
-
"eslint-plugin-jsdoc": "~61.1.
|
|
61
|
+
"eslint-plugin-jsdoc": "~61.1.11",
|
|
62
62
|
"eslint-plugin-mocha": "~11.2.0",
|
|
63
63
|
"globals": "~16.4.0",
|
|
64
64
|
"husky": "~9.1.7",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {Route} from '../route.js';
|
|
2
2
|
import {ServerResponse} from 'http';
|
|
3
3
|
import {ValueOrPromise} from '../types.js';
|
|
4
|
-
import {
|
|
4
|
+
import {RouterHookType} from './hook-registry.js';
|
|
5
5
|
import {DebuggableService} from '../debuggable-service.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -18,7 +18,7 @@ export declare class HookInvoker extends DebuggableService {
|
|
|
18
18
|
*/
|
|
19
19
|
invokeAndContinueUntilValueReceived(
|
|
20
20
|
route: Route,
|
|
21
|
-
hookType:
|
|
21
|
+
hookType: RouterHookType,
|
|
22
22
|
response: ServerResponse,
|
|
23
23
|
...args: unknown[]
|
|
24
24
|
): ValueOrPromise<unknown>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {Route} from '../route.js';
|
|
2
2
|
import {Errorf} from '@e22m4u/js-format';
|
|
3
3
|
import {isPromise} from '../utils/index.js';
|
|
4
|
-
import {HookType} from './hook-registry.js';
|
|
5
4
|
import {HookRegistry} from './hook-registry.js';
|
|
6
5
|
import {isResponseSent} from '../utils/index.js';
|
|
6
|
+
import {RouterHookType} from './hook-registry.js';
|
|
7
7
|
import {DebuggableService} from '../debuggable-service.js';
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -34,7 +34,7 @@ export class HookInvoker extends DebuggableService {
|
|
|
34
34
|
'should be a non-empty String, but %v was given.',
|
|
35
35
|
hookType,
|
|
36
36
|
);
|
|
37
|
-
if (!Object.values(
|
|
37
|
+
if (!Object.values(RouterHookType).includes(hookType))
|
|
38
38
|
throw new Errorf('The hook type %v is not supported.', hookType);
|
|
39
39
|
if (
|
|
40
40
|
!response ||
|
|
@@ -2,9 +2,9 @@ import {expect} from '../chai.js';
|
|
|
2
2
|
import {Route} from '../route.js';
|
|
3
3
|
import {HttpMethod} from '../route.js';
|
|
4
4
|
import {format} from '@e22m4u/js-format';
|
|
5
|
-
import {HookType} from './hook-registry.js';
|
|
6
5
|
import {HookInvoker} from './hook-invoker.js';
|
|
7
6
|
import {HookRegistry} from './hook-registry.js';
|
|
7
|
+
import {RouterHookType} from './hook-registry.js';
|
|
8
8
|
import {createResponseMock} from '../utils/index.js';
|
|
9
9
|
|
|
10
10
|
describe('HookInvoker', function () {
|
|
@@ -13,7 +13,11 @@ describe('HookInvoker', function () {
|
|
|
13
13
|
const s = new HookInvoker();
|
|
14
14
|
const res = createResponseMock();
|
|
15
15
|
const throwable = v => () =>
|
|
16
|
-
s.invokeAndContinueUntilValueReceived(
|
|
16
|
+
s.invokeAndContinueUntilValueReceived(
|
|
17
|
+
v,
|
|
18
|
+
RouterHookType.PRE_HANDLER,
|
|
19
|
+
res,
|
|
20
|
+
);
|
|
17
21
|
const error = v =>
|
|
18
22
|
format(
|
|
19
23
|
'The parameter "route" of ' +
|
|
@@ -66,7 +70,7 @@ describe('HookInvoker', function () {
|
|
|
66
70
|
expect(throwable({})).to.throw(error('Object'));
|
|
67
71
|
expect(throwable([])).to.throw(error('Array'));
|
|
68
72
|
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
69
|
-
throwable(
|
|
73
|
+
throwable(RouterHookType.PRE_HANDLER)();
|
|
70
74
|
});
|
|
71
75
|
|
|
72
76
|
it('requires the parameter "hookType" to be a supported hook', function () {
|
|
@@ -77,7 +81,7 @@ describe('HookInvoker', function () {
|
|
|
77
81
|
handler: () => undefined,
|
|
78
82
|
});
|
|
79
83
|
const res = createResponseMock();
|
|
80
|
-
Object.values(
|
|
84
|
+
Object.values(RouterHookType).forEach(type =>
|
|
81
85
|
s.invokeAndContinueUntilValueReceived(route, type, res),
|
|
82
86
|
);
|
|
83
87
|
const throwable = () =>
|
|
@@ -93,7 +97,11 @@ describe('HookInvoker', function () {
|
|
|
93
97
|
handler: () => undefined,
|
|
94
98
|
});
|
|
95
99
|
const throwable = v => () =>
|
|
96
|
-
s.invokeAndContinueUntilValueReceived(
|
|
100
|
+
s.invokeAndContinueUntilValueReceived(
|
|
101
|
+
route,
|
|
102
|
+
RouterHookType.PRE_HANDLER,
|
|
103
|
+
v,
|
|
104
|
+
);
|
|
97
105
|
const error = v =>
|
|
98
106
|
format(
|
|
99
107
|
'The parameter "response" of ' +
|
|
@@ -117,10 +125,10 @@ describe('HookInvoker', function () {
|
|
|
117
125
|
it('invokes global hooks in priority', function () {
|
|
118
126
|
const s = new HookInvoker();
|
|
119
127
|
const order = [];
|
|
120
|
-
s.getService(HookRegistry).addHook(
|
|
128
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
121
129
|
order.push('globalHook1');
|
|
122
130
|
});
|
|
123
|
-
s.getService(HookRegistry).addHook(
|
|
131
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
124
132
|
order.push('globalHook2');
|
|
125
133
|
});
|
|
126
134
|
const route = new Route({
|
|
@@ -138,7 +146,7 @@ describe('HookInvoker', function () {
|
|
|
138
146
|
});
|
|
139
147
|
s.invokeAndContinueUntilValueReceived(
|
|
140
148
|
route,
|
|
141
|
-
|
|
149
|
+
RouterHookType.PRE_HANDLER,
|
|
142
150
|
createResponseMock(),
|
|
143
151
|
);
|
|
144
152
|
expect(order).to.be.eql([
|
|
@@ -153,14 +161,14 @@ describe('HookInvoker', function () {
|
|
|
153
161
|
const s = new HookInvoker();
|
|
154
162
|
const order = [];
|
|
155
163
|
const ret = 'OK';
|
|
156
|
-
s.getService(HookRegistry).addHook(
|
|
164
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
157
165
|
order.push('globalHook1');
|
|
158
166
|
});
|
|
159
|
-
s.getService(HookRegistry).addHook(
|
|
167
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
160
168
|
order.push('globalHook2');
|
|
161
169
|
return ret;
|
|
162
170
|
});
|
|
163
|
-
s.getService(HookRegistry).addHook(
|
|
171
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
164
172
|
order.push('globalHook3');
|
|
165
173
|
});
|
|
166
174
|
const route = new Route({
|
|
@@ -178,7 +186,7 @@ describe('HookInvoker', function () {
|
|
|
178
186
|
});
|
|
179
187
|
const result = s.invokeAndContinueUntilValueReceived(
|
|
180
188
|
route,
|
|
181
|
-
|
|
189
|
+
RouterHookType.PRE_HANDLER,
|
|
182
190
|
createResponseMock(),
|
|
183
191
|
);
|
|
184
192
|
expect(result).to.be.eq(ret);
|
|
@@ -189,10 +197,10 @@ describe('HookInvoker', function () {
|
|
|
189
197
|
const s = new HookInvoker();
|
|
190
198
|
const order = [];
|
|
191
199
|
const ret = 'OK';
|
|
192
|
-
s.getService(HookRegistry).addHook(
|
|
200
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
193
201
|
order.push('globalHook1');
|
|
194
202
|
});
|
|
195
|
-
s.getService(HookRegistry).addHook(
|
|
203
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
196
204
|
order.push('globalHook2');
|
|
197
205
|
});
|
|
198
206
|
const route = new Route({
|
|
@@ -214,7 +222,7 @@ describe('HookInvoker', function () {
|
|
|
214
222
|
});
|
|
215
223
|
const result = s.invokeAndContinueUntilValueReceived(
|
|
216
224
|
route,
|
|
217
|
-
|
|
225
|
+
RouterHookType.PRE_HANDLER,
|
|
218
226
|
createResponseMock(),
|
|
219
227
|
);
|
|
220
228
|
expect(result).to.be.eq(ret);
|
|
@@ -230,14 +238,14 @@ describe('HookInvoker', function () {
|
|
|
230
238
|
const s = new HookInvoker();
|
|
231
239
|
const order = [];
|
|
232
240
|
const res = createResponseMock();
|
|
233
|
-
s.getService(HookRegistry).addHook(
|
|
241
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
234
242
|
order.push('globalHook1');
|
|
235
243
|
});
|
|
236
|
-
s.getService(HookRegistry).addHook(
|
|
244
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
237
245
|
order.push('globalHook2');
|
|
238
246
|
res._headersSent = true;
|
|
239
247
|
});
|
|
240
|
-
s.getService(HookRegistry).addHook(
|
|
248
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
241
249
|
order.push('globalHook3');
|
|
242
250
|
});
|
|
243
251
|
const route = new Route({
|
|
@@ -255,7 +263,7 @@ describe('HookInvoker', function () {
|
|
|
255
263
|
});
|
|
256
264
|
const result = s.invokeAndContinueUntilValueReceived(
|
|
257
265
|
route,
|
|
258
|
-
|
|
266
|
+
RouterHookType.PRE_HANDLER,
|
|
259
267
|
res,
|
|
260
268
|
);
|
|
261
269
|
expect(result).to.be.eq(res);
|
|
@@ -266,10 +274,10 @@ describe('HookInvoker', function () {
|
|
|
266
274
|
const s = new HookInvoker();
|
|
267
275
|
const order = [];
|
|
268
276
|
const res = createResponseMock();
|
|
269
|
-
s.getService(HookRegistry).addHook(
|
|
277
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
270
278
|
order.push('globalHook1');
|
|
271
279
|
});
|
|
272
|
-
s.getService(HookRegistry).addHook(
|
|
280
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
273
281
|
order.push('globalHook2');
|
|
274
282
|
});
|
|
275
283
|
const route = new Route({
|
|
@@ -291,7 +299,7 @@ describe('HookInvoker', function () {
|
|
|
291
299
|
});
|
|
292
300
|
const result = s.invokeAndContinueUntilValueReceived(
|
|
293
301
|
route,
|
|
294
|
-
|
|
302
|
+
RouterHookType.PRE_HANDLER,
|
|
295
303
|
res,
|
|
296
304
|
);
|
|
297
305
|
expect(result).to.be.eq(res);
|
|
@@ -306,13 +314,16 @@ describe('HookInvoker', function () {
|
|
|
306
314
|
it('returns a Promise if any global hook is asynchronous', async function () {
|
|
307
315
|
const s = new HookInvoker();
|
|
308
316
|
const order = [];
|
|
309
|
-
s.getService(HookRegistry).addHook(
|
|
317
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
310
318
|
order.push('globalHook1');
|
|
311
319
|
});
|
|
312
|
-
s.getService(HookRegistry).addHook(
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
320
|
+
s.getService(HookRegistry).addHook(
|
|
321
|
+
RouterHookType.PRE_HANDLER,
|
|
322
|
+
async () => {
|
|
323
|
+
order.push('globalHook2');
|
|
324
|
+
},
|
|
325
|
+
);
|
|
326
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
316
327
|
order.push('globalHook3');
|
|
317
328
|
});
|
|
318
329
|
const route = new Route({
|
|
@@ -330,7 +341,7 @@ describe('HookInvoker', function () {
|
|
|
330
341
|
});
|
|
331
342
|
const promise = s.invokeAndContinueUntilValueReceived(
|
|
332
343
|
route,
|
|
333
|
-
|
|
344
|
+
RouterHookType.PRE_HANDLER,
|
|
334
345
|
createResponseMock(),
|
|
335
346
|
);
|
|
336
347
|
expect(promise).to.be.instanceof(Promise);
|
|
@@ -347,12 +358,18 @@ describe('HookInvoker', function () {
|
|
|
347
358
|
it('returns a Promise if entire global hooks are asynchronous', async function () {
|
|
348
359
|
const s = new HookInvoker();
|
|
349
360
|
const order = [];
|
|
350
|
-
s.getService(HookRegistry).addHook(
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
361
|
+
s.getService(HookRegistry).addHook(
|
|
362
|
+
RouterHookType.PRE_HANDLER,
|
|
363
|
+
async () => {
|
|
364
|
+
order.push('globalHook1');
|
|
365
|
+
},
|
|
366
|
+
);
|
|
367
|
+
s.getService(HookRegistry).addHook(
|
|
368
|
+
RouterHookType.PRE_HANDLER,
|
|
369
|
+
async () => {
|
|
370
|
+
order.push('globalHook2');
|
|
371
|
+
},
|
|
372
|
+
);
|
|
356
373
|
const route = new Route({
|
|
357
374
|
method: HttpMethod.GET,
|
|
358
375
|
path: '/',
|
|
@@ -368,7 +385,7 @@ describe('HookInvoker', function () {
|
|
|
368
385
|
});
|
|
369
386
|
const promise = s.invokeAndContinueUntilValueReceived(
|
|
370
387
|
route,
|
|
371
|
-
|
|
388
|
+
RouterHookType.PRE_HANDLER,
|
|
372
389
|
createResponseMock(),
|
|
373
390
|
);
|
|
374
391
|
expect(promise).to.be.instanceof(Promise);
|
|
@@ -384,10 +401,10 @@ describe('HookInvoker', function () {
|
|
|
384
401
|
it('returns a Promise if any route hook is asynchronous', async function () {
|
|
385
402
|
const s = new HookInvoker();
|
|
386
403
|
const order = [];
|
|
387
|
-
s.getService(HookRegistry).addHook(
|
|
404
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
388
405
|
order.push('globalHook1');
|
|
389
406
|
});
|
|
390
|
-
s.getService(HookRegistry).addHook(
|
|
407
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
391
408
|
order.push('globalHook2');
|
|
392
409
|
});
|
|
393
410
|
const route = new Route({
|
|
@@ -408,7 +425,7 @@ describe('HookInvoker', function () {
|
|
|
408
425
|
});
|
|
409
426
|
const promise = s.invokeAndContinueUntilValueReceived(
|
|
410
427
|
route,
|
|
411
|
-
|
|
428
|
+
RouterHookType.PRE_HANDLER,
|
|
412
429
|
createResponseMock(),
|
|
413
430
|
);
|
|
414
431
|
expect(promise).to.be.instanceof(Promise);
|
|
@@ -425,10 +442,10 @@ describe('HookInvoker', function () {
|
|
|
425
442
|
it('returns a Promise if entire route hooks are asynchronous', async function () {
|
|
426
443
|
const s = new HookInvoker();
|
|
427
444
|
const order = [];
|
|
428
|
-
s.getService(HookRegistry).addHook(
|
|
445
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
429
446
|
order.push('globalHook1');
|
|
430
447
|
});
|
|
431
|
-
s.getService(HookRegistry).addHook(
|
|
448
|
+
s.getService(HookRegistry).addHook(RouterHookType.PRE_HANDLER, () => {
|
|
432
449
|
order.push('globalHook2');
|
|
433
450
|
});
|
|
434
451
|
const route = new Route({
|
|
@@ -446,7 +463,7 @@ describe('HookInvoker', function () {
|
|
|
446
463
|
});
|
|
447
464
|
const promise = s.invokeAndContinueUntilValueReceived(
|
|
448
465
|
route,
|
|
449
|
-
|
|
466
|
+
RouterHookType.PRE_HANDLER,
|
|
450
467
|
createResponseMock(),
|
|
451
468
|
);
|
|
452
469
|
expect(promise).to.be.instanceof(Promise);
|
|
@@ -1,23 +1,35 @@
|
|
|
1
1
|
import {Callable} from '../types.js';
|
|
2
|
+
import {RequestContext} from '../request-context.js';
|
|
2
3
|
import {DebuggableService} from '../debuggable-service.js';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Hook type.
|
|
6
7
|
*/
|
|
7
|
-
export declare const
|
|
8
|
+
export declare const RouterHookType: {
|
|
8
9
|
PRE_HANDLER: 'preHandler';
|
|
9
10
|
POST_HANDLER: 'postHandler';
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
|
-
* Type of
|
|
14
|
+
* Type of RouterHookType.
|
|
14
15
|
*/
|
|
15
|
-
export type
|
|
16
|
+
export type RouterHookType =
|
|
17
|
+
(typeof RouterHookType)[keyof typeof RouterHookType];
|
|
16
18
|
|
|
17
19
|
/**
|
|
18
20
|
* Router hook.
|
|
19
21
|
*/
|
|
20
|
-
export type RouterHook
|
|
22
|
+
export type RouterHook = Callable;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Pre handler hook.
|
|
26
|
+
*/
|
|
27
|
+
export type PreHandlerHook = (ctx: RequestContext) => unknown;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Post handler hook.
|
|
31
|
+
*/
|
|
32
|
+
export type PostHandlerHook = (ctx: RequestContext, data: unknown) => unknown;
|
|
21
33
|
|
|
22
34
|
/**
|
|
23
35
|
* Hook registry.
|
|
@@ -29,7 +41,26 @@ export declare class HookRegistry extends DebuggableService {
|
|
|
29
41
|
* @param type
|
|
30
42
|
* @param hook
|
|
31
43
|
*/
|
|
32
|
-
addHook(type:
|
|
44
|
+
addHook(type: typeof RouterHookType.PRE_HANDLER, hook: PreHandlerHook): this;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Add hook.
|
|
48
|
+
*
|
|
49
|
+
* @param type
|
|
50
|
+
* @param hook
|
|
51
|
+
*/
|
|
52
|
+
addHook(
|
|
53
|
+
type: typeof RouterHookType.POST_HANDLER,
|
|
54
|
+
hook: PostHandlerHook,
|
|
55
|
+
): this;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Add hook.
|
|
59
|
+
*
|
|
60
|
+
* @param type
|
|
61
|
+
* @param hook
|
|
62
|
+
*/
|
|
63
|
+
addHook(type: RouterHookType, hook: RouterHook): this;
|
|
33
64
|
|
|
34
65
|
/**
|
|
35
66
|
* Has hook.
|
|
@@ -37,12 +68,26 @@ export declare class HookRegistry extends DebuggableService {
|
|
|
37
68
|
* @param type
|
|
38
69
|
* @param hook
|
|
39
70
|
*/
|
|
40
|
-
hasHook(type:
|
|
71
|
+
hasHook(type: RouterHookType, hook: RouterHook): boolean;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get hooks.
|
|
75
|
+
*
|
|
76
|
+
* @param type
|
|
77
|
+
*/
|
|
78
|
+
getHooks(type: typeof RouterHookType.PRE_HANDLER): PreHandlerHook[];
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get hooks.
|
|
82
|
+
*
|
|
83
|
+
* @param type
|
|
84
|
+
*/
|
|
85
|
+
getHooks(type: typeof RouterHookType.POST_HANDLER): PostHandlerHook[];
|
|
41
86
|
|
|
42
87
|
/**
|
|
43
88
|
* Get hooks.
|
|
44
89
|
*
|
|
45
90
|
* @param type
|
|
46
91
|
*/
|
|
47
|
-
getHooks(type:
|
|
92
|
+
getHooks(type: RouterHookType): RouterHook[];
|
|
48
93
|
}
|
|
@@ -8,7 +8,7 @@ import {Errorf} from '@e22m4u/js-format';
|
|
|
8
8
|
* POST_HANDLER: 'postHandler',
|
|
9
9
|
* }}
|
|
10
10
|
*/
|
|
11
|
-
export const
|
|
11
|
+
export const RouterHookType = {
|
|
12
12
|
PRE_HANDLER: 'preHandler',
|
|
13
13
|
POST_HANDLER: 'postHandler',
|
|
14
14
|
};
|
|
@@ -35,7 +35,7 @@ export class HookRegistry {
|
|
|
35
35
|
addHook(type, hook) {
|
|
36
36
|
if (!type || typeof type !== 'string')
|
|
37
37
|
throw new Errorf('The hook type is required, but %v was given.', type);
|
|
38
|
-
if (!Object.values(
|
|
38
|
+
if (!Object.values(RouterHookType).includes(type))
|
|
39
39
|
throw new Errorf('The hook type %v is not supported.', type);
|
|
40
40
|
if (!hook || typeof hook !== 'function')
|
|
41
41
|
throw new Errorf(
|
|
@@ -59,7 +59,7 @@ export class HookRegistry {
|
|
|
59
59
|
hasHook(type, hook) {
|
|
60
60
|
if (!type || typeof type !== 'string')
|
|
61
61
|
throw new Errorf('The hook type is required, but %v was given.', type);
|
|
62
|
-
if (!Object.values(
|
|
62
|
+
if (!Object.values(RouterHookType).includes(type))
|
|
63
63
|
throw new Errorf('The hook type %v is not supported.', type);
|
|
64
64
|
if (!hook || typeof hook !== 'function')
|
|
65
65
|
throw new Errorf(
|
|
@@ -80,7 +80,7 @@ export class HookRegistry {
|
|
|
80
80
|
getHooks(type) {
|
|
81
81
|
if (!type || typeof type !== 'string')
|
|
82
82
|
throw new Errorf('The hook type is required, but %v was given.', type);
|
|
83
|
-
if (!Object.values(
|
|
83
|
+
if (!Object.values(RouterHookType).includes(type))
|
|
84
84
|
throw new Errorf('The hook type %v is not supported.', type);
|
|
85
85
|
return this._hooks.get(type) || [];
|
|
86
86
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {expect} from '../chai.js';
|
|
2
2
|
import {format} from '@e22m4u/js-format';
|
|
3
|
-
import {HookType} from './hook-registry.js';
|
|
4
3
|
import {HookRegistry} from './hook-registry.js';
|
|
4
|
+
import {RouterHookType} from './hook-registry.js';
|
|
5
5
|
|
|
6
6
|
describe('HookRegistry', function () {
|
|
7
7
|
describe('addHook', function () {
|
|
@@ -20,12 +20,12 @@ describe('HookRegistry', function () {
|
|
|
20
20
|
expect(throwable([])).to.throw(error('Array'));
|
|
21
21
|
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
22
22
|
expect(throwable(() => undefined)).to.throw(error('Function'));
|
|
23
|
-
throwable(
|
|
23
|
+
throwable(RouterHookType.PRE_HANDLER)();
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
it('requires the parameter "hook" to be a Function', function () {
|
|
27
27
|
const s = new HookRegistry();
|
|
28
|
-
const throwable = v => () => s.addHook(
|
|
28
|
+
const throwable = v => () => s.addHook(RouterHookType.PRE_HANDLER, v);
|
|
29
29
|
const error = v =>
|
|
30
30
|
format(
|
|
31
31
|
'The hook "preHandler" should be a Function, but %s was given.',
|
|
@@ -47,14 +47,14 @@ describe('HookRegistry', function () {
|
|
|
47
47
|
it('requires the parameter "type" to be a supported hook', function () {
|
|
48
48
|
const s = new HookRegistry();
|
|
49
49
|
const hook = () => undefined;
|
|
50
|
-
Object.values(
|
|
50
|
+
Object.values(RouterHookType).forEach(type => s.addHook(type, hook));
|
|
51
51
|
const throwable = () => s.addHook('unknown', hook);
|
|
52
52
|
expect(throwable).to.throw('The hook type "unknown" is not supported.');
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
it('sets the given function to the map array by the hook type', function () {
|
|
56
56
|
const s = new HookRegistry();
|
|
57
|
-
const type =
|
|
57
|
+
const type = RouterHookType.PRE_HANDLER;
|
|
58
58
|
const hook = () => undefined;
|
|
59
59
|
s.addHook(type, hook);
|
|
60
60
|
expect(s._hooks.get(type)).to.include(hook);
|
|
@@ -63,7 +63,7 @@ describe('HookRegistry', function () {
|
|
|
63
63
|
it('returns this', function () {
|
|
64
64
|
const s = new HookRegistry();
|
|
65
65
|
const hook = () => undefined;
|
|
66
|
-
const type =
|
|
66
|
+
const type = RouterHookType.PRE_HANDLER;
|
|
67
67
|
const res = s.addHook(type, hook);
|
|
68
68
|
expect(res).to.be.eq(s);
|
|
69
69
|
});
|
|
@@ -85,12 +85,12 @@ describe('HookRegistry', function () {
|
|
|
85
85
|
expect(throwable([])).to.throw(error('Array'));
|
|
86
86
|
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
87
87
|
expect(throwable(() => undefined)).to.throw(error('Function'));
|
|
88
|
-
throwable(
|
|
88
|
+
throwable(RouterHookType.PRE_HANDLER)();
|
|
89
89
|
});
|
|
90
90
|
|
|
91
91
|
it('requires the parameter "hook" to be a Function', function () {
|
|
92
92
|
const s = new HookRegistry();
|
|
93
|
-
const throwable = v => () => s.hasHook(
|
|
93
|
+
const throwable = v => () => s.hasHook(RouterHookType.PRE_HANDLER, v);
|
|
94
94
|
const error = v =>
|
|
95
95
|
format(
|
|
96
96
|
'The hook "preHandler" should be a Function, but %s was given.',
|
|
@@ -112,14 +112,14 @@ describe('HookRegistry', function () {
|
|
|
112
112
|
it('requires the parameter "type" to be a supported hook', function () {
|
|
113
113
|
const s = new HookRegistry();
|
|
114
114
|
const hook = () => undefined;
|
|
115
|
-
Object.values(
|
|
115
|
+
Object.values(RouterHookType).forEach(type => s.hasHook(type, hook));
|
|
116
116
|
const throwable = () => s.hasHook('unknown', hook);
|
|
117
117
|
expect(throwable).to.throw('The hook type "unknown" is not supported.');
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
it('returns true if the given hook is set or false', function () {
|
|
121
121
|
const s = new HookRegistry();
|
|
122
|
-
const type =
|
|
122
|
+
const type = RouterHookType.PRE_HANDLER;
|
|
123
123
|
const hook = () => undefined;
|
|
124
124
|
expect(s.hasHook(type, hook)).to.be.false;
|
|
125
125
|
s.addHook(type, hook);
|
|
@@ -143,12 +143,12 @@ describe('HookRegistry', function () {
|
|
|
143
143
|
expect(throwable([])).to.throw(error('Array'));
|
|
144
144
|
expect(throwable(undefined)).to.throw(error('undefined'));
|
|
145
145
|
expect(throwable(() => undefined)).to.throw(error('Function'));
|
|
146
|
-
throwable(
|
|
146
|
+
throwable(RouterHookType.PRE_HANDLER)();
|
|
147
147
|
});
|
|
148
148
|
|
|
149
149
|
it('requires the parameter "type" to be a supported hook', function () {
|
|
150
150
|
const s = new HookRegistry();
|
|
151
|
-
Object.values(
|
|
151
|
+
Object.values(RouterHookType).forEach(type => s.getHooks(type));
|
|
152
152
|
const throwable = () => s.getHooks('unknown');
|
|
153
153
|
expect(throwable).to.throw('The hook type "unknown" is not supported.');
|
|
154
154
|
});
|
|
@@ -156,7 +156,7 @@ describe('HookRegistry', function () {
|
|
|
156
156
|
it('returns existing hooks', function () {
|
|
157
157
|
const s = new HookRegistry();
|
|
158
158
|
const hook = () => undefined;
|
|
159
|
-
const type =
|
|
159
|
+
const type = RouterHookType.PRE_HANDLER;
|
|
160
160
|
const res1 = s.getHooks(type);
|
|
161
161
|
expect(res1).to.be.eql([]);
|
|
162
162
|
s.addHook(type, hook);
|
|
@@ -167,7 +167,7 @@ describe('HookRegistry', function () {
|
|
|
167
167
|
|
|
168
168
|
it('returns an empty array if no hook exists', function () {
|
|
169
169
|
const s = new HookRegistry();
|
|
170
|
-
const res = s.getHooks(
|
|
170
|
+
const res = s.getHooks(RouterHookType.PRE_HANDLER);
|
|
171
171
|
expect(res).to.be.eql([]);
|
|
172
172
|
});
|
|
173
173
|
});
|
package/src/route-registry.js
CHANGED
|
@@ -63,7 +63,10 @@ export class RouteRegistry extends DebuggableService {
|
|
|
63
63
|
req.method.toUpperCase(),
|
|
64
64
|
requestPath,
|
|
65
65
|
);
|
|
66
|
-
const
|
|
66
|
+
const rawTriePath = `${req.method.toUpperCase()}/${requestPath}`;
|
|
67
|
+
// маршрут формируется с удалением дубликатов косой черты
|
|
68
|
+
// "OPTIONS//api/users/login" => "OPTIONS/api/users/login"
|
|
69
|
+
const triePath = rawTriePath.replace(/\/+/, '/');
|
|
67
70
|
const resolved = this._trie.match(triePath);
|
|
68
71
|
if (resolved) {
|
|
69
72
|
const route = resolved.value;
|
package/src/route.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {Errorf} from '@e22m4u/js-format';
|
|
2
|
-
import {HookType} from './hooks/index.js';
|
|
3
2
|
import {Debuggable} from '@e22m4u/js-debug';
|
|
4
3
|
import {HookRegistry} from './hooks/index.js';
|
|
4
|
+
import {RouterHookType} from './hooks/index.js';
|
|
5
5
|
import {getRequestPathname} from './utils/index.js';
|
|
6
6
|
import {MODULE_DEBUG_NAMESPACE} from './debuggable-service.js';
|
|
7
7
|
|
|
@@ -153,7 +153,7 @@ export class Route extends Debuggable {
|
|
|
153
153
|
? routeDef.preHandler
|
|
154
154
|
: [routeDef.preHandler];
|
|
155
155
|
preHandlerHooks.forEach(hook => {
|
|
156
|
-
this._hookRegistry.addHook(
|
|
156
|
+
this._hookRegistry.addHook(RouterHookType.PRE_HANDLER, hook);
|
|
157
157
|
});
|
|
158
158
|
}
|
|
159
159
|
if (routeDef.postHandler != null) {
|
|
@@ -161,7 +161,7 @@ export class Route extends Debuggable {
|
|
|
161
161
|
? routeDef.postHandler
|
|
162
162
|
: [routeDef.postHandler];
|
|
163
163
|
postHandlerHooks.forEach(hook => {
|
|
164
|
-
this._hookRegistry.addHook(
|
|
164
|
+
this._hookRegistry.addHook(RouterHookType.POST_HANDLER, hook);
|
|
165
165
|
});
|
|
166
166
|
}
|
|
167
167
|
this.ctorDebug('A new route %s %v was created.', this._method, this._path);
|
package/src/route.spec.js
CHANGED
|
@@ -2,7 +2,7 @@ import {Route} from './route.js';
|
|
|
2
2
|
import {expect} from './chai.js';
|
|
3
3
|
import {HttpMethod} from './route.js';
|
|
4
4
|
import {format} from '@e22m4u/js-format';
|
|
5
|
-
import {
|
|
5
|
+
import {RouterHookType} from './hooks/index.js';
|
|
6
6
|
import {createRequestMock} from './utils/index.js';
|
|
7
7
|
import {createResponseMock} from './utils/index.js';
|
|
8
8
|
import {RequestContext} from './request-context.js';
|
|
@@ -238,8 +238,8 @@ describe('Route', function () {
|
|
|
238
238
|
preHandler: value,
|
|
239
239
|
handler: () => undefined,
|
|
240
240
|
});
|
|
241
|
-
expect(route.hookRegistry.hasHook(
|
|
242
|
-
.true;
|
|
241
|
+
expect(route.hookRegistry.hasHook(RouterHookType.PRE_HANDLER, value)).to
|
|
242
|
+
.be.true;
|
|
243
243
|
});
|
|
244
244
|
|
|
245
245
|
it('adds Function items of an Array to "preHandler" hooks', function () {
|
|
@@ -250,10 +250,10 @@ describe('Route', function () {
|
|
|
250
250
|
preHandler: value,
|
|
251
251
|
handler: () => undefined,
|
|
252
252
|
});
|
|
253
|
-
expect(route.hookRegistry.hasHook(
|
|
254
|
-
.true;
|
|
255
|
-
expect(route.hookRegistry.hasHook(
|
|
256
|
-
.true;
|
|
253
|
+
expect(route.hookRegistry.hasHook(RouterHookType.PRE_HANDLER, value[0]))
|
|
254
|
+
.to.be.true;
|
|
255
|
+
expect(route.hookRegistry.hasHook(RouterHookType.PRE_HANDLER, value[1]))
|
|
256
|
+
.to.be.true;
|
|
257
257
|
});
|
|
258
258
|
|
|
259
259
|
it('adds a Function to "postHandler" hooks', function () {
|
|
@@ -264,8 +264,8 @@ describe('Route', function () {
|
|
|
264
264
|
handler: () => undefined,
|
|
265
265
|
postHandler: value,
|
|
266
266
|
});
|
|
267
|
-
expect(route.hookRegistry.hasHook(
|
|
268
|
-
.true;
|
|
267
|
+
expect(route.hookRegistry.hasHook(RouterHookType.POST_HANDLER, value)).to
|
|
268
|
+
.be.true;
|
|
269
269
|
});
|
|
270
270
|
|
|
271
271
|
it('adds Function items of an Array to "postHandler" hooks', function () {
|
|
@@ -276,10 +276,10 @@ describe('Route', function () {
|
|
|
276
276
|
handler: () => undefined,
|
|
277
277
|
postHandler: value,
|
|
278
278
|
});
|
|
279
|
-
expect(route.hookRegistry.hasHook(
|
|
280
|
-
.true;
|
|
281
|
-
expect(route.hookRegistry.hasHook(
|
|
282
|
-
.true;
|
|
279
|
+
expect(route.hookRegistry.hasHook(RouterHookType.POST_HANDLER, value[0]))
|
|
280
|
+
.to.be.true;
|
|
281
|
+
expect(route.hookRegistry.hasHook(RouterHookType.POST_HANDLER, value[1]))
|
|
282
|
+
.to.be.true;
|
|
283
283
|
});
|
|
284
284
|
});
|
|
285
285
|
|
package/src/trie-router.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import {Route} from './route.js';
|
|
2
2
|
import {RequestListener} from 'http';
|
|
3
|
-
import {HookType} from './hooks/index.js';
|
|
4
3
|
import {RouteDefinition} from './route.js';
|
|
5
|
-
import {RouterHook} from './hooks/index.js';
|
|
6
4
|
import {DebuggableService} from './debuggable-service.js';
|
|
7
5
|
|
|
6
|
+
import {
|
|
7
|
+
RouterHook,
|
|
8
|
+
RouterHookType,
|
|
9
|
+
PostHandlerHook,
|
|
10
|
+
PreHandlerHook,
|
|
11
|
+
} from './hooks/index.js';
|
|
12
|
+
|
|
8
13
|
/**
|
|
9
14
|
* Trie router.
|
|
10
15
|
*/
|
|
@@ -62,5 +67,24 @@ export declare class TrieRouter extends DebuggableService {
|
|
|
62
67
|
* @param type
|
|
63
68
|
* @param hook
|
|
64
69
|
*/
|
|
65
|
-
addHook(type:
|
|
70
|
+
addHook(type: typeof RouterHookType.PRE_HANDLER, hook: PreHandlerHook): this;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Add hook.
|
|
74
|
+
*
|
|
75
|
+
* @param type
|
|
76
|
+
* @param hook
|
|
77
|
+
*/
|
|
78
|
+
addHook(
|
|
79
|
+
type: typeof RouterHookType.POST_HANDLER,
|
|
80
|
+
hook: PostHandlerHook,
|
|
81
|
+
): this;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Add hook.
|
|
85
|
+
*
|
|
86
|
+
* @param type
|
|
87
|
+
* @param hook
|
|
88
|
+
*/
|
|
89
|
+
addHook(type: RouterHookType, hook: RouterHook): this;
|
|
66
90
|
}
|
package/src/trie-router.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {ServerResponse} from 'http';
|
|
2
2
|
import {IncomingMessage} from 'http';
|
|
3
|
-
import {HookType} from './hooks/index.js';
|
|
4
3
|
import {isPromise} from './utils/index.js';
|
|
5
4
|
import {HookInvoker} from './hooks/index.js';
|
|
6
5
|
import {DataSender} from './senders/index.js';
|
|
7
6
|
import {HookRegistry} from './hooks/index.js';
|
|
8
7
|
import {ErrorSender} from './senders/index.js';
|
|
9
8
|
import {isResponseSent} from './utils/index.js';
|
|
9
|
+
import {RouterHookType} from './hooks/index.js';
|
|
10
10
|
import {RequestParser} from './parsers/index.js';
|
|
11
11
|
import {RouteRegistry} from './route-registry.js';
|
|
12
12
|
import {RequestContext} from './request-context.js';
|
|
@@ -134,7 +134,7 @@ export class TrieRouter extends DebuggableService {
|
|
|
134
134
|
// то такое значение используется в качестве ответа
|
|
135
135
|
data = hookInvoker.invokeAndContinueUntilValueReceived(
|
|
136
136
|
route,
|
|
137
|
-
|
|
137
|
+
RouterHookType.PRE_HANDLER,
|
|
138
138
|
res,
|
|
139
139
|
context,
|
|
140
140
|
);
|
|
@@ -150,7 +150,7 @@ export class TrieRouter extends DebuggableService {
|
|
|
150
150
|
// также может быть использован в качестве ответа
|
|
151
151
|
let postHandlerData = hookInvoker.invokeAndContinueUntilValueReceived(
|
|
152
152
|
route,
|
|
153
|
-
|
|
153
|
+
RouterHookType.POST_HANDLER,
|
|
154
154
|
res,
|
|
155
155
|
context,
|
|
156
156
|
data,
|
|
@@ -178,20 +178,20 @@ export class TrieRouter extends DebuggableService {
|
|
|
178
178
|
* Example:
|
|
179
179
|
* ```
|
|
180
180
|
* import {TrieRouter} from '@e22m4u/js-trie-router';
|
|
181
|
-
* import {
|
|
181
|
+
* import {RouterHookType} from '@e22m4u/js-trie-router';
|
|
182
182
|
*
|
|
183
183
|
* // Router instance.
|
|
184
184
|
* const router = new TrieRouter();
|
|
185
185
|
*
|
|
186
186
|
* // Adds the "preHandler" hook for each route.
|
|
187
187
|
* router.addHook(
|
|
188
|
-
*
|
|
188
|
+
* RouterHookType.PRE_HANDLER,
|
|
189
189
|
* ctx => { ... },
|
|
190
190
|
* );
|
|
191
191
|
*
|
|
192
192
|
* // Adds the "postHandler" hook for each route.
|
|
193
193
|
* router.addHook(
|
|
194
|
-
*
|
|
194
|
+
* RouterHookType.POST_HANDLER,
|
|
195
195
|
* ctx => { ... },
|
|
196
196
|
* );
|
|
197
197
|
* ```
|
package/src/trie-router.spec.js
CHANGED
|
@@ -3,11 +3,11 @@ import {expect} from './chai.js';
|
|
|
3
3
|
import {ServerResponse} from 'http';
|
|
4
4
|
import {IncomingMessage} from 'http';
|
|
5
5
|
import {HttpMethod} from './route.js';
|
|
6
|
-
import {HookType} from './hooks/index.js';
|
|
7
6
|
import {TrieRouter} from './trie-router.js';
|
|
8
7
|
import {HookRegistry} from './hooks/index.js';
|
|
9
8
|
import {DataSender} from './senders/index.js';
|
|
10
9
|
import {ErrorSender} from './senders/index.js';
|
|
10
|
+
import {RouterHookType} from './hooks/index.js';
|
|
11
11
|
import {createRequestMock} from './utils/index.js';
|
|
12
12
|
import {createResponseMock} from './utils/index.js';
|
|
13
13
|
import {RequestContext} from './request-context.js';
|
|
@@ -563,7 +563,7 @@ describe('TrieRouter', function () {
|
|
|
563
563
|
it('adds the given hook to the HookRegistry and returns itself', function () {
|
|
564
564
|
const router = new TrieRouter();
|
|
565
565
|
const reg = router.getService(HookRegistry);
|
|
566
|
-
const type =
|
|
566
|
+
const type = RouterHookType.PRE_HANDLER;
|
|
567
567
|
const hook = () => undefined;
|
|
568
568
|
expect(reg.hasHook(type, hook)).to.be.false;
|
|
569
569
|
const res = router.addHook(type, hook);
|