@scpxl/nodejs-framework 1.0.17 → 1.0.19

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 (192) hide show
  1. package/README.md +29 -0
  2. package/dist/api-requester/api-requester.d.ts +27 -6
  3. package/dist/api-requester/api-requester.d.ts.map +1 -1
  4. package/dist/api-requester/api-requester.js +188 -26
  5. package/dist/api-requester/api-requester.js.map +2 -2
  6. package/dist/api-requester/index.d.ts +1 -0
  7. package/dist/api-requester/index.d.ts.map +1 -1
  8. package/dist/api-requester/index.js.map +1 -1
  9. package/dist/application/base-application.d.ts +15 -22
  10. package/dist/application/base-application.d.ts.map +1 -1
  11. package/dist/application/base-application.js +145 -111
  12. package/dist/application/base-application.js.map +2 -2
  13. package/dist/application/command-application.d.ts.map +1 -1
  14. package/dist/application/command-application.js +3 -4
  15. package/dist/application/command-application.js.map +2 -2
  16. package/dist/application/web-application.d.ts.map +1 -1
  17. package/dist/application/web-application.js +9 -2
  18. package/dist/application/web-application.js.map +2 -2
  19. package/dist/cache/manager.d.ts +87 -6
  20. package/dist/cache/manager.d.ts.map +1 -1
  21. package/dist/cache/manager.js +77 -30
  22. package/dist/cache/manager.js.map +2 -2
  23. package/dist/cluster/cluster-manager.d.ts.map +1 -1
  24. package/dist/cluster/cluster-manager.js +5 -8
  25. package/dist/cluster/cluster-manager.js.map +2 -2
  26. package/dist/config/env.d.ts +11 -0
  27. package/dist/config/env.d.ts.map +1 -0
  28. package/dist/config/env.js +103 -0
  29. package/dist/config/env.js.map +7 -0
  30. package/dist/config/index.d.ts +3 -0
  31. package/dist/config/index.d.ts.map +1 -0
  32. package/dist/config/index.js +3 -0
  33. package/dist/config/index.js.map +7 -0
  34. package/dist/config/schema.d.ts +408 -0
  35. package/dist/config/schema.d.ts.map +1 -0
  36. package/dist/config/schema.js +218 -0
  37. package/dist/config/schema.js.map +7 -0
  38. package/dist/database/dynamic-entity.d.ts.map +1 -1
  39. package/dist/database/dynamic-entity.js +6 -2
  40. package/dist/database/dynamic-entity.js.map +2 -2
  41. package/dist/database/instance.d.ts.map +1 -1
  42. package/dist/database/instance.js +0 -8
  43. package/dist/database/instance.js.map +2 -2
  44. package/dist/database/manager.d.ts.map +1 -1
  45. package/dist/database/manager.js +71 -9
  46. package/dist/database/manager.js.map +2 -2
  47. package/dist/error/error-reporter.d.ts +96 -0
  48. package/dist/error/error-reporter.d.ts.map +1 -0
  49. package/dist/error/error-reporter.js +228 -0
  50. package/dist/error/error-reporter.js.map +7 -0
  51. package/dist/error/error.interface.d.ts +126 -0
  52. package/dist/error/error.interface.d.ts.map +1 -0
  53. package/dist/error/error.interface.js +45 -0
  54. package/dist/error/error.interface.js.map +7 -0
  55. package/dist/error/framework-errors.d.ts +113 -0
  56. package/dist/error/framework-errors.d.ts.map +1 -0
  57. package/dist/error/framework-errors.js +176 -0
  58. package/dist/error/framework-errors.js.map +7 -0
  59. package/dist/error/index.d.ts +6 -0
  60. package/dist/error/index.d.ts.map +1 -0
  61. package/dist/error/index.js +34 -0
  62. package/dist/error/index.js.map +7 -0
  63. package/dist/event/manager.d.ts.map +1 -1
  64. package/dist/event/manager.js +2 -9
  65. package/dist/event/manager.js.map +2 -2
  66. package/dist/index.d.ts +5 -1
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +5 -1
  69. package/dist/index.js.map +2 -2
  70. package/dist/lifecycle/exit.d.ts +2 -1
  71. package/dist/lifecycle/exit.d.ts.map +1 -1
  72. package/dist/lifecycle/exit.js +6 -0
  73. package/dist/lifecycle/exit.js.map +2 -2
  74. package/dist/lifecycle/index.d.ts +7 -0
  75. package/dist/lifecycle/index.d.ts.map +1 -0
  76. package/dist/lifecycle/index.js +12 -0
  77. package/dist/lifecycle/index.js.map +7 -0
  78. package/dist/lifecycle/lifecycle-manager.d.ts +55 -2
  79. package/dist/lifecycle/lifecycle-manager.d.ts.map +1 -1
  80. package/dist/lifecycle/lifecycle-manager.js +233 -7
  81. package/dist/lifecycle/lifecycle-manager.js.map +3 -3
  82. package/dist/lifecycle/shutdown-controller.d.ts +15 -0
  83. package/dist/lifecycle/shutdown-controller.d.ts.map +1 -0
  84. package/dist/lifecycle/shutdown-controller.js +38 -0
  85. package/dist/lifecycle/shutdown-controller.js.map +7 -0
  86. package/dist/lifecycle/types.d.ts +28 -0
  87. package/dist/lifecycle/types.d.ts.map +1 -0
  88. package/dist/lifecycle/types.js +13 -0
  89. package/dist/lifecycle/types.js.map +7 -0
  90. package/dist/logger/logger.d.ts +2 -1
  91. package/dist/logger/logger.d.ts.map +1 -1
  92. package/dist/logger/logger.js +35 -11
  93. package/dist/logger/logger.js.map +2 -2
  94. package/dist/performance/cache-performance.d.ts +6 -0
  95. package/dist/performance/cache-performance.d.ts.map +1 -1
  96. package/dist/performance/cache-performance.js +16 -0
  97. package/dist/performance/cache-performance.js.map +2 -2
  98. package/dist/performance/index.d.ts +1 -0
  99. package/dist/performance/index.d.ts.map +1 -1
  100. package/dist/performance/index.js +1 -0
  101. package/dist/performance/index.js.map +2 -2
  102. package/dist/performance/performance-monitor.d.ts.map +1 -1
  103. package/dist/performance/performance-monitor.js +47 -18
  104. package/dist/performance/performance-monitor.js.map +2 -2
  105. package/dist/performance/performance-monitor.plugin.d.ts +24 -0
  106. package/dist/performance/performance-monitor.plugin.d.ts.map +1 -0
  107. package/dist/performance/performance-monitor.plugin.js +89 -0
  108. package/dist/performance/performance-monitor.plugin.js.map +7 -0
  109. package/dist/performance/webserver-performance.js +1 -1
  110. package/dist/performance/webserver-performance.js.map +2 -2
  111. package/dist/queue/manager.d.ts.map +1 -1
  112. package/dist/queue/manager.js +3 -10
  113. package/dist/queue/manager.js.map +2 -2
  114. package/dist/queue/worker.d.ts.map +1 -1
  115. package/dist/queue/worker.js +2 -2
  116. package/dist/queue/worker.js.map +2 -2
  117. package/dist/redis/manager.d.ts.map +1 -1
  118. package/dist/redis/manager.js +228 -33
  119. package/dist/redis/manager.js.map +2 -2
  120. package/dist/request-context/index.d.ts +3 -0
  121. package/dist/request-context/index.d.ts.map +1 -0
  122. package/dist/request-context/index.js +25 -0
  123. package/dist/request-context/index.js.map +7 -0
  124. package/dist/request-context/request-context.d.ts +108 -0
  125. package/dist/request-context/request-context.d.ts.map +1 -0
  126. package/dist/request-context/request-context.interface.d.ts +46 -0
  127. package/dist/request-context/request-context.interface.d.ts.map +1 -0
  128. package/dist/request-context/request-context.interface.js +1 -0
  129. package/dist/request-context/request-context.interface.js.map +7 -0
  130. package/dist/request-context/request-context.js +79 -0
  131. package/dist/request-context/request-context.js.map +7 -0
  132. package/dist/services/aws/s3.js +4 -6
  133. package/dist/services/aws/s3.js.map +2 -2
  134. package/dist/util/file.d.ts +13 -0
  135. package/dist/util/file.d.ts.map +1 -1
  136. package/dist/util/file.js +46 -9
  137. package/dist/util/file.js.map +2 -2
  138. package/dist/util/helper.d.ts +16 -1
  139. package/dist/util/helper.d.ts.map +1 -1
  140. package/dist/util/helper.js +19 -43
  141. package/dist/util/helper.js.map +2 -2
  142. package/dist/util/index.d.ts +1 -0
  143. package/dist/util/index.d.ts.map +1 -1
  144. package/dist/util/index.js +18 -16
  145. package/dist/util/index.js.map +2 -2
  146. package/dist/util/loader.d.ts.map +1 -1
  147. package/dist/util/loader.js +13 -2
  148. package/dist/util/loader.js.map +2 -2
  149. package/dist/util/os.d.ts.map +1 -1
  150. package/dist/util/os.js +8 -14
  151. package/dist/util/os.js.map +2 -2
  152. package/dist/util/time.d.ts +8 -2
  153. package/dist/util/time.d.ts.map +1 -1
  154. package/dist/util/time.js +12 -7
  155. package/dist/util/time.js.map +2 -2
  156. package/dist/util/timing.d.ts +36 -0
  157. package/dist/util/timing.d.ts.map +1 -0
  158. package/dist/util/timing.interface.d.ts +47 -0
  159. package/dist/util/timing.interface.d.ts.map +1 -0
  160. package/dist/util/timing.interface.js +1 -0
  161. package/dist/util/timing.interface.js.map +7 -0
  162. package/dist/util/timing.js +98 -0
  163. package/dist/util/timing.js.map +7 -0
  164. package/dist/util/url.js +1 -1
  165. package/dist/util/url.js.map +2 -2
  166. package/dist/webserver/controller/base.d.ts +3 -1
  167. package/dist/webserver/controller/base.d.ts.map +1 -1
  168. package/dist/webserver/controller/base.interface.d.ts +2 -0
  169. package/dist/webserver/controller/base.interface.d.ts.map +1 -1
  170. package/dist/webserver/controller/base.js +4 -1
  171. package/dist/webserver/controller/base.js.map +2 -2
  172. package/dist/webserver/controller/health.d.ts +8 -1
  173. package/dist/webserver/controller/health.d.ts.map +1 -1
  174. package/dist/webserver/controller/health.js +36 -22
  175. package/dist/webserver/controller/health.js.map +2 -2
  176. package/dist/webserver/webserver.d.ts +16 -2
  177. package/dist/webserver/webserver.d.ts.map +1 -1
  178. package/dist/webserver/webserver.interface.d.ts +37 -0
  179. package/dist/webserver/webserver.interface.d.ts.map +1 -1
  180. package/dist/webserver/webserver.interface.js.map +2 -2
  181. package/dist/webserver/webserver.js +117 -20
  182. package/dist/webserver/webserver.js.map +2 -2
  183. package/dist/websocket/controllers/server/system.d.ts.map +1 -1
  184. package/dist/websocket/controllers/server/system.js.map +2 -2
  185. package/dist/websocket/websocket-base.d.ts.map +1 -1
  186. package/dist/websocket/websocket-base.js +2 -3
  187. package/dist/websocket/websocket-base.js.map +2 -2
  188. package/dist/websocket/websocket-server.d.ts +1 -1
  189. package/dist/websocket/websocket-server.d.ts.map +1 -1
  190. package/dist/websocket/websocket-server.js +7 -31
  191. package/dist/websocket/websocket-server.js.map +2 -2
  192. package/package.json +51 -10
