@scpxl/nodejs-framework 1.0.22 → 1.0.25

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 (326) hide show
  1. package/README.md +264 -26
  2. package/dist/api-requester/api-requester.d.ts +32 -0
  3. package/dist/api-requester/api-requester.d.ts.map +1 -0
  4. package/dist/api-requester/api-requester.js +2 -1
  5. package/dist/api-requester/api-requester.js.map +2 -2
  6. package/dist/api-requester/index.d.ts +3 -0
  7. package/dist/api-requester/index.d.ts.map +1 -0
  8. package/dist/application/base-application.d.ts +106 -0
  9. package/dist/application/base-application.d.ts.map +1 -0
  10. package/dist/application/base-application.interface.d.ts +162 -0
  11. package/dist/application/base-application.interface.d.ts.map +1 -0
  12. package/dist/application/base-application.js +7 -3
  13. package/dist/application/base-application.js.map +2 -2
  14. package/dist/application/command-application.d.ts +18 -0
  15. package/dist/application/command-application.d.ts.map +1 -0
  16. package/dist/application/command-application.interface.d.ts +26 -0
  17. package/dist/application/command-application.interface.d.ts.map +1 -0
  18. package/dist/application/index.d.ts +5 -0
  19. package/dist/application/index.d.ts.map +1 -0
  20. package/dist/application/web-application.d.ts +43 -0
  21. package/dist/application/web-application.d.ts.map +1 -0
  22. package/dist/application/web-application.interface.d.ts +21 -0
  23. package/dist/application/web-application.interface.d.ts.map +1 -0
  24. package/dist/application/web-application.js +1 -0
  25. package/dist/application/web-application.js.map +2 -2
  26. package/dist/auth/index.d.ts +2 -0
  27. package/dist/auth/index.d.ts.map +1 -0
  28. package/dist/auth/jwt.d.ts +25 -0
  29. package/dist/auth/jwt.d.ts.map +1 -0
  30. package/dist/cache/index.d.ts +2 -0
  31. package/dist/cache/index.d.ts.map +1 -0
  32. package/dist/cache/manager.d.ts +107 -0
  33. package/dist/cache/manager.d.ts.map +1 -0
  34. package/dist/cache/manager.js +2 -1
  35. package/dist/cache/manager.js.map +2 -2
  36. package/dist/cli/index.d.ts +2 -0
  37. package/dist/cli/index.d.ts.map +1 -0
  38. package/dist/cli/index.js +12591 -0
  39. package/dist/cli/index.js.map +7 -0
  40. package/dist/cluster/cluster-manager.d.ts +18 -0
  41. package/dist/cluster/cluster-manager.d.ts.map +1 -0
  42. package/dist/cluster/cluster-manager.interface.d.ts +23 -0
  43. package/dist/cluster/cluster-manager.interface.d.ts.map +1 -0
  44. package/dist/cluster/cluster-manager.js +45 -8
  45. package/dist/cluster/cluster-manager.js.map +2 -2
  46. package/dist/cluster/index.d.ts +2 -0
  47. package/dist/cluster/index.d.ts.map +1 -0
  48. package/dist/command/command-manager.d.ts +19 -0
  49. package/dist/command/command-manager.d.ts.map +1 -0
  50. package/dist/command/command.d.ts +27 -0
  51. package/dist/command/command.d.ts.map +1 -0
  52. package/dist/command/command.interface.d.ts +11 -0
  53. package/dist/command/command.interface.d.ts.map +1 -0
  54. package/dist/command/index.d.ts +3 -0
  55. package/dist/command/index.d.ts.map +1 -0
  56. package/dist/config/env.d.ts +11 -0
  57. package/dist/config/env.d.ts.map +1 -0
  58. package/dist/config/index.d.ts +3 -0
  59. package/dist/config/index.d.ts.map +1 -0
  60. package/dist/config/schema.d.ts +432 -0
  61. package/dist/config/schema.d.ts.map +1 -0
  62. package/dist/database/dynamic-entity-form-decorators.d.ts +31 -0
  63. package/dist/database/dynamic-entity-form-decorators.d.ts.map +1 -0
  64. package/dist/database/dynamic-entity-form-decorators.js.map +1 -1
  65. package/dist/database/dynamic-entity.d.ts +18 -0
  66. package/dist/database/dynamic-entity.d.ts.map +1 -0
  67. package/dist/database/dynamic-entity.js +11 -1
  68. package/dist/database/dynamic-entity.js.map +2 -2
  69. package/dist/database/index.d.ts +5 -0
  70. package/dist/database/index.d.ts.map +1 -0
  71. package/dist/database/instance.d.ts +36 -0
  72. package/dist/database/instance.d.ts.map +1 -0
  73. package/dist/database/instance.interface.d.ts +5 -0
  74. package/dist/database/instance.interface.d.ts.map +1 -0
  75. package/dist/database/manager.d.ts +27 -0
  76. package/dist/database/manager.d.ts.map +1 -0
  77. package/dist/database/manager.interface.d.ts +18 -0
  78. package/dist/database/manager.interface.d.ts.map +1 -0
  79. package/dist/database/manager.js +3 -2
  80. package/dist/database/manager.js.map +2 -2
  81. package/dist/error/error-reporter.d.ts +109 -0
  82. package/dist/error/error-reporter.d.ts.map +1 -0
  83. package/dist/error/error-reporter.js +32 -29
  84. package/dist/error/error-reporter.js.map +2 -2
  85. package/dist/error/error.interface.d.ts +126 -0
  86. package/dist/error/error.interface.d.ts.map +1 -0
  87. package/dist/error/framework-errors.d.ts +113 -0
  88. package/dist/error/framework-errors.d.ts.map +1 -0
  89. package/dist/error/index.d.ts +6 -0
  90. package/dist/error/index.d.ts.map +1 -0
  91. package/dist/error/index.js +3 -2
  92. package/dist/error/index.js.map +2 -2
  93. package/dist/event/controller/base.d.ts +23 -0
  94. package/dist/event/controller/base.d.ts.map +1 -0
  95. package/dist/event/controller/base.interface.d.ts +11 -0
  96. package/dist/event/controller/base.interface.d.ts.map +1 -0
  97. package/dist/event/controller/base.js +2 -1
  98. package/dist/event/controller/base.js.map +2 -2
  99. package/dist/event/index.d.ts +5 -0
  100. package/dist/event/index.d.ts.map +1 -0
  101. package/dist/event/manager.d.ts +21 -0
  102. package/dist/event/manager.d.ts.map +1 -0
  103. package/dist/event/manager.interface.d.ts +137 -0
  104. package/dist/event/manager.interface.d.ts.map +1 -0
  105. package/dist/event/manager.js +5 -4
  106. package/dist/event/manager.js.map +2 -2
  107. package/dist/index.d.ts +22 -0
  108. package/dist/index.d.ts.map +1 -0
  109. package/dist/lifecycle/exit.d.ts +11 -0
  110. package/dist/lifecycle/exit.d.ts.map +1 -0
  111. package/dist/lifecycle/exit.js.map +2 -2
  112. package/dist/lifecycle/index.d.ts +7 -0
  113. package/dist/lifecycle/index.d.ts.map +1 -0
  114. package/dist/lifecycle/lifecycle-manager.d.ts +66 -0
  115. package/dist/lifecycle/lifecycle-manager.d.ts.map +1 -0
  116. package/dist/lifecycle/lifecycle-manager.js +6 -11
  117. package/dist/lifecycle/lifecycle-manager.js.map +2 -2
  118. package/dist/lifecycle/shutdown-controller.d.ts +15 -0
  119. package/dist/lifecycle/shutdown-controller.d.ts.map +1 -0
  120. package/dist/lifecycle/types.d.ts +28 -0
  121. package/dist/lifecycle/types.d.ts.map +1 -0
  122. package/dist/logger/index.d.ts +2 -0
  123. package/dist/logger/index.d.ts.map +1 -0
  124. package/dist/logger/logger.d.ts +59 -0
  125. package/dist/logger/logger.d.ts.map +1 -0
  126. package/dist/logger/logger.interface.d.ts +2 -0
  127. package/dist/logger/logger.interface.d.ts.map +1 -0
  128. package/dist/logger/logger.js +11 -3
  129. package/dist/logger/logger.js.map +2 -2
  130. package/dist/performance/cache-performance.d.ts +64 -0
  131. package/dist/performance/cache-performance.d.ts.map +1 -0
  132. package/dist/performance/database-performance.d.ts +40 -0
  133. package/dist/performance/database-performance.d.ts.map +1 -0
  134. package/dist/performance/index.d.ts +8 -0
  135. package/dist/performance/index.d.ts.map +1 -0
  136. package/dist/performance/performance-monitor.d.ts +68 -0
  137. package/dist/performance/performance-monitor.d.ts.map +1 -0
  138. package/dist/performance/performance-monitor.js +10 -3
  139. package/dist/performance/performance-monitor.js.map +2 -2
  140. package/dist/performance/performance-monitor.plugin.d.ts +24 -0
  141. package/dist/performance/performance-monitor.plugin.d.ts.map +1 -0
  142. package/dist/performance/queue-performance.d.ts +46 -0
  143. package/dist/performance/queue-performance.d.ts.map +1 -0
  144. package/dist/performance/webserver-performance.d.ts +69 -0
  145. package/dist/performance/webserver-performance.d.ts.map +1 -0
  146. package/dist/performance/websocket-performance.d.ts +44 -0
  147. package/dist/performance/websocket-performance.d.ts.map +1 -0
  148. package/dist/queue/index.d.ts +6 -0
  149. package/dist/queue/index.d.ts.map +1 -0
  150. package/dist/queue/index.interface.d.ts +10 -0
  151. package/dist/queue/index.interface.d.ts.map +1 -0
  152. package/dist/queue/job.interface.d.ts +43 -0
  153. package/dist/queue/job.interface.d.ts.map +1 -0
  154. package/dist/queue/manager.d.ts +44 -0
  155. package/dist/queue/manager.d.ts.map +1 -0
  156. package/dist/queue/manager.interface.d.ts +18 -0
  157. package/dist/queue/manager.interface.d.ts.map +1 -0
  158. package/dist/queue/processor/base.d.ts +29 -0
  159. package/dist/queue/processor/base.d.ts.map +1 -0
  160. package/dist/queue/processor/base.js +2 -1
  161. package/dist/queue/processor/base.js.map +2 -2
  162. package/dist/queue/processor/processor.interface.d.ts +16 -0
  163. package/dist/queue/processor/processor.interface.d.ts.map +1 -0
  164. package/dist/queue/worker.d.ts +14 -0
  165. package/dist/queue/worker.d.ts.map +1 -0
  166. package/dist/queue/worker.interface.d.ts +13 -0
  167. package/dist/queue/worker.interface.d.ts.map +1 -0
  168. package/dist/redis/index.d.ts +3 -0
  169. package/dist/redis/index.d.ts.map +1 -0
  170. package/dist/redis/instance.d.ts +32 -0
  171. package/dist/redis/instance.d.ts.map +1 -0
  172. package/dist/redis/instance.interface.d.ts +9 -0
  173. package/dist/redis/instance.interface.d.ts.map +1 -0
  174. package/dist/redis/manager.d.ts +15 -0
  175. package/dist/redis/manager.d.ts.map +1 -0
  176. package/dist/redis/manager.interface.d.ts +8 -0
  177. package/dist/redis/manager.interface.d.ts.map +1 -0
  178. package/dist/redis/manager.js +16 -16
  179. package/dist/redis/manager.js.map +2 -2
  180. package/dist/request-context/index.d.ts +3 -0
  181. package/dist/request-context/index.d.ts.map +1 -0
  182. package/dist/request-context/request-context.d.ts +108 -0
  183. package/dist/request-context/request-context.d.ts.map +1 -0
  184. package/dist/request-context/request-context.interface.d.ts +46 -0
  185. package/dist/request-context/request-context.interface.d.ts.map +1 -0
  186. package/dist/schemas/common.d.ts +197 -0
  187. package/dist/schemas/common.d.ts.map +1 -0
  188. package/dist/schemas/common.js +108 -0
  189. package/dist/schemas/common.js.map +7 -0
  190. package/dist/schemas/index.d.ts +6 -0
  191. package/dist/schemas/index.d.ts.map +1 -0
  192. package/dist/schemas/index.js +2 -0
  193. package/dist/schemas/index.js.map +7 -0
  194. package/dist/services/aws/index.d.ts +2 -0
  195. package/dist/services/aws/index.d.ts.map +1 -0
  196. package/dist/services/aws/s3.d.ts +54 -0
  197. package/dist/services/aws/s3.d.ts.map +1 -0
  198. package/dist/services/aws/s3.interface.d.ts +14 -0
  199. package/dist/services/aws/s3.interface.d.ts.map +1 -0
  200. package/dist/services/index.d.ts +2 -0
  201. package/dist/services/index.d.ts.map +1 -0
  202. package/dist/util/file.d.ts +58 -0
  203. package/dist/util/file.d.ts.map +1 -0
  204. package/dist/util/helper.d.ts +51 -0
  205. package/dist/util/helper.d.ts.map +1 -0
  206. package/dist/util/helper.js +72 -10
  207. package/dist/util/helper.js.map +2 -2
  208. package/dist/util/image.d.ts +12 -0
  209. package/dist/util/image.d.ts.map +1 -0
  210. package/dist/util/index.d.ts +11 -0
  211. package/dist/util/index.d.ts.map +1 -0
  212. package/dist/util/loader.d.ts +21 -0
  213. package/dist/util/loader.d.ts.map +1 -0
  214. package/dist/util/loader.js +5 -2
  215. package/dist/util/loader.js.map +2 -2
  216. package/dist/util/num.d.ts +13 -0
  217. package/dist/util/num.d.ts.map +1 -0
  218. package/dist/util/os.d.ts +6 -0
  219. package/dist/util/os.d.ts.map +1 -0
  220. package/dist/util/str.d.ts +39 -0
  221. package/dist/util/str.d.ts.map +1 -0
  222. package/dist/util/time.d.ts +19 -0
  223. package/dist/util/time.d.ts.map +1 -0
  224. package/dist/util/time.interface.d.ts +12 -0
  225. package/dist/util/time.interface.d.ts.map +1 -0
  226. package/dist/util/timing.d.ts +36 -0
  227. package/dist/util/timing.d.ts.map +1 -0
  228. package/dist/util/timing.interface.d.ts +47 -0
  229. package/dist/util/timing.interface.d.ts.map +1 -0
  230. package/dist/util/url.d.ts +7 -0
  231. package/dist/util/url.d.ts.map +1 -0
  232. package/dist/webserver/controller/auth-middleware.d.ts +21 -0
  233. package/dist/webserver/controller/auth-middleware.d.ts.map +1 -0
  234. package/dist/webserver/controller/base.d.ts +41 -0
  235. package/dist/webserver/controller/base.d.ts.map +1 -0
  236. package/dist/webserver/controller/base.interface.d.ts +50 -0
  237. package/dist/webserver/controller/base.interface.d.ts.map +1 -0
  238. package/dist/webserver/controller/base.js +4 -4
  239. package/dist/webserver/controller/base.js.map +2 -2
  240. package/dist/webserver/controller/entity.d.ts +94 -0
  241. package/dist/webserver/controller/entity.d.ts.map +1 -0
  242. package/dist/webserver/controller/entity.js.map +2 -2
  243. package/dist/webserver/controller/example-auth.d.ts +12 -0
  244. package/dist/webserver/controller/example-auth.d.ts.map +1 -0
  245. package/dist/webserver/controller/health.d.ts +13 -0
  246. package/dist/webserver/controller/health.d.ts.map +1 -0
  247. package/dist/webserver/controller/health.js +0 -14
  248. package/dist/webserver/controller/health.js.map +2 -2
  249. package/dist/webserver/define-action.d.ts +26 -0
  250. package/dist/webserver/define-action.d.ts.map +1 -0
  251. package/dist/webserver/define-action.js +16 -0
  252. package/dist/webserver/define-action.js.map +7 -0
  253. package/dist/webserver/define-route.d.ts +53 -0
  254. package/dist/webserver/define-route.d.ts.map +1 -0
  255. package/dist/webserver/define-route.js +11 -6
  256. package/dist/webserver/define-route.js.map +2 -2
  257. package/dist/webserver/index.d.ts +14 -0
  258. package/dist/webserver/index.d.ts.map +1 -0
  259. package/dist/webserver/index.js +2 -0
  260. package/dist/webserver/index.js.map +2 -2
  261. package/dist/webserver/util.d.ts +10 -0
  262. package/dist/webserver/util.d.ts.map +1 -0
  263. package/dist/webserver/util.js +5 -2
  264. package/dist/webserver/util.js.map +2 -2
  265. package/dist/webserver/webserver.d.ts +93 -0
  266. package/dist/webserver/webserver.d.ts.map +1 -0
  267. package/dist/webserver/webserver.interface.d.ts +181 -0
  268. package/dist/webserver/webserver.interface.d.ts.map +1 -0
  269. package/dist/webserver/webserver.interface.js.map +1 -1
  270. package/dist/webserver/webserver.js +30 -33
  271. package/dist/webserver/webserver.js.map +2 -2
  272. package/dist/websocket/controller/client/base.d.ts +12 -0
  273. package/dist/websocket/controller/client/base.d.ts.map +1 -0
  274. package/dist/websocket/controller/client/base.interface.d.ts +12 -0
  275. package/dist/websocket/controller/client/base.interface.d.ts.map +1 -0
  276. package/dist/websocket/controller/server/base.d.ts +13 -0
  277. package/dist/websocket/controller/server/base.d.ts.map +1 -0
  278. package/dist/websocket/controller/server/base.interface.d.ts +13 -0
  279. package/dist/websocket/controller/server/base.interface.d.ts.map +1 -0
  280. package/dist/websocket/controllers/client/system.d.ts +6 -0
  281. package/dist/websocket/controllers/client/system.d.ts.map +1 -0
  282. package/dist/websocket/controllers/server/system.d.ts +7 -0
  283. package/dist/websocket/controllers/server/system.d.ts.map +1 -0
  284. package/dist/websocket/index.d.ts +9 -0
  285. package/dist/websocket/index.d.ts.map +1 -0
  286. package/dist/websocket/index.js +2 -0
  287. package/dist/websocket/index.js.map +2 -2
  288. package/dist/websocket/routes/client/system.d.ts +3 -0
  289. package/dist/websocket/routes/client/system.d.ts.map +1 -0
  290. package/dist/websocket/routes/server/system.d.ts +3 -0
  291. package/dist/websocket/routes/server/system.d.ts.map +1 -0
  292. package/dist/websocket/utils.d.ts +9 -0
  293. package/dist/websocket/utils.d.ts.map +1 -0
  294. package/dist/websocket/websocket-auth.d.ts +17 -0
  295. package/dist/websocket/websocket-auth.d.ts.map +1 -0
  296. package/dist/websocket/websocket-auth.js +46 -0
  297. package/dist/websocket/websocket-auth.js.map +7 -0
  298. package/dist/websocket/websocket-base.d.ts +19 -0
  299. package/dist/websocket/websocket-base.d.ts.map +1 -0
  300. package/dist/websocket/websocket-client-manager.d.ts +53 -0
  301. package/dist/websocket/websocket-client-manager.d.ts.map +1 -0
  302. package/dist/websocket/websocket-client-manager.interface.d.ts +8 -0
  303. package/dist/websocket/websocket-client-manager.interface.d.ts.map +1 -0
  304. package/dist/websocket/websocket-client-manager.js +6 -5
  305. package/dist/websocket/websocket-client-manager.js.map +2 -2
  306. package/dist/websocket/websocket-client.d.ts +64 -0
  307. package/dist/websocket/websocket-client.d.ts.map +1 -0
  308. package/dist/websocket/websocket-client.interface.d.ts +14 -0
  309. package/dist/websocket/websocket-client.interface.d.ts.map +1 -0
  310. package/dist/websocket/websocket-client.js +97 -3
  311. package/dist/websocket/websocket-client.js.map +2 -2
  312. package/dist/websocket/websocket-room-manager.d.ts +32 -0
  313. package/dist/websocket/websocket-room-manager.d.ts.map +1 -0
  314. package/dist/websocket/websocket-server.d.ts +102 -0
  315. package/dist/websocket/websocket-server.d.ts.map +1 -0
  316. package/dist/websocket/websocket-server.interface.d.ts +16 -0
  317. package/dist/websocket/websocket-server.interface.d.ts.map +1 -0
  318. package/dist/websocket/websocket-server.js +62 -50
  319. package/dist/websocket/websocket-server.js.map +2 -2
  320. package/dist/websocket/websocket-service.d.ts +44 -0
  321. package/dist/websocket/websocket-service.d.ts.map +1 -0
  322. package/dist/websocket/websocket.interface.d.ts +137 -0
  323. package/dist/websocket/websocket.interface.d.ts.map +1 -0
  324. package/dist/websocket/websocket.interface.js.map +2 -2
  325. package/package.json +21 -24
  326. package/pxl.js +0 -4
