@solidstarters/solid-core 1.2.200 → 1.2.201

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 (371) hide show
  1. package/dist/commands/fixtures/fixtures-setup.command.d.ts +15 -0
  2. package/dist/commands/fixtures/fixtures-setup.command.d.ts.map +1 -0
  3. package/dist/commands/fixtures/fixtures-setup.command.js +58 -0
  4. package/dist/commands/fixtures/fixtures-setup.command.js.map +1 -0
  5. package/dist/commands/fixtures/fixtures-tear-down.command.d.ts +16 -0
  6. package/dist/commands/fixtures/fixtures-tear-down.command.d.ts.map +1 -0
  7. package/dist/commands/fixtures/fixtures-tear-down.command.js +59 -0
  8. package/dist/commands/fixtures/fixtures-tear-down.command.js.map +1 -0
  9. package/dist/commands/refresh-model.command.d.ts.map +1 -1
  10. package/dist/commands/refresh-model.command.js +4 -0
  11. package/dist/commands/refresh-model.command.js.map +1 -1
  12. package/dist/constants/error-messages.d.ts +2 -0
  13. package/dist/constants/error-messages.d.ts.map +1 -1
  14. package/dist/constants/error-messages.js +4 -0
  15. package/dist/constants/error-messages.js.map +1 -1
  16. package/dist/controllers/model-sequence.controller.d.ts +43 -0
  17. package/dist/controllers/model-sequence.controller.d.ts.map +1 -0
  18. package/dist/controllers/model-sequence.controller.js +179 -0
  19. package/dist/controllers/model-sequence.controller.js.map +1 -0
  20. package/dist/controllers/setting.controller.d.ts +1 -0
  21. package/dist/controllers/setting.controller.d.ts.map +1 -1
  22. package/dist/controllers/setting.controller.js +15 -0
  23. package/dist/controllers/setting.controller.js.map +1 -1
  24. package/dist/dtos/basic-filters.dto.d.ts +3 -1
  25. package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
  26. package/dist/dtos/basic-filters.dto.js +8 -2
  27. package/dist/dtos/basic-filters.dto.js.map +1 -1
  28. package/dist/dtos/basic-group-filters.dto.d.ts +6 -0
  29. package/dist/dtos/basic-group-filters.dto.d.ts.map +1 -0
  30. package/dist/dtos/basic-group-filters.dto.js +46 -0
  31. package/dist/dtos/basic-group-filters.dto.js.map +1 -0
  32. package/dist/dtos/create-field-metadata.dto.js +2 -2
  33. package/dist/dtos/create-field-metadata.dto.js.map +1 -1
  34. package/dist/dtos/create-model-sequence.dto.d.ts +14 -0
  35. package/dist/dtos/create-model-sequence.dto.d.ts.map +1 -0
  36. package/dist/dtos/create-model-sequence.dto.js +90 -0
  37. package/dist/dtos/create-model-sequence.dto.js.map +1 -0
  38. package/dist/dtos/create-role-metadata.dto.d.ts.map +1 -1
  39. package/dist/dtos/create-role-metadata.dto.js +1 -0
  40. package/dist/dtos/create-role-metadata.dto.js.map +1 -1
  41. package/dist/dtos/get-mcp-url.dto.d.ts +5 -0
  42. package/dist/dtos/get-mcp-url.dto.d.ts.map +1 -0
  43. package/dist/dtos/get-mcp-url.dto.js +31 -0
  44. package/dist/dtos/get-mcp-url.dto.js.map +1 -0
  45. package/dist/dtos/resolve-s3-url.dto.d.ts +5 -5
  46. package/dist/dtos/resolve-s3-url.dto.d.ts.map +1 -1
  47. package/dist/dtos/resolve-s3-url.dto.js +7 -7
  48. package/dist/dtos/resolve-s3-url.dto.js.map +1 -1
  49. package/dist/dtos/update-model-sequence.dto.d.ts +15 -0
  50. package/dist/dtos/update-model-sequence.dto.d.ts.map +1 -0
  51. package/dist/dtos/update-model-sequence.dto.js +94 -0
  52. package/dist/dtos/update-model-sequence.dto.js.map +1 -0
  53. package/dist/entities/common.entity.d.ts.map +1 -1
  54. package/dist/entities/common.entity.js +1 -0
  55. package/dist/entities/common.entity.js.map +1 -1
  56. package/dist/entities/legacy-common.entity.d.ts.map +1 -1
  57. package/dist/entities/legacy-common.entity.js +1 -0
  58. package/dist/entities/legacy-common.entity.js.map +1 -1
  59. package/dist/entities/model-sequence.entity.d.ts +15 -0
  60. package/dist/entities/model-sequence.entity.d.ts.map +1 -0
  61. package/dist/entities/model-sequence.entity.js +67 -0
  62. package/dist/entities/model-sequence.entity.js.map +1 -0
  63. package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.d.ts.map +1 -1
  64. package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.js +13 -2
  65. package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.js.map +1 -1
  66. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.d.ts +0 -1
  67. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.d.ts.map +1 -1
  68. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.js +4 -9
  69. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.js.map +1 -1
  70. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.d.ts +0 -1
  71. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.d.ts.map +1 -1
  72. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.js +7 -8
  73. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.js.map +1 -1
  74. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.d.ts +0 -1
  75. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.d.ts.map +1 -1
  76. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.js +4 -9
  77. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.js.map +1 -1
  78. package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -1
  79. package/dist/helpers/model-metadata-helper.service.js +6 -2
  80. package/dist/helpers/model-metadata-helper.service.js.map +1 -1
  81. package/dist/helpers/module-metadata-helper.service.d.ts +1 -0
  82. package/dist/helpers/module-metadata-helper.service.d.ts.map +1 -1
  83. package/dist/helpers/module-metadata-helper.service.js +9 -0
  84. package/dist/helpers/module-metadata-helper.service.js.map +1 -1
  85. package/dist/helpers/module.helper.d.ts +1 -0
  86. package/dist/helpers/module.helper.d.ts.map +1 -1
  87. package/dist/helpers/module.helper.js +29 -3
  88. package/dist/helpers/module.helper.js.map +1 -1
  89. package/dist/helpers/solid-registry.d.ts +11 -0
  90. package/dist/helpers/solid-registry.d.ts.map +1 -1
  91. package/dist/helpers/solid-registry.js.map +1 -1
  92. package/dist/index.d.ts +3 -1
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +4 -2
  95. package/dist/index.js.map +1 -1
  96. package/dist/jobs/computed-field-evaluation-subscriber.service.d.ts +1 -0
  97. package/dist/jobs/computed-field-evaluation-subscriber.service.d.ts.map +1 -1
  98. package/dist/jobs/computed-field-evaluation-subscriber.service.js +16 -4
  99. package/dist/jobs/computed-field-evaluation-subscriber.service.js.map +1 -1
  100. package/dist/repository/media.repository.d.ts.map +1 -1
  101. package/dist/repository/media.repository.js +4 -0
  102. package/dist/repository/media.repository.js.map +1 -1
  103. package/dist/repository/model-sequence.repository.d.ts +14 -0
  104. package/dist/repository/model-sequence.repository.d.ts.map +1 -0
  105. package/dist/repository/model-sequence.repository.js +103 -0
  106. package/dist/repository/model-sequence.repository.js.map +1 -0
  107. package/dist/seeders/module-metadata-seeder.service.d.ts +7 -12
  108. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  109. package/dist/seeders/module-metadata-seeder.service.js +64 -26
  110. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  111. package/dist/seeders/seed-data/solid-core-metadata.json +343 -27
  112. package/dist/seeders/system-fields-seeder.service.d.ts +1 -0
  113. package/dist/seeders/system-fields-seeder.service.d.ts.map +1 -1
  114. package/dist/seeders/system-fields-seeder.service.js +11 -2
  115. package/dist/seeders/system-fields-seeder.service.js.map +1 -1
  116. package/dist/services/action-metadata.service.d.ts.map +1 -1
  117. package/dist/services/action-metadata.service.js +1 -0
  118. package/dist/services/action-metadata.service.js.map +1 -1
  119. package/dist/services/ai-interaction.service.d.ts.map +1 -1
  120. package/dist/services/ai-interaction.service.js +1 -0
  121. package/dist/services/ai-interaction.service.js.map +1 -1
  122. package/dist/services/authentication.service.d.ts.map +1 -1
  123. package/dist/services/authentication.service.js +22 -14
  124. package/dist/services/authentication.service.js.map +1 -1
  125. package/dist/services/chatter-message-details.service.d.ts.map +1 -1
  126. package/dist/services/chatter-message-details.service.js +1 -0
  127. package/dist/services/chatter-message-details.service.js.map +1 -1
  128. package/dist/services/chatter-message.service.d.ts.map +1 -1
  129. package/dist/services/chatter-message.service.js +7 -3
  130. package/dist/services/chatter-message.service.js.map +1 -1
  131. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.d.ts.map +1 -1
  132. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js +7 -5
  133. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js.map +1 -1
  134. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts +15 -0
  135. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -0
  136. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +72 -0
  137. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -0
  138. package/dist/services/crud-helper.service.d.ts +23 -6
  139. package/dist/services/crud-helper.service.d.ts.map +1 -1
  140. package/dist/services/crud-helper.service.js +257 -45
  141. package/dist/services/crud-helper.service.js.map +1 -1
  142. package/dist/services/crud.service.d.ts +3 -1
  143. package/dist/services/crud.service.d.ts.map +1 -1
  144. package/dist/services/crud.service.js +53 -24
  145. package/dist/services/crud.service.js.map +1 -1
  146. package/dist/services/database/database-bootstrap.service.d.ts +12 -0
  147. package/dist/services/database/database-bootstrap.service.d.ts.map +1 -0
  148. package/dist/services/database/database-bootstrap.service.js +115 -0
  149. package/dist/services/database/database-bootstrap.service.js.map +1 -0
  150. package/dist/services/email-template.service.d.ts +7 -7
  151. package/dist/services/email-template.service.d.ts.map +1 -1
  152. package/dist/services/email-template.service.js +8 -7
  153. package/dist/services/email-template.service.js.map +1 -1
  154. package/dist/services/excel.service.d.ts +10 -0
  155. package/dist/services/excel.service.d.ts.map +1 -1
  156. package/dist/services/excel.service.js +100 -0
  157. package/dist/services/excel.service.js.map +1 -1
  158. package/dist/services/field-metadata.service.d.ts +4 -1
  159. package/dist/services/field-metadata.service.d.ts.map +1 -1
  160. package/dist/services/field-metadata.service.js +35 -30
  161. package/dist/services/field-metadata.service.js.map +1 -1
  162. package/dist/services/file.service.d.ts +1 -0
  163. package/dist/services/file.service.d.ts.map +1 -1
  164. package/dist/services/file.service.js +9 -0
  165. package/dist/services/file.service.js.map +1 -1
  166. package/dist/services/fixtures.service.d.ts +13 -0
  167. package/dist/services/fixtures.service.d.ts.map +1 -0
  168. package/dist/services/fixtures.service.js +95 -0
  169. package/dist/services/fixtures.service.js.map +1 -0
  170. package/dist/services/genai/ingest-metadata.service.d.ts.map +1 -1
  171. package/dist/services/genai/ingest-metadata.service.js +1 -1
  172. package/dist/services/genai/ingest-metadata.service.js.map +1 -1
  173. package/dist/services/import-transaction-error-log.service.d.ts.map +1 -1
  174. package/dist/services/import-transaction-error-log.service.js +1 -0
  175. package/dist/services/import-transaction-error-log.service.js.map +1 -1
  176. package/dist/services/import-transaction.service.d.ts.map +1 -1
  177. package/dist/services/import-transaction.service.js +7 -1
  178. package/dist/services/import-transaction.service.js.map +1 -1
  179. package/dist/services/list-of-values.service.d.ts +2 -2
  180. package/dist/services/list-of-values.service.d.ts.map +1 -1
  181. package/dist/services/list-of-values.service.js +2 -1
  182. package/dist/services/list-of-values.service.js.map +1 -1
  183. package/dist/services/locale.service.d.ts.map +1 -1
  184. package/dist/services/locale.service.js +1 -0
  185. package/dist/services/locale.service.js.map +1 -1
  186. package/dist/services/mail/smtp-email.service.js +0 -1
  187. package/dist/services/mail/smtp-email.service.js.map +1 -1
  188. package/dist/services/media.service.d.ts +3 -3
  189. package/dist/services/media.service.d.ts.map +1 -1
  190. package/dist/services/media.service.js +6 -4
  191. package/dist/services/media.service.js.map +1 -1
  192. package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts.map +1 -1
  193. package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +17 -6
  194. package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
  195. package/dist/services/mediaStorageProviders/file-storage-provider.d.ts.map +1 -1
  196. package/dist/services/mediaStorageProviders/file-storage-provider.js +0 -13
  197. package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
  198. package/dist/services/menu-item-metadata.service.d.ts.map +1 -1
  199. package/dist/services/menu-item-metadata.service.js +4 -0
  200. package/dist/services/menu-item-metadata.service.js.map +1 -1
  201. package/dist/services/model-metadata.service.d.ts.map +1 -1
  202. package/dist/services/model-metadata.service.js +2 -42
  203. package/dist/services/model-metadata.service.js.map +1 -1
  204. package/dist/services/model-sequence.service.d.ts +23 -0
  205. package/dist/services/model-sequence.service.d.ts.map +1 -0
  206. package/dist/services/model-sequence.service.js +55 -0
  207. package/dist/services/model-sequence.service.js.map +1 -0
  208. package/dist/services/module-metadata.service.d.ts +1 -0
  209. package/dist/services/module-metadata.service.d.ts.map +1 -1
  210. package/dist/services/module-metadata.service.js +35 -1
  211. package/dist/services/module-metadata.service.js.map +1 -1
  212. package/dist/services/permission-metadata.service.d.ts +5 -5
  213. package/dist/services/permission-metadata.service.d.ts.map +1 -1
  214. package/dist/services/permission-metadata.service.js +6 -5
  215. package/dist/services/permission-metadata.service.js.map +1 -1
  216. package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
  217. package/dist/services/queues/database-subscriber.service.js +2 -1
  218. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  219. package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
  220. package/dist/services/queues/rabbitmq-subscriber.service.js +2 -2
  221. package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
  222. package/dist/services/role-metadata.service.d.ts.map +1 -1
  223. package/dist/services/role-metadata.service.js +1 -0
  224. package/dist/services/role-metadata.service.js.map +1 -1
  225. package/dist/services/scheduled-job.service.d.ts +6 -6
  226. package/dist/services/scheduled-job.service.d.ts.map +1 -1
  227. package/dist/services/scheduled-job.service.js +8 -8
  228. package/dist/services/scheduled-job.service.js.map +1 -1
  229. package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
  230. package/dist/services/scheduled-jobs/scheduler.service.js +4 -0
  231. package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
  232. package/dist/services/security-rule.service.d.ts.map +1 -1
  233. package/dist/services/security-rule.service.js +1 -0
  234. package/dist/services/security-rule.service.js.map +1 -1
  235. package/dist/services/selection-providers/list-of-models-selection-provider.service.d.ts.map +1 -1
  236. package/dist/services/selection-providers/list-of-models-selection-provider.service.js +4 -0
  237. package/dist/services/selection-providers/list-of-models-selection-provider.service.js.map +1 -1
  238. package/dist/services/setting.service.d.ts +7 -5
  239. package/dist/services/setting.service.d.ts.map +1 -1
  240. package/dist/services/setting.service.js +26 -4
  241. package/dist/services/setting.service.js.map +1 -1
  242. package/dist/services/sms-template.service.d.ts +7 -7
  243. package/dist/services/sms-template.service.d.ts.map +1 -1
  244. package/dist/services/sms-template.service.js +8 -7
  245. package/dist/services/sms-template.service.js.map +1 -1
  246. package/dist/services/solid-introspect.service.d.ts +4 -13
  247. package/dist/services/solid-introspect.service.d.ts.map +1 -1
  248. package/dist/services/solid-introspect.service.js +4 -22
  249. package/dist/services/solid-introspect.service.js.map +1 -1
  250. package/dist/services/solid-ts-morph.service.js +2 -2
  251. package/dist/services/solid-ts-morph.service.js.map +1 -1
  252. package/dist/services/user-activity-history.service.d.ts.map +1 -1
  253. package/dist/services/user-activity-history.service.js +1 -0
  254. package/dist/services/user-activity-history.service.js.map +1 -1
  255. package/dist/services/user-view-metadata.service.d.ts.map +1 -1
  256. package/dist/services/user-view-metadata.service.js +3 -2
  257. package/dist/services/user-view-metadata.service.js.map +1 -1
  258. package/dist/services/user.service.d.ts.map +1 -1
  259. package/dist/services/user.service.js +1 -0
  260. package/dist/services/user.service.js.map +1 -1
  261. package/dist/services/view-metadata.service.d.ts +1 -1
  262. package/dist/services/view-metadata.service.d.ts.map +1 -1
  263. package/dist/services/view-metadata.service.js +3 -1
  264. package/dist/services/view-metadata.service.js.map +1 -1
  265. package/dist/solid-core-cli-db.module.d.ts.map +1 -1
  266. package/dist/solid-core-cli-db.module.js +5 -2
  267. package/dist/solid-core-cli-db.module.js.map +1 -1
  268. package/dist/solid-core.module.d.ts.map +1 -1
  269. package/dist/solid-core.module.js +18 -0
  270. package/dist/solid-core.module.js.map +1 -1
  271. package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
  272. package/dist/subscribers/audit.subscriber.js +5 -1
  273. package/dist/subscribers/audit.subscriber.js.map +1 -1
  274. package/dist/subscribers/computed-entity-field.subscriber.d.ts +4 -2
  275. package/dist/subscribers/computed-entity-field.subscriber.d.ts.map +1 -1
  276. package/dist/subscribers/computed-entity-field.subscriber.js +53 -12
  277. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  278. package/dist/transformers/typeorm/local-date-time-transformer.d.ts +5 -0
  279. package/dist/transformers/typeorm/local-date-time-transformer.d.ts.map +1 -0
  280. package/dist/transformers/typeorm/local-date-time-transformer.js +26 -0
  281. package/dist/transformers/typeorm/local-date-time-transformer.js.map +1 -0
  282. package/dist/tsconfig.tsbuildinfo +1 -1
  283. package/docs/grouping-enhancements.md +89 -0
  284. package/package.json +1 -1
  285. package/src/commands/fixtures/fixtures-setup.command.ts +44 -0
  286. package/src/commands/fixtures/fixtures-tear-down.command.ts +45 -0
  287. package/src/commands/refresh-model.command.ts +3 -1
  288. package/src/constants/error-messages.ts +7 -1
  289. package/src/controllers/model-sequence.controller.ts +93 -0
  290. package/src/controllers/setting.controller.ts +33 -21
  291. package/src/dtos/basic-filters.dto.ts +6 -1
  292. package/src/dtos/basic-group-filters.dto.ts +23 -0
  293. package/src/dtos/create-field-metadata.dto.ts +1 -1
  294. package/src/dtos/create-model-sequence.dto.ts +51 -0
  295. package/src/dtos/create-role-metadata.dto.ts +16 -3
  296. package/src/dtos/get-mcp-url.dto.ts +13 -0
  297. package/src/dtos/resolve-s3-url.dto.ts +9 -11
  298. package/src/dtos/update-model-sequence.dto.ts +53 -0
  299. package/src/entities/common.entity.ts +2 -2
  300. package/src/entities/legacy-common.entity.ts +2 -1
  301. package/src/entities/model-sequence.entity.ts +32 -0
  302. package/src/helpers/field-crud-managers/BigIntFieldCrudManager.ts +18 -5
  303. package/src/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.ts +9 -9
  304. package/src/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.ts +16 -8
  305. package/src/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.ts +9 -9
  306. package/src/helpers/model-metadata-helper.service.ts +6 -4
  307. package/src/helpers/module-metadata-helper.service.ts +18 -1
  308. package/src/helpers/module.helper.ts +40 -5
  309. package/src/helpers/solid-registry.ts +14 -0
  310. package/src/index.ts +3 -1
  311. package/src/jobs/computed-field-evaluation-subscriber.service.ts +15 -4
  312. package/src/repository/media.repository.ts +3 -2
  313. package/src/repository/model-sequence.repository.ts +97 -0
  314. package/src/seeders/module-metadata-seeder.service.ts +103 -29
  315. package/src/seeders/seed-data/solid-core-metadata.json +343 -27
  316. package/src/seeders/system-fields-seeder.service.ts +6 -2
  317. package/src/services/action-metadata.service.ts +3 -2
  318. package/src/services/ai-interaction.service.ts +2 -1
  319. package/src/services/authentication.service.ts +46 -14
  320. package/src/services/chatter-message-details.service.ts +2 -1
  321. package/src/services/chatter-message.service.ts +10 -4
  322. package/src/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.ts +8 -7
  323. package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +86 -0
  324. package/src/services/crud-helper.service.ts +287 -49
  325. package/src/services/crud.service.ts +83 -32
  326. package/src/services/database/database-bootstrap.service.ts +91 -0
  327. package/src/services/email-template.service.ts +11 -13
  328. package/src/services/excel.service.ts +146 -3
  329. package/src/services/field-metadata.service.ts +102 -55
  330. package/src/services/file.service.ts +9 -0
  331. package/src/services/fixtures.service.ts +108 -0
  332. package/src/services/genai/ingest-metadata.service.ts +4 -3
  333. package/src/services/import-transaction-error-log.service.ts +2 -1
  334. package/src/services/import-transaction.service.ts +8 -4
  335. package/src/services/list-of-values.service.ts +4 -4
  336. package/src/services/locale.service.ts +2 -1
  337. package/src/services/mail/smtp-email.service.ts +1 -1
  338. package/src/services/media.service.ts +10 -11
  339. package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +22 -7
  340. package/src/services/mediaStorageProviders/file-storage-provider.ts +18 -13
  341. package/src/services/menu-item-metadata.service.ts +6 -2
  342. package/src/services/model-metadata.service.ts +50 -44
  343. package/src/services/model-sequence.service.ts +33 -0
  344. package/src/services/module-metadata.service.ts +49 -2
  345. package/src/services/permission-metadata.service.ts +8 -9
  346. package/src/services/queues/database-subscriber.service.ts +3 -1
  347. package/src/services/queues/rabbitmq-subscriber.service.ts +4 -2
  348. package/src/services/role-metadata.service.ts +1 -0
  349. package/src/services/scheduled-job.service.ts +9 -9
  350. package/src/services/scheduled-jobs/scheduler.service.ts +5 -0
  351. package/src/services/security-rule.service.ts +1 -0
  352. package/src/services/selection-providers/list-of-models-selection-provider.service.ts +5 -2
  353. package/src/services/setting.service.ts +33 -6
  354. package/src/services/sms-template.service.ts +11 -13
  355. package/src/services/solid-introspect.service.ts +6 -19
  356. package/src/services/solid-ts-morph.service.ts +2 -2
  357. package/src/services/user-activity-history.service.ts +3 -2
  358. package/src/services/user-view-metadata.service.ts +4 -3
  359. package/src/services/user.service.ts +2 -1
  360. package/src/services/view-metadata.service.ts +5 -4
  361. package/src/solid-core-cli-db.module.ts +5 -4
  362. package/src/solid-core.module.ts +18 -0
  363. package/src/subscribers/audit.subscriber.ts +3 -2
  364. package/src/subscribers/computed-entity-field.subscriber.ts +60 -17
  365. package/src/transformers/typeorm/local-date-time-transformer.ts +30 -0
  366. /package/sql/{mssql → default/mssql}/proc_CleanupModelMetadata.sql +0 -0
  367. /package/sql/{mssql → default/mssql}/proc_CleanupModuleMetadata.sql +0 -0
  368. /package/sql/{mssql/scratchpad.sql → default/mssql/scratchpad.sql.txt} +0 -0
  369. /package/sql/{postgres → default/postgres}/proc_CleanupModelMetadata.sql +0 -0
  370. /package/sql/{postgres → default/postgres}/proc_CleanupModuleMetadata.sql +0 -0
  371. /package/sql/{postgres/scratchpad.sql → default/postgres/scratchpad.sql.txt} +0 -0
