@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.
Files changed (114) hide show
  1. package/README.md +229 -2
  2. package/index.mjs +23 -0
  3. package/package.json +71 -4
  4. package/source/application/Kernel/index.mjs +1137 -0
  5. package/source/application/Server/index.mjs +1201 -0
  6. package/source/application/configurations/Http2CleartextServerConfiguration/index.mjs +168 -0
  7. package/source/application/configurations/Http2SecureServerConfiguration/index.mjs +172 -0
  8. package/source/application/configurations/HttpServerConfiguration/index.mjs +169 -0
  9. package/source/application/configurations/HttpsServerConfiguration/index.mjs +172 -0
  10. package/source/application/configurations/ServerConfiguration/Options/CORSOptions/CORSOptionsValue.mjs +158 -0
  11. package/source/application/configurations/ServerConfiguration/Options/CORSOptions/index.mjs +87 -0
  12. package/source/application/configurations/ServerConfiguration/Options/CSRFOptions/CSRFOptionsValue.mjs +178 -0
  13. package/source/application/configurations/ServerConfiguration/Options/CSRFOptions/index.mjs +80 -0
  14. package/source/application/configurations/ServerConfiguration/Options/CompressOptions/CompressOptionsValue.mjs +126 -0
  15. package/source/application/configurations/ServerConfiguration/Options/CompressOptions/index.mjs +81 -0
  16. package/source/application/configurations/ServerConfiguration/Options/CookieParserOptions/CookieParserOptionsValue.mjs +107 -0
  17. package/source/application/configurations/ServerConfiguration/Options/CookieParserOptions/index.mjs +82 -0
  18. package/source/application/configurations/ServerConfiguration/Options/CookieSessionOptions/CookieSessionOptionsValue.mjs +182 -0
  19. package/source/application/configurations/ServerConfiguration/Options/CookieSessionOptions/index.mjs +86 -0
  20. package/source/application/configurations/ServerConfiguration/Options/ListenOptions/ListenOptionsValue.mjs +95 -0
  21. package/source/application/configurations/ServerConfiguration/Options/ListenOptions/index.mjs +47 -0
  22. package/source/application/configurations/ServerConfiguration/Options/MiddlewareOption.mjs +102 -0
  23. package/source/application/configurations/ServerConfiguration/Options/Options.mjs +105 -0
  24. package/source/application/configurations/ServerConfiguration/Options/RateLimitOptions/RateLimitOptionsValue.mjs +164 -0
  25. package/source/application/configurations/ServerConfiguration/Options/RateLimitOptions/index.mjs +84 -0
  26. package/source/application/configurations/ServerConfiguration/Options/RequestOptions/RequestOptionsValue.mjs +108 -0
  27. package/source/application/configurations/ServerConfiguration/Options/RequestOptions/index.mjs +47 -0
  28. package/source/application/configurations/ServerConfiguration/Options/ResponseOptions/ResponseOptionsValue.mjs +101 -0
  29. package/source/application/configurations/ServerConfiguration/Options/ResponseOptions/index.mjs +47 -0
  30. package/source/application/configurations/ServerConfiguration/Options/SecurityHeadersOptions/SecurityHeadersOptionsValue.mjs +272 -0
  31. package/source/application/configurations/ServerConfiguration/Options/SecurityHeadersOptions/index.mjs +85 -0
  32. package/source/application/configurations/ServerConfiguration/Options/ServerOption.mjs +50 -0
  33. package/source/application/configurations/ServerConfiguration/Options/StaticOptions/StaticOptionsValue.mjs +164 -0
  34. package/source/application/configurations/ServerConfiguration/Options/StaticOptions/index.mjs +89 -0
  35. package/source/application/configurations/ServerConfiguration/index.mjs +781 -0
  36. package/source/application/resolvers/TransportResolver/index.mjs +119 -0
  37. package/source/application/use-cases/CloseServer/index.mjs +85 -0
  38. package/source/application/use-cases/ListenServer/index.mjs +98 -0
  39. package/source/core/EventSystem/index.mjs +110 -0
  40. package/source/core/Exchange/ExchangeContext.mjs +291 -0
  41. package/source/core/Exchange/Telemetry.mjs +193 -0
  42. package/source/core/Exchange/index.mjs +604 -0
  43. package/source/core/ExchangeLayerBuilder/index.mjs +133 -0
  44. package/source/core/IPCMain/IPCMain.mjs +507 -0
  45. package/source/core/IPCMain/IPCProtocol.mjs +441 -0
  46. package/source/core/IPCMain/IPCServerChannel.mjs +331 -0
  47. package/source/core/IPCMain/WebSocketAdapter.mjs +189 -0
  48. package/source/core/Request/BodyParser/BodyParser.mjs +197 -0
  49. package/source/core/Request/BodyParser/JSONParser.mjs +70 -0
  50. package/source/core/Request/BodyParser/MultipartParser.mjs +612 -0
  51. package/source/core/Request/BodyParser/URLEncodedParser.mjs +71 -0
  52. package/source/core/Request/RequestHeaders.mjs +177 -0
  53. package/source/core/Request/index.mjs +805 -0
  54. package/source/core/Response/ResponseHeaders.mjs +402 -0
  55. package/source/core/Response/index.mjs +1370 -0
  56. package/source/core/middlewares/CORSMiddleware/index.mjs +289 -0
  57. package/source/core/middlewares/CSRFMiddleware/index.mjs +284 -0
  58. package/source/core/middlewares/CompressMiddleware/index.mjs +460 -0
  59. package/source/core/middlewares/CookieParserMiddleware/index.mjs +194 -0
  60. package/source/core/middlewares/CookieSessionMiddleware/index.mjs +460 -0
  61. package/source/core/middlewares/RateLimitMiddleware/index.mjs +245 -0
  62. package/source/core/middlewares/SecurityHeadersMiddleware/index.mjs +151 -0
  63. package/source/core/middlewares/StaticMiddleware/index.mjs +628 -0
  64. package/source/core/routing/ExchangeLayer/ExchangeMatcher.mjs +127 -0
  65. package/source/core/routing/ExchangeLayer/index.mjs +254 -0
  66. package/source/core/routing/Pipeline/index.mjs +157 -0
  67. package/source/core/routing/Router/Route.mjs +184 -0
  68. package/source/core/routing/Router/index.mjs +523 -0
  69. package/source/core/routing/RouterRegister/OptionsMiddleware.mjs +147 -0
  70. package/source/core/routing/RouterRegister/index.mjs +150 -0
  71. package/source/core/routing/RouterSystem/index.mjs +225 -0
  72. package/source/core/value-objects/Address/index.mjs +281 -0
  73. package/source/core/value-objects/Endpoint/index.mjs +293 -0
  74. package/source/index.mjs +62 -0
  75. package/source/infrastructure/adapters/Http2Adapter/index.mjs +144 -0
  76. package/source/infrastructure/adapters/Http2CleartextAdapter/index.mjs +147 -0
  77. package/source/infrastructure/adapters/HttpAdapter/index.mjs +124 -0
  78. package/source/infrastructure/adapters/HttpsAdapter/index.mjs +124 -0
  79. package/source/infrastructure/adapters/TransportAdapter/createWebSocketOpenRequest.mjs +843 -0
  80. package/source/infrastructure/adapters/TransportAdapter/index.mjs +555 -0
  81. package/source/shared/Identifier/index.mjs +671 -0
  82. package/source/shared/constants/symbols/brands/index.mjs +45 -0
  83. package/source/shared/domain/UUIDV7/index.mjs +346 -0
  84. package/source/shared/errors/BaseError/index.mjs +157 -0
  85. package/source/shared/errors/IPCError/index.mjs +97 -0
  86. package/source/shared/errors/MiddlewareError/index.mjs +106 -0
  87. package/source/shared/errors/PathnamePatternError/index.mjs +103 -0
  88. package/source/shared/errors/RequestError/index.mjs +116 -0
  89. package/source/shared/errors/ResponseError/index.mjs +140 -0
  90. package/source/shared/errors/RouterError/index.mjs +90 -0
  91. package/source/shared/errors/ServerConfigurationError/index.mjs +551 -0
  92. package/source/shared/errors/ServerError/index.mjs +127 -0
  93. package/source/shared/errors/WebSocketError/index.mjs +58 -0
  94. package/source/shared/outcome/ErrorSchema.mjs +361 -0
  95. package/source/shared/outcome/Result/index.mjs +239 -0
  96. package/source/shared/outcome/Validation/index.mjs +208 -0
  97. package/source/shared/validations/Middleware/index.mjs +160 -0
  98. package/source/shared/validations/PathnamePattern/index.mjs +256 -0
  99. package/source/shared/validations/Server/NotFoundHandler/index.mjs +94 -0
  100. package/source/shared/validations/Server/Router/index.mjs +68 -0
  101. package/source/shared/validations/Server/ServerConfiguration/index.mjs +68 -0
  102. package/source/shared/validations/Server/SystemErrorHandler/index.mjs +94 -0
  103. package/source/shared/validations/ServerConfiguration/CORSOptions/index.mjs +310 -0
  104. package/source/shared/validations/ServerConfiguration/CSRFOptions/index.mjs +299 -0
  105. package/source/shared/validations/ServerConfiguration/CompressOptions/index.mjs +204 -0
  106. package/source/shared/validations/ServerConfiguration/CookieParserOptions/index.mjs +102 -0
  107. package/source/shared/validations/ServerConfiguration/CookieSessionOptions/index.mjs +332 -0
  108. package/source/shared/validations/ServerConfiguration/ListenOptions/index.mjs +178 -0
  109. package/source/shared/validations/ServerConfiguration/RateLimitOptions/index.mjs +229 -0
  110. package/source/shared/validations/ServerConfiguration/RequestOptions/index.mjs +132 -0
  111. package/source/shared/validations/ServerConfiguration/ResponseOptions/index.mjs +122 -0
  112. package/source/shared/validations/ServerConfiguration/SecurityHeadersOptions/index.mjs +137 -0
  113. package/source/shared/validations/ServerConfiguration/StaticOptions/index.mjs +248 -0
  114. package/types/index.d.ts +719 -0
