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

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