@catbee/utils 0.0.6 → 0.0.7

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 (122) hide show
  1. package/README.md +51 -1106
  2. package/build/esm/config.d.ts +5 -13
  3. package/build/esm/config.js +0 -12
  4. package/build/esm/config.js.map +1 -1
  5. package/build/esm/servers/server.builder.d.ts +1 -118
  6. package/build/esm/servers/server.builder.js +0 -20
  7. package/build/esm/servers/server.builder.js.map +1 -1
  8. package/build/esm/servers/server.d.ts +2 -2
  9. package/build/esm/servers/server.js +3 -13
  10. package/build/esm/servers/server.js.map +1 -1
  11. package/build/esm/types/api-response.d.ts +28 -0
  12. package/build/esm/types/api-response.js +10 -1
  13. package/build/esm/types/api-response.js.map +1 -1
  14. package/build/esm/types/server.d.ts +0 -17
  15. package/build/esm/types/server.js.map +1 -1
  16. package/build/esm/utils/async.utils.d.ts +91 -0
  17. package/build/esm/utils/async.utils.js +244 -0
  18. package/build/esm/utils/async.utils.js.map +1 -1
  19. package/build/esm/utils/context-store.utils.d.ts +3 -0
  20. package/build/esm/utils/context-store.utils.js +9 -6
  21. package/build/esm/utils/context-store.utils.js.map +1 -1
  22. package/build/esm/utils/date.utils.d.ts +159 -0
  23. package/build/esm/utils/date.utils.js +389 -0
  24. package/build/esm/utils/date.utils.js.map +1 -0
  25. package/build/esm/utils/logger.utils.d.ts +3 -9
  26. package/build/esm/utils/logger.utils.js +3 -9
  27. package/build/esm/utils/logger.utils.js.map +1 -1
  28. package/build/esm/utils/middleware.utils.js +2 -1
  29. package/build/esm/utils/middleware.utils.js.map +1 -1
  30. package/build/esm/utils/performance.utils.d.ts +136 -0
  31. package/build/esm/utils/performance.utils.js +376 -0
  32. package/build/esm/utils/performance.utils.js.map +1 -0
  33. package/build/esm/utils/request.utils.d.ts +9 -0
  34. package/build/esm/utils/request.utils.js +32 -5
  35. package/build/esm/utils/request.utils.js.map +1 -1
  36. package/build/esm/utils/stream.utils.d.ts +88 -0
  37. package/build/esm/utils/stream.utils.js +284 -0
  38. package/build/esm/utils/stream.utils.js.map +1 -0
  39. package/build/esm/utils/type.utils.d.ts +90 -0
  40. package/build/esm/utils/type.utils.js +190 -0
  41. package/build/esm/utils/type.utils.js.map +1 -0
  42. package/build/esnext/config.d.ts +5 -13
  43. package/build/esnext/config.js +0 -12
  44. package/build/esnext/config.js.map +1 -1
  45. package/build/esnext/servers/server.builder.d.ts +1 -118
  46. package/build/esnext/servers/server.builder.js +0 -20
  47. package/build/esnext/servers/server.builder.js.map +1 -1
  48. package/build/esnext/servers/server.d.ts +2 -2
  49. package/build/esnext/servers/server.js +3 -13
  50. package/build/esnext/servers/server.js.map +1 -1
  51. package/build/esnext/types/api-response.d.ts +28 -0
  52. package/build/esnext/types/api-response.js +10 -1
  53. package/build/esnext/types/api-response.js.map +1 -1
  54. package/build/esnext/types/server.d.ts +0 -17
  55. package/build/esnext/types/server.js.map +1 -1
  56. package/build/esnext/utils/async.utils.d.ts +91 -0
  57. package/build/esnext/utils/async.utils.js +190 -0
  58. package/build/esnext/utils/async.utils.js.map +1 -1
  59. package/build/esnext/utils/context-store.utils.d.ts +3 -0
  60. package/build/esnext/utils/context-store.utils.js +9 -6
  61. package/build/esnext/utils/context-store.utils.js.map +1 -1
  62. package/build/esnext/utils/date.utils.d.ts +159 -0
  63. package/build/esnext/utils/date.utils.js +384 -0
  64. package/build/esnext/utils/date.utils.js.map +1 -0
  65. package/build/esnext/utils/logger.utils.d.ts +3 -9
  66. package/build/esnext/utils/logger.utils.js +3 -9
  67. package/build/esnext/utils/logger.utils.js.map +1 -1
  68. package/build/esnext/utils/middleware.utils.js +2 -1
  69. package/build/esnext/utils/middleware.utils.js.map +1 -1
  70. package/build/esnext/utils/performance.utils.d.ts +136 -0
  71. package/build/esnext/utils/performance.utils.js +271 -0
  72. package/build/esnext/utils/performance.utils.js.map +1 -0
  73. package/build/esnext/utils/request.utils.d.ts +9 -0
  74. package/build/esnext/utils/request.utils.js +23 -5
  75. package/build/esnext/utils/request.utils.js.map +1 -1
  76. package/build/esnext/utils/stream.utils.d.ts +88 -0
  77. package/build/esnext/utils/stream.utils.js +210 -0
  78. package/build/esnext/utils/stream.utils.js.map +1 -0
  79. package/build/esnext/utils/type.utils.d.ts +90 -0
  80. package/build/esnext/utils/type.utils.js +187 -0
  81. package/build/esnext/utils/type.utils.js.map +1 -0
  82. package/build/src/config.d.ts +5 -13
  83. package/build/src/config.js +0 -12
  84. package/build/src/config.js.map +1 -1
  85. package/build/src/servers/server.builder.d.ts +1 -118
  86. package/build/src/servers/server.builder.js +0 -20
  87. package/build/src/servers/server.builder.js.map +1 -1
  88. package/build/src/servers/server.d.ts +2 -2
  89. package/build/src/servers/server.js +2 -12
  90. package/build/src/servers/server.js.map +1 -1
  91. package/build/src/types/api-response.d.ts +28 -0
  92. package/build/src/types/api-response.js +11 -0
  93. package/build/src/types/api-response.js.map +1 -1
  94. package/build/src/types/server.d.ts +0 -17
  95. package/build/src/types/server.js.map +1 -1
  96. package/build/src/utils/async.utils.d.ts +91 -0
  97. package/build/src/utils/async.utils.js +194 -0
  98. package/build/src/utils/async.utils.js.map +1 -1
  99. package/build/src/utils/context-store.utils.d.ts +3 -0
  100. package/build/src/utils/context-store.utils.js +9 -6
  101. package/build/src/utils/context-store.utils.js.map +1 -1
  102. package/build/src/utils/date.utils.d.ts +159 -0
  103. package/build/src/utils/date.utils.js +396 -0
  104. package/build/src/utils/date.utils.js.map +1 -0
  105. package/build/src/utils/logger.utils.d.ts +3 -9
  106. package/build/src/utils/logger.utils.js +4 -10
  107. package/build/src/utils/logger.utils.js.map +1 -1
  108. package/build/src/utils/middleware.utils.js +2 -1
  109. package/build/src/utils/middleware.utils.js.map +1 -1
  110. package/build/src/utils/performance.utils.d.ts +136 -0
  111. package/build/src/utils/performance.utils.js +278 -0
  112. package/build/src/utils/performance.utils.js.map +1 -0
  113. package/build/src/utils/request.utils.d.ts +9 -0
  114. package/build/src/utils/request.utils.js +25 -5
  115. package/build/src/utils/request.utils.js.map +1 -1
  116. package/build/src/utils/stream.utils.d.ts +88 -0
  117. package/build/src/utils/stream.utils.js +218 -0
  118. package/build/src/utils/stream.utils.js.map +1 -0
  119. package/build/src/utils/type.utils.d.ts +90 -0
  120. package/build/src/utils/type.utils.js +196 -0
  121. package/build/src/utils/type.utils.js.map +1 -0
  122. package/package.json +6 -2
@@ -1,4 +1,4 @@
1
- import { LoggerLevels } from './utils/logger.utils';
1
+ import { Logger, LoggerLevels } from './utils/logger.utils';
2
2
  /**
3
3
  * Extends Express Request interface to add request ID tracking.
4
4
  * Added by requestId middleware during request processing.
@@ -8,6 +8,10 @@ declare global {
8
8
  interface Request {
9
9
  /** Unique request identifier (set by middleware) */
10
10
  id?: string;
11
+ /** Logger instance for the request (set by middleware) */
12
+ logger?: Logger;
13
+ /** User information (set by authentication middleware) */
14
+ user?: any;
11
15
  }
