@nest-omni/core 4.1.3-2 → 4.1.3-22

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 (441) hide show
  1. package/audit/audit.module.d.ts +11 -0
  2. package/audit/audit.module.js +65 -1
  3. package/audit/controllers/audit.controller.d.ts +81 -1
  4. package/audit/controllers/audit.controller.js +67 -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 +9 -1
  8. package/audit/decorators/audit-controller.decorator.js +11 -2
  9. package/audit/decorators/audit-operation.decorator.d.ts +38 -0
  10. package/audit/decorators/audit-operation.decorator.js +42 -0
  11. package/audit/decorators/entity-audit.decorator.d.ts +85 -1
  12. package/audit/decorators/entity-audit.decorator.js +153 -3
  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/audit-log-query.dto.d.ts +3 -0
  18. package/audit/dto/audit-log-query.dto.js +3 -0
  19. package/audit/dto/begin-transaction.dto.d.ts +3 -0
  20. package/audit/dto/begin-transaction.dto.js +3 -0
  21. package/audit/dto/compare-entities.dto.d.ts +3 -0
  22. package/audit/dto/compare-entities.dto.js +3 -0
  23. package/audit/dto/index.d.ts +1 -0
  24. package/audit/dto/index.js +1 -0
  25. package/audit/dto/pre-check-restore.dto.d.ts +3 -0
  26. package/audit/dto/pre-check-restore.dto.js +3 -0
  27. package/audit/dto/restore-entity.dto.d.ts +3 -0
  28. package/audit/dto/restore-entity.dto.js +3 -0
  29. package/audit/entities/audit-action-summary.entity.d.ts +23 -0
  30. package/audit/entities/audit-action-summary.entity.js +101 -0
  31. package/audit/entities/entity-audit-log.entity.d.ts +10 -2
  32. package/audit/entities/entity-audit-log.entity.js +48 -9
  33. package/audit/entities/entity-transaction.entity.d.ts +11 -2
  34. package/audit/entities/entity-transaction.entity.js +42 -3
  35. package/audit/entities/index.d.ts +3 -0
  36. package/audit/entities/index.js +3 -0
  37. package/audit/entities/manual-operation-log.entity.d.ts +4 -2
  38. package/audit/entities/manual-operation-log.entity.js +12 -9
  39. package/audit/entities/operation-template.entity.d.ts +4 -0
  40. package/audit/entities/operation-template.entity.js +4 -0
  41. package/audit/enums/audit.enums.d.ts +29 -6
  42. package/audit/enums/audit.enums.js +31 -7
  43. package/audit/examples/decorator-value-mapping.example.d.ts +70 -0
  44. package/audit/examples/decorator-value-mapping.example.js +414 -0
  45. package/audit/index.d.ts +5 -1
  46. package/audit/index.js +38 -1
  47. package/audit/interceptors/audit-action.interceptor.d.ts +38 -0
  48. package/audit/interceptors/audit-action.interceptor.js +215 -0
  49. package/audit/interceptors/audit.interceptor.d.ts +16 -0
  50. package/audit/interceptors/audit.interceptor.js +41 -11
  51. package/audit/interceptors/index.d.ts +1 -0
  52. package/audit/interceptors/index.js +1 -0
  53. package/audit/interfaces/audit.interfaces.d.ts +174 -4
  54. package/audit/services/audit-action.service.d.ts +141 -0
  55. package/audit/services/audit-action.service.js +244 -0
  56. package/audit/services/audit-context.service.d.ts +106 -0
  57. package/audit/services/audit-context.service.js +185 -0
  58. package/audit/services/audit-strategy.service.d.ts +6 -0
  59. package/audit/services/audit-strategy.service.js +13 -0
  60. package/audit/services/entity-audit.service.d.ts +273 -5
  61. package/audit/services/entity-audit.service.js +840 -60
  62. package/audit/services/index.d.ts +3 -0
  63. package/audit/services/index.js +3 -0
  64. package/audit/services/manual-audit-log.service.d.ts +133 -9
  65. package/audit/services/manual-audit-log.service.js +157 -42
  66. package/audit/services/multi-database.service.d.ts +9 -2
  67. package/audit/services/multi-database.service.js +9 -21
  68. package/audit/services/operation-description.service.d.ts +71 -2
  69. package/audit/services/operation-description.service.js +231 -20
  70. package/audit/services/transaction-audit.service.d.ts +30 -0
  71. package/audit/services/transaction-audit.service.js +53 -5
  72. package/audit/subscribers/entity-audit.subscriber.d.ts +20 -0
  73. package/audit/subscribers/entity-audit.subscriber.js +98 -6
  74. package/cache/cache-metrics.service.d.ts +67 -0
  75. package/cache/cache-metrics.service.js +68 -4
  76. package/cache/cache-serialization.service.d.ts +31 -0
  77. package/cache/cache-serialization.service.js +25 -0
  78. package/cache/cache.constants.d.ts +9 -0
  79. package/cache/cache.constants.js +9 -0
  80. package/cache/cache.health.d.ts +26 -0
  81. package/cache/cache.health.js +30 -0
  82. package/cache/cache.module.d.ts +87 -2
  83. package/cache/cache.module.js +84 -11
  84. package/cache/cache.service.d.ts +143 -3
  85. package/cache/cache.service.js +173 -4
  86. package/cache/cache.warmup.service.d.ts +39 -0
  87. package/cache/cache.warmup.service.js +32 -0
  88. package/cache/decorators/cache-evict.decorator.d.ts +47 -0
  89. package/cache/decorators/cache-evict.decorator.js +56 -0
  90. package/cache/decorators/cache-put.decorator.d.ts +34 -0
  91. package/cache/decorators/cache-put.decorator.js +39 -0
  92. package/cache/decorators/cacheable.decorator.d.ts +40 -0
  93. package/cache/decorators/cacheable.decorator.js +55 -0
  94. package/cache/dependencies/callback.dependency.d.ts +33 -0
  95. package/cache/dependencies/callback.dependency.js +39 -1
  96. package/cache/dependencies/chain.dependency.d.ts +28 -0
  97. package/cache/dependencies/chain.dependency.js +34 -0
  98. package/cache/dependencies/db.dependency.d.ts +83 -7
  99. package/cache/dependencies/db.dependency.js +89 -14
  100. package/cache/dependencies/file.dependency.d.ts +32 -0
  101. package/cache/dependencies/file.dependency.js +34 -0
  102. package/cache/dependencies/tag.dependency.d.ts +75 -4
  103. package/cache/dependencies/tag.dependency.js +145 -11
  104. package/cache/dependencies/time.dependency.d.ts +43 -0
  105. package/cache/dependencies/time.dependency.js +43 -0
  106. package/cache/entities/index.d.ts +1 -0
  107. package/cache/entities/index.js +17 -0
  108. package/cache/entities/typeorm-cache.entity.d.ts +71 -0
  109. package/cache/entities/typeorm-cache.entity.js +110 -0
  110. package/cache/examples/basic-usage.d.ts +15 -0
  111. package/cache/examples/basic-usage.js +62 -8
  112. package/cache/index.d.ts +2 -1
  113. package/cache/index.js +28 -2
  114. package/cache/interfaces/cache-dependency.interface.d.ts +53 -0
  115. package/cache/interfaces/cache-options.interface.d.ts +89 -0
  116. package/cache/interfaces/cache-options.interface.js +6 -0
  117. package/cache/interfaces/cache-provider.interface.d.ts +78 -0
  118. package/cache/providers/base-cache.provider.d.ts +14 -0
  119. package/cache/providers/base-cache.provider.js +16 -0
  120. package/cache/providers/cls-cache.provider.d.ts +20 -0
  121. package/cache/providers/cls-cache.provider.js +28 -0
  122. package/cache/providers/index.d.ts +2 -1
  123. package/cache/providers/index.js +2 -1
  124. package/cache/providers/lrucache.provider.d.ts +76 -0
  125. package/cache/providers/lrucache.provider.js +226 -0
  126. package/cache/providers/redis-cache.provider.d.ts +26 -0
  127. package/cache/providers/redis-cache.provider.js +29 -0
  128. package/cache/providers/typeorm-cache.provider.d.ts +211 -0
  129. package/cache/providers/typeorm-cache.provider.js +483 -0
  130. package/cache/utils/dependency-manager.util.d.ts +52 -0
  131. package/cache/utils/dependency-manager.util.js +59 -0
  132. package/cache/utils/key-generator.util.d.ts +42 -0
  133. package/cache/utils/key-generator.util.js +53 -1
  134. package/common/abstract.entity.d.ts +14 -0
  135. package/common/abstract.entity.js +14 -0
  136. package/common/boilerplate.polyfill.d.ts +143 -0
  137. package/common/boilerplate.polyfill.js +35 -1
  138. package/common/dto/dto-container.d.ts +16 -0
  139. package/common/dto/dto-container.js +20 -0
  140. package/common/dto/dto-decorators.d.ts +18 -0
  141. package/common/dto/dto-decorators.js +14 -0
  142. package/common/dto/dto-extensions.d.ts +11 -0
  143. package/common/dto/dto-extensions.js +9 -0
  144. package/common/dto/dto-service-accessor.d.ts +17 -0
  145. package/common/dto/dto-service-accessor.js +18 -0
  146. package/common/dto/dto-transformer.d.ts +12 -0
  147. package/common/dto/dto-transformer.js +9 -0
  148. package/common/dto/index.js +2 -0
  149. package/common/examples/paginate-and-map.example.d.ts +6 -0
  150. package/common/examples/paginate-and-map.example.js +26 -0
  151. package/common/helpers/validation-metadata-helper.d.ts +55 -0
  152. package/common/helpers/validation-metadata-helper.js +60 -0
  153. package/common/index.d.ts +1 -0
  154. package/common/index.js +4 -0
  155. package/common/utils.d.ts +15 -0
  156. package/common/utils.js +15 -0
  157. package/constants/language-code.js +1 -0
  158. package/decorators/field.decorators.d.ts +72 -3
  159. package/decorators/field.decorators.js +155 -19
  160. package/decorators/property.decorators.js +1 -0
  161. package/decorators/public-route.decorator.js +1 -0
  162. package/decorators/transform.decorators.d.ts +27 -2
  163. package/decorators/transform.decorators.js +29 -23
  164. package/decorators/translate.decorator.js +1 -0
  165. package/decorators/user.decorator.js +1 -0
  166. package/decorators/validator.decorators.d.ts +8 -18
  167. package/decorators/validator.decorators.js +22 -190
  168. package/file-upload/controllers/file-access.controller.d.ts +23 -0
  169. package/file-upload/controllers/file-access.controller.js +128 -0
  170. package/file-upload/decorators/column.decorator.d.ts +151 -0
  171. package/file-upload/decorators/column.decorator.js +273 -0
  172. package/file-upload/decorators/csv-data.decorator.d.ts +30 -0
  173. package/file-upload/decorators/csv-data.decorator.js +85 -0
  174. package/file-upload/decorators/csv-import.decorator.d.ts +34 -0
  175. package/file-upload/decorators/csv-import.decorator.js +24 -0
  176. package/file-upload/decorators/examples/column-mapping.example.d.ts +76 -0
  177. package/file-upload/decorators/examples/column-mapping.example.js +122 -0
  178. package/file-upload/decorators/excel-data.decorator.d.ts +30 -0
  179. package/file-upload/decorators/excel-data.decorator.js +85 -0
  180. package/file-upload/decorators/file-upload.decorator.d.ts +83 -0
  181. package/file-upload/decorators/file-upload.decorator.js +172 -0
  182. package/file-upload/decorators/index.d.ts +5 -0
  183. package/file-upload/decorators/index.js +38 -0
  184. package/file-upload/decorators/process.decorator.d.ts +40 -0
  185. package/file-upload/decorators/process.decorator.js +52 -0
  186. package/file-upload/decorators/validate-data.decorator.d.ts +91 -0
  187. package/file-upload/decorators/validate-data.decorator.js +39 -0
  188. package/file-upload/dto/create-file.dto.d.ts +24 -0
  189. package/file-upload/dto/create-file.dto.js +112 -0
  190. package/file-upload/dto/find-files.dto.d.ts +15 -0
  191. package/file-upload/dto/find-files.dto.js +76 -0
  192. package/file-upload/dto/index.d.ts +4 -0
  193. package/file-upload/dto/index.js +20 -0
  194. package/file-upload/dto/pagination.dto.d.ts +7 -0
  195. package/file-upload/dto/pagination.dto.js +39 -0
  196. package/file-upload/dto/update-file.dto.d.ts +15 -0
  197. package/file-upload/dto/update-file.dto.js +67 -0
  198. package/file-upload/entities/file-metadata.entity.d.ts +25 -0
  199. package/file-upload/entities/file-metadata.entity.js +76 -0
  200. package/file-upload/entities/file.entity.d.ts +114 -0
  201. package/file-upload/entities/file.entity.js +350 -0
  202. package/file-upload/entities/index.d.ts +2 -0
  203. package/file-upload/entities/index.js +18 -0
  204. package/file-upload/enums/file-type.enum.d.ts +72 -0
  205. package/file-upload/enums/file-type.enum.js +212 -0
  206. package/file-upload/exceptions/file-upload.exception.d.ts +57 -0
  207. package/file-upload/exceptions/file-upload.exception.js +120 -0
  208. package/file-upload/exceptions/index.d.ts +1 -0
  209. package/file-upload/exceptions/index.js +17 -0
  210. package/file-upload/file-upload.module.d.ts +89 -0
  211. package/file-upload/file-upload.module.js +292 -0
  212. package/file-upload/index.d.ts +37 -0
  213. package/file-upload/index.js +77 -0
  214. package/file-upload/interceptors/file-upload.interceptor.d.ts +101 -0
  215. package/file-upload/interceptors/file-upload.interceptor.js +594 -0
  216. package/file-upload/interceptors/index.d.ts +1 -0
  217. package/file-upload/interceptors/index.js +17 -0
  218. package/file-upload/interfaces/custom-file-type.interface.d.ts +72 -0
  219. package/file-upload/interfaces/custom-file-type.interface.js +2 -0
  220. package/file-upload/interfaces/file-buffer.interface.d.ts +72 -0
  221. package/file-upload/interfaces/file-buffer.interface.js +2 -0
  222. package/file-upload/interfaces/file-entity.interface.d.ts +142 -0
  223. package/file-upload/interfaces/file-entity.interface.js +28 -0
  224. package/file-upload/interfaces/file-metadata.interface.d.ts +21 -0
  225. package/file-upload/interfaces/file-metadata.interface.js +2 -0
  226. package/file-upload/interfaces/file-processor.interface.d.ts +93 -0
  227. package/file-upload/interfaces/file-processor.interface.js +2 -0
  228. package/file-upload/interfaces/file-upload-options.interface.d.ts +74 -0
  229. package/file-upload/interfaces/file-upload-options.interface.js +5 -0
  230. package/file-upload/interfaces/index.d.ts +7 -0
  231. package/file-upload/interfaces/index.js +24 -0
  232. package/file-upload/interfaces/processor-options.interface.d.ts +102 -0
  233. package/file-upload/interfaces/processor-options.interface.js +2 -0
  234. package/file-upload/interfaces/storage-provider.interface.d.ts +239 -0
  235. package/file-upload/interfaces/storage-provider.interface.js +2 -0
  236. package/file-upload/interfaces/upload-options.interface.d.ts +19 -0
  237. package/file-upload/interfaces/upload-options.interface.js +2 -0
  238. package/file-upload/processors/csv.processor.d.ts +98 -0
  239. package/file-upload/processors/csv.processor.js +391 -0
  240. package/file-upload/processors/excel.processor.d.ts +130 -0
  241. package/file-upload/processors/excel.processor.js +547 -0
  242. package/file-upload/processors/image.processor.d.ts +199 -0
  243. package/file-upload/processors/image.processor.js +377 -0
  244. package/file-upload/providers/index.d.ts +2 -0
  245. package/file-upload/providers/index.js +18 -0
  246. package/file-upload/providers/local-storage.provider.d.ts +98 -0
  247. package/file-upload/providers/local-storage.provider.js +484 -0
  248. package/file-upload/providers/s3-storage.provider.d.ts +87 -0
  249. package/file-upload/providers/s3-storage.provider.js +455 -0
  250. package/file-upload/services/file-signature-validator.service.d.ts +118 -0
  251. package/file-upload/services/file-signature-validator.service.js +376 -0
  252. package/file-upload/services/file.service.d.ts +193 -0
  253. package/file-upload/services/file.service.js +638 -0
  254. package/file-upload/services/index.d.ts +4 -0
  255. package/file-upload/services/index.js +20 -0
  256. package/file-upload/services/malicious-file-detector.service.d.ts +300 -0
  257. package/file-upload/services/malicious-file-detector.service.js +1234 -0
  258. package/file-upload/services/mime-registry.service.d.ts +47 -0
  259. package/file-upload/services/mime-registry.service.js +167 -0
  260. package/file-upload/utils/checksum.util.d.ts +28 -0
  261. package/file-upload/utils/checksum.util.js +65 -0
  262. package/file-upload/utils/dynamic-import.util.d.ts +54 -0
  263. package/file-upload/utils/dynamic-import.util.js +156 -0
  264. package/file-upload/utils/filename.util.d.ts +59 -0
  265. package/file-upload/utils/filename.util.js +184 -0
  266. package/file-upload/utils/filepath.util.d.ts +70 -0
  267. package/file-upload/utils/filepath.util.js +152 -0
  268. package/file-upload/utils/index.d.ts +4 -0
  269. package/file-upload/utils/index.js +20 -0
  270. package/filters/bad-request.filter.js +19 -4
  271. package/filters/constraint-errors.js +1 -0
  272. package/helpers/common.helper.d.ts +13 -0
  273. package/helpers/common.helper.js +13 -0
  274. package/http-client/config/http-client.config.d.ts +20 -0
  275. package/http-client/config/http-client.config.js +48 -21
  276. package/http-client/decorators/http-client.decorators.d.ts +55 -14
  277. package/http-client/decorators/http-client.decorators.js +154 -78
  278. package/http-client/entities/http-log.entity.d.ts +217 -8
  279. package/http-client/entities/http-log.entity.js +7 -22
  280. package/http-client/errors/http-client.errors.d.ts +57 -0
  281. package/http-client/errors/http-client.errors.js +58 -0
  282. package/http-client/examples/advanced-usage.example.d.ts +40 -0
  283. package/http-client/examples/advanced-usage.example.js +53 -61
  284. package/http-client/examples/auth-with-waiting-lock.example.d.ts +31 -0
  285. package/http-client/examples/auth-with-waiting-lock.example.js +52 -5
  286. package/http-client/examples/basic-usage.example.d.ts +60 -0
  287. package/http-client/examples/basic-usage.example.js +60 -0
  288. package/http-client/examples/multi-api-configuration.example.d.ts +60 -0
  289. package/http-client/examples/multi-api-configuration.example.js +76 -5
  290. package/http-client/examples/proxy-from-environment.example.d.ts +133 -0
  291. package/http-client/examples/proxy-from-environment.example.js +409 -0
  292. package/http-client/http-client.module.d.ts +48 -2
  293. package/http-client/http-client.module.js +147 -68
  294. package/http-client/index.d.ts +1 -1
  295. package/http-client/index.js +8 -0
  296. package/http-client/interfaces/api-client-config.interface.d.ts +80 -45
  297. package/http-client/interfaces/api-client-config.interface.js +3 -0
  298. package/http-client/interfaces/http-client-config.interface.d.ts +109 -52
  299. package/http-client/services/api-client-registry.service.d.ts +50 -11
  300. package/http-client/services/api-client-registry.service.js +90 -250
  301. package/http-client/services/circuit-breaker.service.d.ts +115 -2
  302. package/http-client/services/circuit-breaker.service.js +237 -7
  303. package/http-client/services/http-client.service.d.ts +124 -14
  304. package/http-client/services/http-client.service.js +437 -148
  305. package/http-client/services/http-log-query.service.d.ts +83 -0
  306. package/http-client/services/http-log-query.service.js +121 -13
  307. package/http-client/services/http-replay.service.d.ts +101 -0
  308. package/http-client/services/http-replay.service.js +86 -0
  309. package/http-client/services/index.d.ts +0 -1
  310. package/http-client/services/index.js +0 -1
  311. package/http-client/services/log-cleanup.service.d.ts +63 -0
  312. package/http-client/services/log-cleanup.service.js +54 -2
  313. package/http-client/services/logging.service.d.ts +116 -7
  314. package/http-client/services/logging.service.js +349 -86
  315. package/http-client/utils/call-stack-extractor.util.d.ts +63 -0
  316. package/http-client/utils/call-stack-extractor.util.js +83 -0
  317. package/http-client/utils/context-extractor.util.d.ts +49 -0
  318. package/http-client/utils/context-extractor.util.js +54 -0
  319. package/http-client/utils/curl-generator.util.d.ts +21 -0
  320. package/http-client/utils/curl-generator.util.js +44 -3
  321. package/http-client/utils/index.d.ts +1 -0
  322. package/http-client/utils/index.js +1 -0
  323. package/http-client/utils/proxy-environment.util.d.ts +42 -0
  324. package/http-client/utils/proxy-environment.util.js +148 -0
  325. package/http-client/utils/request-id.util.d.ts +18 -0
  326. package/http-client/utils/request-id.util.js +20 -0
  327. package/http-client/utils/retry-recorder.util.d.ts +42 -0
  328. package/http-client/utils/retry-recorder.util.js +44 -0
  329. package/http-client/utils/security-validator.util.d.ts +118 -0
  330. package/http-client/utils/security-validator.util.js +352 -0
  331. package/index.d.ts +3 -1
  332. package/index.js +12 -1
  333. package/interceptors/translation-interceptor.service.js +5 -0
  334. package/ip-filter/constants.d.ts +21 -0
  335. package/ip-filter/constants.js +24 -0
  336. package/ip-filter/decorators/index.d.ts +1 -0
  337. package/ip-filter/decorators/index.js +17 -0
  338. package/ip-filter/decorators/ip-filter.decorator.d.ts +58 -0
  339. package/ip-filter/decorators/ip-filter.decorator.js +79 -0
  340. package/ip-filter/guards/index.d.ts +1 -0
  341. package/ip-filter/guards/index.js +17 -0
  342. package/ip-filter/guards/ip-filter.guard.d.ts +62 -0
  343. package/ip-filter/guards/ip-filter.guard.js +174 -0
  344. package/ip-filter/index.d.ts +7 -0
  345. package/ip-filter/index.js +23 -0
  346. package/ip-filter/interfaces/index.d.ts +4 -0
  347. package/ip-filter/interfaces/index.js +20 -0
  348. package/ip-filter/interfaces/ip-filter-async-options.interface.d.ts +15 -0
  349. package/ip-filter/interfaces/ip-filter-async-options.interface.js +2 -0
  350. package/ip-filter/interfaces/ip-filter-metadata.interface.d.ts +26 -0
  351. package/ip-filter/interfaces/ip-filter-metadata.interface.js +2 -0
  352. package/ip-filter/interfaces/ip-filter-options.interface.d.ts +34 -0
  353. package/ip-filter/interfaces/ip-filter-options.interface.js +2 -0
  354. package/ip-filter/interfaces/ip-rule.interface.d.ts +36 -0
  355. package/ip-filter/interfaces/ip-rule.interface.js +2 -0
  356. package/ip-filter/ip-filter.module.d.ts +55 -0
  357. package/ip-filter/ip-filter.module.js +105 -0
  358. package/ip-filter/services/index.d.ts +1 -0
  359. package/ip-filter/services/index.js +17 -0
  360. package/ip-filter/services/ip-filter.service.d.ts +92 -0
  361. package/ip-filter/services/ip-filter.service.js +238 -0
  362. package/ip-filter/utils/index.d.ts +1 -0
  363. package/ip-filter/utils/index.js +17 -0
  364. package/ip-filter/utils/ip-utils.d.ts +61 -0
  365. package/ip-filter/utils/ip-utils.js +162 -0
  366. package/package.json +32 -29
  367. package/providers/context.provider.d.ts +9 -0
  368. package/providers/context.provider.js +15 -0
  369. package/providers/generator.provider.d.ts +4 -0
  370. package/providers/generator.provider.js +4 -0
  371. package/redis-lock/comprehensive-lock-cleanup.service.d.ts +94 -0
  372. package/redis-lock/comprehensive-lock-cleanup.service.js +253 -0
  373. package/redis-lock/examples/lock-strategy.examples.d.ts +89 -0
  374. package/redis-lock/examples/lock-strategy.examples.js +130 -15
  375. package/redis-lock/index.d.ts +2 -0
  376. package/redis-lock/index.js +8 -1
  377. package/redis-lock/lock-heartbeat.service.d.ts +80 -0
  378. package/redis-lock/lock-heartbeat.service.js +232 -0
  379. package/redis-lock/redis-lock.decorator.d.ts +101 -0
  380. package/redis-lock/redis-lock.decorator.js +120 -0
  381. package/redis-lock/redis-lock.module.d.ts +66 -0
  382. package/redis-lock/redis-lock.module.js +175 -70
  383. package/redis-lock/redis-lock.service.d.ts +282 -0
  384. package/redis-lock/redis-lock.service.js +343 -20
  385. package/setup/bootstrap.setup.d.ts +2 -1
  386. package/setup/bootstrap.setup.js +22 -1
  387. package/setup/index.d.ts +1 -0
  388. package/setup/index.js +1 -0
  389. package/setup/mode.setup.d.ts +44 -0
  390. package/setup/mode.setup.js +44 -0
  391. package/setup/run-in-mode.decorator.d.ts +56 -0
  392. package/setup/run-in-mode.decorator.js +92 -0
  393. package/setup/schedule.decorator.d.ts +227 -0
  394. package/setup/schedule.decorator.js +240 -12
  395. package/setup/worker.decorator.d.ts +86 -0
  396. package/setup/worker.decorator.js +97 -0
  397. package/shared/index.d.ts +1 -1
  398. package/shared/index.js +1 -1
  399. package/shared/{serviceRegistryModule.js → service-registry.module.js} +19 -18
  400. package/shared/services/api-config.service.d.ts +3 -0
  401. package/shared/services/api-config.service.js +21 -9
  402. package/shared/services/index.d.ts +0 -1
  403. package/shared/services/index.js +0 -1
  404. package/validator-json/decorators.d.ts +17 -0
  405. package/validator-json/decorators.js +17 -2
  406. package/validator-json/default.d.ts +6 -0
  407. package/validator-json/default.js +30 -2
  408. package/validator-json/defaultConverters.js +1 -0
  409. package/validator-json/options.d.ts +23 -0
  410. package/validators/common-validators.d.ts +143 -0
  411. package/validators/common-validators.js +249 -0
  412. package/validators/custom-validate.examples.d.ts +23 -0
  413. package/validators/custom-validate.examples.js +78 -6
  414. package/validators/custom-validate.validator.d.ts +108 -0
  415. package/validators/custom-validate.validator.js +85 -0
  416. package/validators/file-mimetype.validator.d.ts +0 -2
  417. package/validators/file-mimetype.validator.js +4 -6
  418. package/validators/index.d.ts +1 -0
  419. package/validators/index.js +1 -0
  420. package/validators/is-exists.validator.d.ts +26 -6
  421. package/validators/is-exists.validator.js +30 -7
  422. package/validators/is-unique.validator.d.ts +33 -7
  423. package/validators/is-unique.validator.js +59 -17
  424. package/validators/skip-empty.validator.d.ts +5 -0
  425. package/validators/skip-empty.validator.js +5 -0
  426. package/vault/interfaces/vault-options.interface.d.ts +9 -0
  427. package/vault/vault-config.loader.d.ts +30 -0
  428. package/vault/vault-config.loader.js +48 -1
  429. package/vault/vault-config.service.d.ts +53 -0
  430. package/vault/vault-config.service.js +57 -0
  431. package/vault/vault.module.d.ts +4 -0
  432. package/vault/vault.module.js +4 -0
  433. package/cache/providers/memory-cache.provider.d.ts +0 -26
  434. package/cache/providers/memory-cache.provider.js +0 -171
  435. package/decorators/examples/validation-decorators.example.d.ts +0 -69
  436. package/decorators/examples/validation-decorators.example.js +0 -331
  437. package/http-client/services/cache.service.d.ts +0 -24
  438. package/http-client/services/cache.service.js +0 -264
  439. package/shared/services/validator.service.d.ts +0 -3
  440. package/shared/services/validator.service.js +0 -20
  441. /package/shared/{serviceRegistryModule.d.ts → service-registry.module.d.ts} +0 -0
