@boo-labs/server 0.0.0-stage → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +287 -2
  3. package/index.mjs +23 -0
  4. package/package.json +71 -4
  5. package/source/application/Kernel/index.mjs +1137 -0
  6. package/source/application/Server/index.mjs +1201 -0
  7. package/source/application/configurations/Http2CleartextServerConfiguration/index.mjs +168 -0
  8. package/source/application/configurations/Http2SecureServerConfiguration/index.mjs +172 -0
  9. package/source/application/configurations/HttpServerConfiguration/index.mjs +169 -0
  10. package/source/application/configurations/HttpsServerConfiguration/index.mjs +172 -0
  11. package/source/application/configurations/ServerConfiguration/Options/CORSOptions/CORSOptionsValue.mjs +158 -0
  12. package/source/application/configurations/ServerConfiguration/Options/CORSOptions/index.mjs +87 -0
  13. package/source/application/configurations/ServerConfiguration/Options/CSRFOptions/CSRFOptionsValue.mjs +178 -0
  14. package/source/application/configurations/ServerConfiguration/Options/CSRFOptions/index.mjs +80 -0
  15. package/source/application/configurations/ServerConfiguration/Options/CompressOptions/CompressOptionsValue.mjs +126 -0
  16. package/source/application/configurations/ServerConfiguration/Options/CompressOptions/index.mjs +81 -0
  17. package/source/application/configurations/ServerConfiguration/Options/CookieParserOptions/CookieParserOptionsValue.mjs +107 -0
  18. package/source/application/configurations/ServerConfiguration/Options/CookieParserOptions/index.mjs +82 -0
  19. package/source/application/configurations/ServerConfiguration/Options/CookieSessionOptions/CookieSessionOptionsValue.mjs +182 -0
  20. package/source/application/configurations/ServerConfiguration/Options/CookieSessionOptions/index.mjs +86 -0
  21. package/source/application/configurations/ServerConfiguration/Options/ListenOptions/ListenOptionsValue.mjs +95 -0
  22. package/source/application/configurations/ServerConfiguration/Options/ListenOptions/index.mjs +47 -0
  23. package/source/application/configurations/ServerConfiguration/Options/MiddlewareOption.mjs +102 -0
  24. package/source/application/configurations/ServerConfiguration/Options/Options.mjs +105 -0
  25. package/source/application/configurations/ServerConfiguration/Options/RateLimitOptions/RateLimitOptionsValue.mjs +164 -0
  26. package/source/application/configurations/ServerConfiguration/Options/RateLimitOptions/index.mjs +84 -0
  27. package/source/application/configurations/ServerConfiguration/Options/RequestOptions/RequestOptionsValue.mjs +108 -0
  28. package/source/application/configurations/ServerConfiguration/Options/RequestOptions/index.mjs +47 -0
  29. package/source/application/configurations/ServerConfiguration/Options/ResponseOptions/ResponseOptionsValue.mjs +101 -0
  30. package/source/application/configurations/ServerConfiguration/Options/ResponseOptions/index.mjs +47 -0
  31. package/source/application/configurations/ServerConfiguration/Options/SecurityHeadersOptions/SecurityHeadersOptionsValue.mjs +272 -0
  32. package/source/application/configurations/ServerConfiguration/Options/SecurityHeadersOptions/index.mjs +85 -0
  33. package/source/application/configurations/ServerConfiguration/Options/ServerOption.mjs +50 -0
  34. package/source/application/configurations/ServerConfiguration/Options/StaticOptions/StaticOptionsValue.mjs +164 -0
  35. package/source/application/configurations/ServerConfiguration/Options/StaticOptions/index.mjs +89 -0
  36. package/source/application/configurations/ServerConfiguration/index.mjs +781 -0
  37. package/source/application/resolvers/TransportResolver/index.mjs +119 -0
  38. package/source/application/use-cases/CloseServer/index.mjs +85 -0
  39. package/source/application/use-cases/ListenServer/index.mjs +98 -0
  40. package/source/core/EventSystem/index.mjs +110 -0
  41. package/source/core/Exchange/ExchangeContext.mjs +291 -0
  42. package/source/core/Exchange/Telemetry.mjs +193 -0
  43. package/source/core/Exchange/index.mjs +604 -0
  44. package/source/core/ExchangeLayerBuilder/index.mjs +133 -0
  45. package/source/core/IPCMain/IPCMain.mjs +507 -0
  46. package/source/core/IPCMain/IPCProtocol.mjs +441 -0
  47. package/source/core/IPCMain/IPCServerChannel.mjs +331 -0
  48. package/source/core/IPCMain/WebSocketAdapter.mjs +189 -0
  49. package/source/core/Request/BodyParser/BodyParser.mjs +197 -0
  50. package/source/core/Request/BodyParser/JSONParser.mjs +70 -0
  51. package/source/core/Request/BodyParser/MultipartParser.mjs +612 -0
  52. package/source/core/Request/BodyParser/URLEncodedParser.mjs +71 -0
  53. package/source/core/Request/RequestHeaders.mjs +177 -0
  54. package/source/core/Request/index.mjs +805 -0
  55. package/source/core/Response/ResponseHeaders.mjs +402 -0
  56. package/source/core/Response/index.mjs +1370 -0
  57. package/source/core/middlewares/CORSMiddleware/index.mjs +289 -0
  58. package/source/core/middlewares/CSRFMiddleware/index.mjs +284 -0
  59. package/source/core/middlewares/CompressMiddleware/index.mjs +460 -0
  60. package/source/core/middlewares/CookieParserMiddleware/index.mjs +194 -0
  61. package/source/core/middlewares/CookieSessionMiddleware/index.mjs +460 -0
  62. package/source/core/middlewares/RateLimitMiddleware/index.mjs +245 -0
  63. package/source/core/middlewares/SecurityHeadersMiddleware/index.mjs +151 -0
  64. package/source/core/middlewares/StaticMiddleware/index.mjs +628 -0
  65. package/source/core/routing/ExchangeLayer/ExchangeMatcher.mjs +127 -0
  66. package/source/core/routing/ExchangeLayer/index.mjs +254 -0
  67. package/source/core/routing/Pipeline/index.mjs +157 -0
  68. package/source/core/routing/Router/Route.mjs +184 -0
  69. package/source/core/routing/Router/index.mjs +523 -0
  70. package/source/core/routing/RouterRegister/OptionsMiddleware.mjs +147 -0
  71. package/source/core/routing/RouterRegister/index.mjs +150 -0
  72. package/source/core/routing/RouterSystem/index.mjs +225 -0
  73. package/source/core/value-objects/Address/index.mjs +281 -0
  74. package/source/core/value-objects/Endpoint/index.mjs +293 -0
  75. package/source/index.mjs +62 -0
  76. package/source/infrastructure/adapters/Http2Adapter/index.mjs +144 -0
  77. package/source/infrastructure/adapters/Http2CleartextAdapter/index.mjs +147 -0
  78. package/source/infrastructure/adapters/HttpAdapter/index.mjs +124 -0
  79. package/source/infrastructure/adapters/HttpsAdapter/index.mjs +124 -0
  80. package/source/infrastructure/adapters/TransportAdapter/createWebSocketOpenRequest.mjs +843 -0
  81. package/source/infrastructure/adapters/TransportAdapter/index.mjs +555 -0
  82. package/source/shared/Identifier/index.mjs +671 -0
  83. package/source/shared/constants/symbols/brands/index.mjs +45 -0
  84. package/source/shared/domain/UUIDV7/index.mjs +346 -0
  85. package/source/shared/errors/BaseError/index.mjs +157 -0
  86. package/source/shared/errors/IPCError/index.mjs +97 -0
  87. package/source/shared/errors/MiddlewareError/index.mjs +106 -0
  88. package/source/shared/errors/PathnamePatternError/index.mjs +103 -0
  89. package/source/shared/errors/RequestError/index.mjs +116 -0
  90. package/source/shared/errors/ResponseError/index.mjs +140 -0
  91. package/source/shared/errors/RouterError/index.mjs +90 -0
  92. package/source/shared/errors/ServerConfigurationError/index.mjs +551 -0
  93. package/source/shared/errors/ServerError/index.mjs +127 -0
  94. package/source/shared/errors/WebSocketError/index.mjs +58 -0
  95. package/source/shared/outcome/ErrorSchema.mjs +361 -0
  96. package/source/shared/outcome/Result/index.mjs +239 -0
  97. package/source/shared/outcome/Validation/index.mjs +208 -0
  98. package/source/shared/validations/Middleware/index.mjs +160 -0
  99. package/source/shared/validations/PathnamePattern/index.mjs +256 -0
  100. package/source/shared/validations/Server/NotFoundHandler/index.mjs +94 -0
  101. package/source/shared/validations/Server/Router/index.mjs +68 -0
  102. package/source/shared/validations/Server/ServerConfiguration/index.mjs +68 -0
  103. package/source/shared/validations/Server/SystemErrorHandler/index.mjs +94 -0
  104. package/source/shared/validations/ServerConfiguration/CORSOptions/index.mjs +310 -0
  105. package/source/shared/validations/ServerConfiguration/CSRFOptions/index.mjs +299 -0
  106. package/source/shared/validations/ServerConfiguration/CompressOptions/index.mjs +204 -0
  107. package/source/shared/validations/ServerConfiguration/CookieParserOptions/index.mjs +102 -0
  108. package/source/shared/validations/ServerConfiguration/CookieSessionOptions/index.mjs +332 -0
  109. package/source/shared/validations/ServerConfiguration/ListenOptions/index.mjs +178 -0
  110. package/source/shared/validations/ServerConfiguration/RateLimitOptions/index.mjs +229 -0
  111. package/source/shared/validations/ServerConfiguration/RequestOptions/index.mjs +132 -0
  112. package/source/shared/validations/ServerConfiguration/ResponseOptions/index.mjs +122 -0
  113. package/source/shared/validations/ServerConfiguration/SecurityHeadersOptions/index.mjs +137 -0
  114. package/source/shared/validations/ServerConfiguration/StaticOptions/index.mjs +248 -0
  115. package/types/index.d.ts +719 -0