12
16
  }
13
17
  }
@@ -34,12 +38,6 @@ export declare let config: {
34
38
  */
35
39
  singleLine: boolean;
36
40
  };
37
- http: {
38
- /**
39
- * Timeout for HTTP requests in milliseconds
40
- */
41
- timeout: number;
42
- };
43
41
  cache: {
44
42
  /**
45
43
  * Default TTL (time to live) for cache entries in seconds
@@ -100,12 +98,6 @@ export declare const defaultServerConfig: {
100
98
  exposeHeader: true;
101
99
  generator: () => string;
102
100
  };
103
- logger: {
104
- name: string;
105
- level: LoggerLevels;
106
- prettyPrint: false;
107
- singleLine: false;
108
- };
109
101
  metrics: {
110
102
  enable: false;
111
103
  path: string;
@@ -47,12 +47,6 @@ export var config = {
47
47
  */
48
48
  singleLine: Env.getBoolean('LOGGER_PRETTY_SINGLE_LINE', false)
49
49
  },
50
- http: {
51
- /**
52
- * Timeout for HTTP requests in milliseconds
53
- */
54
- timeout: Env.getNumber('HTTP_TIMEOUT', 30000)
55
- },
56
50
  cache: {
57
51
  /**
58
52
  * Default TTL (time to live) for cache entries in seconds
@@ -111,12 +105,6 @@ export var defaultServerConfig = {
111
105
  exposeHeader: true,
112
106
  generator: function () { return uuid(); }
113
107
  },
114
- logger: {
115
- name: 'express_app',
116
- level: 'info',
117
- prettyPrint: false,
118
- singleLine: false
119
- },
120
108
  metrics: {
121
109
  enable: false,
122
110
  path: '/metrics',
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The MIT License\n *\n * Copyright (c) 2025 Catbee Technologies\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { ServerConfig } from './types/server';\nimport { Env } from './utils/env.utils';\nimport { uuid } from './utils/id.utils';\nimport { LoggerLevels } from './utils/logger.utils';\nimport { deepObjMerge } from './utils/obj.utils';\n\n/**\n * Extends Express Request interface to add request ID tracking.\n * Added by requestId middleware during request processing.\n */\ndeclare global {\n namespace Express {\n interface Request {\n /** Unique request identifier (set by middleware) */\n id?: string;\n }\n }\n}\n\n/**\n * Application runtime configuration loaded from environment variables.\n */\nexport let config = {\n logger: {\n /**\n * Logging level (e.g., 'info', 'debug', 'warn', 'error').\n */\n level: Env.get('LOGGER_LEVEL', 'info') as LoggerLevels,\n\n /**\n * Name of the logger instance (defaults to npm package name).\n */\n name: Env.get('LOGGER_NAME', Env.get('npm_package_name', '@catbee/utils')),\n\n /**\n * Enables pretty-print logging in development.\n * Has no effect in production.\n */\n pretty: Env.getBoolean('LOGGER_PRETTY', true),\n /**\n * Single line output for pretty-print (default: false)\n */\n singleLine: Env.getBoolean('LOGGER_PRETTY_SINGLE_LINE', false)\n },\n\n http: {\n /**\n * Timeout for HTTP requests in milliseconds\n */\n timeout: Env.getNumber('HTTP_TIMEOUT', 30000)\n },\n\n cache: {\n /**\n * Default TTL (time to live) for cache entries in seconds\n */\n defaultTtl: Env.getNumber('CACHE_DEFAULT_TTL_SECONDS', 3600) * 1000\n }\n};\n\nexport const defaultServerConfig = {\n port: 3000,\n host: '0.0.0.0',\n cors: false,\n helmet: false,\n compression: false,\n bodyParser: {\n json: { limit: '1mb' },\n urlencoded: { extended: true, limit: '1mb' }\n },\n cookieParser: false,\n isMicroservice: false,\n appName: 'express_app',\n globalHeaders: {},\n rateLimit: {\n enable: false,\n windowMs: 15 * 60 * 1000,\n max: 100,\n message: 'Too many requests',\n standardHeaders: true,\n legacyHeaders: false\n },\n requestLogging: {\n enable: Env.isDev(),\n ignorePaths: (req, _res) => {\n const skipPaths = ['/healthz', '/favicon.ico', '/metrics', '/docs', '/.well-known'];\n return skipPaths.some(path => req.path.startsWith(path));\n },\n skipNotFoundRoutes: false\n },\n openApi: {\n enable: false,\n mountPath: '/docs',\n verbose: false,\n withGlobalPrefix: false\n },\n healthCheck: {\n path: '/healthz',\n detailed: true\n },\n requestTimeout: 30000,\n responseTime: {\n enable: false,\n addHeader: true,\n logOnComplete: false\n },\n requestId: {\n headerName: 'x-request-id',\n exposeHeader: true,\n generator: () => uuid()\n },\n logger: {\n name: 'express_app',\n level: 'info' as LoggerLevels,\n prettyPrint: false,\n singleLine: false\n },\n metrics: {\n enable: false,\n path: '/metrics',\n withGlobalPrefix: false\n },\n serviceVersion: {\n enable: false,\n headerName: 'x-service-version',\n version: '0.0.0'\n }\n} satisfies ServerConfig;\n\n/**\n * Update the @catbee/utils configuration.\n * @param value Partial configuration object.\n */\nexport function setConfig(value: Partial<typeof config>): void {\n deepObjMerge(config, value);\n}\n\n/**\n * Get the current @catbee/utils configuration.\n * @returns The current configuration object.\n */\nexport function getConfig(): typeof config {\n return config;\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAGH,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAmBjD;;GAEG;AACH,MAAM,CAAC,IAAI,MAAM,GAAG;IAClB,MAAM,EAAE;QACN;;WAEG;QACH,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,MAAM,CAAiB;QAEtD;;WAEG;QACH,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,eAAe,CAAC,CAAC;QAE1E;;;WAGG;QACH,MAAM,EAAE,GAAG,CAAC,UAAU,CAAC,eAAe,EAAE,IAAI,CAAC;QAC7C;;WAEG;QACH,UAAU,EAAE,GAAG,CAAC,UAAU,CAAC,2BAA2B,EAAE,KAAK,CAAC;KAC/D;IAED,KAAK,EAAE;QACL;;WAEG;QACH,UAAU,EAAE,GAAG,CAAC,SAAS,CAAC,2BAA2B,EAAE,IAAI,CAAC,GAAG,IAAI;KACpE;CACF,CAAC;AAEF,MAAM,CAAC,IAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,KAAK;IACX,MAAM,EAAE,KAAK;IACb,WAAW,EAAE,KAAK;IAClB,UAAU,EAAE;QACV,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;QACtB,UAAU,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE;KAC7C;IACD,YAAY,EAAE,KAAK;IACnB,cAAc,EAAE,KAAK;IACrB,OAAO,EAAE,aAAa;IACtB,aAAa,EAAE,EAAE;IACjB,SAAS,EAAE;QACT,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI;QACxB,GAAG,EAAE,GAAG;QACR,OAAO,EAAE,mBAAmB;QAC5B,eAAe,EAAE,IAAI;QACrB,aAAa,EAAE,KAAK;KACrB;IACD,cAAc,EAAE;QACd,MAAM,EAAE,GAAG,CAAC,KAAK,EAAE;QACnB,WAAW,EAAE,UAAC,GAAG,EAAE,IAAI;YACrB,IAAM,SAAS,GAAG,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;YACpF,OAAO,SAAS,CAAC,IAAI,CAAC,UAAA,IAAI,IAAI,OAAA,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAzB,CAAyB,CAAC,CAAC;QAC3D,CAAC;QACD,kBAAkB,EAAE,KAAK;KAC1B;IACD,OAAO,EAAE;QACP,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,OAAO;QAClB,OAAO,EAAE,KAAK;QACd,gBAAgB,EAAE,KAAK;KACxB;IACD,WAAW,EAAE;QACX,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,IAAI;KACf;IACD,cAAc,EAAE,KAAK;IACrB,YAAY,EAAE;QACZ,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,KAAK;KACrB;IACD,SAAS,EAAE;QACT,UAAU,EAAE,cAAc;QAC1B,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,cAAM,OAAA,IAAI,EAAE,EAAN,CAAM;KACxB;IACD,OAAO,EAAE;QACP,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,UAAU;QAChB,gBAAgB,EAAE,KAAK;KACxB;IACD,cAAc,EAAE;QACd,MAAM,EAAE,KAAK;QACb,UAAU,EAAE,mBAAmB;QAC/B,OAAO,EAAE,OAAO;KACjB;CACqB,CAAC;AAEzB;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,KAA6B;IACrD,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["/*\n * The MIT License\n *\n * Copyright (c) 2025 Catbee Technologies\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { ServerConfig } from './types/server';\nimport { Env } from './utils/env.utils';\nimport { uuid } from './utils/id.utils';\nimport { Logger, LoggerLevels } from './utils/logger.utils';\nimport { deepObjMerge } from './utils/obj.utils';\n\n/**\n * Extends Express Request interface to add request ID tracking.\n * Added by requestId middleware during request processing.\n */\ndeclare global {\n namespace Express {\n interface Request {\n /** Unique request identifier (set by middleware) */\n id?: string;\n /** Logger instance for the request (set by middleware) */\n logger?: Logger;\n /** User information (set by authentication middleware) */\n user?: any;\n }\n }\n}\n\n/**\n * Application runtime configuration loaded from environment variables.\n */\nexport let config = {\n logger: {\n /**\n * Logging level (e.g., 'info', 'debug', 'warn', 'error').\n */\n level: Env.get('LOGGER_LEVEL', 'info') as LoggerLevels,\n\n /**\n * Name of the logger instance (defaults to npm package name).\n */\n name: Env.get('LOGGER_NAME', Env.get('npm_package_name', '@catbee/utils')),\n\n /**\n * Enables pretty-print logging in development.\n * Has no effect in production.\n */\n pretty: Env.getBoolean('LOGGER_PRETTY', true),\n /**\n * Single line output for pretty-print (default: false)\n */\n singleLine: Env.getBoolean('LOGGER_PRETTY_SINGLE_LINE', false)\n },\n\n cache: {\n /**\n * Default TTL (time to live) for cache entries in seconds\n */\n defaultTtl: Env.getNumber('CACHE_DEFAULT_TTL_SECONDS', 3600) * 1000\n }\n};\n\nexport const defaultServerConfig = {\n port: 3000,\n host: '0.0.0.0',\n cors: false,\n helmet: false,\n compression: false,\n bodyParser: {\n json: { limit: '1mb' },\n urlencoded: { extended: true, limit: '1mb' }\n },\n cookieParser: false,\n isMicroservice: false,\n appName: 'express_app',\n globalHeaders: {},\n rateLimit: {\n enable: false,\n windowMs: 15 * 60 * 1000,\n max: 100,\n message: 'Too many requests',\n standardHeaders: true,\n legacyHeaders: false\n },\n requestLogging: {\n enable: Env.isDev(),\n ignorePaths: (req, _res) => {\n const skipPaths = ['/healthz', '/favicon.ico', '/metrics', '/docs', '/.well-known'];\n return skipPaths.some(path => req.path.startsWith(path));\n },\n skipNotFoundRoutes: false\n },\n openApi: {\n enable: false,\n mountPath: '/docs',\n verbose: false,\n withGlobalPrefix: false\n },\n healthCheck: {\n path: '/healthz',\n detailed: true\n },\n requestTimeout: 30000,\n responseTime: {\n enable: false,\n addHeader: true,\n logOnComplete: false\n },\n requestId: {\n headerName: 'x-request-id',\n exposeHeader: true,\n generator: () => uuid()\n },\n metrics: {\n enable: false,\n path: '/metrics',\n withGlobalPrefix: false\n },\n serviceVersion: {\n enable: false,\n headerName: 'x-service-version',\n version: '0.0.0'\n }\n} satisfies ServerConfig;\n\n/**\n * Update the @catbee/utils configuration.\n * @param value Partial configuration object.\n */\nexport function setConfig(value: Partial<typeof config>): void {\n deepObjMerge(config, value);\n}\n\n/**\n * Get the current @catbee/utils configuration.\n * @returns The current configuration object.\n */\nexport function getConfig(): typeof config {\n return config;\n}\n"]}
@@ -408,23 +408,6 @@ export declare class ServerConfigBuilder {
408
408
  * ```
409
409
  */
410
410
  withCookies(opts: ServerConfig['cookieParser']): this;
411
- /**
412
- * Configures the logger used by the server.
413
- *
414
- * @param opts - Logger configuration options
415
- * @returns The builder instance for chaining
416
- * @default { name: 'express_app', level: 'info', prettyPrint: true in dev, singleLine: false }
417
- *
418
- * @example
419
- * ```typescript
420
- * builder.withLogger({
421
- * level: 'info',
422
- * prettyPrint: true,
423
- * singleLine: false
424
- * })
425
- * ```
426
- */
427
- withLogger(opts: Partial<NonNullable<ServerConfig['logger']>>): this;
428
411
  /**
429
412
  * Adds a static folder to serve files from.
430
413
  *
@@ -518,107 +501,7 @@ export declare class ServerConfigBuilder {
518
501
  * .build();
519
502
  * ```
520
503
  */
521
- build(): Readonly<{
522
- [BUILD_MARKER]: boolean;
523
- port: number;
524
- host?: string;
525
- cors?: import("..").ToggleConfig<import("cors").CorsOptions>;
526
- helmet?: import("..").ToggleConfig<import("helmet").HelmetOptions>;
527
- compression?: import("..").ToggleConfig<import("compression").CompressionOptions>;
528
- bodyParser?: {
529
- json? /**
530
- * Sets the hostname the server will bind to.
531
- *
532
- * @param host - The hostname (e.g., 'localhost', '0.0.0.0', '127.0.0.1')
533
- * @returns The builder instance for chaining
534
- * @default '0.0.0.0' (can be overridden via HOST env variable)
535
- *
536
- * @example
537
- * ```typescript
538
- * builder.withHost('0.0.0.0') // Listen on all interfaces
539
- * ```
540
- */: Parameters<typeof import("express").json>[0];
541
- urlencoded?: Parameters<typeof import("express").urlencoded>[0];
542
- };
543
- cookieParser?: import("..").ToggleConfig<import("cookie-parser").CookieParseOptions>;
544
- trustProxy?: boolean;
545
- staticFolders?: Array<{
546
- path?: string;
547
- directory: string;
548
- maxAge?: string;
549
- etag?: boolean;
550
- immutable?: boolean;
551
- lastModified?: boolean;
552
- cacheControl?: boolean;
553
- }>;
554
- isMicroservice?: boolean;
555
- appName?: string;
556
- globalHeaders?: Record<string, string | (() => string)>;
557
- rateLimit?: {
558
- enable: boolean;
559
- windowMs?: number;
560
- max?: number;
561
- message?: string;
562
- standardHeaders?: boolean;
563
- legacyHeaders?: boolean;
564
- };
565
- requestLogging?: {
566
- enable: boolean;
567
- ignorePaths?: string[] | ((req: import("express").Request, res: import("express").Response) => boolean);
568
- skipNotFoundRoutes?: boolean;
569
- };
570
- healthCheck?: {
571
- path?: string;
572
- checks?: Array<{
573
- name: string;
574
- check: () => Promise<boolean> | boolean;
575
- }>;
576
- detailed?: boolean;
577
- withGlobalPrefix?: boolean;
578
- };
579
- requestTimeout?: number;
580
- responseTime?: {
581
- enable: boolean;
582
- addHeader?: boolean;
583
- logOnComplete?: boolean;
584
- };
585
- requestId?: {
586
- headerName?: string;
587
- exposeHeader?: boolean;
588
- generator?: () => string;
589
- };
590
- globalPrefix?: string;
591
- openApi?: {
592
- enable: boolean;
593
- mountPath?: string;
594
- filePath?: string;
595
- verbose?: boolean;
596
- withGlobalPrefix?: boolean;
597
- };
598
- logger?: {
599
- name?: string;
600
- level?: import("..").LoggerLevels;
601
- prettyPrint?: boolean;
602
- singleLine?: boolean;
603
- };
604
- metrics?: {
605
- enable: boolean;
606
- path?: string;
607
- withGlobalPrefix?: boolean;
608
- };
609
- serviceVersion?: {
610
- enable: boolean;
611
- headerName?: string;
612
- version?: string | (() => string);
613
- };
614
- https?: {
615
- key: string;
616
- cert: string;
617
- ca?: string;
618
- passphrase?: string;
619
- [key: string]: any;
620
- };
621
- }>;
504
+ build(): Readonly<ServerConfig>;
622
505
  private mergeConfig;
623
506
  private setEnabled;
624
507
  }
@@ -563,26 +563,6 @@ var ServerConfigBuilder = /** @class */ (function () {
563
563
  this.config.cookieParser = opts;
564
564
  return this;
565
565
  };
566
- /**
567
- * Configures the logger used by the server.
568
- *
569
- * @param opts - Logger configuration options
570
- * @returns The builder instance for chaining
571
- * @default { name: 'express_app', level: 'info', prettyPrint: true in dev, singleLine: false }
572
- *
573
- * @example
574
- * ```typescript
575
- * builder.withLogger({
576
- * level: 'info',
577
- * prettyPrint: true,
578
- * singleLine: false
579
- * })
580
- * ```
581
- */
582
- ServerConfigBuilder.prototype.withLogger = function (opts) {
583
- this.mergeConfig('logger', opts);
584
- return this;
585
- };
586
566
  /**
587
567
  * Adds a static folder to serve files from.
588
568
  *
@@ -1 +1 @@
1
- {"version":3,"file":"server.builder.js","sourceRoot":"","sources":["../../../src/servers/server.builder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The MIT License\n *\n * Copyright (c) 2025 Catbee Technologies\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { deepObjMerge } from '../utils/obj.utils';\nimport { ServerConfig } from '../types/server';\nimport { defaultServerConfig } from '../config';\nimport { isPort } from '../utils/validate.utils';\n\n/**\n * Builder class for creating and configuring an Express server configuration.\n *\n * This class provides a fluent interface to configure all aspects of the Express server\n * including security settings, middleware, routing, and more.\n *\n * @example\n * ```typescript\n * const serverConfig = new ServerConfigBuilder()\n * .withPort(3000)\n * .withHost('localhost')\n * .enableCors()\n * .enableHelmet()\n * .build();\n * ```\n */\n\nexport const BUILD_MARKER = Symbol.for('catbee.express.server.build');\n\nexport class ServerConfigBuilder {\n private config: Partial<ServerConfig> = {};\n\n /**\n * Validates that a port number is valid and usable.\n *\n * @private\n * @param port - The port number to validate\n * @throws {Error} If port is not an integer or is outside the valid range (1-65535)\n */\n private validatePort(port: number): void {\n if (!isPort(port)) {\n throw new Error(`Port must be a valid number between 1 and 65535, got: ${port}`);\n }\n }\n\n /**\n * Sets the port the server will listen on.\n *\n * @param port - The port number (1-65535)\n * @returns The builder instance for chaining\n * @throws {Error} If port is invalid\n * @default 3000 (can be overridden via PORT env variable)\n *\n * @example\n * ```typescript\n * builder.withPort(3000)\n * ```\n */\n withPort(port: number): this {\n this.validatePort(port);\n this.config.port = port;\n return this;\n }\n\n /**\n * Sets the hostname the server will bind to.\n *\n * @param host - The hostname (e.g., 'localhost', '0.0.0.0', '127.0.0.1')\n * @returns The builder instance for chaining\n * @default '0.0.0.0' (can be overridden via HOST env variable)\n *\n * @example\n * ```typescript\n * builder.withHost('0.0.0.0') // Listen on all interfaces\n * ```\n */\n withHost(host: string): this {\n this.config.host = host;\n return this;\n }\n\n /**\n * Configures Cross-Origin Resource Sharing (CORS) for the server.\n *\n * @param opts - CORS options object or boolean (true to enable with defaults, false to disable)\n * @returns The builder instance for chaining\n * @default false (CORS is disabled by default)\n *\n * @example\n * ```typescript\n * // Enable CORS with default options\n * builder.withCors(true)\n *\n * // Configure CORS with specific options\n * builder.withCors({\n * origin: ['https://example.com'],\n * methods: ['GET', 'POST']\n * })\n * ```\n */\n withCors(opts: ServerConfig['cors']): this {\n this.config.cors = opts;\n return this;\n }\n\n /**\n * Enables CORS with default settings\n *\n * @returns The builder instance for chaining\n */\n enableCors(): this {\n return this.withCors(true);\n }\n\n /**\n * Disables CORS\n *\n * @returns The builder instance for chaining\n */\n disableCors(): this {\n return this.withCors(false);\n }\n\n /**\n * Configures the Helmet middleware for setting HTTP security headers.\n *\n * @param opts - Helmet options object or boolean (true to enable with defaults, false to disable)\n * @returns The builder instance for chaining\n * @default false (Helmet is disabled by default)\n *\n * @example\n * ```typescript\n * // Enable Helmet with default settings\n * builder.withHelmet(true)\n *\n * // Configure Helmet with specific options\n * builder.withHelmet({\n * contentSecurityPolicy: false,\n * xssFilter: true\n * })\n * ```\n */\n withHelmet(opts: ServerConfig['helmet']): this {\n this.config.helmet = opts;\n return this;\n }\n\n /**\n * Enables Helmet with default settings\n *\n * @returns The builder instance for chaining\n */\n enableHelmet(): this {\n return this.withHelmet(true);\n }\n\n /**\n * Disables Helmet\n *\n * @returns The builder instance for chaining\n */\n disableHelmet(): this {\n return this.withHelmet(false);\n }\n\n /**\n * Configures response compression middleware.\n *\n * @param opts - Compression options object or boolean (true to enable with defaults, false to disable)\n * @returns The builder instance for chaining\n * @default false (Compression is disabled by default)\n *\n * @example\n * ```typescript\n * // Enable compression with default settings\n * builder.withCompression(true)\n *\n * // Configure compression with specific options\n * builder.withCompression({\n * level: 6,\n * threshold: 1024\n * })\n * ```\n */\n withCompression(opts: ServerConfig['compression']): this {\n this.config.compression = opts;\n return this;\n }\n\n /**\n * Enables compression with default settings\n *\n * @returns The builder instance for chaining\n */\n enableCompression(): this {\n return this.withCompression(true);\n }\n\n /**\n * Disables compression\n *\n * @returns The builder instance for chaining\n */\n disableCompression(): this {\n return this.withCompression(false);\n }\n\n /**\n * Configures rate limiting to protect against brute-force attacks.\n *\n * @param opts - Rate limit configuration options\n * @returns The builder instance for chaining\n * @default { enable: false, windowMs: 15 * 60 * 1000, max: 100, message: 'Too many requests', standardHeaders: true, legacyHeaders: false }\n *\n * @example\n * ```typescript\n * builder.withRateLimit({\n * enable: true,\n * windowMs: 15 * 60 * 1000, // 15 minutes\n * max: 100 // limit each IP to 100 requests per windowMs\n * })\n * ```\n */\n withRateLimit(opts: Partial<ServerConfig['rateLimit']>): this {\n this.mergeConfig('rateLimit', opts as NonNullable<ServerConfig['rateLimit']>);\n return this;\n }\n\n /**\n * Enables rate limiting with default or custom settings\n *\n * @param opts - Optional rate limit configuration (max requests, window, etc.)\n * @returns The builder instance for chaining\n */\n enableRateLimit(opts: Omit<Partial<NonNullable<ServerConfig['rateLimit']>>, 'enable'> = {}): this {\n return this.setEnabled('rateLimit', true, opts);\n }\n\n /**\n * Disables rate limiting\n *\n * @returns The builder instance for chaining\n */\n disableRateLimit(): this {\n return this.setEnabled('rateLimit', false);\n }\n\n /**\n * Configures HTTP request logging middleware.\n *\n * @param opts - Request logging configuration options\n * @returns The builder instance for chaining\n * @default { enable: true in dev/false in prod, ignorePaths: ['/healthz', '/favicon.ico', '/metrics', '/docs', '/.well-known'], skipNotFoundRoutes: false }\n *\n * @example\n * ```typescript\n * builder.withRequestLogging({\n * enable: true,\n * ignorePaths: ['/health', '/metrics'],\n * skipNotFoundRoutes: true\n * })\n * ```\n */\n withRequestLogging(opts: Partial<NonNullable<ServerConfig['requestLogging']>>): this {\n this.mergeConfig('requestLogging', opts as NonNullable<ServerConfig['requestLogging']>);\n return this;\n }\n\n /**\n * Enables request logging with default or custom settings\n *\n * @param opts - Optional request logging configuration\n * @returns The builder instance for chaining\n */\n enableRequestLogging(opts: Omit<Partial<NonNullable<ServerConfig['requestLogging']>>, 'enable'> = {}): this {\n return this.setEnabled('requestLogging', true, opts);\n }\n\n /**\n * Disables request logging\n *\n * @returns The builder instance for chaining\n */\n disableRequestLogging(): this {\n return this.setEnabled('requestLogging', false);\n }\n\n /**\n * Configures server metrics collection and endpoints.\n *\n * @param opts - Metrics configuration options\n * @returns The builder instance for chaining\n * @default { enable: false, path: '/metrics', withGlobalPrefix: false }\n *\n * @example\n * ```typescript\n * builder.withMetrics({\n * enable: true,\n * path: '/metrics'\n * })\n * ```\n */\n withMetrics(opts: Partial<NonNullable<ServerConfig['metrics']>>): this {\n this.mergeConfig('metrics', opts as NonNullable<ServerConfig['metrics']>);\n return this;\n }\n\n /**\n * Enables Prometheus metrics collection and endpoint\n *\n * @param opts - Optional metrics configuration\n * @returns The builder instance for chaining\n */\n enableMetrics(opts: Omit<Partial<NonNullable<ServerConfig['metrics']>>, 'enable'> = {}): this {\n return this.setEnabled('metrics', true, opts);\n }\n\n /**\n * Disables Prometheus metrics\n *\n * @returns The builder instance for chaining\n */\n disableMetrics(): this {\n return this.setEnabled('metrics', false);\n }\n\n /**\n * Configures server health check endpoint.\n *\n * @param opts - Health check configuration options\n * @returns The builder instance for chaining\n * @default { path: '/healthz', detailed: true, withGlobalPrefix: false }\n *\n * @example\n * ```typescript\n * builder.withHealthCheck({\n * path: '/health',\n * detailed: true\n * })\n * ```\n */\n withHealthCheck(opts: Partial<NonNullable<ServerConfig['healthCheck']>>): this {\n this.mergeConfig('healthCheck', opts as NonNullable<ServerConfig['healthCheck']>);\n return this;\n }\n\n /**\n * Configures OpenAPI/Swagger documentation for the API.\n *\n * @param opts - OpenAPI configuration options\n * @returns The builder instance for chaining\n * @default { enable: false, mountPath: '/docs', verbose: false, withGlobalPrefix: false }\n *\n * @example\n * ```typescript\n * builder.withOpenApi({\n * enable: true,\n * path: '/api-docs',\n * filePath: './openapi.yaml'\n * })\n * ```\n */\n withOpenApi(opts: Partial<NonNullable<ServerConfig['openApi']>>): this {\n this.mergeConfig('openApi', opts as NonNullable<ServerConfig['openApi']>);\n return this;\n }\n\n /**\n * Enables OpenAPI documentation with required file path\n *\n * @param filePath - Path to OpenAPI specification file (required)\n * @param opts - Optional OpenAPI configuration\n * @returns The builder instance for chaining\n */\n enableOpenApi(\n filePath: string,\n opts: Omit<Partial<NonNullable<ServerConfig['openApi']>>, 'enable' | 'filePath'> = {}\n ): this {\n this.setEnabled('openApi', true, { filePath, ...opts });\n return this;\n }\n\n /**\n * Disables OpenAPI documentation\n *\n * @returns The builder instance for chaining\n */\n disableOpenApi(): this {\n return this.setEnabled('openApi', false);\n }\n\n /**\n * Configures the server as a microservice with versioning.\n *\n * @param opts - Microservice configuration options including app name and service version\n * @returns The builder instance for chaining\n * @default { isMicroservice: false, appName: 'express_app' }\n *\n * @example\n * ```typescript\n * builder.withMicroService({\n * appName: 'user-service',\n * serviceVersion: {\n * enable: true,\n * version: '1.2.3'\n * }\n * })\n * ```\n */\n withMicroService(opts: {\n appName: NonNullable<ServerConfig['appName']>;\n serviceVersion: Partial<NonNullable<ServerConfig['serviceVersion']>>;\n }): this {\n this.config.isMicroservice = true;\n this.config.appName = opts.appName;\n\n this.mergeConfig('serviceVersion', opts.serviceVersion as NonNullable<ServerConfig['serviceVersion']>);\n return this;\n }\n\n /**\n * Configures the trust proxy settings to determine if X-Forwarded-* headers should be trusted.\n *\n * @param opts - Trust proxy configuration options\n * @returns The builder instance for chaining\n * @default false\n *\n * @example\n * ```typescript\n * // Trust proxy headers (useful when behind a load balancer)\n * builder.withTrustProxy(true)\n * ```\n */\n withTrustProxy(opts: NonNullable<ServerConfig['trustProxy']>): this {\n this.config.trustProxy = opts;\n return this;\n }\n\n /**\n * Configures the request ID middleware for tracing requests across services.\n *\n * @param opts - Request ID configuration options\n * @returns The builder instance for chaining\n * @default { headerName: 'x-request-id', exposeHeader: true }\n *\n * @example\n * ```typescript\n * builder.withRequestId({\n * headerName: 'X-Request-Id',\n * generator: () => crypto.randomUUID()\n * })\n * ```\n */\n withRequestId(opts: Partial<NonNullable<ServerConfig['requestId']>>): this {\n this.mergeConfig('requestId', opts as NonNullable<ServerConfig['requestId']>);\n return this;\n }\n\n /**\n * Configures the response time middleware for measuring request processing times.\n *\n * @param opts - Response time configuration options\n * @returns The builder instance for chaining\n * @default { enable: false, addHeader: true, logOnComplete: false }\n *\n * @example\n * ```typescript\n * builder.withResponseTime({\n * enable: true,\n * addHeader: true,\n * logOnComplete: true\n * })\n * ```\n */\n withResponseTime(opts: Partial<NonNullable<ServerConfig['responseTime']>>): this {\n this.mergeConfig('responseTime', opts as NonNullable<ServerConfig['responseTime']>);\n return this;\n }\n\n /**\n * Enables response time tracking with default or custom settings\n *\n * @param opts - Optional response time configuration\n * @returns The builder instance for chaining\n */\n enableResponseTime(opts: Omit<Partial<NonNullable<ServerConfig['responseTime']>>, 'enable'> = {}): this {\n this.setEnabled('responseTime', true, opts);\n return this;\n }\n\n /**\n * Disables response time tracking\n *\n * @returns The builder instance for chaining\n */\n disableResponseTime(): this {\n return this.setEnabled('responseTime', false);\n }\n\n /**\n * Configures the body parser middleware options for parsing request bodies.\n *\n * @param opts - Body parser configuration options\n * @returns The builder instance for chaining\n * @default { json: { limit: '1mb' }, urlencoded: { extended: true, limit: '1mb' } }\n *\n * @example\n * ```typescript\n * builder.withBodyParser({\n * json: {\n * limit: '1mb'\n * },\n * urlencoded: {\n * extended: true,\n * limit: '1mb'\n * }\n * })\n * ```\n */\n withBodyParser(opts: NonNullable<ServerConfig['bodyParser']>): this {\n this.config.bodyParser = deepObjMerge({}, this.config.bodyParser ?? {}, opts);\n return this;\n }\n\n /**\n * Configures cookie parsing middleware.\n *\n * @param opts - Cookie parser options or boolean (true to enable with defaults, false to disable)\n * @returns The builder instance for chaining\n * @default false\n *\n * @example\n * ```typescript\n * // Enable cookie parsing with default options\n * builder.withCookies(true)\n *\n * // Enable cookie parsing with specific options\n * builder.withCookies({\n * secret: 'your-secret-key',\n * secure: true\n * })\n * ```\n */\n withCookies(opts: ServerConfig['cookieParser']): this {\n this.config.cookieParser = opts;\n return this;\n }\n\n /**\n * Configures the logger used by the server.\n *\n * @param opts - Logger configuration options\n * @returns The builder instance for chaining\n * @default { name: 'express_app', level: 'info', prettyPrint: true in dev, singleLine: false }\n *\n * @example\n * ```typescript\n * builder.withLogger({\n * level: 'info',\n * prettyPrint: true,\n * singleLine: false\n * })\n * ```\n */\n withLogger(opts: Partial<NonNullable<ServerConfig['logger']>>): this {\n this.mergeConfig('logger', opts as NonNullable<ServerConfig['logger']>);\n return this;\n }\n\n /**\n * Adds a static folder to serve files from.\n *\n * @param folder - Static folder configuration\n * @returns The builder instance for chaining\n *\n * @example\n * ```typescript\n * builder.withStaticFolder({\n * path: '/assets',\n * directory: './public',\n * options: { maxAge: '1d' }\n * })\n * ```\n */\n withStaticFolder(folder: NonNullable<ServerConfig['staticFolders']>[number]): this {\n if (!folder.path) throw new Error('Static folder requires a path');\n const folders = [...(this.config.staticFolders ?? []), folder];\n this.config.staticFolders = Array.from(new Map(folders.map(f => [f.path, f])).values());\n return this;\n }\n\n /**\n * Sets global headers to be included in all responses.\n *\n * @param headers - Object containing header name/value pairs or functions that return values\n * @returns The builder instance for chaining\n * @default {}\n *\n * @example\n * ```typescript\n * builder.withGlobalHeaders({\n * 'X-Powered-By': 'Catbee',\n * 'Server-Time': () => new Date().toISOString()\n * })\n * ```\n */\n withGlobalHeaders(headers: NonNullable<ServerConfig['globalHeaders']>): this {\n this.mergeConfig('globalHeaders', headers);\n return this;\n }\n\n /**\n * Sets a global prefix for all routes.\n *\n * @param prefix - The prefix to prepend to all routes (e.g., '/api/v1')\n * @returns The builder instance for chaining\n * @default '/'\n *\n * @example\n * ```typescript\n * builder.withGlobalPrefix('/api/v1')\n * ```\n */\n withGlobalPrefix(prefix: string): this {\n this.config.globalPrefix = prefix;\n return this;\n }\n\n /**\n * Applies custom configuration overrides directly.\n *\n * @param overrides - Custom configuration options to merge\n * @returns The builder instance for chaining\n *\n * @example\n * ```typescript\n * builder.withCustom({\n * port: 8080,\n * customMiddleware: myMiddlewareFunction\n * })\n * ```\n */\n withCustom(overrides: Partial<ServerConfig>): this {\n this.config = deepObjMerge({}, this.config, overrides);\n return this;\n }\n\n /**\n * Configures HTTPS server options.\n *\n * @param opts - HTTPS configuration (key, cert, ca, passphrase, etc.)\n * @returns The builder instance for chaining\n *\n * @example\n * ```typescript\n * builder.withHttps({\n * key: './localhost-key.pem',\n * cert: './localhost-cert.pem'\n * })\n * ```\n */\n withHttps(opts: NonNullable<ServerConfig['https']>): this {\n this.config.https = opts;\n return this;\n }\n\n /**\n * Builds and returns the final server configuration.\n *\n * This method merges the user-specified configuration with default values,\n * ensures all sections with 'enable' flags are properly structured, and\n * produces the final configuration to be used by the server.\n *\n * @returns The complete ServerConfig object\n *\n * @example\n * ```typescript\n * const config = new ServerConfigBuilder()\n * .withPort(3000)\n * .withHost('localhost')\n * .withCors(true)\n * .build();\n * ```\n */\n build() {\n const config = deepObjMerge({}, defaultServerConfig, this.config) as ServerConfig;\n\n // Common validation\n if (config.openApi?.enable && !config.openApi.filePath) {\n throw new Error('OpenAPI is enabled but no filePath is specified');\n }\n\n return Object.freeze({\n ...config,\n [BUILD_MARKER]: true\n });\n }\n\n private mergeConfig<K extends keyof ServerConfig>(key: K, value: Partial<NonNullable<ServerConfig[K]>>): void {\n const current =\n typeof this.config[key] === 'object' && this.config[key] !== null\n ? (this.config[key] as NonNullable<ServerConfig[K]>)\n : {};\n this.config[key] = deepObjMerge({}, current, value) as NonNullable<ServerConfig[K]>;\n }\n\n private setEnabled<K extends keyof ServerConfig>(\n key: K,\n enable: boolean,\n overrides: Partial<NonNullable<ServerConfig[K]>> = {}\n ): this {\n this.mergeConfig(key, { ...overrides, enable });\n return this;\n }\n}\n"]}
1
+ {"version":3,"file":"server.builder.js","sourceRoot":"","sources":["../../../src/servers/server.builder.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * The MIT License\n *\n * Copyright (c) 2025 Catbee Technologies\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nimport { deepObjMerge } from '../utils/obj.utils';\nimport { ServerConfig } from '../types/server';\nimport { defaultServerConfig } from '../config';\nimport { isPort } from '../utils/validate.utils';\n\n/**\n * Builder class for creating and configuring an Express server configuration.\n *\n * This class provides a fluent interface to configure all aspects of the Express server\n * including security settings, middleware, routing, and more.\n *\n * @example\n * ```typescript\n * const serverConfig = new ServerConfigBuilder()\n * .withPort(3000)\n * .withHost('localhost')\n * .enableCors()\n * .enableHelmet()\n * .build();\n * ```\n */\n\nexport const BUILD_MARKER = Symbol.for('catbee.express.server.build');\n\nexport class ServerConfigBuilder {\n private config: Partial<ServerConfig> = {};\n\n /**\n * Validates that a port number is valid and usable.\n *\n * @private\n * @param port - The port number to validate\n * @throws {Error} If port is not an integer or is outside the valid range (1-65535)\n */\n private validatePort(port: number): void {\n if (!isPort(port)) {\n throw new Error(`Port must be a valid number between 1 and 65535, got: ${port}`);\n }\n }\n\n /**\n * Sets the port the server will listen on.\n *\n * @param port - The port number (1-65535)\n * @returns The builder instance for chaining\n * @throws {Error} If port is invalid\n * @default 3000 (can be overridden via PORT env variable)\n *\n * @example\n * ```typescript\n * builder.withPort(3000)\n * ```\n */\n withPort(port: number): this {\n this.validatePort(port);\n this.config.port = port;\n return this;\n }\n\n /**\n * Sets the hostname the server will bind to.\n *\n * @param host - The hostname (e.g., 'localhost', '0.0.0.0', '127.0.0.1')\n * @returns The builder instance for chaining\n * @default '0.0.0.0' (can be overridden via HOST env variable)\n *\n * @example\n * ```typescript\n * builder.withHost('0.0.0.0') // Listen on all interfaces\n * ```\n */\n withHost(host: string): this {\n this.config.host = host;\n return this;\n }\n\n /**\n * Configures Cross-Origin Resource Sharing (CORS) for the server.\n *\n * @param opts - CORS options object or boolean (true to enable with defaults, false to disable)\n * @returns The builder instance for chaining\n * @default false (CORS is disabled by default)\n *\n * @example\n * ```typescript\n * // Enable CORS with default options\n * builder.withCors(true)\n *\n * // Configure CORS with specific options\n * builder.withCors({\n * origin: ['https://example.com'],\n * methods: ['GET', 'POST']\n * })\n * ```\n */\n withCors(opts: ServerConfig['cors']): this {\n this.config.cors = opts;\n return this;\n }\n\n /**\n * Enables CORS with default settings\n *\n * @returns The builder instance for chaining\n */\n enableCors(): this {\n return this.withCors(true);\n }\n\n /**\n * Disables CORS\n *\n * @returns The builder instance for chaining\n */\n disableCors(): this {\n return this.withCors(false);\n }\n\n /**\n * Configures the Helmet middleware for setting HTTP security headers.\n *\n * @param opts - Helmet options object or boolean (true to enable with defaults, false to disable)\n * @returns The builder instance for chaining\n * @default false (Helmet is disabled by default)\n *\n * @example\n * ```typescript\n * // Enable Helmet with default settings\n * builder.withHelmet(true)\n *\n * // Configure Helmet with specific options\n * builder.withHelmet({\n * contentSecurityPolicy: false,\n * xssFilter: true\n * })\n * ```\n */\n withHelmet(opts: ServerConfig['helmet']): this {\n this.config.helmet = opts;\n return this;\n }\n\n /**\n * Enables Helmet with default settings\n *\n * @returns The builder instance for chaining\n */\n enableHelmet(): this {\n return this.withHelmet(true);\n }\n\n /**\n * Disables Helmet\n *\n * @returns The builder instance for chaining\n */\n disableHelmet(): this {\n return this.withHelmet(false);\n }\n\n /**\n * Configures response compression middleware.\n *\n * @param opts - Compression options object or boolean (true to enable with defaults, false to disable)\n * @returns The builder instance for chaining\n * @default false (Compression is disabled by default)\n *\n * @example\n * ```typescript\n * // Enable compression with default settings\n * builder.withCompression(true)\n *\n * // Configure compression with specific options\n * builder.withCompression({\n * level: 6,\n * threshold: 1024\n * })\n * ```\n */\n withCompression(opts: ServerConfig['compression']): this {\n this.config.compression = opts;\n return this;\n }\n\n /**\n * Enables compression with default settings\n *\n * @returns The builder instance for chaining\n */\n enableCompression(): this {\n return this.withCompression(true);\n }\n\n /**\n * Disables compression\n *\n * @returns The builder instance for chaining\n */\n disableCompression(): this {\n return this.withCompression(false);\n }\n\n /**\n * Configures rate limiting to protect against brute-force attacks.\n *\n * @param opts - Rate limit configuration options\n * @returns The builder instance for chaining\n * @default { enable: false, windowMs: 15 * 60 * 1000, max: 100, message: 'Too many requests', standardHeaders: true, legacyHeaders: false }\n *\n * @example\n * ```typescript\n * builder.withRateLimit({\n * enable: true,\n * windowMs: 15 * 60 * 1000, // 15 minutes\n * max: 100 // limit each IP to 100 requests per windowMs\n * })\n * ```\n */\n withRateLimit(opts: Partial<ServerConfig['rateLimit']>): this {\n this.mergeConfig('rateLimit', opts as NonNullable<ServerConfig['rateLimit']>);\n return this;\n }\n\n /**\n * Enables rate limiting with default or custom settings\n *\n * @param opts - Optional rate limit configuration (max requests, window, etc.)\n * @returns The builder instance for chaining\n */\n enableRateLimit(opts: Omit<Partial<NonNullable<ServerConfig['rateLimit']>>, 'enable'> = {}): this {\n return this.setEnabled('rateLimit', true, opts);\n }\n\n /**\n * Disables rate limiting\n *\n * @returns The builder instance for chaining\n */\n disableRateLimit(): this {\n return this.setEnabled('rateLimit', false);\n }\n\n /**\n * Configures HTTP request logging middleware.\n *\n * @param opts - Request logging configuration options\n * @returns The builder instance for chaining\n * @default { enable: true in dev/false in prod, ignorePaths: ['/healthz', '/favicon.ico', '/metrics', '/docs', '/.well-known'], skipNotFoundRoutes: false }\n *\n * @example\n * ```typescript\n * builder.withRequestLogging({\n * enable: true,\n * ignorePaths: ['/health', '/metrics'],\n * skipNotFoundRoutes: true\n * })\n * ```\n */\n withRequestLogging(opts: Partial<NonNullable<ServerConfig['requestLogging']>>): this {\n this.mergeConfig('requestLogging', opts as NonNullable<ServerConfig['requestLogging']>);\n return this;\n }\n\n /**\n * Enables request logging with default or custom settings\n *\n * @param opts - Optional request logging configuration\n * @returns The builder instance for chaining\n */\n enableRequestLogging(opts: Omit<Partial<NonNullable<ServerConfig['requestLogging']>>, 'enable'> = {}): this {\n return this.setEnabled('requestLogging', true, opts);\n }\n\n /**\n * Disables request logging\n *\n * @returns The builder instance for chaining\n */\n disableRequestLogging(): this {\n return this.setEnabled('requestLogging', false);\n }\n\n /**\n * Configures server metrics collection and endpoints.\n *\n * @param opts - Metrics configuration options\n * @returns The builder instance for chaining\n * @default { enable: false, path: '/metrics', withGlobalPrefix: false }\n *\n * @example\n * ```typescript\n * builder.withMetrics({\n * enable: true,\n * path: '/metrics'\n * })\n * ```\n */\n withMetrics(opts: Partial<NonNullable<ServerConfig['metrics']>>): this {\n this.mergeConfig('metrics', opts as NonNullable<ServerConfig['metrics']>);\n return this;\n }\n\n /**\n * Enables Prometheus metrics collection and endpoint\n *\n * @param opts - Optional metrics configuration\n * @returns The builder instance for chaining\n */\n enableMetrics(opts: Omit<Partial<NonNullable<ServerConfig['metrics']>>, 'enable'> = {}): this {\n return this.setEnabled('metrics', true, opts);\n }\n\n /**\n * Disables Prometheus metrics\n *\n * @returns The builder instance for chaining\n */\n disableMetrics(): this {\n return this.setEnabled('metrics', false);\n }\n\n /**\n * Configures server health check endpoint.\n *\n * @param opts - Health check configuration options\n * @returns The builder instance for chaining\n * @default { path: '/healthz', detailed: true, withGlobalPrefix: false }\n *\n * @example\n * ```typescript\n * builder.withHealthCheck({\n * path: '/health',\n * detailed: true\n * })\n * ```\n */\n withHealthCheck(opts: Partial<NonNullable<ServerConfig['healthCheck']>>): this {\n this.mergeConfig('healthCheck', opts as NonNullable<ServerConfig['healthCheck']>);\n return this;\n }\n\n /**\n * Configures OpenAPI/Swagger documentation for the API.\n *\n * @param opts - OpenAPI configuration options\n * @returns The builder instance for chaining\n * @default { enable: false, mountPath: '/docs', verbose: false, withGlobalPrefix: false }\n *\n * @example\n * ```typescript\n * builder.withOpenApi({\n * enable: true,\n * path: '/api-docs',\n * filePath: './openapi.yaml'\n * })\n * ```\n */\n withOpenApi(opts: Partial<NonNullable<ServerConfig['openApi']>>): this {\n this.mergeConfig('openApi', opts as NonNullable<ServerConfig['openApi']>);\n return this;\n }\n\n /**\n * Enables OpenAPI documentation with required file path\n *\n * @param filePath - Path to OpenAPI specification file (required)\n * @param opts - Optional OpenAPI configuration\n * @returns The builder instance for chaining\n */\n enableOpenApi(\n filePath: string,\n opts: Omit<Partial<NonNullable<ServerConfig['openApi']>>, 'enable' | 'filePath'> = {}\n ): this {\n this.setEnabled('openApi', true, { filePath, ...opts });\n return this;\n }\n\n /**\n * Disables OpenAPI documentation\n *\n * @returns The builder instance for chaining\n */\n disableOpenApi(): this {\n return this.setEnabled('openApi', false);\n }\n\n /**\n * Configures the server as a microservice with versioning.\n *\n * @param opts - Microservice configuration options including app name and service version\n * @returns The builder instance for chaining\n * @default { isMicroservice: false, appName: 'express_app' }\n *\n * @example\n * ```typescript\n * builder.withMicroService({\n * appName: 'user-service',\n * serviceVersion: {\n * enable: true,\n * version: '1.2.3'\n * }\n * })\n * ```\n */\n withMicroService(opts: {\n appName: NonNullable<ServerConfig['appName']>;\n serviceVersion: Partial<NonNullable<ServerConfig['serviceVersion']>>;\n }): this {\n this.config.isMicroservice = true;\n this.config.appName = opts.appName;\n\n this.mergeConfig('serviceVersion', opts.serviceVersion as NonNullable<ServerConfig['serviceVersion']>);\n return this;\n }\n\n /**\n * Configures the trust proxy settings to determine if X-Forwarded-* headers should be trusted.\n *\n * @param opts - Trust proxy configuration options\n * @returns The builder instance for chaining\n * @default false\n *\n * @example\n * ```typescript\n * // Trust proxy headers (useful when behind a load balancer)\n * builder.withTrustProxy(true)\n * ```\n */\n withTrustProxy(opts: NonNullable<ServerConfig['trustProxy']>): this {\n this.config.trustProxy = opts;\n return this;\n }\n\n /**\n * Configures the request ID middleware for tracing requests across services.\n *\n * @param opts - Request ID configuration options\n * @returns The builder instance for chaining\n * @default { headerName: 'x-request-id', exposeHeader: true }\n *\n * @example\n * ```typescript\n * builder.withRequestId({\n * headerName: 'X-Request-Id',\n * generator: () => crypto.randomUUID()\n * })\n * ```\n */\n withRequestId(opts: Partial<NonNullable<ServerConfig['requestId']>>): this {\n this.mergeConfig('requestId', opts as NonNullable<ServerConfig['requestId']>);\n return this;\n }\n\n /**\n * Configures the response time middleware for measuring request processing times.\n *\n * @param opts - Response time configuration options\n * @returns The builder instance for chaining\n * @default { enable: false, addHeader: true, logOnComplete: false }\n *\n * @example\n * ```typescript\n * builder.withResponseTime({\n * enable: true,\n * addHeader: true,\n * logOnComplete: true\n * })\n * ```\n */\n withResponseTime(opts: Partial<NonNullable<ServerConfig['responseTime']>>): this {\n this.mergeConfig('responseTime', opts as NonNullable<ServerConfig['responseTime']>);\n return this;\n }\n\n /**\n * Enables response time tracking with default or custom settings\n *\n * @param opts - Optional response time configuration\n * @returns The builder instance for chaining\n */\n enableResponseTime(opts: Omit<Partial<NonNullable<ServerConfig['responseTime']>>, 'enable'> = {}): this {\n this.setEnabled('responseTime', true, opts);\n return this;\n }\n\n /**\n * Disables response time tracking\n *\n * @returns The builder instance for chaining\n */\n disableResponseTime(): this {\n return this.setEnabled('responseTime', false);\n }\n\n /**\n * Configures the body parser middleware options for parsing request bodies.\n *\n * @param opts - Body parser configuration options\n * @returns The builder instance for chaining\n * @default { json: { limit: '1mb' }, urlencoded: { extended: true, limit: '1mb' } }\n *\n * @example\n * ```typescript\n * builder.withBodyParser({\n * json: {\n * limit: '1mb'\n * },\n * urlencoded: {\n * extended: true,\n * limit: '1mb'\n * }\n * })\n * ```\n */\n withBodyParser(opts: NonNullable<ServerConfig['bodyParser']>): this {\n this.config.bodyParser = deepObjMerge({}, this.config.bodyParser ?? {}, opts);\n return this;\n }\n\n /**\n * Configures cookie parsing middleware.\n *\n * @param opts - Cookie parser options or boolean (true to enable with defaults, false to disable)\n * @returns The builder instance for chaining\n * @default false\n *\n * @example\n * ```typescript\n * // Enable cookie parsing with default options\n * builder.withCookies(true)\n *\n * // Enable cookie parsing with specific options\n * builder.withCookies({\n * secret: 'your-secret-key',\n * secure: true\n * })\n * ```\n */\n withCookies(opts: ServerConfig['cookieParser']): this {\n this.config.cookieParser = opts;\n return this;\n }\n\n /**\n * Adds a static folder to serve files from.\n *\n * @param folder - Static folder configuration\n * @returns The builder instance for chaining\n *\n * @example\n * ```typescript\n * builder.withStaticFolder({\n * path: '/assets',\n * directory: './public',\n * options: { maxAge: '1d' }\n * })\n * ```\n */\n withStaticFolder(folder: NonNullable<ServerConfig['staticFolders']>[number]): this {\n if (!folder.path) throw new Error('Static folder requires a path');\n const folders = [...(this.config.staticFolders ?? []), folder];\n this.config.staticFolders = Array.from(new Map(folders.map(f => [f.path, f])).values());\n return this;\n }\n\n /**\n * Sets global headers to be included in all responses.\n *\n * @param headers - Object containing header name/value pairs or functions that return values\n * @returns The builder instance for chaining\n * @default {}\n *\n * @example\n * ```typescript\n * builder.withGlobalHeaders({\n * 'X-Powered-By': 'Catbee',\n * 'Server-Time': () => new Date().toISOString()\n * })\n * ```\n */\n withGlobalHeaders(headers: NonNullable<ServerConfig['globalHeaders']>): this {\n this.mergeConfig('globalHeaders', headers);\n return this;\n }\n\n /**\n * Sets a global prefix for all routes.\n *\n * @param prefix - The prefix to prepend to all routes (e.g., '/api/v1')\n * @returns The builder instance for chaining\n * @default '/'\n *\n * @example\n * ```typescript\n * builder.withGlobalPrefix('/api/v1')\n * ```\n */\n withGlobalPrefix(prefix: string): this {\n this.config.globalPrefix = prefix;\n return this;\n }\n\n /**\n * Applies custom configuration overrides directly.\n *\n * @param overrides - Custom configuration options to merge\n * @returns The builder instance for chaining\n *\n * @example\n * ```typescript\n * builder.withCustom({\n * port: 8080,\n * customMiddleware: myMiddlewareFunction\n * })\n * ```\n */\n withCustom(overrides: Partial<ServerConfig>): this {\n this.config = deepObjMerge({}, this.config, overrides);\n return this;\n }\n\n /**\n * Configures HTTPS server options.\n *\n * @param opts - HTTPS configuration (key, cert, ca, passphrase, etc.)\n * @returns The builder instance for chaining\n *\n * @example\n * ```typescript\n * builder.withHttps({\n * key: './localhost-key.pem',\n * cert: './localhost-cert.pem'\n * })\n * ```\n */\n withHttps(opts: NonNullable<ServerConfig['https']>): this {\n this.config.https = opts;\n return this;\n }\n\n /**\n * Builds and returns the final server configuration.\n *\n * This method merges the user-specified configuration with default values,\n * ensures all sections with 'enable' flags are properly structured, and\n * produces the final configuration to be used by the server.\n *\n * @returns The complete ServerConfig object\n *\n * @example\n * ```typescript\n * const config = new ServerConfigBuilder()\n * .withPort(3000)\n * .withHost('localhost')\n * .withCors(true)\n * .build();\n * ```\n */\n build(): Readonly<ServerConfig> {\n const config = deepObjMerge({}, defaultServerConfig, this.config) as ServerConfig;\n\n // Common validation\n if (config.openApi?.enable && !config.openApi.filePath) {\n throw new Error('OpenAPI is enabled but no filePath is specified');\n }\n\n return Object.freeze({\n ...config,\n [BUILD_MARKER]: true\n });\n }\n\n private mergeConfig<K extends keyof ServerConfig>(key: K, value: Partial<NonNullable<ServerConfig[K]>>): void {\n const current =\n typeof this.config[key] === 'object' && this.config[key] !== null\n ? (this.config[key] as NonNullable<ServerConfig[K]>)\n : {};\n this.config[key] = deepObjMerge({}, current, value) as NonNullable<ServerConfig[K]>;\n }\n\n private setEnabled<K extends keyof ServerConfig>(\n key: K,\n enable: boolean,\n overrides: Partial<NonNullable<ServerConfig[K]>> = {}\n ): this {\n this.mergeConfig(key, { ...overrides, enable });\n return this;\n }\n}\n"]}
@@ -183,12 +183,12 @@ export declare class ExpressServer {
183
183
  *
184
184
  * @param signals Array of process signals to listen for (default: SIGINT, SIGTERM)
185
185
  */
186
- enableGracefulShutdown(signals?: NodeJS.Signals[]): void;
186
+ enableGracefulShutdown(signals?: NodeJS.Signals[]): this;
187
187
  /**
188
188
  * Set an externally created base router.
189
189
  * This will override the internal rootRouter.
190
190
  */
191
- setBaseRouter(router: Router): void;
191
+ setBaseRouter(router: Router): this;
192
192
  /**
193
193
  * Create and register a new router (only used if not injecting one externally - use `setBaseRouter` instead).
194
194
  */
@@ -110,7 +110,7 @@ import client, { Counter, Histogram } from 'prom-client';
110
110
  import { NotFoundException } from '../utils/exception.utils';
111
111
  import fs from 'fs';
112
112
  import { apiReference } from '@scalar/express-api-reference';
113
- import { defaultServerConfig, setConfig } from '../config';
113
+ import { defaultServerConfig } from '../config';
114
114
  import { deepObjMerge } from '../utils/obj.utils';
115
115
  import { fileExists } from '../utils/fs.utils';
116
116
  import { BUILD_MARKER } from './server.builder';
@@ -214,18 +214,6 @@ var ExpressServer = /** @class */ (function () {
214
214
  if ((_c = config.healthCheck) === null || _c === void 0 ? void 0 : _c.checks) {
215
215
  (_a = this.healthChecks).push.apply(_a, __spreadArray([], __read(config.healthCheck.checks), false));
216
216
  }
217
- // Logger
218
- if (this.config.logger) {
219
- var _e = this.config.logger, name_1 = _e.name, level = _e.level, pretty = _e.prettyPrint, singleLine = _e.singleLine;
220
- setConfig({
221
- logger: {
222
- name: name_1 !== null && name_1 !== void 0 ? name_1 : 'express_app',
223
- level: level !== null && level !== void 0 ? level : 'info',
224
- pretty: pretty !== null && pretty !== void 0 ? pretty : Env.isDev(),
225
- singleLine: singleLine !== null && singleLine !== void 0 ? singleLine : false
226
- }
227
- });
228
- }
229
217
  // Set global prefix (normalize to empty string or "/prefix" without trailing slash)
230
218
  this.globalPrefix = this.normalizePath((_d = this.config.globalPrefix) !== null && _d !== void 0 ? _d : '', false);
231
219
  this.hooks = hooks;
@@ -962,6 +950,7 @@ var ExpressServer = /** @class */ (function () {
962
950
  });
963
951
  }); });
964
952
  });
953
+ return this;
965
954
  };
966
955
  /**
967
956
  * Set an externally created base router.
@@ -969,6 +958,7 @@ var ExpressServer = /** @class */ (function () {
969
958
  */
970
959
  ExpressServer.prototype.setBaseRouter = function (router) {
971
960
  this.externalRouter = router;
961
+ return this;
972
962
  };
973
963
  /**
974
964
  * Create and register a new router (only used if not injecting one externally - use `setBaseRouter` instead).