@solidxai/core 0.1.6 → 0.1.7

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 (357) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/dist/controllers/dashboard-layout.controller.d.ts +47 -0
  3. package/dist/controllers/dashboard-layout.controller.d.ts.map +1 -0
  4. package/dist/controllers/dashboard-layout.controller.js +204 -0
  5. package/dist/controllers/dashboard-layout.controller.js.map +1 -0
  6. package/dist/controllers/scheduled-job.controller.d.ts +1 -0
  7. package/dist/controllers/scheduled-job.controller.d.ts.map +1 -1
  8. package/dist/controllers/scheduled-job.controller.js +12 -0
  9. package/dist/controllers/scheduled-job.controller.js.map +1 -1
  10. package/dist/dtos/create-dashboard-layout.dto.d.ts +8 -0
  11. package/dist/dtos/create-dashboard-layout.dto.d.ts.map +1 -0
  12. package/dist/dtos/create-dashboard-layout.dto.js +53 -0
  13. package/dist/dtos/create-dashboard-layout.dto.js.map +1 -0
  14. package/dist/dtos/create-dashboard-variable.dto.d.ts +1 -0
  15. package/dist/dtos/create-dashboard-variable.dto.d.ts.map +1 -1
  16. package/dist/dtos/create-dashboard-variable.dto.js +7 -1
  17. package/dist/dtos/create-dashboard-variable.dto.js.map +1 -1
  18. package/dist/dtos/update-dashboard-layout.dto.d.ts +8 -0
  19. package/dist/dtos/update-dashboard-layout.dto.d.ts.map +1 -0
  20. package/dist/dtos/update-dashboard-layout.dto.js +53 -0
  21. package/dist/dtos/update-dashboard-layout.dto.js.map +1 -0
  22. package/dist/dtos/update-dashboard-variable.dto.d.ts +1 -0
  23. package/dist/dtos/update-dashboard-variable.dto.d.ts.map +1 -1
  24. package/dist/dtos/update-dashboard-variable.dto.js +7 -1
  25. package/dist/dtos/update-dashboard-variable.dto.js.map +1 -1
  26. package/dist/entities/action-metadata.entity.d.ts.map +1 -1
  27. package/dist/entities/action-metadata.entity.js.map +1 -1
  28. package/dist/entities/ai-interaction.entity.d.ts.map +1 -1
  29. package/dist/entities/ai-interaction.entity.js +5 -4
  30. package/dist/entities/ai-interaction.entity.js.map +1 -1
  31. package/dist/entities/chatter-message-details.entity.d.ts +1 -0
  32. package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
  33. package/dist/entities/chatter-message-details.entity.js +9 -4
  34. package/dist/entities/chatter-message-details.entity.js.map +1 -1
  35. package/dist/entities/chatter-message.entity.d.ts.map +1 -1
  36. package/dist/entities/chatter-message.entity.js +4 -3
  37. package/dist/entities/chatter-message.entity.js.map +1 -1
  38. package/dist/entities/common.entity.js +1 -1
  39. package/dist/entities/common.entity.js.map +1 -1
  40. package/dist/entities/dashboard-layout.entity.d.ts +9 -0
  41. package/dist/entities/dashboard-layout.entity.d.ts.map +1 -0
  42. package/dist/entities/dashboard-layout.entity.js +41 -0
  43. package/dist/entities/dashboard-layout.entity.js.map +1 -0
  44. package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts.map +1 -1
  45. package/dist/entities/dashboard-question-sql-dataset-config.entity.js +5 -4
  46. package/dist/entities/dashboard-question-sql-dataset-config.entity.js.map +1 -1
  47. package/dist/entities/dashboard-question.entity.d.ts.map +1 -1
  48. package/dist/entities/dashboard-question.entity.js +5 -4
  49. package/dist/entities/dashboard-question.entity.js.map +1 -1
  50. package/dist/entities/dashboard-variable.entity.d.ts +1 -0
  51. package/dist/entities/dashboard-variable.entity.d.ts.map +1 -1
  52. package/dist/entities/dashboard-variable.entity.js +10 -4
  53. package/dist/entities/dashboard-variable.entity.js.map +1 -1
  54. package/dist/entities/dashboard.entity.d.ts +2 -0
  55. package/dist/entities/dashboard.entity.d.ts.map +1 -1
  56. package/dist/entities/dashboard.entity.js +9 -3
  57. package/dist/entities/dashboard.entity.js.map +1 -1
  58. package/dist/entities/email-attachment.entity.d.ts.map +1 -1
  59. package/dist/entities/email-attachment.entity.js +2 -1
  60. package/dist/entities/email-attachment.entity.js.map +1 -1
  61. package/dist/entities/email-template.entity.js +1 -1
  62. package/dist/entities/email-template.entity.js.map +1 -1
  63. package/dist/entities/export-transaction.entity.d.ts.map +1 -1
  64. package/dist/entities/export-transaction.entity.js +2 -1
  65. package/dist/entities/export-transaction.entity.js.map +1 -1
  66. package/dist/entities/field-metadata.entity.js +2 -2
  67. package/dist/entities/field-metadata.entity.js.map +1 -1
  68. package/dist/entities/import-transaction-error-log.entity.d.ts.map +1 -1
  69. package/dist/entities/import-transaction-error-log.entity.js +3 -2
  70. package/dist/entities/import-transaction-error-log.entity.js.map +1 -1
  71. package/dist/entities/import-transaction.entity.d.ts.map +1 -1
  72. package/dist/entities/import-transaction.entity.js +2 -1
  73. package/dist/entities/import-transaction.entity.js.map +1 -1
  74. package/dist/entities/legacy-common.entity.d.ts.map +1 -1
  75. package/dist/entities/legacy-common.entity.js +1 -1
  76. package/dist/entities/legacy-common.entity.js.map +1 -1
  77. package/dist/entities/mq-message-queue.entity.d.ts.map +1 -1
  78. package/dist/entities/mq-message-queue.entity.js.map +1 -1
  79. package/dist/entities/mq-message.entity.d.ts.map +1 -1
  80. package/dist/entities/mq-message.entity.js +5 -3
  81. package/dist/entities/mq-message.entity.js.map +1 -1
  82. package/dist/entities/saved-filters.entity.d.ts.map +1 -1
  83. package/dist/entities/saved-filters.entity.js +3 -2
  84. package/dist/entities/saved-filters.entity.js.map +1 -1
  85. package/dist/entities/security-rule.entity.d.ts.map +1 -1
  86. package/dist/entities/security-rule.entity.js +2 -1
  87. package/dist/entities/security-rule.entity.js.map +1 -1
  88. package/dist/entities/sms-template.entity.js +1 -1
  89. package/dist/entities/sms-template.entity.js.map +1 -1
  90. package/dist/entities/user-view-metadata.entity.d.ts.map +1 -1
  91. package/dist/entities/user-view-metadata.entity.js +2 -1
  92. package/dist/entities/user-view-metadata.entity.js.map +1 -1
  93. package/dist/entities/user.entity.d.ts.map +1 -1
  94. package/dist/entities/user.entity.js +2 -0
  95. package/dist/entities/user.entity.js.map +1 -1
  96. package/dist/entities/view-metadata.entity.d.ts.map +1 -1
  97. package/dist/entities/view-metadata.entity.js.map +1 -1
  98. package/dist/helpers/bootstrap.helper.d.ts +14 -0
  99. package/dist/helpers/bootstrap.helper.d.ts.map +1 -0
  100. package/dist/helpers/bootstrap.helper.js +132 -0
  101. package/dist/helpers/bootstrap.helper.js.map +1 -0
  102. package/dist/helpers/cache.helper.d.ts +2 -0
  103. package/dist/helpers/cache.helper.d.ts.map +1 -0
  104. package/dist/helpers/cache.helper.js +8 -0
  105. package/dist/helpers/cache.helper.js.map +1 -0
  106. package/dist/helpers/cors.helper.d.ts.map +1 -1
  107. package/dist/helpers/cors.helper.js +13 -4
  108. package/dist/helpers/cors.helper.js.map +1 -1
  109. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts +2 -2
  110. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts.map +1 -1
  111. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js +8 -5
  112. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
  113. package/dist/helpers/solid-registry.d.ts +3 -0
  114. package/dist/helpers/solid-registry.d.ts.map +1 -1
  115. package/dist/helpers/solid-registry.js +7 -0
  116. package/dist/helpers/solid-registry.js.map +1 -1
  117. package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
  118. package/dist/helpers/typeorm-db-helper.js +21 -0
  119. package/dist/helpers/typeorm-db-helper.js.map +1 -1
  120. package/dist/index.d.ts +3 -0
  121. package/dist/index.d.ts.map +1 -1
  122. package/dist/index.js +3 -0
  123. package/dist/index.js.map +1 -1
  124. package/dist/interfaces.d.ts +6 -1
  125. package/dist/interfaces.d.ts.map +1 -1
  126. package/dist/interfaces.js.map +1 -1
  127. package/dist/jobs/chatter-queue-options.js +1 -1
  128. package/dist/jobs/chatter-queue-options.js.map +1 -1
  129. package/dist/jobs/chatter-queue-publisher.service.d.ts +9 -9
  130. package/dist/jobs/chatter-queue-publisher.service.d.ts.map +1 -1
  131. package/dist/jobs/chatter-queue-publisher.service.js +5 -5
  132. package/dist/jobs/chatter-queue-publisher.service.js.map +1 -1
  133. package/dist/jobs/chatter-queue-subscriber.service.d.ts +4 -4
  134. package/dist/jobs/chatter-queue-subscriber.service.d.ts.map +1 -1
  135. package/dist/jobs/chatter-queue-subscriber.service.js +11 -11
  136. package/dist/jobs/chatter-queue-subscriber.service.js.map +1 -1
  137. package/dist/jobs/computed-field-evaluation-queue-options.d.ts +2 -0
  138. package/dist/jobs/computed-field-evaluation-queue-options.d.ts.map +1 -1
  139. package/dist/jobs/computed-field-evaluation-queue-options.js +2 -0
  140. package/dist/jobs/computed-field-evaluation-queue-options.js.map +1 -1
  141. package/dist/jobs/database/chatter-queue-options-database.d.ts +8 -0
  142. package/dist/jobs/database/chatter-queue-options-database.d.ts.map +1 -0
  143. package/dist/jobs/database/chatter-queue-options-database.js +10 -0
  144. package/dist/jobs/database/chatter-queue-options-database.js.map +1 -0
  145. package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts +12 -0
  146. package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts.map +1 -0
  147. package/dist/jobs/database/chatter-queue-publisher-database.service.js +39 -0
  148. package/dist/jobs/database/chatter-queue-publisher-database.service.js.map +1 -0
  149. package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts +19 -0
  150. package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts.map +1 -0
  151. package/dist/jobs/database/chatter-queue-subscriber-database.service.js +62 -0
  152. package/dist/jobs/database/chatter-queue-subscriber-database.service.js.map +1 -0
  153. package/dist/repository/dashboard-layout.repository.d.ts +12 -0
  154. package/dist/repository/dashboard-layout.repository.d.ts.map +1 -0
  155. package/dist/repository/dashboard-layout.repository.js +34 -0
  156. package/dist/repository/dashboard-layout.repository.js.map +1 -0
  157. package/dist/repository/model-metadata.repository.d.ts +6 -1
  158. package/dist/repository/model-metadata.repository.d.ts.map +1 -1
  159. package/dist/repository/model-metadata.repository.js +41 -2
  160. package/dist/repository/model-metadata.repository.js.map +1 -1
  161. package/dist/seeders/module-metadata-seeder.service.js +4 -4
  162. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  163. package/dist/seeders/seed-data/solid-core-metadata.json +445 -35
  164. package/dist/services/authentication.service.d.ts.map +1 -1
  165. package/dist/services/authentication.service.js +45 -21
  166. package/dist/services/authentication.service.js.map +1 -1
  167. package/dist/services/chatter-message.service.d.ts +4 -4
  168. package/dist/services/chatter-message.service.d.ts.map +1 -1
  169. package/dist/services/chatter-message.service.js +59 -9
  170. package/dist/services/chatter-message.service.js.map +1 -1
  171. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts +7 -3
  172. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -1
  173. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +61 -22
  174. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -1
  175. package/dist/services/crud.service.js +1 -1
  176. package/dist/services/crud.service.js.map +1 -1
  177. package/dist/services/dashboard-layout.service.d.ts +20 -0
  178. package/dist/services/dashboard-layout.service.d.ts.map +1 -0
  179. package/dist/services/dashboard-layout.service.js +120 -0
  180. package/dist/services/dashboard-layout.service.js.map +1 -0
  181. package/dist/services/dashboard-question.service.d.ts +4 -0
  182. package/dist/services/dashboard-question.service.d.ts.map +1 -1
  183. package/dist/services/dashboard-question.service.js +22 -8
  184. package/dist/services/dashboard-question.service.js.map +1 -1
  185. package/dist/services/dashboard.service.d.ts +2 -0
  186. package/dist/services/dashboard.service.d.ts.map +1 -1
  187. package/dist/services/dashboard.service.js +4 -0
  188. package/dist/services/dashboard.service.js.map +1 -1
  189. package/dist/services/model-metadata.service.d.ts +3 -1
  190. package/dist/services/model-metadata.service.d.ts.map +1 -1
  191. package/dist/services/model-metadata.service.js +122 -8
  192. package/dist/services/model-metadata.service.js.map +1 -1
  193. package/dist/services/permission-metadata.service.d.ts +5 -1
  194. package/dist/services/permission-metadata.service.d.ts.map +1 -1
  195. package/dist/services/permission-metadata.service.js +66 -20
  196. package/dist/services/permission-metadata.service.js.map +1 -1
  197. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts +2 -4
  198. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts.map +1 -1
  199. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js +2 -1
  200. package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js.map +1 -1
  201. package/dist/services/question-data-providers/interfaces.d.ts +1 -0
  202. package/dist/services/question-data-providers/interfaces.d.ts.map +1 -0
  203. package/dist/services/question-data-providers/interfaces.js +1 -0
  204. package/dist/services/question-data-providers/interfaces.js.map +1 -0
  205. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts +2 -5
  206. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts.map +1 -1
  207. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js +2 -1
  208. package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js.map +1 -1
  209. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts +2 -5
  210. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts.map +1 -1
  211. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js +2 -1
  212. package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js.map +1 -1
  213. package/dist/services/queues/database-subscriber.service.d.ts +4 -2
  214. package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
  215. package/dist/services/queues/database-subscriber.service.js +15 -2
  216. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  217. package/dist/services/queues/publisher-factory.service.d.ts.map +1 -1
  218. package/dist/services/queues/publisher-factory.service.js +4 -7
  219. package/dist/services/queues/publisher-factory.service.js.map +1 -1
  220. package/dist/services/queues/rabbitmq-publisher.service.d.ts +1 -0
  221. package/dist/services/queues/rabbitmq-publisher.service.d.ts.map +1 -1
  222. package/dist/services/queues/rabbitmq-publisher.service.js +6 -1
  223. package/dist/services/queues/rabbitmq-publisher.service.js.map +1 -1
  224. package/dist/services/queues/rabbitmq-subscriber.service.d.ts +9 -3
  225. package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
  226. package/dist/services/queues/rabbitmq-subscriber.service.js +93 -10
  227. package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
  228. package/dist/services/request-context.service.d.ts +2 -1
  229. package/dist/services/request-context.service.d.ts.map +1 -1
  230. package/dist/services/request-context.service.js.map +1 -1
  231. package/dist/services/scheduled-job.service.d.ts +6 -1
  232. package/dist/services/scheduled-job.service.d.ts.map +1 -1
  233. package/dist/services/scheduled-job.service.js +26 -2
  234. package/dist/services/scheduled-job.service.js.map +1 -1
  235. package/dist/services/scheduled-jobs/scheduler.interface.d.ts +2 -0
  236. package/dist/services/scheduled-jobs/scheduler.interface.d.ts.map +1 -1
  237. package/dist/services/scheduled-jobs/scheduler.interface.js.map +1 -1
  238. package/dist/services/scheduled-jobs/scheduler.service.d.ts +6 -2
  239. package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
  240. package/dist/services/scheduled-jobs/scheduler.service.js +75 -17
  241. package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
  242. package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.d.ts.map +1 -1
  243. package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js +4 -1
  244. package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js.map +1 -1
  245. package/dist/services/solid-introspect.service.d.ts +6 -1
  246. package/dist/services/solid-introspect.service.d.ts.map +1 -1
  247. package/dist/services/solid-introspect.service.js +27 -2
  248. package/dist/services/solid-introspect.service.js.map +1 -1
  249. package/dist/services/solid-ts-morph.service.d.ts +9 -0
  250. package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
  251. package/dist/services/solid-ts-morph.service.js +76 -0
  252. package/dist/services/solid-ts-morph.service.js.map +1 -1
  253. package/dist/solid-core.module.d.ts.map +1 -1
  254. package/dist/solid-core.module.js +16 -0
  255. package/dist/solid-core.module.js.map +1 -1
  256. package/dist/subscribers/audit.subscriber.d.ts +10 -7
  257. package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
  258. package/dist/subscribers/audit.subscriber.js +58 -85
  259. package/dist/subscribers/audit.subscriber.js.map +1 -1
  260. package/dist/subscribers/computed-entity-field.subscriber.js +3 -1
  261. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  262. package/dist/subscribers/created-by-updated-by.subscriber.d.ts +0 -1
  263. package/dist/subscribers/created-by-updated-by.subscriber.d.ts.map +1 -1
  264. package/dist/subscribers/created-by-updated-by.subscriber.js +3 -13
  265. package/dist/subscribers/created-by-updated-by.subscriber.js.map +1 -1
  266. package/dist/transformers/typeorm/local-date-time-transformer.d.ts +4 -4
  267. package/dist/transformers/typeorm/local-date-time-transformer.d.ts.map +1 -1
  268. package/dist/transformers/typeorm/local-date-time-transformer.js +25 -28
  269. package/dist/transformers/typeorm/local-date-time-transformer.js.map +1 -1
  270. package/dist/winston.logger.d.ts.map +1 -1
  271. package/dist/winston.logger.js +2 -1
  272. package/dist/winston.logger.js.map +1 -1
  273. package/package.json +3 -1
  274. package/sql/default/mariadb/proc_CleanupModelMetadata.sql +153 -0
  275. package/sql/default/mariadb/proc_CleanupModuleMetadata.sql +56 -0
  276. package/sql/default/mysql/proc_CleanupModelMetadata.sql +153 -0
  277. package/sql/default/mysql/proc_CleanupModuleMetadata.sql +56 -0
  278. package/src/controllers/dashboard-layout.controller.ts +106 -0
  279. package/src/controllers/scheduled-job.controller.ts +6 -0
  280. package/src/dtos/create-dashboard-layout.dto.ts +31 -0
  281. package/src/dtos/create-dashboard-variable.dto.ts +4 -0
  282. package/src/dtos/update-dashboard-layout.dto.ts +30 -0
  283. package/src/dtos/update-dashboard-variable.dto.ts +5 -1
  284. package/src/entities/action-metadata.entity.ts +3 -2
  285. package/src/entities/ai-interaction.entity.ts +5 -4
  286. package/src/entities/chatter-message-details.entity.ts +7 -3
  287. package/src/entities/chatter-message.entity.ts +4 -3
  288. package/src/entities/common.entity.ts +2 -2
  289. package/src/entities/dashboard-layout.entity.ts +18 -0
  290. package/src/entities/dashboard-question-sql-dataset-config.entity.ts +5 -4
  291. package/src/entities/dashboard-question.entity.ts +5 -4
  292. package/src/entities/dashboard-variable.entity.ts +9 -4
  293. package/src/entities/dashboard.entity.ts +7 -2
  294. package/src/entities/email-attachment.entity.ts +2 -1
  295. package/src/entities/email-template.entity.ts +1 -1
  296. package/src/entities/export-transaction.entity.ts +2 -1
  297. package/src/entities/field-metadata.entity.ts +2 -2
  298. package/src/entities/import-transaction-error-log.entity.ts +3 -2
  299. package/src/entities/import-transaction.entity.ts +2 -1
  300. package/src/entities/legacy-common.entity.ts +3 -4
  301. package/src/entities/mq-message-queue.entity.ts +8 -8
  302. package/src/entities/mq-message.entity.ts +5 -3
  303. package/src/entities/saved-filters.entity.ts +3 -2
  304. package/src/entities/security-rule.entity.ts +2 -1
  305. package/src/entities/sms-template.entity.ts +1 -1
  306. package/src/entities/user-view-metadata.entity.ts +2 -1
  307. package/src/entities/user.entity.ts +37 -2
  308. package/src/entities/view-metadata.entity.ts +3 -0
  309. package/src/helpers/bootstrap.helper.ts +222 -0
  310. package/src/helpers/cache.helper.ts +5 -0
  311. package/src/helpers/cors.helper.ts +26 -6
  312. package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +9 -6
  313. package/src/helpers/solid-registry.ts +10 -5
  314. package/src/helpers/typeorm-db-helper.ts +26 -0
  315. package/src/index.ts +3 -0
  316. package/src/interfaces.ts +10 -1
  317. package/src/jobs/chatter-queue-options.ts +1 -1
  318. package/src/jobs/chatter-queue-publisher.service.ts +11 -11
  319. package/src/jobs/chatter-queue-subscriber.service.ts +13 -8
  320. package/src/jobs/computed-field-evaluation-queue-options.ts +2 -0
  321. package/src/jobs/database/chatter-queue-options-database.ts +9 -0
  322. package/src/jobs/database/chatter-queue-publisher-database.service.ts +24 -0
  323. package/src/jobs/database/chatter-queue-subscriber-database.service.ts +53 -0
  324. package/src/repository/dashboard-layout.repository.ts +17 -0
  325. package/src/repository/model-metadata.repository.ts +45 -2
  326. package/src/seeders/module-metadata-seeder.service.ts +5 -5
  327. package/src/seeders/seed-data/solid-core-metadata.json +446 -36
  328. package/src/services/authentication.service.ts +47 -24
  329. package/src/services/chatter-message.service.ts +67 -9
  330. package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +79 -40
  331. package/src/services/crud.service.ts +1 -1
  332. package/src/services/dashboard-layout.service.ts +111 -0
  333. package/src/services/dashboard-question.service.ts +23 -4
  334. package/src/services/dashboard.service.ts +7 -0
  335. package/src/services/model-metadata.service.ts +131 -50
  336. package/src/services/permission-metadata.service.ts +73 -20
  337. package/src/services/question-data-providers/chartjs-sql-data-provider.service.ts +3 -7
  338. package/src/services/question-data-providers/interfaces.ts +0 -0
  339. package/src/services/question-data-providers/prime-react-datatable-sql-data-provider.service.ts +4 -8
  340. package/src/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.ts +4 -8
  341. package/src/services/queues/database-subscriber.service.ts +19 -2
  342. package/src/services/queues/publisher-factory.service.ts +9 -7
  343. package/src/services/queues/rabbitmq-publisher.service.ts +8 -2
  344. package/src/services/queues/rabbitmq-subscriber.service.ts +139 -11
  345. package/src/services/request-context.service.ts +2 -1
  346. package/src/services/scheduled-job.service.ts +31 -2
  347. package/src/services/scheduled-jobs/scheduler.interface.ts +4 -1
  348. package/src/services/scheduled-jobs/scheduler.service.ts +82 -20
  349. package/src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts +4 -1
  350. package/src/services/solid-introspect.service.ts +28 -0
  351. package/src/services/solid-ts-morph.service.ts +98 -0
  352. package/src/solid-core.module.ts +21 -2
  353. package/src/subscribers/audit.subscriber.ts +63 -271
  354. package/src/subscribers/computed-entity-field.subscriber.ts +3 -3
  355. package/src/subscribers/created-by-updated-by.subscriber.ts +22 -16
  356. package/src/transformers/typeorm/local-date-time-transformer.ts +41 -33
  357. package/src/winston.logger.ts +2 -1
