@catbee/utils 0.0.8-next.0 → 0.0.8-rc.1

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 (284) hide show
  1. package/README.md +1 -2
  2. package/build/esm/config.d.ts +122 -0
  3. package/build/esm/config.js +133 -0
  4. package/build/esm/config.js.map +1 -0
  5. package/build/esm/index.d.ts +27 -0
  6. package/build/esm/index.js +50 -0
  7. package/build/esm/index.js.map +1 -0
  8. package/build/esm/servers/server.builder.d.ts +508 -0
  9. package/build/esm/servers/server.builder.js +702 -0
  10. package/build/esm/servers/server.builder.js.map +1 -0
  11. package/build/esm/servers/server.d.ts +256 -0
  12. package/build/esm/servers/server.js +1248 -0
  13. package/build/esm/servers/server.js.map +1 -0
  14. package/build/esm/types/api-response.d.ts +152 -0
  15. package/build/esm/types/api-response.js +34 -0
  16. package/build/esm/types/api-response.js.map +1 -0
  17. package/build/esm/types/index.d.ts +125 -0
  18. package/build/esm/types/index.js +25 -0
  19. package/build/esm/types/index.js.map +1 -0
  20. package/build/esm/types/server.d.ts +268 -0
  21. package/build/esm/types/server.js +25 -0
  22. package/build/esm/types/server.js.map +1 -0
  23. package/build/esm/utils/array.utils.d.ts +168 -0
  24. package/build/esm/utils/array.utils.js +382 -0
  25. package/build/esm/utils/array.utils.js.map +1 -0
  26. package/build/esm/utils/async.utils.d.ts +265 -0
  27. package/build/esm/utils/async.utils.js +896 -0
  28. package/build/esm/utils/async.utils.js.map +1 -0
  29. package/build/esm/utils/cache.utils.d.ts +153 -0
  30. package/build/esm/utils/cache.utils.js +499 -0
  31. package/build/esm/utils/cache.utils.js.map +1 -0
  32. package/build/esm/utils/context-store.utils.d.ts +189 -0
  33. package/build/esm/utils/context-store.utils.js +307 -0
  34. package/build/esm/utils/context-store.utils.js.map +1 -0
  35. package/build/esm/utils/crypto.utils.d.ts +160 -0
  36. package/build/esm/utils/crypto.utils.js +375 -0
  37. package/build/esm/utils/crypto.utils.js.map +1 -0
  38. package/build/esm/utils/date.utils.d.ts +159 -0
  39. package/build/esm/utils/date.utils.js +389 -0
  40. package/build/esm/utils/date.utils.js.map +1 -0
  41. package/build/esm/utils/decorators.utils.d.ts +508 -0
  42. package/build/esm/utils/decorators.utils.js +1057 -0
  43. package/build/esm/utils/decorators.utils.js.map +1 -0
  44. package/build/esm/utils/dir.utils.d.ts +196 -0
  45. package/build/esm/utils/dir.utils.js +998 -0
  46. package/build/esm/utils/dir.utils.js.map +1 -0
  47. package/build/esm/utils/env.utils.d.ts +377 -0
  48. package/build/esm/utils/env.utils.js +873 -0
  49. package/build/esm/utils/env.utils.js.map +1 -0
  50. package/build/esm/utils/exception.utils.d.ts +230 -0
  51. package/build/esm/utils/exception.utils.js +559 -0
  52. package/build/esm/utils/exception.utils.js.map +1 -0
  53. package/build/esm/utils/fs.utils.d.ts +164 -0
  54. package/build/esm/utils/fs.utils.js +580 -0
  55. package/build/esm/utils/fs.utils.js.map +1 -0
  56. package/build/esm/utils/http-status-codes.d.ts +266 -0
  57. package/build/esm/utils/http-status-codes.js +295 -0
  58. package/build/esm/utils/http-status-codes.js.map +1 -0
  59. package/build/esm/utils/id.utils.d.ts +36 -0
  60. package/build/esm/utils/id.utils.js +87 -0
  61. package/build/esm/utils/id.utils.js.map +1 -0
  62. package/build/esm/utils/logger.utils.d.ts +160 -0
  63. package/build/esm/utils/logger.utils.js +341 -0
  64. package/build/esm/utils/logger.utils.js.map +1 -0
  65. package/build/esm/utils/middleware.utils.d.ts +100 -0
  66. package/build/esm/utils/middleware.utils.js +325 -0
  67. package/build/esm/utils/middleware.utils.js.map +1 -0
  68. package/build/esm/utils/obj.utils.d.ts +124 -0
  69. package/build/esm/utils/obj.utils.js +519 -0
  70. package/build/esm/utils/obj.utils.js.map +1 -0
  71. package/build/esm/utils/performance.utils.d.ts +136 -0
  72. package/build/esm/utils/performance.utils.js +376 -0
  73. package/build/esm/utils/performance.utils.js.map +1 -0
  74. package/build/esm/utils/request.utils.d.ts +86 -0
  75. package/build/esm/utils/request.utils.js +223 -0
  76. package/build/esm/utils/request.utils.js.map +1 -0
  77. package/build/esm/utils/response.utils.d.ts +163 -0
  78. package/build/esm/utils/response.utils.js +284 -0
  79. package/build/esm/utils/response.utils.js.map +1 -0
  80. package/build/esm/utils/stream.utils.d.ts +88 -0
  81. package/build/esm/utils/stream.utils.js +284 -0
  82. package/build/esm/utils/stream.utils.js.map +1 -0
  83. package/build/esm/utils/string.utils.d.ts +93 -0
  84. package/build/esm/utils/string.utils.js +169 -0
  85. package/build/esm/utils/string.utils.js.map +1 -0
  86. package/build/esm/utils/type.utils.d.ts +90 -0
  87. package/build/esm/utils/type.utils.js +190 -0
  88. package/build/esm/utils/type.utils.js.map +1 -0
  89. package/build/esm/utils/url.utils.d.ts +141 -0
  90. package/build/esm/utils/url.utils.js +381 -0
  91. package/build/esm/utils/url.utils.js.map +1 -0
  92. package/build/esm/utils/validate.utils.d.ts +177 -0
  93. package/build/esm/utils/validate.utils.js +336 -0
  94. package/build/esm/utils/validate.utils.js.map +1 -0
  95. package/build/esnext/config.d.ts +122 -0
  96. package/build/esnext/config.js +133 -0
  97. package/build/esnext/config.js.map +1 -0
  98. package/build/esnext/index.d.ts +27 -0
  99. package/build/esnext/index.js +50 -0
  100. package/build/esnext/index.js.map +1 -0
  101. package/build/esnext/servers/server.builder.d.ts +508 -0
  102. package/build/esnext/servers/server.builder.js +657 -0
  103. package/build/esnext/servers/server.builder.js.map +1 -0
  104. package/build/esnext/servers/server.d.ts +256 -0
  105. package/build/esnext/servers/server.js +955 -0
  106. package/build/esnext/servers/server.js.map +1 -0
  107. package/build/esnext/types/api-response.d.ts +152 -0
  108. package/build/esnext/types/api-response.js +34 -0
  109. package/build/esnext/types/api-response.js.map +1 -0
  110. package/build/esnext/types/index.d.ts +125 -0
  111. package/build/esnext/types/index.js +25 -0
  112. package/build/esnext/types/index.js.map +1 -0
  113. package/build/esnext/types/server.d.ts +268 -0
  114. package/build/esnext/types/server.js +25 -0
  115. package/build/esnext/types/server.js.map +1 -0
  116. package/build/esnext/utils/array.utils.d.ts +168 -0
  117. package/build/esnext/utils/array.utils.js +345 -0
  118. package/build/esnext/utils/array.utils.js.map +1 -0
  119. package/build/esnext/utils/async.utils.d.ts +265 -0
  120. package/build/esnext/utils/async.utils.js +620 -0
  121. package/build/esnext/utils/async.utils.js.map +1 -0
  122. package/build/esnext/utils/cache.utils.d.ts +153 -0
  123. package/build/esnext/utils/cache.utils.js +293 -0
  124. package/build/esnext/utils/cache.utils.js.map +1 -0
  125. package/build/esnext/utils/context-store.utils.d.ts +189 -0
  126. package/build/esnext/utils/context-store.utils.js +289 -0
  127. package/build/esnext/utils/context-store.utils.js.map +1 -0
  128. package/build/esnext/utils/crypto.utils.d.ts +160 -0
  129. package/build/esnext/utils/crypto.utils.js +276 -0
  130. package/build/esnext/utils/crypto.utils.js.map +1 -0
  131. package/build/esnext/utils/date.utils.d.ts +159 -0
  132. package/build/esnext/utils/date.utils.js +384 -0
  133. package/build/esnext/utils/date.utils.js.map +1 -0
  134. package/build/esnext/utils/decorators.utils.d.ts +508 -0
  135. package/build/esnext/utils/decorators.utils.js +877 -0
  136. package/build/esnext/utils/decorators.utils.js.map +1 -0
  137. package/build/esnext/utils/dir.utils.d.ts +196 -0
  138. package/build/esnext/utils/dir.utils.js +477 -0
  139. package/build/esnext/utils/dir.utils.js.map +1 -0
  140. package/build/esnext/utils/env.utils.d.ts +377 -0
  141. package/build/esnext/utils/env.utils.js +785 -0
  142. package/build/esnext/utils/env.utils.js.map +1 -0
  143. package/build/esnext/utils/exception.utils.d.ts +230 -0
  144. package/build/esnext/utils/exception.utils.js +381 -0
  145. package/build/esnext/utils/exception.utils.js.map +1 -0
  146. package/build/esnext/utils/fs.utils.d.ts +164 -0
  147. package/build/esnext/utils/fs.utils.js +349 -0
  148. package/build/esnext/utils/fs.utils.js.map +1 -0
  149. package/build/esnext/utils/http-status-codes.d.ts +266 -0
  150. package/build/esnext/utils/http-status-codes.js +295 -0
  151. package/build/esnext/utils/http-status-codes.js.map +1 -0
  152. package/build/esnext/utils/id.utils.d.ts +36 -0
  153. package/build/esnext/utils/id.utils.js +84 -0
  154. package/build/esnext/utils/id.utils.js.map +1 -0
  155. package/build/esnext/utils/logger.utils.d.ts +160 -0
  156. package/build/esnext/utils/logger.utils.js +300 -0
  157. package/build/esnext/utils/logger.utils.js.map +1 -0
  158. package/build/esnext/utils/middleware.utils.d.ts +100 -0
  159. package/build/esnext/utils/middleware.utils.js +236 -0
  160. package/build/esnext/utils/middleware.utils.js.map +1 -0
  161. package/build/esnext/utils/obj.utils.d.ts +124 -0
  162. package/build/esnext/utils/obj.utils.js +413 -0
  163. package/build/esnext/utils/obj.utils.js.map +1 -0
  164. package/build/esnext/utils/performance.utils.d.ts +136 -0
  165. package/build/esnext/utils/performance.utils.js +271 -0
  166. package/build/esnext/utils/performance.utils.js.map +1 -0
  167. package/build/esnext/utils/request.utils.d.ts +86 -0
  168. package/build/esnext/utils/request.utils.js +186 -0
  169. package/build/esnext/utils/request.utils.js.map +1 -0
  170. package/build/esnext/utils/response.utils.d.ts +163 -0
  171. package/build/esnext/utils/response.utils.js +247 -0
  172. package/build/esnext/utils/response.utils.js.map +1 -0
  173. package/build/esnext/utils/stream.utils.d.ts +88 -0
  174. package/build/esnext/utils/stream.utils.js +210 -0
  175. package/build/esnext/utils/stream.utils.js.map +1 -0
  176. package/build/esnext/utils/string.utils.d.ts +93 -0
  177. package/build/esnext/utils/string.utils.js +165 -0
  178. package/build/esnext/utils/string.utils.js.map +1 -0
  179. package/build/esnext/utils/type.utils.d.ts +90 -0
  180. package/build/esnext/utils/type.utils.js +187 -0
  181. package/build/esnext/utils/type.utils.js.map +1 -0
  182. package/build/esnext/utils/url.utils.d.ts +141 -0
  183. package/build/esnext/utils/url.utils.js +304 -0
  184. package/build/esnext/utils/url.utils.js.map +1 -0
  185. package/build/esnext/utils/validate.utils.d.ts +177 -0
  186. package/build/esnext/utils/validate.utils.js +320 -0
  187. package/build/esnext/utils/validate.utils.js.map +1 -0
  188. package/build/src/config.d.ts +122 -0
  189. package/build/src/config.js +138 -0
  190. package/build/src/config.js.map +1 -0
  191. package/build/src/index.d.ts +27 -0
  192. package/build/src/index.js +69 -0
  193. package/build/src/index.js.map +1 -0
  194. package/build/src/servers/server.builder.d.ts +508 -0
  195. package/build/src/servers/server.builder.js +661 -0
  196. package/build/src/servers/server.builder.js.map +1 -0
  197. package/build/src/servers/server.d.ts +256 -0
  198. package/build/src/servers/server.js +962 -0
  199. package/build/src/servers/server.js.map +1 -0
  200. package/build/src/types/api-response.d.ts +152 -0
  201. package/build/src/types/api-response.js +37 -0
  202. package/build/src/types/api-response.js.map +1 -0
  203. package/build/src/types/index.d.ts +125 -0
  204. package/build/src/types/index.js +26 -0
  205. package/build/src/types/index.js.map +1 -0
  206. package/build/src/types/server.d.ts +268 -0
  207. package/build/src/types/server.js +26 -0
  208. package/build/src/types/server.js.map +1 -0
  209. package/build/src/utils/array.utils.d.ts +168 -0
  210. package/build/src/utils/array.utils.js +364 -0
  211. package/build/src/utils/array.utils.js.map +1 -0
  212. package/build/src/utils/async.utils.d.ts +265 -0
  213. package/build/src/utils/async.utils.js +641 -0
  214. package/build/src/utils/async.utils.js.map +1 -0
  215. package/build/src/utils/cache.utils.d.ts +153 -0
  216. package/build/src/utils/cache.utils.js +297 -0
  217. package/build/src/utils/cache.utils.js.map +1 -0
  218. package/build/src/utils/context-store.utils.d.ts +189 -0
  219. package/build/src/utils/context-store.utils.js +296 -0
  220. package/build/src/utils/context-store.utils.js.map +1 -0
  221. package/build/src/utils/crypto.utils.d.ts +160 -0
  222. package/build/src/utils/crypto.utils.js +293 -0
  223. package/build/src/utils/crypto.utils.js.map +1 -0
  224. package/build/src/utils/date.utils.d.ts +159 -0
  225. package/build/src/utils/date.utils.js +396 -0
  226. package/build/src/utils/date.utils.js.map +1 -0
  227. package/build/src/utils/decorators.utils.d.ts +508 -0
  228. package/build/src/utils/decorators.utils.js +896 -0
  229. package/build/src/utils/decorators.utils.js.map +1 -0
  230. package/build/src/utils/dir.utils.d.ts +196 -0
  231. package/build/src/utils/dir.utils.js +501 -0
  232. package/build/src/utils/dir.utils.js.map +1 -0
  233. package/build/src/utils/env.utils.d.ts +377 -0
  234. package/build/src/utils/env.utils.js +789 -0
  235. package/build/src/utils/env.utils.js.map +1 -0
  236. package/build/src/utils/exception.utils.d.ts +230 -0
  237. package/build/src/utils/exception.utils.js +407 -0
  238. package/build/src/utils/exception.utils.js.map +1 -0
  239. package/build/src/utils/fs.utils.d.ts +164 -0
  240. package/build/src/utils/fs.utils.js +372 -0
  241. package/build/src/utils/fs.utils.js.map +1 -0
  242. package/build/src/utils/http-status-codes.d.ts +266 -0
  243. package/build/src/utils/http-status-codes.js +298 -0
  244. package/build/src/utils/http-status-codes.js.map +1 -0
  245. package/build/src/utils/id.utils.d.ts +36 -0
  246. package/build/src/utils/id.utils.js +91 -0
  247. package/build/src/utils/id.utils.js.map +1 -0
  248. package/build/src/utils/logger.utils.d.ts +160 -0
  249. package/build/src/utils/logger.utils.js +346 -0
  250. package/build/src/utils/logger.utils.js.map +1 -0
  251. package/build/src/utils/middleware.utils.d.ts +100 -0
  252. package/build/src/utils/middleware.utils.js +244 -0
  253. package/build/src/utils/middleware.utils.js.map +1 -0
  254. package/build/src/utils/obj.utils.d.ts +124 -0
  255. package/build/src/utils/obj.utils.js +429 -0
  256. package/build/src/utils/obj.utils.js.map +1 -0
  257. package/build/src/utils/performance.utils.d.ts +136 -0
  258. package/build/src/utils/performance.utils.js +278 -0
  259. package/build/src/utils/performance.utils.js.map +1 -0
  260. package/build/src/utils/request.utils.d.ts +86 -0
  261. package/build/src/utils/request.utils.js +195 -0
  262. package/build/src/utils/request.utils.js.map +1 -0
  263. package/build/src/utils/response.utils.d.ts +163 -0
  264. package/build/src/utils/response.utils.js +260 -0
  265. package/build/src/utils/response.utils.js.map +1 -0
  266. package/build/src/utils/stream.utils.d.ts +88 -0
  267. package/build/src/utils/stream.utils.js +218 -0
  268. package/build/src/utils/stream.utils.js.map +1 -0
  269. package/build/src/utils/string.utils.d.ts +93 -0
  270. package/build/src/utils/string.utils.js +179 -0
  271. package/build/src/utils/string.utils.js.map +1 -0
  272. package/build/src/utils/type.utils.d.ts +90 -0
  273. package/build/src/utils/type.utils.js +196 -0
  274. package/build/src/utils/type.utils.js.map +1 -0
  275. package/build/src/utils/url.utils.d.ts +141 -0
  276. package/build/src/utils/url.utils.js +317 -0
  277. package/build/src/utils/url.utils.js.map +1 -0
  278. package/build/src/utils/validate.utils.d.ts +177 -0
  279. package/build/src/utils/validate.utils.js +345 -0
  280. package/build/src/utils/validate.utils.js.map +1 -0
  281. package/package.json +66 -12
  282. package/build/index.cjs +0 -6888
  283. package/build/index.d.ts +0 -5242
  284. package/build/index.mjs +0 -6615
