@nest-omni/core 4.1.3-3 → 4.1.3-30

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 (370) hide show
  1. package/audit/audit.module.d.ts +1 -0
  2. package/audit/audit.module.js +51 -2
  3. package/audit/controllers/audit.controller.d.ts +57 -1
  4. package/audit/controllers/audit.controller.js +43 -0
  5. package/audit/decorators/audit-action.decorator.d.ts +74 -0
  6. package/audit/decorators/audit-action.decorator.js +42 -0
  7. package/audit/decorators/audit-controller.decorator.d.ts +1 -1
  8. package/audit/decorators/audit-controller.decorator.js +2 -2
  9. package/audit/decorators/audit-operation.decorator.d.ts +0 -7
  10. package/audit/decorators/audit-operation.decorator.js +0 -7
  11. package/audit/decorators/entity-audit.decorator.d.ts +78 -2
  12. package/audit/decorators/entity-audit.decorator.js +145 -4
  13. package/audit/decorators/index.d.ts +2 -0
  14. package/audit/decorators/index.js +2 -0
  15. package/audit/dto/audit-action-query.dto.d.ts +13 -0
  16. package/audit/dto/audit-action-query.dto.js +77 -0
  17. package/audit/dto/index.d.ts +1 -0
  18. package/audit/dto/index.js +1 -0
  19. package/audit/entities/audit-action-summary.entity.d.ts +23 -0
  20. package/audit/entities/audit-action-summary.entity.js +101 -0
  21. package/audit/entities/entity-audit-log.entity.d.ts +7 -2
  22. package/audit/entities/entity-audit-log.entity.js +45 -9
  23. package/audit/entities/entity-transaction.entity.d.ts +8 -2
  24. package/audit/entities/entity-transaction.entity.js +39 -3
  25. package/audit/entities/index.d.ts +3 -0
  26. package/audit/entities/index.js +3 -0
  27. package/audit/entities/manual-operation-log.entity.d.ts +0 -2
  28. package/audit/entities/manual-operation-log.entity.js +8 -9
  29. package/audit/enums/audit.enums.d.ts +14 -6
  30. package/audit/enums/audit.enums.js +18 -9
  31. package/audit/examples/decorator-value-mapping.example.d.ts +70 -0
  32. package/audit/examples/decorator-value-mapping.example.js +414 -0
  33. package/audit/index.d.ts +5 -1
  34. package/audit/index.js +29 -2
  35. package/audit/interceptors/audit-action.interceptor.d.ts +39 -0
  36. package/audit/interceptors/audit-action.interceptor.js +217 -0
  37. package/audit/interceptors/audit.interceptor.d.ts +1 -0
  38. package/audit/interceptors/audit.interceptor.js +19 -11
  39. package/audit/interceptors/index.d.ts +1 -0
  40. package/audit/interceptors/index.js +1 -0
  41. package/audit/interfaces/audit.interfaces.d.ts +132 -4
  42. package/audit/services/audit-action.service.d.ts +142 -0
  43. package/audit/services/audit-action.service.js +246 -0
  44. package/audit/services/audit-context.service.d.ts +91 -0
  45. package/audit/services/audit-context.service.js +170 -0
  46. package/audit/services/entity-audit.service.d.ts +220 -9
  47. package/audit/services/entity-audit.service.js +761 -72
  48. package/audit/services/index.d.ts +3 -0
  49. package/audit/services/index.js +3 -0
  50. package/audit/services/manual-audit-log.service.d.ts +23 -23
  51. package/audit/services/manual-audit-log.service.js +34 -57
  52. package/audit/services/multi-database.service.d.ts +0 -5
  53. package/audit/services/multi-database.service.js +0 -24
  54. package/audit/services/operation-description.service.d.ts +14 -3
  55. package/audit/services/operation-description.service.js +165 -26
  56. package/audit/services/transaction-audit.service.d.ts +1 -0
  57. package/audit/services/transaction-audit.service.js +12 -9
  58. package/audit/subscribers/entity-audit.subscriber.d.ts +5 -0
  59. package/audit/subscribers/entity-audit.subscriber.js +69 -5
  60. package/cache/cache.module.d.ts +7 -8
  61. package/cache/cache.module.js +15 -13
  62. package/cache/cache.service.d.ts +6 -4
  63. package/cache/cache.service.js +24 -12
  64. package/cache/decorators/cache-put.decorator.js +5 -4
  65. package/cache/dependencies/callback.dependency.js +9 -0
  66. package/cache/dependencies/db.dependency.d.ts +43 -12
  67. package/cache/dependencies/db.dependency.js +46 -18
  68. package/cache/dependencies/tag.dependency.d.ts +31 -4
  69. package/cache/dependencies/tag.dependency.js +100 -11
  70. package/cache/entities/index.d.ts +1 -0
  71. package/cache/entities/index.js +17 -0
  72. package/cache/entities/typeorm-cache.entity.d.ts +71 -0
  73. package/cache/entities/typeorm-cache.entity.js +110 -0
  74. package/cache/index.d.ts +2 -1
  75. package/cache/index.js +19 -2
  76. package/cache/interfaces/cache-options.interface.d.ts +8 -0
  77. package/cache/providers/index.d.ts +2 -1
  78. package/cache/providers/index.js +2 -1
  79. package/cache/providers/lrucache.provider.d.ts +77 -0
  80. package/cache/providers/lrucache.provider.js +228 -0
  81. package/cache/providers/redis-cache.provider.d.ts +1 -0
  82. package/cache/providers/redis-cache.provider.js +8 -6
  83. package/cache/providers/typeorm-cache.provider.d.ts +211 -0
  84. package/cache/providers/typeorm-cache.provider.js +483 -0
  85. package/common/boilerplate.polyfill.d.ts +1 -0
  86. package/common/boilerplate.polyfill.js +18 -1
  87. package/common/helpers/validation-metadata-helper.d.ts +112 -0
  88. package/common/helpers/validation-metadata-helper.js +164 -0
  89. package/common/index.d.ts +1 -0
  90. package/common/index.js +4 -0
  91. package/decorators/examples/field-i18n.example.d.ts +294 -0
  92. package/decorators/examples/field-i18n.example.js +478 -0
  93. package/decorators/field.decorators.d.ts +95 -3
  94. package/decorators/field.decorators.js +152 -18
  95. package/decorators/transform.decorators.d.ts +0 -2
  96. package/decorators/transform.decorators.js +0 -23
  97. package/decorators/translate.decorator.d.ts +26 -0
  98. package/decorators/translate.decorator.js +26 -1
  99. package/email-log/email-log.constants.d.ts +8 -0
  100. package/email-log/email-log.constants.js +11 -0
  101. package/email-log/email-log.module.d.ts +47 -0
  102. package/email-log/email-log.module.js +140 -0
  103. package/email-log/index.d.ts +11 -0
  104. package/email-log/index.js +48 -0
  105. package/email-log/interfaces/email-log-options.interface.d.ts +61 -0
  106. package/email-log/interfaces/email-log-options.interface.js +134 -0
  107. package/email-log/interfaces/email-log-transport.interface.d.ts +20 -0
  108. package/email-log/interfaces/email-log-transport.interface.js +2 -0
  109. package/email-log/interfaces/index.d.ts +2 -0
  110. package/email-log/interfaces/index.js +18 -0
  111. package/email-log/providers/email-provider.d.ts +42 -0
  112. package/email-log/providers/email-provider.js +127 -0
  113. package/email-log/providers/index.d.ts +1 -0
  114. package/email-log/providers/index.js +17 -0
  115. package/email-log/services/email-log-alert.service.d.ts +46 -0
  116. package/email-log/services/email-log-alert.service.js +162 -0
  117. package/email-log/services/email-log-formatter.service.d.ts +78 -0
  118. package/email-log/services/email-log-formatter.service.js +442 -0
  119. package/email-log/services/email-log-logger.service.d.ts +85 -0
  120. package/email-log/services/email-log-logger.service.js +168 -0
  121. package/email-log/services/email-log-rate-limiter.service.d.ts +42 -0
  122. package/email-log/services/email-log-rate-limiter.service.js +110 -0
  123. package/email-log/services/email-log-transport.service.d.ts +80 -0
  124. package/email-log/services/email-log-transport.service.js +271 -0
  125. package/email-log/services/index.d.ts +5 -0
  126. package/email-log/services/index.js +21 -0
  127. package/email-log/transports/index.d.ts +1 -0
  128. package/email-log/transports/index.js +17 -0
  129. package/email-log/transports/pino-email.transport.d.ts +56 -0
  130. package/email-log/transports/pino-email.transport.js +188 -0
  131. package/email-log/utils/index.d.ts +2 -0
  132. package/email-log/utils/index.js +18 -0
  133. package/email-log/utils/log-level.helper.d.ts +46 -0
  134. package/email-log/utils/log-level.helper.js +74 -0
  135. package/email-log/utils/pino-transport.utils.d.ts +135 -0
  136. package/email-log/utils/pino-transport.utils.js +238 -0
  137. package/file-upload/controllers/file-access.controller.d.ts +23 -0
  138. package/file-upload/controllers/file-access.controller.js +128 -0
  139. package/file-upload/decorators/column.decorator.d.ts +151 -0
  140. package/file-upload/decorators/column.decorator.js +273 -0
  141. package/file-upload/decorators/csv-data.decorator.d.ts +30 -0
  142. package/file-upload/decorators/csv-data.decorator.js +85 -0
  143. package/file-upload/decorators/csv-import.decorator.d.ts +34 -0
  144. package/file-upload/decorators/csv-import.decorator.js +24 -0
  145. package/file-upload/decorators/examples/column-mapping.example.d.ts +76 -0
  146. package/file-upload/decorators/examples/column-mapping.example.js +122 -0
  147. package/file-upload/decorators/excel-data.decorator.d.ts +30 -0
  148. package/file-upload/decorators/excel-data.decorator.js +85 -0
  149. package/file-upload/decorators/file-upload.decorator.d.ts +83 -0
  150. package/file-upload/decorators/file-upload.decorator.js +172 -0
  151. package/file-upload/decorators/index.d.ts +5 -0
  152. package/file-upload/decorators/index.js +38 -0
  153. package/file-upload/decorators/process.decorator.d.ts +40 -0
  154. package/file-upload/decorators/process.decorator.js +52 -0
  155. package/file-upload/decorators/validate-data.decorator.d.ts +91 -0
  156. package/file-upload/decorators/validate-data.decorator.js +39 -0
  157. package/file-upload/dto/create-file.dto.d.ts +24 -0
  158. package/file-upload/dto/create-file.dto.js +112 -0
  159. package/file-upload/dto/find-files.dto.d.ts +15 -0
  160. package/file-upload/dto/find-files.dto.js +76 -0
  161. package/file-upload/dto/index.d.ts +4 -0
  162. package/file-upload/dto/index.js +20 -0
  163. package/file-upload/dto/pagination.dto.d.ts +7 -0
  164. package/file-upload/dto/pagination.dto.js +39 -0
  165. package/file-upload/dto/update-file.dto.d.ts +15 -0
  166. package/file-upload/dto/update-file.dto.js +67 -0
  167. package/file-upload/entities/file-metadata.entity.d.ts +25 -0
  168. package/file-upload/entities/file-metadata.entity.js +76 -0
  169. package/file-upload/entities/file.entity.d.ts +114 -0
  170. package/file-upload/entities/file.entity.js +350 -0
  171. package/file-upload/entities/index.d.ts +2 -0
  172. package/file-upload/entities/index.js +18 -0
  173. package/file-upload/enums/file-type.enum.d.ts +72 -0
  174. package/file-upload/enums/file-type.enum.js +212 -0
  175. package/file-upload/exceptions/file-upload.exception.d.ts +57 -0
  176. package/file-upload/exceptions/file-upload.exception.js +120 -0
  177. package/file-upload/exceptions/index.d.ts +1 -0
  178. package/file-upload/exceptions/index.js +17 -0
  179. package/file-upload/file-upload.module.d.ts +89 -0
  180. package/file-upload/file-upload.module.js +292 -0
  181. package/file-upload/index.d.ts +37 -0
  182. package/file-upload/index.js +77 -0
  183. package/file-upload/interceptors/file-upload.interceptor.d.ts +101 -0
  184. package/file-upload/interceptors/file-upload.interceptor.js +594 -0
  185. package/file-upload/interceptors/index.d.ts +1 -0
  186. package/file-upload/interceptors/index.js +17 -0
  187. package/file-upload/interfaces/custom-file-type.interface.d.ts +72 -0
  188. package/file-upload/interfaces/custom-file-type.interface.js +2 -0
  189. package/file-upload/interfaces/file-buffer.interface.d.ts +72 -0
  190. package/file-upload/interfaces/file-buffer.interface.js +2 -0
  191. package/file-upload/interfaces/file-entity.interface.d.ts +142 -0
  192. package/file-upload/interfaces/file-entity.interface.js +28 -0
  193. package/file-upload/interfaces/file-metadata.interface.d.ts +21 -0
  194. package/file-upload/interfaces/file-metadata.interface.js +2 -0
  195. package/file-upload/interfaces/file-processor.interface.d.ts +93 -0
  196. package/file-upload/interfaces/file-processor.interface.js +2 -0
  197. package/file-upload/interfaces/file-upload-options.interface.d.ts +74 -0
  198. package/file-upload/interfaces/file-upload-options.interface.js +5 -0
  199. package/file-upload/interfaces/index.d.ts +7 -0
  200. package/file-upload/interfaces/index.js +24 -0
  201. package/file-upload/interfaces/processor-options.interface.d.ts +102 -0
  202. package/file-upload/interfaces/processor-options.interface.js +2 -0
  203. package/file-upload/interfaces/storage-provider.interface.d.ts +239 -0
  204. package/file-upload/interfaces/storage-provider.interface.js +2 -0
  205. package/file-upload/interfaces/upload-options.interface.d.ts +19 -0
  206. package/file-upload/interfaces/upload-options.interface.js +2 -0
  207. package/file-upload/processors/csv.processor.d.ts +98 -0
  208. package/file-upload/processors/csv.processor.js +391 -0
  209. package/file-upload/processors/excel.processor.d.ts +130 -0
  210. package/file-upload/processors/excel.processor.js +547 -0
  211. package/file-upload/processors/image.processor.d.ts +199 -0
  212. package/file-upload/processors/image.processor.js +377 -0
  213. package/file-upload/providers/index.d.ts +2 -0
  214. package/file-upload/providers/index.js +18 -0
  215. package/file-upload/providers/local-storage.provider.d.ts +98 -0
  216. package/file-upload/providers/local-storage.provider.js +484 -0
  217. package/file-upload/providers/s3-storage.provider.d.ts +87 -0
  218. package/file-upload/providers/s3-storage.provider.js +455 -0
  219. package/file-upload/services/file-signature-validator.service.d.ts +118 -0
  220. package/file-upload/services/file-signature-validator.service.js +376 -0
  221. package/file-upload/services/file.service.d.ts +193 -0
  222. package/file-upload/services/file.service.js +638 -0
  223. package/file-upload/services/index.d.ts +4 -0
  224. package/file-upload/services/index.js +20 -0
  225. package/file-upload/services/malicious-file-detector.service.d.ts +300 -0
  226. package/file-upload/services/malicious-file-detector.service.js +1234 -0
  227. package/file-upload/services/mime-registry.service.d.ts +47 -0
  228. package/file-upload/services/mime-registry.service.js +167 -0
  229. package/file-upload/utils/checksum.util.d.ts +28 -0
  230. package/file-upload/utils/checksum.util.js +65 -0
  231. package/file-upload/utils/dynamic-import.util.d.ts +54 -0
  232. package/file-upload/utils/dynamic-import.util.js +156 -0
  233. package/file-upload/utils/filename.util.d.ts +59 -0
  234. package/file-upload/utils/filename.util.js +184 -0
  235. package/file-upload/utils/filepath.util.d.ts +70 -0
  236. package/file-upload/utils/filepath.util.js +152 -0
  237. package/file-upload/utils/index.d.ts +4 -0
  238. package/file-upload/utils/index.js +20 -0
  239. package/filters/bad-request.filter.d.ts +9 -0
  240. package/filters/bad-request.filter.js +57 -16
  241. package/http-client/config/http-client.config.d.ts +5 -0
  242. package/http-client/config/http-client.config.js +27 -14
  243. package/http-client/decorators/http-client.decorators.d.ts +7 -28
  244. package/http-client/decorators/http-client.decorators.js +124 -99
  245. package/http-client/entities/http-log.entity.d.ts +0 -20
  246. package/http-client/entities/http-log.entity.js +1 -21
  247. package/http-client/examples/advanced-usage.example.d.ts +4 -5
  248. package/http-client/examples/advanced-usage.example.js +7 -59
  249. package/http-client/examples/axios-config-extended.example.d.ts +17 -0
  250. package/http-client/examples/axios-config-extended.example.js +311 -0
  251. package/http-client/examples/flexible-response-example.d.ts +28 -0
  252. package/http-client/examples/flexible-response-example.js +120 -0
  253. package/http-client/examples/index.d.ts +2 -0
  254. package/http-client/examples/index.js +2 -0
  255. package/http-client/examples/proxy-from-environment.example.d.ts +133 -0
  256. package/http-client/examples/proxy-from-environment.example.js +409 -0
  257. package/http-client/examples/ssl-certificate.example.d.ts +47 -0
  258. package/http-client/examples/ssl-certificate.example.js +432 -0
  259. package/http-client/http-client.module.d.ts +43 -2
  260. package/http-client/http-client.module.js +150 -90
  261. package/http-client/index.d.ts +1 -1
  262. package/http-client/interfaces/api-client-config.interface.d.ts +24 -103
  263. package/http-client/interfaces/http-client-config.interface.d.ts +137 -62
  264. package/http-client/services/api-client-registry.service.d.ts +8 -21
  265. package/http-client/services/api-client-registry.service.js +31 -282
  266. package/http-client/services/circuit-breaker.service.d.ts +69 -2
  267. package/http-client/services/circuit-breaker.service.js +185 -7
  268. package/http-client/services/http-client.service.d.ts +85 -23
  269. package/http-client/services/http-client.service.js +512 -168
  270. package/http-client/services/http-log-query.service.js +0 -13
  271. package/http-client/services/index.d.ts +0 -1
  272. package/http-client/services/index.js +0 -1
  273. package/http-client/services/logging.service.d.ts +69 -16
  274. package/http-client/services/logging.service.js +290 -170
  275. package/http-client/utils/call-stack-extractor.util.d.ts +26 -0
  276. package/http-client/utils/call-stack-extractor.util.js +35 -0
  277. package/http-client/utils/context-extractor.util.d.ts +2 -0
  278. package/http-client/utils/context-extractor.util.js +17 -3
  279. package/http-client/utils/curl-generator.util.js +2 -5
  280. package/http-client/utils/index.d.ts +2 -0
  281. package/http-client/utils/index.js +2 -0
  282. package/http-client/utils/proxy-environment.util.d.ts +42 -0
  283. package/http-client/utils/proxy-environment.util.js +154 -0
  284. package/http-client/utils/retry-recorder.util.d.ts +0 -4
  285. package/http-client/utils/retry-recorder.util.js +2 -27
  286. package/http-client/utils/sanitize.util.d.ts +58 -0
  287. package/http-client/utils/sanitize.util.js +188 -0
  288. package/http-client/utils/security-validator.util.d.ts +118 -0
  289. package/http-client/utils/security-validator.util.js +354 -0
  290. package/index.d.ts +4 -1
  291. package/index.js +6 -1
  292. package/interceptors/translation-interceptor.service.d.ts +7 -0
  293. package/interceptors/translation-interceptor.service.js +40 -8
  294. package/ip-filter/constants.d.ts +21 -0
  295. package/ip-filter/constants.js +24 -0
  296. package/ip-filter/decorators/index.d.ts +1 -0
  297. package/ip-filter/decorators/index.js +17 -0
  298. package/ip-filter/decorators/ip-filter.decorator.d.ts +58 -0
  299. package/ip-filter/decorators/ip-filter.decorator.js +79 -0
  300. package/ip-filter/guards/index.d.ts +1 -0
  301. package/ip-filter/guards/index.js +17 -0
  302. package/ip-filter/guards/ip-filter.guard.d.ts +62 -0
  303. package/ip-filter/guards/ip-filter.guard.js +174 -0
  304. package/ip-filter/index.d.ts +7 -0
  305. package/ip-filter/index.js +23 -0
  306. package/ip-filter/interfaces/index.d.ts +4 -0
  307. package/ip-filter/interfaces/index.js +20 -0
  308. package/ip-filter/interfaces/ip-filter-async-options.interface.d.ts +15 -0
  309. package/ip-filter/interfaces/ip-filter-async-options.interface.js +2 -0
  310. package/ip-filter/interfaces/ip-filter-metadata.interface.d.ts +26 -0
  311. package/ip-filter/interfaces/ip-filter-metadata.interface.js +2 -0
  312. package/ip-filter/interfaces/ip-filter-options.interface.d.ts +34 -0
  313. package/ip-filter/interfaces/ip-filter-options.interface.js +2 -0
  314. package/ip-filter/interfaces/ip-rule.interface.d.ts +36 -0
  315. package/ip-filter/interfaces/ip-rule.interface.js +2 -0
  316. package/ip-filter/ip-filter.module.d.ts +55 -0
  317. package/ip-filter/ip-filter.module.js +105 -0
  318. package/ip-filter/services/index.d.ts +1 -0
  319. package/ip-filter/services/index.js +17 -0
  320. package/ip-filter/services/ip-filter.service.d.ts +92 -0
  321. package/ip-filter/services/ip-filter.service.js +238 -0
  322. package/ip-filter/utils/index.d.ts +1 -0
  323. package/ip-filter/utils/index.js +17 -0
  324. package/ip-filter/utils/ip-utils.d.ts +61 -0
  325. package/ip-filter/utils/ip-utils.js +162 -0
  326. package/package.json +34 -29
  327. package/providers/context.provider.d.ts +9 -0
  328. package/providers/context.provider.js +13 -0
  329. package/redis-lock/comprehensive-lock-cleanup.service.d.ts +94 -0
  330. package/redis-lock/comprehensive-lock-cleanup.service.js +253 -0
  331. package/redis-lock/index.d.ts +2 -0
  332. package/redis-lock/index.js +5 -1
  333. package/redis-lock/lock-heartbeat.service.d.ts +80 -0
  334. package/redis-lock/lock-heartbeat.service.js +232 -0
  335. package/redis-lock/redis-lock.module.d.ts +6 -0
  336. package/redis-lock/redis-lock.module.js +136 -77
  337. package/redis-lock/redis-lock.service.d.ts +31 -0
  338. package/redis-lock/redis-lock.service.js +124 -17
  339. package/setup/bootstrap.setup.d.ts +2 -1
  340. package/setup/bootstrap.setup.js +3 -2
  341. package/setup/index.d.ts +1 -0
  342. package/setup/index.js +1 -0
  343. package/setup/run-in-mode.decorator.d.ts +56 -0
  344. package/setup/run-in-mode.decorator.js +92 -0
  345. package/setup/schedule.decorator.d.ts +1 -0
  346. package/setup/schedule.decorator.js +28 -13
  347. package/setup/worker.decorator.js +10 -1
  348. package/shared/index.d.ts +1 -1
  349. package/shared/index.js +1 -1
  350. package/shared/{serviceRegistryModule.js → service-registry.module.js} +28 -17
  351. package/shared/services/api-config.service.d.ts +41 -0
  352. package/shared/services/api-config.service.js +166 -8
  353. package/shared/services/index.d.ts +0 -1
  354. package/shared/services/index.js +0 -1
  355. package/validators/custom-validate.validator.d.ts +1 -0
  356. package/validators/custom-validate.validator.js +1 -0
  357. package/validators/file-mimetype.validator.d.ts +0 -2
  358. package/validators/file-mimetype.validator.js +4 -6
  359. package/validators/is-exists.validator.d.ts +15 -6
  360. package/validators/is-exists.validator.js +8 -7
  361. package/validators/is-unique.validator.d.ts +22 -7
  362. package/validators/is-unique.validator.js +41 -17
  363. package/vault/vault-config.service.js +1 -1
  364. package/cache/providers/memory-cache.provider.d.ts +0 -49
  365. package/cache/providers/memory-cache.provider.js +0 -197
  366. package/http-client/services/cache.service.d.ts +0 -76
  367. package/http-client/services/cache.service.js +0 -333
  368. package/shared/services/validator.service.d.ts +0 -3
  369. package/shared/services/validator.service.js +0 -20
  370. /package/shared/{serviceRegistryModule.d.ts → service-registry.module.d.ts} +0 -0