@@ -0,0 +1,98 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+ class TimerInstance {
4
+ static {
5
+ __name(this, "TimerInstance");
6
+ }
7
+ startTime;
8
+ constructor(startTime) {
9
+ this.startTime = startTime;
10
+ }
11
+ stop() {
12
+ return performance.now() - this.startTime;
13
+ }
14
+ elapsed() {
15
+ return performance.now() - this.startTime;
16
+ }
17
+ }
18
+ class Timing {
19
+ static {
20
+ __name(this, "Timing");
21
+ }
22
+ /**
23
+ * Get current high-resolution timestamp in milliseconds.
24
+ * Uses performance.now() which provides sub-millisecond precision.
25
+ */
26
+ static now() {
27
+ return performance.now();
28
+ }
29
+ /**
30
+ * Start a timer and return a Timer instance.
31
+ * Call timer.stop() to get elapsed time in milliseconds.
32
+ */
33
+ static start() {
34
+ return new TimerInstance(performance.now());
35
+ }
36
+ /**
37
+ * Measure the execution time of a function (async or sync).
38
+ * Returns both the function result and timing information.
39
+ */
40
+ static async measure(fn, options = {}) {
41
+ const startTime = performance.now();
42
+ const result = await fn();
43
+ const endTime = performance.now();
44
+ const duration = endTime - startTime;
45
+ if (options.log) {
46
+ const name = options.name ?? "Anonymous function";
47
+ const message = `${name} executed`;
48
+ if (options.logger) {
49
+ options.logger(message, duration);
50
+ } else {
51
+ console.log(`${message} in ${duration.toFixed(3)}ms`);
52
+ }
53
+ }
54
+ return {
55
+ result,
56
+ duration,
57
+ startTime,
58
+ endTime
59
+ };
60
+ }
61
+ /**
62
+ * Measure the execution time of a synchronous function.
63
+ * Returns both the function result and timing information.
64
+ */
65
+ static measureSync(fn, options = {}) {
66
+ const startTime = performance.now();
67
+ const result = fn();
68
+ const endTime = performance.now();
69
+ const duration = endTime - startTime;
70
+ if (options.log) {
71
+ const name = options.name ?? "Anonymous function";
72
+ const message = `${name} executed`;
73
+ if (options.logger) {
74
+ options.logger(message, duration);
75
+ } else {
76
+ console.log(`${message} in ${duration.toFixed(3)}ms`);
77
+ }
78
+ }
79
+ return {
80
+ result,
81
+ duration,
82
+ startTime,
83
+ endTime
84
+ };
85
+ }
86
+ /**
87
+ * Calculate duration between two timestamps in milliseconds.
88
+ * Both timestamps should be from performance.now().
89
+ */
90
+ static duration(startTime, endTime) {
91
+ return endTime - startTime;
92
+ }
93
+ }
94
+ var timing_default = Timing;
95
+ export {
96
+ timing_default as default
97
+ };
98
+ //# sourceMappingURL=timing.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/util/timing.ts"],
4
+ "sourcesContent": ["import type { MeasureOptions, Timer, TimingResult } from './timing.interface.js';\n\n/**\n * Timer instance implementation using performance.now()\n */\nclass TimerInstance implements Timer {\n public readonly startTime: number;\n\n constructor(startTime: number) {\n this.startTime = startTime;\n }\n\n stop(): number {\n return performance.now() - this.startTime;\n }\n\n elapsed(): number {\n return performance.now() - this.startTime;\n }\n}\n\n/**\n * Modern high-resolution timing utility using performance.now()\n *\n * Provides simple APIs for measuring function execution time and manual timing.\n * All durations are returned in milliseconds with decimal precision.\n */\nclass Timing {\n /**\n * Get current high-resolution timestamp in milliseconds.\n * Uses performance.now() which provides sub-millisecond precision.\n */\n static now(): number {\n return performance.now();\n }\n\n /**\n * Start a timer and return a Timer instance.\n * Call timer.stop() to get elapsed time in milliseconds.\n */\n static start(): Timer {\n return new TimerInstance(performance.now());\n }\n\n /**\n * Measure the execution time of a function (async or sync).\n * Returns both the function result and timing information.\n */\n static async measure<T>(fn: () => T | Promise<T>, options: MeasureOptions = {}): Promise<TimingResult<T>> {\n const startTime = performance.now();\n const result = await fn();\n const endTime = performance.now();\n const duration = endTime - startTime;\n\n if (options.log) {\n const name = options.name ?? 'Anonymous function';\n const message = `${name} executed`;\n if (options.logger) {\n options.logger(message, duration);\n } else {\n console.log(`${message} in ${duration.toFixed(3)}ms`);\n }\n }\n\n return {\n result,\n duration,\n startTime,\n endTime,\n };\n }\n\n /**\n * Measure the execution time of a synchronous function.\n * Returns both the function result and timing information.\n */\n static measureSync<T>(fn: () => T, options: MeasureOptions = {}): TimingResult<T> {\n const startTime = performance.now();\n const result = fn();\n const endTime = performance.now();\n const duration = endTime - startTime;\n\n if (options.log) {\n const name = options.name ?? 'Anonymous function';\n const message = `${name} executed`;\n if (options.logger) {\n options.logger(message, duration);\n } else {\n console.log(`${message} in ${duration.toFixed(3)}ms`);\n }\n }\n\n return {\n result,\n duration,\n startTime,\n endTime,\n };\n }\n\n /**\n * Calculate duration between two timestamps in milliseconds.\n * Both timestamps should be from performance.now().\n */\n static duration(startTime: number, endTime: number): number {\n return endTime - startTime;\n }\n}\n\nexport default Timing;\n"],
5
+ "mappings": ";;AAKA,MAAM,cAA+B;AAAA,EALrC,OAKqC;AAAA;AAAA;AAAA,EACnB;AAAA,EAEhB,YAAY,WAAmB;AAC7B,SAAK,YAAY;AAAA,EACnB;AAAA,EAEA,OAAe;AACb,WAAO,YAAY,IAAI,IAAI,KAAK;AAAA,EAClC;AAAA,EAEA,UAAkB;AAChB,WAAO,YAAY,IAAI,IAAI,KAAK;AAAA,EAClC;AACF;AAQA,MAAM,OAAO;AAAA,EA3Bb,OA2Ba;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAKX,OAAO,MAAc;AACnB,WAAO,YAAY,IAAI;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,QAAe;AACpB,WAAO,IAAI,cAAc,YAAY,IAAI,CAAC;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,aAAa,QAAW,IAA0B,UAA0B,CAAC,GAA6B;AACxG,UAAM,YAAY,YAAY,IAAI;AAClC,UAAM,SAAS,MAAM,GAAG;AACxB,UAAM,UAAU,YAAY,IAAI;AAChC,UAAM,WAAW,UAAU;AAE3B,QAAI,QAAQ,KAAK;AACf,YAAM,OAAO,QAAQ,QAAQ;AAC7B,YAAM,UAAU,GAAG,IAAI;AACvB,UAAI,QAAQ,QAAQ;AAClB,gBAAQ,OAAO,SAAS,QAAQ;AAAA,MAClC,OAAO;AACL,gBAAQ,IAAI,GAAG,OAAO,OAAO,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,MACtD;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,YAAe,IAAa,UAA0B,CAAC,GAAoB;AAChF,UAAM,YAAY,YAAY,IAAI;AAClC,UAAM,SAAS,GAAG;AAClB,UAAM,UAAU,YAAY,IAAI;AAChC,UAAM,WAAW,UAAU;AAE3B,QAAI,QAAQ,KAAK;AACf,YAAM,OAAO,QAAQ,QAAQ;AAC7B,YAAM,UAAU,GAAG,IAAI;AACvB,UAAI,QAAQ,QAAQ;AAClB,gBAAQ,OAAO,SAAS,QAAQ;AAAA,MAClC,OAAO;AACL,gBAAQ,IAAI,GAAG,OAAO,OAAO,SAAS,QAAQ,CAAC,CAAC,IAAI;AAAA,MACtD;AAAA,IACF;AAEA,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,SAAS,WAAmB,SAAyB;AAC1D,WAAO,UAAU;AAAA,EACnB;AACF;AAEA,IAAO,iBAAQ;",
6
+ "names": []
7
+ }
package/dist/util/url.js CHANGED
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
  const buildQueryString = /* @__PURE__ */ __name((params) => {
4
- return Object.keys(params).filter((key) => params[key] !== void 0 && params[key] !== "").map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`).join("&");
4
+ return Object.entries(params).filter(([, value]) => value !== void 0 && value !== "").map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`).join("&");
5
5
  }, "buildQueryString");