@@ -0,0 +1,32 @@
1
+ import type { Redis } from 'ioredis';
2
+ import type { RedisInstanceProps } from './instance.interface.js';
3
+ export default class RedisInstance {
4
+ private redisManager;
5
+ client: Redis;
6
+ publisherClient: Redis;
7
+ subscriberClient: Redis;
8
+ constructor({ redisManager, client, publisherClient, subscriberClient }: RedisInstanceProps);
9
+ disconnect(): Promise<void>;
10
+ isConnected(): Promise<boolean>;
11
+ /**
12
+ * Sets a value in the cache with an optional expiration time.
13
+ *
14
+ * @param key - The key to set in the cache.
15
+ * @param value - The value to set in the cache.
16
+ * @param expiration - The expiration time in seconds (optional).
17
+ * @throws Error if the value type is not supported.
18
+ * @returns A Promise that resolves when the value is set in the cache.
19
+ */
20
+ setCache({ key, value, expiration, }: {
21
+ key: string;
22
+ value: unknown;
23
+ expiration?: number;
24
+ }): Promise<void>;
25
+ getCache({ key }: {
26
+ key: string;
27
+ }): Promise<string | null>;
28
+ deleteCache({ key }: {
29
+ key: string;
30
+ }): Promise<void>;
31
+ }
32
+ //# sourceMappingURL=instance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/redis/instance.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAGlE,MAAM,CAAC,OAAO,OAAO,aAAa;IAChC,OAAO,CAAC,YAAY,CAAe;IAE5B,MAAM,EAAE,KAAK,CAAC;IACd,eAAe,EAAE,KAAK,CAAC;IACvB,gBAAgB,EAAE,KAAK,CAAC;gBAEnB,EAAE,YAAY,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,EAAE,kBAAkB;IAQ9E,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAsBjC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAgBtC;;;;;;;;OAQG;IACU,QAAQ,CAAC,EACpB,GAAG,EACH,KAAK,EACL,UAAU,GACX,EAAE;QACD,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBJ,QAAQ,CAAC,EAAE,GAAG,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAM1D,WAAW,CAAC,EAAE,GAAG,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAGlE"}
@@ -0,0 +1,9 @@
1
+ import type { Redis } from 'ioredis';
2
+ import type { RedisManager } from './index.js';
3
+ export interface RedisInstanceProps {
4
+ redisManager: RedisManager;
5
+ client: Redis;
6
+ publisherClient: Redis;
7
+ subscriberClient: Redis;
8
+ }
9
+ //# sourceMappingURL=instance.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.interface.d.ts","sourceRoot":"","sources":["../../src/redis/instance.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,KAAK,CAAC;IACd,eAAe,EAAE,KAAK,CAAC;IACvB,gBAAgB,EAAE,KAAK,CAAC;CACzB"}
@@ -0,0 +1,15 @@
1
+ import type { RedisManagerConfig as RedisManagerOptions } from './manager.interface.js';
2
+ import RedisInstance from './instance.js';
3
+ export default class RedisManager {
4
+ private logger;
5
+ private options;
6
+ instances: RedisInstance[];
7
+ constructor(config: RedisManagerOptions);
8
+ connect(): Promise<RedisInstance>;
9
+ disconnect(): Promise<void>;
10
+ /**
11
+ * Log Redis message
12
+ */
13
+ log(message: string, meta?: Record<string, unknown>): void;
14
+ }
15
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/redis/manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,IAAI,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,aAAa,MAAM,eAAe,CAAC;AAwJ1C,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,OAAO,CAAC,MAAM,CAAyB;IAEvC,OAAO,CAAC,OAAO,CAAsB;IAE9B,SAAS,EAAE,aAAa,EAAE,CAAM;gBAE3B,MAAM,EAAE,mBAAmB;IAI1B,OAAO,IAAI,OAAO,CAAC,aAAa,CAAC;IAkGjC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiDxC;;OAEG;IACI,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAGlE"}
@@ -0,0 +1,8 @@
1
+ import type { ApplicationConfig } from '../application/base-application.interface.js';
2
+ export interface RedisManagerConfig {
3
+ applicationConfig: ApplicationConfig;
4
+ host: string;
5
+ port: number;
6
+ password?: string;
7
+ }
8
+ //# sourceMappingURL=manager.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.interface.d.ts","sourceRoot":"","sources":["../../src/redis/manager.interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8CAA8C,CAAC;AAEtF,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
@@ -5,10 +5,21 @@ import { EventEmitter } from "node:events";
5
5
  import RedisInstance from "./instance.js";