@@ -27,8 +27,6 @@ const typeorm_1 = require("@nestjs/typeorm");
27
27
  const schedule_1 = require("@nestjs/schedule");
28
28
  const setup_1 = require("@sentry/nestjs/setup");
29
29
  const cache_1 = require("../cache");
30
- const transactional_1 = require("@nestjs-cls/transactional");
31
- const transactional_adapter_typeorm_1 = require("@nestjs-cls/transactional-adapter-typeorm");
32
30
  const nestjs_i18n_1 = require("nestjs-i18n");
33
31
  const health_checker_1 = require("../health-checker");
34
32
  const nestjs_redis_1 = require("@songkeys/nestjs-redis");
@@ -38,9 +36,10 @@ const redis_lock_1 = require("../redis-lock");
38
36
  const typeorm_2 = require("typeorm");
39
37
  const vault_1 = require("../vault");
40
38
  const validators_1 = require("../validators");
39
+ const transaction_1 = require("@nest-omni/transaction");
40
+ const email_log_1 = require("../email-log");
41
41
  const providers = [
42
42
  services_1.ApiConfigService,
43
- services_1.ValidatorService,
44
43
  services_1.GeneratorService,
45
44
  services_1.TranslationService,
46
45
  validators_1.IsExistsValidator,
@@ -61,19 +60,6 @@ const modules = [
61
60
  expandVariables: false,
62
61
  envFilePath: [process.env.ENV_FILE_PATH, process.env.BASE_ENV_FILE_PATH],
63
62
  }),