@@ -0,0 +1,164 @@
1
+ // @ts-check
2
+ /**
3
+ * @file Defines the StaticOptionsValue value object.
4
+ *
5
+ * @description Normalizes and validates static middleware configuration used
6
+ * by StaticMiddleware. When options are omitted, the value is undefined.
7
+ *
8
+ * @module StaticOptionsValue
9
+ */
10
+
11
+ // ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
12
+ // » IMPORT NATIVE NODEJS MODULES
13
+ import { resolve } from 'node:path';
14
+
15
+ // » IMPORT LOCAL MODULES
16
+ import { assertStaticOptions } from '#shared/validations/ServerConfiguration/StaticOptions';
17
+
18
+ // ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
19
+ /**
20
+ * Domain error thrown by server configuration validation.
21
+ *
22
+ * @typedef {import('#shared/errors/ServerConfigurationError').default} ServerConfigurationError
23
+ */
24
+
25
+ /**
26
+ * Represents the static options accepted by the server configuration.
27
+ *
28
+ * @typedef {object} StaticOptionsInput
29
+ * @property {string} root - Filesystem root directory for static files.
30
+ * @property {Readonly<Array<string>>} [index] - Ordered list of index file names.
31
+ * @property {number} [maxAge] - Cache-Control max-age value in seconds.
32
+ * @property {boolean} [etag] - Whether to generate ETag headers.
33
+ * @property {boolean} [lastModified] - Whether to generate Last-Modified headers.
34
+ * @property {boolean} [fallthrough] - Whether to delegate to the next middleware when no file is found.
35
+ * @property {Readonly<Array<string>>} [extensions] - Extensions to try when the request has no extension.
36
+ * @property {boolean} [dotfiles] - Whether to serve dot-prefixed paths.
37
+ */
38
+
39
+ /**
40
+ * Represents the normalized static options.
41
+ *
42
+ * @typedef {object} StaticOptionsData
43
+ * @property {string} root - Absolute resolved path to the static files root directory.
44
+ * @property {Readonly<Array<string>>} index - Ordered list of index file names.
45
+ * @property {number} maxAge - Cache-Control max-age value in seconds.
46
+ * @property {boolean} etag - Whether to generate ETag headers.
47
+ * @property {boolean} lastModified - Whether to generate Last-Modified headers.
48
+ * @property {boolean} fallthrough - Whether to delegate to the next middleware when no file is found.
49
+ * @property {Readonly<Array<string>>|undefined} extensions - Extensions to try when the request has no extension.
50
+ * @property {boolean} dotfiles - Whether to serve dot-prefixed paths.
51
+ */
52
+
53
+ // ━━ CONSTANTS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
54
+ /**
55
+ * Default index file names.
56
+ *
57
+ * @type {readonly string[]}
58
+ */
59
+ const DEFAULT_INDEX = Object.freeze(['index.html']);
60
+
61
+ /**
62
+ * Default Cache-Control max-age value in seconds.
63
+ *
64
+ * @type {number}
65
+ */
66
+ const DEFAULT_MAX_AGE = 0;
67
+
68
+ /**
69
+ * Default ETag generation behavior.
70
+ *
71
+ * @type {boolean}
72
+ */
73
+ const DEFAULT_ETAG = true;
74
+
75
+ /**
76
+ * Default Last-Modified header behavior.
77
+ *
78
+ * @type {boolean}
79
+ */
80
+ const DEFAULT_LAST_MODIFIED = true;
81
+
82
+ /**
83
+ * Default fallthrough behavior.
84
+ *
85
+ * @type {boolean}
86
+ */
87
+ const DEFAULT_FALLTHROUGH = true;
88
+
89
+ /**
90
+ * Default dotfile serving behavior.
91
+ *
92
+ * @type {boolean}
93
+ */
94
+ const DEFAULT_DOTFILES = false;
95
+
96
+ // ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
97
+ /**
98
+ * Immutable value object representing normalized static middleware options.
99
+ *
100
+ * @classdesc Validates and normalizes static middleware options.
101
+ *
102
+ */
103
+ class StaticOptionsValue {
104
+ /**
105
+ * The normalized static options.
106
+ *
107
+ * @type {Readonly<StaticOptionsData>|undefined}
108
+ */
109
+ #value;
110
+
111
+ /**
112
+ * Creates a new {@link StaticOptionsValue}.
113
+ *
114
+ * @param {StaticOptionsInput} [options] - The static middleware options.
115
+ * @throws {ServerConfigurationError} If `options` is invalid.
116
+ * @example
117
+ * ```js
118
+ * const options = new StaticOptionsValue({ root: '/var/www/public' });
119
+ *
120
+ * options.value;
121
+ * // => {
122
+ * // root: '/var/www/public',
123
+ * // index: ['index.html'],
124
+ * // maxAge: 0,
125
+ * // etag: true,
126
+ * // lastModified: true,
127
+ * // fallthrough: true,
128
+ * // extensions: undefined,
129
+ * // dotfiles: false,
130
+ * // }
131
+ * ```
132
+ */
133
+ constructor(options) {
134
+ assertStaticOptions(options);
135
+
136
+ this.#value =
137
+ options === undefined
138
+ ? options
139
+ : Object.freeze({
140
+ root: resolve(options.root),
141
+ index: Object.freeze(options.index ?? [...DEFAULT_INDEX]),
142
+ maxAge: options.maxAge ?? DEFAULT_MAX_AGE,
143
+ etag: options.etag ?? DEFAULT_ETAG,
144
+ lastModified: options.lastModified ?? DEFAULT_LAST_MODIFIED,
145
+ fallthrough: options.fallthrough ?? DEFAULT_FALLTHROUGH,
146
+ extensions:
147
+ options.extensions === undefined ? undefined : Object.freeze([...options.extensions]),
148
+ dotfiles: options.dotfiles ?? DEFAULT_DOTFILES,
149
+ });
150
+ }
151
+
152
+ /**
153
+ * The normalized static options.
154
+ *
155
+ * @readonly
156
+ * @type {Readonly<StaticOptionsData>|undefined}
157
+ */
158
+ get value() {
159
+ return this.#value;
160
+ }
161
+ }
162
+
163
+ // ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
164
+ export default StaticOptionsValue;
@@ -0,0 +1,89 @@
1
+ // @ts-check
2
+ /**
3
+ * @file Defines the StaticOption middleware configuration option.
4
+ *
5
+ * @description StaticOption wraps a normalized StaticOptionsValue into the
6
+ * middleware configuration option hierarchy.
7
+ *
8
+ * @module StaticOption
9
+ */
10
+
11
+ // ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
12
+ // » IMPORT LOCAL MODULES
13
+ import MiddlewareOption from '../MiddlewareOption.mjs';
14
+ import StaticOptionsValue from './StaticOptionsValue.mjs';
15
+
16
+ // ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
17
+ /**
18
+ * Represents the static options accepted by the server configuration.
19
+ *
20
+ * @typedef {import('./StaticOptionsValue.mjs').StaticOptionsInput} StaticOptionsInput
21
+ */
22
+
23
+ /**
24
+ * Represents the normalized static options.
25
+ *
26
+ * @typedef {import('./StaticOptionsValue.mjs').StaticOptionsData} StaticOptionsData
27
+ */
28
+
29
+ /**
30
+ * Represents one middleware configuration consumed by the exchange layer builder.
31
+ *
32
+ * @typedef {import('../MiddlewareOption.mjs').MiddlewareConfiguration} MiddlewareConfiguration
33
+ */
34
+
35
+ // ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
36
+ /**
37
+ * Middleware configuration option wrapping a normalized static configuration.
38
+ *
39
+ * @augments {MiddlewareOption<StaticOptionsData|undefined>}
40
+ */
41
+ class StaticOption extends MiddlewareOption {
42
+ /**
43
+ * Creates a new {@link StaticOption}.
44
+ *
45
+ * @param {StaticOptionsInput} [options] - The static middleware options.
46
+ * @example
47
+ * ```js
48
+ * const staticOptions = new StaticOption({
49
+ * root: '/var/www/public',
50
+ * index: ['index.html'],
51
+ * maxAge: 0,
52
+ * etag: true,
53
+ * lastModified: true,
54
+ * fallthrough: true,
55
+ * extensions: undefined,
56
+ * dotfiles: false,
57
+ * });
58
+ * ```
59
+ */
60
+ constructor(options) {
61
+ super('static', new StaticOptionsValue(options));
62
+ }
63
+
64
+ /**
65
+ * Composes the static middleware configuration consumed by the exchange
66
+ * layer builder.
67
+ *
68
+ * The `root` option is a filesystem concern and does not translate to a
69
+ * layer-level pathname pattern. The middleware is scoped by the surrounding
70
+ * `use()` registration when a mount path is required.
71
+ *
72
+ * @returns {MiddlewareConfiguration} The composed middleware configuration.
73
+ * @example
74
+ * ```js
75
+ * const configuration = staticOptions.compose();
76
+ * ```
77
+ */
78
+ compose() {
79
+ return {
80
+ name: this.name,
81
+ options: this.value,
82
+ pathnamePattern: undefined,
83
+ method: undefined,
84
+ };
85
+ }
86
+ }
87
+
88
+ // ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
89
+ export default StaticOption;