@@ -0,0 +1,896 @@
1
+ "use strict";
2
+ /*
3
+ * The MIT License
4
+ *
5
+ * Copyright (c) 2025 Catbee Technologies. https://catbee-utils.npm.hprasath.com/license
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in all
15
+ * copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23
+ * SOFTWARE.
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.rateLimiterCache = exports.Res = exports.Req = exports.Body = exports.Param = exports.Query = exports.Connect = exports.Trace = exports.Head = exports.Options = exports.Delete = exports.Patch = exports.Put = exports.Post = exports.Get = exports.RateLimiterCache = void 0;
27
+ exports.Controller = Controller;
28
+ exports.Use = Use;
29
+ exports.HttpCode = HttpCode;
30
+ exports.Header = Header;
31
+ exports.Headers = Headers;
32
+ exports.Before = Before;
33
+ exports.After = After;
34
+ exports.Roles = Roles;
35
+ exports.Redirect = Redirect;
36
+ exports.Cache = Cache;
37
+ exports.RateLimit = RateLimit;
38
+ exports.ContentType = ContentType;
39
+ exports.Version = Version;
40
+ exports.Timeout = Timeout;
41
+ exports.Log = Log;
42
+ exports.registerControllers = registerControllers;
43
+ require("reflect-metadata");
44
+ const logger_utils_1 = require("./logger.utils");
45
+ const response_utils_1 = require("./response.utils");
46
+ const http_status_codes_1 = require("./http-status-codes");
47
+ const express_rate_limit_1 = require("express-rate-limit");
48
+ const cache_utils_1 = require("./cache.utils");
49
+ // Metadata keys
50
+ const ROUTES_KEY = Symbol('routes');
51
+ const MIDDLEWARE_KEY = Symbol('middlewares');
52
+ const PARAMS_KEY = Symbol('params');
53
+ const HTTP_CODE_KEY = Symbol('httpCode');
54
+ const HEADER_KEY = Symbol('headers');
55
+ const BEFORE_KEY = Symbol('before');
56
+ const AFTER_KEY = Symbol('after');
57
+ const ROLES_KEY = Symbol('roles');
58
+ const REDIRECT_KEY = Symbol('redirect');
59
+ const CACHE_KEY = Symbol('cache');
60
+ const RATE_LIMIT_KEY = Symbol('rateLimit');
61
+ const CONTENT_TYPE_KEY = Symbol('contentType');
62
+ const VERSION_KEY = Symbol('version');
63
+ const TIMEOUT_KEY = Symbol('timeout');
64
+ const LOG_KEY = Symbol('log');
65
+ /**
66
+ * RateLimiter cache that uses TTLCache for automatic TTL and LRU handling.
67
+ */
68
+ class RateLimiterCache {
69
+ constructor(maxSize = 100, ttlMs = 5 * 60 * 1000) {
70
+ this.cache = new cache_utils_1.TTLCache({
71
+ maxSize,
72
+ ttlMs
73
+ });
74
+ }
75
+ generateKey(options) {
76
+ return `${options.max}:${options.windowMs}:${options.standardHeaders}:${options.legacyHeaders}`;
77
+ }
78
+ get(options) {
79
+ const key = this.generateKey(options);
80
+ const cached = this.cache.get(key);
81
+ if (cached) {
82
+ return cached.limiter;
83
+ }
84
+ // Create new limiter
85
+ const limiter = (0, express_rate_limit_1.rateLimit)(Object.assign(Object.assign({}, options), { handler: (req, res) => {
86
+ const errorResponse = (0, response_utils_1.createFinalErrorResponse)(req, http_status_codes_1.HttpStatusCodes.TOO_MANY_REQUESTS, 'Too Many Requests');
87
+ res.status(http_status_codes_1.HttpStatusCodes.TOO_MANY_REQUESTS).json(errorResponse);
88
+ } }));
89
+ // Store in cache
90
+ this.cache.set(key, {
91
+ limiter,
92
+ config: key
93
+ });
94
+ return limiter;
95
+ }
96
+ clear() {
97
+ this.cache.clear();
98
+ }
99
+ size() {
100
+ return this.cache.size();
101
+ }
102
+ destroy() {
103
+ this.cache.destroy();
104
+ }
105
+ }
106
+ exports.RateLimiterCache = RateLimiterCache;
107
+ // Global cache instance
108
+ const rateLimiterCache = new RateLimiterCache();
109
+ exports.rateLimiterCache = rateLimiterCache;
110
+ function normalizeHeaderValue(value) {
111
+ if (typeof value === 'undefined')
112
+ return undefined;
113
+ if (typeof value === 'string')
114
+ return value;
115
+ if (Array.isArray(value) && value.every(item => typeof item === 'string')) {
116
+ return value;
117
+ }
118
+ return String(value);
119
+ }
120
+ /**
121
+ * Factory function that creates HTTP method decorators.
122
+ *
123
+ * @param method - HTTP method to create decorator for
124
+ * @returns A method decorator function
125
+ */
126
+ function createRouteDecorator(method) {
127
+ return (path) => {
128
+ return (target, propertyKey, descriptor) => {
129
+ const routes = Reflect.getMetadata(ROUTES_KEY, target.constructor) || [];
130
+ routes.push({
131
+ path,
132
+ method,
133
+ handlerName: propertyKey
134
+ });
135
+ Reflect.defineMetadata(ROUTES_KEY, routes, target.constructor);
136
+ };
137
+ };
138
+ }
139
+ /**
140
+ * Decorator for GET HTTP method routes.
141
+ *
142
+ * @param path - URL path for the route
143
+ * @returns Method decorator
144
+ *
145
+ * @example
146
+ * ```ts
147
+ * @Get('/users')
148
+ * getUsers() {
149
+ * return this.userService.findAll();
150
+ * }
151
+ * ```
152
+ */
153
+ exports.Get = createRouteDecorator('get');
154
+ /**
155
+ * Decorator for POST HTTP method routes.
156
+ *
157
+ * @param path - URL path for the route
158
+ * @returns Method decorator
159
+ *
160
+ * @example
161
+ * ```ts
162
+ * @Post('/users')
163
+ * createUser(@Body() userData: any) {
164
+ * return this.userService.create(userData);
165
+ * }
166
+ * ```
167
+ */
168
+ exports.Post = createRouteDecorator('post');
169
+ /**
170
+ * Decorator for PUT HTTP method routes.
171
+ *
172
+ * @param path - URL path for the route
173
+ * @returns Method decorator
174
+ */
175
+ exports.Put = createRouteDecorator('put');
176
+ /**
177
+ * Decorator for PATCH HTTP method routes.
178
+ *
179
+ * @param path - URL path for the route
180
+ * @returns Method decorator
181
+ */
182
+ exports.Patch = createRouteDecorator('patch');
183
+ /**
184
+ * Decorator for DELETE HTTP method routes.
185
+ *
186
+ * @param path - URL path for the route
187
+ * @returns Method decorator
188
+ */
189
+ exports.Delete = createRouteDecorator('delete');
190
+ /**
191
+ * Decorator for OPTIONS HTTP method routes.
192
+ *
193
+ * @param path - URL path for the route
194
+ * @returns Method decorator
195
+ */
196
+ exports.Options = createRouteDecorator('options');
197
+ /**
198
+ * Decorator for HEAD HTTP method routes.
199
+ *
200
+ * @param path - URL path for the route
201
+ * @returns Method decorator
202
+ */
203
+ exports.Head = createRouteDecorator('head');
204
+ /**
205
+ * Decorator for TRACE HTTP method routes.
206
+ *
207
+ * @param path - URL path for the route
208
+ * @returns Method decorator
209
+ */
210
+ exports.Trace = createRouteDecorator('trace');
211
+ /**
212
+ * Decorator for CONNECT HTTP method routes.
213
+ *
214
+ * @param path - URL path for the route
215
+ * @returns Method decorator
216
+ */
217
+ exports.Connect = createRouteDecorator('connect');
218
+ /**
219
+ * Decorator that marks a class as a controller with a base path.
220
+ * Used as the entry point for routing configuration.
221
+ *
222
+ * @param basePath - Base URL path for all routes in this controller
223
+ * @returns Class decorator
224
+ *
225
+ * @example
226
+ * ```ts
227
+ * @Controller('/api/users')
228
+ * class UserController {
229
+ * // Controller methods...
230
+ * }
231
+ * ```
232
+ */
233
+ function Controller(basePath) {
234
+ return target => {
235
+ Reflect.defineMetadata('basePath', basePath, target);
236
+ };
237
+ }
238
+ /**
239
+ * Decorator that applies middleware to a controller method.
240
+ * Multiple middlewares can be applied and will execute in order.
241
+ *
242
+ * @param middlewares - Express middleware functions to apply
243
+ * @returns Method decorator
244
+ *
245
+ * @example
246
+ * ```ts
247
+ * @Get('/protected')
248
+ * @Use(authMiddleware, loggingMiddleware)
249
+ * getProtectedResource() {
250
+ * // This route is protected by auth middleware
251
+ * }
252
+ * ```
253
+ */
254
+ function Use(...middlewares) {
255
+ return (target, propertyKey, _descriptor) => {
256
+ const existing = Reflect.getMetadata(MIDDLEWARE_KEY, target, propertyKey) || [];
257
+ Reflect.defineMetadata(MIDDLEWARE_KEY, [...existing, ...middlewares], target, propertyKey);
258
+ };
259
+ }
260
+ /**
261
+ * Factory function that creates parameter decorators.
262
+ *
263
+ * @param type - Parameter type to extract from request
264
+ * @param key - Optional fixed key for extraction
265
+ * @returns Parameter decorator function
266
+ */
267
+ function createParamDecorator(type, key) {
268
+ return (paramKey) => {
269
+ return (target, propertyKey, parameterIndex) => {
270
+ const params = Reflect.getMetadata(PARAMS_KEY, target, propertyKey) || [];
271
+ // Ensure parameters are ordered by index
272
+ params.push({ index: parameterIndex, type, key: paramKey || key });
273
+ params.sort((a, b) => a.index - b.index);
274
+ Reflect.defineMetadata(PARAMS_KEY, params, target, propertyKey);
275
+ };
276
+ };
277
+ }
278
+ /**
279
+ * Decorator that extracts query parameters from request.
280
+ *
281
+ * @param paramKey - Optional key to extract specific query parameter
282
+ * @returns Parameter decorator
283
+ *
284
+ * @example
285
+ * ```ts
286
+ * @Get('/search')
287
+ * search(@Query('term') searchTerm: string) {
288
+ * // searchTerm will contain the value of req.query.term
289
+ * }
290
+ * ```
291
+ */
292
+ exports.Query = createParamDecorator('query');
293
+ /**
294
+ * Decorator that extracts route parameters from request.
295
+ *
296
+ * @param paramKey - Optional key to extract specific route parameter
297
+ * @returns Parameter decorator
298
+ *
299
+ * @example
300
+ * ```ts
301
+ * @Get('/users/:id')
302
+ * getUser(@Param('id') userId: string) {
303
+ * // userId will contain the value of req.params.id
304
+ * }
305
+ * ```
306
+ */
307
+ exports.Param = createParamDecorator('param');
308
+ /**
309
+ * Decorator that extracts body or body property from request.
310
+ *
311
+ * @param paramKey - Optional key to extract specific body property
312
+ * @returns Parameter decorator
313
+ *
314
+ * @example
315
+ * ```ts
316
+ * @Post('/users')
317
+ * createUser(@Body() userData: any) {
318
+ * // userData will contain the entire req.body
319
+ * }
320
+ *
321
+ * @Post('/update')
322
+ * updateName(@Body('name') name: string) {
323
+ * // name will contain the value of req.body.name
324
+ * }
325
+ * ```
326
+ */
327
+ exports.Body = createParamDecorator('body');
328
+ /**
329
+ * Decorator that injects the entire request object.
330
+ *
331
+ * @returns Parameter decorator
332
+ *
333
+ * @example
334
+ * ```ts
335
+ * @Get('/complex')
336
+ * complex(@Req() req: Request) {
337
+ * // Access the full request object
338
+ * console.log(req.headers);
339
+ * }
340
+ * ```
341
+ */
342
+ exports.Req = createParamDecorator('req');
343
+ /**
344
+ * Decorator that injects the response object.
345
+ *
346
+ * @returns Parameter decorator
347
+ *
348
+ * @example
349
+ * ```ts
350
+ * @Get('/custom')
351
+ * custom(@Res() res: Response) {
352
+ * // Direct access to response object
353
+ * return res.status(201).send('Created');
354
+ * }
355
+ * ```
356
+ */
357
+ exports.Res = createParamDecorator('res');
358
+ /**
359
+ * Decorator that sets a custom HTTP status code for a response.
360
+ *
361
+ * @param status - HTTP status code to use
362
+ * @returns Method decorator
363
+ *
364
+ * @example
365
+ * ```ts
366
+ * @Post('/users')
367
+ * @HttpCode(201)
368
+ * createUser(@Body() userData: any) {
369
+ * // Response will have 201 Created status code
370
+ * return { id: '123', ...userData };
371
+ * }
372
+ * ```
373
+ */
374
+ function HttpCode(status) {
375
+ return (target, propertyKey, _descriptor) => {
376
+ Reflect.defineMetadata(HTTP_CODE_KEY, status, target, propertyKey);
377
+ };
378
+ }
379
+ /**
380
+ * Decorator that adds a custom HTTP header to the response.
381
+ *
382
+ * @param header - Header name-value pairs or a single header name and value
383
+ * @param value - Header value if a single header name is provided
384
+ * @returns Method decorator
385
+ *
386
+ * @example
387
+ * ```ts
388
+ * @Get('/data')
389
+ * @Header('Cache-Control', 'max-age=60')
390
+ * getData() {
391
+ * // Response will include the Cache-Control header
392
+ * return { data: '...' };
393
+ * }
394
+ */
395
+ function Header(name, value) {
396
+ return Headers(name, value);
397
+ }
398
+ /**
399
+ * Decorator that adds a custom HTTP headers to the response.
400
+ *
401
+ * @param headers - Header name-value pairs or a single header name and value
402
+ * @param value - Header value if a single header name is provided
403
+ * @returns Method decorator
404
+ *
405
+ * @example
406
+ * ```ts
407
+ * @Get('/data')
408
+ * @Headers('Cache-Control', 'max-age=60')
409
+ * getData() {
410
+ * // Response will include the Cache-Control header
411
+ * return { data: '...' };
412
+ * }
413
+ *
414
+ * @Get('/data/:id')
415
+ * @Headers({
416
+ * 'Cache-Control': 'max-age=60',
417
+ * 'X-Custom-Header': 'custom-value',
418
+ * 'Content-Security-Policy': "default-src 'self'"
419
+ * })
420
+ * getData() {
421
+ * // Response will include all specified headers
422
+ * return { data: '...' };
423
+ * }
424
+ *
425
+ * ```
426
+ */
427
+ function Headers(headers, value) {
428
+ return (target, propertyKey) => {
429
+ const existing = Reflect.getMetadata(HEADER_KEY, target, propertyKey) || {};
430
+ const newHeaders = typeof headers === 'string' ? { [headers]: value } : headers;
431
+ Reflect.defineMetadata(HEADER_KEY, Object.assign(Object.assign({}, existing), newHeaders), target, propertyKey);
432
+ };
433
+ }
434
+ /**
435
+ * Decorator that registers a function to run before route handler execution.
436
+ * Useful for pre-processing or logging.
437
+ *
438
+ * @param fn - Function to execute before the handler
439
+ * @returns Method decorator
440
+ *
441
+ * @example
442
+ * ```ts
443
+ * @Get('/users/:id')
444
+ * @Before((req, res) => console.log(`Accessing user ${req.params.id}`))
445
+ * getUser(@Param('id') id: string) {
446
+ * // Function will log before this handler runs
447
+ * }
448
+ * ```
449
+ */
450
+ function Before(fn) {
451
+ return (target, propertyKey, _descriptor) => {
452
+ const hooks = Reflect.getMetadata(BEFORE_KEY, target, propertyKey) || [];
453
+ hooks.push(fn);
454
+ Reflect.defineMetadata(BEFORE_KEY, hooks, target, propertyKey);
455
+ };
456
+ }
457
+ /**
458
+ * Decorator that registers a function to run after route handler execution.
459
+ * Can access the handler's result.
460
+ *
461
+ * @param fn - Function to execute after the handler
462
+ * @returns Method decorator
463
+ *
464
+ * @example
465
+ * ```ts
466
+ * @Get('/users/:id')
467
+ * @After((req, res, result) => console.log(`User data sent: ${JSON.stringify(result)}`))
468
+ * getUser(@Param('id') id: string) {
469
+ * // After this handler, the function will log the returned data
470
+ * return { id, name: 'Example' };
471
+ * }
472
+ * ```
473
+ */
474
+ function After(fn) {
475
+ return (target, propertyKey, _descriptor) => {
476
+ const hooks = Reflect.getMetadata(AFTER_KEY, target, propertyKey) || [];
477
+ hooks.push(fn);
478
+ Reflect.defineMetadata(AFTER_KEY, hooks, target, propertyKey);
479
+ };
480
+ }
481
+ /**
482
+ * Decorator that requires specific roles for accessing a route.
483
+ * Must be used with authentication middleware.
484
+ *
485
+ * @param roles - List of roles that can access this route
486
+ * @returns Method decorator
487
+ *
488
+ * @example
489
+ * ```ts
490
+ * @Get('/admin/settings')
491
+ * @Roles('admin', 'superuser')
492
+ * getSettings() {
493
+ * // Only admins and superusers can access
494
+ * return { settings: [...] };
495
+ * }
496
+ * ```
497
+ */
498
+ function Roles(...roles) {
499
+ return (target, propertyKey, _descriptor) => {
500
+ Reflect.defineMetadata(ROLES_KEY, roles, target, propertyKey);
501
+ };
502
+ }
503
+ /**
504
+ * Decorator that redirects to another URL.
505
+ *
506
+ * @param url - URL to redirect to (can be absolute or relative)
507
+ * @param statusCode - HTTP status code for redirect (default: 302)
508
+ * @returns Method decorator
509
+ *
510
+ * @example
511
+ * ```ts
512
+ * @Get('/old-path')
513
+ * @Redirect('/new-path', 301)
514
+ * redirectToNewPath() {
515
+ * // This method won't be executed; automatic redirect happens
516
+ * }
517
+ *
518
+ * @Get('/dynamic-redirect')
519
+ * @Redirect()
520
+ * getDynamicRedirect() {
521
+ * // Return an object with url and optionally statusCode
522
+ * return { url: '/calculated-path', statusCode: 307 };
523
+ * }
524
+ * ```
525
+ */
526
+ function Redirect(url, statusCode = 302) {
527
+ return (target, propertyKey, descriptor) => {
528
+ // Store the redirect information in metadata
529
+ Reflect.defineMetadata(REDIRECT_KEY, { url, statusCode }, target, propertyKey);
530
+ return descriptor;
531
+ };
532
+ }
533
+ /**
534
+ * Decorator that adds caching to a route response.
535
+ *
536
+ * @param ttlSeconds - Time to live in seconds for the cache
537
+ * @returns Method decorator
538
+ *
539
+ * @example
540
+ * ```ts
541
+ * @Get('/data')
542
+ * @Cache(300) // Cache for 5 minutes
543
+ * getData() {
544
+ * return { data: 'expensive operation result' };
545
+ * }
546
+ * ```
547
+ */
548
+ function Cache(ttlSeconds) {
549
+ return (target, propertyKey, _descriptor) => {
550
+ Reflect.defineMetadata(CACHE_KEY, { ttlSeconds }, target, propertyKey);
551
+ };
552
+ }
553
+ /**
554
+ * Decorator that applies rate limiting to a route.
555
+ * Note: Requires 'express-rate-limit' package to be installed.
556
+ *
557
+ * @param limit - Maximum number of requests allowed in the window
558
+ * @param windowMs - Time window in milliseconds
559
+ * @returns Method decorator
560
+ *
561
+ * Default Options:
562
+ * - standardHeaders: true
563
+ * - legacyHeaders: false
564
+ *
565
+ * @example
566
+ * ```ts
567
+ * @Post('/login')
568
+ * @RateLimit({ max: 5, windowMs: 60000, standardHeaders: true, legacyHeaders: false }) // 5 requests per minute
569
+ * login(@Body() credentials: LoginDto) {
570
+ * return this.authService.login(credentials);
571
+ * }
572
+ * ```
573
+ */
574
+ function RateLimit(options) {
575
+ const opts = Object.assign({ standardHeaders: true, legacyHeaders: false }, options);
576
+ return (target, propertyKey, _descriptor) => {
577
+ Reflect.defineMetadata(RATE_LIMIT_KEY, opts, target, propertyKey);
578
+ };
579
+ }
580
+ /**
581
+ * Decorator that sets the content type for the response.
582
+ *
583
+ * @param type - MIME type for the response
584
+ * @returns Method decorator
585
+ *
586
+ * @example
587
+ * ```ts
588
+ * @Get('/download')
589
+ * @ContentType('application/pdf')
590
+ * downloadPdf() {
591
+ * return this.fileService.generatePdf();
592
+ * }
593
+ * ```
594
+ */
595
+ function ContentType(type) {
596
+ return (target, propertyKey, _descriptor) => {
597
+ Reflect.defineMetadata(CONTENT_TYPE_KEY, { type }, target, propertyKey);
598
+ };
599
+ }
600
+ /**
601
+ * Decorator that adds API versioning to a route.
602
+ *
603
+ * @param version - Version string for the API endpoint
604
+ * @param options - Versioning options
605
+ * @returns Method decorator
606
+ *
607
+ * Default Options:
608
+ * - addPrefix: true
609
+ * - addHeader: true
610
+ * - headerName: 'X-API-Version'
611
+ *
612
+ * @example
613
+ * ```ts
614
+ *
615
+ * @Get('/users')
616
+ * @Version('v2')
617
+ * getUsersV2() {
618
+ * return this.userService.findAllV2();
619
+ * }
620
+ *
621
+ * @Get('/users')
622
+ * @Version('v2', { addPrefix: true, addHeader: true, headerName: 'X-API-Version' })
623
+ * getUsersV2() {
624
+ * // Route becomes /v2/users
625
+ * return this.userService.findAllV2();
626
+ * }
627
+ * ```
628
+ */
629
+ function Version(version, options) {
630
+ const opts = Object.assign({ addPrefix: true, addHeader: true, headerName: 'X-API-Version' }, options);
631
+ return (target, propertyKey, _descriptor) => {
632
+ Reflect.defineMetadata(VERSION_KEY, { version, options: opts }, target, propertyKey);
633
+ };
634
+ }
635
+ /**
636
+ * Decorator that sets a timeout for route execution.
637
+ *
638
+ * @param ms - Timeout in milliseconds
639
+ * @returns Method decorator
640
+ *
641
+ * @example
642
+ * ```ts
643
+ * @Get('/slow-operation')
644
+ * @Timeout(30000) // 30 second timeout
645
+ * slowOperation() {
646
+ * return this.heavyService.processData();
647
+ * }
648
+ * ```
649
+ */
650
+ function Timeout(ms) {
651
+ return (target, propertyKey, _descriptor) => {
652
+ Reflect.defineMetadata(TIMEOUT_KEY, { ms }, target, propertyKey);
653
+ };
654
+ }
655
+ /**
656
+ * Decorator that adds comprehensive logging to a route.
657
+ *
658
+ * @param options - Logging configuration options
659
+ * @returns Method decorator
660
+ *
661
+ * Default Options:
662
+ * - logEntry: true
663
+ * - logExit: true
664
+ * - logBody: false
665
+ * - logParams: false
666
+ * - logResponse: false
667
+ *
668
+ * @example
669
+ * ```ts
670
+ * @Post('/users')
671
+ * @Log({
672
+ * logEntry: true,
673
+ * logExit: true,
674
+ * logBody: true,
675
+ * logParams: true,
676
+ * logResponse: false
677
+ * })
678
+ * createUser(@Body() userData: any) {
679
+ * return this.userService.create(userData);
680
+ * }
681
+ * ```
682
+ */
683
+ function Log(options) {
684
+ return (target, propertyKey, _descriptor) => {
685
+ const config = Object.assign({ logEntry: true, logExit: true, logBody: false, logParams: false, logResponse: false }, options);
686
+ Reflect.defineMetadata(LOG_KEY, config, target, propertyKey);
687
+ };
688
+ }
689
+ /**
690
+ * Registers all controller classes with the provided router.
691
+ * This function processes all decorators and sets up the Express routes.
692
+ *
693
+ * @param router - Express router instance
694
+ * @param controllers - Array of controller classes
695
+ */
696
+ function registerControllers(router, controllers) {
697
+ controllers.forEach(ControllerClass => {
698
+ const instance = new ControllerClass();
699
+ const basePath = Reflect.getMetadata('basePath', ControllerClass) || '';
700
+ const routes = Reflect.getMetadata(ROUTES_KEY, ControllerClass) || [];
701
+ // Get controller-level decorators (fallback values)
702
+ const controllerRateLimit = Reflect.getMetadata(RATE_LIMIT_KEY, ControllerClass);
703
+ const controllerCache = Reflect.getMetadata(CACHE_KEY, ControllerClass);
704
+ const controllerTimeout = Reflect.getMetadata(TIMEOUT_KEY, ControllerClass);
705
+ const controllerVersion = Reflect.getMetadata(VERSION_KEY, ControllerClass);
706
+ const controllerRoles = Reflect.getMetadata(ROLES_KEY, ControllerClass);
707
+ const controllerLogConfig = Reflect.getMetadata(LOG_KEY, ControllerClass);
708
+ const controllerHeaders = Reflect.getMetadata(HEADER_KEY, ControllerClass) || {};
709
+ routes.forEach(({ path, method, handlerName }) => {
710
+ var _a;
711
+ const middlewares = Reflect.getMetadata(MIDDLEWARE_KEY, instance, handlerName) || [];
712
+ const params = Reflect.getMetadata(PARAMS_KEY, instance, handlerName) || [];
713
+ const httpCode = Reflect.getMetadata(HTTP_CODE_KEY, instance, handlerName);
714
+ // Merge controller-level and method-level headers
715
+ const methodHeaders = Reflect.getMetadata(HEADER_KEY, instance, handlerName) || {};
716
+ const headers = Object.assign(Object.assign({}, controllerHeaders), methodHeaders);
717
+ const beforeHooks = Reflect.getMetadata(BEFORE_KEY, instance, handlerName) || [];
718
+ const afterHooks = Reflect.getMetadata(AFTER_KEY, instance, handlerName) || [];
719
+ const redirect = Reflect.getMetadata(REDIRECT_KEY, instance, handlerName);
720
+ const contentType = Reflect.getMetadata(CONTENT_TYPE_KEY, instance, handlerName);
721
+ // Use method-level decorators if present, otherwise fall back to controller-level
722
+ const roles = Reflect.getMetadata(ROLES_KEY, instance, handlerName) || controllerRoles || [];
723
+ const cache = Reflect.getMetadata(CACHE_KEY, instance, handlerName) || controllerCache;
724
+ const rateLimitOptions = Reflect.getMetadata(RATE_LIMIT_KEY, instance, handlerName) || controllerRateLimit;
725
+ const version = Reflect.getMetadata(VERSION_KEY, instance, handlerName) || controllerVersion;
726
+ const timeout = Reflect.getMetadata(TIMEOUT_KEY, instance, handlerName) || controllerTimeout;
727
+ const logConfig = Reflect.getMetadata(LOG_KEY, instance, handlerName) || controllerLogConfig;
728
+ // Create rate limiter for this specific route if needed
729
+ let rateLimiter = null;
730
+ if (rateLimitOptions) {
731
+ try {
732
+ rateLimiter = rateLimiterCache.get(rateLimitOptions);
733
+ }
734
+ catch (err) {
735
+ (0, logger_utils_1.getLogger)().warn({ err }, 'express-rate-limit not available, skipping rate limiting for this route');
736
+ }
737
+ }
738
+ let finalPath = path;
739
+ if ((_a = version === null || version === void 0 ? void 0 : version.options) === null || _a === void 0 ? void 0 : _a.addPrefix) {
740
+ finalPath = `/${version.version}${path}`;
741
+ }
742
+ const handler = async (req, res, next) => {
743
+ var _a, _b, _c, _d;
744
+ // Set start time for duration tracking
745
+ req['startTime'] = Date.now();
746
+ let timeoutId;
747
+ let timedOut = false;
748
+ try {
749
+ // Handle timeout setup
750
+ if (timeout) {
751
+ timeoutId = setTimeout(() => {
752
+ if (!res.headersSent && !timedOut) {
753
+ timedOut = true;
754
+ const errorResponse = (0, response_utils_1.createFinalErrorResponse)(req, http_status_codes_1.HttpStatusCodes.REQUEST_TIMEOUT, 'Request timed out');
755
+ res.status(http_status_codes_1.HttpStatusCodes.REQUEST_TIMEOUT).json(errorResponse);
756
+ }
757
+ }, timeout.ms);
758
+ }
759
+ if (timedOut)
760
+ return;
761
+ // Handle rate limiting
762
+ if (rateLimiter) {
763
+ await new Promise((resolve, reject) => {
764
+ rateLimiter(req, res, (err) => {
765
+ if (err)
766
+ reject(err);
767
+ else
768
+ resolve();
769
+ });
770
+ });
771
+ }
772
+ // Handle content type
773
+ if (!res.headersSent && contentType) {
774
+ res.setHeader('Content-Type', contentType.type);
775
+ }
776
+ // Handle versioning header
777
+ if (((_a = version === null || version === void 0 ? void 0 : version.options) === null || _a === void 0 ? void 0 : _a.addHeader) && ((_b = version === null || version === void 0 ? void 0 : version.options) === null || _b === void 0 ? void 0 : _b.headerName) && (version === null || version === void 0 ? void 0 : version.version)) {
778
+ if (!res.headersSent) {
779
+ res.setHeader(version.options.headerName, version.version);
780
+ }
781
+ }
782
+ // Handle caching
783
+ if (cache && !res.headersSent) {
784
+ res.setHeader('Cache-Control', `public, max-age=${cache.ttlSeconds}`);
785
+ }
786
+ // Handle logging - entry
787
+ if (logConfig === null || logConfig === void 0 ? void 0 : logConfig.logEntry) {
788
+ const logger = (0, logger_utils_1.getLogger)();
789
+ const logData = {
790
+ method: req.method,
791
+ url: req.originalUrl || req.url,
792
+ userAgent: req.get('User-Agent')
793
+ };
794
+ if (logConfig.logParams) {
795
+ logData.params = req.params;
796
+ logData.query = req.query;
797
+ }
798
+ if (logConfig.logBody)
799
+ logData.body = req.body;
800
+ logger.info({ entry: logData }, 'Route Entry:');
801
+ }
802
+ // Handle roles-based access control
803
+ if (roles.length && !((_d = (_c = req === null || req === void 0 ? void 0 : req.user) === null || _c === void 0 ? void 0 : _c.roles) === null || _d === void 0 ? void 0 : _d.some((role) => roles.includes(role)))) {
804
+ const errorResponse = (0, response_utils_1.createFinalErrorResponse)(req, http_status_codes_1.HttpStatusCodes.FORBIDDEN, 'Forbidden Insufficient Roles');
805
+ res.status(http_status_codes_1.HttpStatusCodes.FORBIDDEN).json(errorResponse);
806
+ if (timeoutId) {
807
+ clearTimeout(timeoutId);
808
+ }
809
+ return;
810
+ }
811
+ // Process static redirect if configured
812
+ if (redirect && redirect.url) {
813
+ if (timeoutId) {
814
+ clearTimeout(timeoutId);
815
+ }
816
+ return res.redirect(redirect.statusCode, redirect.url);
817
+ }
818
+ for (const fn of beforeHooks)
819
+ await fn(req, res);
820
+ const args = [];
821
+ if (params.length) {
822
+ params.forEach(({ index, type, key }) => {
823
+ var _a;
824
+ switch (type) {
825
+ case 'query':
826
+ args[index] = key ? req.query[key] : req.query;
827
+ break;
828
+ case 'param':
829
+ args[index] = key ? req.params[key] : req.params;
830
+ break;
831
+ case 'body':
832
+ args[index] = key ? (_a = req.body) === null || _a === void 0 ? void 0 : _a[key] : req.body;
833
+ break;
834
+ case 'req':
835
+ args[index] = req;
836
+ break;
837
+ case 'res':
838
+ args[index] = res;
839
+ break;
840
+ }
841
+ });
842
+ }
843
+ const result = instance[handlerName](...args);
844
+ // Support both sync and async handlers
845
+ const awaited = result instanceof Promise ? await result : result;
846
+ // Clear timeout if operation completed
847
+ if (timeoutId) {
848
+ clearTimeout(timeoutId);
849
+ }
850
+ if (timedOut)
851
+ return;
852
+ // Handle dynamic redirects
853
+ if (redirect && awaited && typeof awaited === 'object' && 'url' in awaited) {
854
+ const redirectUrl = awaited.url;
855
+ const redirectStatus = awaited.statusCode || redirect.statusCode;
856
+ return res.redirect(redirectStatus, redirectUrl);
857
+ }
858
+ if (!res.headersSent && typeof awaited !== 'undefined') {
859
+ if (httpCode)
860
+ res.status(httpCode);
861
+ for (const [k, v] of Object.entries(headers)) {
862
+ const normalized = normalizeHeaderValue(v);
863
+ if (typeof normalized !== 'undefined') {
864
+ res.set(k, normalized);
865
+ }
866
+ }
867
+ res.json(awaited);
868
+ }
869
+ // Handle logging - exit
870
+ if (logConfig === null || logConfig === void 0 ? void 0 : logConfig.logExit) {
871
+ const logger = (0, logger_utils_1.getLogger)();
872
+ const logData = {
873
+ method: req.method,
874
+ url: req.originalUrl || req.url,
875
+ statusCode: res.statusCode,
876
+ duration: `${Date.now() - req.startTime}ms`
877
+ };
878
+ if (logConfig.logResponse)
879
+ logData.response = awaited;
880
+ logger.info({ exit: logData }, 'Route Exit:');
881
+ }
882
+ for (const fn of afterHooks)
883
+ await fn(req, res, awaited);
884
+ }
885
+ catch (err) {
886
+ if (timeoutId) {
887
+ clearTimeout(timeoutId);
888
+ }
889
+ next(err);
890
+ }
891
+ };
892
+ router[method](basePath + finalPath, ...middlewares, handler);
893
+ });
894
+ });
895
+ }
896
+ //# sourceMappingURL=decorators.utils.js.map