@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,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Defines domain-specific errors for pathname pattern validation.
|
|
3
|
+
*
|
|
4
|
+
* @description PathnamePatternError extends BaseError to provide structured,
|
|
5
|
+
* identifiable errors specific to pathname pattern validation. It centralizes
|
|
6
|
+
* error messages and supports template placeholders for dynamic context.
|
|
7
|
+
*
|
|
8
|
+
* @module PathnamePatternError
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
12
|
+
// » IMPORT LOCAL MODULES
|
|
13
|
+
import BaseError from '../BaseError/index.mjs';
|
|
14
|
+
|
|
15
|
+
// ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
16
|
+
/**
|
|
17
|
+
* @template {string} T
|
|
18
|
+
* @typedef {T | (string & {})} LiteralUnion
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Identifies a predefined pathname pattern error or allows a custom error message.
|
|
23
|
+
*
|
|
24
|
+
* @typedef {LiteralUnion<
|
|
25
|
+
* 'INVALID_PATTERN_TYPE' |
|
|
26
|
+
* 'EMPTY_PATTERN' |
|
|
27
|
+
* 'PATTERN_TOO_LONG' |
|
|
28
|
+
* 'INVALID_PATHNAME_PATTERN' |
|
|
29
|
+
* 'DUPLICATE_PARAMETER_NAME'
|
|
30
|
+
* >} PathnamePatternErrorIdentifier
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Options for creating an error instance.
|
|
35
|
+
*
|
|
36
|
+
* @typedef {object} PathnamePatternErrorOptions
|
|
37
|
+
* @property {Record<string, unknown>} [values] - Values for template placeholders in the error message.
|
|
38
|
+
* @property {unknown} [details] - Additional contextual information about the error.
|
|
39
|
+
* @property {Error} [cause] - The original error that caused this error (for error chaining).
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
// ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
43
|
+
/**
|
|
44
|
+
* Error thrown when a pathname pattern cannot be validated.
|
|
45
|
+
*
|
|
46
|
+
* @classdesc This error type provides identifiable failures related to pathname
|
|
47
|
+
* pattern syntax and validation.
|
|
48
|
+
*
|
|
49
|
+
* @augments BaseError
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
class PathnamePatternError extends BaseError {
|
|
53
|
+
/**
|
|
54
|
+
* Creates a new {@link PathnamePatternError}.
|
|
55
|
+
*
|
|
56
|
+
* @param {PathnamePatternErrorIdentifier} identifier - A predefined error identifier or a custom error message.
|
|
57
|
+
* @param {PathnamePatternErrorOptions} [options] - Additional information used to format the message, attach domain details, or preserve the original cause.
|
|
58
|
+
* @example
|
|
59
|
+
* ```js
|
|
60
|
+
* throw new PathnamePatternError('INVALID_PATHNAME_PATTERN', {
|
|
61
|
+
* values: {
|
|
62
|
+
* pattern: '/users/:id',
|
|
63
|
+
* },
|
|
64
|
+
* });
|
|
65
|
+
* ```
|
|
66
|
+
* @example
|
|
67
|
+
* ```js
|
|
68
|
+
* throw new PathnamePatternError('EMPTY_PATTERN');
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
constructor(identifier, options = {}) {
|
|
72
|
+
super(identifier, options);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Collection of predefined pathname pattern error messages.
|
|
77
|
+
*
|
|
78
|
+
* Available error identifiers:
|
|
79
|
+
*
|
|
80
|
+
* - `'INVALID_PATTERN_TYPE'`.
|
|
81
|
+
* - `'EMPTY_PATTERN'`.
|
|
82
|
+
* - `'PATTERN_TOO_LONG'`.
|
|
83
|
+
* - `'INVALID_PATHNAME_PATTERN'`.
|
|
84
|
+
* - `'DUPLICATE_PARAMETER_NAME'`.
|
|
85
|
+
*
|
|
86
|
+
* @private
|
|
87
|
+
* @static
|
|
88
|
+
* @type {Map<PathnamePatternErrorIdentifier, string>}
|
|
89
|
+
*/
|
|
90
|
+
static MESSAGES = new Map([
|
|
91
|
+
['INVALID_PATTERN_TYPE', 'Expected pattern to be a {expected}, but received {received}.'],
|
|
92
|
+
['EMPTY_PATTERN', 'Pathname pattern must not be empty.'],
|
|
93
|
+
[
|
|
94
|
+
'PATTERN_TOO_LONG',
|
|
95
|
+
'Pathname pattern length ({actualLength}) exceeds the maximum allowed limit of {maxLength} characters.',
|
|
96
|
+
],
|
|
97
|
+
['INVALID_PATHNAME_PATTERN', 'Invalid pathname pattern: "{pattern}".'],
|
|
98
|
+
['DUPLICATE_PARAMETER_NAME', 'Duplicate parameter name: "{name}" in pattern.'],
|
|
99
|
+
]);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
103
|
+
export default PathnamePatternError;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Defines domain-specific errors for request processing.
|
|
3
|
+
*
|
|
4
|
+
* @description RequestError extends BaseError to provide structured,
|
|
5
|
+
* identifiable errors specific to request validation, body parsing,
|
|
6
|
+
* and stream consumption. It centralizes error messages and supports
|
|
7
|
+
* template placeholders for dynamic context.
|
|
8
|
+
*
|
|
9
|
+
* @module RequestError
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
13
|
+
// » IMPORT LOCAL MODULES
|
|
14
|
+
import BaseError from '../BaseError/index.mjs';
|
|
15
|
+
|
|
16
|
+
// ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
17
|
+
/**
|
|
18
|
+
* @template {string} T
|
|
19
|
+
* @typedef {T | (string & {})} LiteralUnion
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Identifies a predefined request error or allows a custom error message.
|
|
24
|
+
*
|
|
25
|
+
* @typedef {LiteralUnion<
|
|
26
|
+
* 'UNSUPPORTED_MEDIA_TYPE' |
|
|
27
|
+
* 'BODY_PARSE_FAILED' |
|
|
28
|
+
* 'BODY_LIMIT_EXCEEDED' |
|
|
29
|
+
* 'MISSING_METHOD' |
|
|
30
|
+
* 'INVALID_REQUEST_URL' |
|
|
31
|
+
* 'BODY_STREAM_ERROR' |
|
|
32
|
+
* 'INVALID_CONTENT_LENGTH' |
|
|
33
|
+
* 'MISSING_HOST' |
|
|
34
|
+
* 'INVALID_TRANSFER_ENCODING'
|
|
35
|
+
* >} RequestErrorIdentifier
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Options for creating an error instance.
|
|
40
|
+
*
|
|
41
|
+
* @typedef {object} RequestErrorOptions
|
|
42
|
+
* @property {Record<string, unknown>} [values] - Values for template placeholders in the error message.
|
|
43
|
+
* @property {unknown} [details] - Additional contextual information about the error.
|
|
44
|
+
* @property {Error} [cause] - The original error that caused this error.
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
// ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
48
|
+
/**
|
|
49
|
+
* Error thrown when an incoming request cannot be processed.
|
|
50
|
+
*
|
|
51
|
+
* @classdesc This error type provides identifiable failures related to
|
|
52
|
+
* incoming request validation, body parsing limits, and stream consumption.
|
|
53
|
+
*
|
|
54
|
+
* @augments BaseError
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
class RequestError extends BaseError {
|
|
58
|
+
/**
|
|
59
|
+
* Creates a new {@link RequestError}.
|
|
60
|
+
*
|
|
61
|
+
* @param {RequestErrorIdentifier} identifier - A predefined error identifier or a custom error message.
|
|
62
|
+
* @param {RequestErrorOptions} [options] - Additional information used to format the message, attach domain details, or preserve the original cause.
|
|
63
|
+
* @example
|
|
64
|
+
* ```js
|
|
65
|
+
* throw new RequestError('UNSUPPORTED_MEDIA_TYPE', {
|
|
66
|
+
* values: { mediaType: 'text/xml' },
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
* @example
|
|
70
|
+
* ```js
|
|
71
|
+
* throw new RequestError('BODY_LIMIT_EXCEEDED', {
|
|
72
|
+
* values: { bodySize: 15000000, bodyLimit: 10000000 },
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
constructor(identifier, options = {}) {
|
|
77
|
+
super(identifier, options);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Collection of predefined request error messages.
|
|
82
|
+
*
|
|
83
|
+
* Available error identifiers:
|
|
84
|
+
*
|
|
85
|
+
* - `'UNSUPPORTED_MEDIA_TYPE'`.
|
|
86
|
+
* - `'BODY_PARSE_FAILED'`.
|
|
87
|
+
* - `'BODY_LIMIT_EXCEEDED'`.
|
|
88
|
+
* - `'MISSING_METHOD'`.
|
|
89
|
+
* - `'INVALID_REQUEST_URL'`.
|
|
90
|
+
* - `'BODY_STREAM_ERROR'`.
|
|
91
|
+
* - `'INVALID_CONTENT_LENGTH'`.
|
|
92
|
+
* - `'MISSING_HOST'`.
|
|
93
|
+
* - `'INVALID_TRANSFER_ENCODING'`.
|
|
94
|
+
*
|
|
95
|
+
* @private
|
|
96
|
+
* @static
|
|
97
|
+
* @type {Map<RequestErrorIdentifier, string>}
|
|
98
|
+
*/
|
|
99
|
+
static MESSAGES = new Map([
|
|
100
|
+
['UNSUPPORTED_MEDIA_TYPE', 'Unsupported media type: {mediaType}.'],
|
|
101
|
+
['BODY_PARSE_FAILED', 'Request body could not be parsed: {reason}.'],
|
|
102
|
+
[
|
|
103
|
+
'BODY_LIMIT_EXCEEDED',
|
|
104
|
+
'Request body size ({bodySize} bytes) exceeds the configured limit ({bodyLimit} bytes).',
|
|
105
|
+
],
|
|
106
|
+
['MISSING_METHOD', 'The request does not declare an HTTP method.'],
|
|
107
|
+
['INVALID_REQUEST_URL', 'The request URL could not be parsed.'],
|
|
108
|
+
['BODY_STREAM_ERROR', 'The request body stream failed while being read.'],
|
|
109
|
+
['INVALID_CONTENT_LENGTH', 'Invalid Content-Length header: {contentLength}.'],
|
|
110
|
+
['MISSING_HOST', 'The request does not declare a valid authority.'],
|
|
111
|
+
['INVALID_TRANSFER_ENCODING', 'Invalid Transfer-Encoding header: {transferEncoding}.'],
|
|
112
|
+
]);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
116
|
+
export default RequestError;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Defines domain-specific errors for response construction.
|
|
3
|
+
*
|
|
4
|
+
* @description ResponseError extends BaseError to provide structured,
|
|
5
|
+
* identifiable errors specific to response status, headers, and body
|
|
6
|
+
* validation. It centralizes error messages and supports template
|
|
7
|
+
* placeholders for dynamic context.
|
|
8
|
+
*
|
|
9
|
+
* @module ResponseError
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
// ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
13
|
+
// » IMPORT LOCAL MODULES
|
|
14
|
+
import BaseError from '../BaseError/index.mjs';
|
|
15
|
+
|
|
16
|
+
// ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
17
|
+
/**
|
|
18
|
+
* @template {string} T
|
|
19
|
+
* @typedef {T | (string & {})} LiteralUnion
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Identifies a predefined response error or allows a custom error message.
|
|
24
|
+
*
|
|
25
|
+
* @typedef {LiteralUnion<
|
|
26
|
+
* 'INVALID_STATUS_CODE' |
|
|
27
|
+
* 'BODY_NOT_ALLOWED' |
|
|
28
|
+
* 'RESPONSE_ALREADY_SENT' |
|
|
29
|
+
* 'BODY_ALREADY_DESCRIBED' |
|
|
30
|
+
* 'INVALID_BODY' |
|
|
31
|
+
* 'INVALID_JSON' |
|
|
32
|
+
* 'INVALID_STREAM' |
|
|
33
|
+
* 'INVALID_REDIRECT_URL' |
|
|
34
|
+
* 'INVALID_REDIRECT_STATUS' |
|
|
35
|
+
* 'CONTENT_TYPE_LOCKED' |
|
|
36
|
+
* 'INVALID_CACHE_DURATION' |
|
|
37
|
+
* 'INVALID_HEADER_NAME' |
|
|
38
|
+
* 'INVALID_HEADER_VALUE' |
|
|
39
|
+
* 'INVALID_HEADERS' |
|
|
40
|
+
* 'INVALID_CONTENT_TYPE'|
|
|
41
|
+
* 'BODY_ALREADY_WRAPPED' |
|
|
42
|
+
* 'BODY_NOT_DESCRIBED'
|
|
43
|
+
* >} ResponseErrorIdentifier
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Options for creating an error instance.
|
|
48
|
+
*
|
|
49
|
+
* @typedef {object} ResponseErrorOptions
|
|
50
|
+
* @property {Record<string, unknown>} [values] - Values for template placeholders in the error message.
|
|
51
|
+
* @property {unknown} [details] - Additional contextual information about the error.
|
|
52
|
+
* @property {Error} [cause] - The original error that caused this error.
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
// ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
56
|
+
/**
|
|
57
|
+
* Error thrown when a response cannot be constructed.
|
|
58
|
+
*
|
|
59
|
+
* @classdesc This error type provides identifiable failures related to
|
|
60
|
+
* response status, headers, body composition, and commit operations.
|
|
61
|
+
*
|
|
62
|
+
* @augments BaseError
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
class ResponseError extends BaseError {
|
|
66
|
+
/**
|
|
67
|
+
* Creates a new {@link ResponseError}.
|
|
68
|
+
*
|
|
69
|
+
* @param {ResponseErrorIdentifier} identifier - A predefined error identifier or a custom error message.
|
|
70
|
+
* @param {ResponseErrorOptions} [options] - Additional information used to format the message, attach domain details, or preserve the original cause.
|
|
71
|
+
* @example
|
|
72
|
+
* ```js
|
|
73
|
+
* throw new ResponseError('INVALID_STATUS_CODE', {
|
|
74
|
+
* values: { statusCode: 999 },
|
|
75
|
+
* });
|
|
76
|
+
* ```
|
|
77
|
+
* @example
|
|
78
|
+
* ```js
|
|
79
|
+
* throw new ResponseError('BODY_NOT_ALLOWED', {
|
|
80
|
+
* values: { statusCode: 204 },
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
constructor(identifier, options = {}) {
|
|
85
|
+
super(identifier, options);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Collection of predefined response error messages.
|
|
90
|
+
*
|
|
91
|
+
* Available error identifiers:
|
|
92
|
+
*
|
|
93
|
+
* - `'INVALID_STATUS_CODE'`.
|
|
94
|
+
* - `'BODY_NOT_ALLOWED'`.
|
|
95
|
+
* - `'RESPONSE_ALREADY_SENT'`.
|
|
96
|
+
* - `'BODY_ALREADY_DESCRIBED'`.
|
|
97
|
+
* - `'INVALID_BODY'`.
|
|
98
|
+
* - `'INVALID_JSON'`.
|
|
99
|
+
* - `'INVALID_STREAM'`.
|
|
100
|
+
* - `'INVALID_REDIRECT_URL'`.
|
|
101
|
+
* - `'INVALID_REDIRECT_STATUS'`.
|
|
102
|
+
* - `'CONTENT_TYPE_LOCKED'`.
|
|
103
|
+
* - `'INVALID_CACHE_DURATION'`.
|
|
104
|
+
* - `'INVALID_HEADER_NAME'`.
|
|
105
|
+
* - `'INVALID_HEADER_VALUE'`.
|
|
106
|
+
* - `'INVALID_HEADERS'`.
|
|
107
|
+
* - `'INVALID_CONTENT_TYPE'`.
|
|
108
|
+
* - `'BODY_ALREADY_WRAPPED'`.
|
|
109
|
+
* - `'BODY_NOT_DESCRIBED'`.
|
|
110
|
+
*
|
|
111
|
+
* @private
|
|
112
|
+
* @static
|
|
113
|
+
* @type {Map<ResponseErrorIdentifier, string>}
|
|
114
|
+
*/
|
|
115
|
+
static MESSAGES = new Map([
|
|
116
|
+
['INVALID_STATUS_CODE', 'Invalid or unsupported HTTP status code: {statusCode}.'],
|
|
117
|
+
['BODY_NOT_ALLOWED', 'Status code {statusCode} does not allow a response body.'],
|
|
118
|
+
['RESPONSE_ALREADY_SENT', 'The response has already been committed.'],
|
|
119
|
+
['BODY_ALREADY_DESCRIBED', 'A response body has already been described.'],
|
|
120
|
+
['INVALID_BODY', 'Invalid response body. Received: {received}.'],
|
|
121
|
+
['INVALID_JSON', 'The value cannot be serialized as JSON.'],
|
|
122
|
+
['INVALID_STREAM', 'The provided value is not a valid stream.'],
|
|
123
|
+
['INVALID_REDIRECT_URL', 'The redirect URL must be a non-empty string.'],
|
|
124
|
+
['INVALID_REDIRECT_STATUS', 'Invalid redirect status code: {statusCode}.'],
|
|
125
|
+
[
|
|
126
|
+
'CONTENT_TYPE_LOCKED',
|
|
127
|
+
'Cannot {operation} the Content-Type header after a body has been described.',
|
|
128
|
+
],
|
|
129
|
+
['INVALID_CACHE_DURATION', 'The cache duration must be a non-negative integer.'],
|
|
130
|
+
['INVALID_HEADER_NAME', 'Invalid HTTP header name.'],
|
|
131
|
+
['INVALID_HEADER_VALUE', 'Invalid HTTP header value.'],
|
|
132
|
+
['INVALID_HEADERS', 'Headers must be a plain object.'],
|
|
133
|
+
['INVALID_CONTENT_TYPE', 'Invalid Content-Type. Expected a string, but received {received}.'],
|
|
134
|
+
['BODY_ALREADY_WRAPPED', 'The response body has already been wrapped.'],
|
|
135
|
+
['BODY_NOT_DESCRIBED', 'A response body has not been described.'],
|
|
136
|
+
]);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
140
|
+
export default ResponseError;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Defines domain-specific errors for the HTTP Router.
|
|
3
|
+
*
|
|
4
|
+
* @description RouterError extends BaseError to provide structured,
|
|
5
|
+
* identifiable errors specific to routing operations. It centralizes
|
|
6
|
+
* error messages and supports template placeholders for dynamic context.
|
|
7
|
+
*
|
|
8
|
+
* @module RouterError
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
12
|
+
// » IMPORT LOCAL MODULES
|
|
13
|
+
import BaseError from '../BaseError/index.mjs';
|
|
14
|
+
|
|
15
|
+
// ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
16
|
+
/**
|
|
17
|
+
* @template {string} T
|
|
18
|
+
* @typedef {T | (string & {})} LiteralUnion
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Identifies a predefined response error or allows a custom error message.
|
|
23
|
+
*
|
|
24
|
+
* @typedef {LiteralUnion<
|
|
25
|
+
* 'DUPLICATE_ALL_METHOD' |
|
|
26
|
+
* 'DUPLICATE_ROUTE'
|
|
27
|
+
* >} RouterErrorIdentifier
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Options for creating an error instance.
|
|
32
|
+
*
|
|
33
|
+
* @typedef {object} RouterErrorOptions
|
|
34
|
+
* @property {Record<string, unknown>} [values] - Values for template placeholders in the error message.
|
|
35
|
+
* @property {unknown} [details] - Additional contextual information about the error.
|
|
36
|
+
* @property {Error} [cause] - The original error that caused this error (for error chaining).
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
// ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
40
|
+
/**
|
|
41
|
+
* Error thrown when a `Router` operation cannot be completed.
|
|
42
|
+
*
|
|
43
|
+
* @classdesc This error type provides identifiable failures related to pathname
|
|
44
|
+
* patterns, route registration, and handler configuration.
|
|
45
|
+
*
|
|
46
|
+
* @augments BaseError
|
|
47
|
+
* @private
|
|
48
|
+
*/
|
|
49
|
+
class RouterError extends BaseError {
|
|
50
|
+
/**
|
|
51
|
+
* Creates a new {@link RouterError}.
|
|
52
|
+
*
|
|
53
|
+
* @param {RouterErrorIdentifier} identifier - A predefined error identifier or a custom error message.
|
|
54
|
+
* @param {RouterErrorOptions} [options] - Additional information used to format the message, attach domain details, or preserve the original cause.
|
|
55
|
+
* @example
|
|
56
|
+
* ```js
|
|
57
|
+
* throw new RouterError('DUPLICATE_ALL', { values: { pathnamePattern } });
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
*/
|
|
61
|
+
constructor(identifier, options = {}) {
|
|
62
|
+
super(identifier, options);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Collection of predefined server error messages.
|
|
67
|
+
*
|
|
68
|
+
* Available error identifiers:
|
|
69
|
+
*
|
|
70
|
+
* - `'DUPLICATE_ALL_METHOD'`.
|
|
71
|
+
* - `'ROUTE_ALREADY_REGISTERED'`.
|
|
72
|
+
*
|
|
73
|
+
* @private
|
|
74
|
+
* @static
|
|
75
|
+
* @type {Map<RouterErrorIdentifier, string>}
|
|
76
|
+
*/
|
|
77
|
+
static MESSAGES = new Map([
|
|
78
|
+
[
|
|
79
|
+
'DUPLICATE_ALL_METHOD',
|
|
80
|
+
'The "ALL" registration is already defined for pathname pattern "{pathnamePattern}".',
|
|
81
|
+
],
|
|
82
|
+
[
|
|
83
|
+
'DUPLICATE_ROUTE',
|
|
84
|
+
'The "{mark}" method is already defined for pathname pattern "{pathnamePattern}".',
|
|
85
|
+
],
|
|
86
|
+
]);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
90
|
+
export default RouterError;
|