@@ -21,7 +21,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
21
21
  });
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.EntityAuditService = void 0;
24
+ exports.EntityAuditService = exports.AUDIT_CONSTANTS = void 0;
25
+ exports.registerEntityClass = registerEntityClass;
26
+ exports.getEntityClass = getEntityClass;
25
27
  const common_1 = require("@nestjs/common");
26
28
  const typeorm_1 = require("@nestjs/typeorm");
27
29
  const typeorm_2 = require("typeorm");
@@ -31,34 +33,93 @@ const enums_1 = require("../enums");
31
33
  const audit_context_service_1 = require("./audit-context.service");
32
34
  const audit_strategy_service_1 = require("./audit-strategy.service");
33
35
  const multi_database_service_1 = require("./multi-database.service");
36
+ const operation_description_service_1 = require("./operation-description.service");
34
37
  const dto_1 = require("../../common/dto");
38
+ const entity_audit_decorator_1 = require("../decorators/entity-audit.decorator");
39
+ const transaction_1 = require("@nest-omni/transaction");
40
+ /**
41
+ * 审计配置常量
42
+ */
43
+ exports.AUDIT_CONSTANTS = {
44
+ /** 深度比较的最大深度限制 */
45
+ MAX_DIFF_DEPTH: 5,
46
+ /** 深度比较的最大键数量限制 */
47
+ MAX_KEYS: 100,
48
+ /** 描述的最大长度 */
49
+ MAX_DESCRIPTION_LENGTH: 1000,
50
+ /** 哈希截断长度 */
51
+ HASH_TRUNCATE_LENGTH: 64,
52
+ /** 部分掩码显示的字符数 */
53
+ PARTIAL_MASK_CHARS: 2,
54
+ };
55
+ /**
56
+ * 实体类注册表 - 用于在运行时通过 entityType 字符串获取实体类引用
57
+ */
58
+ const ENTITY_CLASS_REGISTRY = new Map();
59
+ /**
60
+ * 注册实体类到注册表
61
+ */
62
+ function registerEntityClass(entityType, entityClass) {
63
+ ENTITY_CLASS_REGISTRY.set(entityType, entityClass);
64
+ }
65
+ /**
66
+ * 获取实体类
67
+ */
68
+ function getEntityClass(entityType) {
69
+ return ENTITY_CLASS_REGISTRY.get(entityType);
70
+ }
71
+ /**
72
+ * 实体审计服务
73
+ */
35
74
  let EntityAuditService = class EntityAuditService {
36
- constructor(auditLogRepository, transactionRepository, entityManager, contextService, multiDbService, auditStrategy = new audit_strategy_service_1.DefaultAuditStrategy(), config, auditConnectionName) {
75
+ constructor(auditLogRepository, transactionRepository, manualOperationRepository, entityManager, contextService, multiDbService, auditStrategy = new audit_strategy_service_1.DefaultAuditStrategy(), config, auditConnectionName, actionSummaryRepository, descriptionService) {
37
76
  this.auditLogRepository = auditLogRepository;
38
77
  this.transactionRepository = transactionRepository;
78
+ this.manualOperationRepository = manualOperationRepository;
39
79
  this.entityManager = entityManager;
40
80
  this.contextService = contextService;
41
81
  this.multiDbService = multiDbService;
42
82
  this.auditStrategy = auditStrategy;
43
83
  this.config = config;
84
+ this.actionSummaryRepository = actionSummaryRepository;
85
+ this.descriptionService = descriptionService;
44
86
  this.auditConnectionName = auditConnectionName || 'default';
45
87
  }
88
+ /**
89
+ * 记录实体变更
90
+ */
46
91
  logEntityChange(entityType_1, entityId_1, operation_1, oldValue_1, newValue_1) {
47
92
  return __awaiter(this, arguments, void 0, function* (entityType, entityId, operation, oldValue, newValue, metadata = {}) {
48
- var _a, _b;
93
+ // 检查是否应该记录
49
94
  if (!this.auditStrategy.shouldRecord(entityType, operation)) {
50
95
  return null;
51
96
  }
97
+ // 获取记录策略
52
98
  const recordStrategy = this.auditStrategy.getRecordStrategy(entityType, operation);
53
99
  if (recordStrategy === enums_1.RecordStrategy.DISABLED) {
54
100
  return null;
55
101
  }
102
+ // 获取字段过滤器
56
103
  const fieldFilter = this.auditStrategy.getFieldFilter(entityType);
104
+ // 过滤和脱敏字段
57
105
  const filteredOldValue = this.filterAndMaskFields(oldValue, fieldFilter);
58
106
  const filteredNewValue = this.filterAndMaskFields(newValue, fieldFilter);
107
+ // 计算变更字段
59
108
  const changedFields = this.calculateChangedFields(filteredOldValue, filteredNewValue);
60
- const changedFieldPaths = this.calculateChangedFieldPaths(filteredOldValue, filteredNewValue);
109
+ // 生成字段级别的变更详情(前后对比)
110
+ // CREATE 操作不需要 changeDetails,因为只有新值没有旧值
111
+ const changeDetails = operation === enums_1.AuditOperation.CREATE
112
+ ? undefined
113
+ : this.generateChangeDetails(entityType, filteredOldValue, filteredNewValue, changedFields);
114
+ // 获取上下文信息
61
115
  const context = yield this.contextService.getCurrentContext();
116
+ // 准备模板键和参数
117
+ const templateKey = metadata.operationTemplateKey || `${entityType}.${operation.toLowerCase()}`;
118
+ const descriptionParams = Object.assign({ entityType,
119
+ entityId, operation: operation.toLowerCase(), changedFields: changedFields.join(', '), changedFieldsCount: changedFields.length }, metadata.descriptionParams);
120
+ // 生成描述(优先使用模板)
121
+ const description = yield this.generateDescriptionFromTemplate(templateKey, descriptionParams, operation, entityType, entityId, changedFields);
122
+ // 创建审计日志
62
123
  const auditLog = this.auditLogRepository.create({
63
124
  entityType,
64
125
  entityId,
@@ -66,28 +127,37 @@ let EntityAuditService = class EntityAuditService {
66
127
  oldValue: filteredOldValue,
67
128
  newValue: filteredNewValue,
68
129
  changedFields,
69
- changedFieldPaths: changedFieldPaths.join(','),
130
+ changeDetails,
70
131
  userId: context.userId || metadata.userId,
71
132
  username: context.username || metadata.username,
72
133
  requestId: context.requestId || metadata.requestId,
73
134
  requestIp: context.requestIp || metadata.requestIp,
74
135
  userAgent: context.userAgent || metadata.userAgent,
75
- description: this.generateDescription(operation, entityType, entityId, changedFields),
76
- hashChain: ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.security) === null || _b === void 0 ? void 0 : _b.hashChainEnabled)
77
- ? yield this.generateHashChain(entityType, entityId, filteredNewValue)
78
- : undefined,
136
+ description,
137
+ operationTemplateKey: templateKey,
138
+ descriptionParams,
139
+ // 新增:审计动作关联字段
140
+ auditActionId: metadata.auditActionId,
141
+ auditActionName: metadata.auditActionName,
142
+ sequenceInAction: metadata.sequenceInAction || 0,
79
143
  });
144
+ // 保存变更日志
80
145
  const savedLog = yield this.auditLogRepository.save(auditLog);
81
146
  return savedLog;
82
147
  });
83
148
  }
149
+ /**
150
+ * 查询审计日志
151
+ */
84
152
  getAuditLogs(query) {
85
153
  return __awaiter(this, void 0, void 0, function* () {
154
+ // 应用默认值
86
155
  const page = query.page || 1;
87
156
  const limit = query.limit || 20;
88
157
  const sortBy = query.sortBy || 'createdAt';
89
158
  const sortOrder = query.sortOrder || 'DESC';
90
159
  const queryBuilder = this.auditLogRepository.createQueryBuilder('log');
160
+ // 应用过滤条件
91
161
  if (query.entityType) {
92
162
  queryBuilder.andWhere('log.entityType = :entityType', { entityType: query.entityType });
93
163
  }
@@ -111,7 +181,9 @@ let EntityAuditService = class EntityAuditService {
111
181
  search: `%${query.search}%`,
112
182
  });
113
183
  }
184
+ // 应用排序
114
185
  queryBuilder.orderBy(`log.${sortBy}`, sortOrder);
186
+ // 应用分页
115
187
  const skip = (page - 1) * limit;
116
188
  queryBuilder.skip(skip).take(limit);
117
189
  const [data, total] = yield queryBuilder.getManyAndCount();
@@ -124,6 +196,9 @@ let EntityAuditService = class EntityAuditService {
124
196
  return new dto_1.PageDto(data, pageMetaDto);
125
197
  });
126
198
  }