64
- nestjs_cls_1.ClsModule.forRoot({
65
- global: true,
66
- middleware: { mount: true, saveReq: true },
67
- plugins: [
68
- new transactional_1.ClsPluginTransactional({
69
- imports: [typeorm_1.TypeOrmModule],
70
- adapter: new transactional_adapter_typeorm_1.TransactionalAdapterTypeOrm({
71
- dataSourceToken: typeorm_2.DataSource,
72
- }),
73
- enableTransactionProxy: true,
74
- }),
75
- ],
76
- }),
77
63
  nestjs_pino_1.LoggerModule.forRootAsync({
78
64
  inject: [services_1.ApiConfigService],
79
65
  useFactory: (config) => config.pinoConfig,
@@ -101,10 +87,23 @@ const modules = [
101
87
  }),
102
88
  ];
103
89
  if (services_1.ApiConfigService.toBoolean(process.env.DB_ENABLED, true)) {
90
+ // 1. 首先导入 TransactionModule
91
+ modules.push(transaction_1.TransactionModule.forRoot());
92
+ // 2. 导入 TypeORM 模块,并在初始化后注册数据源
104
93
  modules.push(typeorm_1.TypeOrmModule.forRootAsync({
105
94
  inject: [services_1.ApiConfigService],
106
95
  useFactory: (config) => config.typeormConfig,
107
96
  }));
97
+ // 4. 配置 CLS 模块
98
+ modules.push(nestjs_cls_1.ClsModule.forRootAsync({
99
+ imports: [typeorm_1.TypeOrmModule],
100
+ useFactory(args) {
101
+ return {
102
+ middleware: { mount: true, saveReq: true },
103
+ };
104
+ },
105
+ global: true,
106
+ }));
108
107
  }
