@catbee/utils 0.0.7 → 0.0.8-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/LICENSE +1 -1
  2. package/build/esm/config.js +1 -1
  3. package/build/esm/config.js.map +1 -1
  4. package/build/esm/index.js +1 -1
  5. package/build/esm/index.js.map +1 -1
  6. package/build/esm/servers/server.builder.js +1 -1
  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 +67 -20
  10. package/build/esm/servers/server.js.map +1 -1
  11. package/build/esm/types/api-response.js +1 -1
  12. package/build/esm/types/api-response.js.map +1 -1
  13. package/build/esm/types/index.js +1 -1
  14. package/build/esm/types/index.js.map +1 -1
  15. package/build/esm/types/server.js +1 -1
  16. package/build/esm/types/server.js.map +1 -1
  17. package/build/esm/utils/array.utils.js +1 -1
  18. package/build/esm/utils/array.utils.js.map +1 -1
  19. package/build/esm/utils/async.utils.js +1 -1
  20. package/build/esm/utils/async.utils.js.map +1 -1
  21. package/build/esm/utils/cache.utils.js +1 -1
  22. package/build/esm/utils/cache.utils.js.map +1 -1
  23. package/build/esm/utils/context-store.utils.js +1 -1
  24. package/build/esm/utils/context-store.utils.js.map +1 -1
  25. package/build/esm/utils/crypto.utils.js +1 -1
  26. package/build/esm/utils/crypto.utils.js.map +1 -1
  27. package/build/esm/utils/date.utils.js +1 -1
  28. package/build/esm/utils/date.utils.js.map +1 -1
  29. package/build/esm/utils/decorators.utils.js +1 -1
  30. package/build/esm/utils/decorators.utils.js.map +1 -1
  31. package/build/esm/utils/dir.utils.js +1 -1
  32. package/build/esm/utils/dir.utils.js.map +1 -1
  33. package/build/esm/utils/env.utils.js +1 -1
  34. package/build/esm/utils/env.utils.js.map +1 -1
  35. package/build/esm/utils/exception.utils.js +1 -1
  36. package/build/esm/utils/exception.utils.js.map +1 -1
  37. package/build/esm/utils/fs.utils.js +1 -1
  38. package/build/esm/utils/fs.utils.js.map +1 -1
  39. package/build/esm/utils/http-status-codes.js +1 -1
  40. package/build/esm/utils/http-status-codes.js.map +1 -1
  41. package/build/esm/utils/id.utils.js +1 -1
  42. package/build/esm/utils/id.utils.js.map +1 -1
  43. package/build/esm/utils/logger.utils.d.ts +1 -1
  44. package/build/esm/utils/logger.utils.js +1 -1
  45. package/build/esm/utils/logger.utils.js.map +1 -1
  46. package/build/esm/utils/middleware.utils.d.ts +17 -0
  47. package/build/esm/utils/middleware.utils.js +120 -1
  48. package/build/esm/utils/middleware.utils.js.map +1 -1
  49. package/build/esm/utils/obj.utils.js +1 -1
  50. package/build/esm/utils/obj.utils.js.map +1 -1
  51. package/build/esm/utils/performance.utils.js +1 -1
  52. package/build/esm/utils/performance.utils.js.map +1 -1
  53. package/build/esm/utils/request.utils.js +1 -1
  54. package/build/esm/utils/request.utils.js.map +1 -1
  55. package/build/esm/utils/response.utils.js +1 -1
  56. package/build/esm/utils/response.utils.js.map +1 -1
  57. package/build/esm/utils/stream.utils.js +1 -1
  58. package/build/esm/utils/stream.utils.js.map +1 -1
  59. package/build/esm/utils/string.utils.js +1 -1
  60. package/build/esm/utils/string.utils.js.map +1 -1
  61. package/build/esm/utils/type.utils.js +1 -1
  62. package/build/esm/utils/type.utils.js.map +1 -1
  63. package/build/esm/utils/url.utils.js +1 -1
  64. package/build/esm/utils/url.utils.js.map +1 -1
  65. package/build/esm/utils/validate.utils.js +1 -1
  66. package/build/esm/utils/validate.utils.js.map +1 -1
  67. package/build/esnext/config.js +1 -1
  68. package/build/esnext/config.js.map +1 -1
  69. package/build/esnext/index.js +1 -1
  70. package/build/esnext/index.js.map +1 -1
  71. package/build/esnext/servers/server.builder.js +1 -1
  72. package/build/esnext/servers/server.builder.js.map +1 -1
  73. package/build/esnext/servers/server.d.ts +2 -2
  74. package/build/esnext/servers/server.js +66 -19
  75. package/build/esnext/servers/server.js.map +1 -1
  76. package/build/esnext/types/api-response.js +1 -1
  77. package/build/esnext/types/api-response.js.map +1 -1
  78. package/build/esnext/types/index.js +1 -1
  79. package/build/esnext/types/index.js.map +1 -1
  80. package/build/esnext/types/server.js +1 -1
  81. package/build/esnext/types/server.js.map +1 -1
  82. package/build/esnext/utils/array.utils.js +1 -1
  83. package/build/esnext/utils/array.utils.js.map +1 -1
  84. package/build/esnext/utils/async.utils.js +1 -1
  85. package/build/esnext/utils/async.utils.js.map +1 -1
  86. package/build/esnext/utils/cache.utils.js +1 -1
  87. package/build/esnext/utils/cache.utils.js.map +1 -1
  88. package/build/esnext/utils/context-store.utils.js +1 -1
  89. package/build/esnext/utils/context-store.utils.js.map +1 -1
  90. package/build/esnext/utils/crypto.utils.js +1 -1
  91. package/build/esnext/utils/crypto.utils.js.map +1 -1
  92. package/build/esnext/utils/date.utils.js +1 -1
  93. package/build/esnext/utils/date.utils.js.map +1 -1
  94. package/build/esnext/utils/decorators.utils.js +1 -1
  95. package/build/esnext/utils/decorators.utils.js.map +1 -1
  96. package/build/esnext/utils/dir.utils.js +1 -1
  97. package/build/esnext/utils/dir.utils.js.map +1 -1
  98. package/build/esnext/utils/env.utils.js +1 -1
  99. package/build/esnext/utils/env.utils.js.map +1 -1
  100. package/build/esnext/utils/exception.utils.js +1 -1
  101. package/build/esnext/utils/exception.utils.js.map +1 -1
  102. package/build/esnext/utils/fs.utils.js +1 -1
  103. package/build/esnext/utils/fs.utils.js.map +1 -1
  104. package/build/esnext/utils/http-status-codes.js +1 -1
  105. package/build/esnext/utils/http-status-codes.js.map +1 -1
  106. package/build/esnext/utils/id.utils.js +1 -1
  107. package/build/esnext/utils/id.utils.js.map +1 -1
  108. package/build/esnext/utils/logger.utils.d.ts +1 -1
  109. package/build/esnext/utils/logger.utils.js +1 -1
  110. package/build/esnext/utils/logger.utils.js.map +1 -1
  111. package/build/esnext/utils/middleware.utils.d.ts +17 -0
  112. package/build/esnext/utils/middleware.utils.js +38 -1
  113. package/build/esnext/utils/middleware.utils.js.map +1 -1
  114. package/build/esnext/utils/obj.utils.js +1 -1
  115. package/build/esnext/utils/obj.utils.js.map +1 -1
  116. package/build/esnext/utils/performance.utils.js +1 -1
  117. package/build/esnext/utils/performance.utils.js.map +1 -1
  118. package/build/esnext/utils/request.utils.js +1 -1
  119. package/build/esnext/utils/request.utils.js.map +1 -1
  120. package/build/esnext/utils/response.utils.js +1 -1
  121. package/build/esnext/utils/response.utils.js.map +1 -1
  122. package/build/esnext/utils/stream.utils.js +1 -1
  123. package/build/esnext/utils/stream.utils.js.map +1 -1
  124. package/build/esnext/utils/string.utils.js +1 -1
  125. package/build/esnext/utils/string.utils.js.map +1 -1
  126. package/build/esnext/utils/type.utils.js +1 -1
  127. package/build/esnext/utils/type.utils.js.map +1 -1
  128. package/build/esnext/utils/url.utils.js +1 -1
  129. package/build/esnext/utils/url.utils.js.map +1 -1
  130. package/build/esnext/utils/validate.utils.js +1 -1
  131. package/build/esnext/utils/validate.utils.js.map +1 -1
  132. package/build/src/config.js +1 -1
  133. package/build/src/config.js.map +1 -1
  134. package/build/src/index.js +1 -1
  135. package/build/src/index.js.map +1 -1
  136. package/build/src/servers/server.builder.js +1 -1
  137. package/build/src/servers/server.builder.js.map +1 -1
  138. package/build/src/servers/server.d.ts +2 -2
  139. package/build/src/servers/server.js +76 -62
  140. package/build/src/servers/server.js.map +1 -1
  141. package/build/src/types/api-response.js +1 -1
  142. package/build/src/types/api-response.js.map +1 -1
  143. package/build/src/types/index.js +1 -1
  144. package/build/src/types/index.js.map +1 -1
  145. package/build/src/types/server.js +1 -1
  146. package/build/src/types/server.js.map +1 -1
  147. package/build/src/utils/array.utils.js +1 -1
  148. package/build/src/utils/array.utils.js.map +1 -1
  149. package/build/src/utils/async.utils.js +1 -1
  150. package/build/src/utils/async.utils.js.map +1 -1
  151. package/build/src/utils/cache.utils.js +1 -1
  152. package/build/src/utils/cache.utils.js.map +1 -1
  153. package/build/src/utils/context-store.utils.js +1 -1
  154. package/build/src/utils/context-store.utils.js.map +1 -1
  155. package/build/src/utils/crypto.utils.js +1 -1
  156. package/build/src/utils/crypto.utils.js.map +1 -1
  157. package/build/src/utils/date.utils.js +1 -1
  158. package/build/src/utils/date.utils.js.map +1 -1
  159. package/build/src/utils/decorators.utils.js +1 -1
  160. package/build/src/utils/decorators.utils.js.map +1 -1
  161. package/build/src/utils/dir.utils.js +1 -1
  162. package/build/src/utils/dir.utils.js.map +1 -1
  163. package/build/src/utils/env.utils.js +1 -1
  164. package/build/src/utils/env.utils.js.map +1 -1
  165. package/build/src/utils/exception.utils.js +1 -1
  166. package/build/src/utils/exception.utils.js.map +1 -1
  167. package/build/src/utils/fs.utils.js +1 -1
  168. package/build/src/utils/fs.utils.js.map +1 -1
  169. package/build/src/utils/http-status-codes.js +1 -1
  170. package/build/src/utils/http-status-codes.js.map +1 -1
  171. package/build/src/utils/id.utils.js +1 -1
  172. package/build/src/utils/id.utils.js.map +1 -1
  173. package/build/src/utils/logger.utils.d.ts +1 -1
  174. package/build/src/utils/logger.utils.js +1 -1
  175. package/build/src/utils/logger.utils.js.map +1 -1
  176. package/build/src/utils/middleware.utils.d.ts +17 -0
  177. package/build/src/utils/middleware.utils.js +39 -1
  178. package/build/src/utils/middleware.utils.js.map +1 -1
  179. package/build/src/utils/obj.utils.js +1 -1
  180. package/build/src/utils/obj.utils.js.map +1 -1
  181. package/build/src/utils/performance.utils.js +1 -1
  182. package/build/src/utils/performance.utils.js.map +1 -1
  183. package/build/src/utils/request.utils.js +1 -1
  184. package/build/src/utils/request.utils.js.map +1 -1
  185. package/build/src/utils/response.utils.js +1 -1
  186. package/build/src/utils/response.utils.js.map +1 -1
  187. package/build/src/utils/stream.utils.js +1 -1
  188. package/build/src/utils/stream.utils.js.map +1 -1
  189. package/build/src/utils/string.utils.js +1 -1
  190. package/build/src/utils/string.utils.js.map +1 -1
  191. package/build/src/utils/type.utils.js +1 -1
  192. package/build/src/utils/type.utils.js.map +1 -1
  193. package/build/src/utils/url.utils.js +1 -1
  194. package/build/src/utils/url.utils.js.map +1 -1
  195. package/build/src/utils/validate.utils.js +1 -1
  196. package/build/src/utils/validate.utils.js.map +1 -1
  197. package/package.json +17 -36
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  The MIT License
2
2
 
