@boo-labs/server 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +229 -2
- package/index.mjs +23 -0
- package/package.json +71 -4
- package/source/application/Kernel/index.mjs +1137 -0
- package/source/application/Server/index.mjs +1201 -0
- package/source/application/configurations/Http2CleartextServerConfiguration/index.mjs +168 -0
- package/source/application/configurations/Http2SecureServerConfiguration/index.mjs +172 -0
- package/source/application/configurations/HttpServerConfiguration/index.mjs +169 -0
- package/source/application/configurations/HttpsServerConfiguration/index.mjs +172 -0
- package/source/application/configurations/ServerConfiguration/Options/CORSOptions/CORSOptionsValue.mjs +158 -0
- package/source/application/configurations/ServerConfiguration/Options/CORSOptions/index.mjs +87 -0
- package/source/application/configurations/ServerConfiguration/Options/CSRFOptions/CSRFOptionsValue.mjs +178 -0
- package/source/application/configurations/ServerConfiguration/Options/CSRFOptions/index.mjs +80 -0
- package/source/application/configurations/ServerConfiguration/Options/CompressOptions/CompressOptionsValue.mjs +126 -0
- package/source/application/configurations/ServerConfiguration/Options/CompressOptions/index.mjs +81 -0
- package/source/application/configurations/ServerConfiguration/Options/CookieParserOptions/CookieParserOptionsValue.mjs +107 -0
- package/source/application/configurations/ServerConfiguration/Options/CookieParserOptions/index.mjs +82 -0
- package/source/application/configurations/ServerConfiguration/Options/CookieSessionOptions/CookieSessionOptionsValue.mjs +182 -0
- package/source/application/configurations/ServerConfiguration/Options/CookieSessionOptions/index.mjs +86 -0
- package/source/application/configurations/ServerConfiguration/Options/ListenOptions/ListenOptionsValue.mjs +95 -0
- package/source/application/configurations/ServerConfiguration/Options/ListenOptions/index.mjs +47 -0
- package/source/application/configurations/ServerConfiguration/Options/MiddlewareOption.mjs +102 -0
- package/source/application/configurations/ServerConfiguration/Options/Options.mjs +105 -0
- package/source/application/configurations/ServerConfiguration/Options/RateLimitOptions/RateLimitOptionsValue.mjs +164 -0
- package/source/application/configurations/ServerConfiguration/Options/RateLimitOptions/index.mjs +84 -0
- package/source/application/configurations/ServerConfiguration/Options/RequestOptions/RequestOptionsValue.mjs +108 -0
- package/source/application/configurations/ServerConfiguration/Options/RequestOptions/index.mjs +47 -0
- package/source/application/configurations/ServerConfiguration/Options/ResponseOptions/ResponseOptionsValue.mjs +101 -0
- package/source/application/configurations/ServerConfiguration/Options/ResponseOptions/index.mjs +47 -0
- package/source/application/configurations/ServerConfiguration/Options/SecurityHeadersOptions/SecurityHeadersOptionsValue.mjs +272 -0
- package/source/application/configurations/ServerConfiguration/Options/SecurityHeadersOptions/index.mjs +85 -0
- package/source/application/configurations/ServerConfiguration/Options/ServerOption.mjs +50 -0
- package/source/application/configurations/ServerConfiguration/Options/StaticOptions/StaticOptionsValue.mjs +164 -0
- package/source/application/configurations/ServerConfiguration/Options/StaticOptions/index.mjs +89 -0
- package/source/application/configurations/ServerConfiguration/index.mjs +781 -0
- package/source/application/resolvers/TransportResolver/index.mjs +119 -0
- package/source/application/use-cases/CloseServer/index.mjs +85 -0
- package/source/application/use-cases/ListenServer/index.mjs +98 -0
- package/source/core/EventSystem/index.mjs +110 -0
- package/source/core/Exchange/ExchangeContext.mjs +291 -0
- package/source/core/Exchange/Telemetry.mjs +193 -0
- package/source/core/Exchange/index.mjs +604 -0
- package/source/core/ExchangeLayerBuilder/index.mjs +133 -0
- package/source/core/IPCMain/IPCMain.mjs +507 -0
- package/source/core/IPCMain/IPCProtocol.mjs +441 -0
- package/source/core/IPCMain/IPCServerChannel.mjs +331 -0
- package/source/core/IPCMain/WebSocketAdapter.mjs +189 -0
- package/source/core/Request/BodyParser/BodyParser.mjs +197 -0
- package/source/core/Request/BodyParser/JSONParser.mjs +70 -0
- package/source/core/Request/BodyParser/MultipartParser.mjs +612 -0
- package/source/core/Request/BodyParser/URLEncodedParser.mjs +71 -0
- package/source/core/Request/RequestHeaders.mjs +177 -0
- package/source/core/Request/index.mjs +805 -0
- package/source/core/Response/ResponseHeaders.mjs +402 -0
- package/source/core/Response/index.mjs +1370 -0
- package/source/core/middlewares/CORSMiddleware/index.mjs +289 -0
- package/source/core/middlewares/CSRFMiddleware/index.mjs +284 -0
- package/source/core/middlewares/CompressMiddleware/index.mjs +460 -0
- package/source/core/middlewares/CookieParserMiddleware/index.mjs +194 -0
- package/source/core/middlewares/CookieSessionMiddleware/index.mjs +460 -0
- package/source/core/middlewares/RateLimitMiddleware/index.mjs +245 -0
- package/source/core/middlewares/SecurityHeadersMiddleware/index.mjs +151 -0
- package/source/core/middlewares/StaticMiddleware/index.mjs +628 -0
- package/source/core/routing/ExchangeLayer/ExchangeMatcher.mjs +127 -0
- package/source/core/routing/ExchangeLayer/index.mjs +254 -0
- package/source/core/routing/Pipeline/index.mjs +157 -0
- package/source/core/routing/Router/Route.mjs +184 -0
- package/source/core/routing/Router/index.mjs +523 -0
- package/source/core/routing/RouterRegister/OptionsMiddleware.mjs +147 -0
- package/source/core/routing/RouterRegister/index.mjs +150 -0
- package/source/core/routing/RouterSystem/index.mjs +225 -0
- package/source/core/value-objects/Address/index.mjs +281 -0
- package/source/core/value-objects/Endpoint/index.mjs +293 -0
- package/source/index.mjs +62 -0
- package/source/infrastructure/adapters/Http2Adapter/index.mjs +144 -0
- package/source/infrastructure/adapters/Http2CleartextAdapter/index.mjs +147 -0
- package/source/infrastructure/adapters/HttpAdapter/index.mjs +124 -0
- package/source/infrastructure/adapters/HttpsAdapter/index.mjs +124 -0
- package/source/infrastructure/adapters/TransportAdapter/createWebSocketOpenRequest.mjs +843 -0
- package/source/infrastructure/adapters/TransportAdapter/index.mjs +555 -0
- package/source/shared/Identifier/index.mjs +671 -0
- package/source/shared/constants/symbols/brands/index.mjs +45 -0
- package/source/shared/domain/UUIDV7/index.mjs +346 -0
- package/source/shared/errors/BaseError/index.mjs +157 -0
- package/source/shared/errors/IPCError/index.mjs +97 -0
- package/source/shared/errors/MiddlewareError/index.mjs +106 -0
- package/source/shared/errors/PathnamePatternError/index.mjs +103 -0
- package/source/shared/errors/RequestError/index.mjs +116 -0
- package/source/shared/errors/ResponseError/index.mjs +140 -0
- package/source/shared/errors/RouterError/index.mjs +90 -0
- package/source/shared/errors/ServerConfigurationError/index.mjs +551 -0
- package/source/shared/errors/ServerError/index.mjs +127 -0
- package/source/shared/errors/WebSocketError/index.mjs +58 -0
- package/source/shared/outcome/ErrorSchema.mjs +361 -0
- package/source/shared/outcome/Result/index.mjs +239 -0
- package/source/shared/outcome/Validation/index.mjs +208 -0
- package/source/shared/validations/Middleware/index.mjs +160 -0
- package/source/shared/validations/PathnamePattern/index.mjs +256 -0
- package/source/shared/validations/Server/NotFoundHandler/index.mjs +94 -0
- package/source/shared/validations/Server/Router/index.mjs +68 -0
- package/source/shared/validations/Server/ServerConfiguration/index.mjs +68 -0
- package/source/shared/validations/Server/SystemErrorHandler/index.mjs +94 -0
- package/source/shared/validations/ServerConfiguration/CORSOptions/index.mjs +310 -0
- package/source/shared/validations/ServerConfiguration/CSRFOptions/index.mjs +299 -0
- package/source/shared/validations/ServerConfiguration/CompressOptions/index.mjs +204 -0
- package/source/shared/validations/ServerConfiguration/CookieParserOptions/index.mjs +102 -0
- package/source/shared/validations/ServerConfiguration/CookieSessionOptions/index.mjs +332 -0
- package/source/shared/validations/ServerConfiguration/ListenOptions/index.mjs +178 -0
- package/source/shared/validations/ServerConfiguration/RateLimitOptions/index.mjs +229 -0
- package/source/shared/validations/ServerConfiguration/RequestOptions/index.mjs +132 -0
- package/source/shared/validations/ServerConfiguration/ResponseOptions/index.mjs +122 -0
- package/source/shared/validations/ServerConfiguration/SecurityHeadersOptions/index.mjs +137 -0
- package/source/shared/validations/ServerConfiguration/StaticOptions/index.mjs +248 -0
- package/types/index.d.ts +719 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* @file Defines a route grouped by pathname pattern.
|
|
4
|
+
*
|
|
5
|
+
* @description Stores middleware registered for a pathname pattern, grouped by
|
|
6
|
+
* HTTP method. Middleware registered with `all()` applies to every method
|
|
7
|
+
* registered for the route.
|
|
8
|
+
*
|
|
9
|
+
* When `compose()` is called, the route returns its middleware as exchange
|
|
10
|
+
* layer options.
|
|
11
|
+
*
|
|
12
|
+
* @module Route
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
16
|
+
/**
|
|
17
|
+
* Represents a single HTTP transaction.
|
|
18
|
+
*
|
|
19
|
+
* @typedef {import('#Exchange').default} Exchange
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Represents an HTTP method supported by the routing layer.
|
|
24
|
+
*
|
|
25
|
+
* @typedef {'GET'|'HEAD'|'POST'|'PUT'|'PATCH'|'DELETE'|'OPTIONS'|'QUERY'|'TRACE'} HTTPMethod
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Represents a function that delegates execution to the next middleware layer.
|
|
30
|
+
*
|
|
31
|
+
* @typedef {() => void | Promise<void>} NextFunction
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Represents an exchange middleware function.
|
|
36
|
+
*
|
|
37
|
+
* @typedef {(exchange: Exchange, next: NextFunction) => void | Promise<void>} MiddlewareFunction
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Represents the options used to create an exchange layer.
|
|
42
|
+
*
|
|
43
|
+
* @typedef {object} ExchangeLayerOptions
|
|
44
|
+
* @property {HTTPMethod} method - HTTP method to match. When undefined, any HTTP method is accepted.
|
|
45
|
+
* @property {string} pathnamePattern - URL pathname pattern to match. When undefined, any pathname is accepted.
|
|
46
|
+
* @property {MiddlewareFunction} middleware - Middleware executed when the exchange matches the layer criteria.
|
|
47
|
+
*/
|
|
48
|
+
|
|
49
|
+
// ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
50
|
+
/**
|
|
51
|
+
* Groups middleware definitions by pathname pattern.
|
|
52
|
+
*
|
|
53
|
+
* A route can contain middleware that applies to all registered methods and
|
|
54
|
+
* middleware specific to individual HTTP methods.
|
|
55
|
+
*
|
|
56
|
+
* @classdesc `Route` stores middleware for a single pathname pattern and
|
|
57
|
+
* composes the registered middleware into exchange layer options.
|
|
58
|
+
* */
|
|
59
|
+
class Route {
|
|
60
|
+
/**
|
|
61
|
+
* Stores the pathname pattern associated with the route.
|
|
62
|
+
*
|
|
63
|
+
* @type {string}
|
|
64
|
+
*/
|
|
65
|
+
#pathnamePattern;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Stores middleware applied to all registered methods.
|
|
69
|
+
*
|
|
70
|
+
* @type {MiddlewareFunction[]}
|
|
71
|
+
*/
|
|
72
|
+
#all = [];
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Stores middleware grouped by HTTP method.
|
|
76
|
+
*
|
|
77
|
+
* @type {Map<HTTPMethod, MiddlewareFunction[]>}
|
|
78
|
+
*/
|
|
79
|
+
#methods = new Map();
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Creates a route for a pathname pattern.
|
|
83
|
+
*
|
|
84
|
+
* @param {string} pathnamePattern - The pathname pattern associated with the route.
|
|
85
|
+
* @example
|
|
86
|
+
* ```js
|
|
87
|
+
* const route = new Route('/users');
|
|
88
|
+
* ```
|
|
89
|
+
*/
|
|
90
|
+
constructor(pathnamePattern) {
|
|
91
|
+
this.#pathnamePattern = pathnamePattern;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Lists the HTTP methods registered for the route.
|
|
96
|
+
*
|
|
97
|
+
* @type {HTTPMethod[]}
|
|
98
|
+
*/
|
|
99
|
+
get methods() {
|
|
100
|
+
return [...this.#methods.keys()];
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Registers middleware applied to all methods in the route.
|
|
105
|
+
*
|
|
106
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for all registered methods.
|
|
107
|
+
* @example
|
|
108
|
+
* ```js
|
|
109
|
+
* route.all(authenticate);
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
all(...middlewares) {
|
|
113
|
+
this.#all.push(...middlewares);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Registers middleware for a specific HTTP method.
|
|
118
|
+
*
|
|
119
|
+
* @param {HTTPMethod} method - The HTTP method.
|
|
120
|
+
* @param {MiddlewareFunction[]} middlewares - The middleware functions to execute for the method.
|
|
121
|
+
* @example
|
|
122
|
+
* ```js
|
|
123
|
+
* route.add('GET', [getUsers]);
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
add(method, middlewares) {
|
|
127
|
+
this.#methods.set(method, middlewares);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Composes the registered middleware into exchange layer options.
|
|
132
|
+
*
|
|
133
|
+
* Middleware registered with `all()` is emitted before middleware specific
|
|
134
|
+
* to each HTTP method.
|
|
135
|
+
*
|
|
136
|
+
* @returns {ExchangeLayerOptions[]} The exchange layer options.
|
|
137
|
+
* @example
|
|
138
|
+
* ```js
|
|
139
|
+
* route.add('GET', [getUsers]);
|
|
140
|
+
* route.add('POST', [createUser]);
|
|
141
|
+
*
|
|
142
|
+
* const definitions = route.compose();
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
compose() {
|
|
146
|
+
return this.methods.flatMap(method => [
|
|
147
|
+
...this.#getAll(method),
|
|
148
|
+
...this.#getMethodMiddlewares(method),
|
|
149
|
+
]);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Builds exchange layer options for middleware registered with `all()`.
|
|
154
|
+
*
|
|
155
|
+
* @param {HTTPMethod} method - The HTTP method the options are emitted for.
|
|
156
|
+
* @returns {ExchangeLayerOptions[]} The exchange layer options for all-method middleware.
|
|
157
|
+
*/
|
|
158
|
+
#getAll(method) {
|
|
159
|
+
return this.#all.map(middleware => ({
|
|
160
|
+
method,
|
|
161
|
+
pathnamePattern: this.#pathnamePattern,
|
|
162
|
+
middleware,
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Builds exchange layer options for middleware registered for a specific method.
|
|
168
|
+
*
|
|
169
|
+
* @param {HTTPMethod} method - The HTTP method whose options are emitted.
|
|
170
|
+
* @returns {ExchangeLayerOptions[]} The exchange layer options for the method.
|
|
171
|
+
*/
|
|
172
|
+
#getMethodMiddlewares(method) {
|
|
173
|
+
const methodMiddlewares = this.#methods.get(method) ?? [];
|
|
174
|
+
|
|
175
|
+
return methodMiddlewares.map(middleware => ({
|
|
176
|
+
method,
|
|
177
|
+
pathnamePattern: this.#pathnamePattern,
|
|
178
|
+
middleware,
|
|
179
|
+
}));
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
184
|
+
export default Route;
|
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
/**
|
|
3
|
+
* @file Defines the HTTP route builder.
|
|
4
|
+
*
|
|
5
|
+
* @description Provides a fluent interface for registering middleware functions
|
|
6
|
+
* for HTTP methods and pathname patterns.
|
|
7
|
+
*
|
|
8
|
+
* Each instance maintains route definitions grouped by pathname pattern. A
|
|
9
|
+
* pathname pattern can have one definition per HTTP method, and each definition
|
|
10
|
+
* can contain multiple middleware functions.
|
|
11
|
+
*
|
|
12
|
+
* When `compose()` is called, the router returns the registered exchange layer
|
|
13
|
+
* options.
|
|
14
|
+
*
|
|
15
|
+
* @module Router
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
// ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
19
|
+
// » IMPORT LOCAL MODULES
|
|
20
|
+
import { ROUTER_BRAND } from '#shared/constants/symbols/brands';
|
|
21
|
+
import { assertPathnamePattern } from '#shared/validations/PathnamePattern';
|
|
22
|
+
import { assertMiddlewares } from '#shared/validations/Middleware';
|
|
23
|
+
import RouterError from '#shared/errors/RouterError';
|
|
24
|
+
import Route from './Route.mjs';
|
|
25
|
+
|
|
26
|
+
// ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
27
|
+
/**
|
|
28
|
+
* Represents a single HTTP transaction.
|
|
29
|
+
*
|
|
30
|
+
* @typedef {import('#Exchange').default} Exchange
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* This error type provides identifiable failures related to middleware validation.
|
|
35
|
+
*
|
|
36
|
+
* @typedef {import('#shared/errors/MiddlewareError').default} MiddlewareError
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* This error type provides identifiable failures related to pathname pattern syntax and validation.
|
|
41
|
+
*
|
|
42
|
+
* @typedef {import('#shared/errors/PathnamePatternError').default} PathnamePatternError
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Represents an HTTP method supported by the routing layer.
|
|
47
|
+
*
|
|
48
|
+
* @typedef {import('#routing/ExchangeLayer').HTTPMethod} HTTPMethod
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Represents an exchange middleware function.
|
|
53
|
+
*
|
|
54
|
+
* @typedef {import('#routing/ExchangeLayer').MiddlewareFunction} MiddlewareFunction
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Represents the options used to create an exchange layer.
|
|
59
|
+
*
|
|
60
|
+
* @typedef {object} ExchangeLayerOptions
|
|
61
|
+
* @property {HTTPMethod} method - HTTP method to match.
|
|
62
|
+
* @property {string} pathnamePattern - URL pathname pattern to match.
|
|
63
|
+
* @property {MiddlewareFunction} middleware - Middleware executed when the exchange matches the layer criteria.
|
|
64
|
+
*/
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Represents the result produced by composing a router.
|
|
68
|
+
*
|
|
69
|
+
* @typedef {object} RouterComposition
|
|
70
|
+
* @property {MiddlewareFunction[]} middlewares - Middleware applied to all routes.
|
|
71
|
+
* @property {ExchangeLayerOptions[]} layersOptions - Exchange layer options compiled from the registered routes.
|
|
72
|
+
*/
|
|
73
|
+
// ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
74
|
+
/**
|
|
75
|
+
* Defines HTTP middleware pipelines by pathname pattern and method.
|
|
76
|
+
*
|
|
77
|
+
* @classdesc `Router` provides a fluent API for registering middleware for HTTP
|
|
78
|
+
* methods. Each pathname pattern can have one definition per HTTP method, and
|
|
79
|
+
* multiple middleware functions can be registered for each definition.
|
|
80
|
+
*
|
|
81
|
+
* When `compose()` is called, the router returns the registered exchange layer
|
|
82
|
+
* options.
|
|
83
|
+
*/
|
|
84
|
+
class Router {
|
|
85
|
+
/**
|
|
86
|
+
* Stores middleware applied to all routes in the router.
|
|
87
|
+
*
|
|
88
|
+
* @type {MiddlewareFunction[]}
|
|
89
|
+
*/
|
|
90
|
+
#middlewares = [];
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Stores routes grouped by pathname pattern.
|
|
94
|
+
*
|
|
95
|
+
* @type {Map<string, Route>}
|
|
96
|
+
*/
|
|
97
|
+
#routes;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Stores registered methods and pathname patterns.
|
|
101
|
+
*
|
|
102
|
+
* @type {Set<string>}
|
|
103
|
+
*/
|
|
104
|
+
#registrations;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Creates an instance of Router.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```js
|
|
111
|
+
* const router = new Router();
|
|
112
|
+
*
|
|
113
|
+
* router
|
|
114
|
+
* .get('/users', authenticate, getUsers)
|
|
115
|
+
* .post('/users', authenticate, createUser)
|
|
116
|
+
* .get('/posts/:postId', getPost);
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
constructor() {
|
|
120
|
+
this.#routes = new Map();
|
|
121
|
+
this.#registrations = new Set();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Identifies the object as a router.
|
|
126
|
+
*
|
|
127
|
+
* This branded property provides a stable way to recognize objects that
|
|
128
|
+
* implement the router contract without depending on their concrete
|
|
129
|
+
* implementation.
|
|
130
|
+
*
|
|
131
|
+
* @type {boolean}
|
|
132
|
+
*/
|
|
133
|
+
get [ROUTER_BRAND]() {
|
|
134
|
+
return true;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Registers middleware for all routes in the router.
|
|
139
|
+
*
|
|
140
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for all routes.
|
|
141
|
+
* @returns {Router} The router instance.
|
|
142
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
143
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
144
|
+
* @example
|
|
145
|
+
* ```js
|
|
146
|
+
* router
|
|
147
|
+
* .use(authenticate)
|
|
148
|
+
* .get('/users', getUsers)
|
|
149
|
+
* .post('/users', createUser);
|
|
150
|
+
* ```
|
|
151
|
+
*/
|
|
152
|
+
use(...middlewares) {
|
|
153
|
+
this.#assertMiddlewares(middlewares);
|
|
154
|
+
this.#middlewares.push(...middlewares);
|
|
155
|
+
return this;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Registers middleware for all HTTP methods.
|
|
160
|
+
*
|
|
161
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
162
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for all matching HTTP requests.
|
|
163
|
+
* @returns {Router} The router instance.
|
|
164
|
+
* @throws {RouterError} If middleware has already been registered for the pathname pattern with `all()`.
|
|
165
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
166
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
167
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
168
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
169
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
170
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
171
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
172
|
+
* @example
|
|
173
|
+
* ```js
|
|
174
|
+
* router
|
|
175
|
+
* .all('/users', authenticate)
|
|
176
|
+
* .get('/users', getUsers)
|
|
177
|
+
* .post('/users', createUser);
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
all(pathnamePattern, ...middlewares) {
|
|
181
|
+
this.#addAll(pathnamePattern, middlewares);
|
|
182
|
+
return this;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Registers middleware for GET requests.
|
|
187
|
+
*
|
|
188
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
189
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for matching GET requests.
|
|
190
|
+
* @returns {Router} The router instance.
|
|
191
|
+
* @throws {RouterError} If GET middleware has already been registered for the pathname pattern.
|
|
192
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
193
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
194
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
195
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
196
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
197
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
198
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
199
|
+
* @example
|
|
200
|
+
* ```js
|
|
201
|
+
* router.get('/users', getUsers);
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
get(pathnamePattern, ...middlewares) {
|
|
205
|
+
this.#addRoute('GET', pathnamePattern, middlewares);
|
|
206
|
+
return this;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Registers middleware for QUERY requests.
|
|
211
|
+
*
|
|
212
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
213
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for matching QUERY requests.
|
|
214
|
+
* @returns {Router} The router instance.
|
|
215
|
+
* @throws {RouterError} If QUERY middleware has already been registered for the pathname pattern.
|
|
216
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
217
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
218
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
219
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
220
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
221
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
222
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
223
|
+
* @example
|
|
224
|
+
* ```js
|
|
225
|
+
* router.query('/users', queryUsers);
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
query(pathnamePattern, ...middlewares) {
|
|
229
|
+
this.#addRoute('QUERY', pathnamePattern, middlewares);
|
|
230
|
+
return this;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Registers middleware for POST requests.
|
|
235
|
+
*
|
|
236
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
237
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for matching POST requests.
|
|
238
|
+
* @returns {Router} The router instance.
|
|
239
|
+
* @throws {RouterError} If POST middleware has already been registered for the pathname pattern.
|
|
240
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
241
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
242
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
243
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
244
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
245
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
246
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
247
|
+
* @example
|
|
248
|
+
* ```js
|
|
249
|
+
* router.post('/users', createUser);
|
|
250
|
+
* ```
|
|
251
|
+
*/
|
|
252
|
+
post(pathnamePattern, ...middlewares) {
|
|
253
|
+
this.#addRoute('POST', pathnamePattern, middlewares);
|
|
254
|
+
return this;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Registers middleware for PUT requests.
|
|
259
|
+
*
|
|
260
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
261
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for matching PUT requests.
|
|
262
|
+
* @returns {Router} The router instance.
|
|
263
|
+
* @throws {RouterError} If PUT middleware has already been registered for the pathname pattern.
|
|
264
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
265
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
266
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
267
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
268
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
269
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
270
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
271
|
+
* @example
|
|
272
|
+
* ```js
|
|
273
|
+
* router.put('/users/:userId', updateUser);
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
put(pathnamePattern, ...middlewares) {
|
|
277
|
+
this.#addRoute('PUT', pathnamePattern, middlewares);
|
|
278
|
+
return this;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Registers middleware for PATCH requests.
|
|
283
|
+
*
|
|
284
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
285
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for matching PATCH requests.
|
|
286
|
+
* @returns {Router} The router instance.
|
|
287
|
+
* @throws {RouterError} If PATCH middleware has already been registered for the pathname pattern.
|
|
288
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
289
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
290
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
291
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
292
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
293
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
294
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
295
|
+
* @example
|
|
296
|
+
* ```js
|
|
297
|
+
* router.patch('/users/:userId', patchUser);
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
patch(pathnamePattern, ...middlewares) {
|
|
301
|
+
this.#addRoute('PATCH', pathnamePattern, middlewares);
|
|
302
|
+
return this;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Registers middleware for DELETE requests.
|
|
307
|
+
*
|
|
308
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
309
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for matching DELETE requests.
|
|
310
|
+
* @returns {Router} The router instance.
|
|
311
|
+
* @throws {RouterError} If DELETE middleware has already been registered for the pathname pattern.
|
|
312
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
313
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
314
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
315
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
316
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
317
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
318
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
319
|
+
* @example
|
|
320
|
+
* ```js
|
|
321
|
+
* router.delete('/users/:userId', deleteUser);
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
delete(pathnamePattern, ...middlewares) {
|
|
325
|
+
this.#addRoute('DELETE', pathnamePattern, middlewares);
|
|
326
|
+
return this;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Registers middleware for HEAD requests.
|
|
331
|
+
*
|
|
332
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
333
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for matching HEAD requests.
|
|
334
|
+
* @returns {Router} The router instance.
|
|
335
|
+
* @throws {RouterError} If HEAD middleware has already been registered for the pathname pattern.
|
|
336
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
337
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
338
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
339
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
340
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
341
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
342
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
343
|
+
* @example
|
|
344
|
+
* ```js
|
|
345
|
+
* router.head('/users', checkUsers);
|
|
346
|
+
* ```
|
|
347
|
+
*/
|
|
348
|
+
head(pathnamePattern, ...middlewares) {
|
|
349
|
+
this.#addRoute('HEAD', pathnamePattern, middlewares);
|
|
350
|
+
return this;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Registers middleware for TRACE requests.
|
|
355
|
+
*
|
|
356
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
357
|
+
* @param {...MiddlewareFunction} middlewares - The middleware functions to execute for matching TRACE requests.
|
|
358
|
+
* @returns {Router} The router instance.
|
|
359
|
+
* @throws {RouterError} If TRACE middleware has already been registered for the pathname pattern.
|
|
360
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
361
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
362
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
363
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
364
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
365
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
366
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
367
|
+
* @example
|
|
368
|
+
* ```js
|
|
369
|
+
* router.trace('/debug', traceRequest);
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
trace(pathnamePattern, ...middlewares) {
|
|
373
|
+
this.#addRoute('TRACE', pathnamePattern, middlewares);
|
|
374
|
+
return this;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Composes the registered exchange layer options.
|
|
379
|
+
*
|
|
380
|
+
* @returns {RouterComposition} The composed router configuration.
|
|
381
|
+
* @example
|
|
382
|
+
* ```js
|
|
383
|
+
* const router = new Router();
|
|
384
|
+
*
|
|
385
|
+
* router
|
|
386
|
+
* .get('/users', getUsers)
|
|
387
|
+
* .post('/users', createUser);
|
|
388
|
+
*
|
|
389
|
+
* const composition = router.compose();
|
|
390
|
+
*
|
|
391
|
+
* // composition.layerOptions includes:
|
|
392
|
+
* // { method: 'GET', pathnamePattern: '/users', middleware: getUsers }
|
|
393
|
+
* // { method: 'POST', pathnamePattern: '/users', middleware: createUser }
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
compose() {
|
|
397
|
+
const layersOptions = [...this.#routes.values()].flatMap(route => route.compose());
|
|
398
|
+
const middlewares = [...this.#middlewares];
|
|
399
|
+
return {
|
|
400
|
+
middlewares,
|
|
401
|
+
layersOptions,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Registers middleware for all HTTP methods on a pathname pattern.
|
|
407
|
+
*
|
|
408
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
409
|
+
* @param {MiddlewareFunction[]} middlewares - The middleware functions to register.
|
|
410
|
+
* @throws {PathnamePatternError} If the pathname pattern is invalid.
|
|
411
|
+
* @throws {MiddlewareError} If a middleware is invalid.
|
|
412
|
+
* @throws {RouterError} If middleware has already been registered for the pathname pattern with `all()`.
|
|
413
|
+
*/
|
|
414
|
+
#addAll(pathnamePattern, middlewares) {
|
|
415
|
+
this.#assertPathnamePattern(pathnamePattern);
|
|
416
|
+
this.#assertMiddlewares(middlewares);
|
|
417
|
+
this.#ensureRegistration(undefined, pathnamePattern);
|
|
418
|
+
|
|
419
|
+
const route = this.#routes.get(pathnamePattern);
|
|
420
|
+
|
|
421
|
+
if (route) {
|
|
422
|
+
route.all(...middlewares);
|
|
423
|
+
} else {
|
|
424
|
+
this.#createRoute(pathnamePattern).all(...middlewares);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Registers middleware for a specific HTTP method and pathname pattern.
|
|
430
|
+
*
|
|
431
|
+
* Prevents duplicate method and pathname pattern registrations and groups
|
|
432
|
+
* middleware by pathname pattern.
|
|
433
|
+
*
|
|
434
|
+
* @param {HTTPMethod} method - The HTTP method.
|
|
435
|
+
* @param {string} pathnamePattern - The pathname pattern to match.
|
|
436
|
+
* @param {MiddlewareFunction[]} middlewares - The middleware functions to register.
|
|
437
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
438
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
439
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
440
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
441
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
442
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
443
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
444
|
+
* @throws {RouterError} If the method is already registered for the pathname pattern.
|
|
445
|
+
*/
|
|
446
|
+
#addRoute(method, pathnamePattern, middlewares) {
|
|
447
|
+
this.#assertPathnamePattern(pathnamePattern);
|
|
448
|
+
this.#assertMiddlewares(middlewares);
|
|
449
|
+
this.#ensureRegistration(method, pathnamePattern);
|
|
450
|
+
|
|
451
|
+
const route = this.#routes.get(pathnamePattern);
|
|
452
|
+
|
|
453
|
+
if (route) {
|
|
454
|
+
route.add(method, middlewares);
|
|
455
|
+
} else {
|
|
456
|
+
this.#createRoute(pathnamePattern).add(method, middlewares);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* Creates and stores a route for a pathname pattern.
|
|
462
|
+
*
|
|
463
|
+
* @param {string} pathnamePattern - The pathname pattern to associate with the route.
|
|
464
|
+
* @returns {Route} The created route.
|
|
465
|
+
*/
|
|
466
|
+
#createRoute(pathnamePattern) {
|
|
467
|
+
const route = new Route(pathnamePattern);
|
|
468
|
+
this.#routes.set(pathnamePattern, route);
|
|
469
|
+
return route;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
/**
|
|
473
|
+
* Ensures that a registration is unique for a pathname pattern.
|
|
474
|
+
*
|
|
475
|
+
* @param {string|undefined} method - The HTTP method, or `undefined` for an `all()` registration.
|
|
476
|
+
* @param {string} pathnamePattern - The pathname pattern to register.
|
|
477
|
+
* @throws {RouterError} If the registration already exists.
|
|
478
|
+
*/
|
|
479
|
+
#ensureRegistration(method, pathnamePattern) {
|
|
480
|
+
const key = `${method}:${pathnamePattern}`;
|
|
481
|
+
|
|
482
|
+
if (this.#registrations.has(key)) {
|
|
483
|
+
if (method === undefined) {
|
|
484
|
+
throw new RouterError('DUPLICATE_ALL_METHOD', { values: { pathnamePattern } });
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
throw new RouterError('DUPLICATE_ROUTE', { values: { method, pathnamePattern } });
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
this.#registrations.add(key);
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Validates a pathname pattern.
|
|
495
|
+
*
|
|
496
|
+
* @param {unknown} value - The pathname pattern to validate.
|
|
497
|
+
* @throws {PathnamePatternError} If the pathname pattern is not a string.
|
|
498
|
+
* @throws {PathnamePatternError} If the pathname pattern is empty.
|
|
499
|
+
* @throws {PathnamePatternError} If the pathname pattern exceeds the maximum length.
|
|
500
|
+
* @throws {PathnamePatternError} If the pathname pattern syntax is invalid.
|
|
501
|
+
* @throws {PathnamePatternError} If the pathname pattern has duplicate parameter names.
|
|
502
|
+
*/
|
|
503
|
+
#assertPathnamePattern(value) {
|
|
504
|
+
assertPathnamePattern(value);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Validates middleware functions.
|
|
509
|
+
*
|
|
510
|
+
* A middleware must be a function that declares exactly two parameters:
|
|
511
|
+
* `exchange` and `next`.
|
|
512
|
+
*
|
|
513
|
+
* @param {unknown} value - The middleware functions to validate.
|
|
514
|
+
* @throws {MiddlewareError} If a middleware is not a function.
|
|
515
|
+
* @throws {MiddlewareError} If a middleware does not declare exactly two parameters.
|
|
516
|
+
*/
|
|
517
|
+
#assertMiddlewares(value) {
|
|
518
|
+
assertMiddlewares(value);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
// ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
523
|
+
export default Router;
|