@@ -0,0 +1,281 @@
1
+ // @ts-check
2
+ /**
3
+ * @file Defines the Address value object.
4
+ *
5
+ * @module Address
6
+ */
7
+
8
+ // ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
9
+ // » IMPORT NATIVE NODEJS MODULES
10
+ import { inspect } from 'node:util';
11
+
12
+ // ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
13
+ /**
14
+ * Options accepted by the Address constructor.
15
+ *
16
+ * @typedef {object} AddressOptions
17
+ * @property {string} address - The network address where the server is listening.
18
+ * @property {number} port - The TCP port where the server is listening.
19
+ * @property {string} family - The IP address family.
20
+ */
21
+
22
+ /**
23
+ * Plain object representation of an Address.
24
+ *
25
+ * @typedef {object} AddressInfo
26
+ * @property {string} address - The network address where the server is listening.
27
+ * @property {number} port - The TCP port where the server is listening.
28
+ * @property {string} family - The IP address family reported by Node.js.
29
+ * @property {string} displayHost - The hostname used when displaying the address.
30
+ */
31
+
32
+ // ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
33
+
34
+ /**
35
+ * Represents the network address of an HTTP server.
36
+ *
37
+ * @classdesc Immutable value object that encapsulates the network address,
38
+ * port and IP address family of an HTTP server.
39
+ *
40
+ * It provides multiple representations of the same address,
41
+ * including plain objects, JSON serialization and canonical string formatting.
42
+ *
43
+ * IPv6 addresses are automatically enclosed in square brackets when
44
+ * converted to their string representation.
45
+ */
46
+ class Address {
47
+ /**
48
+ * The server network address.
49
+ *
50
+ * @type {string}
51
+ */
52
+ #address;
53
+
54
+ /**
55
+ * The TCP port where the server is listening.
56
+ *
57
+ * @type {number}
58
+ */
59
+ #port;
60
+
61
+ /**
62
+ * The IP address family.
63
+ *
64
+ * @type {string}
65
+ */
66
+ #family;
67
+
68
+ /**
69
+ * Creates a new Address instance.
70
+ *
71
+ * @param {AddressOptions} options - The server network address.
72
+ * @example
73
+ * ```js
74
+ * const address = new Address({
75
+ * address: '127.0.0.1',
76
+ * port: 3000,
77
+ * family: 'IPv4'
78
+ * });
79
+ *
80
+ * console.log(address.toString()); // '127.0.0.1:3000'
81
+ * ```
82
+ */
83
+ constructor({ address, port, family }) {
84
+ this.#address = address;
85
+ this.#port = port;
86
+ this.#family = family;
87
+ }
88
+
89
+ /**
90
+ * The network address where the server is listening.
91
+ *
92
+ * @readonly
93
+ * @type {string}
94
+ */
95
+ get address() {
96
+ return this.#address;
97
+ }
98
+
99
+ /**
100
+ * The TCP port where the server is listening.
101
+ *
102
+ * @readonly
103
+ * @type {number}
104
+ */
105
+ get port() {
106
+ return this.#port;
107
+ }
108
+
109
+ /**
110
+ * The IP address family.
111
+ *
112
+ * @readonly
113
+ * @type {string}
114
+ */
115
+ get family() {
116
+ return this.#family;
117
+ }
118
+
119
+ /**
120
+ * The hostname used when displaying the network address.
121
+ *
122
+ * IPv4 and IPv6 loopback addresses.
123
+ *
124
+ * @readonly
125
+ * @type {string}
126
+ */
127
+ get displayHost() {
128
+ if (this.#address === '127.0.0.1' || this.#address === '::1') {
129
+ return 'localhost';
130
+ }
131
+
132
+ return this.#address;
133
+ }
134
+
135
+ /**
136
+ * Custom string tag for better type identification.
137
+ *
138
+ * @readonly
139
+ * @type {string}
140
+ * @example
141
+ * ```js
142
+ * const address = new Address({...});
143
+ * console.log(Object.prototype.toString.call(address)); // '[object Address]'
144
+ * console.log(address[Symbol.toStringTag]); // 'Address'
145
+ * ```
146
+ */
147
+ get [Symbol.toStringTag]() {
148
+ return this.constructor.name;
149
+ }
150
+
151
+ /**
152
+ * Returns the address as a plain JavaScript object.
153
+ *
154
+ * The returned object includes the real network data and a display-friendly
155
+ * host derived from loopback normalization.
156
+ *
157
+ * @returns {AddressInfo} A plain object representation of this address.
158
+ * @example
159
+ * ```js
160
+ * console.log(address.toObject());
161
+ * // {
162
+ * // address: '::1',
163
+ * // port: 3000,
164
+ * // family: 'IPv6',
165
+ * // displayHost: 'localhost'
166
+ * // }
167
+ * ```
168
+ */
169
+ toObject() {
170
+ return {
171
+ address: this.#address,
172
+ port: this.#port,
173
+ family: this.#family,
174
+ displayHost: this.displayHost,
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Returns a JSON-serializable representation of this address.
180
+ *
181
+ * This method is automatically used by JSON.stringify().
182
+ *
183
+ * @returns {AddressInfo} A JSON representation of this address.
184
+ * @example
185
+ * ```js
186
+ * const json = JSON.stringify(address);
187
+ *
188
+ * console.log(json); // {"address":"::1","port":3000,"family":"IPv6","displayHost":"localhost"}
189
+ * ```
190
+ */
191
+ toJSON() {
192
+ return this.toObject();
193
+ }
194
+
195
+ /**
196
+ * Returns the canonical string representation of this address.
197
+ *
198
+ * IPv4 addresses are represented as `host:port`.
199
+ * IPv6 addresses are represented as `[host]:port`.
200
+ *
201
+ * @returns {string} The canonical network address.
202
+ * @example
203
+ * ```js
204
+ * const ipv4 = new Address({
205
+ * address: '127.0.0.1',
206
+ * port: 3000,
207
+ * family: 'IPv4'
208
+ * });
209
+ *
210
+ * console.log(ipv4.toString()); // '127.0.0.1:3000'
211
+ * ```
212
+ *
213
+ * @example
214
+ * ```js
215
+ * const ipv6 = new Address({
216
+ * address: '2001:db8::1',
217
+ * port: 3000,
218
+ * family: 'IPv6'
219
+ * });
220
+ *
221
+ * console.log(ipv6.toString()); // '[2001:db8::1]:3000'
222
+ * ```
223
+ */
224
+ toString() {
225
+ const host = this.#family === 'IPv6' ? `[${this.#address}]` : this.#address;
226
+
227
+ return `${host}:${this.#port}`;
228
+ }
229
+
230
+ /**
231
+ * Custom inspect implementation for Node.js `util.inspect()`.
232
+ *
233
+ * @returns {string} Custom string representation for debugging.
234
+ * @example
235
+ * ```js
236
+ * const address = new Address({...});
237
+ *
238
+ * console.log(address);
239
+ * // Address {
240
+ * // address: '::1',
241
+ * // port: 5173,
242
+ * // family: 'IPv6',
243
+ * // displayHost: 'localhost'
244
+ * // }
245
+ * ```
246
+ */
247
+ [inspect.custom]() {
248
+ return `${this.constructor.name} ${inspect(this.toObject(), { colors: true })}`;
249
+ }
250
+
251
+ /**
252
+ * Converts this address to a primitive value.
253
+ *
254
+ * String and default conversions return the canonical address string.
255
+ * Numeric conversion is not supported.
256
+ *
257
+ * @param {'string'|'number'|'default'} hint - The preferred primitive type.
258
+ * @returns {string} The canonical address string.
259
+ * @throws {TypeError} Thrown when a numeric conversion is attempted.
260
+ * @example
261
+ * ```js
262
+ * const address = new Address({
263
+ * address: '127.0.0.1',
264
+ * port: 3000,
265
+ * family: 'IPv4'
266
+ * });
267
+ *
268
+ * console.log(`Server Address: ${address}`); // '127.0.0.1:3000'
269
+ * console.log(String(address)); // '127.0.0.1:3000'
270
+ * ```
271
+ */
272
+ [Symbol.toPrimitive](hint) {
273
+ if (hint === 'number') {
274
+ throw new TypeError(`${this.constructor.name} cannot be converted to number.`);
275
+ }
276
+ return this.toString();
277
+ }
278
+ }
279
+
280
+ // ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
281
+ export default Address;
@@ -0,0 +1,293 @@
1
+ // @ts-check
2
+ /**
3
+ * @file Defines the Endpoint value object.
4
+ *
5
+ * @module Endpoint
6
+ */
7
+
8
+ // ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
9
+ // » IMPORT NATIVE NODEJS MODULES
10
+ import { inspect } from 'node:util';
11
+
12
+ // ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
13
+ /**
14
+ * Represents the network address of an HTTP server.
15
+ *
16
+ * @typedef {import('#value-objects/Address').default} Address
17
+ */
18
+
19
+ /**
20
+ * Identifies an application-layer communication protocol.
21
+ *
22
+ * @typedef { 'http'|'https'|'ws'|'wss'|'grpc'|'mqtt'|'coap' } Protocol
23
+ */
24
+
25
+ /**
26
+ * Represents network endpoint configuration options.
27
+ *
28
+ * @typedef {object} EndpointOptions
29
+ * @property {Protocol} protocol - The communication protocol.
30
+ * @property {Address} address - The server network address.
31
+ */
32
+
33
+ /**
34
+ * Represents the data of a network endpoint.
35
+ *
36
+ * @typedef {object} EndpointData
37
+ * @property {Protocol} protocol - The communication protocol.
38
+ * @property {string} address - The network address where the server is listening.
39
+ * @property {number} port - The TCP port where the server is listening.
40
+ * @property {string} family - The IP address family.
41
+ * @property {string} displayHost - The hostname used when displaying the address.
42
+ * @property {string} displayUrl - The URL used when displaying the endpoint.
43
+ */
44
+
45
+ // ━━ MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
46
+ /**
47
+ * Represents a complete network endpoint.
48
+ *
49
+ * @classdesc Immutable value object that combines a communication protocol
50
+ * with a network address.
51
+ *
52
+ * It provides multiple representations of the same endpoint,
53
+ * including plain objects, JSON serialization and URL formatting.
54
+ */
55
+ class Endpoint {
56
+ /**
57
+ * The communication protocol of the endpoint.
58
+ *
59
+ * @type {Protocol}
60
+ */
61
+ #protocol;
62
+
63
+ /**
64
+ * The server network address.
65
+ *
66
+ * @type {Address}
67
+ */
68
+ #address;
69
+
70
+ /**
71
+ * Creates a new Endpoint instance.
72
+ *
73
+ * @param {EndpointOptions} options - The network endpoint configuration.
74
+ * @example
75
+ * ```js
76
+ * const address = new Address({
77
+ * address: '127.0.0.1',
78
+ * port: 3000,
79
+ * family: 'IPv4',
80
+ * });
81
+ *
82
+ * const endpoint = new Endpoint({
83
+ * protocol: 'http',
84
+ * address,
85
+ * });
86
+ * ```
87
+ */
88
+ constructor({ protocol, address }) {
89
+ this.#protocol = protocol;
90
+ this.#address = address;
91
+ }
92
+
93
+ /**
94
+ * The communication protocol.
95
+ *
96
+ * @readonly
97
+ * @type {Protocol}
98
+ */
99
+ get protocol() {
100
+ return this.#protocol;
101
+ }
102
+
103
+ /**
104
+ * The network address where the server is listening.
105
+ *
106
+ * @readonly
107
+ * @type {string}
108
+ */
109
+ get address() {
110
+ return this.#address.address;
111
+ }
112
+
113
+ /**
114
+ * The TCP port where the server is listening.
115
+ *
116
+ * @readonly
117
+ * @type {number}
118
+ */
119
+ get port() {
120
+ return this.#address.port;
121
+ }
122
+
123
+ /**
124
+ * The IP address family.
125
+ *
126
+ * @readonly
127
+ * @type {string}
128
+ */
129
+ get family() {
130
+ return this.#address.family;
131
+ }
132
+
133
+ /**
134
+ * The hostname used when displaying the network address.
135
+ *
136
+ * IPv4 and IPv6 loopback addresses.
137
+ *
138
+ * @readonly
139
+ * @type {string}
140
+ */
141
+ get displayHost() {
142
+ return this.#address.displayHost;
143
+ }
144
+
145
+ /**
146
+ * The URL used when displaying the endpoint.
147
+ *
148
+ * Loopback addresses are rendered as `localhost`.
149
+ *
150
+ * @readonly
151
+ * @type {string}
152
+ * @example
153
+ * ```js
154
+ * console.log(endpoint.displayUrl); // 'http://localhost:3000'
155
+ * ```
156
+ */
157
+ get displayUrl() {
158
+ const { displayHost, family, port } = this.#address;
159
+ const host =
160
+ family === 'IPv6' && displayHost !== 'localhost' ? `[${displayHost}]` : displayHost;
161
+
162
+ return `${this.#protocol}://${host}:${port}`;
163
+ }
164
+
165
+ /**
166
+ * Custom string tag for better type identification.
167
+ *
168
+ * @readonly
169
+ * @type {string}
170
+ * @example
171
+ * ```js
172
+ * const endpoint = new Endpoint({...});
173
+ * console.log(Object.prototype.toString.call(endpoint)); // '[object Endpoint]'
174
+ * console.log(endpoint[Symbol.toStringTag]); // 'Endpoint'
175
+ * ```
176
+ */
177
+ get [Symbol.toStringTag]() {
178
+ return this.constructor.name;
179
+ }
180
+
181
+ /**
182
+ * Returns the endpoint as a plain JavaScript object.
183
+ *
184
+ * @returns {EndpointData} A plain object representation of this endpoint.
185
+ * @example
186
+ * ```js
187
+ * console.log(endpoint.toObject());
188
+ * // {
189
+ * // protocol: 'http',
190
+ * // address: '::1',
191
+ * // port: 3000,
192
+ * // family: 'IPv6',
193
+ * // displayHost: 'localhost',
194
+ * // displayUrl: 'http://localhost:3000',
195
+ * // }
196
+ * ```
197
+ */
198
+ toObject() {
199
+ return {
200
+ protocol: this.#protocol,
201
+ ...this.#address.toObject(),
202
+ displayUrl: this.displayUrl,
203
+ };
204
+ }
205
+
206
+ /**
207
+ * Returns a JSON-serializable representation of this endpoint.
208
+ *
209
+ * This method is automatically used by JSON.stringify().
210
+ *
211
+ * @returns {EndpointData} A JSON representation of this endpoint.
212
+ * @example
213
+ * ```js
214
+ * const json = JSON.stringify(address);
215
+ *
216
+ * console.log(json); // {"protocol":"http","address":"::1","port":3000,"family":"IPv6","displayHost":"localhost","displayUrl":"http://localhost:3000"}
217
+ * ```
218
+ */
219
+ toJSON() {
220
+ return this.toObject();
221
+ }
222
+
223
+ /**
224
+ * Returns the canonical URL representation of this endpoint.
225
+ *
226
+ * The URL consists of the endpoint protocol followed by the canonical
227
+ * string representation of its server address.
228
+ *
229
+ * @returns {string} The canonical endpoint URL.
230
+ * @example
231
+ * ```js
232
+ * const address = new Address({
233
+ * address: '127.0.0.1',
234
+ * port: 3000,
235
+ * family: 'IPv4',
236
+ * });
237
+ *
238
+ * const endpoint = new Endpoint({
239
+ * protocol: 'http',
240
+ * address,
241
+ * });
242
+ *
243
+ * console.log(endpoint.toString()); // 'http://127.0.0.1:3000'
244
+ * ```
245
+ */
246
+ toString() {
247
+ return `${this.#protocol}://${this.#address}`;
248
+ }
249
+
250
+ /**
251
+ * Custom inspect implementation for Node.js `util.inspect()`.
252
+ *
253
+ * @returns {string} Custom string representation for debugging.
254
+ * @example
255
+ * ```js
256
+ * console.log(endpoint);
257
+ * // Endpoint {
258
+ * // protocol: 'http',
259
+ * // address: '::1',
260
+ * // port: 5173,
261
+ * // family: 'IPv6',
262
+ * // displayHost: 'localhost',
263
+ * // displayUrl: 'http://localhost:5173'
264
+ * // }
265
+ * ```
266
+ */
267
+ [inspect.custom]() {
268
+ return `${this.constructor.name} ${inspect(this.toObject(), { colors: true })}`;
269
+ }
270
+
271
+ /**
272
+ * Converts this endpoint to a primitive value.
273
+ *
274
+ * Numeric conversion is not supported.
275
+ *
276
+ * @param {'string'|'number'|'default'} hint - The preferred primitive type.
277
+ * @returns {string} The canonical endpoint URL.
278
+ * @throws {TypeError} Thrown when a numeric conversion is attempted.
279
+ * @example
280
+ * ```js
281
+ * console.log(`${endpoint}`); // 'http://127.0.0.1:3000'
282
+ * ```
283
+ */
284
+ [Symbol.toPrimitive](hint) {
285
+ if (hint === 'number') {
286
+ throw new TypeError(`${this.constructor.name} cannot be converted to number.`);
287
+ }
288
+ return this.toString();
289
+ }
290
+ }
291
+
292
+ // ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
293
+ export default Endpoint;
@@ -0,0 +1,62 @@
1
+ // @ts-check
2
+ /**
3
+ * @file Public API for the `@boo/server` package.
4
+ *
5
+ * @description Exposes the public classes for configuring, routing, and
6
+ * running zero-dependency HTTP servers in Node.js, following Clean
7
+ * Architecture principles.
8
+ *
9
+ * Exports:
10
+ *
11
+ * - Server (default): The main HTTP server class.
12
+ * - Router: Provides route registration and composition.
13
+ * - HttpServerConfiguration: Configuration for standard HTTP/1.1 servers.
14
+ * - HttpsServerConfiguration: Configuration for secure HTTPS servers.
15
+ * - Http2CleartextServerConfiguration: Configuration for cleartext HTTP/2 (h2c) servers.
16
+ * - Http2SecureServerConfiguration: Configuration for secure HTTP/2 (h2) servers.
17
+ *
18
+ * @module BooServerAPI
19
+ */
20
+
21
+ // ━━ IMPORT MODULES ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
22
+ // » IMPORT LOCAL MODULES
23
+ import Server from '#Server';
24
+ import Router from '#routing/Router';
25
+ import HttpServerConfiguration from '#configurations/HttpServerConfiguration';
26
+ import HttpsServerConfiguration from '#configurations/HttpsServerConfiguration';
27
+ import Http2CleartextServerConfiguration from '#configurations/Http2CleartextServerConfiguration';
28
+ import Http2SecureServerConfiguration from '#configurations/Http2SecureServerConfiguration';
29
+
30
+ // ━━ TYPE DEFINITIONS ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
31
+ /**
32
+ * Public API namespace for the `@boo/server` package.
33
+ *
34
+ * Describes the classes exposed by the package's public entry point.
35
+ *
36
+ * @typedef {object} BooServerAPI
37
+ * @property {typeof Server} default - Main HTTP server class.
38
+ * @property {typeof Router} Router - Route registration and composition.
39
+ * @property {typeof HttpServerConfiguration} HttpServerConfiguration - HTTP/1.1 server configuration.
40
+ * @property {typeof HttpsServerConfiguration} HttpsServerConfiguration - HTTPS server configuration.
41
+ * @property {typeof Http2CleartextServerConfiguration} Http2CleartextServerConfiguration - Cleartext HTTP/2 (h2c) server configuration.
42
+ * @property {typeof Http2SecureServerConfiguration} Http2SecureServerConfiguration - Secure HTTP/2 (h2) server configuration.
43
+ */
44
+
45
+ // ━━ EXPORT MODULE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
46
+ /**
47
+ * Default export: The primary class used to create and run an HTTP server.
48
+ *
49
+ * @type {typeof Server}
50
+ */
51
+ export default Server;
52
+
53
+ /**
54
+ * Named exports: The router and the supported server configuration classes.
55
+ */
56
+ export {
57
+ Router,
58
+ HttpServerConfiguration,
59
+ HttpsServerConfiguration,
60
+ Http2CleartextServerConfiguration,
61
+ Http2SecureServerConfiguration,
62
+ };