3
- Copyright (c) 2025 Catbee Technologies
3
+ Copyright (c) 2025 Catbee Technologies. https://catbee-utils.npm.hprasath.com/license
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * The MIT License
3
3
  *
4
- * Copyright (c) 2025 Catbee Technologies
4
+ * Copyright (c) 2025 Catbee Technologies. https://catbee-utils.npm.hprasath.com/license
5
5
  *
6
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  * of this software and associated documentation files (the "Software"), to deal
@@ -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 { 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"]}
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. https://catbee-utils.npm.hprasath.com/license\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"]}
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * The MIT License
3
3
  *
4
- * Copyright (c) 2025 Catbee Technologies
4
+ * Copyright (c) 2025 Catbee Technologies. https://catbee-utils.npm.hprasath.com/license
5
5
  *
6
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  * of this software and associated documentation files (the "Software"), to deal
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEhD,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AAErC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,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\nexport { setConfig, getConfig } from './config';\n\nexport * from './utils/array.utils';\nexport * from './utils/async.utils';\nexport * from './utils/cache.utils';\nexport * from './utils/context-store.utils';\nexport * from './utils/crypto.utils';\nexport * from './utils/decorators.utils';\nexport * from './utils/dir.utils';\nexport * from './utils/env.utils';\nexport * from './utils/exception.utils';\nexport * from './utils/fs.utils';\nexport * from './utils/http-status-codes';\nexport * from './utils/id.utils';\nexport * from './utils/logger.utils';\nexport * from './utils/middleware.utils';\nexport * from './utils/obj.utils';\nexport * from './utils/request.utils';\nexport * from './utils/response.utils';\nexport * from './utils/string.utils';\nexport * from './utils/url.utils';\nexport * from './utils/validate.utils';\n\nexport * from './types/index';\nexport * from './types/server';\nexport * from './types/api-response';\n\nexport * from './servers/server';\nexport * from './servers/server.builder';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAEhD,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AAEvC,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,sBAAsB,CAAC;AAErC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC","sourcesContent":["/*\n * The MIT License\n *\n * Copyright (c) 2025 Catbee Technologies. https://catbee-utils.npm.hprasath.com/license\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\nexport { setConfig, getConfig } from './config';\n\nexport * from './utils/array.utils';\nexport * from './utils/async.utils';\nexport * from './utils/cache.utils';\nexport * from './utils/context-store.utils';\nexport * from './utils/crypto.utils';\nexport * from './utils/decorators.utils';\nexport * from './utils/dir.utils';\nexport * from './utils/env.utils';\nexport * from './utils/exception.utils';\nexport * from './utils/fs.utils';\nexport * from './utils/http-status-codes';\nexport * from './utils/id.utils';\nexport * from './utils/logger.utils';\nexport * from './utils/middleware.utils';\nexport * from './utils/obj.utils';\nexport * from './utils/request.utils';\nexport * from './utils/response.utils';\nexport * from './utils/string.utils';\nexport * from './utils/url.utils';\nexport * from './utils/validate.utils';\n\nexport * from './types/index';\nexport * from './types/server';\nexport * from './types/api-response';\n\nexport * from './servers/server';\nexport * from './servers/server.builder';\n"]}
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * The MIT License
3
3
  *
4
- * Copyright (c) 2025 Catbee Technologies
4
+ * Copyright (c) 2025 Catbee Technologies. https://catbee-utils.npm.hprasath.com/license
5
5
  *
6
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  * of this software and associated documentation files (the "Software"), to deal
@@ -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 * 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"]}
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. https://catbee-utils.npm.hprasath.com/license\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"]}
@@ -1,7 +1,6 @@
1
1
  import express, { Express, Router } from 'express';
2
2
  import http from 'http';
3
3
  import https from 'https';
4
- import client from 'prom-client';
5
4
  import { ServerConfig, ServerHooks } from '../types/server';
6
5
  /**
7
6
  * Production-ready Express server with enterprise features.
@@ -231,7 +230,7 @@ export declare class ExpressServer {
231
230
  *
232
231
  * @return {*} {client.Registry}
233
232
  */
234
- getMetricsRegistry(): client.Registry;
233
+ getMetricsRegistry(): typeof import("prom-client").Registry;
235
234
  /**
236
235
  * Get server configuration
237
236
  *
@@ -252,5 +251,6 @@ export declare class ExpressServer {
252
251
  private destroyConnections;
253
252
  private validateHttpsFiles;
254
253
  private static isBuiltServerConfig;
254
+ private static optionalRequire;
255
255
  }
256
256
  //# sourceMappingURL=server.d.ts.map
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * The MIT License
3
3
  *
4
- * Copyright (c) 2025 Catbee Technologies
4
+ * Copyright (c) 2025 Catbee Technologies. https://catbee-utils.npm.hprasath.com/license
5
5
  *
6
6
  * Permission is hereby granted, free of charge, to any person obtaining a copy
7
7
  * of this software and associated documentation files (the "Software"), to deal
@@ -95,21 +95,14 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
95
95
  };
96
96
  import express from 'express';
97
97
  import https from 'https';
98
- import cors from 'cors';
99
- import helmet from 'helmet';
100
- import compression from 'compression';
101
- import cookieParser from 'cookie-parser';
102
- import rateLimit from 'express-rate-limit';
103
98
  import { HttpStatusCodes } from '../utils/http-status-codes';
104
99
  import { createFinalErrorResponse, SuccessResponse } from '../utils/response.utils';
105
100
  import { errorHandler, requestId, responseTime, setupRequestContext, timeout } from '../utils/middleware.utils';
106
101
  import { Env } from '../utils/env.utils';
107
102
  import { getLogger } from '../utils/logger.utils';
108
103
  import { InternalServerErrorException, ServiceUnavailableException } from '../utils/exception.utils';
109
- import client, { Counter, Histogram } from 'prom-client';
110
104
  import { NotFoundException } from '../utils/exception.utils';
111
105
  import fs from 'fs';
112
- import { apiReference } from '@scalar/express-api-reference';
113
106
  import { defaultServerConfig } from '../config';
114
107
  import { deepObjMerge } from '../utils/obj.utils';
115
108
  import { fileExists } from '../utils/fs.utils';
@@ -152,7 +145,7 @@ var ExpressServer = /** @class */ (function () {
152
145
  if (hooks === void 0) { hooks = {}; }
153
146
  var _b, _c, _d;
154
147
  /** Prometheus client registry for metrics collection */
155
- this.register = new client.Registry();
148
+ this.register = null;
156
149
  /** HTTP server instance (null when not running) */
157
150
  this.server = null;
158
151
  /** Set of active WebSocket connections */
@@ -172,33 +165,40 @@ var ExpressServer = /** @class */ (function () {
172
165
  this.config = deepObjMerge({}, defaultServerConfig, config);
173
166
  }
174
167
  if (!isPort(this.config.port)) {
175
- throw new Error("Port must be a valid number between 1 and 65535, got: ".concat(this.config.port));
168
+ getLogger().error("Port must be a valid number between 1 and 65535, got: ".concat(this.config.port));
169
+ process.exit(1);
176
170
  }
177
171
  // Sanitize app name for metrics (replace invalid characters with underscore)
178
172
  var safeAppName = (this.config.appName || 'express_app').toLowerCase().replace(/[^a-z0-9_]/g, '_');
179
173
  if ((_b = this.config.metrics) === null || _b === void 0 ? void 0 : _b.enable) {
174
+ var client = ExpressServer.optionalRequire('prom-client');
175
+ if (!client) {
176
+ getLogger().error({ command: 'npm install prom-client' }, 'prom-client is required for metrics but not installed. Please add it to your dependencies');
177
+ process.exit(1);
178
+ }
179
+ this.register = new client.Registry();
180
180
  // Initialize Prometheus metrics with sanitized names
181
- this.requestCounter = new Counter({
181
+ this.requestCounter = new client.Counter({
182
182
  name: "".concat(safeAppName, "_http_requests_total"),
183
183
  help: 'Total HTTP requests',
184
184
  labelNames: ['method', 'route', 'status'],
185
185
  registers: [this.register]
186
186
  });
187
- this.routeTimings = new Histogram({
187
+ this.routeTimings = new client.Histogram({
188
188
  name: "".concat(safeAppName, "_http_request_duration_seconds"),
189
189
  help: 'Duration of HTTP requests by route',
190
190
  labelNames: ['method', 'route', 'status'],
191
191
  buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10],
192
192
  registers: [this.register]
193
193
  });
194
- this.requestSizes = new Histogram({
194
+ this.requestSizes = new client.Histogram({
195
195
  name: "".concat(safeAppName, "_http_request_size_bytes"),
196
196
  help: 'Size of HTTP request bodies',
197
197
  labelNames: ['method', 'route'],
198
198
  buckets: [100, 1000, 10000, 100000, 1000000],
199
199
  registers: [this.register]
200
200
  });
201
- this.clientIPs = new Counter({
201
+ this.clientIPs = new client.Counter({
202
202
  name: "".concat(safeAppName, "_http_client_ip_total"),
203
203
  help: 'Client IP request counter',
204
204
  labelNames: ['ip', 'method'],
@@ -305,7 +305,7 @@ var ExpressServer = /** @class */ (function () {
305
305
  */
306
306
  ExpressServer.prototype.setupMiddleware = function () {
307
307
  return __awaiter(this, void 0, void 0, function () {
308
- var openApiMountPath, openApiFilePath, isOpenApiFilePathExists, _a, _b, _c, _d, err_2;
308
+ var helmet, cors, rateLimit, compression, cookieParser, openApiMountPath, openApiFilePath, isOpenApiFilePathExists, apiReference, _a, _b, _c, _d, err_2;
309
309
  var _e, _f;
310
310
  var _this = this;
311
311
  var _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x;
@@ -347,6 +347,11 @@ var ExpressServer = /** @class */ (function () {
347
347
  });
348
348
  // Security middleware should come early
349
349
  if (this.config.helmet) {
350
+ helmet = ExpressServer.optionalRequire('helmet');
351
+ if (!helmet) {
352
+ getLogger().error({ command: 'npm install helmet' }, 'helmet is required but not installed. Please add it to your dependencies');
353
+ process.exit(1);
354
+ }
350
355
  if (typeof this.config.helmet === 'object') {
351
356
  this.app.use(helmet(this.config.helmet));
352
357
  }
@@ -356,6 +361,11 @@ var ExpressServer = /** @class */ (function () {
356
361
  }
357
362
  // CORS middleware should be early
358
363
  if (this.config.cors) {
364
+ cors = ExpressServer.optionalRequire('cors');
365
+ if (!cors) {
366
+ getLogger().error({ command: 'npm install cors' }, 'cors is required but not installed. Please add it to your dependencies');
367
+ process.exit(1);
368
+ }
359
369
  this.app.use(cors(this.config.cors === true ? {} : this.config.cors));
360
370
  }
361
371
  // Global headers
@@ -391,6 +401,11 @@ var ExpressServer = /** @class */ (function () {
391
401
  }
392
402
  // Rate limiting should be early to prevent unnecessary processing
393
403
  if ((_m = this.config.rateLimit) === null || _m === void 0 ? void 0 : _m.enable) {
404
+ rateLimit = ExpressServer.optionalRequire('express-rate-limit');
405
+ if (!rateLimit) {
406
+ getLogger().error({ command: 'npm install express-rate-limit' }, 'express-rate-limit is required but not installed. Please add it to your dependencies');
407
+ process.exit(1);
408
+ }
394
409
  this.app.use(rateLimit({
395
410
  windowMs: (_o = this.config.rateLimit.windowMs) !== null && _o !== void 0 ? _o : 15 * 60 * 1000,
396
411
  max: (_p = this.config.rateLimit.max) !== null && _p !== void 0 ? _p : 100,
@@ -435,6 +450,11 @@ var ExpressServer = /** @class */ (function () {
435
450
  }
436
451
  // Response compression for better performance
437
452
  if (this.config.compression) {
453
+ compression = ExpressServer.optionalRequire('compression');
454
+ if (!compression) {
455
+ getLogger().error({ command: 'npm install compression' }, 'compression is required but not installed. Please add it to your dependencies');
456
+ process.exit(1);
457
+ }
438
458
  if (typeof this.config.compression === 'object') {
439
459
  this.app.use(compression(this.config.compression));
440
460
  }
@@ -467,6 +487,11 @@ var ExpressServer = /** @class */ (function () {
467
487
  }
468
488
  // Cookie parser middleware
469
489
  if (this.config.cookieParser) {
490
+ cookieParser = ExpressServer.optionalRequire('cookie-parser');
491
+ if (!cookieParser) {
492
+ getLogger().error({ command: 'npm install cookie-parser' }, 'cookie-parser is required but not installed. Please add it to your dependencies');
493
+ process.exit(1);
494
+ }
470
495
  if (typeof this.config.cookieParser === 'object') {
471
496
  this.app.use(cookieParser(undefined, this.config.cookieParser));
472
497
  }
@@ -481,18 +506,25 @@ var ExpressServer = /** @class */ (function () {
481
506
  openApiMountPath = this.normalizePath((_u = this.config.openApi.mountPath) !== null && _u !== void 0 ? _u : '/docs', this.config.openApi.withGlobalPrefix);
482
507
  openApiFilePath = this.config.openApi.filePath;
483
508
  if (!openApiFilePath) {
484
- throw new Error('OpenAPI file path is required');
509
+ getLogger().error('OpenAPI file path is required');
510
+ process.exit(1);
485
511
  }
486
512
  return [4 /*yield*/, fileExists(openApiFilePath)];
487
513
  case 4:
488
514
  isOpenApiFilePathExists = _y.sent();
489
515
  if (!isOpenApiFilePathExists) {
490
- throw new Error("OpenAPI spec file not found at ".concat(openApiFilePath));
516
+ getLogger().error("OpenAPI spec file not found at ".concat(openApiFilePath));
517
+ process.exit(1);
491
518
  }
492
519
  if ((_v = this.config.openApi) === null || _v === void 0 ? void 0 : _v.verbose) {
493
520
  getLogger().info("Mounting OpenAPI docs at ".concat(openApiMountPath));
494
521
  getLogger().info("Using OpenAPI spec file at ".concat(openApiFilePath));
495
522
  }
523
+ apiReference = ExpressServer.optionalRequire('@scalar/express-api-reference').apiReference;
524
+ if (!apiReference) {
525
+ getLogger().error({ command: 'npm install @scalar/express-api-reference' }, '@scalar/express-api-reference is required for OpenAPI docs but not installed. Please add it to your dependencies');
526
+ process.exit(1);
527
+ }
496
528
  _b = (_a = this.app).use;
497
529
  _c = [openApiMountPath];
498
530
  _d = apiReference;
@@ -1058,6 +1090,10 @@ var ExpressServer = /** @class */ (function () {
1058
1090
  * @return {*} {client.Registry}
1059
1091
  */
1060
1092
  ExpressServer.prototype.getMetricsRegistry = function () {
1093
+ var _a;
1094
+ if (!((_a = this.config.metrics) === null || _a === void 0 ? void 0 : _a.enable)) {
1095
+ throw new Error('Metrics are not enabled in the server configuration');
1096
+ }
1061
1097
  return this.register;
1062
1098
  };
1063
1099
  /**
@@ -1167,12 +1203,14 @@ var ExpressServer = /** @class */ (function () {
1167
1203
  case 0: return [4 /*yield*/, fileExists(this.config.https.key)];
1168
1204
  case 1:
1169
1205
  if (!(_b.sent())) {
1170
- throw new Error("HTTPS key file not found: ".concat(this.config.https.key));
1206
+ getLogger().error("HTTPS key file not found: ".concat(this.config.https.key));
1207
+ process.exit(1);
1171
1208
  }
1172
1209
  return [4 /*yield*/, fileExists(this.config.https.cert)];
1173
1210
  case 2:
1174
1211
  if (!(_b.sent())) {
1175
- throw new Error("HTTPS cert file not found: ".concat(this.config.https.cert));
1212
+ getLogger().error("HTTPS cert file not found: ".concat(this.config.https.cert));
1213
+ process.exit(1);
1176
1214
  }
1177
1215
  _a = this.config.https.ca;
1178
1216
  if (!_a) return [3 /*break*/, 4];
@@ -1182,7 +1220,8 @@ var ExpressServer = /** @class */ (function () {
1182
1220
  _b.label = 4;
1183
1221
  case 4:
1184
1222
  if (_a) {
1185
- throw new Error("HTTPS CA file not found: ".concat(this.config.https.ca));
1223
+ getLogger().error("HTTPS CA file not found: ".concat(this.config.https.ca));
1224
+ process.exit(1);
1186
1225
  }
1187
1226
  return [2 /*return*/];
1188
1227
  }
@@ -1195,6 +1234,14 @@ var ExpressServer = /** @class */ (function () {
1195
1234
  }
1196
1235
  return false;
1197
1236
  };
1237
+ ExpressServer.optionalRequire = function (name) {
1238
+ try {
1239
+ return require(name);
1240
+ }
1241
+ catch (_a) {
1242
+ return null;
1243
+ }
1244
+ };
1198
1245
  return ExpressServer;
1199
1246
  }());
1200
1247
  export { ExpressServer };