@catbee/utils 0.0.8-rc.2 → 0.0.8-rc.3

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 (66) hide show
  1. package/build/cjs/config.d.ts +121 -0
  2. package/build/cjs/config.js +137 -0
  3. package/build/cjs/index.d.ts +26 -0
  4. package/build/cjs/index.js +68 -0
  5. package/build/cjs/servers/server.builder.d.ts +507 -0
  6. package/build/cjs/servers/server.builder.js +658 -0
  7. package/build/cjs/servers/server.d.ts +255 -0
  8. package/build/cjs/servers/server.js +970 -0
  9. package/build/cjs/types/api-response.d.ts +151 -0
  10. package/build/cjs/types/api-response.js +36 -0
  11. package/build/cjs/types/index.d.ts +124 -0
  12. package/build/cjs/types/index.js +25 -0
  13. package/build/cjs/types/server.d.ts +267 -0
  14. package/build/cjs/types/server.js +25 -0
  15. package/build/cjs/utils/array.utils.d.ts +167 -0
  16. package/build/cjs/utils/array.utils.js +363 -0
  17. package/build/cjs/utils/async.utils.d.ts +264 -0
  18. package/build/cjs/utils/async.utils.js +640 -0
  19. package/build/cjs/utils/cache.utils.d.ts +152 -0
  20. package/build/cjs/utils/cache.utils.js +298 -0
  21. package/build/cjs/utils/context-store.utils.d.ts +188 -0
  22. package/build/cjs/utils/context-store.utils.js +297 -0
  23. package/build/cjs/utils/crypto.utils.d.ts +159 -0
  24. package/build/cjs/utils/crypto.utils.js +295 -0
  25. package/build/cjs/utils/date.utils.d.ts +158 -0
  26. package/build/cjs/utils/date.utils.js +395 -0
  27. package/build/cjs/utils/decorators.utils.d.ts +511 -0
  28. package/build/cjs/utils/decorators.utils.js +1035 -0
  29. package/build/cjs/utils/dir.utils.d.ts +195 -0
  30. package/build/cjs/utils/dir.utils.js +500 -0
  31. package/build/cjs/utils/env.utils.d.ts +376 -0
  32. package/build/cjs/utils/env.utils.js +786 -0
  33. package/build/cjs/utils/exception.utils.d.ts +229 -0
  34. package/build/cjs/utils/exception.utils.js +408 -0
  35. package/build/cjs/utils/fs.utils.d.ts +163 -0
  36. package/build/cjs/utils/fs.utils.js +371 -0
  37. package/build/cjs/utils/http-status-codes.d.ts +265 -0
  38. package/build/cjs/utils/http-status-codes.js +297 -0
  39. package/build/cjs/utils/id.utils.d.ts +35 -0
  40. package/build/cjs/utils/id.utils.js +90 -0
  41. package/build/cjs/utils/logger.utils.d.ts +159 -0
  42. package/build/cjs/utils/logger.utils.js +350 -0
  43. package/build/cjs/utils/middleware.utils.d.ts +99 -0
  44. package/build/cjs/utils/middleware.utils.js +243 -0
  45. package/build/cjs/utils/obj.utils.d.ts +123 -0
  46. package/build/cjs/utils/obj.utils.js +428 -0
  47. package/build/cjs/utils/performance.utils.d.ts +135 -0
  48. package/build/cjs/utils/performance.utils.js +280 -0
  49. package/build/cjs/utils/request.utils.d.ts +85 -0
  50. package/build/cjs/utils/request.utils.js +199 -0
  51. package/build/cjs/utils/response.utils.d.ts +162 -0
  52. package/build/cjs/utils/response.utils.js +274 -0
  53. package/build/cjs/utils/stream.utils.d.ts +87 -0
  54. package/build/cjs/utils/stream.utils.js +217 -0
  55. package/build/cjs/utils/string.utils.d.ts +92 -0
  56. package/build/cjs/utils/string.utils.js +178 -0
  57. package/build/cjs/utils/type.utils.d.ts +89 -0
  58. package/build/cjs/utils/type.utils.js +195 -0
  59. package/build/cjs/utils/url.utils.d.ts +140 -0
  60. package/build/cjs/utils/url.utils.js +316 -0
  61. package/build/cjs/utils/validate.utils.d.ts +176 -0
  62. package/build/cjs/utils/validate.utils.js +344 -0
  63. package/build/esm/utils/context-store.utils.d.ts +1 -1
  64. package/build/esm/utils/context-store.utils.js +1 -1
  65. package/build/esm/utils/decorators.utils.js +1 -1
  66. package/package.json +287 -32