199
+ /**
200
+ * 比较实体差异
201
+ */
127
202
  compareEntities(entityType, entityId, fromLogId, toLogId) {
128
203
  return __awaiter(this, void 0, void 0, function* () {
129
204
  let fromData = {};
@@ -137,6 +212,7 @@ let EntityAuditService = class EntityAuditService {
137
212
  toData = (toLog === null || toLog === void 0 ? void 0 : toLog.newValue) || {};
138
213
  }
139
214
  else {
215
+ // 获取最新的日志
140
216
  const latestLog = yield this.auditLogRepository.findOne({
141
217
  where: { entityType, entityId },
142
218
  order: { createdAt: 'DESC' },
@@ -146,6 +222,9 @@ let EntityAuditService = class EntityAuditService {
146
222
  return this.compareSnapshotData(fromData, toData);
147
223
  });
148
224
  }
225
+ /**
226
+ * 预检查恢复操作
227
+ */
149
228
  preCheckRestore(entityType, entityId, auditLogId) {
150
229
  return __awaiter(this, void 0, void 0, function* () {
151
230
  const auditLog = yield this.auditLogRepository.findOne({ where: { id: auditLogId } });
@@ -163,8 +242,11 @@ let EntityAuditService = class EntityAuditService {
163
242
  warnings: [],
164
243
  };
165
244
  }
245
+ // 获取当前实体状态
166
246
  const repository = this.entityManager.getRepository(entityType);
167
- const currentEntity = yield repository.findOne({ where: { id: entityId } });
247
+ const currentEntity = yield repository.findOne({
248
+ where: { id: entityId },
249
+ });
168
250
  if (!currentEntity) {
169
251
  return {
170
252
  canRestore: false,
@@ -179,6 +261,7 @@ let EntityAuditService = class EntityAuditService {
179
261
  warnings: [],
180
262
  };
181
263
  }
264
+ // 检查冲突
182
265
  const conflicts = this.detectConflicts(currentEntity, auditLog.oldValue);
183
266
  return {
184
267
  canRestore: conflicts.length === 0,
@@ -187,6 +270,9 @@ let EntityAuditService = class EntityAuditService {
187
270
  };
188
271
  });
189
272
  }
273
+ /**
274
+ * 恢复实体
275
+ */
190
276
  restoreEntity(entityType_1, entityId_1, auditLogId_1) {
191
277
  return __awaiter(this, arguments, void 0, function* (entityType, entityId, auditLogId, options = {}) {
192
278
  const auditLog = yield this.auditLogRepository.findOne({ where: { id: auditLogId } });
@@ -196,6 +282,7 @@ let EntityAuditService = class EntityAuditService {
196
282
  message: '审计日志不存在',
197
283
  };
198
284
  }
285
+ // 预检查
199
286
  const preCheckResult = yield this.preCheckRestore(entityType, entityId, auditLogId);
200
287
  if (!preCheckResult.canRestore && !options.force) {
201
288
  return {
@@ -205,10 +292,13 @@ let EntityAuditService = class EntityAuditService {
205
292
  };
206
293
  }
207
294
  try {
295
+ // 获取指定的数据库连接
208
296
  const connectionName = options.connectionName || 'default';
209
- const dataSource = yield this.multiDbService.getDataSource(connectionName);
297
+ const dataSource = (0, transaction_1.getDataSource)(connectionName);
210
298
  const repository = dataSource.getRepository(entityType);
299
+ // 恢复实体
211
300
  const restoreData = Object.assign({}, auditLog.oldValue);
301
+ // 应用字段过滤
212
302
  if (options.includeFields && options.includeFields.length > 0) {
213
303
  Object.keys(restoreData).forEach((key) => {
214
304
  if (!options.includeFields.includes(key)) {
@@ -221,8 +311,10 @@ let EntityAuditService = class EntityAuditService {
221
311
  delete restoreData[field];
222
312
  });
223
313
  }
314
+ // 执行恢复
224
315
  if (!options.dryRun) {
225
316
  yield repository.update({ id: entityId }, restoreData);
317
+ // 记录恢复操作
226
318
  yield this.logEntityChange(entityType, entityId, enums_1.AuditOperation.RESTORE, auditLog.newValue, restoreData);
227
319
  }
228
320
  return {
@@ -239,26 +331,96 @@ let EntityAuditService = class EntityAuditService {
239
331
  }
240
332
  });
241
333
  }
334
+ /**
335
+ * 计算变更字段(支持嵌套路径)
336
+ */
242
337
  calculateChangedFields(oldValue, newValue) {
243
- const changedFields = [];
244
- const allFields = new Set([...Object.keys(oldValue || {}), ...Object.keys(newValue || {})]);
245
- for (const field of allFields) {
246
- const oldVal = oldValue === null || oldValue === void 0 ? void 0 : oldValue[field];
247
- const newVal = newValue === null || newValue === void 0 ? void 0 : newValue[field];
248
- if (!this.deepEqual(oldVal, newVal)) {
249
- changedFields.push(field);
250
- }
251
- }
252
- return changedFields;
338
+ // 使用 deepDiff 获取所有变更,包括嵌套字段
339
+ const diffChanges = this.deepDiff(oldValue, newValue);
340
+ // 将路径数组转换为点号分隔的字符串
341
+ return diffChanges.map(change => change.path.join('.'));
253
342
  }
254
- calculateChangedFieldPaths(oldValue, newValue) {
255
- const changedPaths = [];
256
- const diff = this.deepDiff(oldValue, newValue);
257
- for (const change of diff) {
258
- changedPaths.push(change.path.join('.'));
343
+ /**
344
+ * 生成字段级别的变更详情(前后对比,支持嵌套路径和装饰器值映射)
345
+ */
346
+ generateChangeDetails(entityType, oldValue, newValue, changedFields) {
347
+ const changeDetails = [];
348
+ // 使用 deepDiff 获取详细变更信息
349
+ const diffChanges = this.deepDiff(oldValue, newValue);
350
+ // 尝试获取实体类(用于装饰器值映射)
351
+ const entityClass = getEntityClass(entityType);
352
+ for (const change of diffChanges) {
353
+ const pathStr = change.path.join('.');
354
+ const oldVal = change.oldValue;
355
+ const newVal = change.newValue;
356
+ const fieldName = change.path[0]; // 顶层字段名
357
+ // 确定变更类型
358
+ let changeType;
359
+ if (change.type === 'ADD') {
360
+ changeType = enums_1.ChangeType.ADDED;
361
+ }
362
+ else if (change.type === 'REMOVE') {
363
+ changeType = enums_1.ChangeType.REMOVED;
364
+ }
365
+ else {
366
+ changeType = enums_1.ChangeType.MODIFIED;
367
+ }
368
+ // 尝试从装饰器获取字段标签(支持多语言)
369
+ let fieldLabels;
370
+ let displayOldValue;
371
+ let displayNewValue;
372
+ if (entityClass) {
373
+ try {
374
+ // 获取字段标签(多语言)
375
+ const supportedLanguages = ['zh', 'en', 'ja'];
376
+ fieldLabels = {};
377
+ for (const lang of supportedLanguages) {
378
+ const label = (0, entity_audit_decorator_1.getFieldLabel)(entityClass, pathStr, lang);
379
+ if (label && label !== pathStr) {
380
+ fieldLabels[lang] = label;
381
+ }
382
+ }
383
+ // 获取字段值的标签(多语言值映射)
384
+ if (oldVal !== null && oldVal !== undefined) {
385
+ const oldValueLabel = (0, entity_audit_decorator_1.getFieldValueLabel)(entityClass, fieldName, oldVal, 'zh');
386
+ if (oldValueLabel !== oldVal) {
387
+ // 如果有映射值,创建多语言映射
388
+ displayOldValue = {};
389
+ for (const lang of supportedLanguages) {
390
+ displayOldValue[lang] = (0, entity_audit_decorator_1.getFieldValueLabel)(entityClass, fieldName, oldVal, lang);
391
+ }
392
+ }
393
+ }
394
+ if (newVal !== null && newVal !== undefined) {
395
+ const newValueLabel = (0, entity_audit_decorator_1.getFieldValueLabel)(entityClass, fieldName, newVal, 'zh');
396
+ if (newValueLabel !== newVal) {
397
+ // 如果有映射值,创建多语言映射
398
+ displayNewValue = {};
399
+ for (const lang of supportedLanguages) {
400
+ displayNewValue[lang] = (0, entity_audit_decorator_1.getFieldValueLabel)(entityClass, fieldName, newVal, lang);
401
+ }
402
+ }
403
+ }
404
+ }
405
+ catch (error) {
406
+ // 忽略错误,使用默认值
407
+ }
408
+ }
409
+ changeDetails.push({
410
+ fieldName: pathStr,
411
+ fieldLabels: Object.keys(fieldLabels || {}).length > 0 ? fieldLabels : undefined,
412
+ oldValue: oldVal,
413
+ newValue: newVal,
414
+ displayOldValue,
415
+ displayNewValue,
416
+ changeType,
417
+ });
259
418
  }
260
- return changedPaths;
419
+ return changeDetails;
261
420
  }
421
+ /**
422
+ * 深度比较对象
423
+ */
262
424
  deepEqual(a, b) {
263
425
  if (a === b)
264
426
  return true;
@@ -282,13 +444,18 @@ let EntityAuditService = class EntityAuditService {
282
444
  }
283
445
  return true;
284
446
  }
285
- deepDiff(oldObj, newObj, path = []) {
286
- var _a;
447
+ /**
448
+ * 深度差异比较
449
+ */
450
+ deepDiff(oldObj, newObj, path = [], visited = new WeakSet()) {
451
+ var _a, _b;
287
452
  const changes = [];
288
- const maxDepth = ((_a = this.config) === null || _a === void 0 ? void 0 : _a.maxDiffDepth) || 5;
453
+ const maxDepth = (_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.maxDiffDepth) !== null && _b !== void 0 ? _b : exports.AUDIT_CONSTANTS.MAX_DIFF_DEPTH;
454
+ // 防止过深
289
455
  if (path.length > maxDepth) {
290
456
  return changes;
291
457
  }
458
+ // 处理基本类型
292
459
  if (typeof oldObj !== 'object' || oldObj === null) {
293
460
  if (oldObj !== newObj) {
294
461
  changes.push({
@@ -300,6 +467,20 @@ let EntityAuditService = class EntityAuditService {
300
467
  }
301
468
  return changes;
302
469
  }
470
+ // 检测循环引用
471
+ if (visited.has(oldObj)) {
472
+ // 检测到循环引用,停止递归
473
+ return changes;
474
+ }
475
+ visited.add(oldObj);
476
+ // 如果newObj也是对象,也加入访问集合
477
+ if (typeof newObj === 'object' && newObj !== null) {
478
+ if (visited.has(newObj)) {
479
+ return changes;
480
+ }
481
+ visited.add(newObj);
482
+ }
483
+ // 处理数组
303
484
  if (Array.isArray(oldObj)) {
304
485
  if (!Array.isArray(newObj)) {
305
486
  changes.push({
@@ -320,11 +501,22 @@ let EntityAuditService = class EntityAuditService {
320
501
  return changes;
321
502
  }
322
503
  for (let i = 0; i < oldObj.length; i++) {
323
- changes.push(...this.deepDiff(oldObj[i], newObj[i], [...path, i.toString()]));
504
+ changes.push(...this.deepDiff(oldObj[i], newObj[i], [...path, i.toString()], visited));
324
505
  }
325
506
  return changes;
326
507
  }
508
+ // 处理对象
327
509
  const allKeys = new Set([...Object.keys(oldObj), ...Object.keys(newObj)]);
510
+ // 添加键数量限制,防止内存溢出
511
+ if (allKeys.size > exports.AUDIT_CONSTANTS.MAX_KEYS) {
512
+ changes.push({
513
+ path,
514
+ type: 'CHANGE',
515
+ oldValue: `[Object with too many keys: ${allKeys.size}]`,
516
+ newValue: `[Object with too many keys: ${allKeys.size}]`,
517
+ });
518
+ return changes;
519
+ }
328
520
  for (const key of allKeys) {
329
521
  const oldVal = oldObj[key];
330
522
  const newVal = newObj[key];
@@ -345,11 +537,14 @@ let EntityAuditService = class EntityAuditService {
345
537
  });
346
538
  }
347
539
  else {
348
- changes.push(...this.deepDiff(oldVal, newVal, [...path, key]));
540
+ changes.push(...this.deepDiff(oldVal, newVal, [...path, key], visited));
349
541
  }
350
542
  }
351
543
  return changes;
352
544
  }
545
+ /**
546
+ * 比较快照数据
547
+ */
353
548
  compareSnapshotData(fromData, toData) {
354
549
  const changes = this.deepDiff(fromData, toData);
355
550
  return {
@@ -361,6 +556,9 @@ let EntityAuditService = class EntityAuditService {
361
556
  },
362
557
  };
363
558
  }
559
+ /**
560
+ * 过滤和脱敏字段
561
+ */
364
562
  filterAndMaskFields(data, fieldFilter, path = []) {
365
563
  if (typeof data !== 'object' || data === null) {
366
564
  return data;
@@ -368,14 +566,17 @@ let EntityAuditService = class EntityAuditService {
368
566
  const result = {};
369
567
  for (const [key, value] of Object.entries(data)) {
370
568
  const currentPath = [...path, key];
569
+ // 检查是否应该包含此字段
371
570
  if (!fieldFilter.shouldIncludeField(key, currentPath)) {
372
571
  continue;
373
572
  }
573
+ // 检查是否应该脱敏此字段
374
574
  if (fieldFilter.shouldMaskField(key, currentPath)) {
375
575
  const maskingStrategy = fieldFilter.getMaskingStrategy(key, currentPath);
376
576
  result[key] = this.applyMasking(value, maskingStrategy);
377
577
  }
378
578
  else if (typeof value === 'object' && value !== null) {
579
+ // 递归处理嵌套对象
379
580
  result[key] = this.filterAndMaskFields(value, fieldFilter, currentPath);
380
581
  }
381
582
  else {
@@ -384,6 +585,9 @@ let EntityAuditService = class EntityAuditService {
384
585
  }
385
586
  return result;
386
587
  }
588
+ /**
589
+ * 应用脱敏策略
590
+ */
387
591
  applyMasking(value, strategy) {
388
592
  if (value == null)
389
593
  return value;
@@ -400,42 +604,65 @@ let EntityAuditService = class EntityAuditService {
400
604
  return '***MASKED***';
401
605
  }
402
606
  }
607
+ /**
608
+ * 哈希值
609
+ */
403
610
  hashValue(value) {
404
611
  const strValue = String(value);
405
612
  return (0, crypto_1.createHash)('sha256').update(strValue).digest('hex');
406
613
  }
614
+ /**
615
+ * 掩码值
616
+ */
407
617
  maskValue(value) {
408
618
  const strValue = String(value);
409
619
  return '*'.repeat(strValue.length);
410
620
  }
621
+ /**
622
+ * 部分掩码值
623
+ */
411
624
  partialMaskValue(value) {
412
625
  const strValue = String(value);
413
- if (strValue.length <= 4) {
626
+ const maskChars = exports.AUDIT_CONSTANTS.PARTIAL_MASK_CHARS;
627
+ if (strValue.length <= maskChars * 2) {
414
628
  return '*'.repeat(strValue.length);
415
629
  }
416
- return (strValue.substring(0, 2) +
417
- '*'.repeat(strValue.length - 4) +
418
- strValue.substring(strValue.length - 2));
630
+ return (strValue.substring(0, maskChars) +
631
+ '*'.repeat(strValue.length - maskChars * 2) +
632
+ strValue.substring(strValue.length - maskChars));
419
633
  }
420
- generateHashChain(entityType, entityId, data) {
634
+ /**
635
+ * 生成描述(支持多语言)
636
+ * @param operation 操作类型
637
+ * @param entityType 实体类型
638
+ * @param entityId 实体ID
639
+ * @param changedFields 变更字段列表
640
+ * @param language 语言(默认中文)
641
+ * @param entityClass 实体类(可选,用于获取实体标签)
642
+ */
643
+ /**
644
+ * 使用模板生成描述(优先使用 OperationDescriptionService)
645
+ */
646
+ generateDescriptionFromTemplate(templateKey, descriptionParams, operation, entityType, entityId, changedFields) {
421
647
  return __awaiter(this, void 0, void 0, function* () {
422
- var _a, _b, _c;
423
- const lastLog = yield this.auditLogRepository.findOne({
424
- where: { entityType, entityId },
425
- order: { createdAt: 'DESC' },
426
- });
427
- const previousHash = ((_a = lastLog === null || lastLog === void 0 ? void 0 : lastLog.hashChain) === null || _a === void 0 ? void 0 : _a.currentHash) || '';
428
- const currentData = JSON.stringify(data);
429
- const hashAlgorithm = ((_c = (_b = this.config) === null || _b === void 0 ? void 0 : _b.security) === null || _c === void 0 ? void 0 : _c.hashAlgorithm) || 'sha256';
430
- const currentHash = (0, crypto_1.createHash)(hashAlgorithm).update(currentData + previousHash).digest('hex');
431
- return {
432
- previousHash,
433
- currentHash,
434
- algorithm: hashAlgorithm,
435
- };
648
+ // 优先尝试使用 OperationDescriptionService
649
+ if (this.descriptionService) {
650
+ try {
651
+ const templateDescription = yield this.descriptionService.generateDescription(templateKey, descriptionParams, 'zh');
652
+ // 如果成功获取到模板描述且不是原始的 templateKey,则使用它
653
+ if (templateDescription && templateDescription !== templateKey) {
654
+ return templateDescription;
655
+ }
656
+ }
657
+ catch (error) {
658
+ // 模板服务失败,降级到原有方式
659
+ }
660
+ }
661
+ // 降级:使用原有的描述生成逻辑
662
+ return this.generateDescription(operation, entityType, entityId, changedFields);
436
663
  });
437
664
  }
438
- generateDescription(operation, entityType, entityId, changedFields) {
665
+ generateDescription(operation, entityType, entityId, changedFields, language = 'zh', entityClass) {
439
666
  const operationText = {
440
667
  [enums_1.AuditOperation.CREATE]: '创建',
441
668
  [enums_1.AuditOperation.UPDATE]: '更新',
@@ -443,11 +670,36 @@ let EntityAuditService = class EntityAuditService {
443
670
  [enums_1.AuditOperation.RESTORE]: '恢复',
444
671
  };
445
672
  const text = operationText[operation] || operation;
673
+ // 尝试获取实体的多语言标签
674
+ let entityLabel = entityType;
675
+ if (entityClass) {
676
+ try {
677
+ entityLabel = (0, entity_audit_decorator_1.getEntityLabel)(entityClass, language);
678
+ }
679
+ catch (error) {
680
+ // 忽略错误,使用默认的 entityType
681
+ }
682
+ }
446
683
  if (operation === enums_1.AuditOperation.UPDATE && changedFields.length > 0) {
447
- return `${text} ${entityType}(${entityId}), 变更字段: ${changedFields.join(', ')}`;
684
+ // 对于更新操作,显示哪些字段发生了变化
685
+ const fieldLabels = changedFields.map(field => {
686
+ if (entityClass) {
687
+ try {
688
+ return (0, entity_audit_decorator_1.getFieldLabel)(entityClass, field, language);
689
+ }
690
+ catch (error) {
691
+ return field;
692
+ }
693
+ }
694
+ return field;
695
+ });
696
+ return `${text}${entityLabel}(${entityId}), 变更字段: ${fieldLabels.join('、')}`;
448
697
  }
449
- return `${text} ${entityType}(${entityId})`;
698
+ return `${text}${entityLabel}(${entityId})`;
450
699
  }
700
+ /**
701
+ * 检测冲突
702
+ */
451
703
  detectConflicts(currentEntity, targetValue) {
452
704
  const conflicts = [];
453
705
  for (const [key, targetVal] of Object.entries(targetValue)) {
@@ -463,22 +715,550 @@ let EntityAuditService = class EntityAuditService {
463
715
  }
464
716
  return conflicts;
465
717
  }
718
+ // ========== 新增方法:支持模板和手动操作 ==========
719
+ /**
720
+ * 增强的记录实体变更(支持模板和结构化变更详情)
721
+ * @param data 审计数据
722
+ * @returns 审计日志实体
723
+ */
724
+ logEntityChangeWithTemplate(data) {
725
+ return __awaiter(this, void 0, void 0, function* () {
726
+ var _a, _b, _c, _d, _e;
727
+ // 检查是否应该记录
728
+ if (!this.auditStrategy.shouldRecord(data.entityType, data.operation)) {
729
+ return null;
730
+ }
731
+ // 获取记录策略
732
+ const recordStrategy = this.auditStrategy.getRecordStrategy(data.entityType, data.operation);
733
+ if (recordStrategy === enums_1.RecordStrategy.DISABLED) {
734
+ return null;
735
+ }
736
+ // 获取字段过滤器
737
+ const fieldFilter = this.auditStrategy.getFieldFilter(data.entityType);
738
+ // 过滤和脱敏字段
739
+ const filteredOldValue = this.filterAndMaskFields(data.oldValue || {}, fieldFilter);
740
+ const filteredNewValue = this.filterAndMaskFields(data.newValue || {}, fieldFilter);
741
+ // 计算变更字段
742
+ const changedFields = data.changedFields || this.calculateChangedFields(filteredOldValue, filteredNewValue);
743
+ // 获取上下文信息
744
+ const context = yield this.contextService.getCurrentContext();
745
+ // 如果没有提供操作模板键,使用默认模板
746
+ const operationTemplateKey = data.operationTemplateKey || `${data.entityType}.${data.operation}`;
747
+ // 如果没有提供描述参数,使用实体数据
748
+ const descriptionParams = data.descriptionParams || Object.assign(Object.assign(Object.assign({}, filteredOldValue), filteredNewValue), { changedFields, changedFieldsCount: changedFields.length });
749
+ // 创建审计日志
750
+ const auditLog = this.auditLogRepository.create({
751
+ entityType: data.entityType,
752
+ entityId: data.entityId,
753
+ operation: data.operation,
754
+ oldValue: filteredOldValue,
755
+ newValue: filteredNewValue,
756
+ changedFields,
757
+ userId: context.userId || ((_a = data.metadata) === null || _a === void 0 ? void 0 : _a.userId),
758
+ username: context.username || ((_b = data.metadata) === null || _b === void 0 ? void 0 : _b.username),
759
+ requestId: context.requestId || ((_c = data.metadata) === null || _c === void 0 ? void 0 : _c.requestId),
760
+ requestIp: context.requestIp || ((_d = data.metadata) === null || _d === void 0 ? void 0 : _d.requestIp),
761
+ userAgent: context.userAgent || ((_e = data.metadata) === null || _e === void 0 ? void 0 : _e.userAgent),
762
+ description: this.generateDescription(data.operation, data.entityType, data.entityId, changedFields),
763
+ // 新增字段
764
+ operationTemplateKey,
765
+ descriptionParams,
766
+ changeDetails: data.changeDetails,
767
+ });
768
+ // 保存变更日志
769
+ const savedLog = yield this.auditLogRepository.save(auditLog);
770
+ return savedLog;
771
+ });
772
+ }
773
+ /**
774
+ * 记录手动操作
775
+ * @param data 手动操作数据
776
+ * @returns 手动操作日志实体
777
+ */
778
+ logManualOperation(data) {
779
+ return __awaiter(this, void 0, void 0, function* () {
780
+ // 获取上下文信息
781
+ const context = yield this.contextService.getCurrentContext();
782
+ const manualLog = this.manualOperationRepository.create({
783
+ transactionId: data.transactionId,
784
+ operationTemplateKey: data.operationTemplateKey,
785
+ descriptionParams: data.descriptionParams,
786
+ userId: data.userId || context.userId,
787
+ username: data.username || context.username,
788
+ requestIp: data.requestIp || context.requestIp,
789
+ });
790
+ return yield this.manualOperationRepository.save(manualLog);
791
+ });
792
+ }
793
+ /**
794
+ * 在事务中执行操作
795
+ * @param fn 执行函数
796
+ * @param options 事务选项
797
+ * @returns 执���结果
798
+ */
799
+ withTransaction(fn, options) {
800
+ return __awaiter(this, void 0, void 0, function* () {
801
+ var _a;
802
+ // 获取上下文信息
803
+ const context = yield this.contextService.getCurrentContext();
804
+ // 创建事务
805
+ const transaction = this.transactionRepository.create({
806
+ description: ((_a = options === null || options === void 0 ? void 0 : options.descriptionParams) === null || _a === void 0 ? void 0 : _a.description) || 'Transaction',
807
+ status: 'PENDING',
808
+ entities: [],
809
+ userId: (options === null || options === void 0 ? void 0 : options.userId) || context.userId,
810
+ username: (options === null || options === void 0 ? void 0 : options.username) || context.username,
811
+ requestIp: (options === null || options === void 0 ? void 0 : options.requestIp) || context.requestIp,
812
+ operationTemplateKey: options === null || options === void 0 ? void 0 : options.operationTemplateKey,
813
+ descriptionParams: options === null || options === void 0 ? void 0 : options.descriptionParams,
814
+ metadata: options === null || options === void 0 ? void 0 : options.metadata,
815
+ });
816
+ const savedTransaction = yield this.transactionRepository.save(transaction);
817
+ const transactionId = savedTransaction.id;
818
+ try {
819
+ // 设置事务ID到上下文
820
+ yield this.contextService.setContext(Object.assign(Object.assign({}, context), { transactionId }));
821
+ // 执行操作
822
+ const result = yield fn(transactionId);
823
+ // 提交事务
824
+ yield this.transactionRepository.update(transactionId, {
825
+ status: 'COMMITTED',
826
+ completedAt: new Date(),
827
+ });
828
+ return result;
829
+ }
830
+ catch (error) {
831
+ // 回滚事务
832
+ yield this.transactionRepository.update(transactionId, {
833
+ status: 'ROLLED_BACK',
834
+ completedAt: new Date(),
835
+ });
836
+ throw error;
837
+ }
838
+ });
839
+ }
840
+ /**
841
+ * 获取当前事务ID
842
+ * @returns 当前事务ID或null
843
+ */
844
+ getCurrentTransactionId() {
845
+ return __awaiter(this, void 0, void 0, function* () {
846
+ const context = yield this.contextService.getCurrentContext();
847
+ return context.transactionId || null;
848
+ });
849
+ }
850
+ /**
851
+ * 设置当前事务ID
852
+ * @param transactionId 事务ID
853
+ */
854
+ setCurrentTransactionId(transactionId) {
855
+ return __awaiter(this, void 0, void 0, function* () {
856
+ const context = yield this.contextService.getCurrentContext();
857
+ yield this.contextService.setContext(Object.assign(Object.assign({}, context), { transactionId }));
858
+ });
859
+ }
860
+ /**
861
+ * 开始事务
862
+ * @param userId 用户ID
863
+ * @param userName 用户名
864
+ * @param ip IP地址
865
+ * @param operationTemplateKey 操作模板键
866
+ * @param descriptionParams 描述参数
867
+ * @returns 事务ID
868
+ */
869
+ beginTransaction(userId, userName, ip, operationTemplateKey, descriptionParams) {
870
+ return __awaiter(this, void 0, void 0, function* () {
871
+ // 获取上下文信息
872
+ const context = yield this.contextService.getCurrentContext();
873
+ // 创建事务
874
+ const transaction = this.transactionRepository.create({
875
+ description: (descriptionParams === null || descriptionParams === void 0 ? void 0 : descriptionParams.description) || 'Transaction',
876
+ status: 'pending',
877
+ entities: [],
878
+ userId: userId || context.userId,
879
+ username: userName || context.username,
880
+ requestIp: ip || context.requestIp,
881
+ operationTemplateKey,
882
+ descriptionParams,
883
+ });
884
+ const savedTransaction = yield this.transactionRepository.save(transaction);
885
+ return savedTransaction.id;
886
+ });
887
+ }
888
+ /**
889
+ * 提交事务
890
+ * @param transactionId 事务ID
891
+ */
892
+ commitTransaction(transactionId) {
893
+ return __awaiter(this, void 0, void 0, function* () {
894
+ yield this.transactionRepository.update(transactionId, {
895
+ status: 'committed',
896
+ completedAt: new Date(),
897
+ });
898
+ });
899
+ }
900
+ /**
901
+ * 回滚事务
902
+ * @param transactionId 事务ID
903
+ */
904
+ rollbackTransaction(transactionId) {
905
+ return __awaiter(this, void 0, void 0, function* () {
906
+ yield this.transactionRepository.update(transactionId, {
907
+ status: 'rolled_back',
908
+ completedAt: new Date(),
909
+ });
910
+ });
911
+ }
912
+ /**
913
+ * 查询审计动作汇总记录
914
+ */
915
+ getAuditActions(options) {
916
+ return __awaiter(this, void 0, void 0, function* () {
917
+ if (!this.actionSummaryRepository) {
918
+ throw new Error('AuditActionSummaryEntity repository not available');
919
+ }
920
+ const { page = 1, limit = 20 } = options;
921
+ const queryBuilder = this.actionSummaryRepository.createQueryBuilder('action');
922
+ // 应用过滤条件
923
+ if (options.userId) {
924
+ queryBuilder.andWhere('action.userId = :userId', { userId: options.userId });
925
+ }
926
+ if (options.username) {
927
+ queryBuilder.andWhere('action.username LIKE :username', { username: `%${options.username}%` });
928
+ }
929
+ if (options.actionName) {
930
+ // 支持模糊匹配动作名
931
+ queryBuilder.andWhere('action.actionName LIKE :actionName', { actionName: `%${options.actionName}%` });
932
+ }
933
+ // 新增:全局关键词搜索(搜索多个字段)
934
+ if (options.keyword) {
935
+ queryBuilder.andWhere('(action.username LIKE :keyword OR action.actionName LIKE :keyword OR action.description LIKE :keyword)', { keyword: `%${options.keyword}%` });
936
+ }
937
+ if (options.success !== undefined) {
938
+ queryBuilder.andWhere('action.success = :success', { success: options.success });
939
+ }
940
+ if (options.startTime && options.endTime) {
941
+ queryBuilder.andWhere('action.createdAt BETWEEN :startTime AND :endTime', {
942
+ startTime: options.startTime,
943
+ endTime: options.endTime,
944
+ });
945
+ }
946
+ // 排序
947
+ queryBuilder.orderBy('action.createdAt', 'DESC');
948
+ // 分页
949
+ const skip = (page - 1) * limit;
950
+ queryBuilder.skip(skip).take(limit);
951
+ const [data, total] = yield queryBuilder.getManyAndCount();
952
+ const pageOptionsDto = new dto_1.PageOptionsDto();
953
+ Object.assign(pageOptionsDto, { page, pageSize: limit });
954
+ const pageMetaDto = new dto_1.PageMetaDto({
955
+ pageOptionsDto,
956
+ itemCount: total,
957
+ });
958
+ return new dto_1.PageDto(data, pageMetaDto);
959
+ });
960
+ }
961
+ /**
962
+ * 查询单个审计动作的详细信息(包含关联的实体变更)
963
+ * @param actionId 动作ID
964
+ * @param language 语言代码 (zh/en/ja),默认 zh
965
+ */
966
+ getAuditActionDetail(actionId_1) {
967
+ return __awaiter(this, arguments, void 0, function* (actionId, language = 'zh') {
968
+ if (!this.actionSummaryRepository) {
969
+ throw new Error('AuditActionSummaryEntity repository not available');
970
+ }
971
+ // 查询汇总信息
972
+ const summary = yield this.actionSummaryRepository.findOne({
973
+ where: { id: actionId },
974
+ });
975
+ if (!summary) {
976
+ throw new Error(`Audit action with id ${actionId} not found`);
977
+ }
978
+ // 动态生成多语言描述
979
+ const description = yield this.generateLocalizedDescription(summary.operationTemplateKey, summary.actionName, summary.descriptionParams, summary.success, language);
980
+ // 查询关联的实体变更
981
+ const entityChanges = yield this.auditLogRepository.find({
982
+ where: { auditActionId: actionId },
983
+ order: { sequenceInAction: 'ASC' },
984
+ });
985
+ // 分析每个实体的详细变化(支持多语言)
986
+ const detailedChanges = entityChanges.map((change) => {
987
+ // 使用数据库中存储的 changeDetails,并根据语言转换
988
+ const changeDetails = this.localizeChangeDetails(change.changeDetails, language);
989
+ return {
990
+ id: change.id,
991
+ entityType: change.entityType,
992
+ entityId: change.entityId,
993
+ operation: change.operation,
994
+ operationLabel: this.getOperationLabel(change.operation, language),
995
+ description: change.description,
996
+ sequenceInAction: change.sequenceInAction,
997
+ createdAt: change.createdAt,
998
+ // 数据快照
999
+ oldValue: change.oldValue,
1000
+ newValue: change.newValue,
1001
+ // 详细的字段变化分析 (使用本地化的 changeDetails)
1002
+ changeDetails,
1003
+ changedFieldsCount: (changeDetails === null || changeDetails === void 0 ? void 0 : changeDetails.length) || 0,
1004
+ changedFields: change.changedFields,
1005
+ };
1006
+ });
1007
+ // 统计信息
1008
+ const statistics = {
1009
+ totalChanges: entityChanges.length,
1010
+ totalFieldChanges: detailedChanges.reduce((sum, c) => sum + c.changedFieldsCount, 0),
1011
+ byEntityType: this.groupBy(entityChanges, 'entityType'),
1012
+ byOperation: this.groupBy(entityChanges, 'operation'),
1013
+ operationSequence: entityChanges.map((c) => ({
1014
+ sequence: c.sequenceInAction,
1015
+ entityType: c.entityType,
1016
+ operation: c.operation,
1017
+ })),
1018
+ };
1019
+ return {
1020
+ // 汇总信息(使用本地化描述)
1021
+ summary: {
1022
+ id: summary.id,
1023
+ actionName: summary.actionName,
1024
+ operationTemplateKey: summary.operationTemplateKey,
1025
+ description,
1026
+ descriptionParams: summary.descriptionParams,
1027
+ success: summary.success,
1028
+ errorMessage: summary.errorMessage,
1029
+ duration: summary.duration,
1030
+ userId: summary.userId,
1031
+ username: summary.username,
1032
+ requestId: summary.requestId,
1033
+ requestIp: summary.requestIp,
1034
+ userAgent: summary.userAgent,
1035
+ entityChangesCount: summary.entityChangesCount,
1036
+ entityTypes: summary.entityTypes,
1037
+ operationStats: summary.operationStats,
1038
+ createdAt: summary.createdAt,
1039
+ metadata: summary.metadata,
1040
+ },
1041
+ // 原始实体变更记录
1042
+ entityChanges,
1043
+ // 详细的变化分析
1044
+ detailedChanges,
1045
+ // 统计信息
1046
+ statistics,
1047
+ };
1048
+ });
1049
+ }
1050
+ /**
1051
+ * 生成本地化的描述文本
1052
+ */
1053
+ generateLocalizedDescription(templateKey, actionName, params, success, language) {
1054
+ return __awaiter(this, void 0, void 0, function* () {
1055
+ var _a;
1056
+ let template;
1057
+ // 1. 尝试从模板服务获取多语言模板
1058
+ if (templateKey && this.descriptionService) {
1059
+ try {
1060
+ template = yield this.descriptionService.getTemplate(templateKey, language);
1061
+ }
1062
+ catch (error) {
1063
+ // 如果获取模板失败,继续使用默认逻辑
1064
+ }
1065
+ }
1066
+ // 2. 如果没有模板,使用默认格式
1067
+ if (!template) {
1068
+ const actionLabels = {
1069
+ zh: { success: '执行操作', fail: '执行操作失败' },
1070
+ en: { success: 'Executed operation', fail: 'Operation failed' },
1071
+ ja: { success: '操作を実行', fail: '操作が失敗しました' },
1072
+ };
1073
+ const label = ((_a = actionLabels[language]) === null || _a === void 0 ? void 0 : _a[success ? 'success' : 'fail']) || actionLabels.zh[success ? 'success' : 'fail'];
1074
+ template = `${label}: ${actionName}`;
1075
+ }
1076
+ // 3. 执行模板替换
1077
+ return this.replaceTemplatePlaceholders(template, params);
1078
+ });
1079
+ }
1080
+ /**
1081
+ * 替换模板中的占位符
1082
+ * @param template 模板字符串,如 "创建了产品 {name},价格 ¥{price}"
1083
+ * @param params 参数对象,如 { name: "iPhone", price: 999 }
1084
+ * @returns 替换后的字符串
1085
+ */
1086
+ replaceTemplatePlaceholders(template, params) {
1087
+ let result = template;
1088
+ // 匹配 {paramName} 格式的占位符
1089
+ const placeholderPattern = /\{([^}]+)\}/g;
1090
+ result = result.replace(placeholderPattern, (match, paramName) => {
1091
+ // 支持嵌套属性访问,如 {user.name}
1092
+ const value = this.getNestedValue(params, paramName);
1093
+ return value !== undefined && value !== null ? String(value) : match;
1094
+ });
1095
+ return result;
1096
+ }
1097
+ /**
1098
+ * 获取嵌套对象的值
1099
+ * @param obj 对象
1100
+ * @param path 路径,如 "user.name" 或 "user.profile.age"
1101
+ * @returns 值或 undefined
1102
+ */
1103
+ getNestedValue(obj, path) {
1104
+ return path.split('.').reduce((current, key) => {
1105
+ return current === null || current === void 0 ? void 0 : current[key];
1106
+ }, obj);
1107
+ }
1108
+ /**
1109
+ * 本地化 changeDetails(根据语言转换 fieldLabel 和 displayValue)
1110
+ */
1111
+ localizeChangeDetails(changeDetails, language) {
1112
+ if (!changeDetails)
1113
+ return undefined;
1114
+ return changeDetails.map((detail) => {
1115
+ var _a, _b, _c, _d, _e;
1116
+ return (Object.assign(Object.assign({}, detail), { fieldLabel: ((_a = detail.fieldLabels) === null || _a === void 0 ? void 0 : _a[language]) || detail.fieldName, displayOldValue: (_c = (_b = detail.displayOldValue) === null || _b === void 0 ? void 0 : _b[language]) !== null && _c !== void 0 ? _c : detail.oldValue, displayNewValue: (_e = (_d = detail.displayNewValue) === null || _d === void 0 ? void 0 : _d[language]) !== null && _e !== void 0 ? _e : detail.newValue }));
1117
+ });
1118
+ }
1119
+ /**
1120
+ * 获取操作标签(支持多语言)
1121
+ */
1122
+ getOperationLabel(operation, language = 'zh') {
1123
+ var _a, _b;
1124
+ const labels = {
1125
+ CREATE: { zh: '创建', en: 'Create', ja: '作成' },
1126
+ UPDATE: { zh: '更新', en: 'Update', ja: '更新' },
1127
+ DELETE: { zh: '删除', en: 'Delete', ja: '削除' },
1128
+ RESTORE: { zh: '恢复', en: 'Restore', ja: '復元' },
1129
+ };
1130
+ return ((_a = labels[operation]) === null || _a === void 0 ? void 0 : _a[language]) || ((_b = labels[operation]) === null || _b === void 0 ? void 0 : _b.zh) || operation;
1131
+ }
1132
+ /**
1133
+ * 分析字段变化(支持多语言)
1134
+ * @param oldValue 旧值
1135
+ * @param newValue 新值
1136
+ * @param operation 操作类型
1137
+ * @param entityClass 实体类(可选,用于获取字段和值的多语言标签)
1138
+ * @param language 语言(默认中文)
1139
+ */
1140
+ analyzeFieldChanges(oldValue, newValue, operation, entityClass, language = 'zh') {
1141
+ const changes = [];
1142
+ const allFields = new Set([...Object.keys(oldValue), ...Object.keys(newValue)]);
1143
+ for (const field of allFields) {
1144
+ const oldVal = oldValue[field];
1145
+ const newVal = newValue[field];
1146
+ let changeType;
1147
+ if (operation === enums_1.AuditOperation.CREATE) {
1148
+ // 创建操作,所有字段都是新增
1149
+ changeType = 'added';
1150
+ }
1151
+ else if (operation === enums_1.AuditOperation.DELETE) {
1152
+ // 删除操作,所有字段都是移除
1153
+ changeType = 'removed';
1154
+ }
1155
+ else {
1156
+ // 更新操作,判断字段变化
1157
+ if (oldVal === undefined && newVal !== undefined) {
1158
+ changeType = 'added';
1159
+ }
1160
+ else if (oldVal !== undefined && newVal === undefined) {
1161
+ changeType = 'removed';
1162
+ }
1163
+ else if (JSON.stringify(oldVal) !== JSON.stringify(newVal)) {
1164
+ changeType = 'modified';
1165
+ }
1166
+ else {
1167
+ changeType = 'unchanged';
1168
+ }
1169
+ }
1170
+ // 跳过未变化的字段(对于UPDATE操作)
1171
+ if (changeType === 'unchanged' && operation === enums_1.AuditOperation.UPDATE) {
1172
+ continue;
1173
+ }
1174
+ // 获取字段的多语言标签
1175
+ let fieldLabel = field;
1176
+ if (entityClass) {
1177
+ try {
1178
+ fieldLabel = (0, entity_audit_decorator_1.getFieldLabel)(entityClass, field, language);
1179
+ }
1180
+ catch (error) {
1181
+ // 忽略错误,使用原字段名
1182
+ }
1183
+ }
1184
+ // 获取字段值的多语言标签
1185
+ let displayOldValue = this.formatDisplayValue(oldVal);
1186
+ let displayNewValue = this.formatDisplayValue(newVal);
1187
+ if (entityClass) {
1188
+ try {
1189
+ if (oldVal !== null && oldVal !== undefined) {
1190
+ const valueLabel = (0, entity_audit_decorator_1.getFieldValueLabel)(entityClass, field, oldVal, language);
1191
+ if (valueLabel !== oldVal) {
1192
+ displayOldValue = valueLabel;
1193
+ }
1194
+ }
1195
+ if (newVal !== null && newVal !== undefined) {
1196
+ const valueLabel = (0, entity_audit_decorator_1.getFieldValueLabel)(entityClass, field, newVal, language);
1197
+ if (valueLabel !== newVal) {
1198
+ displayNewValue = valueLabel;
1199
+ }
1200
+ }
1201
+ }
1202
+ catch (error) {
1203
+ // 忽略错误,使用默认格式化值
1204
+ }
1205
+ }
1206
+ changes.push({
1207
+ field,
1208
+ fieldLabel,
1209
+ oldValue: oldVal,
1210
+ newValue: newVal,
1211
+ changeType,
1212
+ displayOldValue,
1213
+ displayNewValue,
1214
+ });
1215
+ }
1216
+ return changes;
1217
+ }
1218
+ /**
1219
+ * 格式化显示值
1220
+ */
1221
+ formatDisplayValue(value) {
1222
+ if (value === null || value === undefined) {
1223
+ return '';
1224
+ }
1225
+ if (typeof value === 'object') {
1226
+ return JSON.stringify(value);
1227
+ }
1228
+ return String(value);
1229
+ }
1230
+ /**
1231
+ * 按字段分组统计
1232
+ */
1233
+ groupBy(items, field) {
1234
+ return items.reduce((acc, item) => {
1235
+ const key = item[field];
1236
+ acc[key] = (acc[key] || 0) + 1;
1237
+ return acc;
1238
+ }, {});
1239
+ }
466
1240
  };
467
1241
  exports.EntityAuditService = EntityAuditService;
468
1242
  exports.EntityAuditService = EntityAuditService = __decorate([
469
1243
  (0, common_1.Injectable)(),
470
1244
  __param(0, (0, typeorm_1.InjectRepository)(entities_1.EntityAuditLogEntity)),
471
1245
  __param(1, (0, typeorm_1.InjectRepository)(entities_1.EntityTransactionEntity)),
472
- __param(2, (0, common_1.Inject)('AUDIT_ENTITY_MANAGER')),
473
- __param(5, (0, common_1.Optional)()),
474
- __param(5, (0, common_1.Inject)('AUDIT_STRATEGY')),
1246
+ __param(2, (0, typeorm_1.InjectRepository)(entities_1.ManualOperationLogEntity)),
1247
+ __param(3, (0, common_1.Inject)('AUDIT_ENTITY_MANAGER')),
475
1248
  __param(6, (0, common_1.Optional)()),
476
- __param(6, (0, common_1.Inject)('AUDIT_CONFIG')),
1249
+ __param(6, (0, common_1.Inject)('AUDIT_STRATEGY')),
477
1250
  __param(7, (0, common_1.Optional)()),
478
- __param(7, (0, common_1.Inject)('AUDIT_CONNECTION_NAME')),
1251
+ __param(7, (0, common_1.Inject)('AUDIT_CONFIG')),
1252
+ __param(8, (0, common_1.Optional)()),
1253
+ __param(8, (0, common_1.Inject)('AUDIT_CONNECTION_NAME')),
1254
+ __param(9, (0, common_1.Optional)()),
1255
+ __param(9, (0, typeorm_1.InjectRepository)(entities_1.AuditActionSummaryEntity)),
1256
+ __param(10, (0, common_1.Optional)()),
479
1257
  __metadata("design:paramtypes", [typeorm_2.Repository,
1258
+ typeorm_2.Repository,
480
1259
  typeorm_2.Repository,
481
1260
  typeorm_2.EntityManager,
482
1261
  audit_context_service_1.AuditContextService,
483
- multi_database_service_1.MultiDatabaseService, Object, Object, String])
1262
+ multi_database_service_1.MultiDatabaseService, Object, Object, String, typeorm_2.Repository,
1263
+ operation_description_service_1.OperationDescriptionService])
484
1264
  ], EntityAuditService);