109
108
  if (services_1.ApiConfigService.toBoolean(process.env.BULL_ENABLED)) {
110
109
  modules.push(bull_1.BullModule.forRootAsync({
@@ -128,7 +127,6 @@ if (services_1.ApiConfigService.toBoolean(process.env.CACHE_ENABLED)) {
128
127
  return {
129
128
  isGlobal: true,
130
129
  redisClient,
131
- dataSource,
132
130
  memoryTtl: config.getNumber('CACHE_TTL'),
133
131
  memoryNamespace: config.getString('CACHE_NAMESPACE', 'default'),
134
132
  enableCompression: config.getBoolean('CACHE_COMPRESSION_ENABLED', false),
@@ -165,6 +163,19 @@ if (services_1.ApiConfigService.toBoolean(process.env.SCHEDULE_ENABLED) &&
165
163
  if (services_1.ApiConfigService.toBoolean(process.env.SCHEDULE_ENABLED)) {
166
164
  modules.push(schedule_1.ScheduleModule.forRoot());
167
165
  }
166
+ // Email log transport for Pino
167
+ if (services_1.ApiConfigService.toBoolean(process.env.EMAIL_LOG_ENABLED, false)) {
168
+ modules.push(email_log_1.EmailLogModule.forRootAsync({
169
+ inject: [services_1.ApiConfigService],
170
+ useFactory: (config) => {
171
+ const emailConfig = config.emailLogConfig;
172
+ if (!emailConfig) {
173
+ throw new Error('EMAIL_LOG_ENABLED is true but emailLogConfig is null');
174
+ }
175
+ return emailConfig;
176
+ },
177
+ }));
178
+ }
168
179
  let ServiceRegistryModule = class ServiceRegistryModule {
169
180
  };
170
181
  exports.ServiceRegistryModule = ServiceRegistryModule;
@@ -5,6 +5,7 @@ import { Params } from 'nestjs-pino';
5
5
  import { BullRootModuleOptions } from '@nestjs/bull/dist/interfaces/bull-module-options.interface';
6
6
  import { AxiosProxyConfig } from 'axios';
7
7
  import { CorsOptions } from '@nestjs/common/interfaces/external/cors-options.interface';
8
+ import { PinoEmailTransport } from '../../email-log';
8
9
  export declare class ApiConfigService {
9
10
  private configService;
10
11
  static rootPath: string;
@@ -47,7 +48,47 @@ export declare class ApiConfigService {
47
48
  get isRedisEnabled(): boolean;
48
49
  get bullConfig(): BullRootModuleOptions;
49
50
  get pinoConfig(): Params;
51
+ /**
52
+ * Get Pino multistream configuration with email transport
53
+ * This method provides additional stream for email logging
54
+ * Usage: pass to LoggerModule or use with pino.multistream()
55
+ */
56
+ get pinoEmailStream(): {
57
+ level: string;
58
+ stream: any;
59
+ };
50
60
  get axiosProxyConfig(): AxiosProxyConfig | false;
61
+ /**
62
+ * Email log transport configuration
63
+ * Returns null if email logging is disabled
64
+ */
65
+ get emailLogConfig(): {
66
+ enabled: boolean;
67
+ to: string[];
68
+ from: string;
69
+ level: string;
70
+ subjectPrefix: string;
71
+ smtpHost: string;
72
+ smtpPort: number;
73
+ smtpUsername: string;
74
+ smtpPassword: string;
75
+ smtpSecure: boolean;
76
+ smtpIgnoreTLSError: boolean;
77
+ rateLimitMaxEmails: number;
78
+ rateLimitWindowMs: number;
79
+ rateLimitBurstSize: number;
80
+ useHtmlFormat: boolean;
81
+ includeApps: string[];
82
+ excludeApps: string[];
83
+ includeErrors: string[];
84
+ excludeErrors: string[];
85
+ };
86
+ /**
87
+ * Get Pino email transport instance
88
+ * This returns a Pino transport that can be used directly with Pino logger
89
+ * Usage: pino(transport) or add to multistream
90
+ */
91
+ get pinoEmailTransport(): PinoEmailTransport;
51
92
  static getRootPath(): string;
52
93
  static toBoolean(value: string, defaultValue?: any): boolean;
53
94
  getNumber(key: string, defaultValue?: number): number;
@@ -16,7 +16,9 @@ const config_1 = require("@nestjs/config");
16
16
  const lodash_1 = require("lodash");
17
17
  const connect_redis_1 = require("connect-redis");
18
18
  const ioredis_1 = require("ioredis");
19
+ const pino_1 = require("pino");
19
20
  const common_2 = require("../../common");
21
+ const email_log_1 = require("../../email-log");
20
22
  let ApiConfigService = ApiConfigService_1 = class ApiConfigService {
21
23
  constructor(configService) {
22
24
  this.configService = configService;
@@ -47,6 +49,7 @@ let ApiConfigService = ApiConfigService_1 = class ApiConfigService {
47
49
  }
48
50
  get typeormConfig() {
49
51
  return {
52
+ name: 'default',
50
53
  autoLoadEntities: true,
51
54
  type: 'mysql',
52
55
  host: this.getString('DB_HOST'),
@@ -56,7 +59,7 @@ let ApiConfigService = ApiConfigService_1 = class ApiConfigService {
56
59
  password: this.getString('DB_PASSWORD'),
57
60
  database: this.getString('DB_DATABASE'),
58
61
  subscribers: [],
59
- synchronize: this.isDev,
62
+ synchronize: this.getBoolean('DB_SYNCHRONIZE', this.isDev),
60
63
  migrationsRun: true,
61
64
  logging: this.getBoolean('DB_LOG_ENABLED'),
62
65
  logger: this.isDev ? 'formatted-console' : 'simple-console',
@@ -203,15 +206,68 @@ let ApiConfigService = ApiConfigService_1 = class ApiConfigService {
203
206
  };
204
207
  }
205
208
  get pinoConfig() {
206
- const transport = this.isDev
207
- ? {
208
- target: 'pino-pretty',
209
+ const emailConfig = this.emailLogConfig;
210
+ const emailEnabled = (emailConfig === null || emailConfig === void 0 ? void 0 : emailConfig.enabled) || false;
211
+ // For dev mode without email, use pino-pretty
212
+ if (this.isDev && !emailEnabled) {
213
+ return {
214
+ pinoHttp: {
215
+ genReqId: (req) => req.id,
216
+ transport: {
217
+ target: 'pino-pretty',
218
+ },
219
+ level: 'debug',
220
+ customLogLevel: function (res) {
221
+ if (res.statusCode >= 500)
222
+ return 'error';
223
+ if (res.statusCode >= 400)
224
+ return 'warn';
225
+ return 'info';
226
+ },
227
+ wrapSerializers: true,
228
+ customProps: (req, res) => {
229
+ return {
230
+ env: this.nodeEnv,
231
+ appName: this.getString('NAME'),
232
+ user: req === null || req === void 0 ? void 0 : req.user,
233
+ 'req.body': req === null || req === void 0 ? void 0 : req.body,
234
+ 'res.body': res === null || res === void 0 ? void 0 : res.body,
235
+ };
236
+ },
237
+ redact: {
238
+ paths: ['req.headers.authorization', 'req.headers.apikey', 'req.headers.cookie'],
239
+ remove: true,
240
+ },
241
+ },
242
+ };
243
+ }
244
+ // For production or when email is enabled
245
+ // Prepare multistream targets
246
+ const streams = [
247
+ {
248
+ level: 'trace',
249
+ stream: process.stdout,
250
+ },
251
+ ];
252
+ // Add email transport if enabled
253
+ if (emailEnabled && emailConfig) {
254
+ try {
255
+ // Create email transport
256
+ const emailTransport = new email_log_1.PinoEmailTransport(emailConfig);
257
+ streams.push({
258
+ level: emailConfig.level || 'error',
259
+ stream: emailTransport,
260
+ });
209
261
  }
210
- : null;
262
+ catch (error) {
263
+ console.error('Failed to create Pino email transport:', error);
264
+ }
265
+ }
211
266
  return {
212
267
  pinoHttp: {
213
268
  genReqId: (req) => req.id,
214
- transport,
269
+ // Use multistream for combining console and email output
270
+ stream: pino_1.default.multistream(streams),
215
271
  level: this.isDev ? 'debug' : 'info',
216
272
  customLogLevel: function (res) {
217
273
  if (res.statusCode >= 500)
@@ -222,21 +278,70 @@ let ApiConfigService = ApiConfigService_1 = class ApiConfigService {
222
278
  },
223
279
  wrapSerializers: true,
224
280
  customProps: (req, res) => {
281
+ var _a, _b, _c, _d, _e;
282
+ // Get protocol, host and port from request
283
+ const protocol = req.protocol || 'http';
284
+ const hostHeader = req.get('host') || req.hostname || 'localhost';
285
+ const hostname = req.hostname || 'localhost';
286
+ const port = ((_a = req.socket) === null || _a === void 0 ? void 0 : _a.localPort) || this.appConfig.port || 3000;
287
+ // Build baseUrl - if host already includes port, don't add it again
288
+ const hasPortInHost = hostHeader.includes(':');
289
+ const baseUrl = hasPortInHost
290
+ ? `${protocol}://${hostHeader}`
291
+ : `${protocol}://${hostHeader}:${port}`;
225
292
  return {
226
293
  env: this.nodeEnv,
227
294
  appName: this.getString('NAME'),
295
+ // User information
228
296
  user: req === null || req === void 0 ? void 0 : req.user,
229
- 'req.body': req === null || req === void 0 ? void 0 : req.body,
297
+ // Request information (for email alerts)
298
+ request: req ? {
299
+ id: req.id,
300
+ method: req.method,
301
+ url: req.originalUrl || req.url,
302
+ query: req.query,
303
+ params: req.params,
304
+ body: req.body,
305
+ ip: req.ip,
306
+ protocol,
307
+ host: hostname,
308
+ port,
309
+ baseUrl,
310
+ headers: {
311
+ 'user-agent': (_b = req.headers) === null || _b === void 0 ? void 0 : _b['user-agent'],
312
+ referer: ((_c = req.headers) === null || _c === void 0 ? void 0 : _c.referer) || ((_d = req.headers) === null || _d === void 0 ? void 0 : _d.referrer),
313
+ host: (_e = req.headers) === null || _e === void 0 ? void 0 : _e.host,
314
+ },
315
+ } : undefined,
316
+ // Response body
230
317
  'res.body': res === null || res === void 0 ? void 0 : res.body,
231
318
  };
232
319
  },
233
320
  redact: {
234
- paths: ['req.headers.authorization', 'req.headers.apikey'],
321
+ paths: ['req.headers.authorization', 'req.headers.apikey', 'req.headers.cookie'],
235
322
  remove: true,
236
323
  },
237
324
  },
238
325
  };
239
326
  }
327
+ /**
328
+ * Get Pino multistream configuration with email transport
329
+ * This method provides additional stream for email logging
330
+ * Usage: pass to LoggerModule or use with pino.multistream()
331
+ */
332
+ get pinoEmailStream() {
333
+ const emailConfig = this.emailLogConfig;
334
+ if (!emailConfig || !emailConfig.enabled) {
335
+ return null;
336
+ }
337
+ // Return stream configuration for email transport
338
+ // The actual stream will be attached by EmailLogModule
339
+ return {
340
+ level: emailConfig.level,
341
+ // This will be replaced with the actual EmailLogTransportService stream
342
+ stream: null,
343
+ };
344
+ }
240
345
  get axiosProxyConfig() {
241
346
  if (!this.getBoolean('DIRECT_PROXY_ENABLED')) {
242
347
  return false;
@@ -246,6 +351,59 @@ let ApiConfigService = ApiConfigService_1 = class ApiConfigService {
246
351
  port: this.getNumber('DIRECT_PROXY_PORT'),
247
352
  };
248
353
  }
354
+ /**
355
+ * Email log transport configuration
356
+ * Returns null if email logging is disabled
357
+ */
358
+ get emailLogConfig() {
359
+ var _a, _b, _c, _d, _e, _f, _g, _h;
360
+ if (!this.getBoolean('EMAIL_LOG_ENABLED', false)) {
361
+ return null;
362
+ }
363
+ return {
364
+ enabled: true,
365
+ to: this.getString('EMAIL_LOG_TO')
366
+ .split(',')
367
+ .map((e) => e.trim())
368
+ .filter(Boolean),
369
+ from: this.getString('EMAIL_LOG_FROM'),
370
+ level: this.getString('EMAIL_LOG_LEVEL', 'error'),
371
+ subjectPrefix: this.getString('EMAIL_LOG_SUBJECT_PREFIX', '[Log Alert]'),
372
+ smtpHost: this.getString('EMAIL_LOG_SMTP_HOST'),
373
+ smtpPort: this.getNumber('EMAIL_LOG_SMTP_PORT', 587),
374
+ smtpUsername: this.getString('EMAIL_LOG_SMTP_USERNAME', ''),
375
+ smtpPassword: this.getString('EMAIL_LOG_SMTP_PASSWORD', ''),
376
+ smtpSecure: this.getBoolean('EMAIL_LOG_SMTP_SECURE', false),
377
+ smtpIgnoreTLSError: this.getBoolean('EMAIL_LOG_SMTP_IGNORE_TLS_ERROR', false),
378
+ rateLimitMaxEmails: this.getNumber('EMAIL_LOG_RATE_LIMIT_MAX_EMAILS', 10),
379
+ rateLimitWindowMs: this.getNumber('EMAIL_LOG_RATE_LIMIT_WINDOW_MS', 60000),
380
+ rateLimitBurstSize: this.getNumber('EMAIL_LOG_RATE_LIMIT_BURST_SIZE', 3),
381
+ useHtmlFormat: this.getBoolean('EMAIL_LOG_USE_HTML_FORMAT', true),
382
+ includeApps: ((_b = (_a = this.getString('EMAIL_LOG_INCLUDE_APPS', '')) === null || _a === void 0 ? void 0 : _a.split(',')) === null || _b === void 0 ? void 0 : _b.filter(Boolean)) || undefined,
383
+ excludeApps: ((_d = (_c = this.getString('EMAIL_LOG_EXCLUDE_APPS', '')) === null || _c === void 0 ? void 0 : _c.split(',')) === null || _d === void 0 ? void 0 : _d.filter(Boolean)) || undefined,
384
+ includeErrors: ((_f = (_e = this.getString('EMAIL_LOG_INCLUDE_ERRORS', '')) === null || _e === void 0 ? void 0 : _e.split(',')) === null || _f === void 0 ? void 0 : _f.filter(Boolean)) || undefined,
385
+ excludeErrors: ((_h = (_g = this.getString('EMAIL_LOG_EXCLUDE_ERRORS', '')) === null || _g === void 0 ? void 0 : _g.split(',')) === null || _h === void 0 ? void 0 : _h.filter(Boolean)) || undefined,
386
+ };
387
+ }
388
+ /**
389
+ * Get Pino email transport instance
390
+ * This returns a Pino transport that can be used directly with Pino logger
391
+ * Usage: pino(transport) or add to multistream
392
+ */
393
+ get pinoEmailTransport() {
394
+ const config = this.emailLogConfig;
395
+ if (!config) {
396
+ return null;
397
+ }
398
+ // Create and return email transport
399
+ try {
400
+ return new email_log_1.PinoEmailTransport(config);
401
+ }
402
+ catch (error) {
403
+ console.error('Failed to create Pino email transport:', error);
404
+ return null;
405
+ }
406
+ }
249
407
  static getRootPath() {
250
408
  if (!ApiConfigService_1.rootPath) {
251
409
  throw new Error(`rootPath is not set`);
@@ -1,4 +1,3 @@
1
1
  export * from './api-config.service';
2
2
  export * from './generator.service';
3
3
  export * from './translation.service';
4
- export * from './validator.service';
@@ -17,4 +17,3 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./api-config.service"), exports);
18
18
  __exportStar(require("./generator.service"), exports);
19
19
  __exportStar(require("./translation.service"), exports);
20
- __exportStar(require("./validator.service"), exports);
@@ -75,6 +75,7 @@ export declare class CustomValidateValidator implements ValidatorConstraintInter
75
75
  * 支持多种验证方式的灵活验证装饰器
76
76
  *
77
77
  * @example
78
+ *
78
79
  * // 1. 内联函数(同步)
79
80
  * @CustomValidate(
80
81
  * (value) => value > 0,
@@ -145,6 +145,7 @@ exports.CustomValidateValidator = CustomValidateValidator = __decorate([
145
145
  * 支持多种验证方式的灵活验证装饰器
146
146
  *
147
147
  * @example
148
+ *
148
149
  * // 1. 内联函数(同步)
149
150
  * @CustomValidate(
150
151
  * (value) => value > 0,
@@ -5,8 +5,6 @@ export type FileMimetypeValidatorOptions = {
5
5
  message?: string;
6
6
  };
7
7
  export declare class FileMimetypeValidator extends FileValidator<FileMimetypeValidatorOptions, IFile> {
8
- private allowedMimetypes;
9
- private message;
10
8
  constructor(options: FileMimetypeValidatorOptions);
11
9
  buildErrorMessage(): string;
12
10
  isValid(file?: IFile): boolean;
@@ -5,17 +5,15 @@ const file_validator_interface_1 = require("@nestjs/common/pipes/file/file-valid
5
5
  class FileMimetypeValidator extends file_validator_interface_1.FileValidator {
6
6
  constructor(options) {
7
7
  super(options);
8
- this.allowedMimetypes = options.allowedMimetypes;
9
- this.message = options.message;
10
8
  }
11
9
  buildErrorMessage() {
12
- if (this.message) {
13
- return this.message;
10
+ if (this.validationOptions.message) {
11
+ return this.validationOptions.message;
14
12
  }
15
- return `Invalid file type. Only ${this.allowedMimetypes.join(', ')} are allowed.`;
13
+ return `Invalid file type. Only ${this.validationOptions.allowedMimetypes.join(', ')} are allowed.`;
16
14
  }
17
15
  isValid(file) {
18
- return this.allowedMimetypes.includes(file.mimetype);
16
+ return this.validationOptions.allowedMimetypes.includes(file.mimetype);
19
17
  }
20
18
  }
21
19
  exports.FileMimetypeValidator = FileMimetypeValidator;
@@ -1,10 +1,7 @@
1
1
  import type { ValidationArguments, ValidationOptions, ValidatorConstraintInterface } from 'class-validator';
2
2
  import type { EntitySchema, FindOptionsWhere, ObjectType } from 'typeorm';
3
- import { TransactionHost } from '@nestjs-cls/transactional';
4
- import { TransactionalAdapterTypeOrm } from '@nestjs-cls/transactional-adapter-typeorm';
5
3
  export declare class IsExistsValidator implements ValidatorConstraintInterface {
6
- private readonly transactionHost;
7
- constructor(transactionHost: TransactionHost<TransactionalAdapterTypeOrm>);
4
+ constructor();
8
5
  /**
9
6
  * 解析 Entity 引用,支持多种形式:
10
7
  * 1. Entity 类直接引用
@@ -21,9 +18,21 @@ export declare class IsExistsValidator implements ValidatorConstraintInterface {
21
18
  validate<E>(value: string, args: IExistsValidationArguments<E>): Promise<boolean>;
22
19
  defaultMessage(args: ValidationArguments): string;
23
20
  }
21
+ /**
22
+ * IsExists 配置选项
23
+ */
24
+ export interface IsExistsOptions {
25
+ /**
26
+ * 数据源名称或 DataSource 实例
27
+ * 用于多数据源场景,指定使用哪个数据源进行验证
28
+ * 例如:'readonly', 'report', 或直接传入 DataSource 实例
29
+ */
30
+ dataSource?: string;
31
+ }
24
32
  type ExistsValidationConstraints<E> = [
25
- ObjectType<E> | EntitySchema<E> | string | (() => ObjectType<E> | EntitySchema<E> | string),
26
- (validationArguments: ValidationArguments) => FindOptionsWhere<E>
33
+ (ObjectType<E> | EntitySchema<E> | string | (() => ObjectType<E> | EntitySchema<E> | string)),
34
+ (validationArguments: ValidationArguments) => FindOptionsWhere<E>,
35
+ IsExistsOptions?
27
36
  ];
28
37
  interface IExistsValidationArguments<E> extends ValidationArguments {
29
38
  constraints: ExistsValidationConstraints<E>;
@@ -23,11 +23,9 @@ exports.IsExists = IsExists;
23
23
  const class_validator_1 = require("class-validator");
24
24
  const nestjs_i18n_1 = require("nestjs-i18n");
25
25
  const common_1 = require("@nestjs/common");
26
- const transactional_1 = require("@nestjs-cls/transactional");
26
+ const transaction_1 = require("@nest-omni/transaction");
27
27
  let IsExistsValidator = class IsExistsValidator {
28
- constructor(transactionHost) {
29
- this.transactionHost = transactionHost;
30
- }
28
+ constructor() { }
31
29
  /**
32
30
  * 解析 Entity 引用,支持多种形式:
33
31
  * 1. Entity 类直接引用
@@ -88,10 +86,13 @@ let IsExistsValidator = class IsExistsValidator {
88
86
  }
89
87
  validate(value, args) {
90
88
  return __awaiter(this, void 0, void 0, function* () {
91
- const [entityRef, findCondition] = args.constraints;
89
+ const [entityRef, findCondition, options] = args.constraints;
92
90
  // 解析 Entity 引用
93
91
  const entityClass = this.resolveEntity(entityRef, args.property, args.object);
94
- const repository = this.transactionHost.tx.getRepository(entityClass);
92
+ // 获取数据源(支持多数据源)
93
+ const dataSourceName = (options === null || options === void 0 ? void 0 : options.dataSource) || 'default';
94
+ const dataSource = (0, transaction_1.getDataSource)(dataSourceName);
95
+ const repository = dataSource.getRepository(entityClass);
95
96
  args.value = value;
96
97
  return ((yield repository.count({
97
98
  where: findCondition(args),
@@ -106,7 +107,7 @@ exports.IsExistsValidator = IsExistsValidator;
106
107
  exports.IsExistsValidator = IsExistsValidator = __decorate([
107
108
  (0, common_1.Injectable)(),
108
109
  (0, class_validator_1.ValidatorConstraint)({ name: 'isExists', async: true }),
109
- __metadata("design:paramtypes", [transactional_1.TransactionHost])
110
+ __metadata("design:paramtypes", [])
110
111
  ], IsExistsValidator);
111
112
  function IsExists(constraints, validationOptions) {
112
113
  return (object, propertyName) => {
@@ -1,10 +1,7 @@
1
1
  import type { ValidationArguments, ValidationOptions, ValidatorConstraintInterface } from 'class-validator';
2
- import { EntitySchema, FindOptionsWhere, ObjectType } from 'typeorm';
3
- import { TransactionHost } from '@nestjs-cls/transactional';
4
- import { TransactionalAdapterTypeOrm } from '@nestjs-cls/transactional-adapter-typeorm';
2
+ import type { EntitySchema, FindOptionsWhere, ObjectType } from 'typeorm';
5
3
  export declare class IsUniqueValidator implements ValidatorConstraintInterface {
6
- private readonly transactionHost;
7
- constructor(transactionHost: TransactionHost<TransactionalAdapterTypeOrm>);
4
+ constructor();
8
5
  /**
9
6
  * 解析 Entity 引用,支持多种形式:
10
7
  * 1. Entity 类直接引用
@@ -21,9 +18,27 @@ export declare class IsUniqueValidator implements ValidatorConstraintInterface {
21
18
  validate<E>(value: string, args: IUniqueValidationArguments<E>): Promise<boolean>;
22
19
  defaultMessage(args: ValidationArguments): string;
23
20
  }
21
+ /**
22
+ * IsUnique 配置选项
23
+ */
24
+ export interface IsUniqueOptions {
25
+ /**
26
+ * 手动指定用于判断是否为新建的字段名
27
+ * 适用于视图(View)等没有主键的场景
28
+ * 例如:uniqueKeys: ['id'] 或 uniqueKeys: ['id', 'version']
29
+ */
30
+ uniqueKeys?: string[];
31
+ /**
32
+ * 数据源名称或 DataSource 实例
33
+ * 用于多数据源场景,指定使用哪个数据源进行验证
34
+ * 例如:'readonly', 'report', 或直接传入 DataSource 实例
35
+ */
36
+ dataSource?: string;
37
+ }
24
38
  type UniqueValidationConstraints<E> = [
25
- ObjectType<E> | EntitySchema<E> | string | (() => ObjectType<E> | EntitySchema<E> | string),
26
- (validationArguments: ValidationArguments) => FindOptionsWhere<E>
39
+ (ObjectType<E> | EntitySchema<E> | string | (() => ObjectType<E> | EntitySchema<E> | string)),
40
+ (validationArguments: ValidationArguments) => FindOptionsWhere<E>,
41
+ IsUniqueOptions?
27
42
  ];
28
43
  interface IUniqueValidationArguments<E> extends ValidationArguments {
29
44
  constraints: UniqueValidationConstraints<E>;
@@ -23,11 +23,9 @@ exports.IsUnique = IsUnique;
23
23
  const class_validator_1 = require("class-validator");
24
24
  const nestjs_i18n_1 = require("nestjs-i18n");
25
25
  const common_1 = require("@nestjs/common");
26
- const transactional_1 = require("@nestjs-cls/transactional");
26
+ const transaction_1 = require("@nest-omni/transaction");
27
27
  let IsUniqueValidator = class IsUniqueValidator {
28
- constructor(transactionHost) {
29
- this.transactionHost = transactionHost;
30
- }
28
+ constructor() { }
31
29
  /**
32
30
  * 解析 Entity 引用,支持多种形式:
33
31
  * 1. Entity 类直接引用
@@ -84,40 +82,66 @@ let IsUniqueValidator = class IsUniqueValidator {
84
82
  }
85
83
  validate(value, args) {
86
84
  return __awaiter(this, void 0, void 0, function* () {
87
- const [entityRef, findCondition] = args.constraints;
85
+ const [entityRef, findCondition, options] = args.constraints;
88
86
  // 解析 Entity 引用
89
87
  const entityClass = this.resolveEntity(entityRef, args.property, args.object);
90
- const repository = this.transactionHost.tx.getRepository(entityClass);
88
+ // 获取数据源(支持多数据源)
89
+ const dataSourceName = (options === null || options === void 0 ? void 0 : options.dataSource) || 'default';
90
+ const dataSource = (0, transaction_1.getDataSource)(dataSourceName);
91
+ const repository = dataSource.getRepository(entityClass);
91
92
  args.value = value;
92
93
  let exists;
93
94
  const defCon = findCondition(args);
94
- const pkCols = repository.metadata
95
- .primaryColumns.map((column) => column.propertyName);
96
- const isNew = pkCols.some((pk) => args.object[pk]);
97
- if (!isNew) {
98
- exists =
99
- (yield repository
100
- .count({ where: defCon })) < 1;
95
+ // 获取用于判断是否为新建的字段
96
+ // 优先级:手动配置的 uniqueKeys > 实体主键
97
+ let pkCols;
98
+ if ((options === null || options === void 0 ? void 0 : options.uniqueKeys) && options.uniqueKeys.length > 0) {
99
+ // 1. 使用手动指定的字段
100
+ pkCols = options.uniqueKeys;
101
+ }
102
+ else {
103
+ // 2. 使用实体的主键
104
+ pkCols = repository.metadata.primaryColumns.map((column) => column.propertyName);
105
+ }
106
+ // 如果没有主键也没有 uniqueKeys,使用简化逻辑
107
+ // 查询条件本身表示唯一性,只要存在记录就不允许
108
+ if (pkCols.length === 0) {
109
+ const count = yield repository.count({ where: defCon });
110
+ exists = count < 1;
111
+ return exists;
112
+ }
113
+ // 修复:检查是否为新建记录
114
+ // 如果所有 uniqueKeys/主键都没有值(null/undefined),则为新建
115
+ const isNew = !pkCols.some((pk) => {
116
+ const pkValue = args.object[pk];
117
+ return pkValue !== null && pkValue !== undefined && pkValue !== '';
118
+ });
119
+ if (isNew) {
120
+ // 新建场景:简单检查是否存在相同值的记录
121
+ exists = (yield repository.count({ where: defCon })) < 1;
101
122
  }
102
123
  else {
124
+ // 更新场景:需要排除当前记录(通过主键对比)
103
125
  const entities = yield repository
104
126
  .createQueryBuilder()
105
127
  .where(defCon)
106
- .select(pkCols)
107
128
  .limit(2)
108
- .execute();
129
+ .getMany();
109
130
  const entityCount = entities.length;
110
131
  if (entityCount === 1) {
132
+ // 只有一条记录,检查是否是当前记录本身
111
133
  const entity = entities[0];
112
134
  const oldPk = {};
113
135
  const newPk = {};
114
- pkCols.map((pk) => {
136
+ pkCols.forEach((pk) => {
115
137
  oldPk[pk] = entity[pk];
116
138
  newPk[pk] = args.object[pk];
117
139
  });
140
+ // 如果主键相同,说明是自己,允许(唯一)
118
141
  exists = JSON.stringify(oldPk) === JSON.stringify(newPk);
119
142
  }
120
143
  else {
144
+ // 0条或多条记录
121
145
  exists = entityCount < 1;
122
146
  }
123
147
  }
@@ -132,7 +156,7 @@ exports.IsUniqueValidator = IsUniqueValidator;
132
156
  exports.IsUniqueValidator = IsUniqueValidator = __decorate([
133
157
  (0, common_1.Injectable)(),
134
158
  (0, class_validator_1.ValidatorConstraint)({ name: 'isUnique', async: true }),
135
- __metadata("design:paramtypes", [transactional_1.TransactionHost])
159
+ __metadata("design:paramtypes", [])
136
160
  ], IsUniqueValidator);
137
161
  function IsUnique(constraints, validationOptions) {
138
162
  return function (object, propertyName) {