@@ -0,0 +1,658 @@
1
+ "use strict";
2
+ /*
3
+ * The MIT License
4
+ *
5
+ * Copyright (c) 2025 Catbee Technologies. https://catbee-utils.npm.hprasath.com/license
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in all
15
+ * copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ * SOFTWARE.
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.ServerConfigBuilder = exports.BUILD_MARKER = void 0;
27
+ const obj_utils_1 = require("../utils/obj.utils");
28
+ const config_1 = require("../config");
29
+ const validate_utils_1 = require("../utils/validate.utils");
30
+ /**
31
+ * Builder class for creating and configuring an Express server configuration.
32
+ *
33
+ * This class provides a fluent interface to configure all aspects of the Express server
34
+ * including security settings, middleware, routing, and more.
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const serverConfig = new ServerConfigBuilder()
39
+ * .withPort(3000)
40
+ * .withHost('localhost')
41
+ * .enableCors()
42
+ * .enableHelmet()
43
+ * .build();
44
+ * ```
45
+ */
46
+ exports.BUILD_MARKER = Symbol.for('catbee.express.server.build');
47
+ class ServerConfigBuilder {
48
+ config = {};
49
+ /**
50
+ * Validates that a port number is valid and usable.
51
+ *
52
+ * @private
53
+ * @param port - The port number to validate
54
+ * @throws {Error} If port is not an integer or is outside the valid range (1-65535)
55
+ */
56
+ validatePort(port) {
57
+ if (!(0, validate_utils_1.isPort)(port)) {
58
+ throw new Error(`Port must be a valid number between 1 and 65535, got: ${port}`);
59
+ }
60
+ }
61
+ /**
62
+ * Sets the port the server will listen on.
63
+ *
64
+ * @param port - The port number (1-65535)
65
+ * @returns The builder instance for chaining
66
+ * @throws {Error} If port is invalid
67
+ * @default 3000 (can be overridden via PORT env variable)
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * builder.withPort(3000)
72
+ * ```
73
+ */
74
+ withPort(port) {
75
+ this.validatePort(port);
76
+ this.config.port = port;
77
+ return this;
78
+ }
79
+ /**
80
+ * Sets the hostname the server will bind to.
81
+ *
82
+ * @param host - The hostname (e.g., 'localhost', '0.0.0.0', '127.0.0.1')
83
+ * @returns The builder instance for chaining
84
+ * @default '0.0.0.0' (can be overridden via HOST env variable)
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * builder.withHost('0.0.0.0') // Listen on all interfaces
89
+ * ```
90
+ */
91
+ withHost(host) {
92
+ this.config.host = host;
93
+ return this;
94
+ }
95
+ /**
96
+ * Configures Cross-Origin Resource Sharing (CORS) for the server.
97
+ *
98
+ * @param opts - CORS options object or boolean (true to enable with defaults, false to disable)
99
+ * @returns The builder instance for chaining
100
+ * @default false (CORS is disabled by default)
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * // Enable CORS with default options
105
+ * builder.withCors(true)
106
+ *
107
+ * // Configure CORS with specific options
108
+ * builder.withCors({
109
+ * origin: ['https://example.com'],
110
+ * methods: ['GET', 'POST']
111
+ * })
112
+ * ```
113
+ */
114
+ withCors(opts) {
115
+ this.config.cors = opts;
116
+ return this;
117
+ }
118
+ /**
119
+ * Enables CORS with default settings
120
+ *
121
+ * @returns The builder instance for chaining
122
+ */
123
+ enableCors() {
124
+ return this.withCors(true);
125
+ }
126
+ /**
127
+ * Disables CORS
128
+ *
129
+ * @returns The builder instance for chaining
130
+ */
131
+ disableCors() {
132
+ return this.withCors(false);
133
+ }
134
+ /**
135
+ * Configures the Helmet middleware for setting HTTP security headers.
136
+ *
137
+ * @param opts - Helmet options object or boolean (true to enable with defaults, false to disable)
138
+ * @returns The builder instance for chaining
139
+ * @default false (Helmet is disabled by default)
140
+ *
141
+ * @example
142
+ * ```typescript
143
+ * // Enable Helmet with default settings
144
+ * builder.withHelmet(true)
145
+ *
146
+ * // Configure Helmet with specific options
147
+ * builder.withHelmet({
148
+ * contentSecurityPolicy: false,
149
+ * xssFilter: true
150
+ * })
151
+ * ```
152
+ */
153
+ withHelmet(opts) {
154
+ this.config.helmet = opts;
155
+ return this;
156
+ }
157
+ /**
158
+ * Enables Helmet with default settings
159
+ *
160
+ * @returns The builder instance for chaining
161
+ */
162
+ enableHelmet() {
163
+ return this.withHelmet(true);
164
+ }
165
+ /**
166
+ * Disables Helmet
167
+ *
168
+ * @returns The builder instance for chaining
169
+ */
170
+ disableHelmet() {
171
+ return this.withHelmet(false);
172
+ }
173
+ /**
174
+ * Configures response compression middleware.
175
+ *
176
+ * @param opts - Compression options object or boolean (true to enable with defaults, false to disable)
177
+ * @returns The builder instance for chaining
178
+ * @default false (Compression is disabled by default)
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * // Enable compression with default settings
183
+ * builder.withCompression(true)
184
+ *
185
+ * // Configure compression with specific options
186
+ * builder.withCompression({
187
+ * level: 6,
188
+ * threshold: 1024
189
+ * })
190
+ * ```
191
+ */
192
+ withCompression(opts) {
193
+ this.config.compression = opts;
194
+ return this;
195
+ }
196
+ /**
197
+ * Enables compression with default settings
198
+ *
199
+ * @returns The builder instance for chaining
200
+ */
201
+ enableCompression() {
202
+ return this.withCompression(true);
203
+ }
204
+ /**
205
+ * Disables compression
206
+ *
207
+ * @returns The builder instance for chaining
208
+ */
209
+ disableCompression() {
210
+ return this.withCompression(false);
211
+ }
212
+ /**
213
+ * Configures rate limiting to protect against brute-force attacks.
214
+ *
215
+ * @param opts - Rate limit configuration options
216
+ * @returns The builder instance for chaining
217
+ * @default { enable: false, windowMs: 15 * 60 * 1000, max: 100, message: 'Too many requests', standardHeaders: true, legacyHeaders: false }
218
+ *
219
+ * @example
220
+ * ```typescript
221
+ * builder.withRateLimit({
222
+ * enable: true,
223
+ * windowMs: 15 * 60 * 1000, // 15 minutes
224
+ * max: 100 // limit each IP to 100 requests per windowMs
225
+ * })
226
+ * ```
227
+ */
228
+ withRateLimit(opts) {
229
+ this.mergeConfig('rateLimit', opts);
230
+ return this;
231
+ }
232
+ /**
233
+ * Enables rate limiting with default or custom settings
234
+ *
235
+ * @param opts - Optional rate limit configuration (max requests, window, etc.)
236
+ * @returns The builder instance for chaining
237
+ */
238
+ enableRateLimit(opts = {}) {
239
+ return this.setEnabled('rateLimit', true, opts);
240
+ }
241
+ /**
242
+ * Disables rate limiting
243
+ *
244
+ * @returns The builder instance for chaining
245
+ */
246
+ disableRateLimit() {
247
+ return this.setEnabled('rateLimit', false);
248
+ }
249
+ /**
250
+ * Configures HTTP request logging middleware.
251
+ *
252
+ * @param opts - Request logging configuration options
253
+ * @returns The builder instance for chaining
254
+ * @default { enable: true in dev/false in prod, ignorePaths: ['/healthz', '/favicon.ico', '/metrics', '/docs', '/.well-known'], skipNotFoundRoutes: false }
255
+ *
256
+ * @example
257
+ * ```typescript
258
+ * builder.withRequestLogging({
259
+ * enable: true,
260
+ * ignorePaths: ['/health', '/metrics'],
261
+ * skipNotFoundRoutes: true
262
+ * })
263
+ * ```
264
+ */
265
+ withRequestLogging(opts) {
266
+ this.mergeConfig('requestLogging', opts);
267
+ return this;
268
+ }
269
+ /**
270
+ * Enables request logging with default or custom settings
271
+ *
272
+ * @param opts - Optional request logging configuration
273
+ * @returns The builder instance for chaining
274
+ */
275
+ enableRequestLogging(opts = {}) {
276
+ return this.setEnabled('requestLogging', true, opts);
277
+ }
278
+ /**
279
+ * Disables request logging
280
+ *
281
+ * @returns The builder instance for chaining
282
+ */
283
+ disableRequestLogging() {
284
+ return this.setEnabled('requestLogging', false);
285
+ }
286
+ /**
287
+ * Configures server metrics collection and endpoints.
288
+ *
289
+ * @param opts - Metrics configuration options
290
+ * @returns The builder instance for chaining
291
+ * @default { enable: false, path: '/metrics', withGlobalPrefix: false }
292
+ *
293
+ * @example
294
+ * ```typescript
295
+ * builder.withMetrics({
296
+ * enable: true,
297
+ * path: '/metrics'
298
+ * })
299
+ * ```
300
+ */
301
+ withMetrics(opts) {
302
+ this.mergeConfig('metrics', opts);
303
+ return this;
304
+ }
305
+ /**
306
+ * Enables Prometheus metrics collection and endpoint
307
+ *
308
+ * @param opts - Optional metrics configuration
309
+ * @returns The builder instance for chaining
310
+ */
311
+ enableMetrics(opts = {}) {
312
+ return this.setEnabled('metrics', true, opts);
313
+ }
314
+ /**
315
+ * Disables Prometheus metrics
316
+ *
317
+ * @returns The builder instance for chaining
318
+ */
319
+ disableMetrics() {
320
+ return this.setEnabled('metrics', false);
321
+ }
322
+ /**
323
+ * Configures server health check endpoint.
324
+ *
325
+ * @param opts - Health check configuration options
326
+ * @returns The builder instance for chaining
327
+ * @default { path: '/healthz', detailed: true, withGlobalPrefix: false }
328
+ *
329
+ * @example
330
+ * ```typescript
331
+ * builder.withHealthCheck({
332
+ * path: '/health',
333
+ * detailed: true
334
+ * })
335
+ * ```
336
+ */
337
+ withHealthCheck(opts) {
338
+ this.mergeConfig('healthCheck', opts);
339
+ return this;
340
+ }
341
+ /**
342
+ * Configures OpenAPI/Swagger documentation for the API.
343
+ *
344
+ * @param opts - OpenAPI configuration options
345
+ * @returns The builder instance for chaining
346
+ * @default { enable: false, mountPath: '/docs', verbose: false, withGlobalPrefix: false }
347
+ *
348
+ * @example
349
+ * ```typescript
350
+ * builder.withOpenApi({
351
+ * enable: true,
352
+ * path: '/api-docs',
353
+ * filePath: './openapi.yaml'
354
+ * })
355
+ * ```
356
+ */
357
+ withOpenApi(opts) {
358
+ this.mergeConfig('openApi', opts);
359
+ return this;
360
+ }
361
+ /**
362
+ * Enables OpenAPI documentation with required file path
363
+ *
364
+ * @param filePath - Path to OpenAPI specification file (required)
365
+ * @param opts - Optional OpenAPI configuration
366
+ * @returns The builder instance for chaining
367
+ */
368
+ enableOpenApi(filePath, opts = {}) {
369
+ this.setEnabled('openApi', true, { filePath, ...opts });
370
+ return this;
371
+ }
372
+ /**
373
+ * Disables OpenAPI documentation
374
+ *
375
+ * @returns The builder instance for chaining
376
+ */
377
+ disableOpenApi() {
378
+ return this.setEnabled('openApi', false);
379
+ }
380
+ /**
381
+ * Configures the server as a microservice with versioning.
382
+ *
383
+ * @param opts - Microservice configuration options including app name and service version
384
+ * @returns The builder instance for chaining
385
+ * @default { isMicroservice: false, appName: 'express_app' }
386
+ *
387
+ * @example
388
+ * ```typescript
389
+ * builder.withMicroService({
390
+ * appName: 'user-service',
391
+ * serviceVersion: {
392
+ * enable: true,
393
+ * version: '1.2.3'
394
+ * }
395
+ * })
396
+ * ```
397
+ */
398
+ withMicroService(opts) {
399
+ this.config.isMicroservice = true;
400
+ this.config.appName = opts.appName;
401
+ this.mergeConfig('serviceVersion', opts.serviceVersion);
402
+ return this;
403
+ }
404
+ /**
405
+ * Configures the trust proxy settings to determine if X-Forwarded-* headers should be trusted.
406
+ *
407
+ * @param opts - Trust proxy configuration options
408
+ * @returns The builder instance for chaining
409
+ * @default false
410
+ *
411
+ * @example
412
+ * ```typescript
413
+ * // Trust proxy headers (useful when behind a load balancer)
414
+ * builder.withTrustProxy(true)
415
+ * ```
416
+ */
417
+ withTrustProxy(opts) {
418
+ this.config.trustProxy = opts;
419
+ return this;
420
+ }
421
+ /**
422
+ * Configures the request ID middleware for tracing requests across services.
423
+ *
424
+ * @param opts - Request ID configuration options
425
+ * @returns The builder instance for chaining
426
+ * @default { headerName: 'x-request-id', exposeHeader: true }
427
+ *
428
+ * @example
429
+ * ```typescript
430
+ * builder.withRequestId({
431
+ * headerName: 'X-Request-Id',
432
+ * generator: () => crypto.randomUUID()
433
+ * })
434
+ * ```
435
+ */
436
+ withRequestId(opts) {
437
+ this.mergeConfig('requestId', opts);
438
+ return this;
439
+ }
440
+ /**
441
+ * Configures the response time middleware for measuring request processing times.
442
+ *
443
+ * @param opts - Response time configuration options
444
+ * @returns The builder instance for chaining
445
+ * @default { enable: false, addHeader: true, logOnComplete: false }
446
+ *
447
+ * @example
448
+ * ```typescript
449
+ * builder.withResponseTime({
450
+ * enable: true,
451
+ * addHeader: true,
452
+ * logOnComplete: true
453
+ * })
454
+ * ```
455
+ */
456
+ withResponseTime(opts) {
457
+ this.mergeConfig('responseTime', opts);
458
+ return this;
459
+ }
460
+ /**
461
+ * Enables response time tracking with default or custom settings
462
+ *
463
+ * @param opts - Optional response time configuration
464
+ * @returns The builder instance for chaining
465
+ */
466
+ enableResponseTime(opts = {}) {
467
+ this.setEnabled('responseTime', true, opts);
468
+ return this;
469
+ }
470
+ /**
471
+ * Disables response time tracking
472
+ *
473
+ * @returns The builder instance for chaining
474
+ */
475
+ disableResponseTime() {
476
+ return this.setEnabled('responseTime', false);
477
+ }
478
+ /**
479
+ * Configures the body parser middleware options for parsing request bodies.
480
+ *
481
+ * @param opts - Body parser configuration options
482
+ * @returns The builder instance for chaining
483
+ * @default { json: { limit: '1mb' }, urlencoded: { extended: true, limit: '1mb' } }
484
+ *
485
+ * @example
486
+ * ```typescript
487
+ * builder.withBodyParser({
488
+ * json: {
489
+ * limit: '1mb'
490
+ * },
491
+ * urlencoded: {
492
+ * extended: true,
493
+ * limit: '1mb'
494
+ * }
495
+ * })
496
+ * ```
497
+ */
498
+ withBodyParser(opts) {
499
+ this.config.bodyParser = (0, obj_utils_1.deepObjMerge)({}, this.config.bodyParser ?? {}, opts);
500
+ return this;
501
+ }
502
+ /**
503
+ * Configures cookie parsing middleware.
504
+ *
505
+ * @param opts - Cookie parser options or boolean (true to enable with defaults, false to disable)
506
+ * @returns The builder instance for chaining
507
+ * @default false
508
+ *
509
+ * @example
510
+ * ```typescript
511
+ * // Enable cookie parsing with default options
512
+ * builder.withCookies(true)
513
+ *
514
+ * // Enable cookie parsing with specific options
515
+ * builder.withCookies({
516
+ * secret: 'your-secret-key',
517
+ * secure: true
518
+ * })
519
+ * ```
520
+ */
521
+ withCookies(opts) {
522
+ this.config.cookieParser = opts;
523
+ return this;
524
+ }
525
+ /**
526
+ * Adds a static folder to serve files from.
527
+ *
528
+ * @param folder - Static folder configuration
529
+ * @returns The builder instance for chaining
530
+ *
531
+ * @example
532
+ * ```typescript
533
+ * builder.withStaticFolder({
534
+ * path: '/assets',
535
+ * directory: './public',
536
+ * options: { maxAge: '1d' }
537
+ * })
538
+ * ```
539
+ */
540
+ withStaticFolder(folder) {
541
+ if (!folder.path)
542
+ throw new Error('Static folder requires a path');
543
+ const folders = [...(this.config.staticFolders ?? []), folder];
544
+ this.config.staticFolders = Array.from(new Map(folders.map(f => [f.path, f])).values());
545
+ return this;
546
+ }
547
+ /**
548
+ * Sets global headers to be included in all responses.
549
+ *
550
+ * @param headers - Object containing header name/value pairs or functions that return values
551
+ * @returns The builder instance for chaining
552
+ * @default {}
553
+ *
554
+ * @example
555
+ * ```typescript
556
+ * builder.withGlobalHeaders({
557
+ * 'X-Powered-By': 'Catbee',
558
+ * 'Server-Time': () => new Date().toISOString()
559
+ * })
560
+ * ```
561
+ */
562
+ withGlobalHeaders(headers) {
563
+ this.mergeConfig('globalHeaders', headers);
564
+ return this;
565
+ }
566
+ /**
567
+ * Sets a global prefix for all routes.
568
+ *
569
+ * @param prefix - The prefix to prepend to all routes (e.g., '/api/v1')
570
+ * @returns The builder instance for chaining
571
+ * @default '/'
572
+ *
573
+ * @example
574
+ * ```typescript
575
+ * builder.withGlobalPrefix('/api/v1')
576
+ * ```
577
+ */
578
+ withGlobalPrefix(prefix) {
579
+ this.config.globalPrefix = prefix;
580
+ return this;
581
+ }
582
+ /**
583
+ * Applies custom configuration overrides directly.
584
+ *
585
+ * @param overrides - Custom configuration options to merge
586
+ * @returns The builder instance for chaining
587
+ *
588
+ * @example
589
+ * ```typescript
590
+ * builder.withCustom({
591
+ * port: 8080,
592
+ * customMiddleware: myMiddlewareFunction
593
+ * })
594
+ * ```
595
+ */
596
+ withCustom(overrides) {
597
+ this.config = (0, obj_utils_1.deepObjMerge)({}, this.config, overrides);
598
+ return this;
599
+ }
600
+ /**
601
+ * Configures HTTPS server options.
602
+ *
603
+ * @param opts - HTTPS configuration (key, cert, ca, passphrase, etc.)
604
+ * @returns The builder instance for chaining
605
+ *
606
+ * @example
607
+ * ```typescript
608
+ * builder.withHttps({
609
+ * key: './localhost-key.pem',
610
+ * cert: './localhost-cert.pem'
611
+ * })
612
+ * ```
613
+ */
614
+ withHttps(opts) {
615
+ this.config.https = opts;
616
+ return this;
617
+ }
618
+ /**
619
+ * Builds and returns the final server configuration.
620
+ *
621
+ * This method merges the user-specified configuration with default values,
622
+ * ensures all sections with 'enable' flags are properly structured, and
623
+ * produces the final configuration to be used by the server.
624
+ *
625
+ * @returns The complete ServerConfig object
626
+ *
627
+ * @example
628
+ * ```typescript
629
+ * const config = new ServerConfigBuilder()
630
+ * .withPort(3000)
631
+ * .withHost('localhost')
632
+ * .withCors(true)
633
+ * .build();
634
+ * ```
635
+ */
636
+ build() {
637
+ const config = (0, obj_utils_1.deepObjMerge)({}, config_1.defaultServerConfig, this.config);
638
+ // Common validation
639
+ if (config.openApi?.enable && !config.openApi.filePath) {
640
+ throw new Error('OpenAPI is enabled but no filePath is specified');
641
+ }
642
+ return Object.freeze({
643
+ ...config,
644
+ [exports.BUILD_MARKER]: true
645
+ });
646
+ }
647
+ mergeConfig(key, value) {
648
+ const current = typeof this.config[key] === 'object' && this.config[key] !== null
649
+ ? this.config[key]
650
+ : {};
651
+ this.config[key] = (0, obj_utils_1.deepObjMerge)({}, current, value);
652
+ }
653
+ setEnabled(key, enable, overrides = {}) {
654
+ this.mergeConfig(key, { ...overrides, enable });
655
+ return this;
656
+ }
657
+ }
658
+ exports.ServerConfigBuilder = ServerConfigBuilder;