@@ -14,6 +14,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
14
14
  var ChatterMessageService_1;
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.ChatterMessageService = void 0;
17
+ const local_date_time_transformer_1 = require("../transformers/typeorm/local-date-time-transformer");
17
18
  const common_1 = require("@nestjs/common");
18
19
  const core_1 = require("@nestjs/core");
19
20
  const typeorm_1 = require("@nestjs/typeorm");
@@ -82,13 +83,13 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
82
83
  }
83
84
  return savedMessage;
84
85
  }
85
- async postAuditMessageOnInsert(entity, metadata, messageQueue = false) {
86
+ async postAuditMessageOnInsert(entity, modelName, messageQueue = false) {
86
87
  if (!entity) {
87
88
  return;
88
89
  }
89
90
  const model = await this.modelMetadataRepo.findOne({
90
91
  where: {
91
- singularName: (0, string_helper_1.lowerFirst)(metadata.name)
92
+ singularName: (0, string_helper_1.lowerFirst)(modelName)
92
93
  },
93
94
  relations: {
94
95
  fields: true,
@@ -126,6 +127,7 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
126
127
  messageDetail.chatterMessage = savedMessage;
127
128
  messageDetail.fieldName = field.name;
128
129
  messageDetail.fieldDisplayName = field.displayName;
130
+ messageDetail.fieldType = field.type;
129
131
  messageDetail.oldValue = null;
130
132
  messageDetail.oldValueDisplay = null;
131
133
  messageDetail.newValue = this.formatFieldValue(field, fieldValue);
@@ -134,13 +136,13 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
134
136
  }
135
137
  }
136
138
  }
137
- async postAuditMessageOnUpdate(entity, metadata, databaseEntity, updatedColumns = [], messageQueue = false) {
139
+ async postAuditMessageOnUpdate(entity, modelName, databaseEntity, updatedColumns = [], messageQueue = false) {
138
140
  if (!databaseEntity || !entity) {
139
141
  return;
140
142
  }
141
143
  const model = await this.modelMetadataRepo.findOne({
142
144
  where: {
143
- singularName: (0, string_helper_1.lowerFirst)(metadata.name)
145
+ singularName: (0, string_helper_1.lowerFirst)(modelName)
144
146
  },
145
147
  relations: {
146
148
  fields: true,
@@ -173,6 +175,7 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
173
175
  });
174
176
  const changedRelationFields = [];
175
177
  if (potentialRelationFields.length > 0) {
178
+ const metadata = this.entityManager.connection.entityMetadatas.find(m => m.name === modelName);
176
179
  const populatedOldEntity = await this.populateRelationFields(databaseEntity, potentialRelationFields, metadata);
177
180
  for (const field of potentialRelationFields) {
178
181
  const newValue = entity[field.name];
@@ -219,6 +222,7 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
219
222
  messageDetail.chatterMessage = savedMessage;
220
223
  messageDetail.fieldName = field.name;
221
224
  messageDetail.fieldDisplayName = field.displayName;
225
+ messageDetail.fieldType = field.type;
222
226
  messageDetail.oldValue = this.formatFieldValue(field, oldValue);
223
227
  messageDetail.newValue = this.formatFieldValue(field, newValue);
224
228
  messageDetail.oldValueDisplay = await this.formatFieldValueDisplay(field, oldValue);
@@ -226,13 +230,12 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
226
230
  await this.chatterMessageDetailsRepo.save(messageDetail);
227
231
  }
228
232
  }
229
- async postAuditMessageOnDelete(entity, metadata, databaseEntity, messageQueue = false) {
233
+ async postAuditMessageOnDelete(modelName, databaseEntity, messageQueue = false) {
230
234
  const model = await this.modelMetadataRepo.findOne({
231
235
  where: {
232
- singularName: (0, string_helper_1.lowerFirst)(metadata.name)
236
+ singularName: (0, string_helper_1.lowerFirst)(modelName)
233
237
  },
234
238
  relations: {
235
- fields: true,
236
239
  module: true,
237
240
  userKeyField: true
238
241
  }
@@ -240,13 +243,22 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
240
243
  if (!model || !model.enableAuditTracking) {
241
244
  return;
242
245
  }
246
+ const modelFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName);
247
+ const auditFields = modelFields.filter(field => field.enableAuditTracking &&
248
+ !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&
249
+ !(field.type === 'relation' && field.relationType === 'one-to-many'));
250
+ const relationFields = auditFields.filter(field => field.type === 'relation');
251
+ const entityMetadata = this.entityManager.connection.entityMetadatas.find(m => m.name === modelName);
252
+ const populatedEntity = relationFields.length > 0 && entityMetadata
253
+ ? await this.populateRelationFields(databaseEntity, relationFields, entityMetadata)
254
+ : { ...databaseEntity };
243
255
  const chatterMessage = new chatter_message_entity_1.ChatterMessage();
244
256
  chatterMessage.messageType = chatter_message_constants_1.CHATTER_MESSAGE_TYPE.AUDIT;
245
257
  chatterMessage.messageSubType = chatter_message_constants_1.CHATTER_MESSAGE_SUBTYPE.AUDIT_DELETE;
246
258
  chatterMessage.coModelEntityId = databaseEntity?.id;
247
259
  chatterMessage.coModelName = model?.singularName;
248
260
  chatterMessage.modelDisplayName = model?.displayName;
249
- chatterMessage.modelUserKey = entity[model?.userKeyField?.name];
261
+ chatterMessage.modelUserKey = databaseEntity[model?.userKeyField?.name];
250
262
  chatterMessage.messageBody = `${model?.displayName} deleted`;
251
263
  const activeUser = this.requestContextService.getActiveUser();
252
264
  if (activeUser) {
@@ -256,7 +268,22 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
256
268
  else {
257
269
  chatterMessage.user = null;
258
270
  }
259
- await this.repo.save(chatterMessage);
271
+ const savedMessage = await this.repo.save(chatterMessage);
272
+ for (const field of auditFields) {
273
+ const fieldValue = populatedEntity[field.name];
274
+ if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {
275
+ const messageDetail = new chatter_message_details_entity_1.ChatterMessageDetails();
276
+ messageDetail.chatterMessage = savedMessage;
277
+ messageDetail.fieldName = field.name;
278
+ messageDetail.fieldDisplayName = field.displayName;
279
+ messageDetail.fieldType = field.type;
280
+ messageDetail.oldValue = this.formatFieldValue(field, fieldValue);
281
+ messageDetail.oldValueDisplay = await this.formatFieldValueDisplay(field, fieldValue);
282
+ messageDetail.newValue = null;
283
+ messageDetail.newValueDisplay = null;
284
+ await this.chatterMessageDetailsRepo.save(messageDetail);
285
+ }
286
+ }
260
287
  }
261
288
  formatFieldValue(field, value) {
262
289
  if (value === null || value === undefined) {
@@ -273,6 +300,9 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
273
300
  return value.map(item => item.id).join(', ');
274
301
  }
275
302
  }
303
+ if (value instanceof Date) {
304
+ return (0, local_date_time_transformer_1.serializeDate)(value);
305
+ }
276
306
  return value.toString();
277
307
  }
278
308
  async formatFieldValueDisplay(field, value) {
@@ -282,6 +312,9 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
282
312
  if (field.type === 'selectionStatic' || field.type === 'selectionDynamic') {
283
313
  return `${value}`;
284
314
  }
315
+ if (['date', 'datetime', 'time'].includes(field.type)) {
316
+ return null;
317
+ }
285
318
  if (field.type === 'relation') {
286
319
  if (field.relationType === "many-to-one") {
287
320
  if (value.name) {
@@ -513,6 +546,23 @@ let ChatterMessageService = ChatterMessageService_1 = class ChatterMessageServic
513
546
  qb.skip(offset).take(limit);
514
547
  const [entities, count] = await qb.getManyAndCount();
515
548
  this.logHeapUsed('getChatterMessages-entitiesLoaded');
549
+ const DATE_FIELD_TYPES = ['date', 'datetime', 'time'];
550
+ for (const entity of entities) {
551
+ for (const detail of entity.chatterMessageDetails ?? []) {
552
+ if (!detail.fieldType || !DATE_FIELD_TYPES.includes(detail.fieldType))
553
+ continue;
554
+ if (detail.oldValue) {
555
+ const d = local_date_time_transformer_1.LocalDateTimeTransformer.from(detail.oldValue);
556
+ if (d)
557
+ detail.oldValue = d.toISOString();
558
+ }
559
+ if (detail.newValue) {
560
+ const d = local_date_time_transformer_1.LocalDateTimeTransformer.from(detail.newValue);
561
+ if (d)
562
+ detail.newValue = d.toISOString();
563
+ }
564
+ }
565
+ }
516
566
  if (populateMedia && populateMedia.length > 0) {
517
567
  const normalizedPopulateMedia = this.crudHelperService.normalize(populateMedia);
518
568
  this.logHeapUsed('getChatterMessages-beforePopulateMedia');
@@ -1 +1 @@
1
- {"version":3,"file":"chatter-message.service.js","sourceRoot":"","sources":["../../src/services/chatter-message.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAgE;AAChE,uCAAyC;AACzC,6CAAsD;AACtD,qCAAkE;AAElE,oEAAkE;AAClE,sFAAwG;AAExG,4FAAuF;AACvF,4DAAuD;AACvD,yGAAoG;AACpG,yFAAqF;AACrF,uFAAmF;AACnF,uFAAmF;AACnF,iDAAwD;AAExD,+FAAmF;AACnF,+EAAoE;AACpE,mEAAkE;AAClE,uEAAkE;AAClE,2CAAwC;AAGjC,IAAM,qBAAqB,6BAA3B,MAAM,qBAAsB,SAAQ,0BAA2B;IAGlE,YAEI,aAAqC,EAE5B,IAA8B,EAE9B,yBAA0D,EAG1D,iBAA0C,EAC1C,SAAoB,EAI7B,iBAA2D,EAClD,qBAA4C,EACpC,0BAAsD;QAEvE,KAAK,CAAC,aAAa,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;QAhB7D,kBAAa,GAAb,aAAa,CAAe;QAE5B,SAAI,GAAJ,IAAI,CAA0B;QAE9B,8BAAyB,GAAzB,yBAAyB,CAAiC;QAG1D,sBAAiB,GAAjB,iBAAiB,CAAyB;QAC1C,cAAS,GAAT,SAAS,CAAW;QAIZ,sBAAiB,GAAjB,iBAAiB,CAAyB;QAClD,0BAAqB,GAArB,qBAAqB,CAAuB;QACpC,+BAA0B,GAA1B,0BAA0B,CAA4B;QAlB1D,YAAO,GAAG,IAAI,eAAM,CAAC,uBAAqB,CAAC,IAAI,CAAC,CAAC;IAqBlE,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAA8B,EAAE,QAA+B,EAAE;QAC/E,MAAM,cAAc,GAAG,IAAI,uCAAc,EAAE,CAAC;QAC5C,cAAc,CAAC,WAAW,GAAG,gDAAoB,CAAC,MAAM,CAAC;QACzD,cAAc,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,mDAAuB,CAAC,MAAM,CAAC;QACzF,cAAc,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACjD,cAAc,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QACzD,cAAc,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QAEjD,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;QAE9D,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,UAAU,EAAE,GAAG,CAAC;YAC/B,cAAc,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAS,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE1D,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,qBAAqB,CAAC,gBAAgB,EAAE;gBAClF,MAAM,EAAE;oBACJ,KAAK,EAAE,IAAI;oBACX,oBAAoB,EAAE,IAAI;iBAC7B;gBACD,MAAM,EAAE,IAAI;aACf,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC;YAEjH,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;gBACnC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC;gBACnF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACnB,MAAM,uBAAuB,GAAG,UAAU,CAAC,oBAAoB,CAAC;oBAChE,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,IAAgC,CAAC;oBACrF,MAAM,eAAe,GAAG,MAAM,IAAA,+CAAuB,EAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;oBAC3F,MAAM,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;gBACjE,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,YAAY,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,MAAW,EAAE,QAAwB,EAAE,eAAwB,KAAK;QAC/F,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;YAC/C,KAAK,EAAE;gBACH,YAAY,EAAE,IAAA,0BAAU,EAAC,QAAQ,CAAC,IAAI,CAAC;aAC1C;YACD,SAAS,EAAE;gBACP,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,IAAI;gBACZ,YAAY,EAAE,IAAI;aACrB;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;YACvC,OAAO;QACX,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC5C,KAAK,CAAC,mBAAmB;YACzB,CAAC,CAAC,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;YAC1E,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,CAAC,CACvE,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;QAE9D,MAAM,cAAc,GAAG,IAAI,uCAAc,EAAE,CAAC;QAC5C,cAAc,CAAC,WAAW,GAAG,gDAAoB,CAAC,KAAK,CAAC;QACxD,cAAc,CAAC,cAAc,GAAG,mDAAuB,CAAC,YAAY,CAAC;QACrE,cAAc,CAAC,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC;QAC3C,cAAc,CAAC,WAAW,GAAG,KAAK,EAAE,YAAY,CAAC;QACjD,cAAc,CAAC,gBAAgB,GAAG,KAAK,EAAE,WAAW,CAAC;QACrD,cAAc,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;QAChE,cAAc,CAAC,WAAW,GAAG,OAAO,KAAK,EAAE,WAAW,UAAU,CAAC;QAEjE,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,UAAU,EAAE,GAAG,CAAC;YAC/B,cAAc,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAS,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE1D,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,EAAE,EAAE,CAAC;gBACvE,MAAM,aAAa,GAAG,IAAI,sDAAqB,EAAE,CAAC;gBAClD,aAAa,CAAC,cAAc,GAAG,YAAY,CAAC;gBAC5C,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;gBACrC,aAAa,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC;gBACnD,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC;gBAC9B,aAAa,CAAC,eAAe,GAAG,IAAI,CAAC;gBACrC,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBAClE,aAAa,CAAC,eAAe,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBACtF,MAAM,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC7D,CAAC;QACL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,MAAW,EAAE,QAAwB,EAAE,cAAmB,EAAE,iBAAwB,EAAE,EAAE,eAAwB,KAAK;QAChJ,IAAI,CAAC,cAAc,IAAI,CAAC,MAAM,EAAE,CAAC;YAC7B,OAAO;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;YAC/C,KAAK,EAAE;gBACH,YAAY,EAAE,IAAA,0BAAU,EAAC,QAAQ,CAAC,IAAI,CAAC;aAC1C;YACD,SAAS,EAAE;gBACP,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,IAAI;gBACZ,YAAY,EAAE,IAAI;aACrB;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;YACvC,OAAO;QACX,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAAC,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAEhG,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC3C,KAAK,CAAC,mBAAmB;YACzB,CAAC,CAAC,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;YAC1E,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,CAAC,CACvE,CAAC;QAEF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QAE/E,MAAM,oBAAoB,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QACpF,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAEjF,IAAI,0BAA0B,GAAG,EAAE,CAAC;QAEpC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,0BAA0B,GAAG,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC7D,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CACpC,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,0BAA0B,GAAG,oBAAoB,CAAC;QACtD,CAAC;QAED,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;QAElD,MAAM,wBAAwB,GAAG,0BAA0B,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,MAAM,qBAAqB,GAAG,EAAE,CAAC;QACjC,IAAI,uBAAuB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,uBAAuB,EAAE,QAAQ,CAAC,CAAC;YAEhH,KAAK,MAAM,KAAK,IAAI,uBAAuB,EAAE,CAAC;gBAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACpC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAEhD,IAAI,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;oBAC1D,qBAAqB,CAAC,IAAI,CAAC;wBACvB,KAAK;wBACL,QAAQ;wBACR,QAAQ;qBACX,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;QACL,CAAC;QAGD,MAAM,gBAAgB,GAAG;YACrB,GAAG,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACtC,KAAK;gBACL,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC5B,QAAQ,EAAE,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC;aACvC,CAAC,CAAC;YACH,GAAG,qBAAqB;SAC3B,CAAC;QAEF,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO;QACX,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;QAE9D,MAAM,cAAc,GAAG,IAAI,uCAAc,EAAE,CAAC;QAC5C,cAAc,CAAC,WAAW,GAAG,gDAAoB,CAAC,KAAK,CAAC;QACxD,cAAc,CAAC,cAAc,GAAG,mDAAuB,CAAC,YAAY,CAAC;QACrE,cAAc,CAAC,eAAe,GAAG,MAAM,EAAE,EAAE,CAAC;QAC5C,cAAc,CAAC,WAAW,GAAG,KAAK,EAAE,YAAY,CAAC;QACjD,cAAc,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC;QACpD,cAAc,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;QAChE,cAAc,CAAC,WAAW,GAAG,GAAG,KAAK,EAAE,WAAW,UAAU,CAAC;QAE7D,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,UAAU,EAAE,GAAG,CAAC;YAC/B,cAAc,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAS,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE1D,KAAK,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,gBAAgB,EAAE,CAAC;YAC3D,MAAM,aAAa,GAAG,IAAI,sDAAqB,EAAE,CAAC;YAClD,aAAa,CAAC,cAAc,GAAG,YAAY,CAAC;YAC5C,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;YACrC,aAAa,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC;YACnD,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAChE,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAChE,aAAa,CAAC,eAAe,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YACpF,aAAa,CAAC,eAAe,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YACpF,MAAM,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC7D,CAAC;IACL,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,MAAW,EAAE,QAAwB,EAAE,cAAmB,EAAE,eAAwB,KAAK;QACpH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;YAC/C,KAAK,EAAE;gBACH,YAAY,EAAE,IAAA,0BAAU,EAAC,QAAQ,CAAC,IAAI,CAAC;aAC1C;YACD,SAAS,EAAE;gBACP,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,IAAI;gBACZ,YAAY,EAAE,IAAI;aACrB;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;YACvC,OAAO;QACX,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,uCAAc,EAAE,CAAC;QAC5C,cAAc,CAAC,WAAW,GAAG,gDAAoB,CAAC,KAAK,CAAC;QACxD,cAAc,CAAC,cAAc,GAAG,mDAAuB,CAAC,YAAY,CAAC;QACrE,cAAc,CAAC,eAAe,GAAG,cAAc,EAAE,EAAE,CAAC;QACpD,cAAc,CAAC,WAAW,GAAG,KAAK,EAAE,YAAY,CAAC;QACjD,cAAc,CAAC,gBAAgB,GAAG,KAAK,EAAE,WAAW,CAAC;QACrD,cAAc,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;QAChE,cAAc,CAAC,WAAW,GAAG,GAAG,KAAK,EAAE,WAAW,UAAU,CAAC;QAE7D,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;QAE9D,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,UAAU,EAAE,GAAG,CAAC;YAC/B,cAAc,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAS,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC;IAEO,gBAAgB,CAAC,KAAU,EAAE,KAAU;QAC3C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACxE,OAAO,GAAG,KAAK,EAAE,CAAC;QACtB,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;gBACvC,OAAO,KAAK,CAAC,EAAE,CAAC;YACpB,CAAC;YACD,IAAI,KAAK,CAAC,YAAY,KAAK,cAAc,EAAE,CAAC;gBACxC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjD,CAAC;QACL,CAAC;QAGD,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAC,KAAU,EAAE,KAAU;QACxD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACxE,OAAO,GAAG,KAAK,EAAE,CAAC;QACtB,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;gBACvC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;oBACb,OAAO,KAAK,CAAC,IAAI,CAAC;gBACtB,CAAC;gBAED,IAAI,CAAC;oBACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;wBACtD,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,2BAA2B,IAAI,KAAK,CAAC,QAAQ,EAAE;wBAC5E,SAAS,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;qBACpC,CAAC,CAAC;oBAEH,IAAI,YAAY,IAAI,YAAY,CAAC,YAAY,EAAE,CAAC;wBAC5C,MAAM,gBAAgB,GAAG,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC;wBACxD,OAAO,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC7E,CAAC;oBAED,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;wBACX,OAAO,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;oBAC/B,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;oBAC/D,OAAO,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/C,CAAC;YACL,CAAC;YAED,IAAI,KAAK,CAAC,YAAY,KAAK,cAAc,EAAE,CAAC;gBACxC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnD,CAAC;QACL,CAAC;QAGD,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAEO,eAAe,CAAC,QAAa,EAAE,QAAa;QAChD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACzC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACnD,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,QAAQ,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACvF,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;gBACzD,OAAO,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,CAAC;YACvC,CAAC;YAED,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACrD,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACtC,OAAO,IAAI,CAAC;gBAChB,CAAC;gBACD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC5D,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC5D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC7D,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,uBAAuB,CAAC,KAAU,EAAE,QAAa,EAAE,QAAa;QACpE,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,CAAC,EAAE,CAAC;YACjG,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAC/C,OAAO,KAAK,KAAK,KAAK,CAAC;QAC3B,CAAC;QAED,IAAI,KAAK,CAAC,YAAY,KAAK,cAAc,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAEjD,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClC,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,MAAM,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,EAAE,CAAC;YAEd,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC;IAEO,iBAAiB,CAAC,KAAU;QAChC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACzD,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YACtD,OAAO,KAAK,CAAC,EAAE,CAAC;QACpB,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,kBAAkB,CAAC,KAAU;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACzC,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,CAAC;QAED,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IACrF,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAC,cAAmB,EAAE,cAAqB,EAAE,QAAwB;QACrG,MAAM,eAAe,GAAG,EAAE,GAAG,cAAc,EAAE,CAAC;QAE9C,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACjC,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEjD,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;gBACxD,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBAC5C,SAAS;YACb,CAAC;YAED,MAAM,gBAAgB,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC;YACzF,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACpB,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBAC5C,SAAS;YACb,CAAC;YAED,MAAM,YAAY,GAAG,gBAAgB,CAAC,qBAAqB,IAAI,gBAAgB,CAAC,IAAI,CAAC;YAErF,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;gBACvC,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;gBACzD,IAAI,UAAU,EAAE,CAAC;oBACb,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,YAAmB,EAAE;wBACxE,KAAK,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;qBAC5B,CAAC,CAAC;oBACH,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBAChD,CAAC;qBAAM,CAAC;oBACJ,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBAChD,CAAC;YACL,CAAC;iBAAM,IAAI,KAAK,CAAC,YAAY,KAAK,cAAc,IAAI,KAAK,CAAC,YAAY,KAAK,YAAY,EAAE,CAAC;gBACtF,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;gBAC3D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzB,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,YAAmB,EAAE,WAAW,CAAC,CAAC;oBAC7F,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACJ,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBAChD,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;YAChD,CAAC;QACL,CAAC;QAED,OAAO,eAAe,CAAC;IAC3B,CAAC;IAEO,WAAW,CAAC,KAAa;QAC7B,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;QAC1E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACtD,CAAC;IAID,KAAK,CAAC,kBAAkB,CAAC,QAAgB,EAAE,UAAkB,EAAE,KAAU;QACrE,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,CAAC,EAAE,QAAQ,GAAG,EAAE,EAAE,aAAa,GAAG,EAAE,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QACrF,IAAI,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC;QAE7C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;YAC/C,KAAK,EAAE;gBACH,YAAY,EAAE,UAAU;aAC3B;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,gCAAgC,CAAC,CAAC;QACnD,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YACtD,KAAK,EAAE;gBACH,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE;gBACvB,IAAI,EAAE,UAAU;gBAChB,YAAY,EAAE,aAAa;aAC9B;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,0CAA0C,CAAC,CAAC;QAE7D,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAoB,CAAC;QAEvD,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,mBAAmB,KAAK,KAAK,EAAE,CAAC;gBACtC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,CAAC,IAAI,mEAAmE,CAAC,CAAC;gBAClH,SAAQ;YACZ,CAAC;YACD,MAAM,WAAW,GAAG,KAAK,CAAC,2BAA2B,CAAC;YACtD,MAAM,gBAAgB,GAAG,KAAK,CAAC,wBAAwB,CAAC;YAExD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;gBACjD,KAAK,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE;aACvC,CAAC,CAAC;YAEH,IAAI,OAAO,EAAE,CAAC;gBAEV,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,IAAI,SAAS,CAAC;gBAC/C,MAAM,EAAE,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,eAAe,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;gBAEvH,MAAM,uBAAuB,GAAG,EAAE,CAAC,aAAa,CAAC,IAAA,kBAAQ,EAAC,WAAW,CAAC,CAAC,CAAC;gBAExE,MAAM,eAAe,GAAG,MAAM,uBAAuB,CAAC,IAAI,CAAC;oBACvD,MAAM,EAAE;wBACJ,EAAE,EAAE,IAAI;qBACX;oBACD,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;oBAC/C,IAAI,EAAE,CAAC;iBACV,CAAC,CAAC;gBAEH,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,MAAW,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACnE,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACnD,CAAC;QACL,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,0CAA0C,CAAC,CAAC;QAE7D,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,mCAAmC,CAAC,QAAQ,CAAC,CAAC;QACzE,IAAI,CAAC,WAAW,CAAC,sCAAsC,CAAC,CAAC;QAEzD,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,MAAM,UAAU,GAAQ,EAAE,CAAC;QAE3B,YAAY,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;QAC/F,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC;QACnC,UAAU,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAE/B,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,kBAAkB,CAAC,OAAO,EAAE,EAAE,CAAC;YACjE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;gBAC9D,IAAI,KAAK,EAAE,CAAC;oBACR,MAAM,WAAW,GAAG,KAAK,CAAC,2BAA2B,CAAC;oBACtD,MAAM,YAAY,GAAG,aAAa,UAAU,EAAE,CAAC;oBAC/C,YAAY,CAAC,IAAI,CAAC,qCAAqC,UAAU,uCAAuC,YAAY,IAAI,CAAC,CAAC;oBAC1H,UAAU,CAAC,cAAc,UAAU,EAAE,CAAC,GAAG,WAAW,CAAC;oBACrD,UAAU,CAAC,YAAY,CAAC,GAAG,UAAU,CAAC;oBACtC,UAAU,EAAE,CAAC;gBACjB,CAAC;YACL,CAAC;QACL,CAAC;QAED,EAAE,CAAC,KAAK,CAAC,IAAI,kBAAQ,CAAC,EAAE,CAAC,EAAE;YACvB,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC,CAAC;QAEJ,MAAM,SAAS,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;QACpD,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACtE,SAAS,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAClF,CAAC;QAED,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YACzB,EAAE,CAAC,iBAAiB,CAAC,UAAU,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,EAAE,CAAC;YACV,EAAE,CAAC,QAAQ,CAAC,IAAI,kBAAQ,CAAC,OAAO,CAAC,EAAE;gBAC/B,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC,CAAC;QACR,CAAC;QAED,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;QAEvC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE5B,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,eAAe,EAAE,CAAC;QACrD,IAAI,CAAC,WAAW,CAAC,mCAAmC,CAAC,CAAC;QAEtD,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,uBAAuB,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YAChF,IAAI,CAAC,WAAW,CAAC,wCAAwC,CAAC,CAAC;YAC3D,MAAM,IAAI,CAAC,qBAAqB,CAAC,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC;YACrE,IAAI,CAAC,WAAW,CAAC,uCAAuC,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACnE,MAAM,QAAQ,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE1D,OAAO;YACH,IAAI,EAAE;gBACF,YAAY,EAAE,KAAK;gBACnB,WAAW,EAAE,WAAW;gBACxB,QAAQ,EAAE,QAAQ;gBAClB,QAAQ,EAAE,QAAQ;gBAClB,UAAU,EAAE,UAAU;gBACtB,OAAO,EAAE,CAAC,KAAK;aAClB;YACD,OAAO,EAAE,QAAQ;SACpB,CAAC;IACN,CAAC;CACJ,CAAA;AA7mBY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;IAKJ,WAAA,IAAA,6BAAmB,GAAE,CAAA;IAYrB,WAAA,IAAA,eAAM,EAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,mDAAuB,CAAC,CAAC,CAAA;qCAX1B,uBAAa;QAEtB,qDAAwB;QAEH,oEAA+B;QAGvC,mDAAuB;QAC/B,gBAAS;QAIO,mDAAuB;QAC3B,+CAAqB;QACR,0DAA0B;GAnBlE,qBAAqB,CA6mBjC","sourcesContent":["import { forwardRef, Inject, Injectable } from '@nestjs/common';\nimport { ModuleRef } from \"@nestjs/core\";\nimport { InjectEntityManager } from '@nestjs/typeorm';\nimport { Brackets, EntityManager, EntityMetadata } from 'typeorm';\n\nimport { classify } from '@angular-devkit/core/src/utils/strings';\nimport { CHATTER_MESSAGE_SUBTYPE, CHATTER_MESSAGE_TYPE } from 'src/constants/chatter-message.constants';\nimport { PostChatterMessageDto } from 'src/dtos/post-chatter-message.dto';\nimport { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';\nimport { lowerFirst } from 'src/helpers/string.helper';\nimport { ChatterMessageDetailsRepository } from 'src/repository/chatter-message-details.repository';\nimport { ChatterMessageRepository } from 'src/repository/chatter-message.repository';\nimport { FieldMetadataRepository } from 'src/repository/field-metadata.repository';\nimport { ModelMetadataRepository } from 'src/repository/model-metadata.repository';\nimport { CRUDService } from 'src/services/crud.service';\nimport { MediaStorageProviderType } from '../dtos/create-media-storage-provider-metadata.dto';\nimport { ChatterMessageDetails } from '../entities/chatter-message-details.entity';\nimport { ChatterMessage } from '../entities/chatter-message.entity';\nimport { getMediaStorageProvider } from './mediaStorageProviders';\nimport { RequestContextService } from './request-context.service';\nimport { Logger } from '@nestjs/common';\n\n@Injectable()\nexport class ChatterMessageService extends CRUDService<ChatterMessage> {\n private readonly _logger = new Logger(ChatterMessageService.name);\n\n constructor(\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n // @InjectRepository(ChatterMessage, 'default')\n readonly repo: ChatterMessageRepository,\n // @InjectRepository(ChatterMessageDetailsRepository, 'default')\n readonly chatterMessageDetailsRepo: ChatterMessageDetailsRepository,\n // @InjectRepository(FieldMetadata, 'default')\n // readonly fieldMetadataRepo: Repository<FieldMetadata>,\n readonly fieldMetadataRepo: FieldMetadataRepository,\n readonly moduleRef: ModuleRef,\n // @InjectRepository(ModelMetadata)\n // private readonly modelMetadataRepo: Repository<ModelMetadata>,\n @Inject(forwardRef(() => ModelMetadataRepository))\n private readonly modelMetadataRepo: ModelMetadataRepository,\n readonly requestContextService: RequestContextService,\n private readonly modelMetadataHelperService: ModelMetadataHelperService,\n ) {\n super(entityManager, repo, 'chatterMessage', 'solid-core', moduleRef);\n }\n\n async postMessage(postDto: PostChatterMessageDto, files: Express.Multer.File[] = []) {\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.CUSTOM;\n chatterMessage.messageSubType = postDto.messageSubType || CHATTER_MESSAGE_SUBTYPE.CUSTOM;\n chatterMessage.messageBody = postDto.messageBody;\n chatterMessage.coModelEntityId = postDto.coModelEntityId;\n chatterMessage.coModelName = postDto.coModelName;\n\n const activeUser = this.requestContextService.getActiveUser();\n\n if (activeUser) {\n const userId = activeUser?.sub;\n chatterMessage.user = { id: userId } as any;\n } else {\n chatterMessage.user = null;\n }\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n if (files && files.length > 0) {\n const model = await this.modelMetadataService.findOneBySingularName('chatterMessage', {\n fields: {\n model: true,\n mediaStorageProvider: true,\n },\n module: true,\n });\n\n const mediaFields = model.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');\n\n for (const mediaField of mediaFields) {\n const media = files.filter(multerFile => multerFile.fieldname === mediaField.name);\n if (media.length > 0) {\n const storageProviderMetadata = mediaField.mediaStorageProvider;\n const storageProviderType = storageProviderMetadata.type as MediaStorageProviderType;\n const storageProvider = await getMediaStorageProvider(this.moduleRef, storageProviderType);\n await storageProvider.store(media, savedMessage, mediaField);\n }\n }\n }\n\n return savedMessage;\n }\n\n async postAuditMessageOnInsert(entity: any, metadata: EntityMetadata, messageQueue: boolean = false) {\n if (!entity) {\n return;\n }\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(metadata.name)\n },\n relations: {\n fields: true,\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const auditFields = model.fields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n const activeUser = this.requestContextService.getActiveUser();\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_INSERT;\n chatterMessage.coModelEntityId = entity.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model?.displayName;\n chatterMessage.modelUserKey = entity[model?.userKeyField?.name];\n chatterMessage.messageBody = `New ${model?.displayName} created`;\n\n if (activeUser) {\n const userId = activeUser?.sub;\n chatterMessage.user = { id: userId } as any;\n } else {\n chatterMessage.user = null;\n }\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const field of auditFields) {\n const fieldValue = entity[field.name];\n if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.oldValue = null;\n messageDetail.oldValueDisplay = null;\n messageDetail.newValue = this.formatFieldValue(field, fieldValue);\n messageDetail.newValueDisplay = await this.formatFieldValueDisplay(field, fieldValue);\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n }\n\n async postAuditMessageOnUpdate(entity: any, metadata: EntityMetadata, databaseEntity: any, updatedColumns: any[] = [], messageQueue: boolean = false) {\n if (!databaseEntity || !entity) {\n return;\n }\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(metadata.name)\n },\n relations: {\n fields: true,\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const modelFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName)\n\n const auditFields = modelFields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n const updatedFieldNames = new Set(updatedColumns.map(col => col.propertyName));\n\n const allNonRelationFields = auditFields.filter(field => field.type !== 'relation');\n const allRelationFields = auditFields.filter(field => field.type === 'relation');\n\n let potentialNonRelationFields = [];\n\n if (updatedColumns.length > 0) {\n potentialNonRelationFields = allNonRelationFields.filter(field =>\n updatedFieldNames.has(field.name)\n );\n } else {\n potentialNonRelationFields = allNonRelationFields;\n }\n\n const potentialRelationFields = allRelationFields;\n\n const changedNonRelationFields = potentialNonRelationFields.filter(field => {\n const newValue = entity[field.name];\n const oldValue = databaseEntity[field.name];\n return this.hasValueChanged(newValue, oldValue);\n });\n\n const changedRelationFields = [];\n if (potentialRelationFields.length > 0) {\n const populatedOldEntity = await this.populateRelationFields(databaseEntity, potentialRelationFields, metadata);\n\n for (const field of potentialRelationFields) {\n const newValue = entity[field.name];\n const oldValue = populatedOldEntity[field.name];\n\n if (this.hasRelationValueChanged(field, newValue, oldValue)) {\n changedRelationFields.push({\n field,\n newValue,\n oldValue\n });\n }\n }\n }\n\n\n const allChangedFields = [\n ...changedNonRelationFields.map(field => ({\n field,\n newValue: entity[field.name],\n oldValue: databaseEntity[field.name]\n })),\n ...changedRelationFields\n ];\n\n if (allChangedFields.length === 0) {\n return;\n }\n\n const activeUser = this.requestContextService.getActiveUser();\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_UPDATE;\n chatterMessage.coModelEntityId = entity?.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model.displayName;\n chatterMessage.modelUserKey = entity[model?.userKeyField?.name];\n chatterMessage.messageBody = `${model?.displayName} updated`;\n\n if (activeUser) {\n const userId = activeUser?.sub;\n chatterMessage.user = { id: userId } as any;\n } else {\n chatterMessage.user = null;\n }\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const { field, newValue, oldValue } of allChangedFields) {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.oldValue = this.formatFieldValue(field, oldValue);\n messageDetail.newValue = this.formatFieldValue(field, newValue);\n messageDetail.oldValueDisplay = await this.formatFieldValueDisplay(field, oldValue);\n messageDetail.newValueDisplay = await this.formatFieldValueDisplay(field, newValue);\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n\n async postAuditMessageOnDelete(entity: any, metadata: EntityMetadata, databaseEntity: any, messageQueue: boolean = false) {\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(metadata.name)\n },\n relations: {\n fields: true,\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_DELETE;\n chatterMessage.coModelEntityId = databaseEntity?.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model?.displayName;\n chatterMessage.modelUserKey = entity[model?.userKeyField?.name];\n chatterMessage.messageBody = `${model?.displayName} deleted`;\n\n const activeUser = this.requestContextService.getActiveUser();\n\n if (activeUser) {\n const userId = activeUser?.sub;\n chatterMessage.user = { id: userId } as any;\n } else {\n chatterMessage.user = null;\n }\n\n await this.repo.save(chatterMessage);\n }\n\n private formatFieldValue(field: any, value: any): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (field.type === 'selectionStatic' || field.type === 'selectionDynamic') {\n return `${value}`;\n }\n\n if (field.type === 'relation') {\n if (field.relationType === \"many-to-one\") {\n return value.id;\n }\n if (field.relationType === 'many-to-many') {\n return value.map(item => item.id).join(', ');\n }\n }\n\n\n return value.toString();\n }\n\n private async formatFieldValueDisplay(field: any, value: any): Promise<string> {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (field.type === 'selectionStatic' || field.type === 'selectionDynamic') {\n return `${value}`;\n }\n\n if (field.type === 'relation') {\n if (field.relationType === \"many-to-one\") {\n if (value.name) {\n return value.name;\n }\n\n try {\n const relatedModel = await this.modelMetadataRepo.findOne({\n where: { singularName: field.relationCoModelSingularName || field.relation },\n relations: { userKeyField: true }\n });\n\n if (relatedModel && relatedModel.userKeyField) {\n const userKeyFieldName = relatedModel.userKeyField.name;\n return value[userKeyFieldName] ? value[userKeyFieldName].toString() : '';\n }\n\n if (value.id) {\n return value.id.toString();\n }\n } catch (error) {\n console.error('Error fetching related model metadata:', error);\n return value.id ? value.id.toString() : '';\n }\n }\n\n if (field.relationType === 'many-to-many') {\n return value.map(item => item.name).join(', ');\n }\n }\n\n\n return value.toString();\n }\n\n private hasValueChanged(newValue: any, oldValue: any): boolean {\n if (newValue === oldValue) {\n return false;\n }\n\n if (newValue === null && oldValue === null) {\n return false;\n }\n\n if (newValue === undefined && oldValue === undefined) {\n return false;\n }\n\n if (newValue && oldValue && typeof newValue === 'object' && typeof oldValue === 'object') {\n if (newValue.id !== undefined && oldValue.id !== undefined) {\n return newValue.id !== oldValue.id;\n }\n\n if (Array.isArray(newValue) && Array.isArray(oldValue)) {\n if (newValue.length !== oldValue.length) {\n return true;\n }\n const newIds = newValue.map(item => item.id || item).sort();\n const oldIds = oldValue.map(item => item.id || item).sort();\n return JSON.stringify(newIds) !== JSON.stringify(oldIds);\n }\n }\n\n if (Array.isArray(newValue) && Array.isArray(oldValue)) {\n return JSON.stringify(newValue) !== JSON.stringify(oldValue);\n }\n\n return true;\n }\n\n private hasRelationValueChanged(field: any, newValue: any, oldValue: any): boolean {\n if (newValue === oldValue) {\n return false;\n }\n\n if ((newValue === null || newValue === undefined) && (oldValue === null || oldValue === undefined)) {\n return false;\n }\n\n if (field.relationType === 'many-to-one') {\n const newId = this.extractRelationId(newValue);\n const oldId = this.extractRelationId(oldValue);\n return newId !== oldId;\n }\n\n if (field.relationType === 'many-to-many') {\n const newIds = this.extractRelationIds(newValue);\n const oldIds = this.extractRelationIds(oldValue);\n\n if (newIds.length !== oldIds.length) {\n return true;\n }\n\n newIds.sort();\n oldIds.sort();\n\n return JSON.stringify(newIds) !== JSON.stringify(oldIds);\n }\n\n return this.hasValueChanged(newValue, oldValue);\n }\n\n private extractRelationId(value: any): any {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n return value;\n }\n\n if (typeof value === 'object' && value.id !== undefined) {\n return value.id;\n }\n\n return null;\n }\n\n private extractRelationIds(value: any): any[] {\n if (!Array.isArray(value)) {\n const id = this.extractRelationId(value);\n return id !== null ? [id] : [];\n }\n\n return value.map(item => this.extractRelationId(item)).filter(id => id !== null);\n }\n\n private async populateRelationFields(databaseEntity: any, relationFields: any[], metadata: EntityMetadata): Promise<any> {\n const populatedEntity = { ...databaseEntity };\n\n for (const field of relationFields) {\n const relationValue = databaseEntity[field.name];\n\n if (relationValue === null || relationValue === undefined) {\n populatedEntity[field.name] = relationValue;\n continue;\n }\n\n const relationMetadata = metadata.relations.find(rel => rel.propertyName === field.name);\n if (!relationMetadata) {\n populatedEntity[field.name] = relationValue;\n continue;\n }\n\n const targetEntity = relationMetadata.inverseEntityMetadata || relationMetadata.type;\n\n if (field.relationType === 'many-to-one') {\n const relationId = this.extractRelationId(relationValue);\n if (relationId) {\n const relatedEntity = await this.entityManager.findOne(targetEntity as any, {\n where: { id: relationId }\n });\n populatedEntity[field.name] = relatedEntity;\n } else {\n populatedEntity[field.name] = relationValue;\n }\n } else if (field.relationType === 'many-to-many' || field.relationType === 'manyToMany') {\n const relationIds = this.extractRelationIds(relationValue);\n if (relationIds.length > 0) {\n const relatedEntities = await this.entityManager.findByIds(targetEntity as any, relationIds);\n populatedEntity[field.name] = relatedEntities;\n } else {\n populatedEntity[field.name] = relationValue;\n }\n } else {\n populatedEntity[field.name] = relationValue;\n }\n }\n\n return populatedEntity;\n }\n\n private logHeapUsed(label: string) {\n const mb = () => Math.round(process.memoryUsage().heapUsed / 1024 / 1024);\n this._logger.log(`heapUsedMB(${label}): ${mb()}`);\n }\n\n // [2026-02-05T23:31:21.025Z] INFO: [200 OK] \n // GET /api/chatter-message/getChatterMessages/216/mswipeBoomboxBulkUpload?populateMedia[0]=messageAttachments&populate[0]=user&populate[1]=chatterMessageDetails&limit=25 22747ms\n async getChatterMessages(entityId: number, entityName: string, query: any) {\n const { limit = 25, offset = 0, populate = [], populateMedia = [], filters } = query;\n this.logHeapUsed('getChatterMessages-start');\n\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: entityName\n },\n });\n this.logHeapUsed('getChatterMessages-modelLoaded');\n const oneToManyFields = await this.fieldMetadataRepo.find({\n where: {\n model: { id: model.id },\n type: 'relation',\n relationType: 'one-to-many'\n }\n });\n this.logHeapUsed('getChatterMessages-oneToManyFieldsLoaded');\n\n const relatedEntitiesMap = new Map<string, number[]>();\n\n for (const field of oneToManyFields) {\n if (field.enableAuditTracking === false) {\n this._logger.log(`Skipping field ${field.name} for chatter message retrieval because audit tracking is disabled`);\n continue\n }\n const coModelName = field.relationCoModelSingularName;\n const coModelFieldName = field.relationCoModelFieldName;\n\n const coModel = await this.modelMetadataRepo.findOne({\n where: { singularName: coModelName }\n });\n\n if (coModel) {\n //const relatedEntityRepository = this.entityManager.getRepository(classify(coModelName));\n const dsName = coModel.dataSource || 'default';\n const em = dsName === 'default' ? this.entityManager : this.moduleRef.get(`${dsName}EntityManager`, { strict: false });\n\n const relatedEntityRepository = em.getRepository(classify(coModelName));\n\n const relatedEntities = await relatedEntityRepository.find({\n select: {\n id: true,\n },\n where: { [coModelFieldName]: { id: entityId } },\n take: 5,\n });\n\n const relatedIds = relatedEntities.map((entity: any) => entity.id);\n relatedEntitiesMap.set(field.name, relatedIds);\n }\n }\n this.logHeapUsed('getChatterMessages-relatedEntitiesLoaded');\n\n const qb = await this.repo.createSecurityRuleAwareQueryBuilder('entity');\n this.logHeapUsed('getChatterMessages-queryBuilderReady');\n\n const orConditions: string[] = [];\n const parameters: any = {};\n\n orConditions.push('(entity.coModelName = :entityName AND entity.coModelEntityId = :entityId)');\n parameters.entityName = entityName;\n parameters.entityId = entityId;\n\n let paramIndex = 0;\n for (const [fieldName, relatedIds] of relatedEntitiesMap.entries()) {\n if (relatedIds.length > 0) {\n const field = oneToManyFields.find(f => f.name === fieldName);\n if (field) {\n const coModelName = field.relationCoModelSingularName;\n const idsParamName = `relatedIds${paramIndex}`;\n orConditions.push(`(entity.coModelName = :coModelName${paramIndex} AND entity.coModelEntityId IN (:...${idsParamName}))`);\n parameters[`coModelName${paramIndex}`] = coModelName;\n parameters[idsParamName] = relatedIds;\n paramIndex++;\n }\n }\n }\n\n qb.where(new Brackets(qb => {\n qb.where(orConditions.join(' OR '), parameters);\n }));\n\n const relations = ['chatterMessageDetails', 'user'];\n if (populate && populate.length > 0) {\n const normalizedPopulate = this.crudHelperService.normalize(populate);\n relations.push(...normalizedPopulate.filter(rel => !relations.includes(rel)));\n }\n\n relations.forEach(relation => {\n qb.leftJoinAndSelect(`entity.${relation}`, relation);\n });\n\n if (filters) {\n qb.andWhere(new Brackets(whereQb => {\n this.crudHelperService.applyFilters(whereQb, filters, 'entity', qb);\n }));\n }\n\n qb.orderBy('entity.createdAt', 'DESC');\n\n qb.skip(offset).take(limit);\n\n const [entities, count] = await qb.getManyAndCount();\n this.logHeapUsed('getChatterMessages-entitiesLoaded');\n\n if (populateMedia && populateMedia.length > 0) {\n const normalizedPopulateMedia = this.crudHelperService.normalize(populateMedia);\n this.logHeapUsed('getChatterMessages-beforePopulateMedia');\n await this['handlePopulateMedia'](normalizedPopulateMedia, entities);\n this.logHeapUsed('getChatterMessages-afterPopulateMedia');\n }\n\n const currentPage = Math.floor(offset / limit) + 1;\n const totalPages = Math.ceil(count / limit);\n const nextPage = currentPage < totalPages ? currentPage + 1 : null;\n const prevPage = currentPage > 1 ? currentPage - 1 : null;\n\n return {\n meta: {\n totalRecords: count,\n currentPage: currentPage,\n nextPage: nextPage,\n prevPage: prevPage,\n totalPages: totalPages,\n perPage: +limit,\n },\n records: entities\n };\n }\n}\n"]}
1
+ {"version":3,"file":"chatter-message.service.js","sourceRoot":"","sources":["../../src/services/chatter-message.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qGAA+G;AAC/G,2CAAgE;AAChE,uCAAyC;AACzC,6CAAsD;AACtD,qCAAkE;AAElE,oEAAkE;AAClE,sFAAwG;AAExG,4FAAuF;AACvF,4DAAuD;AACvD,yGAAoG;AACpG,yFAAqF;AACrF,uFAAmF;AACnF,uFAAmF;AACnF,iDAAwD;AAExD,+FAAmF;AACnF,+EAAoE;AACpE,mEAAkE;AAClE,uEAAkE;AAClE,2CAAwC;AAGjC,IAAM,qBAAqB,6BAA3B,MAAM,qBAAsB,SAAQ,0BAA2B;IAGlE,YAEI,aAAqC,EAE5B,IAA8B,EAE9B,yBAA0D,EAG1D,iBAA0C,EAC1C,SAAoB,EAI7B,iBAA2D,EAClD,qBAA4C,EACpC,0BAAsD;QAEvE,KAAK,CAAC,aAAa,EAAE,IAAI,EAAE,gBAAgB,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;QAhB7D,kBAAa,GAAb,aAAa,CAAe;QAE5B,SAAI,GAAJ,IAAI,CAA0B;QAE9B,8BAAyB,GAAzB,yBAAyB,CAAiC;QAG1D,sBAAiB,GAAjB,iBAAiB,CAAyB;QAC1C,cAAS,GAAT,SAAS,CAAW;QAIZ,sBAAiB,GAAjB,iBAAiB,CAAyB;QAClD,0BAAqB,GAArB,qBAAqB,CAAuB;QACpC,+BAA0B,GAA1B,0BAA0B,CAA4B;QAlB1D,YAAO,GAAG,IAAI,eAAM,CAAC,uBAAqB,CAAC,IAAI,CAAC,CAAC;IAqBlE,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAA8B,EAAE,QAA+B,EAAE;QAC/E,MAAM,cAAc,GAAG,IAAI,uCAAc,EAAE,CAAC;QAC5C,cAAc,CAAC,WAAW,GAAG,gDAAoB,CAAC,MAAM,CAAC;QACzD,cAAc,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,mDAAuB,CAAC,MAAM,CAAC;QACzF,cAAc,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACjD,cAAc,CAAC,eAAe,GAAG,OAAO,CAAC,eAAe,CAAC;QACzD,cAAc,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QAEjD,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;QAE9D,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,UAAU,EAAE,GAAG,CAAC;YAC/B,cAAc,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAS,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE1D,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,qBAAqB,CAAC,gBAAgB,EAAE;gBAClF,MAAM,EAAE;oBACJ,KAAK,EAAE,IAAI;oBACX,oBAAoB,EAAE,IAAI;iBAC7B;gBACD,MAAM,EAAE,IAAI;aACf,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC;YAEjH,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;gBACnC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,KAAK,UAAU,CAAC,IAAI,CAAC,CAAC;gBACnF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACnB,MAAM,uBAAuB,GAAG,UAAU,CAAC,oBAAoB,CAAC;oBAChE,MAAM,mBAAmB,GAAG,uBAAuB,CAAC,IAAgC,CAAC;oBACrF,MAAM,eAAe,GAAG,MAAM,IAAA,+CAAuB,EAAC,IAAI,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC;oBAC3F,MAAM,eAAe,CAAC,KAAK,CAAC,KAAK,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;gBACjE,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,YAAY,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,MAAW,EAAE,SAAiB,EAAE,eAAwB,KAAK;QACxF,IAAI,CAAC,MAAM,EAAE,CAAC;YACV,OAAO;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;YAC/C,KAAK,EAAE;gBACH,YAAY,EAAE,IAAA,0BAAU,EAAC,SAAS,CAAC;aACtC;YACD,SAAS,EAAE;gBACP,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,IAAI;gBACZ,YAAY,EAAE,IAAI;aACrB;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;YACvC,OAAO;QACX,CAAC;QAED,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC5C,KAAK,CAAC,mBAAmB;YACzB,CAAC,CAAC,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;YAC1E,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,CAAC,CACvE,CAAC;QAEF,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;QAE9D,MAAM,cAAc,GAAG,IAAI,uCAAc,EAAE,CAAC;QAC5C,cAAc,CAAC,WAAW,GAAG,gDAAoB,CAAC,KAAK,CAAC;QACxD,cAAc,CAAC,cAAc,GAAG,mDAAuB,CAAC,YAAY,CAAC;QACrE,cAAc,CAAC,eAAe,GAAG,MAAM,CAAC,EAAE,CAAC;QAC3C,cAAc,CAAC,WAAW,GAAG,KAAK,EAAE,YAAY,CAAC;QACjD,cAAc,CAAC,gBAAgB,GAAG,KAAK,EAAE,WAAW,CAAC;QACrD,cAAc,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;QAChE,cAAc,CAAC,WAAW,GAAG,OAAO,KAAK,EAAE,WAAW,UAAU,CAAC;QAEjE,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,UAAU,EAAE,GAAG,CAAC;YAC/B,cAAc,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAS,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE1D,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,EAAE,EAAE,CAAC;gBACvE,MAAM,aAAa,GAAG,IAAI,sDAAqB,EAAE,CAAC;gBAClD,aAAa,CAAC,cAAc,GAAG,YAAY,CAAC;gBAC5C,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;gBACrC,aAAa,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC;gBACnD,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;gBACrC,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC;gBAC9B,aAAa,CAAC,eAAe,GAAG,IAAI,CAAC;gBACrC,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBAClE,aAAa,CAAC,eAAe,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBACtF,MAAM,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC7D,CAAC;QACL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,MAAW,EAAE,SAAiB,EAAE,cAAmB,EAAE,iBAAwB,EAAE,EAAE,eAAwB,KAAK;QACzI,IAAI,CAAC,cAAc,IAAI,CAAC,MAAM,EAAE,CAAC;YAC7B,OAAO;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;YAC/C,KAAK,EAAE;gBACH,YAAY,EAAE,IAAA,0BAAU,EAAC,SAAS,CAAC;aACtC;YACD,SAAS,EAAE;gBACP,MAAM,EAAE,IAAI;gBACZ,MAAM,EAAE,IAAI;gBACZ,YAAY,EAAE,IAAI;aACrB;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;YACvC,OAAO;QACX,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAAC,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAEhG,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC3C,KAAK,CAAC,mBAAmB;YACzB,CAAC,CAAC,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;YAC1E,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,CAAC,CACvE,CAAC;QAEF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC;QAE/E,MAAM,oBAAoB,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QACpF,MAAM,iBAAiB,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAEjF,IAAI,0BAA0B,GAAG,EAAE,CAAC;QAEpC,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,0BAA0B,GAAG,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC7D,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CACpC,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,0BAA0B,GAAG,oBAAoB,CAAC;QACtD,CAAC;QAED,MAAM,uBAAuB,GAAG,iBAAiB,CAAC;QAElD,MAAM,wBAAwB,GAAG,0BAA0B,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;YACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACpC,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5C,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,MAAM,qBAAqB,GAAG,EAAE,CAAC;QACjC,IAAI,uBAAuB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;YAC/F,MAAM,kBAAkB,GAAG,MAAM,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,uBAAuB,EAAE,QAAQ,CAAC,CAAC;YAEhH,KAAK,MAAM,KAAK,IAAI,uBAAuB,EAAE,CAAC;gBAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACpC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAEhD,IAAI,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;oBAC1D,qBAAqB,CAAC,IAAI,CAAC;wBACvB,KAAK;wBACL,QAAQ;wBACR,QAAQ;qBACX,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;QACL,CAAC;QAGD,MAAM,gBAAgB,GAAG;YACrB,GAAG,wBAAwB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACtC,KAAK;gBACL,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;gBAC5B,QAAQ,EAAE,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC;aACvC,CAAC,CAAC;YACH,GAAG,qBAAqB;SAC3B,CAAC;QAEF,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO;QACX,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;QAE9D,MAAM,cAAc,GAAG,IAAI,uCAAc,EAAE,CAAC;QAC5C,cAAc,CAAC,WAAW,GAAG,gDAAoB,CAAC,KAAK,CAAC;QACxD,cAAc,CAAC,cAAc,GAAG,mDAAuB,CAAC,YAAY,CAAC;QACrE,cAAc,CAAC,eAAe,GAAG,MAAM,EAAE,EAAE,CAAC;QAC5C,cAAc,CAAC,WAAW,GAAG,KAAK,EAAE,YAAY,CAAC;QACjD,cAAc,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC;QACpD,cAAc,CAAC,YAAY,GAAG,MAAM,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;QAChE,cAAc,CAAC,WAAW,GAAG,GAAG,KAAK,EAAE,WAAW,UAAU,CAAC;QAE7D,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,UAAU,EAAE,GAAG,CAAC;YAC/B,cAAc,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAS,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE1D,KAAK,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,gBAAgB,EAAE,CAAC;YAC3D,MAAM,aAAa,GAAG,IAAI,sDAAqB,EAAE,CAAC;YAClD,aAAa,CAAC,cAAc,GAAG,YAAY,CAAC;YAC5C,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;YACrC,aAAa,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC;YACnD,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;YACrC,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAChE,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YAChE,aAAa,CAAC,eAAe,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YACpF,aAAa,CAAC,eAAe,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;YACpF,MAAM,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC7D,CAAC;IACL,CAAC;IAED,KAAK,CAAC,wBAAwB,CAAC,SAAiB,EAAE,cAAmB,EAAE,eAAwB,KAAK;QAChG,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;YAC/C,KAAK,EAAE;gBACH,YAAY,EAAE,IAAA,0BAAU,EAAC,SAAS,CAAC;aACtC;YACD,SAAS,EAAE;gBACP,MAAM,EAAE,IAAI;gBACZ,YAAY,EAAE,IAAI;aACrB;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;YACvC,OAAO;QACX,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,0BAA0B,CAAC,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;QAEjG,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAC3C,KAAK,CAAC,mBAAmB;YACzB,CAAC,CAAC,aAAa,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC;YAC1E,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,CAAC,CACvE,CAAC;QAIF,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;QAC9E,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;QACrG,MAAM,eAAe,GAAG,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,cAAc;YAC/D,CAAC,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAAC,cAAc,EAAE,cAAc,EAAE,cAAc,CAAC;YACnF,CAAC,CAAC,EAAE,GAAG,cAAc,EAAE,CAAC;QAE5B,MAAM,cAAc,GAAG,IAAI,uCAAc,EAAE,CAAC;QAC5C,cAAc,CAAC,WAAW,GAAG,gDAAoB,CAAC,KAAK,CAAC;QACxD,cAAc,CAAC,cAAc,GAAG,mDAAuB,CAAC,YAAY,CAAC;QACrE,cAAc,CAAC,eAAe,GAAG,cAAc,EAAE,EAAE,CAAC;QACpD,cAAc,CAAC,WAAW,GAAG,KAAK,EAAE,YAAY,CAAC;QACjD,cAAc,CAAC,gBAAgB,GAAG,KAAK,EAAE,WAAW,CAAC;QACrD,cAAc,CAAC,YAAY,GAAG,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,CAAC,CAAC;QACxE,cAAc,CAAC,WAAW,GAAG,GAAG,KAAK,EAAE,WAAW,UAAU,CAAC;QAE7D,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,CAAC;QAE9D,IAAI,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,UAAU,EAAE,GAAG,CAAC;YAC/B,cAAc,CAAC,IAAI,GAAG,EAAE,EAAE,EAAE,MAAM,EAAS,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,cAAc,CAAC,IAAI,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE1D,KAAK,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/C,IAAI,UAAU,KAAK,SAAS,IAAI,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,EAAE,EAAE,CAAC;gBACvE,MAAM,aAAa,GAAG,IAAI,sDAAqB,EAAE,CAAC;gBAClD,aAAa,CAAC,cAAc,GAAG,YAAY,CAAC;gBAC5C,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;gBACrC,aAAa,CAAC,gBAAgB,GAAG,KAAK,CAAC,WAAW,CAAC;gBACnD,aAAa,CAAC,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;gBACrC,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBAClE,aAAa,CAAC,eAAe,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;gBACtF,aAAa,CAAC,QAAQ,GAAG,IAAI,CAAC;gBAC9B,aAAa,CAAC,eAAe,GAAG,IAAI,CAAC;gBACrC,MAAM,IAAI,CAAC,yBAAyB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAC7D,CAAC;QACL,CAAC;IACL,CAAC;IAEO,gBAAgB,CAAC,KAAU,EAAE,KAAU;QAC3C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACxE,OAAO,GAAG,KAAK,EAAE,CAAC;QACtB,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;gBACvC,OAAO,KAAK,CAAC,EAAE,CAAC;YACpB,CAAC;YACD,IAAI,KAAK,CAAC,YAAY,KAAK,cAAc,EAAE,CAAC;gBACxC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjD,CAAC;QACL,CAAC;QAED,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;YACxB,OAAO,IAAA,2CAAa,EAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAC,KAAU,EAAE,KAAU;QACxD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,EAAE,CAAC;QACd,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,EAAE,CAAC;YACxE,OAAO,GAAG,KAAK,EAAE,CAAC;QACtB,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;gBACvC,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;oBACb,OAAO,KAAK,CAAC,IAAI,CAAC;gBACtB,CAAC;gBAED,IAAI,CAAC;oBACD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;wBACtD,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,CAAC,2BAA2B,IAAI,KAAK,CAAC,QAAQ,EAAE;wBAC5E,SAAS,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;qBACpC,CAAC,CAAC;oBAEH,IAAI,YAAY,IAAI,YAAY,CAAC,YAAY,EAAE,CAAC;wBAC5C,MAAM,gBAAgB,GAAG,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC;wBACxD,OAAO,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC7E,CAAC;oBAED,IAAI,KAAK,CAAC,EAAE,EAAE,CAAC;wBACX,OAAO,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC;oBAC/B,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,KAAK,CAAC,CAAC;oBAC/D,OAAO,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/C,CAAC;YACL,CAAC;YAED,IAAI,KAAK,CAAC,YAAY,KAAK,cAAc,EAAE,CAAC;gBACxC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnD,CAAC;QACL,CAAC;QAGD,OAAO,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC;IAEO,eAAe,CAAC,QAAa,EAAE,QAAa;QAChD,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACzC,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACnD,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,QAAQ,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACvF,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;gBACzD,OAAO,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,EAAE,CAAC;YACvC,CAAC;YAED,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACrD,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACtC,OAAO,IAAI,CAAC;gBAChB,CAAC;gBACD,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC5D,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC5D,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC7D,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrD,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,uBAAuB,CAAC,KAAU,EAAE,QAAa,EAAE,QAAa;QACpE,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,CAAC,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,QAAQ,KAAK,SAAS,CAAC,EAAE,CAAC;YACjG,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAC/C,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YAC/C,OAAO,KAAK,KAAK,KAAK,CAAC;QAC3B,CAAC;QAED,IAAI,KAAK,CAAC,YAAY,KAAK,cAAc,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC;YAEjD,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClC,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,MAAM,CAAC,IAAI,EAAE,CAAC;YACd,MAAM,CAAC,IAAI,EAAE,CAAC;YAEd,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACpD,CAAC;IAEO,iBAAiB,CAAC,KAAU;QAChC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACzD,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YACtD,OAAO,KAAK,CAAC,EAAE,CAAC;QACpB,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAEO,kBAAkB,CAAC,KAAU;QACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,EAAE,GAAG,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACzC,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,CAAC;QAED,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IACrF,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAC,cAAmB,EAAE,cAAqB,EAAE,QAAwB;QACrG,MAAM,eAAe,GAAG,EAAE,GAAG,cAAc,EAAE,CAAC;QAE9C,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACjC,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAEjD,IAAI,aAAa,KAAK,IAAI,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;gBACxD,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBAC5C,SAAS;YACb,CAAC;YAED,MAAM,gBAAgB,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,YAAY,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC;YACzF,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACpB,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBAC5C,SAAS;YACb,CAAC;YAED,MAAM,YAAY,GAAG,gBAAgB,CAAC,qBAAqB,IAAI,gBAAgB,CAAC,IAAI,CAAC;YAErF,IAAI,KAAK,CAAC,YAAY,KAAK,aAAa,EAAE,CAAC;gBACvC,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC;gBACzD,IAAI,UAAU,EAAE,CAAC;oBACb,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,YAAmB,EAAE;wBACxE,KAAK,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;qBAC5B,CAAC,CAAC;oBACH,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBAChD,CAAC;qBAAM,CAAC;oBACJ,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBAChD,CAAC;YACL,CAAC;iBAAM,IAAI,KAAK,CAAC,YAAY,KAAK,cAAc,IAAI,KAAK,CAAC,YAAY,KAAK,YAAY,EAAE,CAAC;gBACtF,MAAM,WAAW,GAAG,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;gBAC3D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACzB,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,YAAmB,EAAE,WAAW,CAAC,CAAC;oBAC7F,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC;gBAClD,CAAC;qBAAM,CAAC;oBACJ,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBAChD,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;YAChD,CAAC;QACL,CAAC;QAED,OAAO,eAAe,CAAC;IAC3B,CAAC;IAEO,WAAW,CAAC,KAAa;QAC7B,MAAM,EAAE,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;QAC1E,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACtD,CAAC;IAID,KAAK,CAAC,kBAAkB,CAAC,QAAgB,EAAE,UAAkB,EAAE,KAAU;QACrE,MAAM,EAAE,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,CAAC,EAAE,QAAQ,GAAG,EAAE,EAAE,aAAa,GAAG,EAAE,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QACrF,IAAI,CAAC,WAAW,CAAC,0BAA0B,CAAC,CAAC;QAE7C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;YAC/C,KAAK,EAAE;gBACH,YAAY,EAAE,UAAU;aAC3B;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,gCAAgC,CAAC,CAAC;QACnD,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YACtD,KAAK,EAAE;gBACH,KAAK,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE;gBACvB,IAAI,EAAE,UAAU;gBAChB,YAAY,EAAE,aAAa;aAC9B;SACJ,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,CAAC,0CAA0C,CAAC,CAAC;QAE7D,MAAM,kBAAkB,GAAG,IAAI,GAAG,EAAoB,CAAC;QAEvD,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,mBAAmB,KAAK,KAAK,EAAE,CAAC;gBACtC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,CAAC,IAAI,mEAAmE,CAAC,CAAC;gBAClH,SAAQ;YACZ,CAAC;YACD,MAAM,WAAW,GAAG,KAAK,CAAC,2BAA2B,CAAC;YACtD,MAAM,gBAAgB,GAAG,KAAK,CAAC,wBAAwB,CAAC;YAExD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC;gBACjD,KAAK,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE;aACvC,CAAC,CAAC;YAEH,IAAI,OAAO,EAAE,CAAC;gBAEV,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,IAAI,SAAS,CAAC;gBAC/C,MAAM,EAAE,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,MAAM,eAAe,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;gBAEvH,MAAM,uBAAuB,GAAG,EAAE,CAAC,aAAa,CAAC,IAAA,kBAAQ,EAAC,WAAW,CAAC,CAAC,CAAC;gBAExE,MAAM,eAAe,GAAG,MAAM,uBAAuB,CAAC,IAAI,CAAC;oBACvD,MAAM,EAAE;wBACJ,EAAE,EAAE,IAAI;qBACX;oBACD,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE;oBAC/C,IAAI,EAAE,CAAC;iBACV,CAAC,CAAC;gBAEH,MAAM,UAAU,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,MAAW,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACnE,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACnD,CAAC;QACL,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,0CAA0C,CAAC,CAAC;QAE7D,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,mCAAmC,CAAC,QAAQ,CAAC,CAAC;QACzE,IAAI,CAAC,WAAW,CAAC,sCAAsC,CAAC,CAAC;QAEzD,MAAM,YAAY,GAAa,EAAE,CAAC;QAClC,MAAM,UAAU,GAAQ,EAAE,CAAC;QAE3B,YAAY,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;QAC/F,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC;QACnC,UAAU,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAE/B,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,KAAK,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,kBAAkB,CAAC,OAAO,EAAE,EAAE,CAAC;YACjE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC;gBAC9D,IAAI,KAAK,EAAE,CAAC;oBACR,MAAM,WAAW,GAAG,KAAK,CAAC,2BAA2B,CAAC;oBACtD,MAAM,YAAY,GAAG,aAAa,UAAU,EAAE,CAAC;oBAC/C,YAAY,CAAC,IAAI,CAAC,qCAAqC,UAAU,uCAAuC,YAAY,IAAI,CAAC,CAAC;oBAC1H,UAAU,CAAC,cAAc,UAAU,EAAE,CAAC,GAAG,WAAW,CAAC;oBACrD,UAAU,CAAC,YAAY,CAAC,GAAG,UAAU,CAAC;oBACtC,UAAU,EAAE,CAAC;gBACjB,CAAC;YACL,CAAC;QACL,CAAC;QAED,EAAE,CAAC,KAAK,CAAC,IAAI,kBAAQ,CAAC,EAAE,CAAC,EAAE;YACvB,EAAE,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC,CAAC;QAEJ,MAAM,SAAS,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC;QACpD,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,MAAM,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACtE,SAAS,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAClF,CAAC;QAED,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;YACzB,EAAE,CAAC,iBAAiB,CAAC,UAAU,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,EAAE,CAAC;YACV,EAAE,CAAC,QAAQ,CAAC,IAAI,kBAAQ,CAAC,OAAO,CAAC,EAAE;gBAC/B,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;YACxE,CAAC,CAAC,CAAC,CAAC;QACR,CAAC;QAED,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;QAEvC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE5B,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,eAAe,EAAE,CAAC;QACrD,IAAI,CAAC,WAAW,CAAC,mCAAmC,CAAC,CAAC;QAGtD,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QACtD,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;YAC5B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,qBAAqB,IAAI,EAAE,EAAE,CAAC;gBACtD,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;oBAAE,SAAS;gBAChF,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAClB,MAAM,CAAC,GAAG,sDAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACzD,IAAI,CAAC;wBAAE,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC7C,CAAC;gBACD,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;oBAClB,MAAM,CAAC,GAAG,sDAAwB,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;oBACzD,IAAI,CAAC;wBAAE,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;gBAC7C,CAAC;YACL,CAAC;QACL,CAAC;QAED,IAAI,aAAa,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,uBAAuB,GAAG,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YAChF,IAAI,CAAC,WAAW,CAAC,wCAAwC,CAAC,CAAC;YAC3D,MAAM,IAAI,CAAC,qBAAqB,CAAC,CAAC,uBAAuB,EAAE,QAAQ,CAAC,CAAC;YACrE,IAAI,CAAC,WAAW,CAAC,uCAAuC,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACnE,MAAM,QAAQ,GAAG,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE1D,OAAO;YACH,IAAI,EAAE;gBACF,YAAY,EAAE,KAAK;gBACnB,WAAW,EAAE,WAAW;gBACxB,QAAQ,EAAE,QAAQ;gBAClB,QAAQ,EAAE,QAAQ;gBAClB,UAAU,EAAE,UAAU;gBACtB,OAAO,EAAE,CAAC,KAAK;aAClB;YACD,OAAO,EAAE,QAAQ;SACpB,CAAC;IACN,CAAC;CACJ,CAAA;AAtqBY,sDAAqB;gCAArB,qBAAqB;IADjC,IAAA,mBAAU,GAAE;IAKJ,WAAA,IAAA,6BAAmB,GAAE,CAAA;IAYrB,WAAA,IAAA,eAAM,EAAC,IAAA,mBAAU,EAAC,GAAG,EAAE,CAAC,mDAAuB,CAAC,CAAC,CAAA;qCAX1B,uBAAa;QAEtB,qDAAwB;QAEH,oEAA+B;QAGvC,mDAAuB;QAC/B,gBAAS;QAIO,mDAAuB;QAC3B,+CAAqB;QACR,0DAA0B;GAnBlE,qBAAqB,CAsqBjC","sourcesContent":["import { LocalDateTimeTransformer, serializeDate } from 'src/transformers/typeorm/local-date-time-transformer';\nimport { forwardRef, Inject, Injectable } from '@nestjs/common';\nimport { ModuleRef } from \"@nestjs/core\";\nimport { InjectEntityManager } from '@nestjs/typeorm';\nimport { Brackets, EntityManager, EntityMetadata } from 'typeorm';\n\nimport { classify } from '@angular-devkit/core/src/utils/strings';\nimport { CHATTER_MESSAGE_SUBTYPE, CHATTER_MESSAGE_TYPE } from 'src/constants/chatter-message.constants';\nimport { PostChatterMessageDto } from 'src/dtos/post-chatter-message.dto';\nimport { ModelMetadataHelperService } from 'src/helpers/model-metadata-helper.service';\nimport { lowerFirst } from 'src/helpers/string.helper';\nimport { ChatterMessageDetailsRepository } from 'src/repository/chatter-message-details.repository';\nimport { ChatterMessageRepository } from 'src/repository/chatter-message.repository';\nimport { FieldMetadataRepository } from 'src/repository/field-metadata.repository';\nimport { ModelMetadataRepository } from 'src/repository/model-metadata.repository';\nimport { CRUDService } from 'src/services/crud.service';\nimport { MediaStorageProviderType } from '../dtos/create-media-storage-provider-metadata.dto';\nimport { ChatterMessageDetails } from '../entities/chatter-message-details.entity';\nimport { ChatterMessage } from '../entities/chatter-message.entity';\nimport { getMediaStorageProvider } from './mediaStorageProviders';\nimport { RequestContextService } from './request-context.service';\nimport { Logger } from '@nestjs/common';\n\n@Injectable()\nexport class ChatterMessageService extends CRUDService<ChatterMessage> {\n private readonly _logger = new Logger(ChatterMessageService.name);\n\n constructor(\n @InjectEntityManager()\n readonly entityManager: EntityManager,\n // @InjectRepository(ChatterMessage, 'default')\n readonly repo: ChatterMessageRepository,\n // @InjectRepository(ChatterMessageDetailsRepository, 'default')\n readonly chatterMessageDetailsRepo: ChatterMessageDetailsRepository,\n // @InjectRepository(FieldMetadata, 'default')\n // readonly fieldMetadataRepo: Repository<FieldMetadata>,\n readonly fieldMetadataRepo: FieldMetadataRepository,\n readonly moduleRef: ModuleRef,\n // @InjectRepository(ModelMetadata)\n // private readonly modelMetadataRepo: Repository<ModelMetadata>,\n @Inject(forwardRef(() => ModelMetadataRepository))\n private readonly modelMetadataRepo: ModelMetadataRepository,\n readonly requestContextService: RequestContextService,\n private readonly modelMetadataHelperService: ModelMetadataHelperService,\n ) {\n super(entityManager, repo, 'chatterMessage', 'solid-core', moduleRef);\n }\n\n async postMessage(postDto: PostChatterMessageDto, files: Express.Multer.File[] = []) {\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.CUSTOM;\n chatterMessage.messageSubType = postDto.messageSubType || CHATTER_MESSAGE_SUBTYPE.CUSTOM;\n chatterMessage.messageBody = postDto.messageBody;\n chatterMessage.coModelEntityId = postDto.coModelEntityId;\n chatterMessage.coModelName = postDto.coModelName;\n\n const activeUser = this.requestContextService.getActiveUser();\n\n if (activeUser) {\n const userId = activeUser?.sub;\n chatterMessage.user = { id: userId } as any;\n } else {\n chatterMessage.user = null;\n }\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n if (files && files.length > 0) {\n const model = await this.modelMetadataService.findOneBySingularName('chatterMessage', {\n fields: {\n model: true,\n mediaStorageProvider: true,\n },\n module: true,\n });\n\n const mediaFields = model.fields.filter(field => field.type === 'mediaSingle' || field.type === 'mediaMultiple');\n\n for (const mediaField of mediaFields) {\n const media = files.filter(multerFile => multerFile.fieldname === mediaField.name);\n if (media.length > 0) {\n const storageProviderMetadata = mediaField.mediaStorageProvider;\n const storageProviderType = storageProviderMetadata.type as MediaStorageProviderType;\n const storageProvider = await getMediaStorageProvider(this.moduleRef, storageProviderType);\n await storageProvider.store(media, savedMessage, mediaField);\n }\n }\n }\n\n return savedMessage;\n }\n\n async postAuditMessageOnInsert(entity: any, modelName: string, messageQueue: boolean = false) {\n if (!entity) {\n return;\n }\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(modelName)\n },\n relations: {\n fields: true,\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const auditFields = model.fields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n const activeUser = this.requestContextService.getActiveUser();\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_INSERT;\n chatterMessage.coModelEntityId = entity.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model?.displayName;\n chatterMessage.modelUserKey = entity[model?.userKeyField?.name];\n chatterMessage.messageBody = `New ${model?.displayName} created`;\n\n if (activeUser) {\n const userId = activeUser?.sub;\n chatterMessage.user = { id: userId } as any;\n } else {\n chatterMessage.user = null;\n }\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const field of auditFields) {\n const fieldValue = entity[field.name];\n if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.fieldType = field.type;\n messageDetail.oldValue = null;\n messageDetail.oldValueDisplay = null;\n messageDetail.newValue = this.formatFieldValue(field, fieldValue);\n messageDetail.newValueDisplay = await this.formatFieldValueDisplay(field, fieldValue);\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n }\n\n async postAuditMessageOnUpdate(entity: any, modelName: string, databaseEntity: any, updatedColumns: any[] = [], messageQueue: boolean = false) {\n if (!databaseEntity || !entity) {\n return;\n }\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(modelName)\n },\n relations: {\n fields: true,\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const modelFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName)\n\n const auditFields = modelFields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n const updatedFieldNames = new Set(updatedColumns.map(col => col.propertyName));\n\n const allNonRelationFields = auditFields.filter(field => field.type !== 'relation');\n const allRelationFields = auditFields.filter(field => field.type === 'relation');\n\n let potentialNonRelationFields = [];\n\n if (updatedColumns.length > 0) {\n potentialNonRelationFields = allNonRelationFields.filter(field =>\n updatedFieldNames.has(field.name)\n );\n } else {\n potentialNonRelationFields = allNonRelationFields;\n }\n\n const potentialRelationFields = allRelationFields;\n\n const changedNonRelationFields = potentialNonRelationFields.filter(field => {\n const newValue = entity[field.name];\n const oldValue = databaseEntity[field.name];\n return this.hasValueChanged(newValue, oldValue);\n });\n\n const changedRelationFields = [];\n if (potentialRelationFields.length > 0) {\n const metadata = this.entityManager.connection.entityMetadatas.find(m => m.name === modelName);\n const populatedOldEntity = await this.populateRelationFields(databaseEntity, potentialRelationFields, metadata);\n\n for (const field of potentialRelationFields) {\n const newValue = entity[field.name];\n const oldValue = populatedOldEntity[field.name];\n\n if (this.hasRelationValueChanged(field, newValue, oldValue)) {\n changedRelationFields.push({\n field,\n newValue,\n oldValue\n });\n }\n }\n }\n\n\n const allChangedFields = [\n ...changedNonRelationFields.map(field => ({\n field,\n newValue: entity[field.name],\n oldValue: databaseEntity[field.name]\n })),\n ...changedRelationFields\n ];\n\n if (allChangedFields.length === 0) {\n return;\n }\n\n const activeUser = this.requestContextService.getActiveUser();\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_UPDATE;\n chatterMessage.coModelEntityId = entity?.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model.displayName;\n chatterMessage.modelUserKey = entity[model?.userKeyField?.name];\n chatterMessage.messageBody = `${model?.displayName} updated`;\n\n if (activeUser) {\n const userId = activeUser?.sub;\n chatterMessage.user = { id: userId } as any;\n } else {\n chatterMessage.user = null;\n }\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const { field, newValue, oldValue } of allChangedFields) {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.fieldType = field.type;\n messageDetail.oldValue = this.formatFieldValue(field, oldValue);\n messageDetail.newValue = this.formatFieldValue(field, newValue);\n messageDetail.oldValueDisplay = await this.formatFieldValueDisplay(field, oldValue);\n messageDetail.newValueDisplay = await this.formatFieldValueDisplay(field, newValue);\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n\n async postAuditMessageOnDelete(modelName: string, databaseEntity: any, messageQueue: boolean = false) {\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: lowerFirst(modelName)\n },\n relations: {\n module: true,\n userKeyField: true\n }\n });\n\n if (!model || !model.enableAuditTracking) {\n return;\n }\n\n const modelFields = await this.modelMetadataHelperService.loadFieldHierarchy(model.singularName);\n\n const auditFields = modelFields.filter(field =>\n field.enableAuditTracking &&\n !['mediaSingle', 'mediaMultiple', 'richText', 'json'].includes(field.type) &&\n !(field.type === 'relation' && field.relationType === 'one-to-many')\n );\n\n // Populate relation fields so display values (e.g. names) are resolvable.\n // The related entities themselves still exist in the DB after a delete.\n const relationFields = auditFields.filter(field => field.type === 'relation');\n const entityMetadata = this.entityManager.connection.entityMetadatas.find(m => m.name === modelName);\n const populatedEntity = relationFields.length > 0 && entityMetadata\n ? await this.populateRelationFields(databaseEntity, relationFields, entityMetadata)\n : { ...databaseEntity };\n\n const chatterMessage = new ChatterMessage();\n chatterMessage.messageType = CHATTER_MESSAGE_TYPE.AUDIT;\n chatterMessage.messageSubType = CHATTER_MESSAGE_SUBTYPE.AUDIT_DELETE;\n chatterMessage.coModelEntityId = databaseEntity?.id;\n chatterMessage.coModelName = model?.singularName;\n chatterMessage.modelDisplayName = model?.displayName;\n chatterMessage.modelUserKey = databaseEntity[model?.userKeyField?.name];\n chatterMessage.messageBody = `${model?.displayName} deleted`;\n\n const activeUser = this.requestContextService.getActiveUser();\n\n if (activeUser) {\n const userId = activeUser?.sub;\n chatterMessage.user = { id: userId } as any;\n } else {\n chatterMessage.user = null;\n }\n\n const savedMessage = await this.repo.save(chatterMessage);\n\n for (const field of auditFields) {\n const fieldValue = populatedEntity[field.name];\n if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {\n const messageDetail = new ChatterMessageDetails();\n messageDetail.chatterMessage = savedMessage;\n messageDetail.fieldName = field.name;\n messageDetail.fieldDisplayName = field.displayName;\n messageDetail.fieldType = field.type;\n messageDetail.oldValue = this.formatFieldValue(field, fieldValue);\n messageDetail.oldValueDisplay = await this.formatFieldValueDisplay(field, fieldValue);\n messageDetail.newValue = null;\n messageDetail.newValueDisplay = null;\n await this.chatterMessageDetailsRepo.save(messageDetail);\n }\n }\n }\n\n private formatFieldValue(field: any, value: any): string {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (field.type === 'selectionStatic' || field.type === 'selectionDynamic') {\n return `${value}`;\n }\n\n if (field.type === 'relation') {\n if (field.relationType === \"many-to-one\") {\n return value.id;\n }\n if (field.relationType === 'many-to-many') {\n return value.map(item => item.id).join(', ');\n }\n }\n\n if (value instanceof Date) {\n return serializeDate(value);\n }\n\n return value.toString();\n }\n\n private async formatFieldValueDisplay(field: any, value: any): Promise<string> {\n if (value === null || value === undefined) {\n return '';\n }\n\n if (field.type === 'selectionStatic' || field.type === 'selectionDynamic') {\n return `${value}`;\n }\n\n if (['date', 'datetime', 'time'].includes(field.type)) {\n return null;\n }\n\n if (field.type === 'relation') {\n if (field.relationType === \"many-to-one\") {\n if (value.name) {\n return value.name;\n }\n\n try {\n const relatedModel = await this.modelMetadataRepo.findOne({\n where: { singularName: field.relationCoModelSingularName || field.relation },\n relations: { userKeyField: true }\n });\n\n if (relatedModel && relatedModel.userKeyField) {\n const userKeyFieldName = relatedModel.userKeyField.name;\n return value[userKeyFieldName] ? value[userKeyFieldName].toString() : '';\n }\n\n if (value.id) {\n return value.id.toString();\n }\n } catch (error) {\n console.error('Error fetching related model metadata:', error);\n return value.id ? value.id.toString() : '';\n }\n }\n\n if (field.relationType === 'many-to-many') {\n return value.map(item => item.name).join(', ');\n }\n }\n\n\n return value.toString();\n }\n\n private hasValueChanged(newValue: any, oldValue: any): boolean {\n if (newValue === oldValue) {\n return false;\n }\n\n if (newValue === null && oldValue === null) {\n return false;\n }\n\n if (newValue === undefined && oldValue === undefined) {\n return false;\n }\n\n if (newValue && oldValue && typeof newValue === 'object' && typeof oldValue === 'object') {\n if (newValue.id !== undefined && oldValue.id !== undefined) {\n return newValue.id !== oldValue.id;\n }\n\n if (Array.isArray(newValue) && Array.isArray(oldValue)) {\n if (newValue.length !== oldValue.length) {\n return true;\n }\n const newIds = newValue.map(item => item.id || item).sort();\n const oldIds = oldValue.map(item => item.id || item).sort();\n return JSON.stringify(newIds) !== JSON.stringify(oldIds);\n }\n }\n\n if (Array.isArray(newValue) && Array.isArray(oldValue)) {\n return JSON.stringify(newValue) !== JSON.stringify(oldValue);\n }\n\n return true;\n }\n\n private hasRelationValueChanged(field: any, newValue: any, oldValue: any): boolean {\n if (newValue === oldValue) {\n return false;\n }\n\n if ((newValue === null || newValue === undefined) && (oldValue === null || oldValue === undefined)) {\n return false;\n }\n\n if (field.relationType === 'many-to-one') {\n const newId = this.extractRelationId(newValue);\n const oldId = this.extractRelationId(oldValue);\n return newId !== oldId;\n }\n\n if (field.relationType === 'many-to-many') {\n const newIds = this.extractRelationIds(newValue);\n const oldIds = this.extractRelationIds(oldValue);\n\n if (newIds.length !== oldIds.length) {\n return true;\n }\n\n newIds.sort();\n oldIds.sort();\n\n return JSON.stringify(newIds) !== JSON.stringify(oldIds);\n }\n\n return this.hasValueChanged(newValue, oldValue);\n }\n\n private extractRelationId(value: any): any {\n if (value === null || value === undefined) {\n return null;\n }\n\n if (typeof value === 'string' || typeof value === 'number') {\n return value;\n }\n\n if (typeof value === 'object' && value.id !== undefined) {\n return value.id;\n }\n\n return null;\n }\n\n private extractRelationIds(value: any): any[] {\n if (!Array.isArray(value)) {\n const id = this.extractRelationId(value);\n return id !== null ? [id] : [];\n }\n\n return value.map(item => this.extractRelationId(item)).filter(id => id !== null);\n }\n\n private async populateRelationFields(databaseEntity: any, relationFields: any[], metadata: EntityMetadata): Promise<any> {\n const populatedEntity = { ...databaseEntity };\n\n for (const field of relationFields) {\n const relationValue = databaseEntity[field.name];\n\n if (relationValue === null || relationValue === undefined) {\n populatedEntity[field.name] = relationValue;\n continue;\n }\n\n const relationMetadata = metadata.relations.find(rel => rel.propertyName === field.name);\n if (!relationMetadata) {\n populatedEntity[field.name] = relationValue;\n continue;\n }\n\n const targetEntity = relationMetadata.inverseEntityMetadata || relationMetadata.type;\n\n if (field.relationType === 'many-to-one') {\n const relationId = this.extractRelationId(relationValue);\n if (relationId) {\n const relatedEntity = await this.entityManager.findOne(targetEntity as any, {\n where: { id: relationId }\n });\n populatedEntity[field.name] = relatedEntity;\n } else {\n populatedEntity[field.name] = relationValue;\n }\n } else if (field.relationType === 'many-to-many' || field.relationType === 'manyToMany') {\n const relationIds = this.extractRelationIds(relationValue);\n if (relationIds.length > 0) {\n const relatedEntities = await this.entityManager.findByIds(targetEntity as any, relationIds);\n populatedEntity[field.name] = relatedEntities;\n } else {\n populatedEntity[field.name] = relationValue;\n }\n } else {\n populatedEntity[field.name] = relationValue;\n }\n }\n\n return populatedEntity;\n }\n\n private logHeapUsed(label: string) {\n const mb = () => Math.round(process.memoryUsage().heapUsed / 1024 / 1024);\n this._logger.log(`heapUsedMB(${label}): ${mb()}`);\n }\n\n // [2026-02-05T23:31:21.025Z] INFO: [200 OK] \n // GET /api/chatter-message/getChatterMessages/216/mswipeBoomboxBulkUpload?populateMedia[0]=messageAttachments&populate[0]=user&populate[1]=chatterMessageDetails&limit=25 22747ms\n async getChatterMessages(entityId: number, entityName: string, query: any) {\n const { limit = 25, offset = 0, populate = [], populateMedia = [], filters } = query;\n this.logHeapUsed('getChatterMessages-start');\n\n const model = await this.modelMetadataRepo.findOne({\n where: {\n singularName: entityName\n },\n });\n this.logHeapUsed('getChatterMessages-modelLoaded');\n const oneToManyFields = await this.fieldMetadataRepo.find({\n where: {\n model: { id: model.id },\n type: 'relation',\n relationType: 'one-to-many'\n }\n });\n this.logHeapUsed('getChatterMessages-oneToManyFieldsLoaded');\n\n const relatedEntitiesMap = new Map<string, number[]>();\n\n for (const field of oneToManyFields) {\n if (field.enableAuditTracking === false) {\n this._logger.log(`Skipping field ${field.name} for chatter message retrieval because audit tracking is disabled`);\n continue\n }\n const coModelName = field.relationCoModelSingularName;\n const coModelFieldName = field.relationCoModelFieldName;\n\n const coModel = await this.modelMetadataRepo.findOne({\n where: { singularName: coModelName }\n });\n\n if (coModel) {\n //const relatedEntityRepository = this.entityManager.getRepository(classify(coModelName));\n const dsName = coModel.dataSource || 'default';\n const em = dsName === 'default' ? this.entityManager : this.moduleRef.get(`${dsName}EntityManager`, { strict: false });\n\n const relatedEntityRepository = em.getRepository(classify(coModelName));\n\n const relatedEntities = await relatedEntityRepository.find({\n select: {\n id: true,\n },\n where: { [coModelFieldName]: { id: entityId } },\n take: 5,\n });\n\n const relatedIds = relatedEntities.map((entity: any) => entity.id);\n relatedEntitiesMap.set(field.name, relatedIds);\n }\n }\n this.logHeapUsed('getChatterMessages-relatedEntitiesLoaded');\n\n const qb = await this.repo.createSecurityRuleAwareQueryBuilder('entity');\n this.logHeapUsed('getChatterMessages-queryBuilderReady');\n\n const orConditions: string[] = [];\n const parameters: any = {};\n\n orConditions.push('(entity.coModelName = :entityName AND entity.coModelEntityId = :entityId)');\n parameters.entityName = entityName;\n parameters.entityId = entityId;\n\n let paramIndex = 0;\n for (const [fieldName, relatedIds] of relatedEntitiesMap.entries()) {\n if (relatedIds.length > 0) {\n const field = oneToManyFields.find(f => f.name === fieldName);\n if (field) {\n const coModelName = field.relationCoModelSingularName;\n const idsParamName = `relatedIds${paramIndex}`;\n orConditions.push(`(entity.coModelName = :coModelName${paramIndex} AND entity.coModelEntityId IN (:...${idsParamName}))`);\n parameters[`coModelName${paramIndex}`] = coModelName;\n parameters[idsParamName] = relatedIds;\n paramIndex++;\n }\n }\n }\n\n qb.where(new Brackets(qb => {\n qb.where(orConditions.join(' OR '), parameters);\n }));\n\n const relations = ['chatterMessageDetails', 'user'];\n if (populate && populate.length > 0) {\n const normalizedPopulate = this.crudHelperService.normalize(populate);\n relations.push(...normalizedPopulate.filter(rel => !relations.includes(rel)));\n }\n\n relations.forEach(relation => {\n qb.leftJoinAndSelect(`entity.${relation}`, relation);\n });\n\n if (filters) {\n qb.andWhere(new Brackets(whereQb => {\n this.crudHelperService.applyFilters(whereQb, filters, 'entity', qb);\n }));\n }\n\n qb.orderBy('entity.createdAt', 'DESC');\n\n qb.skip(offset).take(limit);\n\n const [entities, count] = await qb.getManyAndCount();\n this.logHeapUsed('getChatterMessages-entitiesLoaded');\n\n // Convert date strings in message details to ISO format for consistent handling on the frontend\n const DATE_FIELD_TYPES = ['date', 'datetime', 'time'];\n for (const entity of entities) {\n for (const detail of entity.chatterMessageDetails ?? []) {\n if (!detail.fieldType || !DATE_FIELD_TYPES.includes(detail.fieldType)) continue;\n if (detail.oldValue) {\n const d = LocalDateTimeTransformer.from(detail.oldValue);\n if (d) detail.oldValue = d.toISOString();\n }\n if (detail.newValue) {\n const d = LocalDateTimeTransformer.from(detail.newValue);\n if (d) detail.newValue = d.toISOString();\n }\n }\n }\n\n if (populateMedia && populateMedia.length > 0) {\n const normalizedPopulateMedia = this.crudHelperService.normalize(populateMedia);\n this.logHeapUsed('getChatterMessages-beforePopulateMedia');\n await this['handlePopulateMedia'](normalizedPopulateMedia, entities);\n this.logHeapUsed('getChatterMessages-afterPopulateMedia');\n }\n\n const currentPage = Math.floor(offset / limit) + 1;\n const totalPages = Math.ceil(count / limit);\n const nextPage = currentPage < totalPages ? currentPage + 1 : null;\n const prevPage = currentPage > 1 ? currentPage - 1 : null;\n\n return {\n meta: {\n totalRecords: count,\n currentPage: currentPage,\n nextPage: nextPage,\n prevPage: prevPage,\n totalPages: totalPages,\n perPage: +limit,\n },\n records: entities\n };\n }\n}\n"]}
@@ -1,15 +1,19 @@
1
1
  import { CommonEntity } from "src/entities/common.entity";
2
2
  import { ComputedFieldMetadata } from "src/helpers/solid-registry";
3
- import { IEntityPreComputeFieldProvider } from "src/interfaces";
3
+ import { IEntityPostComputeFieldProvider } from "src/interfaces";
4
4
  import { DataSource } from "typeorm";
5
5
  export interface SequenceNumComputedFieldContext {
6
6
  sequenceName: string;
7
+ mode?: 'counter' | 'entityId';
7
8
  }
8
- export declare class SequenceNumComputedFieldProvider<T extends CommonEntity> implements IEntityPreComputeFieldProvider<T, SequenceNumComputedFieldContext> {
9
+ export declare class SequenceNumComputedFieldProvider<T extends CommonEntity> implements IEntityPostComputeFieldProvider<T, SequenceNumComputedFieldContext> {
9
10
  private readonly dataSource;
10
11
  constructor(dataSource: DataSource);
11
12
  name(): string;
12
13
  help(): string;
13
- preComputeValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<SequenceNumComputedFieldContext>): Promise<void>;
14
+ private buildSequenceString;
15
+ private generateCounterSequenceValue;
16
+ private generateEntityIdSequenceValue;
17
+ postComputeAndSaveValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<SequenceNumComputedFieldContext>): Promise<void>;
14
18
  }
15
19
  //# sourceMappingURL=sequence-num-computed-field-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sequence-num-computed-field-provider.d.ts","sourceRoot":"","sources":["../../../../src/services/computed-fields/entity/sequence-num-computed-field-provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,EAAE,UAAU,EAAgB,MAAM,SAAS,CAAC;AAGnD,MAAM,WAAW,+BAA+B;IAC5C,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,qBAEa,gCAAgC,CAAC,CAAC,SAAS,YAAY,CAAE,YAAW,8BAA8B,CAAC,CAAC,EAAE,+BAA+B,CAAC;IAG3I,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,UAAU;IAG3C,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAIR,eAAe,CAAC,aAAa,EAAE,CAAC,EAAE,qBAAqB,EAAE,qBAAqB,CAAC,+BAA+B,CAAC;CAuDxH"}
1
+ {"version":3,"file":"sequence-num-computed-field-provider.d.ts","sourceRoot":"","sources":["../../../../src/services/computed-fields/entity/sequence-num-computed-field-provider.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAE1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,+BAA+B,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,UAAU,EAAiB,MAAM,SAAS,CAAC;AAGpD,MAAM,WAAW,+BAA+B;IAC5C,YAAY,EAAE,MAAM,CAAC;IAMrB,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;CACjC;AAED,qBAEa,gCAAgC,CAAC,CAAC,SAAS,YAAY,CAAE,YAAW,+BAA+B,CAAC,CAAC,EAAE,+BAA+B,CAAC;IAG5I,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,UAAU;IAG3C,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAMd,OAAO,CAAC,mBAAmB;YAOb,4BAA4B;YAkC5B,6BAA6B;IAmBrC,uBAAuB,CAAC,aAAa,EAAE,CAAC,EAAE,qBAAqB,EAAE,qBAAqB,CAAC,+BAA+B,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;CAwBhJ"}
@@ -13,8 +13,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
13
13
  };
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.SequenceNumComputedFieldProvider = void 0;
16
+ const strings_1 = require("@angular-devkit/core/src/utils/strings");
16
17
  const common_1 = require("@nestjs/common");
17
18
  const typeorm_1 = require("@nestjs/typeorm");
19
+ const create_field_metadata_dto_1 = require("../../../dtos/create-field-metadata.dto");
18
20
  const computed_field_provider_decorator_1 = require("../../../decorators/computed-field-provider.decorator");
19
21
  const model_sequence_entity_1 = require("../../../entities/model-sequence.entity");
20
22
  const typeorm_2 = require("typeorm");
@@ -26,15 +28,19 @@ let SequenceNumComputedFieldProvider = class SequenceNumComputedFieldProvider {
26
28
  return "SequenceNumComputedFieldProvider";
27
29
  }
28
30
  help() {
29
- return "Computed field provider used to create fields whose value is based on some prefix, padding & sequence number.";
31
+ return "Computed field provider used to create fields whose value is based on some prefix, padding & sequence number. " +
32
+ "Use mode='counter' (default) to auto-increment the sequence's currentValue. " +
33
+ "Use mode='entityId' to use the entity's own id as the number (afterInsert only, does not update the counter).";
30
34
  }
31
- async preComputeValue(triggerEntity, computedFieldMetadata) {
32
- const { sequenceName } = computedFieldMetadata.computedFieldValueProviderCtxt ?? {};
33
- if (!sequenceName) {
34
- throw new Error("sequenceName is required for sequence computation");
35
- }
36
- await this.dataSource.transaction(async (manager) => {
37
- const modelSequenceRepo = manager.getRepository(model_sequence_entity_1.ModelSequence);
35
+ buildSequenceString(modelSequence, numericValue) {
36
+ const prefix = modelSequence.prefix ?? "";
37
+ const separator = modelSequence.separator ?? "";
38
+ const padded = String(numericValue).padStart(modelSequence.padding ?? 5, "0");
39
+ return `${prefix}${separator}${padded}`;
40
+ }
41
+ async generateCounterSequenceValue(sequenceName, manager) {
42
+ const run = async (mgr) => {
43
+ const modelSequenceRepo = mgr.getRepository(model_sequence_entity_1.ModelSequence);
38
44
  const modelSequence = await modelSequenceRepo.findOne({
39
45
  where: { sequenceName },
40
46
  lock: { mode: "pessimistic_write" }
@@ -43,23 +49,56 @@ let SequenceNumComputedFieldProvider = class SequenceNumComputedFieldProvider {
43
49
  throw new Error(`ModelSequence not found for ${sequenceName}`);
44
50
  }
45
51
  const nextValue = modelSequence.currentValue + 1;
46
- const paddedValue = String(nextValue).padStart(modelSequence.padding ?? 5, "0");
47
- const prefix = modelSequence.prefix ?? "";
48
- const separator = modelSequence.separator ?? "";
49
- const sequenceString = `${prefix}${separator}${paddedValue}`;
50
- const entityRepo = manager.getRepository(triggerEntity.constructor);
51
- const existing = await entityRepo.findOne({
52
- where: {
53
- [computedFieldMetadata.fieldName]: sequenceString,
54
- },
55
- });
56
- if (existing) {
57
- throw new Error(`Duplicate Sequence generated: ${sequenceString}`);
58
- }
59
- triggerEntity[computedFieldMetadata.fieldName] = sequenceString;
52
+ const sequenceString = this.buildSequenceString(modelSequence, nextValue);
60
53
  modelSequence.currentValue = nextValue;
61
54
  await modelSequenceRepo.save(modelSequence);
55
+ const modelSequenceWithModel = await modelSequenceRepo.findOne({
56
+ where: { id: modelSequence.id },
57
+ relations: { model: true },
58
+ });
59
+ const modelSingularName = modelSequenceWithModel?.model?.singularName;
60
+ if (!modelSingularName) {
61
+ throw new Error(`Model singularName not found for sequence ${sequenceName}`);
62
+ }
63
+ return { sequenceString, currentValue: nextValue, modelSingularName };
64
+ };
65
+ return manager ? run(manager) : this.dataSource.transaction(run);
66
+ }
67
+ async generateEntityIdSequenceValue(sequenceName, entityId) {
68
+ const modelSequenceRepo = this.dataSource.manager.getRepository(model_sequence_entity_1.ModelSequence);
69
+ const modelSequence = await modelSequenceRepo.findOne({
70
+ where: { sequenceName },
71
+ relations: { model: true },
62
72
  });
73
+ if (!modelSequence) {
74
+ throw new Error(`ModelSequence not found for ${sequenceName}`);
75
+ }
76
+ const modelSingularName = modelSequence.model?.singularName;
77
+ if (!modelSingularName) {
78
+ throw new Error(`Model singularName not found for sequence ${sequenceName}`);
79
+ }
80
+ return { sequenceString: this.buildSequenceString(modelSequence, entityId), modelSingularName };
81
+ }
82
+ async postComputeAndSaveValue(triggerEntity, computedFieldMetadata) {
83
+ const { sequenceName, mode = 'counter' } = computedFieldMetadata.computedFieldValueProviderCtxt ?? {};
84
+ if (!sequenceName) {
85
+ throw new Error("sequenceName is required for sequence computation");
86
+ }
87
+ let sequenceString;
88
+ let modelSingularName;
89
+ if (mode === 'entityId') {
90
+ const eventType = computedFieldMetadata.eventContext?.eventType;
91
+ if (eventType !== create_field_metadata_dto_1.ComputedFieldTriggerOperation.afterInsert) {
92
+ throw new Error(`SequenceNumComputedFieldProvider with mode='entityId' only supports "${create_field_metadata_dto_1.ComputedFieldTriggerOperation.afterInsert}" events, but received "${eventType}"`);
93
+ }
94
+ ({ sequenceString, modelSingularName } = await this.generateEntityIdSequenceValue(sequenceName, triggerEntity.id));
95
+ }
96
+ else {
97
+ ({ sequenceString, modelSingularName } = await this.generateCounterSequenceValue(sequenceName));
98
+ }
99
+ const entityName = (0, strings_1.classify)(modelSingularName);
100
+ const entityRepo = this.dataSource.manager.getRepository(entityName);
101
+ await entityRepo.update(triggerEntity.id, { [computedFieldMetadata.fieldName]: sequenceString });
63
102
  }
64
103
  };
65
104
  exports.SequenceNumComputedFieldProvider = SequenceNumComputedFieldProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"sequence-num-computed-field-provider.js","sourceRoot":"","sources":["../../../../src/services/computed-fields/entity/sequence-num-computed-field-provider.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6CAAmD;AACnD,6GAAyF;AAEzF,mFAAmE;AAGnE,qCAAmD;AAS5C,IAAM,gCAAgC,GAAtC,MAAM,gCAAgC;IACzC,YAEqB,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IACvC,CAAC;IAEL,IAAI;QACA,OAAO,kCAAkC,CAAC;IAC9C,CAAC;IAED,IAAI;QACA,OAAO,+GAA+G,CAAC;IAC3H,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,aAAgB,EAAE,qBAA6E;QACjH,MAAM,EAAE,YAAY,EAAE,GAClB,qBAAqB,CAAC,8BAA8B,IAAI,EAAE,CAAC;QAE/D,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACzE,CAAC;QAED,MAAM,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;YAKhD,MAAM,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,qCAAa,CAAC,CAAA;YAC9D,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC;gBAClD,KAAK,EAAE,EAAE,YAAY,EAAE;gBACvB,IAAI,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE;aACtC,CAAC,CAAC;YAEH,IAAI,CAAC,aAAa,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,+BAA+B,YAAY,EAAE,CAAC,CAAC;YACnE,CAAC;YAGD,MAAM,SAAS,GAAG,aAAa,CAAC,YAAY,GAAG,CAAC,CAAC;YAEjD,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;YAEhF,MAAM,MAAM,GAAG,aAAa,CAAC,MAAM,IAAI,EAAE,CAAC;YAC1C,MAAM,SAAS,GAAG,aAAa,CAAC,SAAS,IAAI,EAAE,CAAC;YAEhD,MAAM,cAAc,GAAG,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,EAAE,CAAC;YAG7D,MAAM,UAAU,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,WAAkB,CAAC,CAAC;YAE3E,MAAM,QAAQ,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC;gBACtC,KAAK,EAAE;oBACH,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,cAAc;iBACpD;aACJ,CAAC,CAAC;YAEH,IAAI,QAAQ,EAAE,CAAC;gBACX,MAAM,IAAI,KAAK,CAAC,iCAAiC,cAAc,EAAE,CAAC,CAAC;YACvE,CAAC;YAGA,aAAqB,CAAC,qBAAqB,CAAC,SAAS,CAAC,GAAG,cAAc,CAAC;YAGzE,aAAa,CAAC,YAAY,GAAG,SAAS,CAAC;YACvC,MAAM,iBAAiB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACP,CAAC;CAEJ,CAAA;AArEY,4EAAgC;2CAAhC,gCAAgC;IAF5C,IAAA,yDAAqB,GAAE;IACvB,IAAA,mBAAU,GAAE;IAGJ,WAAA,IAAA,0BAAgB,GAAE,CAAA;qCACU,oBAAU;GAHlC,gCAAgC,CAqE5C","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { InjectDataSource } from \"@nestjs/typeorm\";\nimport { ComputedFieldProvider } from \"src/decorators/computed-field-provider.decorator\";\nimport { CommonEntity } from \"src/entities/common.entity\";\nimport { ModelSequence } from \"src/entities/model-sequence.entity\";\nimport { ComputedFieldMetadata } from \"src/helpers/solid-registry\";\nimport { IEntityPreComputeFieldProvider } from \"src/interfaces\";\nimport { DataSource, EntityTarget } from \"typeorm\";\n\n\nexport interface SequenceNumComputedFieldContext {\n sequenceName: string; // The separator to use between concatenated values\n}\n\n@ComputedFieldProvider()\n@Injectable()\nexport class SequenceNumComputedFieldProvider<T extends CommonEntity> implements IEntityPreComputeFieldProvider<T, SequenceNumComputedFieldContext> {\n constructor(\n @InjectDataSource()\n private readonly dataSource: DataSource\n ) { }\n\n name(): string {\n return \"SequenceNumComputedFieldProvider\";\n }\n\n help(): string {\n return \"Computed field provider used to create fields whose value is based on some prefix, padding & sequence number.\";\n }\n\n async preComputeValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<SequenceNumComputedFieldContext>) {\n const { sequenceName } =\n computedFieldMetadata.computedFieldValueProviderCtxt ?? {};\n\n if (!sequenceName) {\n throw new Error(\"sequenceName is required for sequence computation\");\n }\n\n await this.dataSource.transaction(async (manager) => {\n /**\n * 1️⃣ Lock sequence row (prevents race conditions)\n */\n // 1️⃣ Fetch sequence row\n const modelSequenceRepo = manager.getRepository(ModelSequence)\n const modelSequence = await modelSequenceRepo.findOne({\n where: { sequenceName },\n lock: { mode: \"pessimistic_write\" }\n });\n\n if (!modelSequence) {\n throw new Error(`ModelSequence not found for ${sequenceName}`);\n }\n\n // 2️⃣ Generate next sequence value\n const nextValue = modelSequence.currentValue + 1;\n\n const paddedValue = String(nextValue).padStart(modelSequence.padding ?? 5, \"0\");\n\n const prefix = modelSequence.prefix ?? \"\";\n const separator = modelSequence.separator ?? \"\";\n\n const sequenceString = `${prefix}${separator}${paddedValue}`;\n\n // 3️⃣ Duplicate check on TARGET ENTITY (extra safety)\n const entityRepo = manager.getRepository(triggerEntity.constructor as any);\n\n const existing = await entityRepo.findOne({\n where: {\n [computedFieldMetadata.fieldName]: sequenceString,\n },\n });\n\n if (existing) {\n throw new Error(`Duplicate Sequence generated: ${sequenceString}`);\n }\n\n // 4️⃣ set the computed field on the entity\n (triggerEntity as any)[computedFieldMetadata.fieldName] = sequenceString;\n\n // 5️⃣ Persist updated sequence current value\n modelSequence.currentValue = nextValue;\n await modelSequenceRepo.save(modelSequence);\n });\n }\n\n}"]}
1
+ {"version":3,"file":"sequence-num-computed-field-provider.js","sourceRoot":"","sources":["../../../../src/services/computed-fields/entity/sequence-num-computed-field-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import { classify } from \"@angular-devkit/core/src/utils/strings\";\nimport { Injectable } from \"@nestjs/common\";\nimport { InjectDataSource } from \"@nestjs/typeorm\";\nimport { ComputedFieldTriggerOperation } from \"src/dtos/create-field-metadata.dto\";\nimport { ComputedFieldProvider } from \"src/decorators/computed-field-provider.decorator\";\nimport { CommonEntity } from \"src/entities/common.entity\";\nimport { ModelSequence } from \"src/entities/model-sequence.entity\";\nimport { ComputedFieldMetadata } from \"src/helpers/solid-registry\";\nimport { IEntityPostComputeFieldProvider } from \"src/interfaces\";\nimport { DataSource, EntityManager } from \"typeorm\";\n\n\nexport interface SequenceNumComputedFieldContext {\n sequenceName: string;\n /**\n * - `'counter'` (default): increments the sequence's `currentValue` and uses it as the number.\n * - `'entityId'`: uses the entity's own `id` as the number; does not update the counter.\n * Only valid on `afterInsert` events.\n */\n mode?: 'counter' | 'entityId';\n}\n\n@ComputedFieldProvider()\n@Injectable()\nexport class SequenceNumComputedFieldProvider<T extends CommonEntity> implements IEntityPostComputeFieldProvider<T, SequenceNumComputedFieldContext> {\n constructor(\n @InjectDataSource()\n private readonly dataSource: DataSource\n ) { }\n\n name(): string {\n return \"SequenceNumComputedFieldProvider\";\n }\n\n help(): string {\n return \"Computed field provider used to create fields whose value is based on some prefix, padding & sequence number. \" +\n \"Use mode='counter' (default) to auto-increment the sequence's currentValue. \" +\n \"Use mode='entityId' to use the entity's own id as the number (afterInsert only, does not update the counter).\";\n }\n\n private buildSequenceString(modelSequence: ModelSequence, numericValue: number): string {\n const prefix = modelSequence.prefix ?? \"\";\n const separator = modelSequence.separator ?? \"\";\n const padded = String(numericValue).padStart(modelSequence.padding ?? 5, \"0\");\n return `${prefix}${separator}${padded}`;\n }\n\n private async generateCounterSequenceValue(sequenceName: string, manager?: EntityManager): Promise<{ sequenceString: string; currentValue: number; modelSingularName: string }> {\n const run = async (mgr: EntityManager) => {\n const modelSequenceRepo = mgr.getRepository(ModelSequence);\n const modelSequence = await modelSequenceRepo.findOne({\n where: { sequenceName },\n lock: { mode: \"pessimistic_write\" }\n });\n\n if (!modelSequence) {\n throw new Error(`ModelSequence not found for ${sequenceName}`);\n }\n\n const nextValue = modelSequence.currentValue + 1;\n const sequenceString = this.buildSequenceString(modelSequence, nextValue);\n\n modelSequence.currentValue = nextValue;\n await modelSequenceRepo.save(modelSequence);\n\n // Load model relation in a separate query to avoid FOR UPDATE on joined relation.\n const modelSequenceWithModel = await modelSequenceRepo.findOne({\n where: { id: modelSequence.id },\n relations: { model: true },\n });\n const modelSingularName = modelSequenceWithModel?.model?.singularName;\n if (!modelSingularName) {\n throw new Error(`Model singularName not found for sequence ${sequenceName}`);\n }\n\n return { sequenceString, currentValue: nextValue, modelSingularName };\n };\n\n return manager ? run(manager) : this.dataSource.transaction(run);\n }\n\n private async generateEntityIdSequenceValue(sequenceName: string, entityId: number): Promise<{ sequenceString: string; modelSingularName: string }> {\n const modelSequenceRepo = this.dataSource.manager.getRepository(ModelSequence);\n const modelSequence = await modelSequenceRepo.findOne({\n where: { sequenceName },\n relations: { model: true },\n });\n\n if (!modelSequence) {\n throw new Error(`ModelSequence not found for ${sequenceName}`);\n }\n\n const modelSingularName = modelSequence.model?.singularName;\n if (!modelSingularName) {\n throw new Error(`Model singularName not found for sequence ${sequenceName}`);\n }\n\n return { sequenceString: this.buildSequenceString(modelSequence, entityId), modelSingularName };\n }\n\n async postComputeAndSaveValue(triggerEntity: T, computedFieldMetadata: ComputedFieldMetadata<SequenceNumComputedFieldContext>): Promise<void> {\n const { sequenceName, mode = 'counter' } = computedFieldMetadata.computedFieldValueProviderCtxt ?? {};\n\n if (!sequenceName) {\n throw new Error(\"sequenceName is required for sequence computation\");\n }\n\n let sequenceString: string;\n let modelSingularName: string;\n\n if (mode === 'entityId') {\n const eventType = computedFieldMetadata.eventContext?.eventType;\n if (eventType !== ComputedFieldTriggerOperation.afterInsert) {\n throw new Error(`SequenceNumComputedFieldProvider with mode='entityId' only supports \"${ComputedFieldTriggerOperation.afterInsert}\" events, but received \"${eventType}\"`);\n }\n ({ sequenceString, modelSingularName } = await this.generateEntityIdSequenceValue(sequenceName, triggerEntity.id));\n } else {\n ({ sequenceString, modelSingularName } = await this.generateCounterSequenceValue(sequenceName));\n }\n\n const entityName = classify(modelSingularName);\n const entityRepo = this.dataSource.manager.getRepository(entityName);\n await entityRepo.update(triggerEntity.id, { [computedFieldMetadata.fieldName]: sequenceString });\n }\n}\n"]}
@@ -326,7 +326,7 @@ class CRUDService {
326
326
  return new SelectionStaticFieldCrudManager_1.SelectionStaticFieldCrudManager(options);
327
327
  }
328
328
  case create_field_metadata_dto_1.SolidFieldType.selectionDynamic: {
329
- const options = { ...commonOptions, selectionDynamicProvider: fieldMetadata.selectionDynamicProvider, selectionDynamicProviderCtxt: fieldMetadata.selectionDynamicProviderCtxt, selectionValueType: fieldMetadata.selectionValueType, discoveryService: this.discoveryService, isMultiSelect: fieldMetadata.isMultiSelect };
329
+ const options = { ...commonOptions, selectionDynamicProvider: fieldMetadata.selectionDynamicProvider, selectionDynamicProviderCtxt: JSON.parse(fieldMetadata.selectionDynamicProviderCtxt), selectionValueType: fieldMetadata.selectionValueType, discoveryService: this.discoveryService, isMultiSelect: fieldMetadata.isMultiSelect };
330
330
  return new SelectionDynamicFieldCrudManager_1.SelectionDynamicFieldCrudManager(options);
331
331
  }
332
332
  case create_field_metadata_dto_1.SolidFieldType.uuid: {