@lenne.tech/nest-server 11.32.4 → 11.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/.claude/rules/architecture.md +16 -0
  2. package/.claude/rules/configurable-features.md +11 -3
  3. package/.claude/rules/testing.md +101 -1
  4. package/CLAUDE.md +5 -0
  5. package/FRAMEWORK-API.md +58 -3
  6. package/dist/core/common/helpers/content-disposition.helper.d.ts +1 -0
  7. package/dist/core/common/helpers/content-disposition.helper.js +14 -0
  8. package/dist/core/common/helpers/content-disposition.helper.js.map +1 -0
  9. package/dist/core/common/helpers/file.helper.d.ts +7 -0
  10. package/dist/core/common/helpers/file.helper.js +21 -4
  11. package/dist/core/common/helpers/file.helper.js.map +1 -1
  12. package/dist/core/common/helpers/graceful-shutdown.helper.d.ts +2 -0
  13. package/dist/core/common/helpers/graceful-shutdown.helper.js +55 -0
  14. package/dist/core/common/helpers/graceful-shutdown.helper.js.map +1 -0
  15. package/dist/core/common/helpers/project-name.helper.d.ts +2 -0
  16. package/dist/core/common/helpers/project-name.helper.js +38 -0
  17. package/dist/core/common/helpers/project-name.helper.js.map +1 -0
  18. package/dist/core/common/interfaces/cron-job-config.interface.d.ts +1 -0
  19. package/dist/core/common/interfaces/server-options.interface.d.ts +39 -0
  20. package/dist/core/common/services/core-cron-jobs.initializer.d.ts +10 -0
  21. package/dist/core/common/services/core-cron-jobs.initializer.js +46 -0
  22. package/dist/core/common/services/core-cron-jobs.initializer.js.map +1 -0
  23. package/dist/core/common/services/core-cron-jobs.registry.d.ts +8 -0
  24. package/dist/core/common/services/core-cron-jobs.registry.js +12 -0
  25. package/dist/core/common/services/core-cron-jobs.registry.js.map +1 -0
  26. package/dist/core/common/services/core-cron-jobs.service.d.ts +37 -7
  27. package/dist/core/common/services/core-cron-jobs.service.js +278 -27
  28. package/dist/core/common/services/core-cron-jobs.service.js.map +1 -1
  29. package/dist/core/common/services/core-redis-pubsub.d.ts +20 -0
  30. package/dist/core/common/services/core-redis-pubsub.js +112 -0
  31. package/dist/core/common/services/core-redis-pubsub.js.map +1 -0
  32. package/dist/core/common/services/core-redis.service.d.ts +25 -0
  33. package/dist/core/common/services/core-redis.service.js +154 -0
  34. package/dist/core/common/services/core-redis.service.js.map +1 -0
  35. package/dist/core/common/services/core-s3.service.d.ts +51 -0
  36. package/dist/core/common/services/core-s3.service.js +261 -0
  37. package/dist/core/common/services/core-s3.service.js.map +1 -0
  38. package/dist/core/common/services/core-trust-proxy.initializer.d.ts +16 -0
  39. package/dist/core/common/services/core-trust-proxy.initializer.js +77 -0
  40. package/dist/core/common/services/core-trust-proxy.initializer.js.map +1 -0
  41. package/dist/core/common/services/rate-limit-store.d.ts +61 -0
  42. package/dist/core/common/services/rate-limit-store.js +235 -0
  43. package/dist/core/common/services/rate-limit-store.js.map +1 -0
  44. package/dist/core/modules/ai/core-ai-mcp.controller.d.ts +19 -3
  45. package/dist/core/modules/ai/core-ai-mcp.controller.js +148 -18
  46. package/dist/core/modules/ai/core-ai-mcp.controller.js.map +1 -1
  47. package/dist/core/modules/ai/services/core-ai.service.d.ts +7 -2
  48. package/dist/core/modules/ai/services/core-ai.service.js +24 -20
  49. package/dist/core/modules/ai/services/core-ai.service.js.map +1 -1
  50. package/dist/core/modules/auth/core-auth.module.js +4 -1
  51. package/dist/core/modules/auth/core-auth.module.js.map +1 -1
  52. package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.d.ts +1 -1
  53. package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js +3 -14
  54. package/dist/core/modules/auth/guards/legacy-auth-rate-limit.guard.js.map +1 -1
  55. package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.d.ts +12 -10
  56. package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.js +30 -59
  57. package/dist/core/modules/auth/services/legacy-auth-rate-limiter.service.js.map +1 -1
  58. package/dist/core/modules/better-auth/core-better-auth-email-verification.service.d.ts +8 -2
  59. package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js +118 -45
  60. package/dist/core/modules/better-auth/core-better-auth-email-verification.service.js.map +1 -1
  61. package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.d.ts +1 -1
  62. package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.js +2 -11
  63. package/dist/core/modules/better-auth/core-better-auth-rate-limit.middleware.js.map +1 -1
  64. package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.d.ts +12 -10
  65. package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.js +30 -85
  66. package/dist/core/modules/better-auth/core-better-auth-rate-limiter.service.js.map +1 -1
  67. package/dist/core/modules/better-auth/core-better-auth-user.mapper.js +0 -1
  68. package/dist/core/modules/better-auth/core-better-auth-user.mapper.js.map +1 -1
  69. package/dist/core/modules/file/core-file.controller.d.ts +11 -2
  70. package/dist/core/modules/file/core-file.controller.js +52 -15
  71. package/dist/core/modules/file/core-file.controller.js.map +1 -1
  72. package/dist/core/modules/file/core-file.resolver.d.ts +4 -4
  73. package/dist/core/modules/file/core-file.resolver.js +23 -16
  74. package/dist/core/modules/file/core-file.resolver.js.map +1 -1
  75. package/dist/core/modules/file/core-file.service.d.ts +41 -7
  76. package/dist/core/modules/file/core-file.service.js +227 -7
  77. package/dist/core/modules/file/core-file.service.js.map +1 -1
  78. package/dist/core/modules/file/file-metadata.helper.d.ts +16 -0
  79. package/dist/core/modules/file/file-metadata.helper.js +33 -0
  80. package/dist/core/modules/file/file-metadata.helper.js.map +1 -0
  81. package/dist/core/modules/file/file-roles.helper.d.ts +4 -0
  82. package/dist/core/modules/file/file-roles.helper.js +53 -0
  83. package/dist/core/modules/file/file-roles.helper.js.map +1 -0
  84. package/dist/core/modules/file/file-storage.helper.d.ts +13 -0
  85. package/dist/core/modules/file/file-storage.helper.js +65 -0
  86. package/dist/core/modules/file/file-storage.helper.js.map +1 -0
  87. package/dist/core/modules/file/filesystem-file.helper.d.ts +22 -0
  88. package/dist/core/modules/file/filesystem-file.helper.js +77 -0
  89. package/dist/core/modules/file/filesystem-file.helper.js.map +1 -0
  90. package/dist/core/modules/file/interfaces/file-service-options.interface.d.ts +1 -0
  91. package/dist/core/modules/file/interfaces/file-upload.interface.d.ts +7 -1
  92. package/dist/core/modules/file/s3-file.helper.d.ts +37 -0
  93. package/dist/core/modules/file/s3-file.helper.js +81 -0
  94. package/dist/core/modules/file/s3-file.helper.js.map +1 -0
  95. package/dist/core/modules/hub/core-hub.controller.d.ts +8 -8
  96. package/dist/core/modules/hub/core-hub.controller.js +24 -22
  97. package/dist/core/modules/hub/core-hub.controller.js.map +1 -1
  98. package/dist/core/modules/hub/helpers/hub-mask.helper.js +2 -2
  99. package/dist/core/modules/hub/helpers/hub-mask.helper.js.map +1 -1
  100. package/dist/core/modules/hub/hub-buffer.d.ts +23 -0
  101. package/dist/core/modules/hub/hub-buffer.js +101 -0
  102. package/dist/core/modules/hub/hub-buffer.js.map +1 -0
  103. package/dist/core/modules/hub/services/core-hub-mailbox.service.d.ts +7 -5
  104. package/dist/core/modules/hub/services/core-hub-mailbox.service.js +14 -10
  105. package/dist/core/modules/hub/services/core-hub-mailbox.service.js.map +1 -1
  106. package/dist/core/modules/hub/services/hub-log-buffer.service.d.ts +5 -2
  107. package/dist/core/modules/hub/services/hub-log-buffer.service.js +17 -8
  108. package/dist/core/modules/hub/services/hub-log-buffer.service.js.map +1 -1
  109. package/dist/core/modules/hub/services/hub-query-profiler.service.d.ts +4 -2
  110. package/dist/core/modules/hub/services/hub-query-profiler.service.js +13 -7
  111. package/dist/core/modules/hub/services/hub-query-profiler.service.js.map +1 -1
  112. package/dist/core/modules/hub/services/hub-trace-buffer.service.d.ts +4 -2
  113. package/dist/core/modules/hub/services/hub-trace-buffer.service.js +13 -8
  114. package/dist/core/modules/hub/services/hub-trace-buffer.service.js.map +1 -1
  115. package/dist/core/modules/migrate/helpers/migration.helper.d.ts +2 -6
  116. package/dist/core/modules/migrate/helpers/migration.helper.js +4 -4
  117. package/dist/core/modules/migrate/helpers/migration.helper.js.map +1 -1
  118. package/dist/core/modules/migrate/migration-runner.d.ts +1 -0
  119. package/dist/core/modules/migrate/migration-runner.js +4 -0
  120. package/dist/core/modules/migrate/migration-runner.js.map +1 -1
  121. package/dist/core/modules/migrate/mongo-state-store.d.ts +1 -0
  122. package/dist/core/modules/migrate/mongo-state-store.js +98 -9
  123. package/dist/core/modules/migrate/mongo-state-store.js.map +1 -1
  124. package/dist/core/modules/system-setup/core-system-setup.service.d.ts +2 -0
  125. package/dist/core/modules/system-setup/core-system-setup.service.js +31 -1
  126. package/dist/core/modules/system-setup/core-system-setup.service.js.map +1 -1
  127. package/dist/core/modules/tenant/core-tenant.guard.d.ts +17 -3
  128. package/dist/core/modules/tenant/core-tenant.guard.js +92 -15
  129. package/dist/core/modules/tenant/core-tenant.guard.js.map +1 -1
  130. package/dist/core/modules/tenant/core-tenant.module.js +3 -4
  131. package/dist/core/modules/tenant/core-tenant.module.js.map +1 -1
  132. package/dist/core/modules/tus/core-tus.controller.d.ts +2 -0
  133. package/dist/core/modules/tus/core-tus.controller.js +29 -3
  134. package/dist/core/modules/tus/core-tus.controller.js.map +1 -1
  135. package/dist/core/modules/tus/core-tus.service.d.ts +24 -1
  136. package/dist/core/modules/tus/core-tus.service.js +182 -28
  137. package/dist/core/modules/tus/core-tus.service.js.map +1 -1
  138. package/dist/core/modules/tus/interfaces/tus-config.interface.js +3 -0
  139. package/dist/core/modules/tus/interfaces/tus-config.interface.js.map +1 -1
  140. package/dist/core/modules/tus/tus-redis-locker.d.ts +25 -0
  141. package/dist/core/modules/tus/tus-redis-locker.js +87 -0
  142. package/dist/core/modules/tus/tus-redis-locker.js.map +1 -0
  143. package/dist/core/modules/tus/tus.module.d.ts +1 -0
  144. package/dist/core/modules/tus/tus.module.js +30 -4
  145. package/dist/core/modules/tus/tus.module.js.map +1 -1
  146. package/dist/core.module.js +18 -1
  147. package/dist/core.module.js.map +1 -1
  148. package/dist/index.d.ts +10 -0
  149. package/dist/index.js +10 -0
  150. package/dist/index.js.map +1 -1
  151. package/dist/main.js +2 -1
  152. package/dist/main.js.map +1 -1
  153. package/dist/server/modules/file/file.controller.js.map +1 -1
  154. package/dist/server/modules/file/file.resolver.js +1 -12
  155. package/dist/server/modules/file/file.resolver.js.map +1 -1
  156. package/dist/server/modules/file/file.service.d.ts +5 -1
  157. package/dist/server/modules/file/file.service.js +12 -3
  158. package/dist/server/modules/file/file.service.js.map +1 -1
  159. package/dist/server/modules/user/avatar.controller.d.ts +5 -1
  160. package/dist/server/modules/user/avatar.controller.js +26 -10
  161. package/dist/server/modules/user/avatar.controller.js.map +1 -1
  162. package/dist/server/modules/user/user.model.js +3 -2
  163. package/dist/server/modules/user/user.model.js.map +1 -1
  164. package/dist/server/modules/user/user.module.js +6 -2
  165. package/dist/server/modules/user/user.module.js.map +1 -1
  166. package/dist/server/modules/user/user.service.d.ts +1 -1
  167. package/dist/server/modules/user/user.service.js +6 -13
  168. package/dist/server/modules/user/user.service.js.map +1 -1
  169. package/dist/tsconfig.build.tsbuildinfo +1 -1
  170. package/docs/REQUEST-LIFECYCLE.md +57 -8
  171. package/docs/security-overrides.md +21 -3
  172. package/migration-guides/11.32.3-to-11.32.4.md +15 -3
  173. package/migration-guides/11.32.x-to-11.33.x.md +1551 -0
  174. package/package.json +74 -42
  175. package/src/core/common/helpers/content-disposition.helper.ts +90 -0
  176. package/src/core/common/helpers/file.helper.ts +53 -10
  177. package/src/core/common/helpers/graceful-shutdown.helper.ts +116 -0
  178. package/src/core/common/helpers/project-name.helper.ts +71 -0
  179. package/src/core/common/interfaces/cron-job-config.interface.ts +16 -0
  180. package/src/core/common/interfaces/server-options.interface.ts +439 -2
  181. package/src/core/common/services/core-cron-jobs.initializer.ts +39 -0
  182. package/src/core/common/services/core-cron-jobs.registry.ts +45 -0
  183. package/src/core/common/services/core-cron-jobs.service.ts +589 -47
  184. package/src/core/common/services/core-redis-pubsub.ts +183 -0
  185. package/src/core/common/services/core-redis.service.ts +249 -0
  186. package/src/core/common/services/core-s3.service.ts +465 -0
  187. package/src/core/common/services/core-trust-proxy.initializer.ts +112 -0
  188. package/src/core/common/services/rate-limit-store.ts +492 -0
  189. package/src/core/modules/ai/README.md +25 -0
  190. package/src/core/modules/ai/core-ai-mcp.controller.ts +253 -22
  191. package/src/core/modules/ai/services/core-ai.service.ts +33 -24
  192. package/src/core/modules/auth/core-auth.module.ts +7 -1
  193. package/src/core/modules/auth/guards/legacy-auth-rate-limit.guard.ts +12 -21
  194. package/src/core/modules/auth/services/legacy-auth-rate-limiter.service.ts +49 -93
  195. package/src/core/modules/better-auth/core-better-auth-email-verification.service.ts +202 -66
  196. package/src/core/modules/better-auth/core-better-auth-rate-limit.middleware.ts +11 -18
  197. package/src/core/modules/better-auth/core-better-auth-rate-limiter.service.ts +51 -132
  198. package/src/core/modules/better-auth/core-better-auth-user.mapper.ts +7 -1
  199. package/src/core/modules/file/INTEGRATION-CHECKLIST.md +108 -0
  200. package/src/core/modules/file/README.md +277 -53
  201. package/src/core/modules/file/core-file.controller.ts +168 -12
  202. package/src/core/modules/file/core-file.resolver.ts +46 -12
  203. package/src/core/modules/file/core-file.service.ts +482 -16
  204. package/src/core/modules/file/file-metadata.helper.ts +142 -0
  205. package/src/core/modules/file/file-roles.helper.ts +110 -0
  206. package/src/core/modules/file/file-storage.helper.ts +163 -0
  207. package/src/core/modules/file/filesystem-file.helper.ts +184 -0
  208. package/src/core/modules/file/interfaces/file-service-options.interface.ts +14 -0
  209. package/src/core/modules/file/interfaces/file-upload.interface.ts +17 -1
  210. package/src/core/modules/file/s3-file.helper.ts +209 -0
  211. package/src/core/modules/hub/README.md +48 -0
  212. package/src/core/modules/hub/core-hub.controller.ts +18 -16
  213. package/src/core/modules/hub/helpers/hub-mask.helper.ts +21 -4
  214. package/src/core/modules/hub/hub-buffer.ts +198 -0
  215. package/src/core/modules/hub/services/core-hub-mailbox.service.ts +22 -12
  216. package/src/core/modules/hub/services/hub-log-buffer.service.ts +24 -8
  217. package/src/core/modules/hub/services/hub-query-profiler.service.ts +9 -6
  218. package/src/core/modules/hub/services/hub-trace-buffer.service.ts +14 -9
  219. package/src/core/modules/migrate/README.md +33 -6
  220. package/src/core/modules/migrate/helpers/migration.helper.ts +13 -6
  221. package/src/core/modules/migrate/migration-runner.ts +10 -1
  222. package/src/core/modules/migrate/mongo-state-store.ts +179 -11
  223. package/src/core/modules/system-setup/README.md +7 -2
  224. package/src/core/modules/system-setup/core-system-setup.service.ts +95 -1
  225. package/src/core/modules/tenant/README.md +21 -1
  226. package/src/core/modules/tenant/core-tenant.guard.ts +135 -14
  227. package/src/core/modules/tenant/core-tenant.module.ts +8 -4
  228. package/src/core/modules/tus/INTEGRATION-CHECKLIST.md +93 -21
  229. package/src/core/modules/tus/README.md +35 -2
  230. package/src/core/modules/tus/core-tus.controller.ts +64 -12
  231. package/src/core/modules/tus/core-tus.service.ts +358 -34
  232. package/src/core/modules/tus/interfaces/tus-config.interface.ts +9 -0
  233. package/src/core/modules/tus/tus-redis-locker.ts +139 -0
  234. package/src/core/modules/tus/tus.module.ts +78 -6
  235. package/src/core.module.ts +26 -1
  236. package/src/index.ts +10 -0
  237. package/src/main.ts +7 -1
  238. package/src/server/modules/file/file.controller.ts +7 -3
  239. package/src/server/modules/file/file.resolver.ts +5 -17
  240. package/src/server/modules/file/file.service.ts +42 -3
  241. package/src/server/modules/user/avatar.controller.ts +39 -9
  242. package/src/server/modules/user/user.model.ts +9 -3
  243. package/src/server/modules/user/user.module.ts +12 -3
  244. package/src/server/modules/user/user.service.ts +20 -17
  245. package/src/test/README.md +7 -2
  246. package/src/core/common/helpers/file.helper.spec.ts +0 -145
  247. package/src/core/common/helpers/logging.helper.spec.ts +0 -61
  248. package/src/core/common/helpers/process-diagnostics.helper.spec.ts +0 -310
  249. package/src/core/common/services/brevo.service.spec.ts +0 -266
  250. package/src/core/modules/file/core-file.controller.spec.ts +0 -164
  251. package/src/core/modules/hub/core-hub.module.spec.ts +0 -108
  252. package/src/core/modules/hub/helpers/hub-command-shape.helper.spec.ts +0 -48
  253. package/src/core/modules/hub/helpers/hub-mask.helper.spec.ts +0 -67
  254. package/src/core/modules/hub/helpers/hub-mermaid.helper.spec.ts +0 -61
  255. package/src/core/modules/hub/helpers/hub-shell.helper.spec.ts +0 -106
  256. package/src/core/modules/hub/hub-config.helper.spec.ts +0 -108
  257. package/src/core/modules/hub/hub-ring-buffer.spec.ts +0 -95
  258. package/src/core/modules/hub/services/core-hub-mailbox.service.spec.ts +0 -116
  259. package/src/core/modules/hub/services/hub-trace-buffer.service.spec.ts +0 -112
  260. package/src/core/modules/migrate/helpers/migration.helper.spec.ts +0 -85
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CoreRedisPubSub = void 0;
4
+ const common_1 = require("@nestjs/common");
5
+ const graphql_subscriptions_1 = require("graphql-subscriptions");
6
+ const ISO_DATE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
7
+ function reviveDates(_key, value) {
8
+ return typeof value === 'string' && ISO_DATE.test(value) ? new Date(value) : value;
9
+ }
10
+ class CoreRedisPubSub extends graphql_subscriptions_1.PubSubEngine {
11
+ redisService;
12
+ logger = new common_1.Logger(CoreRedisPubSub.name);
13
+ handlers = new Map();
14
+ messageListener;
15
+ subscriptions = new Map();
16
+ subIdCounter = 0;
17
+ constructor(redisService) {
18
+ super();
19
+ this.redisService = redisService;
20
+ }
21
+ async publish(triggerName, payload) {
22
+ try {
23
+ await this.redisService.getClient().publish(this.channel(triggerName), JSON.stringify(payload));
24
+ }
25
+ catch (error) {
26
+ this.logger.warn(`Subscription publish to "${triggerName}" failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
27
+ }
28
+ }
29
+ async subscribe(triggerName, onMessage) {
30
+ const channel = this.channel(triggerName);
31
+ let channelHandlers = this.handlers.get(channel);
32
+ if (!channelHandlers) {
33
+ channelHandlers = new Map();
34
+ this.handlers.set(channel, channelHandlers);
35
+ try {
36
+ await this.getSubscriber().subscribe(channel);
37
+ }
38
+ catch (error) {
39
+ this.handlers.delete(channel);
40
+ throw error;
41
+ }
42
+ }
43
+ const subId = ++this.subIdCounter;
44
+ channelHandlers.set(subId, onMessage);
45
+ this.subscriptions.set(subId, channel);
46
+ return subId;
47
+ }
48
+ async unsubscribe(subId) {
49
+ const channel = this.subscriptions.get(subId);
50
+ if (!channel) {
51
+ return;
52
+ }
53
+ this.subscriptions.delete(subId);
54
+ const channelHandlers = this.handlers.get(channel);
55
+ if (!channelHandlers) {
56
+ return;
57
+ }
58
+ channelHandlers.delete(subId);
59
+ if (channelHandlers.size === 0) {
60
+ this.handlers.delete(channel);
61
+ await this.getSubscriber().unsubscribe(channel);
62
+ }
63
+ }
64
+ channel(triggerName) {
65
+ return this.redisService.key('pubsub', triggerName);
66
+ }
67
+ dispatch(channel, message) {
68
+ const channelHandlers = this.handlers.get(channel);
69
+ if (!channelHandlers?.size) {
70
+ return;
71
+ }
72
+ let payload;
73
+ try {
74
+ payload = JSON.parse(message, reviveDates);
75
+ }
76
+ catch {
77
+ this.logger.warn(`Ignoring non-JSON message on channel ${channel}`);
78
+ return;
79
+ }
80
+ for (const handler of channelHandlers.values()) {
81
+ handler(payload);
82
+ }
83
+ }
84
+ async onModuleDestroy() {
85
+ const channels = [...this.handlers.keys()];
86
+ this.handlers.clear();
87
+ this.subscriptions.clear();
88
+ try {
89
+ const subscriber = this.redisService.getSubscriber();
90
+ if (this.messageListener) {
91
+ subscriber.off('message', this.messageListener);
92
+ this.messageListener = undefined;
93
+ }
94
+ if (channels.length) {
95
+ await subscriber.unsubscribe(...channels);
96
+ }
97
+ }
98
+ catch (error) {
99
+ this.logger.debug(`PubSub teardown skipped: ${error instanceof Error ? error.message : 'Unknown error'}`);
100
+ }
101
+ }
102
+ getSubscriber() {
103
+ const subscriber = this.redisService.getSubscriber();
104
+ if (!this.messageListener) {
105
+ this.messageListener = (channel, message) => this.dispatch(channel, message);
106
+ subscriber.on('message', this.messageListener);
107
+ }
108
+ return subscriber;
109
+ }
110
+ }
111
+ exports.CoreRedisPubSub = CoreRedisPubSub;
112
+ //# sourceMappingURL=core-redis-pubsub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-redis-pubsub.js","sourceRoot":"","sources":["../../../../src/core/common/services/core-redis-pubsub.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { Logger, OnApplicationShutdown, OnModuleInit } from '@nestjs/common';
2
+ import { ConfigService } from './config.service';
3
+ import type { IRedisConfig } from '../interfaces/server-options.interface';
4
+ import type { Redis, RedisOptions } from 'ioredis';
5
+ export type NormalizedRedisConfig = Required<Pick<IRedisConfig, 'db' | 'host' | 'keyPrefix' | 'port'>> & Pick<IRedisConfig, 'options' | 'password' | 'url' | 'username'>;
6
+ export declare class CoreRedisService implements OnApplicationShutdown, OnModuleInit {
7
+ protected readonly configService: ConfigService;
8
+ protected readonly logger: Logger;
9
+ protected clients: Redis[];
10
+ protected config?: NormalizedRedisConfig;
11
+ protected RedisCtor?: new (...args: any[]) => Redis;
12
+ protected sharedClient?: Redis;
13
+ protected subscriberClient?: Redis;
14
+ constructor(configService: ConfigService);
15
+ get enabled(): boolean;
16
+ getConfig(): NormalizedRedisConfig | undefined;
17
+ key(...parts: string[]): string;
18
+ onModuleInit(): Promise<void>;
19
+ protected logActivationSummary(): void;
20
+ getClient(): Redis;
21
+ getSubscriber(): Redis;
22
+ createClient(label?: string, overrides?: RedisOptions): Redis;
23
+ onApplicationShutdown(): Promise<void>;
24
+ protected newConnection(label: string, overrides?: RedisOptions): Redis;
25
+ }
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var CoreRedisService_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.CoreRedisService = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const project_name_helper_1 = require("../helpers/project-name.helper");
16
+ const config_service_1 = require("./config.service");
17
+ let CoreRedisService = CoreRedisService_1 = class CoreRedisService {
18
+ configService;
19
+ logger = new common_1.Logger(CoreRedisService_1.name);
20
+ clients = [];
21
+ config;
22
+ RedisCtor;
23
+ sharedClient;
24
+ subscriberClient;
25
+ constructor(configService) {
26
+ this.configService = configService;
27
+ const raw = this.configService.getFastButReadOnly('redis');
28
+ if (raw === undefined || raw === null || raw === false) {
29
+ return;
30
+ }
31
+ const partial = typeof raw === 'boolean' ? {} : raw;
32
+ if (partial.enabled === false) {
33
+ return;
34
+ }
35
+ this.config = {
36
+ db: partial.db ?? 0,
37
+ host: partial.host ?? 'localhost',
38
+ keyPrefix: partial.keyPrefix ?? (0, project_name_helper_1.getProjectSlug)(),
39
+ options: partial.options,
40
+ password: partial.password,
41
+ port: partial.port ?? 6379,
42
+ url: partial.url,
43
+ username: partial.username,
44
+ };
45
+ }
46
+ get enabled() {
47
+ return !!this.config;
48
+ }
49
+ getConfig() {
50
+ return this.config;
51
+ }
52
+ key(...parts) {
53
+ return [this.config?.keyPrefix ?? (0, project_name_helper_1.getProjectSlug)(), ...parts].join(':');
54
+ }
55
+ async onModuleInit() {
56
+ if (!this.config) {
57
+ return;
58
+ }
59
+ try {
60
+ const mod = await Promise.resolve().then(() => require('ioredis'));
61
+ this.RedisCtor = mod.Redis ?? mod.default;
62
+ }
63
+ catch {
64
+ throw new Error('Redis is configured (ServerOptions.redis) but the optional peer dependency "ioredis" is not installed. ' +
65
+ 'Run: pnpm add ioredis');
66
+ }
67
+ this.sharedClient = this.newConnection('shared');
68
+ this.logActivationSummary();
69
+ }
70
+ logActivationSummary() {
71
+ if (!this.config) {
72
+ return;
73
+ }
74
+ const cfg = this.configService.configFastButReadOnly ?? {};
75
+ const changed = [
76
+ 'rate limits (legacy auth, better-auth, AI) — now exact across replicas instead of per replica',
77
+ 'cron jobs — deduplicated fleet-wide; per-job opt-out via `distributed: false`',
78
+ 'email-verification cooldown — one slot fleet-wide instead of one per replica',
79
+ ];
80
+ if (cfg.graphQl !== false) {
81
+ changed.push('GraphQL subscriptions — via Redis pub/sub; payloads must be JSON-serializable');
82
+ }
83
+ if (cfg.multiTenancy) {
84
+ changed.push('tenant-membership cache — invalidation is broadcast to every replica');
85
+ }
86
+ if (cfg.hub) {
87
+ changed.push('Hub log/trace/query buffers — mirrored to Redis, so they outlive the process');
88
+ }
89
+ if (cfg.ai?.mcp) {
90
+ changed.push('MCP sessions — ownership registry (sticky sessions still required)');
91
+ }
92
+ this.logger.log(`Redis configured (${this.config.url ? 'url' : `${this.config.host}:${this.config.port}`}, ` +
93
+ `db ${this.config.db}, keyPrefix "${this.config.keyPrefix}") — these subsystems are now ` +
94
+ `distributed:\n - ${changed.join('\n - ')}`);
95
+ }
96
+ getClient() {
97
+ if (!this.config) {
98
+ throw new Error('Redis is not configured/enabled (ServerOptions.redis)');
99
+ }
100
+ if (!this.sharedClient) {
101
+ throw new Error('CoreRedisService is not initialized yet (onModuleInit pending)');
102
+ }
103
+ return this.sharedClient;
104
+ }
105
+ getSubscriber() {
106
+ this.getClient();
107
+ if (!this.subscriberClient) {
108
+ this.subscriberClient = this.newConnection('subscriber');
109
+ }
110
+ return this.subscriberClient;
111
+ }
112
+ createClient(label = 'extra', overrides) {
113
+ this.getClient();
114
+ return this.newConnection(label, overrides);
115
+ }
116
+ async onApplicationShutdown() {
117
+ await Promise.allSettled(this.clients.map(async (client) => {
118
+ try {
119
+ await Promise.race([client.quit(), new Promise((resolve) => setTimeout(resolve, 2000).unref())]);
120
+ }
121
+ finally {
122
+ client.disconnect();
123
+ }
124
+ }));
125
+ this.clients = [];
126
+ this.sharedClient = undefined;
127
+ this.subscriberClient = undefined;
128
+ }
129
+ newConnection(label, overrides) {
130
+ if (!this.config || !this.RedisCtor) {
131
+ throw new Error('CoreRedisService is not initialized yet (onModuleInit pending)');
132
+ }
133
+ const { db, host, options, password, port, url, username } = this.config;
134
+ const baseOptions = {
135
+ commandTimeout: 2000,
136
+ ...options,
137
+ ...overrides,
138
+ };
139
+ const client = url
140
+ ? new this.RedisCtor(url, baseOptions)
141
+ : new this.RedisCtor({ db, host, password, port, username, ...baseOptions });
142
+ client.on?.('error', (error) => {
143
+ this.logger.error(`Redis connection error (${label}): ${error.message}`);
144
+ });
145
+ this.clients.push(client);
146
+ return client;
147
+ }
148
+ };
149
+ exports.CoreRedisService = CoreRedisService;
150
+ exports.CoreRedisService = CoreRedisService = CoreRedisService_1 = __decorate([
151
+ (0, common_1.Injectable)(),
152
+ __metadata("design:paramtypes", [config_service_1.ConfigService])
153
+ ], CoreRedisService);
154
+ //# sourceMappingURL=core-redis.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-redis.service.js","sourceRoot":"","sources":["../../../../src/core/common/services/core-redis.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { Logger, OnApplicationShutdown, OnModuleInit } from '@nestjs/common';
2
+ import { ConfigService } from './config.service';
3
+ import type { IS3Config } from '../interfaces/server-options.interface';
4
+ import type { S3Client } from '@aws-sdk/client-s3';
5
+ import type { Readable } from 'stream';
6
+ export type NormalizedS3Config = Omit<IS3Config, 'enabled' | 'presignedDownloads'> & {
7
+ bucket: string;
8
+ forcePathStyle: boolean;
9
+ presignedDownloads?: {
10
+ expiresInSeconds: number;
11
+ };
12
+ region: string;
13
+ stagingBucket: string;
14
+ };
15
+ export declare class CoreS3Service implements OnApplicationShutdown, OnModuleInit {
16
+ protected readonly configService: ConfigService;
17
+ protected readonly logger: Logger;
18
+ protected config?: NormalizedS3Config;
19
+ protected client?: S3Client;
20
+ protected sdk?: typeof import('@aws-sdk/client-s3');
21
+ protected presigner?: typeof import('@aws-sdk/s3-request-presigner');
22
+ constructor(configService: ConfigService);
23
+ protected clampPresignedExpiry(seconds: number): number;
24
+ get enabled(): boolean;
25
+ getConfig(): NormalizedS3Config | undefined;
26
+ onModuleInit(): Promise<void>;
27
+ protected verifyBuckets(): Promise<void>;
28
+ protected bucketExists(bucket: string): Promise<boolean>;
29
+ getClient(): S3Client;
30
+ putObject(key: string, body: Buffer | Readable | string, contentType?: string, contentLength?: number): Promise<void>;
31
+ copyObject(sourceKey: string, destinationKey: string, sourceBucket?: string, contentType?: string): Promise<void>;
32
+ static readonly MAX_COPY_OBJECT_BYTES: number;
33
+ protected copySource(bucket: string, key: string): string;
34
+ protected isStream(body: unknown): body is Readable;
35
+ protected collect(stream: Readable): Promise<Buffer>;
36
+ getObject(key: string): Promise<{
37
+ body: Readable;
38
+ contentLength?: number;
39
+ contentType?: string;
40
+ }>;
41
+ deleteObject(key: string, bucket?: string): Promise<void>;
42
+ objectExists(key: string): Promise<boolean>;
43
+ getPresignedDownloadUrl(key: string, filename?: string): Promise<string | undefined>;
44
+ ensureBucket(bucket: string): Promise<void>;
45
+ onApplicationShutdown(): Promise<void>;
46
+ protected requireInit(): {
47
+ client: S3Client;
48
+ config: NormalizedS3Config;
49
+ sdk: typeof import('@aws-sdk/client-s3');
50
+ };
51
+ }
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var CoreS3Service_1;
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.CoreS3Service = void 0;
14
+ const common_1 = require("@nestjs/common");
15
+ const content_disposition_helper_1 = require("../helpers/content-disposition.helper");
16
+ const config_service_1 = require("./config.service");
17
+ const MAX_PRESIGNED_EXPIRY_SECONDS = 604_800;
18
+ const PRESIGNED_EXPIRY_ADVISORY_SECONDS = 900;
19
+ let CoreS3Service = class CoreS3Service {
20
+ static { CoreS3Service_1 = this; }
21
+ configService;
22
+ logger = new common_1.Logger(CoreS3Service_1.name);
23
+ config;
24
+ client;
25
+ sdk;
26
+ presigner;
27
+ constructor(configService) {
28
+ this.configService = configService;
29
+ const raw = this.configService.getFastButReadOnly('s3');
30
+ if (!raw || raw.enabled === false) {
31
+ return;
32
+ }
33
+ if (!raw.bucket) {
34
+ this.logger.warn('Ignoring the `s3` configuration: no `bucket` is set, so S3 cannot be used.');
35
+ return;
36
+ }
37
+ const presigned = raw.presignedDownloads;
38
+ this.config = {
39
+ accessKeyId: raw.accessKeyId,
40
+ autoCreateBucket: raw.autoCreateBucket ?? false,
41
+ bucket: raw.bucket,
42
+ endpoint: raw.endpoint,
43
+ forcePathStyle: raw.forcePathStyle ?? false,
44
+ presignedDownloads: presigned
45
+ ? {
46
+ expiresInSeconds: this.clampPresignedExpiry((typeof presigned === 'object' ? presigned.expiresInSeconds : undefined) ?? 300),
47
+ }
48
+ : undefined,
49
+ region: raw.region ?? 'us-east-1',
50
+ secretAccessKey: raw.secretAccessKey,
51
+ stagingBucket: raw.stagingBucket ?? raw.bucket,
52
+ };
53
+ }
54
+ clampPresignedExpiry(seconds) {
55
+ if (!Number.isFinite(seconds) || seconds <= 0) {
56
+ this.logger.warn(`s3.presignedDownloads.expiresInSeconds is "${seconds}", which is not a positive number — using 300s.`);
57
+ return 300;
58
+ }
59
+ if (seconds > MAX_PRESIGNED_EXPIRY_SECONDS) {
60
+ this.logger.warn(`s3.presignedDownloads.expiresInSeconds is ${seconds}s, above the ${MAX_PRESIGNED_EXPIRY_SECONDS}s AWS SigV4 ` +
61
+ 'maximum — capping it, since a longer signature is rejected by S3 rather than honored.');
62
+ return MAX_PRESIGNED_EXPIRY_SECONDS;
63
+ }
64
+ if (seconds > PRESIGNED_EXPIRY_ADVISORY_SECONDS) {
65
+ this.logger.warn(`s3.presignedDownloads.expiresInSeconds is ${seconds}s. A presigned URL is an unrevocable bearer capability ` +
66
+ 'authorized once at issue time — keep it just long enough for the download to start (a few minutes), not ' +
67
+ 'long enough for the link to be forwarded, logged and reused.');
68
+ }
69
+ return seconds;
70
+ }
71
+ get enabled() {
72
+ return !!this.config;
73
+ }
74
+ getConfig() {
75
+ return this.config;
76
+ }
77
+ async onModuleInit() {
78
+ if (!this.config) {
79
+ return;
80
+ }
81
+ try {
82
+ this.sdk = await Promise.resolve().then(() => require('@aws-sdk/client-s3'));
83
+ }
84
+ catch {
85
+ throw new Error('S3 is configured (ServerOptions.s3) but the optional peer dependency "@aws-sdk/client-s3" is not installed. ' +
86
+ 'Run: pnpm add @aws-sdk/client-s3');
87
+ }
88
+ const { accessKeyId, endpoint, forcePathStyle, region, secretAccessKey } = this.config;
89
+ this.client = new this.sdk.S3Client({
90
+ ...(endpoint ? { endpoint } : {}),
91
+ forcePathStyle,
92
+ region,
93
+ ...(accessKeyId && secretAccessKey ? { credentials: { accessKeyId, secretAccessKey } } : {}),
94
+ });
95
+ await this.verifyBuckets();
96
+ }
97
+ async verifyBuckets() {
98
+ const buckets = [...new Set([this.config.bucket, this.config.stagingBucket])];
99
+ for (const bucket of buckets) {
100
+ try {
101
+ if (await this.bucketExists(bucket)) {
102
+ continue;
103
+ }
104
+ if (this.config.autoCreateBucket) {
105
+ await this.ensureBucket(bucket);
106
+ this.logger.log(`Created S3 bucket "${bucket}" (s3.autoCreateBucket is on)`);
107
+ continue;
108
+ }
109
+ this.logger.error(`S3 bucket "${bucket}" does not exist. Every upload will fail until it is created. ` +
110
+ 'Create it in your object storage, or set s3.autoCreateBucket: true to have the server create it.');
111
+ }
112
+ catch (error) {
113
+ this.logger.error(`Could not verify S3 bucket "${bucket}": ${error instanceof Error ? error.message : 'Unknown error'}`);
114
+ }
115
+ }
116
+ }
117
+ async bucketExists(bucket) {
118
+ const { client, sdk } = this.requireInit();
119
+ try {
120
+ await client.send(new sdk.HeadBucketCommand({ Bucket: bucket }));
121
+ return true;
122
+ }
123
+ catch (error) {
124
+ const status = error?.$metadata?.httpStatusCode;
125
+ if (status === 404 || error?.name === 'NotFound' || error?.name === 'NoSuchBucket') {
126
+ return false;
127
+ }
128
+ throw error;
129
+ }
130
+ }
131
+ getClient() {
132
+ if (!this.config) {
133
+ throw new Error('S3 is not configured/enabled (ServerOptions.s3)');
134
+ }
135
+ if (!this.client || !this.sdk) {
136
+ throw new Error('CoreS3Service is not initialized yet (onModuleInit pending)');
137
+ }
138
+ return this.client;
139
+ }
140
+ async putObject(key, body, contentType, contentLength) {
141
+ const { client, config, sdk } = this.requireInit();
142
+ let payload = body;
143
+ let length = contentLength;
144
+ if (this.isStream(body) && length === undefined) {
145
+ payload = await this.collect(body);
146
+ length = payload.length;
147
+ }
148
+ else if (length === undefined && typeof body !== 'string') {
149
+ length = body.length;
150
+ }
151
+ await client.send(new sdk.PutObjectCommand({
152
+ Body: payload,
153
+ Bucket: config.bucket,
154
+ ...(contentType ? { ContentType: contentType } : {}),
155
+ ...(length === undefined ? {} : { ContentLength: length }),
156
+ Key: key,
157
+ }));
158
+ }
159
+ async copyObject(sourceKey, destinationKey, sourceBucket, contentType) {
160
+ const { client, config, sdk } = this.requireInit();
161
+ await client.send(new sdk.CopyObjectCommand({
162
+ Bucket: config.bucket,
163
+ CopySource: this.copySource(sourceBucket ?? config.bucket, sourceKey),
164
+ Key: destinationKey,
165
+ ...(contentType ? { ContentType: contentType, MetadataDirective: 'REPLACE' } : {}),
166
+ }));
167
+ }
168
+ static MAX_COPY_OBJECT_BYTES = 5 * 1024 * 1024 * 1024;
169
+ copySource(bucket, key) {
170
+ const encoded = key
171
+ .split('/')
172
+ .map((segment) => encodeURIComponent(segment))
173
+ .join('/');
174
+ return `/${encodeURIComponent(bucket)}/${encoded}`;
175
+ }
176
+ isStream(body) {
177
+ return !!body && typeof body.pipe === 'function';
178
+ }
179
+ async collect(stream) {
180
+ const chunks = [];
181
+ for await (const chunk of stream) {
182
+ chunks.push(Buffer.from(chunk));
183
+ }
184
+ return Buffer.concat(chunks);
185
+ }
186
+ async getObject(key) {
187
+ const { client, config, sdk } = this.requireInit();
188
+ const result = await client.send(new sdk.GetObjectCommand({ Bucket: config.bucket, Key: key }));
189
+ return {
190
+ body: result.Body,
191
+ contentLength: result.ContentLength,
192
+ contentType: result.ContentType,
193
+ };
194
+ }
195
+ async deleteObject(key, bucket) {
196
+ const { client, config, sdk } = this.requireInit();
197
+ await client.send(new sdk.DeleteObjectCommand({ Bucket: bucket ?? config.bucket, Key: key }));
198
+ }
199
+ async objectExists(key) {
200
+ const { client, config, sdk } = this.requireInit();
201
+ try {
202
+ await client.send(new sdk.HeadObjectCommand({ Bucket: config.bucket, Key: key }));
203
+ return true;
204
+ }
205
+ catch (error) {
206
+ if (error?.$metadata?.httpStatusCode === 404 || error?.name === 'NotFound') {
207
+ return false;
208
+ }
209
+ throw error;
210
+ }
211
+ }
212
+ async getPresignedDownloadUrl(key, filename) {
213
+ const { client, config, sdk } = this.requireInit();
214
+ if (!config.presignedDownloads) {
215
+ return undefined;
216
+ }
217
+ if (!this.presigner) {
218
+ try {
219
+ this.presigner = await Promise.resolve().then(() => require('@aws-sdk/s3-request-presigner'));
220
+ }
221
+ catch {
222
+ throw new Error('s3.presignedDownloads is enabled but the optional peer dependency "@aws-sdk/s3-request-presigner" is not installed. ' +
223
+ 'Run: pnpm add @aws-sdk/s3-request-presigner');
224
+ }
225
+ }
226
+ const command = new sdk.GetObjectCommand({
227
+ Bucket: config.bucket,
228
+ Key: key,
229
+ ...(filename ? { ResponseContentDisposition: (0, content_disposition_helper_1.buildContentDisposition)(filename) } : {}),
230
+ });
231
+ return this.presigner.getSignedUrl(client, command, { expiresIn: config.presignedDownloads.expiresInSeconds });
232
+ }
233
+ async ensureBucket(bucket) {
234
+ const { client, sdk } = this.requireInit();
235
+ try {
236
+ await client.send(new sdk.HeadBucketCommand({ Bucket: bucket }));
237
+ }
238
+ catch {
239
+ await client.send(new sdk.CreateBucketCommand({ Bucket: bucket }));
240
+ }
241
+ }
242
+ async onApplicationShutdown() {
243
+ this.client?.destroy();
244
+ this.client = undefined;
245
+ }
246
+ requireInit() {
247
+ if (!this.config) {
248
+ throw new Error('S3 is not configured/enabled (ServerOptions.s3)');
249
+ }
250
+ if (!this.client || !this.sdk) {
251
+ throw new Error('CoreS3Service is not initialized yet (onModuleInit pending)');
252
+ }
253
+ return { client: this.client, config: this.config, sdk: this.sdk };
254
+ }
255
+ };
256
+ exports.CoreS3Service = CoreS3Service;
257
+ exports.CoreS3Service = CoreS3Service = CoreS3Service_1 = __decorate([
258
+ (0, common_1.Injectable)(),
259
+ __metadata("design:paramtypes", [config_service_1.ConfigService])
260
+ ], CoreS3Service);
261
+ //# sourceMappingURL=core-s3.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core-s3.service.js","sourceRoot":"","sources":["../../../../src/core/common/services/core-s3.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { Logger, OnApplicationBootstrap, OnModuleInit } from '@nestjs/common';
2
+ import { HttpAdapterHost } from '@nestjs/core';
3
+ import { IServerOptions } from '../interfaces/server-options.interface';
4
+ export declare class CoreTrustProxyInitializer implements OnApplicationBootstrap, OnModuleInit {
5
+ protected readonly httpAdapterHost?: HttpAdapterHost;
6
+ protected readonly logger: Logger;
7
+ constructor(httpAdapterHost?: HttpAdapterHost);
8
+ onModuleInit(): void;
9
+ onApplicationBootstrap(): void;
10
+ protected enabledIpRateLimiters(): string[];
11
+ protected getConfigured(): IServerOptions['trustProxy'];
12
+ protected getExpressApp(): undefined | {
13
+ get: (name: string) => any;
14
+ set: (name: string, value: any) => void;
15
+ };
16
+ }