6
6
  var url_default = {
7
7
  buildQueryString
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/util/url.ts"],
4
- "sourcesContent": ["const buildQueryString = (params: { [key: string]: string | number | boolean }): string => {\n return Object.keys(params)\n .filter(key => params[key] !== undefined && params[key] !== '')\n .map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)\n .join('&');\n};\n\nexport default {\n buildQueryString,\n};\n"],
5
- "mappings": ";;AAAA,MAAM,mBAAmB,wBAAC,WAAiE;AACzF,SAAO,OAAO,KAAK,MAAM,EACtB,OAAO,SAAO,OAAO,GAAG,MAAM,UAAa,OAAO,GAAG,MAAM,EAAE,EAC7D,IAAI,SAAO,GAAG,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,OAAO,GAAG,CAAC,CAAC,EAAE,EAC1E,KAAK,GAAG;AACb,GALyB;AAOzB,IAAO,cAAQ;AAAA,EACb;AACF;",
4
+ "sourcesContent": ["const buildQueryString = (params: { [key: string]: string | number | boolean }): string => {\n return Object.entries(params)\n .filter(([, value]) => value !== undefined && value !== '')\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)\n .join('&');\n};\n\nexport default {\n buildQueryString,\n};\n"],
5
+ "mappings": ";;AAAA,MAAM,mBAAmB,wBAAC,WAAiE;AACzF,SAAO,OAAO,QAAQ,MAAM,EACzB,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,UAAU,UAAa,UAAU,EAAE,EACzD,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,GAAG,mBAAmB,GAAG,CAAC,IAAI,mBAAmB,OAAO,KAAK,CAAC,CAAC,EAAE,EACvF,KAAK,GAAG;AACb,GALyB;AAOzB,IAAO,cAAQ;AAAA,EACb;AACF;",
6
6
  "names": []
7
7
  }
@@ -7,6 +7,7 @@ import type { ApiError, ApiResponse, WebServerBaseControllerConstructorParams }
7
7
  import type { ApplicationConfig } from '../../application/base-application.interface.js';
8
8
  import type EventManager from '../../event/manager.js';
9
9
  import type { WebServerOptions } from '../webserver.interface.js';