6
6
  import { Logger } from "../logger/index.js";
7
7
  import { CachePerformanceWrapper } from "../performance/index.js";
8
+ import { safeSerializeError } from "../error/error-reporter.js";
8
9
  const truthyPattern = /^(1|true|yes|on)$/i;
9
10
  const scheduleMicrotask = typeof globalThis.queueMicrotask === "function" ? globalThis.queueMicrotask.bind(globalThis) : (callback) => {
10
11
  void Promise.resolve().then(callback);
11
12
  };
13
+ let globalInMemoryRedisState = null;
14
+ function getGlobalInMemoryRedisState() {
15
+ globalInMemoryRedisState ??= {
16
+ store: /* @__PURE__ */ new Map(),
17
+ expirations: /* @__PURE__ */ new Map(),
18
+ subscriptions: /* @__PURE__ */ new Map()
19
+ };
20
+ return globalInMemoryRedisState;
21
+ }
22
+ __name(getGlobalInMemoryRedisState, "getGlobalInMemoryRedisState");
12
23
  class InMemoryRedisClient extends EventEmitter {
13
24
  static {
14
25
  __name(this, "InMemoryRedisClient");
@@ -96,14 +107,14 @@ class InMemoryRedisClient extends EventEmitter {
96
107
  }
97
108
  async quit() {
98
109
  this.cleanupSubscriptions();
99
- this.removeAllListeners();
100
110
  this.emit("end");
111
+ this.removeAllListeners();
101
112
  return "OK";
102
113
  }
103
114
  disconnect() {
104
115
  this.cleanupSubscriptions();
105
- this.removeAllListeners();
106
116
  this.emit("end");
117
+ this.removeAllListeners();
107
118
  }
108
119
  }
109
120
  class RedisManager {
@@ -129,20 +140,9 @@ class RedisManager {
129
140
  // Needed for bullmq
130
141
  };
131
142
  const useInMemoryRedis = truthyPattern.test(process.env.PXL_REDIS_IN_MEMORY ?? "") || truthyPattern.test(process.env.REDIS_IN_MEMORY ?? "");
132
- let sharedState;
133
- if (useInMemoryRedis) {
134
- sharedState = {
135
- store: /* @__PURE__ */ new Map(),
136
- expirations: /* @__PURE__ */ new Map(),
137
- subscriptions: /* @__PURE__ */ new Map()
138
- };
139
- }
140
143
  const createClient = /* @__PURE__ */ __name(() => {
141
144
  if (useInMemoryRedis) {
142
- if (!sharedState) {
143
- throw new Error("In-memory Redis shared state not initialized");
144
- }
145
- return new InMemoryRedisClient(sharedState);
145
+ return new InMemoryRedisClient(getGlobalInMemoryRedisState());
146
146
  }
147
147
  return new Redis(redisOptions);
148
148
  }, "createClient");
@@ -191,7 +191,7 @@ class RedisManager {
191
191
  const duration = performance.now() - startTime;
192
192
  await Promise.allSettled([client.quit(), publisherClient.quit(), subscriberClient.quit()]);
193
193
  this.logger.error({
194
- error: error instanceof Error ? error : new Error(String(error)),
194
+ error: error instanceof Error ? error : new Error(safeSerializeError(error)),
195
195
  message: "Redis connection failed",
196
196
  meta: {
197
197
  Host: this.options.host,
@@ -232,7 +232,7 @@ class RedisManager {
232
232
  } catch (error) {
233
233
  const duration = performance.now() - startTime;
234
234
  this.logger.error({
235
- error: error instanceof Error ? error : new Error(String(error)),
235
+ error: error instanceof Error ? error : new Error(safeSerializeError(error)),
236
236
  message: "Redis disconnection failed",
237
237
  meta: {
238
238
  Host: this.options.host,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/redis/manager.ts"],
4
- "sourcesContent": ["import { Redis, type RedisOptions } from 'ioredis';\nimport { EventEmitter } from 'node:events';\nimport type { RedisManagerConfig as RedisManagerOptions } from './manager.interface.js';\nimport RedisInstance from './instance.js';\nimport { Logger } from '../logger/index.js';\nimport { CachePerformanceWrapper } from '../performance/index.js';\n\nconst truthyPattern = /^(1|true|yes|on)$/i;\nconst scheduleMicrotask =\n typeof (globalThis as any).queueMicrotask === 'function'\n ? (globalThis as any).queueMicrotask.bind(globalThis)\n : (callback: () => void) => {\n void Promise.resolve().then(callback);\n };\n\ntype RedisCallback = (error: Error | null, result?: string) => void;\n\ninterface InMemoryRedisSharedState {\n store: Map<string, string | Buffer>;\n expirations: Map<string, NodeJS.Timeout>;\n subscriptions: Map<string, Set<InMemoryRedisClient>>;\n}\n\nclass InMemoryRedisClient extends EventEmitter {\n private shared: InMemoryRedisSharedState;\n\n constructor(shared: InMemoryRedisSharedState) {\n super();\n this.shared = shared;\n\n scheduleMicrotask(() => {\n this.emit('ready');\n });\n }\n\n private cleanupSubscriptions(): void {\n for (const subscribers of this.shared.subscriptions.values()) {\n subscribers.delete(this);\n }\n }\n\n private clearExpirationForKey(key: string): void {\n const timer = this.shared.expirations.get(key);\n if (timer) {\n clearTimeout(timer);\n this.shared.expirations.delete(key);\n }\n }\n\n public ping(callback?: RedisCallback): Promise<string> {\n if (callback) {\n callback(null, 'PONG');\n return Promise.resolve('PONG');\n }\n\n return Promise.resolve('PONG');\n }\n\n public async set(...args: any[]): Promise<'OK'> {\n const [key, value, mode, expiration] = args;\n const serializedValue: string | Buffer = value instanceof Buffer ? value : String(value);\n\n this.shared.store.set(key, serializedValue);\n this.clearExpirationForKey(key);\n\n if (typeof mode === 'string' && mode.toUpperCase() === 'EX' && typeof expiration === 'number') {\n const timer = setTimeout(() => {\n this.shared.store.delete(key);\n this.shared.expirations.delete(key);\n }, expiration * 1000);\n\n if (typeof timer.unref === 'function') {\n timer.unref();\n }\n\n this.shared.expirations.set(key, timer);\n }\n\n return 'OK';\n }\n\n public async get(key: string): Promise<string | null> {\n return (this.shared.store.get(key) as string | undefined) ?? null;\n }\n\n public async del(key: string): Promise<number> {\n const existed = this.shared.store.delete(key);\n this.clearExpirationForKey(key);\n return existed ? 1 : 0;\n }\n\n public async publish(channel: string, message: string): Promise<number> {\n const subscribers = this.shared.subscriptions.get(channel);\n\n if (!subscribers || subscribers.size === 0) {\n return 0;\n }\n\n for (const subscriber of subscribers) {\n scheduleMicrotask(() => {\n subscriber.emit('message', channel, message);\n });\n }\n\n return subscribers.size;\n }\n\n public async subscribe(channel: string): Promise<number> {\n let subscribers = this.shared.subscriptions.get(channel);\n if (!subscribers) {\n subscribers = new Set<InMemoryRedisClient>();\n this.shared.subscriptions.set(channel, subscribers);\n }\n subscribers.add(this);\n return subscribers.size;\n }\n\n public async unsubscribe(channel: string): Promise<number> {\n const subscribers = this.shared.subscriptions.get(channel);\n\n if (!subscribers) {\n return 0;\n }\n\n subscribers.delete(this);\n return subscribers.size;\n }\n\n public async quit(): Promise<'OK'> {\n this.cleanupSubscriptions();\n this.removeAllListeners();\n this.emit('end');\n return 'OK';\n }\n\n public disconnect(): void {\n this.cleanupSubscriptions();\n this.removeAllListeners();\n this.emit('end');\n }\n}\n\nexport default class RedisManager {\n private logger: typeof Logger = Logger;\n\n private options: RedisManagerOptions;\n\n public instances: RedisInstance[] = [];\n\n constructor(config: RedisManagerOptions) {\n this.options = config;\n }\n\n public async connect(): Promise<RedisInstance> {\n return CachePerformanceWrapper.monitorConnection(\n 'connect',\n async () => {\n const startTime = performance.now();\n\n const redisOptions: RedisOptions = {\n host: this.options.host,\n port: this.options.port,\n password: this.options.password,\n maxRetriesPerRequest: null, // Needed for bullmq\n };\n\n const useInMemoryRedis =\n truthyPattern.test(process.env.PXL_REDIS_IN_MEMORY ?? '') ||\n truthyPattern.test(process.env.REDIS_IN_MEMORY ?? '');\n\n let sharedState: InMemoryRedisSharedState | undefined;\n if (useInMemoryRedis) {\n sharedState = {\n store: new Map<string, string | Buffer>(),\n expirations: new Map<string, NodeJS.Timeout>(),\n subscriptions: new Map<string, Set<InMemoryRedisClient>>(),\n };\n }\n\n const createClient = (): Redis => {\n if (useInMemoryRedis) {\n if (!sharedState) {\n throw new Error('In-memory Redis shared state not initialized');\n }\n return new InMemoryRedisClient(sharedState) as unknown as Redis;\n }\n\n return new Redis(redisOptions);\n };\n\n const client = createClient();\n const publisherClient = createClient();\n const subscriberClient = createClient();\n\n try {\n // Wait for all three clients to be ready\n await Promise.all([\n new Promise<void>((resolve, reject) => {\n client.once('ready', () => resolve());\n client.once('error', (error: Error) => reject(error));\n }),\n new Promise<void>((resolve, reject) => {\n publisherClient.once('ready', () => resolve());\n publisherClient.once('error', (error: Error) => reject(error));\n }),\n new Promise<void>((resolve, reject) => {\n subscriberClient.once('ready', () => resolve());\n subscriberClient.once('error', (error: Error) => reject(error));\n }),\n ]);\n\n const redisInstance = new RedisInstance({\n redisManager: this,\n client,\n publisherClient,\n subscriberClient,\n });\n\n this.instances.push(redisInstance);\n\n const duration = performance.now() - startTime;\n const meta = {\n Host: this.options.host,\n Port: this.options.port,\n Duration: `${duration.toFixed(2)}ms`,\n Mode: useInMemoryRedis ? 'in-memory' : 'network',\n };\n\n if (this.options.applicationConfig.log?.startUp) {\n this.log('Connected', meta);\n } else {\n this.logger.debug({ message: 'Redis connected', meta });\n }\n\n if (useInMemoryRedis) {\n this.logger.debug({ message: 'Using in-memory Redis stub' });\n }\n\n return redisInstance;\n } catch (error) {\n const duration = performance.now() - startTime;\n\n // Clean up clients on error\n await Promise.allSettled([client.quit(), publisherClient.quit(), subscriberClient.quit()]);\n\n this.logger.error({\n error: error instanceof Error ? error : new Error(String(error)),\n message: 'Redis connection failed',\n meta: {\n Host: this.options.host,\n Port: this.options.port,\n Duration: `${duration.toFixed(2)}ms`,\n Mode: useInMemoryRedis ? 'in-memory' : 'network',\n },\n });\n\n throw error;\n }\n },\n { host: this.options.host, port: this.options.port },\n );\n }\n\n public async disconnect(): Promise<void> {\n await CachePerformanceWrapper.monitorConnection(\n 'disconnect',\n async () => {\n const startTime = performance.now();\n const instanceCount = this.instances.length;\n\n try {\n await Promise.all(this.instances.map(instance => instance.disconnect()));\n\n const duration = performance.now() - startTime;\n\n if (instanceCount > 0) {\n const meta = {\n Instances: instanceCount,\n Host: this.options.host,\n Port: this.options.port,\n Duration: `${duration.toFixed(2)}ms`,\n };\n\n if (this.options.applicationConfig.log?.startUp) {\n this.log('Disconnected all Redis instances', meta);\n } else {\n this.logger.debug({ message: 'Redis instances disconnected', meta });\n }\n }\n\n this.instances = [];\n } catch (error) {\n const duration = performance.now() - startTime;\n\n this.logger.error({\n error: error instanceof Error ? error : new Error(String(error)),\n message: 'Redis disconnection failed',\n meta: {\n Host: this.options.host,\n Port: this.options.port,\n Instances: instanceCount,\n Duration: `${duration.toFixed(2)}ms`,\n },\n });\n\n throw error;\n }\n },\n { host: this.options.host, port: this.options.port },\n );\n }\n\n /**\n * Log Redis message\n */\n public log(message: string, meta?: Record<string, unknown>): void {\n this.logger.custom({ level: 'redis', message, meta });\n }\n}\n"],
5
- "mappings": ";;AAAA,SAAS,aAAgC;AACzC,SAAS,oBAAoB;AAE7B,OAAO,mBAAmB;AAC1B,SAAS,cAAc;AACvB,SAAS,+BAA+B;AAExC,MAAM,gBAAgB;AACtB,MAAM,oBACJ,OAAQ,WAAmB,mBAAmB,aACzC,WAAmB,eAAe,KAAK,UAAU,IAClD,CAAC,aAAyB;AACxB,OAAK,QAAQ,QAAQ,EAAE,KAAK,QAAQ;AACtC;AAUN,MAAM,4BAA4B,aAAa;AAAA,EAvB/C,OAuB+C;AAAA;AAAA;AAAA,EACrC;AAAA,EAER,YAAY,QAAkC;AAC5C,UAAM;AACN,SAAK,SAAS;AAEd,sBAAkB,MAAM;AACtB,WAAK,KAAK,OAAO;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEQ,uBAA6B;AACnC,eAAW,eAAe,KAAK,OAAO,cAAc,OAAO,GAAG;AAC5D,kBAAY,OAAO,IAAI;AAAA,IACzB;AAAA,EACF;AAAA,EAEQ,sBAAsB,KAAmB;AAC/C,UAAM,QAAQ,KAAK,OAAO,YAAY,IAAI,GAAG;AAC7C,QAAI,OAAO;AACT,mBAAa,KAAK;AAClB,WAAK,OAAO,YAAY,OAAO,GAAG;AAAA,IACpC;AAAA,EACF;AAAA,EAEO,KAAK,UAA2C;AACrD,QAAI,UAAU;AACZ,eAAS,MAAM,MAAM;AACrB,aAAO,QAAQ,QAAQ,MAAM;AAAA,IAC/B;AAEA,WAAO,QAAQ,QAAQ,MAAM;AAAA,EAC/B;AAAA,EAEA,MAAa,OAAO,MAA4B;AAC9C,UAAM,CAAC,KAAK,OAAO,MAAM,UAAU,IAAI;AACvC,UAAM,kBAAmC,iBAAiB,SAAS,QAAQ,OAAO,KAAK;AAEvF,SAAK,OAAO,MAAM,IAAI,KAAK,eAAe;AAC1C,SAAK,sBAAsB,GAAG;AAE9B,QAAI,OAAO,SAAS,YAAY,KAAK,YAAY,MAAM,QAAQ,OAAO,eAAe,UAAU;AAC7F,YAAM,QAAQ,WAAW,MAAM;AAC7B,aAAK,OAAO,MAAM,OAAO,GAAG;AAC5B,aAAK,OAAO,YAAY,OAAO,GAAG;AAAA,MACpC,GAAG,aAAa,GAAI;AAEpB,UAAI,OAAO,MAAM,UAAU,YAAY;AACrC,cAAM,MAAM;AAAA,MACd;AAEA,WAAK,OAAO,YAAY,IAAI,KAAK,KAAK;AAAA,IACxC;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,MAAa,IAAI,KAAqC;AACpD,WAAQ,KAAK,OAAO,MAAM,IAAI,GAAG,KAA4B;AAAA,EAC/D;AAAA,EAEA,MAAa,IAAI,KAA8B;AAC7C,UAAM,UAAU,KAAK,OAAO,MAAM,OAAO,GAAG;AAC5C,SAAK,sBAAsB,GAAG;AAC9B,WAAO,UAAU,IAAI;AAAA,EACvB;AAAA,EAEA,MAAa,QAAQ,SAAiB,SAAkC;AACtE,UAAM,cAAc,KAAK,OAAO,cAAc,IAAI,OAAO;AAEzD,QAAI,CAAC,eAAe,YAAY,SAAS,GAAG;AAC1C,aAAO;AAAA,IACT;AAEA,eAAW,cAAc,aAAa;AACpC,wBAAkB,MAAM;AACtB,mBAAW,KAAK,WAAW,SAAS,OAAO;AAAA,MAC7C,CAAC;AAAA,IACH;AAEA,WAAO,YAAY;AAAA,EACrB;AAAA,EAEA,MAAa,UAAU,SAAkC;AACvD,QAAI,cAAc,KAAK,OAAO,cAAc,IAAI,OAAO;AACvD,QAAI,CAAC,aAAa;AAChB,oBAAc,oBAAI,IAAyB;AAC3C,WAAK,OAAO,cAAc,IAAI,SAAS,WAAW;AAAA,IACpD;AACA,gBAAY,IAAI,IAAI;AACpB,WAAO,YAAY;AAAA,EACrB;AAAA,EAEA,MAAa,YAAY,SAAkC;AACzD,UAAM,cAAc,KAAK,OAAO,cAAc,IAAI,OAAO;AAEzD,QAAI,CAAC,aAAa;AAChB,aAAO;AAAA,IACT;AAEA,gBAAY,OAAO,IAAI;AACvB,WAAO,YAAY;AAAA,EACrB;AAAA,EAEA,MAAa,OAAsB;AACjC,SAAK,qBAAqB;AAC1B,SAAK,mBAAmB;AACxB,SAAK,KAAK,KAAK;AACf,WAAO;AAAA,EACT;AAAA,EAEO,aAAmB;AACxB,SAAK,qBAAqB;AAC1B,SAAK,mBAAmB;AACxB,SAAK,KAAK,KAAK;AAAA,EACjB;AACF;AAEA,MAAO,aAA2B;AAAA,EA9IlC,OA8IkC;AAAA;AAAA;AAAA,EACxB,SAAwB;AAAA,EAExB;AAAA,EAED,YAA6B,CAAC;AAAA,EAErC,YAAY,QAA6B;AACvC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAa,UAAkC;AAC7C,WAAO,wBAAwB;AAAA,MAC7B;AAAA,MACA,YAAY;AACV,cAAM,YAAY,YAAY,IAAI;AAElC,cAAM,eAA6B;AAAA,UACjC,MAAM,KAAK,QAAQ;AAAA,UACnB,MAAM,KAAK,QAAQ;AAAA,UACnB,UAAU,KAAK,QAAQ;AAAA,UACvB,sBAAsB;AAAA;AAAA,QACxB;AAEA,cAAM,mBACJ,cAAc,KAAK,QAAQ,IAAI,uBAAuB,EAAE,KACxD,cAAc,KAAK,QAAQ,IAAI,mBAAmB,EAAE;AAEtD,YAAI;AACJ,YAAI,kBAAkB;AACpB,wBAAc;AAAA,YACZ,OAAO,oBAAI,IAA6B;AAAA,YACxC,aAAa,oBAAI,IAA4B;AAAA,YAC7C,eAAe,oBAAI,IAAsC;AAAA,UAC3D;AAAA,QACF;AAEA,cAAM,eAAe,6BAAa;AAChC,cAAI,kBAAkB;AACpB,gBAAI,CAAC,aAAa;AAChB,oBAAM,IAAI,MAAM,8CAA8C;AAAA,YAChE;AACA,mBAAO,IAAI,oBAAoB,WAAW;AAAA,UAC5C;AAEA,iBAAO,IAAI,MAAM,YAAY;AAAA,QAC/B,GATqB;AAWrB,cAAM,SAAS,aAAa;AAC5B,cAAM,kBAAkB,aAAa;AACrC,cAAM,mBAAmB,aAAa;AAEtC,YAAI;AAEF,gBAAM,QAAQ,IAAI;AAAA,YAChB,IAAI,QAAc,CAAC,SAAS,WAAW;AACrC,qBAAO,KAAK,SAAS,MAAM,QAAQ,CAAC;AACpC,qBAAO,KAAK,SAAS,CAAC,UAAiB,OAAO,KAAK,CAAC;AAAA,YACtD,CAAC;AAAA,YACD,IAAI,QAAc,CAAC,SAAS,WAAW;AACrC,8BAAgB,KAAK,SAAS,MAAM,QAAQ,CAAC;AAC7C,8BAAgB,KAAK,SAAS,CAAC,UAAiB,OAAO,KAAK,CAAC;AAAA,YAC/D,CAAC;AAAA,YACD,IAAI,QAAc,CAAC,SAAS,WAAW;AACrC,+BAAiB,KAAK,SAAS,MAAM,QAAQ,CAAC;AAC9C,+BAAiB,KAAK,SAAS,CAAC,UAAiB,OAAO,KAAK,CAAC;AAAA,YAChE,CAAC;AAAA,UACH,CAAC;AAED,gBAAM,gBAAgB,IAAI,cAAc;AAAA,YACtC,cAAc;AAAA,YACd;AAAA,YACA;AAAA,YACA;AAAA,UACF,CAAC;AAED,eAAK,UAAU,KAAK,aAAa;AAEjC,gBAAM,WAAW,YAAY,IAAI,IAAI;AACrC,gBAAM,OAAO;AAAA,YACX,MAAM,KAAK,QAAQ;AAAA,YACnB,MAAM,KAAK,QAAQ;AAAA,YACnB,UAAU,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,YAChC,MAAM,mBAAmB,cAAc;AAAA,UACzC;AAEA,cAAI,KAAK,QAAQ,kBAAkB,KAAK,SAAS;AAC/C,iBAAK,IAAI,aAAa,IAAI;AAAA,UAC5B,OAAO;AACL,iBAAK,OAAO,MAAM,EAAE,SAAS,mBAAmB,KAAK,CAAC;AAAA,UACxD;AAEA,cAAI,kBAAkB;AACpB,iBAAK,OAAO,MAAM,EAAE,SAAS,6BAA6B,CAAC;AAAA,UAC7D;AAEA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,WAAW,YAAY,IAAI,IAAI;AAGrC,gBAAM,QAAQ,WAAW,CAAC,OAAO,KAAK,GAAG,gBAAgB,KAAK,GAAG,iBAAiB,KAAK,CAAC,CAAC;AAEzF,eAAK,OAAO,MAAM;AAAA,YAChB,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,YAC/D,SAAS;AAAA,YACT,MAAM;AAAA,cACJ,MAAM,KAAK,QAAQ;AAAA,cACnB,MAAM,KAAK,QAAQ;AAAA,cACnB,UAAU,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,cAChC,MAAM,mBAAmB,cAAc;AAAA,YACzC;AAAA,UACF,CAAC;AAED,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,EAAE,MAAM,KAAK,QAAQ,MAAM,MAAM,KAAK,QAAQ,KAAK;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,MAAa,aAA4B;AACvC,UAAM,wBAAwB;AAAA,MAC5B;AAAA,MACA,YAAY;AACV,cAAM,YAAY,YAAY,IAAI;AAClC,cAAM,gBAAgB,KAAK,UAAU;AAErC,YAAI;AACF,gBAAM,QAAQ,IAAI,KAAK,UAAU,IAAI,cAAY,SAAS,WAAW,CAAC,CAAC;AAEvE,gBAAM,WAAW,YAAY,IAAI,IAAI;AAErC,cAAI,gBAAgB,GAAG;AACrB,kBAAM,OAAO;AAAA,cACX,WAAW;AAAA,cACX,MAAM,KAAK,QAAQ;AAAA,cACnB,MAAM,KAAK,QAAQ;AAAA,cACnB,UAAU,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,YAClC;AAEA,gBAAI,KAAK,QAAQ,kBAAkB,KAAK,SAAS;AAC/C,mBAAK,IAAI,oCAAoC,IAAI;AAAA,YACnD,OAAO;AACL,mBAAK,OAAO,MAAM,EAAE,SAAS,gCAAgC,KAAK,CAAC;AAAA,YACrE;AAAA,UACF;AAEA,eAAK,YAAY,CAAC;AAAA,QACpB,SAAS,OAAO;AACd,gBAAM,WAAW,YAAY,IAAI,IAAI;AAErC,eAAK,OAAO,MAAM;AAAA,YAChB,OAAO,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,YAC/D,SAAS;AAAA,YACT,MAAM;AAAA,cACJ,MAAM,KAAK,QAAQ;AAAA,cACnB,MAAM,KAAK,QAAQ;AAAA,cACnB,WAAW;AAAA,cACX,UAAU,GAAG,SAAS,QAAQ,CAAC,CAAC;AAAA,YAClC;AAAA,UACF,CAAC;AAED,gBAAM;AAAA,QACR;AAAA,MACF;AAAA,MACA,EAAE,MAAM,KAAK,QAAQ,MAAM,MAAM,KAAK,QAAQ,KAAK;AAAA,IACrD;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKO,IAAI,SAAiB,MAAsC;AAChE,SAAK,OAAO,OAAO,EAAE,OAAO,SAAS,SAAS,KAAK,CAAC;AAAA,EACtD;AACF;",
4
+ "sourcesContent": ["import { Redis, type RedisOptions } from 'ioredis';\nimport { EventEmitter } from 'node:events';\nimport type { RedisManagerConfig as RedisManagerOptions } from './manager.interface.js';\nimport RedisInstance from './instance.js';\nimport { Logger } from '../logger/index.js';\nimport { CachePerformanceWrapper } from '../performance/index.js';\nimport { safeSerializeError } from '../error/error-reporter.js';\n\nconst truthyPattern = /^(1|true|yes|on)$/i;\nconst scheduleMicrotask =\n typeof (globalThis as any).queueMicrotask === 'function'\n ? (globalThis as any).queueMicrotask.bind(globalThis)\n : (callback: () => void) => {\n void Promise.resolve().then(callback);\n };\n\ntype RedisCallback = (error: Error | null, result?: string) => void;\n\ninterface InMemoryRedisSharedState {\n store: Map<string, string | Buffer>;\n expirations: Map<string, NodeJS.Timeout>;\n subscriptions: Map<string, Set<InMemoryRedisClient>>;\n}\n\n// Global singleton shared state for in-memory Redis\nlet globalInMemoryRedisState: InMemoryRedisSharedState | null = null;\n\nfunction getGlobalInMemoryRedisState(): InMemoryRedisSharedState {\n globalInMemoryRedisState ??= {\n store: new Map<string, string | Buffer>(),\n expirations: new Map<string, NodeJS.Timeout>(),\n subscriptions: new Map<string, Set<InMemoryRedisClient>>(),\n };\n return globalInMemoryRedisState;\n}\n\nclass InMemoryRedisClient extends EventEmitter {\n private shared: InMemoryRedisSharedState;\n\n constructor(shared: InMemoryRedisSharedState) {\n super();\n this.shared = shared;\n\n scheduleMicrotask(() => {\n this.emit('ready');\n });\n }\n\n private cleanupSubscriptions(): void {\n for (const subscribers of this.shared.subscriptions.values()) {\n subscribers.delete(this);\n }\n }\n\n private clearExpirationForKey(key: string): void {\n const timer = this.shared.expirations.get(key);\n if (timer) {\n clearTimeout(timer);\n this.shared.expirations.delete(key);\n }\n }\n\n public ping(callback?: RedisCallback): Promise<string> {\n if (callback) {\n callback(null, 'PONG');\n return Promise.resolve('PONG');\n }\n\n return Promise.resolve('PONG');\n }\n\n public async set(...args: any[]): Promise<'OK'> {\n const [key, value, mode, expiration] = args;\n const serializedValue: string | Buffer = value instanceof Buffer ? value : String(value);\n\n this.shared.store.set(key, serializedValue);\n this.clearExpirationForKey(key);\n\n if (typeof mode === 'string' && mode.toUpperCase() === 'EX' && typeof expiration === 'number') {\n const timer = setTimeout(() => {\n this.shared.store.delete(key);\n this.shared.expirations.delete(key);\n }, expiration * 1000);\n\n if (typeof timer.unref === 'function') {\n timer.unref();\n }\n\n this.shared.expirations.set(key, timer);\n }\n\n return 'OK';\n }\n\n public async get(key: string): Promise<string | null> {\n return (this.shared.store.get(key) as string | undefined) ?? null;\n }\n\n public async del(key: string): Promise<number> {\n const existed = this.shared.store.delete(key);\n this.clearExpirationForKey(key);\n return existed ? 1 : 0;\n }\n\n public async publish(channel: string, message: string): Promise<number> {\n const subscribers = this.shared.subscriptions.get(channel);\n\n if (!subscribers || subscribers.size === 0) {\n return 0;\n }\n\n for (const subscriber of subscribers) {\n scheduleMicrotask(() => {\n subscriber.emit('message', channel, message);\n });\n }\n\n return subscribers.size;\n }\n\n public async subscribe(channel: string): Promise<number> {\n let subscribers = this.shared.subscriptions.get(channel);\n if (!subscribers) {\n subscribers = new Set<InMemoryRedisClient>();\n this.shared.subscriptions.set(channel, subscribers);\n }\n subscribers.add(this);\n return subscribers.size;\n }\n\n public async unsubscribe(channel: string): Promise<number> {\n const subscribers = this.shared.subscriptions.get(channel);\n\n if (!subscribers) {\n return 0;\n }\n\n subscribers.delete(this);\n return subscribers.size;\n }\n\n public async quit(): Promise<'OK'> {\n this.cleanupSubscriptions();\n this.emit('end');\n this.removeAllListeners();\n return 'OK';\n }\n\n public disconnect(): void {\n this.cleanupSubscriptions();\n this.emit('end');\n this.removeAllListeners();\n }\n}\n\nexport default class RedisManager {\n private logger: typeof Logger = Logger;\n\n private options: RedisManagerOptions;\n\n public instances: RedisInstance[] = [];\n\n constructor(config: RedisManagerOptions) {\n this.options = config;\n }\n\n public async connect(): Promise<RedisInstance> {\n return CachePerformanceWrapper.monitorConnection(\n 'connect',\n async () => {\n const startTime = performance.now();\n\n const redisOptions: RedisOptions = {\n host: this.options.host,\n port: this.options.port,\n password: this.options.password,\n maxRetriesPerRequest: null, // Needed for bullmq\n };\n\n const useInMemoryRedis =\n truthyPattern.test(process.env.PXL_REDIS_IN_MEMORY ?? '') ||\n truthyPattern.test(process.env.REDIS_IN_MEMORY ?? '');\n\n const createClient = (): Redis => {\n if (useInMemoryRedis) {\n return new InMemoryRedisClient(getGlobalInMemoryRedisState()) as unknown as Redis;\n }\n\n return new Redis(redisOptions);\n };\n\n const client = createClient();\n const publisherClient = createClient();\n const subscriberClient = createClient();\n\n try {\n // Wait for all three clients to be ready\n await Promise.all([\n new Promise<void>((resolve, reject) => {\n client.once('ready', () => resolve());\n client.once('error', (error: Error) => reject(error));\n }),\n new Promise<void>((resolve, reject) => {\n publisherClient.once('ready', () => resolve());\n publisherClient.once('error', (error: Error) => reject(error));\n }),\n new Promise<void>((resolve, reject) => {\n subscriberClient.once('ready', () => resolve());\n subscriberClient.once('error', (error: Error) => reject(error));\n }),\n ]);\n\n const redisInstance = new RedisInstance({\n redisManager: this,\n client,\n publisherClient,\n subscriberClient,\n });\n\n this.instances.push(redisInstance);\n\n const duration = performance.now() - startTime;\n const meta = {\n Host: this.options.host,\n Port: this.options.port,\n Duration: `${duration.toFixed(2)}ms`,\n Mode: useInMemoryRedis ? 'in-memory' : 'network',\n };\n\n if (this.options.applicationConfig.log?.startUp) {\n this.log('Connected', meta);\n } else {\n this.logger.debug({ message: 'Redis connected', meta });\n }\n\n if (useInMemoryRedis) {\n this.logger.debug({ message: 'Using in-memory Redis stub' });\n }\n\n return redisInstance;\n } catch (error) {\n const duration = performance.now() - startTime;\n\n // Clean up clients on error\n await Promise.allSettled([client.quit(), publisherClient.quit(), subscriberClient.quit()]);\n\n this.logger.error({\n error: error instanceof Error ? error : new Error(safeSerializeError(error)),\n message: 'Redis connection failed',\n meta: {\n Host: this.options.host,\n Port: this.options.port,\n Duration: `${duration.toFixed(2)}ms`,\n Mode: useInMemoryRedis ? 'in-memory' : 'network',\n },\n });\n\n throw error;\n }\n },\n { host: this.options.host, port: this.options.port },\n );\n }\n\n public async disconnect(): Promise<void> {\n await CachePerformanceWrapper.monitorConnection(\n 'disconnect',\n async () => {\n const startTime = performance.now();\n const instanceCount = this.instances.length;\n\n try {\n await Promise.all(this.instances.map(instance => instance.disconnect()));\n\n const duration = performance.now() - startTime;\n\n if (instanceCount > 0) {\n const meta = {\n Instances: instanceCount,\n Host: this.options.host,\n Port: this.options.port,\n Duration: `${duration.toFixed(2)}ms`,\n };\n\n if (this.options.applicationConfig.log?.startUp) {\n this.log('Disconnected all Redis instances', meta);\n } else {\n this.logger.debug({ message: 'Redis instances disconnected', meta });\n }\n }\n\n this.instances = [];\n } catch (error) {\n const duration = performance.now() - startTime;\n\n this.logger.error({\n error: error instanceof Error ? error : new Error(safeSerializeError(error)),\n message: 'Redis disconnection failed',\n meta: {\n Host: this.options.host,\n Port: this.options.port,\n Instances: instanceCount,\n Duration: `${duration.toFixed(2)}ms`,\n },\n });\n\n throw error;\n }\n },\n { host: this.options.host, port: this.options.port },\n );\n }\n\n /**\n * Log Redis message\n */\n public log(message: string, meta?: Record<string, unknown>): void {\n this.logger.custom({ level: 'redis', message, meta });\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,3 @@
1
+ export type { RequestContext, RunWithContextOptions } from './request-context.interface.js';
2
+ export { getRequestContext, getRequestId, getUserId, setUserId, getContextMetadata, setContextMetadata, runWithContext, runWithContextAsync, enterRequestContext, requestContextStorage, } from './request-context.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/request-context/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5F,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,SAAS,EACT,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,108 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import type { RequestContext, RunWithContextOptions } from './request-context.interface.js';
3
+ /**
4
+ * AsyncLocalStorage instance for request context
5
+ *
6
+ * This provides request-scoped storage that automatically propagates through
7
+ * async operations, enabling correlation IDs and request metadata to be
8
+ * accessible throughout the request lifecycle without explicit passing.
9
+ */
10
+ declare const requestContextStorage: AsyncLocalStorage<RequestContext>;
11
+ /**
12
+ * Get the current request context
13
+ *
14
+ * @returns The current request context, or undefined if not in a request context
15
+ *
16
+ * @example
17
+ * const context = getRequestContext();
18
+ * if (context) {
19
+ * console.log('Request ID:', context.requestId);
20
+ * }
21
+ */
22
+ export declare function getRequestContext(): RequestContext | undefined;
23
+ /**
24
+ * Get the current request ID
25
+ *
26
+ * @returns The current request ID, or undefined if not in a request context
27
+ *
28
+ * @example
29
+ * const requestId = getRequestId();
30
+ * logger.info({ message: 'Processing request', requestId });
31
+ */
32
+ export declare function getRequestId(): string | undefined;
33
+ /**
34
+ * Set metadata in the current request context
35
+ *
36
+ * @param key - Metadata key
37
+ * @param value - Metadata value
38
+ *
39
+ * @example
40
+ * setContextMetadata('operation', 'userLookup');
41
+ * setContextMetadata('cacheHit', true);
42
+ */
43
+ export declare function setContextMetadata(key: string, value: unknown): void;
44
+ /**
45
+ * Get metadata from the current request context
46
+ *
47
+ * @param key - Metadata key
48
+ * @returns Metadata value, or undefined if not found
49
+ */
50
+ export declare function getContextMetadata(key: string): unknown;
51
+ /**
52
+ * Run a function within a new request context
53
+ *
54
+ * @param options - Context options (requestId will be generated if not provided)
55
+ * @param fn - Function to run within the context
56
+ * @returns The result of the function
57
+ *
58
+ * @example
59
+ * await runWithContext({ requestId: 'custom-id' }, async () => {
60
+ * await processRequest();
61
+ * });
62
+ */
63
+ export declare function runWithContext<T>(options: RunWithContextOptions | undefined, fn: () => T): T;
64
+ /**
65
+ * Run a function within a new request context (async version)
66
+ *
67
+ * @param options - Context options (requestId will be generated if not provided)
68
+ * @param fn - Async function to run within the context
69
+ * @returns Promise resolving to the result of the function
70
+ *
71
+ * @example
72
+ * await runWithContextAsync({ requestId: 'custom-id' }, async () => {
73
+ * await processRequest();
74
+ * });
75
+ */
76
+ export declare function runWithContextAsync<T>(options: RunWithContextOptions | undefined, fn: () => Promise<T>): Promise<T>;
77
+ /**
78
+ * Update the user ID in the current request context
79
+ *
80
+ * @param userId - User ID to set
81
+ *
82
+ * @example
83
+ * // After authentication
84
+ * setUserId(authenticatedUser.id);
85
+ */
86
+ export declare function setUserId(userId: string): void;
87
+ /**
88
+ * Get the user ID from the current request context
89
+ *
90
+ * @returns The current user ID, or undefined if not set
91
+ */
92
+ export declare function getUserId(): string | undefined;
93
+ /**
94
+ * Enter a new request context (advanced usage for middleware)
95
+ *
96
+ * This sets the context for the current async execution context without
97
+ * wrapping in a callback. Use with caution - prefer runWithContext when possible.
98
+ *
99
+ * @param options - Context options
100
+ *
101
+ * @example
102
+ * // In Fastify middleware
103
+ * const requestId = req.headers['x-request-id'] || crypto.randomUUID();
104
+ * enterRequestContext({ requestId });
105
+ */
106
+ export declare function enterRequestContext(options: RunWithContextOptions): void;
107
+ export { requestContextStorage };
108
+ //# sourceMappingURL=request-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../../src/request-context/request-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAE5F;;;;;;GAMG;AACH,QAAA,MAAM,qBAAqB,mCAA0C,CAAC;AAEtE;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,SAAS,CAE9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAEjD;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAOpE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,qBAAqB,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAS5F;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,OAAO,EAAE,qBAAqB,GAAG,SAAS,EAC1C,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CASZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAK9C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,MAAM,GAAG,SAAS,CAE9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CASxE;AAGD,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Request context interface
3
+ *
4
+ * This interface defines the shape of the context stored in AsyncLocalStorage
5
+ * for each HTTP request, providing correlation IDs and request metadata.
6
+ */
7
+ export interface RequestContext {
8
+ /**
9
+ * Unique request ID (UUID v4/v7) for tracing/correlation
10
+ */
11
+ requestId: string;
12
+ /**
13
+ * Request start time (performance.now() timestamp)
14
+ */
15
+ startTime?: number;
16
+ /**
17
+ * Authenticated user ID (if available)
18
+ */
19
+ userId?: string;
20
+ /**
21
+ * Additional custom metadata
22
+ */
23
+ metadata?: Record<string, unknown>;
24
+ }
25
+ /**
26
+ * Options for running code within a request context
27
+ */
28
+ export interface RunWithContextOptions {
29
+ /**
30
+ * Request ID to use (generated if not provided)
31
+ */
32
+ requestId?: string;
33
+ /**
34
+ * Request start time
35
+ */
36
+ startTime?: number;
37
+ /**
38
+ * User ID
39
+ */
40
+ userId?: string;
41
+ /**
42
+ * Additional metadata
43
+ */
44
+ metadata?: Record<string, unknown>;
45
+ }
46
+ //# sourceMappingURL=request-context.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.interface.d.ts","sourceRoot":"","sources":["../../src/request-context/request-context.interface.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC"}
@@ -0,0 +1,197 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * Common Zod schemas for reuse across the framework
4
+ */
5
+ /**
6
+ * Numeric ID schema (positive integer)
7
+ */
8
+ export declare const NumericIdSchema: z.ZodCoercedNumber<unknown>;
9
+ /**
10
+ * UUID v4 schema
11
+ */
12
+ export declare const UuidSchema: z.ZodString;
13
+ /**
14
+ * Optional numeric ID (for updates where ID may not be required)
15
+ */
16
+ export declare const OptionalNumericIdSchema: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
17
+ /**
18
+ * Pagination query parameters schema
19
+ */
20
+ export declare const PaginationQuerySchema: z.ZodObject<{
21
+ page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
22
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
23
+ }, z.core.$strip>;
24
+ /**
25
+ * Inferred type for pagination query
26
+ */
27
+ export type PaginationQuery = z.infer<typeof PaginationQuerySchema>;
28
+ /**
29
+ * Paginated response wrapper schema
30
+ */
31
+ export declare const createPaginatedResponseSchema: <T extends z.ZodTypeAny>(itemSchema: T) => z.ZodObject<{
32
+ data: z.ZodArray<T>;
33
+ total_items: z.ZodNumber;
34
+ page: z.ZodNumber;
35
+ total_pages: z.ZodNumber;
36
+ limit: z.ZodNumber;
37
+ }, z.core.$strip>;
38
+ /**
39
+ * Helper type for paginated response
40
+ */
41
+ export type PaginatedResponse<T> = {
42
+ data: T[];
43
+ total_items: number;
44
+ page: number;
45
+ total_pages: number;
46
+ limit: number;
47
+ };
48
+ /**
49
+ * Sort order schema
50
+ */
51
+ export declare const SortOrderSchema: z.ZodDefault<z.ZodEnum<{
52
+ ASC: "ASC";
53
+ DESC: "DESC";
54
+ asc: "asc";
55
+ desc: "desc";
56
+ }>>;
57
+ /**
58
+ * Generic sort query schema
59
+ */
60
+ export declare const SortQuerySchema: z.ZodObject<{
61
+ sort: z.ZodOptional<z.ZodString>;
62
+ 'sort-order': z.ZodOptional<z.ZodDefault<z.ZodEnum<{
63
+ ASC: "ASC";
64
+ DESC: "DESC";
65
+ asc: "asc";
66
+ desc: "desc";
67
+ }>>>;
68
+ }, z.core.$strip>;
69
+ /**
70
+ * Search query schema
71
+ */
72
+ export declare const SearchQuerySchema: z.ZodObject<{
73
+ search: z.ZodOptional<z.ZodString>;
74
+ }, z.core.$strip>;
75
+ /**
76
+ * Combined list query schema (pagination + sorting + search)
77
+ */
78
+ export declare const ListQuerySchema: z.ZodObject<{
79
+ page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
80
+ limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
81
+ sort: z.ZodOptional<z.ZodString>;
82
+ 'sort-order': z.ZodOptional<z.ZodDefault<z.ZodEnum<{
83
+ ASC: "ASC";
84
+ DESC: "DESC";
85
+ asc: "asc";
86
+ desc: "desc";
87
+ }>>>;
88
+ search: z.ZodOptional<z.ZodString>;
89
+ }, z.core.$strip>;
90
+ /**
91
+ * Inferred type for list query
92
+ */
93
+ export type ListQuery = z.infer<typeof ListQuerySchema>;
94
+ /**
95
+ * Success response wrapper schema
96
+ */
97
+ export declare const createSuccessResponseSchema: <T extends z.ZodTypeAny>(dataSchema: T) => z.ZodObject<{
98
+ data: T;
99
+ }, z.core.$strip>;
100
+ /**
101
+ * Error response schema
102
+ */
103
+ export declare const ErrorResponseSchema: z.ZodObject<{
104
+ error: z.ZodString;
105
+ message: z.ZodOptional<z.ZodString>;
106
+ statusCode: z.ZodOptional<z.ZodNumber>;
107
+ details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
108
+ }, z.core.$strip>;
109
+ /**
110
+ * Inferred type for error response
111
+ */
112
+ export type ErrorResponse = z.infer<typeof ErrorResponseSchema>;
113
+ /**
114
+ * Generic API response schema (success or error)
115
+ */
116
+ export declare const createApiResponseSchema: <T extends z.ZodTypeAny>(dataSchema: T) => z.ZodUnion<readonly [z.ZodObject<{
117
+ data: T;
118
+ }, z.core.$strip>, z.ZodObject<{
119
+ error: z.ZodString;
120
+ message: z.ZodOptional<z.ZodString>;
121
+ statusCode: z.ZodOptional<z.ZodNumber>;
122
+ details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
123
+ }, z.core.$strip>]>;
124
+ /**
125
+ * Email schema
126
+ */
127
+ export declare const EmailSchema: z.ZodString;
128
+ /**
129
+ * URL schema
130
+ */
131
+ export declare const UrlSchema: z.ZodString;
132
+ /**
133
+ * Phone number schema (basic validation)
134
+ */
135
+ export declare const PhoneSchema: z.ZodString;
136
+ /**
137
+ * Date string schema (ISO 8601)
138
+ */
139
+ export declare const DateStringSchema: z.ZodString;
140
+ /**
141
+ * Non-empty string schema
142
+ */
143
+ export declare const NonEmptyStringSchema: z.ZodString;
144
+ /**
145
+ * Trimmed non-empty string schema
146
+ */
147
+ export declare const TrimmedStringSchema: z.ZodString;
148
+ /**
149
+ * Boolean schema with string coercion
150
+ */
151
+ export declare const BooleanSchema: z.ZodPipe<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>, z.ZodTransform<boolean, string | boolean>>;
152
+ /**
153
+ * Created/Updated timestamp schema
154
+ */
155
+ export declare const TimestampSchema: z.ZodObject<{
156
+ createdAt: z.ZodDate;
157
+ updatedAt: z.ZodDate;
158
+ }, z.core.$strip>;
159
+ /**
160
+ * Optional timestamp schema
161
+ */
162
+ export declare const OptionalTimestampSchema: z.ZodObject<{
163
+ createdAt: z.ZodOptional<z.ZodDate>;
164
+ updatedAt: z.ZodOptional<z.ZodDate>;
165
+ }, z.core.$strip>;
166
+ /**
167
+ * Comma-separated string to array transformer
168
+ */
169
+ export declare const CommaSeparatedStringSchema: z.ZodPipe<z.ZodString, z.ZodTransform<string[], string>>;
170
+ /**
171
+ * JSON string schema (parses JSON string to object)
172
+ */
173
+ export declare const JsonStringSchema: z.ZodPipe<z.ZodString, z.ZodTransform<any, string>>;
174
+ /**
175
+ * Health check response schema
176
+ */
177
+ export declare const HealthCheckResponseSchema: z.ZodObject<{
178
+ status: z.ZodEnum<{
179
+ healthy: "healthy";
180
+ unhealthy: "unhealthy";
181
+ degraded: "degraded";
182
+ }>;
183
+ timestamp: z.ZodString;
184
+ services: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
185
+ status: z.ZodEnum<{
186
+ degraded: "degraded";
187
+ up: "up";
188
+ down: "down";
189
+ }>;
190
+ message: z.ZodOptional<z.ZodString>;
191
+ }, z.core.$strip>>>;
192
+ }, z.core.$strip>;
193
+ /**
194
+ * Inferred type for health check response
195
+ */
196
+ export type HealthCheckResponse = z.infer<typeof HealthCheckResponseSchema>;
197
+ //# sourceMappingURL=common.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/schemas/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AAMH;;GAEG;AACH,eAAO,MAAM,eAAe,6BAAqC,CAAC;AAElE;;GAEG;AACH,eAAO,MAAM,UAAU,aAAoB,CAAC;AAE5C;;GAEG;AACH,eAAO,MAAM,uBAAuB,4CAA6B,CAAC;AAMlE;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;iBAGhC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE;;GAEG;AACH,eAAO,MAAM,6BAA6B,GAAI,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC;;;;;;iBAQlF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI;IACjC,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;GAAwD,CAAC;AAErF;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;iBAG1B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,iBAAiB;;iBAE5B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;iBAAwE,CAAC;AAErG;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAMxD;;GAEG;AACH,eAAO,MAAM,2BAA2B,GAAI,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC;;iBAIhF,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;iBAK9B,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;GAEG;AACH,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,CAAC,CAAC,UAAU,EAAE,YAAY,CAAC;;;;;;;mBAE5E,CAAC;AAMF;;GAEG;AACH,eAAO,MAAM,WAAW,aAAqB,CAAC;AAE9C;;GAEG;AACH,eAAO,MAAM,SAAS,aAAmB,CAAC;AAE1C;;GAEG;AACH,eAAO,MAAM,WAAW,aAAyC,CAAC;AAElE;;GAEG;AACH,eAAO,MAAM,gBAAgB,aAAwB,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,oBAAoB,aAAoB,CAAC;AAEtD;;GAEG;AACH,eAAO,MAAM,mBAAmB,aAA2B,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,aAAa,wGAExB,CAAC;AAMH;;GAEG;AACH,eAAO,MAAM,eAAe;;;iBAG1B,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,uBAAuB;;;iBAGlC,CAAC;AAMH;;GAEG;AACH,eAAO,MAAM,0BAA0B,0DAErC,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,gBAAgB,qDAO3B,CAAC;AAMH;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;iBAYpC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC"}