@@ -7,24 +7,22 @@ export class ResolveS3UrlDto {
7
7
  @IsNotEmpty()
8
8
  fieldName: string;
9
9
 
10
- @IsNotEmpty()
11
- s3KeyFieldName: string;
12
10
 
13
11
  @IsNotEmpty()
14
- fieldValue: string;
12
+ fileType?: string;
15
13
 
16
14
  @IsNotEmpty()
17
- fileType: string;
18
-
19
- @IsNotEmpty()
20
- bucketName: string;
21
-
22
- @IsNotEmpty()
23
- isPrivate: string;
24
- }
15
+ s3Key?: string;
25
16
 
17
+ @IsOptional()
18
+ bucketName?: string;
26
19
 
20
+ @IsOptional()
21
+ mediaStorageProviderUserKey?: string;
27
22
 
23
+ @IsNotEmpty()
24
+ isPrivate?: string;
25
+ }
28
26
 
29
27
 
30
28
 
@@ -0,0 +1,53 @@
1
+ import { IsInt,IsOptional, IsString, IsNotEmpty } from 'class-validator';
2
+ import { ApiProperty } from '@nestjs/swagger';
3
+
4
+ export class UpdateModelSequenceDto {
5
+ @IsOptional()
6
+ @IsInt()
7
+ id: number;
8
+ @IsOptional()
9
+ @IsInt()
10
+ @ApiProperty()
11
+ moduleId: number;
12
+ @IsString()
13
+ @IsOptional()
14
+ @ApiProperty()
15
+ moduleUserKey: string;
16
+ @IsOptional()
17
+ @IsInt()
18
+ @ApiProperty()
19
+ modelId: number;
20
+ @IsString()
21
+ @IsOptional()
22
+ @ApiProperty()
23
+ modelUserKey: string;
24
+ @IsOptional()
25
+ @IsInt()
26
+ @ApiProperty()
27
+ fieldId: number;
28
+ @IsString()
29
+ @IsOptional()
30
+ @ApiProperty()
31
+ fieldUserKey: string;
32
+ @IsNotEmpty()
33
+ @IsOptional()
34
+ @IsString()
35
+ @ApiProperty()
36
+ sequenceName: string;
37
+ @IsOptional()
38
+ @IsInt()
39
+ @ApiProperty()
40
+ currentValue: number;
41
+ @IsOptional()
42
+ @IsString()
43
+ @ApiProperty()
44
+ prefix: string;
45
+ @IsOptional()
46
+ @IsInt()
47
+ @ApiProperty()
48
+ padding: number;
49
+ @IsOptional()
50
+ @IsString()
51
+ @ApiProperty()
52
+ separator: string;
53
+ }
@@ -1,4 +1,4 @@
1
- import { Column, CreateDateColumn, DeleteDateColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
1
+ import { Column, CreateDateColumn, DeleteDateColumn, Index, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
2
2
  import type { User } from "./user.entity";
3
3
  import { Exclude, Expose, Type } from "class-transformer";
4
4
 
@@ -15,6 +15,7 @@ export abstract class CommonEntity {
15
15
  updatedAt: Date;
16
16
 
17
17
  @DeleteDateColumn({ name: "deleted_at" })
18
+ @Index()
18
19
  deletedAt: Date;
19
20
 
20
21
  @Column({ name: "deletedTracker", default: "not-deleted" })
@@ -49,5 +50,4 @@ export abstract class CommonEntity {
49
50
  @Expose()
50
51
  @Column({ name: `updated_by_id`, nullable: true })
51
52
  updatedBy: number;
52
-
53
53
  }
@@ -1,5 +1,5 @@
1
1
  import { Exclude, Expose, Type } from "class-transformer";
2
- import { Column, CreateDateColumn, DeleteDateColumn, JoinColumn, ManyToOne, UpdateDateColumn } from "typeorm";
2
+ import { Column, CreateDateColumn, DeleteDateColumn, Index, JoinColumn, ManyToOne, UpdateDateColumn } from "typeorm";
3
3
  import type { User } from "./user.entity";
4
4
 
5
5
  export const LEGACY_TABLE_FIELDS_PREFIX = 'ss';
@@ -18,6 +18,7 @@ export abstract class LegacyCommonEntity {
18
18
  updatedAt: Date;
19
19
 
20
20
  @DeleteDateColumn({ name: `${LEGACY_TABLE_FIELDS_PREFIX}_deleted_at` })
21
+ @Index()
21
22
  deletedAt: Date;
22
23
 
23
24
  @Column({ name: `${LEGACY_TABLE_FIELDS_PREFIX}_deleted_tracker`, default: "not-deleted" })
@@ -0,0 +1,32 @@
1
+ import { CommonEntity } from "src/entities/common.entity"
2
+ import { Entity, JoinColumn, ManyToOne, Index, Column } from 'typeorm';
3
+ import { ModuleMetadata } from 'src/entities/module-metadata.entity';
4
+ import { ModelMetadata } from 'src/entities/model-metadata.entity';
5
+ import { FieldMetadata } from 'src/entities/field-metadata.entity'
6
+
7
+ @Entity('ss_model_sequence')
8
+ export class ModelSequence extends CommonEntity {
9
+ @Index()
10
+ @ManyToOne(() => ModuleMetadata, { nullable: false })
11
+ @JoinColumn()
12
+ module: ModuleMetadata;
13
+ @Index()
14
+ @ManyToOne(() => ModelMetadata, { nullable: false })
15
+ @JoinColumn()
16
+ model: ModelMetadata;
17
+ @Index()
18
+ @ManyToOne(() => FieldMetadata, { nullable: false })
19
+ @JoinColumn()
20
+ field: FieldMetadata;
21
+ @Index({ unique: true })
22
+ @Column({ type: "varchar" })
23
+ sequenceName: string;
24
+ @Column({ type: "integer", default: 1 })
25
+ currentValue: number;
26
+ @Column({ type: "varchar", nullable: true })
27
+ prefix: string;
28
+ @Column({ type: "integer", default: 5 })
29
+ padding: number;
30
+ @Column({ type: "varchar", default: "" })
31
+ separator: string;
32
+ }
@@ -14,13 +14,22 @@ export class BigIntFieldCrudManager implements FieldCrudManager {
14
14
  }
15
15
 
16
16
  validate(createDto: any): ValidationError[] {
17
- const fieldValue: any = createDto[this.options.fieldName];
17
+ let fieldValue: any = createDto[this.options.fieldName];
18
+ if (fieldValue !== undefined && fieldValue !== null) {
19
+ try {
20
+ if (typeof fieldValue === 'string' || typeof fieldValue === 'number') {
21
+ fieldValue = BigInt(fieldValue);
22
+ }
23
+ } catch (err) {
24
+ return [{ field: this.options.fieldName, error: 'Invalid numeric value' }];
25
+ }
26
+ }
18
27
  return this.applyValidations(fieldValue);
19
28
  }
20
29
 
21
30
  private applyValidations(fieldValue: any): ValidationError[] {
22
31
  const errors: ValidationError[] = [];
23
- this.isApplyRequiredValidation() && isEmpty(fieldValue) ? errors.push({ field: this.options.fieldName, error: `Field: ${this.options.fieldName} is required` }): "no errors";
32
+ this.isApplyRequiredValidation() && isEmpty(fieldValue) ? errors.push({ field: this.options.fieldName, error: `Field: ${this.options.fieldName} is required` }) : "no errors";
24
33
  if (isNotEmpty(fieldValue)) {
25
34
  errors.push(...this.applyFormatValidations(fieldValue));
26
35
  }
@@ -29,7 +38,7 @@ export class BigIntFieldCrudManager implements FieldCrudManager {
29
38
 
30
39
  private applyFormatValidations(fieldValue: any): ValidationError[] {
31
40
  const errors: ValidationError[] = [];
32
- !this.isBigInt(fieldValue) ? errors.push({ field: this.options.fieldName, error: 'Field is not a bigint' }): "no errors";
41
+ !this.isBigInt(fieldValue) ? errors.push({ field: this.options.fieldName, error: 'Field is not a bigint' }) : "no errors";
33
42
  this.isApplyMinValidation() && !min(fieldValue, this.options.min) ? errors.push({ field: this.options.fieldName, error: 'Field value is lesser than minimum required' }) : "no errors"; //FIXME min length to be handled
34
43
  this.isApplyMaxValidation() && !max(fieldValue, this.options.max) ? errors.push({ field: this.options.fieldName, error: 'Field value is greater than maximum required' }) : "no errors";
35
44
  return errors;
@@ -43,13 +52,17 @@ export class BigIntFieldCrudManager implements FieldCrudManager {
43
52
  private isApplyMinValidation(): boolean {
44
53
  return this.options.min > 0;
45
54
  }
55
+
46
56
  private isApplyMaxValidation(): boolean {
47
57
  return this.options.max > 0;
48
58
  }
59
+
49
60
  private isApplyRequiredValidation(): boolean {
50
61
  return this.options.required;
51
62
  }
63
+
52
64
  private isBigInt(value: any): boolean {
53
- return typeof value === 'bigint';
54
- }
65
+ const valueType = typeof value;
66
+ return valueType === 'bigint' || (valueType === 'number' && Number.isFinite(value));
67
+ }
55
68
  }
@@ -68,11 +68,11 @@ export class ManyToManyRelationFieldCrudManager implements FieldCrudManager {
68
68
  }
69
69
 
70
70
  async transformForCreate(dto: any): Promise<any> {
71
- const currentEntityTarget = this.getEntityTarget(classify(this.options.modelSingularName));
72
- const currentEntityRepository = this.options.entityManager.getRepository(currentEntityTarget);
71
+ const currentEntityName = classify(this.options.modelSingularName);
72
+ const currentEntityRepository = this.options.entityManager.getRepository(currentEntityName);
73
73
 
74
- const relatedEntityTarget = this.getEntityTarget(classify(this.options.relationCoModelSingularName));
75
- const relatedEntityRepository = this.options.entityManager.getRepository(relatedEntityTarget)
74
+ const relatedEntityName = classify(this.options.relationCoModelSingularName);
75
+ const relatedEntityRepository = this.options.entityManager.getRepository(relatedEntityName)
76
76
 
77
77
  dto[this.valueFieldName] = await this.transformByCommand(dto, relatedEntityRepository, currentEntityRepository);
78
78
  return dto;
@@ -192,9 +192,9 @@ export class ManyToManyRelationFieldCrudManager implements FieldCrudManager {
192
192
 
193
193
  // TODO: We have moved this to SolidRegistry service, refactor to use that service.
194
194
  // Returns the entity target class from the entity name
195
- private getEntityTarget(entityName: string): any { //TODO Can be refactored to use this function from crud helper service
196
- const entityMetadatas = this.options.entityManager.connection.entityMetadatas;
197
- const entityMetadata = entityMetadatas.find(em => em.name === entityName);
198
- return entityMetadata.target;
199
- }
195
+ // private getEntityTarget(entityName: string): any { //TODO Can be refactored to use this function from crud helper service
196
+ // const entityMetadatas = this.options.entityManager.connection.entityMetadatas;
197
+ // const entityMetadata = entityMetadatas.find(em => em.name === entityName);
198
+ // return entityMetadata.target;
199
+ // }
200
200
  }
@@ -1,4 +1,5 @@
1
1
  import { classify } from "@angular-devkit/core/src/utils/strings";
2
+ import { BadRequestException } from "@nestjs/common";
2
3
  import { isEmpty, isNotEmpty, isString } from "class-validator";
3
4
  import { FieldCrudManager, ValidationError } from "src/interfaces";
4
5
  import { IsParsableInt } from "src/validators/is-parsable-int";
@@ -64,16 +65,23 @@ export class ManyToOneRelationFieldCrudManager implements FieldCrudManager {
64
65
  // Avoid transforming if both fieldId and fieldUserKey is empty
65
66
  if ((isEmpty(fieldId)) && isEmpty(fieldUserKeyValue)) return dto;
66
67
 
68
+ if (!this.options.relationCoModelSingularName) {
69
+ throw new BadRequestException(`ManyToOneRelationFieldCrudManager: relationCoModelSingularName is not defined in the field: ${this.options.fieldName}`);
70
+ }
67
71
  // // Load the related entity from the database, using the repository of the related entity
68
- const entityTarget = this.getRelatedEntityTarget(classify(this.options.relationCoModelSingularName));
72
+ //const entityTarget = this.getRelatedEntityTarget(classify(this.options.relationCoModelSingularName));
73
+ const coModelEntityName = classify(this.options.relationCoModelSingularName);
74
+
75
+ //Load the related entity from the database, using the repository of the related entity
76
+ //const entityTarget = this.getRelatedEntityTarget(classify(this.options.relationCoModelSingularName));
69
77
  if (isNotEmpty(fieldId)) {
70
- dto[this.options.fieldName] = await this.options.entityManager.getRepository(entityTarget).findOneBy({ id: fieldId });
78
+ dto[this.options.fieldName] = await this.options.entityManager.getRepository(coModelEntityName).findOneBy({ id: fieldId });
71
79
  if (this.options.required && isEmpty(dto[this.options.fieldName])) {
72
80
  throw new Error(`ManyToOneRelationFieldCrudManager: Record with id: ${fieldId} not found in ${this.options.relationCoModelSingularName}`);
73
81
  }
74
82
  }
75
83
  else {
76
- dto[this.options.fieldName] = await this.options.entityManager.getRepository(entityTarget).findOneBy({ [this.options.relationCoModelUserKeyFieldName]: fieldUserKeyValue });
84
+ dto[this.options.fieldName] = await this.options.entityManager.getRepository(coModelEntityName).findOneBy({ [this.options.relationCoModelUserKeyFieldName]: fieldUserKeyValue });
77
85
  if (this.options.required && isEmpty(dto[this.options.fieldName])) {
78
86
  throw new Error(`ManyToOneRelationFieldCrudManager: Record with userKey: ${this.options.relationCoModelUserKeyFieldName}: ${fieldUserKeyValue} not found in ${this.options.relationCoModelSingularName}`);
79
87
  }
@@ -88,10 +96,10 @@ export class ManyToOneRelationFieldCrudManager implements FieldCrudManager {
88
96
  }
89
97
 
90
98
  // Returns the entity target class from the entity name
91
- private getRelatedEntityTarget(relatedEntityName: string): any {
92
- const entityMetadatas = this.options.entityManager.connection.entityMetadatas;
93
- const relatedEntityMetadata = entityMetadatas.find(em => em.name === relatedEntityName);
94
- return relatedEntityMetadata.target;
95
- }
99
+ // private getRelatedEntityTarget(relatedEntityName: string): any {
100
+ // const entityMetadatas = this.options.entityManager.connection.entityMetadatas;
101
+ // const relatedEntityMetadata = entityMetadatas.find(em => em.name === relatedEntityName);
102
+ // return relatedEntityMetadata.target;
103
+ // }
96
104
 
97
105
  }
@@ -75,11 +75,11 @@ export class OneToManyRelationFieldCrudManager implements FieldCrudManager {
75
75
 
76
76
  async transformForCreate(dto: any): Promise<any> {
77
77
  // const relatedFieldData: any[] = dto[this.fieldName()];
78
- const currentEntityTarget = this.getEntityTarget(classify(this.options.modelSingularName));
79
- const currentEntityRepository = this.options.entityManager.getRepository(currentEntityTarget);
78
+ const currentEntityName = classify(this.options.modelSingularName);
79
+ const currentEntityRepository = this.options.entityManager.getRepository(currentEntityName);
80
80
 
81
- const relatedEntityTarget = this.getEntityTarget(classify(this.options.relationCoModelSingularName));
82
- const relatedEntityRepository = this.options.entityManager.getRepository(relatedEntityTarget)
81
+ const relatedEntityName = classify(this.options.relationCoModelSingularName);
82
+ const relatedEntityRepository = this.options.entityManager.getRepository(relatedEntityName);
83
83
 
84
84
  dto[this.valueFieldName] = await this.transformByCommand(dto, relatedEntityRepository, currentEntityRepository);
85
85
  return dto;
@@ -197,9 +197,9 @@ export class OneToManyRelationFieldCrudManager implements FieldCrudManager {
197
197
 
198
198
  // TODO: We have moved this to SolidRegistry service, refactor to use that service.
199
199
  // Returns the entity target class from the entity name
200
- private getEntityTarget(entityName: string): any { //TODO Can be refactored to use this function from crud helper service
201
- const entityMetadatas = this.options.entityManager.connection.entityMetadatas;
202
- const entityMetadata = entityMetadatas.find(em => em.name === entityName);
203
- return entityMetadata.target;
204
- }
200
+ // private getEntityTarget(entityName: string): any { //TODO Can be refactored to use this function from crud helper service
201
+ // const entityMetadatas = this.options.entityManager.connection.entityMetadatas;
202
+ // const entityMetadata = entityMetadatas.find(em => em.name === entityName);
203
+ // return entityMetadata.target;
204
+ // }
205
205
  }
@@ -1,18 +1,20 @@
1
1
  // Return the system fields metadata for a model
2
2
 
3
- import { Injectable, Logger } from "@nestjs/common";
3
+ import { forwardRef, Inject, Injectable, Logger } from "@nestjs/common";
4
+ import { _ } from "lodash";
5
+ import { LEGACY_TABLE_FIELDS_PREFIX } from "src/entities/legacy-common.entity";
4
6
  import { ModelMetadataRepository } from "src/repository/model-metadata.repository";
5
7
  import { SolidRegistry } from "./solid-registry";
6
- import {_ } from "lodash";
7
- import { LEGACY_TABLE_FIELDS_PREFIX } from "src/entities/legacy-common.entity";
8
8
 
9
9
  @Injectable()
10
10
  export class ModelMetadataHelperService {
11
11
  private readonly logger = new Logger(ModelMetadataHelperService.name);
12
12
 
13
- constructor(private readonly registry: SolidRegistry,
13
+ constructor(
14
+ private readonly registry: SolidRegistry,
14
15
  // @InjectRepository(ModelMetadata)
15
16
  // private readonly modelMetadataRepo: Repository<ModelMetadata>,
17
+ @Inject(forwardRef(() => ModelMetadataRepository))
16
18
  private readonly modelMetadataRepo: ModelMetadataRepository,
17
19
  ) {
18
20
  }
@@ -57,4 +57,21 @@ export class ModuleMetadataHelperService {
57
57
  }
58
58
  return filePath;
59
59
  }
60
- }
60
+ async getModuleMetadataFolderPath(moduleName: string): Promise<string> {
61
+ if (!moduleName) {
62
+ return '';
63
+ }
64
+
65
+ const dashModuleName = dasherize(moduleName);
66
+
67
+ const folderPath = path.resolve(
68
+ process.cwd(),
69
+ 'module-metadata',
70
+ dashModuleName,
71
+ );
72
+
73
+ const exists = await this.fileService.pathExists(folderPath);
74
+ return exists ? folderPath : '';
75
+ }
76
+
77
+ }
@@ -1,6 +1,8 @@
1
+ import { Logger } from '@nestjs/common';
1
2
  import * as fs from 'fs'; // Use the Promise-based version of fs for async/await
2
3
  import * as path from 'path'; // To handle file paths
3
4
 
5
+ const logger = new Logger('module.helper');
4
6
 
5
7
  export const getDynamicModuleNames = (): string[] => {
6
8
  const dynamicModulesToExclude = process.env.SOLID_DYNAMIC_MODULES_TO_EXCLUDE?.split(',') || [];
@@ -21,15 +23,48 @@ export const getDynamicModuleNames = (): string[] => {
21
23
 
22
24
  if (!isValidDirectory) return false;
23
25
 
24
- return true
25
- // const fullPath = path.join(srcPath, dirent.name);
26
- // const files = fs.readdirSync(fullPath);
26
+ // return true
27
+ const fullPath = path.join(srcPath, dirent.name);
28
+ const files = fs.readdirSync(fullPath);
27
29
  // skip if empty directory
28
- // return files.length > 0;
30
+ return files.length > 0;
29
31
  })
30
32
  .map(dirent => dirent.name);
31
33
 
32
- console.log(`Enabled dynamic modules:`, enabledModules);
34
+ // logger.debug(`Enabled dynamic modules:`, enabledModules);
35
+ return enabledModules;
36
+ }
37
+
38
+ export const getDynamicModuleNamesBasedOnMetadata = (): string[] => {
39
+ const dynamicModulesToExclude = process.env.SOLID_DYNAMIC_MODULES_TO_EXCLUDE?.split(',') || [];
40
+
41
+ // Find a path that is ../${srcPath}/module-metadata save it in a variable.
42
+ // const srcPath = path.join(process.cwd(), 'src');
43
+ const moduleMetadataPath = path.join(process.cwd(), 'module-metadata');
44
+ const coreModuleNames = getCoreModuleNames();
45
+ const allExcludedModules = [...new Set([...coreModuleNames, ...dynamicModulesToExclude])];
46
+
47
+ // if module-metadata path does not exist, return empty array
48
+ if (!fs.existsSync(moduleMetadataPath)) {
49
+ logger.warn(`Module metadata path does not exist: ${moduleMetadataPath}`);
50
+ return [];
51
+ }
52
+
53
+ const moduleMetadataDirectories = fs.readdirSync(moduleMetadataPath, { withFileTypes: true });
54
+ const enabledModules = moduleMetadataDirectories
55
+ .filter(dirent => {
56
+ const isValidDirectory = dirent.isDirectory() && !allExcludedModules.includes(dirent.name);
57
+
58
+ if (!isValidDirectory) return false;
59
+
60
+ const fullPath = path.join(moduleMetadataPath, dirent.name, `${dirent.name}-metadata.json`);
61
+
62
+ const stats = fs.statSync(fullPath, { throwIfNoEntry: false });
63
+ return !!stats && stats.isFile();
64
+ })
65
+ .map(dirent => dirent.name);
66
+
67
+ // logger.debug(`Enabled dynamic modules basis src:`, enabledModules);
33
68
  return enabledModules;
34
69
  }
35
70
 
@@ -7,6 +7,9 @@ import { SecurityRule } from 'src/entities/security-rule.entity';
7
7
  import { IScheduledJob } from 'src/services/scheduled-jobs/scheduled-job.interface';
8
8
  import { IDashboardQuestionDataProvider, IDashboardVariableSelectionProvider, IErrorCodeProvider, ISecurityRuleConfigProvider, ISelectionProvider, ISelectionProviderContext, ISolidDatabaseModule } from "../interfaces";
9
9
  import { DatasourceType } from 'src/dtos/create-model-metadata.dto';
10
+ import { ObjectLiteral } from 'typeorm';
11
+ import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
12
+ import { RelationMetadata } from 'typeorm/metadata/RelationMetadata';
10
13
 
11
14
  type ControllerMetadata = {
12
15
  name: string;
@@ -39,6 +42,16 @@ export enum RESERVED_SOLID_KEYWORDS {
39
42
  locale = "locale"
40
43
  }
41
44
 
45
+ export interface TypeOrmEventContext {
46
+ eventType?: string;
47
+ entity?: ObjectLiteral | undefined;
48
+ databaseEntity?: any;
49
+ entityId?: any;
50
+ metadataName?: string;
51
+ updatedColumns?: string[];
52
+ updatedRelations?: string[];
53
+ }
54
+
42
55
  export interface ComputedFieldMetadata<TContext = any> {
43
56
  moduleName: string; // Name of the module where the computed field is defined
44
57
  modelName: string; // Name of the model where the computed field is defined
@@ -49,6 +62,7 @@ export interface ComputedFieldMetadata<TContext = any> {
49
62
  computedFieldValueProviderName: string; // Name of the provider that computes the field value
50
63
  // Example: '{"contextKey": "contextValue"}'
51
64
  computedFieldValueProviderCtxt: TContext; // Context for the computed field value
65
+ eventContext: TypeOrmEventContext;
52
66
  }
53
67
 
54
68
  @Injectable()
package/src/index.ts CHANGED
@@ -137,6 +137,7 @@ export * from './entities/dashboard-variable.entity'
137
137
  export * from './entities/dashboard-question.entity'
138
138
  export * from './entities/dashboard-question-sql-dataset-config.entity'
139
139
  export * from './entities/ai-interaction.entity'
140
+ export * from './entities/model-sequence.entity'
140
141
 
141
142
  export * from './enums/auth-type.enum'
142
143
  export * from './decorators/disallow-in-production.decorator'
@@ -299,6 +300,8 @@ export * from './subscribers/audit.subscriber'
299
300
  export * from './transformers/array-transformer'
300
301
  export * from './transformers/boolean-transformer'
301
302
  export * from './transformers/integer-transformer'
303
+ export { default as datetimeTransformer } from './transformers/datetime-transformer'
304
+ export * from './transformers/typeorm/local-date-time-transformer'
302
305
 
303
306
  export * from './validators/is-parsable-int'
304
307
 
@@ -307,6 +310,5 @@ export * from './interfaces'
307
310
  export * from './solid-core.module'
308
311
 
309
312
  export * from './winston.logger'
310
- export { default as datetimeTransformer } from './transformers/datetime-transformer'
311
313
 
312
314
  export { ERROR_MESSAGES } from './constants/error-messages'
@@ -1,4 +1,4 @@
1
- import { Injectable } from "@nestjs/common";
1
+ import { Injectable, Logger } from "@nestjs/common";
2
2
  import { SolidRegistry } from "src/helpers/solid-registry";
3
3
  import { IEntityPostComputeFieldProvider, QueuesModuleOptions } from "src/interfaces";
4
4
  import { QueueMessage } from "src/interfaces/mq";
@@ -11,6 +11,7 @@ import computedFieldEvaluationQueueOptions from "./computed-field-evaluation-que
11
11
 
12
12
  @Injectable()
13
13
  export class ComputedFieldEvaluationSubscriberRabbitmq extends RabbitMqSubscriber<ComputedFieldEvaluationPayload> {
14
+ private readonly _logger = new Logger(ComputedFieldEvaluationSubscriberRabbitmq.name);
14
15
  constructor(
15
16
  readonly mqMessageService: MqMessageService,
16
17
  readonly mqMessageQueueService: MqMessageQueueService,
@@ -30,9 +31,19 @@ export class ComputedFieldEvaluationSubscriberRabbitmq extends RabbitMqSubscribe
30
31
  // It will then call the corresponding provider computeAndSave method to perform the evaluation
31
32
  async subscribe(message: QueueMessage<ComputedFieldEvaluationPayload>) {
32
33
  const { databaseEntity, ...computedFieldMetadata } = message.payload;
33
- const provider = this.solidRegistry.getComputedFieldProvider(computedFieldMetadata.computedFieldValueProviderName);
34
+ const { computedFieldValueProviderName } = computedFieldMetadata;
35
+ const provider = this.solidRegistry.getComputedFieldProvider(computedFieldValueProviderName);
34
36
  // Get the instance of the provider and assert it is of type IEntityComputedFieldProvider
35
37
  const providerInstance = provider.instance as IEntityPostComputeFieldProvider<any, any>; // IEntityComputedFieldProvider
36
- await providerInstance.postComputeAndSaveValue(databaseEntity, computedFieldMetadata); //FIXME There should some way to check/assert if the provider actually has a postComputeAndSaveValue
38
+ if (typeof providerInstance.postComputeAndSaveValue !== 'function') {
39
+ this._logger.warn(`Provider "${computedFieldValueProviderName}" does not implement postComputeAndSaveValue; skipping post-compute.`);
40
+ return;
41
+ }
42
+ await providerInstance.postComputeAndSaveValue(databaseEntity, {
43
+ ...computedFieldMetadata,
44
+ computedFieldValueProviderCtxt: {
45
+ ...(computedFieldMetadata.computedFieldValueProviderCtxt || {}),
46
+ },
47
+ }); //FIXME There should some way to check/assert if the provider actually has a postComputeAndSaveValue
37
48
  }
38
- }
49
+ }
@@ -1,7 +1,7 @@
1
- import { Injectable } from '@nestjs/common';
1
+ import { forwardRef, Inject, Injectable } from '@nestjs/common';
2
2
  import { Media } from 'src/entities/media.entity';
3
3
  import { RequestContextService } from 'src/services/request-context.service';
4
- import { DataSource } from 'typeorm';
4
+ import { DataSource, In } from 'typeorm';
5
5
  import { FieldMetadataRepository } from './field-metadata.repository';
6
6
  import { MediaStorageProviderMetadataRepository } from './media-storage-provider-metadata.repository';
7
7
  import { ModelMetadataRepository } from './model-metadata.repository';
@@ -21,6 +21,7 @@ export class MediaRepository extends SolidBaseRepository<Media> {
21
21
  // @InjectRepository(MediaStorageProviderMetadata)
22
22
  // private readonly mediaStorageProviderMetadataRepo: Repository<MediaStorageProviderMetadata>,
23
23
  private readonly fieldMetadataRepo: FieldMetadataRepository,
24
+ @Inject(forwardRef(() => ModelMetadataRepository))
24
25
  private readonly modelMetadataRepo: ModelMetadataRepository,
25
26
  private readonly mediaStorageProviderMetadataRepo: MediaStorageProviderMetadataRepository,
26
27
  ) {
@@ -0,0 +1,97 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { ModelSequence } from 'src/entities/model-sequence.entity';
3
+ import { RequestContextService } from 'src/services/request-context.service';
4
+ import { DataSource } from 'typeorm';
5
+ import { SecurityRuleRepository } from './security-rule.repository';
6
+ import { SolidBaseRepository } from './solid-base.repository';
7
+ import { CreateModelSequenceDto } from 'src/dtos/create-model-sequence.dto';
8
+ import { ModuleMetadata } from 'src/entities/module-metadata.entity';
9
+ import { ModelMetadata } from 'src/entities/model-metadata.entity';
10
+ import { FieldMetadata } from 'src/entities/field-metadata.entity';
11
+
12
+ @Injectable()
13
+ export class ModelSequenceRepository extends SolidBaseRepository<ModelSequence> {
14
+ constructor(
15
+ readonly dataSource: DataSource,
16
+ readonly requestContextService: RequestContextService,
17
+ readonly securityRuleRepository: SecurityRuleRepository,
18
+ ) {
19
+ super(ModelSequence, dataSource, requestContextService, securityRuleRepository);
20
+ }
21
+
22
+ async upsertWithDto(createDto: CreateModelSequenceDto) {
23
+ // Populate the module from moduleId or moduleUserKey
24
+ const moduleRepository = this.dataSource.getRepository(ModuleMetadata);
25
+ if (createDto.moduleId) {
26
+ const module = await moduleRepository.findOne({
27
+ where: {
28
+ id: createDto.moduleId,
29
+ },
30
+ });
31
+ createDto['module'] = module;
32
+ }
33
+
34
+ if (createDto.moduleUserKey) {
35
+ const module = await moduleRepository.findOne({
36
+ where: {
37
+ name: createDto.moduleUserKey,
38
+ },
39
+ });
40
+ createDto['module'] = module;
41
+ }
42
+
43
+ // Populate the model from modelId or modelUserKey
44
+ const modelRepository = this.dataSource.getRepository(ModelMetadata);
45
+ if (createDto.modelId) {
46
+ const model = await modelRepository.findOne({
47
+ where: {
48
+ id: createDto.modelId,
49
+ },
50
+ });
51
+ createDto['model'] = model;
52
+ }
53
+ if (createDto.modelUserKey) {
54
+ const model = await modelRepository.findOne({
55
+ where: {
56
+ singularName: createDto.modelUserKey,
57
+ },
58
+ });
59
+ createDto['model'] = model;
60
+ }
61
+
62
+ // Populate the field from fieldId or fieldUserKey
63
+ const fieldRepository = this.dataSource.getRepository(FieldMetadata);
64
+ if (createDto.fieldId) {
65
+ const field = await fieldRepository.findOne({
66
+ where: {
67
+ id: createDto.fieldId,
68
+ },
69
+ });
70
+ createDto['field'] = field;
71
+ }
72
+ if (createDto.fieldUserKey) {
73
+ const field = await fieldRepository.findOne({
74
+ where: {
75
+ name: createDto.fieldUserKey,
76
+ },
77
+ });
78
+ createDto['field'] = field;
79
+ }
80
+
81
+ // First check if sequence already exists using name
82
+ const existingModelSequence = await this.findOne({
83
+ where: {
84
+ sequenceName: createDto.sequenceName,
85
+ },
86
+ });
87
+
88
+ if (existingModelSequence) {
89
+ const updatedModelSequence = this.merge(existingModelSequence, createDto);
90
+ return this.save(updatedModelSequence);
91
+ }
92
+ else {
93
+ const modelSequence = this.create(createDto);
94
+ return this.save(modelSequence);
95
+ }
96
+ }
97
+ }