10
+ import type { LifecycleManager } from '../../lifecycle/lifecycle-manager.js';
10
11
  export interface AuthenticatedUser {
11
12
  userId: number;
12
13
  payload: any;
@@ -19,7 +20,8 @@ export default abstract class BaseController {
19
20
  protected queueManager: QueueManager;
20
21
  protected eventManager: EventManager;
21
22
  protected databaseInstance: DatabaseInstance;
22
- constructor({ applicationConfig, webServerOptions, redisInstance, queueManager, eventManager, databaseInstance, }: WebServerBaseControllerConstructorParams);
23
+ protected lifecycleManager: LifecycleManager;
24
+ constructor({ applicationConfig, webServerOptions, redisInstance, queueManager, eventManager, databaseInstance, lifecycleManager, }: WebServerBaseControllerConstructorParams);
23
25
  protected sendSuccessResponse<T = any>({ reply, data, statusCode, meta, }: {
24
26
  reply: FastifyReply;
25
27
  data: T;
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/webserver/controller/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,wCAAwC,EAAE,MAAM,qBAAqB,CAAC;AAE3G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,KAAK,YAAY,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAIlE,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,GAAG,CAAC;CACd;AAED,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,cAAc;IAC1C,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAEvC,SAAS,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAC/C,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAE7C,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IACvC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC;IACrC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC;IACrC,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;gBAEjC,EACV,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,gBAAgB,GACjB,EAAE,wCAAwC;IAY3C,SAAS,CAAC,mBAAmB,CAAC,CAAC,GAAG,GAAG,EAAE,EACrC,KAAK,EACL,IAAI,EACJ,UAA2B,EAC3B,IAAI,GACL,EAAE;QACD,KAAK,EAAE,YAAY,CAAC;QACpB,IAAI,EAAE,CAAC,CAAC;QACR,UAAU,CAAC,EAAE,WAAW,CAAC;QACzB,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;KAC/B;IAYD,SAAS,CAAC,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,GAAE,MAA6B;IAW1F,SAAS,CAAC,iBAAiB,CAAC,EAC1B,KAAK,EACL,KAAK,EACL,UAAoC,EACpC,SAAS,GACV,EAAE;QACD,KAAK,EAAE,YAAY,CAAC;QACpB,KAAK,EAAE,OAAO,CAAC;QACf,UAAU,CAAC,EAAE,WAAW,CAAC;QACzB,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;KAC9B;IA6CD,OAAO,CAAC,YAAY;cAoBJ,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CAwErH"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/webserver/controller/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,wCAAwC,EAAE,MAAM,qBAAqB,CAAC;AAE3G,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,KAAK,YAAY,MAAM,wBAAwB,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAG7E,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,GAAG,CAAC;CACd;AAED,MAAM,CAAC,OAAO,CAAC,QAAQ,OAAO,cAAc;IAC1C,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAEvC,SAAS,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;IAC/C,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAE7C,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC;IACvC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC;IACrC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC;IACrC,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC7C,SAAS,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;gBAEjC,EACV,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,GACjB,EAAE,wCAAwC;IAa3C,SAAS,CAAC,mBAAmB,CAAC,CAAC,GAAG,GAAG,EAAE,EACrC,KAAK,EACL,IAAI,EACJ,UAA2B,EAC3B,IAAI,GACL,EAAE;QACD,KAAK,EAAE,YAAY,CAAC;QACpB,IAAI,EAAE,CAAC,CAAC;QACR,UAAU,CAAC,EAAE,WAAW,CAAC;QACzB,IAAI,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;KAC/B;IAYD,SAAS,CAAC,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,GAAE,MAA6B;IAW1F,SAAS,CAAC,iBAAiB,CAAC,EAC1B,KAAK,EACL,KAAK,EACL,UAAoC,EACpC,SAAS,GACV,EAAE;QACD,KAAK,EAAE,YAAY,CAAC;QACpB,KAAK,EAAE,OAAO,CAAC;QACf,UAAU,CAAC,EAAE,WAAW,CAAC;QACzB,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;KAC9B;IA6CD,OAAO,CAAC,YAAY;cAoBJ,mBAAmB,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;CAwErH"}
@@ -5,6 +5,7 @@ import type { QueueManager } from '../../queue/index.js';
5
5
  import type { RedisInstance } from '../../redis/index.js';
6
6
  import type { WebServerOptions } from '../webserver.interface.js';
7
7
  import type WebServerBaseController from './base.js';
8
+ import type { LifecycleManager } from '../../lifecycle/lifecycle-manager.js';
8
9
  export interface WebServerBaseControllerConstructorParams {
9
10
  applicationConfig: ApplicationConfig;
10
11
  webServerOptions: WebServerOptions;
@@ -12,6 +13,7 @@ export interface WebServerBaseControllerConstructorParams {
12
13
  queueManager: QueueManager;
13
14
  eventManager: EventManager;
14
15
  databaseInstance: DatabaseInstance;
16
+ lifecycleManager: LifecycleManager;
15
17
  }
16
18
  export type WebServerBaseControllerType = new (params: WebServerBaseControllerConstructorParams) => WebServerBaseController;
17
19
  export interface ApiResponse<T = any> {
@@ -1 +1 @@
1
- {"version":3,"file":"base.interface.d.ts","sourceRoot":"","sources":["../../../src/webserver/controller/base.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,YAAY,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,uBAAuB,MAAM,WAAW,CAAC;AAErD,MAAM,WAAW,wCAAwC;IACvD,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,gBAAgB,EAAE,gBAAgB,CAAC;IAEnC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED,MAAM,MAAM,2BAA2B,GAAG,KACxC,MAAM,EAAE,wCAAwC,KAC7C,uBAAuB,CAAC;AAE7B,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,EAAE;QACL,UAAU,CAAC,EAAE;YACX,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,GAAG,gBAAgB,GAAG,eAAe,GAAG,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC;IACxG,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CAC5B"}
1
+ {"version":3,"file":"base.interface.d.ts","sourceRoot":"","sources":["../../../src/webserver/controller/base.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AACzF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,YAAY,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,uBAAuB,MAAM,WAAW,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,MAAM,WAAW,wCAAwC;IACvD,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,gBAAgB,EAAE,gBAAgB,CAAC;IAEnC,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;IAC3B,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,gBAAgB,EAAE,gBAAgB,CAAC;CACpC;AAED,MAAM,MAAM,2BAA2B,GAAG,KACxC,MAAM,EAAE,wCAAwC,KAC7C,uBAAuB,CAAC;AAE7B,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,IAAI,CAAC,EAAE;QACL,UAAU,CAAC,EAAE;YACX,IAAI,EAAE,MAAM,CAAC;YACb,KAAK,EAAE,MAAM,CAAC;YACd,KAAK,EAAE,MAAM,CAAC;YACd,UAAU,EAAE,MAAM,CAAC;SACpB,CAAC;QACF,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,GAAG,gBAAgB,GAAG,eAAe,GAAG,WAAW,GAAG,cAAc,GAAG,cAAc,CAAC;IACxG,OAAO,CAAC,EAAE,GAAG,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CAC5B"}
@@ -15,13 +15,15 @@ class BaseController {
15
15
  queueManager;
16
16
  eventManager;
17
17
  databaseInstance;
18
+ lifecycleManager;
18
19
  constructor({
19
20
  applicationConfig,
20
21
  webServerOptions,
21
22
  redisInstance,
22
23
  queueManager,
23
24
  eventManager,
24
- databaseInstance
25
+ databaseInstance,
26
+ lifecycleManager
25
27
  }) {
26
28
  this.workerId = cluster.worker?.id;
27
29
  this.applicationConfig = applicationConfig;
@@ -30,6 +32,7 @@ class BaseController {
30
32
  this.queueManager = queueManager;
31
33
  this.eventManager = eventManager;
32
34
  this.databaseInstance = databaseInstance;
35
+ this.lifecycleManager = lifecycleManager;
33
36
  }
34
37
  sendSuccessResponse({
35
38
  reply,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/webserver/controller/base.ts"],
4
- "sourcesContent": ["import { StatusCodes } from 'http-status-codes';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport type { DatabaseInstance } from '../../database/index.js';\nimport type { RedisInstance } from '../../redis/index.js';\nimport type { QueueManager } from '../../queue/index.js';\nimport type { ApiError, ApiResponse, WebServerBaseControllerConstructorParams } from './base.interface.js';\nimport { Logger } from '../../logger/index.js';\nimport type { ApplicationConfig } from '../../application/base-application.interface.js';\nimport type EventManager from '../../event/manager.js';\nimport cluster from 'cluster';\nimport type { WebServerOptions } from '../webserver.interface.js';\nimport Jwt from '../../auth/jwt.js';\n// import { env } from '../../env';\n\nexport interface AuthenticatedUser {\n userId: number;\n payload: any;\n}\n\nexport default abstract class BaseController {\n protected workerId: number | undefined;\n\n protected applicationConfig: ApplicationConfig;\n protected webServerOptions: WebServerOptions;\n\n protected redisInstance: RedisInstance;\n protected queueManager: QueueManager;\n protected eventManager: EventManager;\n protected databaseInstance: DatabaseInstance;\n\n constructor({\n applicationConfig,\n webServerOptions,\n redisInstance,\n queueManager,\n eventManager,\n databaseInstance,\n }: WebServerBaseControllerConstructorParams) {\n this.workerId = cluster.worker?.id;\n\n this.applicationConfig = applicationConfig;\n this.webServerOptions = webServerOptions;\n\n this.redisInstance = redisInstance;\n this.queueManager = queueManager;\n this.eventManager = eventManager;\n this.databaseInstance = databaseInstance;\n }\n\n protected sendSuccessResponse<T = any>({\n reply,\n data,\n statusCode = StatusCodes.OK,\n meta,\n }: {\n reply: FastifyReply;\n data: T;\n statusCode?: StatusCodes;\n meta?: ApiResponse<T>['meta'];\n }) {\n const response: ApiResponse<T> = {\n data,\n meta: {\n timestamp: new Date().toISOString(),\n requestId: reply.request.id || 'unknown',\n ...meta,\n },\n };\n reply.status(statusCode).send(response);\n }\n\n protected sendNotFoundResponse(reply: FastifyReply, message: string = 'Resource not found') {\n const error: ApiError = {\n message,\n type: 'not_found',\n timestamp: new Date().toISOString(),\n requestId: reply.request.id || 'unknown',\n };\n const response: ApiResponse = { error };\n reply.status(StatusCodes.NOT_FOUND).send(response);\n }\n\n protected sendErrorResponse({\n reply,\n error,\n statusCode = StatusCodes.BAD_REQUEST,\n errorType,\n }: {\n reply: FastifyReply;\n error: unknown;\n statusCode?: StatusCodes;\n errorType?: ApiError['type'];\n }) {\n let publicErrorMessage: string;\n let errorDetails: any = undefined;\n\n if (this.webServerOptions.errors?.verbose === true) {\n if (error instanceof Error) {\n publicErrorMessage = error.stack ?? error.message;\n errorDetails = { stack: error.stack, name: error.name };\n } else {\n publicErrorMessage = String(error);\n }\n } else {\n if (process.env.NODE_ENV === 'production') {\n if (error instanceof Error) {\n publicErrorMessage = 'Something went wrong';\n } else if (typeof error === 'string') {\n publicErrorMessage = error;\n } else {\n publicErrorMessage = 'An unknown error occurred';\n }\n } else {\n if (error instanceof Error) {\n publicErrorMessage = error.stack ?? error.message;\n errorDetails = { stack: error.stack, name: error.name };\n } else {\n publicErrorMessage = String(error);\n }\n }\n }\n\n Logger.custom({ level: 'webServer', message: error });\n console.error(error);\n\n const apiError: ApiError = {\n message: publicErrorMessage,\n type: errorType ?? this.getErrorType(statusCode),\n timestamp: new Date().toISOString(),\n requestId: reply.request.id || 'unknown',\n ...(errorDetails && { details: errorDetails }),\n };\n\n const response: ApiResponse = { error: apiError };\n reply.status(statusCode).send(response);\n }\n\n private getErrorType(statusCode: StatusCodes): ApiError['type'] {\n switch (statusCode) {\n case StatusCodes.UNAUTHORIZED:\n return 'authentication';\n case StatusCodes.FORBIDDEN:\n return 'authorization';\n case StatusCodes.NOT_FOUND:\n return 'not_found';\n case StatusCodes.BAD_REQUEST:\n case StatusCodes.UNPROCESSABLE_ENTITY:\n return 'validation';\n case StatusCodes.INTERNAL_SERVER_ERROR:\n case StatusCodes.BAD_GATEWAY:\n case StatusCodes.SERVICE_UNAVAILABLE:\n return 'server_error';\n default:\n return 'client_error';\n }\n }\n\n protected async authenticateRequest(request: FastifyRequest, reply: FastifyReply): Promise<AuthenticatedUser | null> {\n // Get JWT secret key from application config\n const jwtSecretKey = this.applicationConfig.auth?.jwtSecretKey;\n\n if (!jwtSecretKey) {\n this.sendErrorResponse({\n reply,\n error: 'Authentication not configured.',\n statusCode: StatusCodes.INTERNAL_SERVER_ERROR,\n errorType: 'server_error',\n });\n return null;\n }\n\n const authHeader = request.headers.authorization;\n\n if (!authHeader) {\n this.sendErrorResponse({\n reply,\n error: 'No token provided.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n\n if (!authHeader.startsWith('Bearer ')) {\n this.sendErrorResponse({\n reply,\n error: 'Invalid token.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n\n try {\n const importedJwtSecretKey = await Jwt.importJwtSecretKey({\n jwtSecretKey,\n });\n\n // Remove \"Bearer \" from token\n const jwtAccessToken = authHeader.substring(7);\n\n const { payload } = await Jwt.jwtVerify(jwtAccessToken, importedJwtSecretKey);\n\n if (!payload.sub) {\n this.sendErrorResponse({\n reply,\n error: 'Invalid token payload.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n\n const userId = parseInt(payload.sub);\n\n return {\n userId,\n payload,\n };\n } catch {\n this.sendErrorResponse({\n reply,\n error: 'Invalid or expired token.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { StatusCodes } from 'http-status-codes';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport type { DatabaseInstance } from '../../database/index.js';\nimport type { RedisInstance } from '../../redis/index.js';\nimport type { QueueManager } from '../../queue/index.js';\nimport type { ApiError, ApiResponse, WebServerBaseControllerConstructorParams } from './base.interface.js';\nimport { Logger } from '../../logger/index.js';\nimport type { ApplicationConfig } from '../../application/base-application.interface.js';\nimport type EventManager from '../../event/manager.js';\nimport cluster from 'cluster';\nimport type { WebServerOptions } from '../webserver.interface.js';\nimport type { LifecycleManager } from '../../lifecycle/lifecycle-manager.js';\nimport Jwt from '../../auth/jwt.js';\n\nexport interface AuthenticatedUser {\n userId: number;\n payload: any;\n}\n\nexport default abstract class BaseController {\n protected workerId: number | undefined;\n\n protected applicationConfig: ApplicationConfig;\n protected webServerOptions: WebServerOptions;\n\n protected redisInstance: RedisInstance;\n protected queueManager: QueueManager;\n protected eventManager: EventManager;\n protected databaseInstance: DatabaseInstance;\n protected lifecycleManager: LifecycleManager;\n\n constructor({\n applicationConfig,\n webServerOptions,\n redisInstance,\n queueManager,\n eventManager,\n databaseInstance,\n lifecycleManager,\n }: WebServerBaseControllerConstructorParams) {\n this.workerId = cluster.worker?.id;\n\n this.applicationConfig = applicationConfig;\n this.webServerOptions = webServerOptions;\n\n this.redisInstance = redisInstance;\n this.queueManager = queueManager;\n this.eventManager = eventManager;\n this.databaseInstance = databaseInstance;\n this.lifecycleManager = lifecycleManager;\n }\n\n protected sendSuccessResponse<T = any>({\n reply,\n data,\n statusCode = StatusCodes.OK,\n meta,\n }: {\n reply: FastifyReply;\n data: T;\n statusCode?: StatusCodes;\n meta?: ApiResponse<T>['meta'];\n }) {\n const response: ApiResponse<T> = {\n data,\n meta: {\n timestamp: new Date().toISOString(),\n requestId: reply.request.id || 'unknown',\n ...meta,\n },\n };\n reply.status(statusCode).send(response);\n }\n\n protected sendNotFoundResponse(reply: FastifyReply, message: string = 'Resource not found') {\n const error: ApiError = {\n message,\n type: 'not_found',\n timestamp: new Date().toISOString(),\n requestId: reply.request.id || 'unknown',\n };\n const response: ApiResponse = { error };\n reply.status(StatusCodes.NOT_FOUND).send(response);\n }\n\n protected sendErrorResponse({\n reply,\n error,\n statusCode = StatusCodes.BAD_REQUEST,\n errorType,\n }: {\n reply: FastifyReply;\n error: unknown;\n statusCode?: StatusCodes;\n errorType?: ApiError['type'];\n }) {\n let publicErrorMessage: string;\n let errorDetails: any = undefined;\n\n if (this.webServerOptions.errors?.verbose === true) {\n if (error instanceof Error) {\n publicErrorMessage = error.stack ?? error.message;\n errorDetails = { stack: error.stack, name: error.name };\n } else {\n publicErrorMessage = String(error);\n }\n } else {\n if (process.env.NODE_ENV === 'production') {\n if (error instanceof Error) {\n publicErrorMessage = 'Something went wrong';\n } else if (typeof error === 'string') {\n publicErrorMessage = error;\n } else {\n publicErrorMessage = 'An unknown error occurred';\n }\n } else {\n if (error instanceof Error) {\n publicErrorMessage = error.stack ?? error.message;\n errorDetails = { stack: error.stack, name: error.name };\n } else {\n publicErrorMessage = String(error);\n }\n }\n }\n\n Logger.custom({ level: 'webServer', message: error });\n console.error(error);\n\n const apiError: ApiError = {\n message: publicErrorMessage,\n type: errorType ?? this.getErrorType(statusCode),\n timestamp: new Date().toISOString(),\n requestId: reply.request.id || 'unknown',\n ...(errorDetails && { details: errorDetails }),\n };\n\n const response: ApiResponse = { error: apiError };\n reply.status(statusCode).send(response);\n }\n\n private getErrorType(statusCode: StatusCodes): ApiError['type'] {\n switch (statusCode) {\n case StatusCodes.UNAUTHORIZED:\n return 'authentication';\n case StatusCodes.FORBIDDEN:\n return 'authorization';\n case StatusCodes.NOT_FOUND:\n return 'not_found';\n case StatusCodes.BAD_REQUEST:\n case StatusCodes.UNPROCESSABLE_ENTITY:\n return 'validation';\n case StatusCodes.INTERNAL_SERVER_ERROR:\n case StatusCodes.BAD_GATEWAY:\n case StatusCodes.SERVICE_UNAVAILABLE:\n return 'server_error';\n default:\n return 'client_error';\n }\n }\n\n protected async authenticateRequest(request: FastifyRequest, reply: FastifyReply): Promise<AuthenticatedUser | null> {\n // Get JWT secret key from application config\n const jwtSecretKey = this.applicationConfig.auth?.jwtSecretKey;\n\n if (!jwtSecretKey) {\n this.sendErrorResponse({\n reply,\n error: 'Authentication not configured.',\n statusCode: StatusCodes.INTERNAL_SERVER_ERROR,\n errorType: 'server_error',\n });\n return null;\n }\n\n const authHeader = request.headers.authorization;\n\n if (!authHeader) {\n this.sendErrorResponse({\n reply,\n error: 'No token provided.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n\n if (!authHeader.startsWith('Bearer ')) {\n this.sendErrorResponse({\n reply,\n error: 'Invalid token.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n\n try {\n const importedJwtSecretKey = await Jwt.importJwtSecretKey({\n jwtSecretKey,\n });\n\n // Remove \"Bearer \" from token\n const jwtAccessToken = authHeader.substring(7);\n\n const { payload } = await Jwt.jwtVerify(jwtAccessToken, importedJwtSecretKey);\n\n if (!payload.sub) {\n this.sendErrorResponse({\n reply,\n error: 'Invalid token payload.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n\n const userId = parseInt(payload.sub);\n\n return {\n userId,\n payload,\n };\n } catch {\n this.sendErrorResponse({\n reply,\n error: 'Invalid or expired token.',\n statusCode: StatusCodes.UNAUTHORIZED,\n errorType: 'authentication',\n });\n return null;\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,7 +1,14 @@
1
1
  import type { FastifyReply, FastifyRequest } from 'fastify';
2
2
  import BaseController from './base.js';
3
3
  export default class HealthController extends BaseController {
4
- health: (_: FastifyRequest, reply: FastifyReply) => Promise<void>;
4
+ /**
5
+ * Liveness probe: process is up and not in stopping phase.
6
+ */
7
+ live: (_: FastifyRequest, reply: FastifyReply) => Promise<void>;
8
+ /**
9
+ * Readiness probe: service dependencies are available & lifecycle is RUNNING with aggregated readiness.
10
+ */
11
+ ready: (_: FastifyRequest, reply: FastifyReply) => Promise<void>;
5
12
  private checkDatabaseConnection;
6
13
  private checkRedisConnection;
7
14
  }
@@ -1 +1 @@
1
- {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../../src/webserver/controller/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,cAAc,MAAM,WAAW,CAAC;AAEvC,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,cAAc;IACnD,MAAM,GAAU,GAAG,cAAc,EAAE,OAAO,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC,CA4B3E;YAEY,uBAAuB;YAQvB,oBAAoB;CAOnC"}
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../../src/webserver/controller/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,cAAc,MAAM,WAAW,CAAC;AAGvC,MAAM,CAAC,OAAO,OAAO,gBAAiB,SAAQ,cAAc;IAC1D;;OAEG;IACI,IAAI,GAAU,GAAG,cAAc,EAAE,OAAO,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC,CAQzE;IAEF;;OAEG;IACI,KAAK,GAAU,GAAG,cAAc,EAAE,OAAO,YAAY,KAAG,OAAO,CAAC,IAAI,CAAC,CA6B1E;YAEY,uBAAuB;YAQvB,oBAAoB;CAOnC"}
@@ -1,34 +1,48 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
  import BaseController from "./base.js";
4
+ import { LifecyclePhase } from "../../lifecycle/types.js";
4
5
  class HealthController extends BaseController {
5
6
  static {
6
7
  __name(this, "HealthController");
7
8
  }
8
- health = /* @__PURE__ */ __name(async (_, reply) => {
9
- try {
10
- const healthCheckPromises = [this.checkDatabaseConnection(), this.checkRedisConnection()];
11
- const results = await Promise.all(
12
- healthCheckPromises.map((healthCheckPromise) => healthCheckPromise.catch((error) => error))
13
- );
14
- const isDatabaseHealthy = results[0] === true;
15
- const isRedisHealthy = results[1] === true;
16
- const isAllHealthy = results.every((result) => result === true);
17
- reply.send({
18
- healthy: isAllHealthy,
19
- services: {
20
- database: { healthy: isDatabaseHealthy },
21
- redis: { healthy: isRedisHealthy }
22
- // queue: { activeItems: activeQueueItems },
23
- }
24
- });
25
- } catch (error) {
26
- reply.status(500).send({
27
- healthy: false,
28
- error: error.message
9
+ /**
10
+ * Liveness probe: process is up and not in stopping phase.
11
+ */
12
+ live = /* @__PURE__ */ __name(async (_, reply) => {
13
+ const phase = this.lifecycleManager.phase;
14
+ const shuttingDown = phase === LifecyclePhase.STOPPING || phase === LifecyclePhase.STOPPED;
15
+ if (shuttingDown) {
16
+ reply.code(503).send({ live: false, phase });
17
+ return;
18
+ }
19
+ reply.send({ live: true, phase });
20
+ }, "live");
21
+ /**
22
+ * Readiness probe: service dependencies are available & lifecycle is RUNNING with aggregated readiness.
23
+ */
24
+ ready = /* @__PURE__ */ __name(async (_, reply) => {
25
+ const phase = this.lifecycleManager.phase;
26
+ const readinessStatus = await this.lifecycleManager.getReadinessStatus();
27
+ const probes = {};
28
+ for (const check of readinessStatus.checks) {
29
+ probes[check.name] = { healthy: check.ready, required: true };
30
+ }
31
+ const requiredFailures = Object.entries(probes).filter(([, v]) => v.required && !v.healthy).map(([k]) => k);
32
+ const ready = readinessStatus.ready;
33
+ if (!ready) {
34
+ reply.code(503).send({
35
+ ready: false,
36
+ phase,
37
+ probes,
38
+ notReady: phase !== LifecyclePhase.RUNNING ? "lifecycle-phase" : "readiness-checks-failed",
39
+ failed: requiredFailures,
40
+ aggregatedReadiness: true
29
41
  });
42
+ return;
30
43
  }
31
- }, "health");
44
+ reply.send({ ready: true, phase, probes, aggregatedReadiness: true });
45
+ }, "ready");
32
46
  async checkDatabaseConnection() {
33
47
  try {
34
48
  return await this.databaseInstance.isConnected();
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/webserver/controller/health.ts"],
4
- "sourcesContent": ["import type { FastifyReply, FastifyRequest } from 'fastify';\nimport BaseController from './base.js';\n\nexport default class HealthController extends BaseController {\n public health = async (_: FastifyRequest, reply: FastifyReply): Promise<void> => {\n try {\n const healthCheckPromises = [this.checkDatabaseConnection(), this.checkRedisConnection()];\n\n const results = await Promise.all(\n healthCheckPromises.map(healthCheckPromise => healthCheckPromise.catch(error => error)),\n );\n\n const isDatabaseHealthy = results[0] === true;\n const isRedisHealthy = results[1] === true;\n // const activeQueueItems = await this.queueManager.listAllJobsWithStatus();\n\n const isAllHealthy = results.every(result => result === true);\n\n reply.send({\n healthy: isAllHealthy,\n services: {\n database: { healthy: isDatabaseHealthy },\n redis: { healthy: isRedisHealthy },\n // queue: { activeItems: activeQueueItems },\n },\n });\n } catch (error: unknown) {\n reply.status(500).send({\n healthy: false,\n error: (error as Error).message,\n });\n }\n };\n\n private async checkDatabaseConnection(): Promise<boolean> {\n try {\n return await this.databaseInstance.isConnected();\n } catch {\n return false;\n }\n }\n\n private async checkRedisConnection(): Promise<boolean> {\n try {\n return await this.redisInstance.isConnected();\n } catch {\n return false;\n }\n }\n}\n"],
5
- "mappings": ";;AACA,OAAO,oBAAoB;AAE3B,MAAO,yBAAuC,eAAe;AAAA,EAH7D,OAG6D;AAAA;AAAA;AAAA,EACpD,SAAS,8BAAO,GAAmB,UAAuC;AAC/E,QAAI;AACF,YAAM,sBAAsB,CAAC,KAAK,wBAAwB,GAAG,KAAK,qBAAqB,CAAC;AAExF,YAAM,UAAU,MAAM,QAAQ;AAAA,QAC5B,oBAAoB,IAAI,wBAAsB,mBAAmB,MAAM,WAAS,KAAK,CAAC;AAAA,MACxF;AAEA,YAAM,oBAAoB,QAAQ,CAAC,MAAM;AACzC,YAAM,iBAAiB,QAAQ,CAAC,MAAM;AAGtC,YAAM,eAAe,QAAQ,MAAM,YAAU,WAAW,IAAI;AAE5D,YAAM,KAAK;AAAA,QACT,SAAS;AAAA,QACT,UAAU;AAAA,UACR,UAAU,EAAE,SAAS,kBAAkB;AAAA,UACvC,OAAO,EAAE,SAAS,eAAe;AAAA;AAAA,QAEnC;AAAA,MACF,CAAC;AAAA,IACH,SAAS,OAAgB;AACvB,YAAM,OAAO,GAAG,EAAE,KAAK;AAAA,QACrB,SAAS;AAAA,QACT,OAAQ,MAAgB;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,EACF,GA5BgB;AAAA,EA8BhB,MAAc,0BAA4C;AACxD,QAAI;AACF,aAAO,MAAM,KAAK,iBAAiB,YAAY;AAAA,IACjD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,uBAAyC;AACrD,QAAI;AACF,aAAO,MAAM,KAAK,cAAc,YAAY;AAAA,IAC9C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import type { FastifyReply, FastifyRequest } from 'fastify';\nimport BaseController from './base.js';\nimport { LifecyclePhase } from '../../lifecycle/types.js';\n\nexport default class HealthController extends BaseController {\n /**\n * Liveness probe: process is up and not in stopping phase.\n */\n public live = async (_: FastifyRequest, reply: FastifyReply): Promise<void> => {\n const phase = this.lifecycleManager.phase;\n const shuttingDown = phase === LifecyclePhase.STOPPING || phase === LifecyclePhase.STOPPED;\n if (shuttingDown) {\n reply.code(503).send({ live: false, phase });\n return;\n }\n reply.send({ live: true, phase });\n };\n\n /**\n * Readiness probe: service dependencies are available & lifecycle is RUNNING with aggregated readiness.\n */\n public ready = async (_: FastifyRequest, reply: FastifyReply): Promise<void> => {\n const phase = this.lifecycleManager.phase;\n const readinessStatus = await this.lifecycleManager.getReadinessStatus();\n\n // Convert readiness check results to probe format for backward compatibility\n const probes: Record<string, { healthy: boolean; required: boolean }> = {};\n for (const check of readinessStatus.checks) {\n probes[check.name] = { healthy: check.ready, required: true };\n }\n\n const requiredFailures = Object.entries(probes)\n .filter(([, v]) => v.required && !v.healthy)\n .map(([k]) => k);\n\n const ready = readinessStatus.ready;\n\n if (!ready) {\n reply.code(503).send({\n ready: false,\n phase,\n probes,\n notReady: phase !== LifecyclePhase.RUNNING ? 'lifecycle-phase' : 'readiness-checks-failed',\n failed: requiredFailures,\n aggregatedReadiness: true,\n });\n return;\n }\n\n reply.send({ ready: true, phase, probes, aggregatedReadiness: true });\n };\n\n private async checkDatabaseConnection(): Promise<boolean> {\n try {\n return await this.databaseInstance.isConnected();\n } catch {\n return false;\n }\n }\n\n private async checkRedisConnection(): Promise<boolean> {\n try {\n return await this.redisInstance.isConnected();\n } catch {\n return false;\n }\n }\n}\n"],
5
+ "mappings": ";;AACA,OAAO,oBAAoB;AAC3B,SAAS,sBAAsB;AAE/B,MAAO,yBAAuC,eAAe;AAAA,EAJ7D,OAI6D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAIpD,OAAO,8BAAO,GAAmB,UAAuC;AAC7E,UAAM,QAAQ,KAAK,iBAAiB;AACpC,UAAM,eAAe,UAAU,eAAe,YAAY,UAAU,eAAe;AACnF,QAAI,cAAc;AAChB,YAAM,KAAK,GAAG,EAAE,KAAK,EAAE,MAAM,OAAO,MAAM,CAAC;AAC3C;AAAA,IACF;AACA,UAAM,KAAK,EAAE,MAAM,MAAM,MAAM,CAAC;AAAA,EAClC,GARc;AAAA;AAAA;AAAA;AAAA,EAaP,QAAQ,8BAAO,GAAmB,UAAuC;AAC9E,UAAM,QAAQ,KAAK,iBAAiB;AACpC,UAAM,kBAAkB,MAAM,KAAK,iBAAiB,mBAAmB;AAGvE,UAAM,SAAkE,CAAC;AACzE,eAAW,SAAS,gBAAgB,QAAQ;AAC1C,aAAO,MAAM,IAAI,IAAI,EAAE,SAAS,MAAM,OAAO,UAAU,KAAK;AAAA,IAC9D;AAEA,UAAM,mBAAmB,OAAO,QAAQ,MAAM,EAC3C,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,EAC1C,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;AAEjB,UAAM,QAAQ,gBAAgB;AAE9B,QAAI,CAAC,OAAO;AACV,YAAM,KAAK,GAAG,EAAE,KAAK;AAAA,QACnB,OAAO;AAAA,QACP;AAAA,QACA;AAAA,QACA,UAAU,UAAU,eAAe,UAAU,oBAAoB;AAAA,QACjE,QAAQ;AAAA,QACR,qBAAqB;AAAA,MACvB,CAAC;AACD;AAAA,IACF;AAEA,UAAM,KAAK,EAAE,OAAO,MAAM,OAAO,QAAQ,qBAAqB,KAAK,CAAC;AAAA,EACtE,GA7Be;AAAA,EA+Bf,MAAc,0BAA4C;AACxD,QAAI;AACF,aAAO,MAAM,KAAK,iBAAiB,YAAY;AAAA,IACjD,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAc,uBAAyC;AACrD,QAAI;AACF,aAAO,MAAM,KAAK,cAAc,YAAY;AAAA,IAC9C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,10 @@
1
1
  import { type FastifyInstance, type HTTPMethods } from 'fastify';
2
2
  import { type WebServerConstructorParams } from './webserver.interface.js';
3
+ import type { LifecycleManager } from '../lifecycle/lifecycle-manager.js';
3
4
  declare module 'fastify' {
4
5
  interface FastifyRequest {
5
- startTime?: [number, number];
6
+ startTime?: number;
7
+ requestId?: string;
6
8
  }
7
9
  }
8
10
  declare class WebServer {
@@ -15,11 +17,19 @@ declare class WebServer {
15
17
  private eventManager;
16
18
  private databaseInstance;
17
19
  fastifyServer: FastifyInstance;
18
- constructor(params: WebServerConstructorParams);
20
+ private lifecycleManager;
21
+ private _isReady;
22
+ constructor(params: WebServerConstructorParams & {
23
+ lifecycleManager: LifecycleManager;
24
+ });
19
25
  /**
20
26
  * Load web server.
21
27
  */
22
28
  load(): Promise<void>;
29
+ /**
30
+ * Configure security features (Helmet, Rate Limiting)
31
+ */
32
+ private configureSecurity;
23
33
  /**
24
34
  * Configure hooks.
25
35
  */
@@ -56,6 +66,10 @@ declare class WebServer {
56
66
  * Stop web server.
57
67
  */
58
68
  stop(): Promise<void>;
69
+ /**
70
+ * Check if web server is ready to accept traffic.
71
+ */
72
+ isReady(): boolean;
59
73
  /**
60
74
  * Log web server message
61
75
  */
@@ -1 +1 @@
1
- {"version":3,"file":"webserver.d.ts","sourceRoot":"","sources":["../../src/webserver/webserver.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,KAAK,eAAe,EAA0C,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAGlH,OAAO,EACL,KAAK,0BAA0B,EAIhC,MAAM,0BAA0B,CAAC;AAalC,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAC9B;CACF;AAED,cAAM,SAAS;IACb,OAAO,CAAC,MAAM,CAAyB;IAEvC,OAAO,CAAC,iBAAiB,CAAoB;IAE7C,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,MAAM,CAAmB;IAEjC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,gBAAgB,CAAmB;IAEpC,aAAa,EAAE,eAAe,CAAC;gBAE1B,MAAM,EAAE,0BAA0B;IA8C9C;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAclC;;OAEG;IACH,OAAO,CAAC,cAAc;YAeR,QAAQ;YAeR,SAAS;YAkBT,UAAU;YAkCV,OAAO;YAMP,OAAO;IAIrB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,yBAAyB;IAcjC;;OAEG;YACW,eAAe;IAmJhB,WAAW,CAAC,EACvB,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,SAAS,EACT,WAAW,EACX,eAAe,GAChB,EAAE;QACD,kBAAkB,EAAE,GAAG,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,WAAW,GAAG,WAAW,EAAE,CAAC;QACzC,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,CAAC,EAAE;YAChB,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;YAClC,MAAM,EAAE;gBAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;aAAE,CAAC;SAChC,CAAC;KACH,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CjB;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAWnC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAKlC;;OAEG;IACI,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAGlE;AAED,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"webserver.d.ts","sourceRoot":"","sources":["../../src/webserver/webserver.ts"],"names":[],"mappings":"AACA,OAAgB,EAAE,KAAK,eAAe,EAA0C,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAKlH,OAAO,EACL,KAAK,0BAA0B,EAIhC,MAAM,0BAA0B,CAAC;AASlC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAK1E,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,cAAc;QACtB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB;CACF;AAED,cAAM,SAAS;IACb,OAAO,CAAC,MAAM,CAAyB;IAEvC,OAAO,CAAC,iBAAiB,CAAoB;IAE7C,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,MAAM,CAAmB;IAEjC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,gBAAgB,CAAmB;IAEpC,aAAa,EAAE,eAAe,CAAC;IAEtC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,QAAQ,CAAS;gBAEb,MAAM,EAAE,0BAA0B,GAAG;QAAE,gBAAgB,EAAE,gBAAgB,CAAA;KAAE;IAgDvF;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBlC;;OAEG;YACW,iBAAiB;IAiD/B;;OAEG;IACH,OAAO,CAAC,cAAc;YAeR,QAAQ;YAeR,SAAS;YA2BT,UAAU;YAuCV,OAAO;YAMP,OAAO;IAIrB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,yBAAyB;IAcjC;;OAEG;YACW,eAAe;IA+JhB,WAAW,CAAC,EACvB,kBAAkB,EAClB,cAAc,EACd,WAAW,EACX,SAAS,EACT,WAAW,EACX,eAAe,GAChB,EAAE;QACD,kBAAkB,EAAE,GAAG,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,WAAW,GAAG,WAAW,EAAE,CAAC;QACzC,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,CAAC,EAAE;YAChB,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;YAClC,MAAM,EAAE;gBAAE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;aAAE,CAAC;SAChC,CAAC;KACH,GAAG,OAAO,CAAC,IAAI,CAAC;IA+DjB;;OAEG;IACU,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAanC;;OAEG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAMlC;;OAEG;IACI,OAAO,IAAI,OAAO;IAIzB;;OAEG;IACI,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAGlE;AAED,eAAe,SAAS,CAAC"}
@@ -5,6 +5,7 @@ import type { RedisInstance } from '../redis/index.js';
5
5
  import type { WebServerBaseControllerType } from './controller/base.interface.js';
6
6
  import type { ApplicationConfig } from '../application/base-application.interface.js';
7
7
  import type EventManager from '../event/manager.js';
8
+ import type { LifecycleManager } from '../lifecycle/lifecycle-manager.js';
8
9
  export interface WebServerConstructorParams {
9
10
  /** Application configuration */
10
11
  applicationConfig: ApplicationConfig;
@@ -20,6 +21,8 @@ export interface WebServerConstructorParams {
20
21
  eventManager: EventManager;
21
22
  /** Database instance */
22
23
  databaseInstance: DatabaseInstance;
24
+ /** Lifecycle manager */
25
+ lifecycleManager: LifecycleManager;
23
26
  }
24
27
  export declare enum WebServerRouteType {
25
28
  Default = "default",
@@ -100,11 +103,43 @@ export type WebServerCorsOptions = WebServerCorsDisabledOptionsBase | WebServerC
100
103
  export interface WebServerErrorsOptions {
101
104
  verbose: boolean;
102
105
  }
106
+ export interface WebServerSecurityHelmetOptions {
107
+ enabled?: boolean;
108
+ contentSecurityPolicy?: boolean;
109
+ crossOriginEmbedderPolicy?: boolean;
110
+ crossOriginOpenerPolicy?: boolean;
111
+ crossOriginResourcePolicy?: boolean;
112
+ dnsPrefetchControl?: boolean;
113
+ frameguard?: boolean;
114
+ hidePoweredBy?: boolean;
115
+ hsts?: boolean;
116
+ ieNoOpen?: boolean;
117
+ noSniff?: boolean;
118
+ originAgentCluster?: boolean;
119
+ permittedCrossDomainPolicies?: boolean;
120
+ referrerPolicy?: boolean;
121
+ xssFilter?: boolean;
122
+ }
123
+ export interface WebServerSecurityRateLimitOptions {
124
+ enabled?: boolean;
125
+ max?: number;
126
+ timeWindow?: string;
127
+ ban?: number;
128
+ cache?: number;
129
+ }
130
+ export interface WebServerSecurityOptions {
131
+ helmet?: WebServerSecurityHelmetOptions;
132
+ rateLimit?: WebServerSecurityRateLimitOptions;
133
+ }
103
134
  export interface WebServerOptions {
104
135
  /** Web server host */
105
136
  host: string;
106
137
  /** Web server port */
107
138
  port: number;
139
+ /** Maximum request body size in bytes (default: 100MB) */
140
+ bodyLimit?: number;
141
+ /** Connection timeout in milliseconds (default: 30s) */
142
+ connectionTimeout?: number;
108
143
  /** Web server CORS options */
109
144
  cors?: WebServerCorsOptions;
110
145
  /** Web server error options */
@@ -112,6 +147,8 @@ export interface WebServerOptions {
112
147
  /** Web server controllers directory */
113
148
  controllersDirectory: string;
114
149
  log?: WebServerLogConfig;
150
+ /** Web server security options (helmet, rate limiting) */
151
+ security?: WebServerSecurityOptions;
115
152
  /** Web server debug options */
116
153
  debug?: WebServerDebugOptions;
117
154
  }
@@ -1 +1 @@
1
- {"version":3,"file":"webserver.interface.d.ts","sourceRoot":"","sources":["../../src/webserver/webserver.interface.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"webserver.interface.d.ts","sourceRoot":"","sources":["../../src/webserver/webserver.interface.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/webserver/webserver.interface.ts"],
4
- "sourcesContent": ["import type { HTTPMethods } from 'fastify';\nimport type { DatabaseInstance } from '../database/index.js';\nimport type { QueueManager } from '../queue/index.js';\nimport type { RedisInstance } from '../redis/index.js';\nimport type { WebServerBaseControllerType } from './controller/base.interface.js';\nimport type { ApplicationConfig } from '../application/base-application.interface.js';\nimport type EventManager from '../event/manager.js';\n\nexport interface WebServerConstructorParams {\n /** Application configuration */\n applicationConfig: ApplicationConfig;\n\n /** Web server options */\n options: WebServerOptions;\n\n /** Web server routes */\n routes: WebServerRoute[];\n\n /** Redis instance */\n redisInstance: RedisInstance;\n\n /** Queue manager */\n queueManager: QueueManager;\n\n /** Event manager */\n eventManager: EventManager;\n\n /** Database instance */\n databaseInstance: DatabaseInstance;\n}\n\nexport enum WebServerRouteType {\n Default = 'default',\n Entity = 'entity',\n}\n\nexport interface BaseWebServerRoute {\n /** Route type */\n type?: WebServerRouteType;\n\n /** Route path */\n path: string;\n\n /** Route controller name */\n controllerName?: string;\n\n /** Route controller */\n controller?: WebServerBaseControllerType;\n\n /** Route validation */\n validation?: {\n /** Validation type */\n type: 'body' | 'query' | 'params';\n\n /** Validation schema */\n schema: { [key: string]: any };\n };\n}\n\nexport interface DefaultWebServerRoute extends BaseWebServerRoute {\n type: WebServerRouteType.Default;\n\n /** Route method */\n method: HTTPMethods | HTTPMethods[];\n\n /** Route action */\n action: string;\n}\n\nexport interface EntityWebServerRoute extends BaseWebServerRoute {\n type: WebServerRouteType.Entity;\n\n /** Entity name */\n entityName: string;\n}\n\nexport type WebServerRoute = DefaultWebServerRoute | EntityWebServerRoute;\n\nexport interface RouteValidationSchema {\n type: 'body' | 'query' | 'params';\n schema: {\n type: 'object';\n properties: { [key: string]: any };\n required: string[];\n };\n}\n\nexport interface EntityRouteDefinition {\n path: string;\n method: HTTPMethods | HTTPMethods[];\n action: string;\n validationSchema?: RouteValidationSchema;\n}\n\nexport interface WebServerLogConfig {\n startUp?: boolean;\n}\n\nexport interface WebServerDebugOptions {\n printRoutes?: boolean;\n simulateSlowConnection?: {\n enabled?: boolean;\n delay?: number;\n };\n}\n\nexport interface WebServerCorsBaseOptions {\n /** Whether CORS is enabled */\n enabled: boolean;\n}\n\nexport interface WebServerCorsDisabledOptionsBase {\n enabled: false;\n}\n\nexport interface WebServerCorsEnabledOptionsBase {\n enabled: true;\n}\n\nexport interface WebServerCorsEnabledOptions extends WebServerCorsEnabledOptionsBase {\n urls: string[];\n}\n\nexport type WebServerCorsOptions = WebServerCorsDisabledOptionsBase | WebServerCorsEnabledOptions;\n\nexport interface WebServerErrorsOptions {\n verbose: boolean;\n}\n\nexport interface WebServerOptions {\n /** Web server host */\n host: string;\n\n /** Web server port */\n port: number;\n\n /** Web server CORS options */\n cors?: WebServerCorsOptions;\n\n /** Web server error options */\n errors?: WebServerErrorsOptions;\n\n /** Web server controllers directory */\n controllersDirectory: string;\n\n log?: WebServerLogConfig;\n\n /** Web server debug options */\n debug?: WebServerDebugOptions;\n}\n\n// export interface WebServerLogParams {\n// /** Method */\n// Method: string;\n\n// /** Path */\n// Path: string;\n\n// /** Status code */\n// Status: number;\n\n// /** IP address */\n// IP?: string;\n\n// /** Execution time */\n// Time?: string;\n\n// [key: string]: unknown;\n// }\n"],
5
- "mappings": "AA+BO,IAAK,qBAAL,kBAAKA,wBAAL;AACL,EAAAA,oBAAA,aAAU;AACV,EAAAA,oBAAA,YAAS;AAFC,SAAAA;AAAA,GAAA;",
4
+ "sourcesContent": ["import type { HTTPMethods } from 'fastify';\nimport type { DatabaseInstance } from '../database/index.js';\nimport type { QueueManager } from '../queue/index.js';\nimport type { RedisInstance } from '../redis/index.js';\nimport type { WebServerBaseControllerType } from './controller/base.interface.js';\nimport type { ApplicationConfig } from '../application/base-application.interface.js';\nimport type EventManager from '../event/manager.js';\nimport type { LifecycleManager } from '../lifecycle/lifecycle-manager.js';\n\nexport interface WebServerConstructorParams {\n /** Application configuration */\n applicationConfig: ApplicationConfig;\n\n /** Web server options */\n options: WebServerOptions;\n\n /** Web server routes */\n routes: WebServerRoute[];\n\n /** Redis instance */\n redisInstance: RedisInstance;\n\n /** Queue manager */\n queueManager: QueueManager;\n\n /** Event manager */\n eventManager: EventManager;\n\n /** Database instance */\n databaseInstance: DatabaseInstance;\n\n /** Lifecycle manager */\n lifecycleManager: LifecycleManager;\n}\n\nexport enum WebServerRouteType {\n Default = 'default',\n Entity = 'entity',\n}\n\nexport interface BaseWebServerRoute {\n /** Route type */\n type?: WebServerRouteType;\n\n /** Route path */\n path: string;\n\n /** Route controller name */\n controllerName?: string;\n\n /** Route controller */\n controller?: WebServerBaseControllerType;\n\n /** Route validation */\n validation?: {\n /** Validation type */\n type: 'body' | 'query' | 'params';\n\n /** Validation schema */\n schema: { [key: string]: any };\n };\n}\n\nexport interface DefaultWebServerRoute extends BaseWebServerRoute {\n type: WebServerRouteType.Default;\n\n /** Route method */\n method: HTTPMethods | HTTPMethods[];\n\n /** Route action */\n action: string;\n}\n\nexport interface EntityWebServerRoute extends BaseWebServerRoute {\n type: WebServerRouteType.Entity;\n\n /** Entity name */\n entityName: string;\n}\n\nexport type WebServerRoute = DefaultWebServerRoute | EntityWebServerRoute;\n\nexport interface RouteValidationSchema {\n type: 'body' | 'query' | 'params';\n schema: {\n type: 'object';\n properties: { [key: string]: any };\n required: string[];\n };\n}\n\nexport interface EntityRouteDefinition {\n path: string;\n method: HTTPMethods | HTTPMethods[];\n action: string;\n validationSchema?: RouteValidationSchema;\n}\n\nexport interface WebServerLogConfig {\n startUp?: boolean;\n}\n\nexport interface WebServerDebugOptions {\n printRoutes?: boolean;\n simulateSlowConnection?: {\n enabled?: boolean;\n delay?: number;\n };\n}\n\nexport interface WebServerCorsBaseOptions {\n /** Whether CORS is enabled */\n enabled: boolean;\n}\n\nexport interface WebServerCorsDisabledOptionsBase {\n enabled: false;\n}\n\nexport interface WebServerCorsEnabledOptionsBase {\n enabled: true;\n}\n\nexport interface WebServerCorsEnabledOptions extends WebServerCorsEnabledOptionsBase {\n urls: string[];\n}\n\nexport type WebServerCorsOptions = WebServerCorsDisabledOptionsBase | WebServerCorsEnabledOptions;\n\nexport interface WebServerErrorsOptions {\n verbose: boolean;\n}\n\nexport interface WebServerSecurityHelmetOptions {\n enabled?: boolean;\n contentSecurityPolicy?: boolean;\n crossOriginEmbedderPolicy?: boolean;\n crossOriginOpenerPolicy?: boolean;\n crossOriginResourcePolicy?: boolean;\n dnsPrefetchControl?: boolean;\n frameguard?: boolean;\n hidePoweredBy?: boolean;\n hsts?: boolean;\n ieNoOpen?: boolean;\n noSniff?: boolean;\n originAgentCluster?: boolean;\n permittedCrossDomainPolicies?: boolean;\n referrerPolicy?: boolean;\n xssFilter?: boolean;\n}\n\nexport interface WebServerSecurityRateLimitOptions {\n enabled?: boolean;\n max?: number;\n timeWindow?: string;\n ban?: number;\n cache?: number;\n}\n\nexport interface WebServerSecurityOptions {\n helmet?: WebServerSecurityHelmetOptions;\n rateLimit?: WebServerSecurityRateLimitOptions;\n}\n\nexport interface WebServerOptions {\n /** Web server host */\n host: string;\n\n /** Web server port */\n port: number;\n\n /** Maximum request body size in bytes (default: 100MB) */\n bodyLimit?: number;\n\n /** Connection timeout in milliseconds (default: 30s) */\n connectionTimeout?: number;\n\n /** Web server CORS options */\n cors?: WebServerCorsOptions;\n\n /** Web server error options */\n errors?: WebServerErrorsOptions;\n\n /** Web server controllers directory */\n controllersDirectory: string;\n\n log?: WebServerLogConfig;\n\n /** Web server security options (helmet, rate limiting) */\n security?: WebServerSecurityOptions;\n\n /** Web server debug options */\n debug?: WebServerDebugOptions;\n}\n\n// export interface WebServerLogParams {\n// /** Method */\n// Method: string;\n\n// /** Path */\n// Path: string;\n\n// /** Status code */\n// Status: number;\n\n// /** IP address */\n// IP?: string;\n\n// /** Execution time */\n// Time?: string;\n\n// [key: string]: unknown;\n// }\n"],
5
+ "mappings": "AAmCO,IAAK,qBAAL,kBAAKA,wBAAL;AACL,EAAAA,oBAAA,aAAU;AACV,EAAAA,oBAAA,YAAS;AAFC,SAAAA;AAAA,GAAA;",
6
6
  "names": ["WebServerRouteType"]
7
7
  }