@solidstarters/solid-core 1.2.200 → 1.2.202

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 (527) 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/config/cache.options.d.ts +1 -1
  13. package/dist/config/cache.options.d.ts.map +1 -1
  14. package/dist/config/cache.options.js +2 -2
  15. package/dist/config/cache.options.js.map +1 -1
  16. package/dist/config/iam.config.d.ts +4 -0
  17. package/dist/config/iam.config.d.ts.map +1 -1
  18. package/dist/config/iam.config.js +2 -0
  19. package/dist/config/iam.config.js.map +1 -1
  20. package/dist/constants/error-messages.d.ts +2 -0
  21. package/dist/constants/error-messages.d.ts.map +1 -1
  22. package/dist/constants/error-messages.js +4 -0
  23. package/dist/constants/error-messages.js.map +1 -1
  24. package/dist/controllers/model-metadata.controller.d.ts +25 -0
  25. package/dist/controllers/model-metadata.controller.d.ts.map +1 -1
  26. package/dist/controllers/model-metadata.controller.js +23 -0
  27. package/dist/controllers/model-metadata.controller.js.map +1 -1
  28. package/dist/controllers/model-sequence.controller.d.ts +43 -0
  29. package/dist/controllers/model-sequence.controller.d.ts.map +1 -0
  30. package/dist/controllers/model-sequence.controller.js +179 -0
  31. package/dist/controllers/model-sequence.controller.js.map +1 -0
  32. package/dist/controllers/setting.controller.d.ts +2 -2
  33. package/dist/controllers/setting.controller.d.ts.map +1 -1
  34. package/dist/controllers/setting.controller.js +36 -42
  35. package/dist/controllers/setting.controller.js.map +1 -1
  36. package/dist/decorators/sms-provider.decorator.d.ts +3 -0
  37. package/dist/decorators/sms-provider.decorator.d.ts.map +1 -0
  38. package/dist/decorators/sms-provider.decorator.js +11 -0
  39. package/dist/decorators/sms-provider.decorator.js.map +1 -0
  40. package/dist/dtos/basic-filters.dto.d.ts +3 -1
  41. package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
  42. package/dist/dtos/basic-filters.dto.js +8 -2
  43. package/dist/dtos/basic-filters.dto.js.map +1 -1
  44. package/dist/dtos/basic-group-filters.dto.d.ts +6 -0
  45. package/dist/dtos/basic-group-filters.dto.d.ts.map +1 -0
  46. package/dist/dtos/basic-group-filters.dto.js +46 -0
  47. package/dist/dtos/basic-group-filters.dto.js.map +1 -0
  48. package/dist/dtos/create-field-metadata.dto.js +2 -2
  49. package/dist/dtos/create-field-metadata.dto.js.map +1 -1
  50. package/dist/dtos/create-model-sequence.dto.d.ts +14 -0
  51. package/dist/dtos/create-model-sequence.dto.d.ts.map +1 -0
  52. package/dist/dtos/create-model-sequence.dto.js +90 -0
  53. package/dist/dtos/create-model-sequence.dto.js.map +1 -0
  54. package/dist/dtos/create-role-metadata.dto.d.ts.map +1 -1
  55. package/dist/dtos/create-role-metadata.dto.js +1 -0
  56. package/dist/dtos/create-role-metadata.dto.js.map +1 -1
  57. package/dist/dtos/get-mcp-url.dto.d.ts +5 -0
  58. package/dist/dtos/get-mcp-url.dto.d.ts.map +1 -0
  59. package/dist/dtos/get-mcp-url.dto.js +31 -0
  60. package/dist/dtos/get-mcp-url.dto.js.map +1 -0
  61. package/dist/dtos/navigation.dto.d.ts +6 -0
  62. package/dist/dtos/navigation.dto.d.ts.map +1 -0
  63. package/dist/dtos/navigation.dto.js +33 -0
  64. package/dist/dtos/navigation.dto.js.map +1 -0
  65. package/dist/dtos/resolve-s3-url.dto.d.ts +5 -5
  66. package/dist/dtos/resolve-s3-url.dto.d.ts.map +1 -1
  67. package/dist/dtos/resolve-s3-url.dto.js +7 -7
  68. package/dist/dtos/resolve-s3-url.dto.js.map +1 -1
  69. package/dist/dtos/sign-in.dto.js +3 -3
  70. package/dist/dtos/sign-in.dto.js.map +1 -1
  71. package/dist/dtos/update-model-sequence.dto.d.ts +15 -0
  72. package/dist/dtos/update-model-sequence.dto.d.ts.map +1 -0
  73. package/dist/dtos/update-model-sequence.dto.js +94 -0
  74. package/dist/dtos/update-model-sequence.dto.js.map +1 -0
  75. package/dist/entities/common.entity.d.ts.map +1 -1
  76. package/dist/entities/common.entity.js +6 -4
  77. package/dist/entities/common.entity.js.map +1 -1
  78. package/dist/entities/field-metadata.entity.d.ts.map +1 -1
  79. package/dist/entities/field-metadata.entity.js +2 -1
  80. package/dist/entities/field-metadata.entity.js.map +1 -1
  81. package/dist/entities/legacy-common.entity.d.ts.map +1 -1
  82. package/dist/entities/legacy-common.entity.js +6 -4
  83. package/dist/entities/legacy-common.entity.js.map +1 -1
  84. package/dist/entities/model-metadata.entity.d.ts.map +1 -1
  85. package/dist/entities/model-metadata.entity.js +5 -1
  86. package/dist/entities/model-metadata.entity.js.map +1 -1
  87. package/dist/entities/model-sequence.entity.d.ts +15 -0
  88. package/dist/entities/model-sequence.entity.d.ts.map +1 -0
  89. package/dist/entities/model-sequence.entity.js +67 -0
  90. package/dist/entities/model-sequence.entity.js.map +1 -0
  91. package/dist/factories/mail.factory.d.ts.map +1 -1
  92. package/dist/factories/mail.factory.js.map +1 -1
  93. package/dist/factories/sms.factory.d.ts +14 -0
  94. package/dist/factories/sms.factory.d.ts.map +1 -0
  95. package/dist/factories/sms.factory.js +53 -0
  96. package/dist/factories/sms.factory.js.map +1 -0
  97. package/dist/helpers/date.helper.d.ts.map +1 -1
  98. package/dist/helpers/date.helper.js +13 -4
  99. package/dist/helpers/date.helper.js.map +1 -1
  100. package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.d.ts.map +1 -1
  101. package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.js +13 -2
  102. package/dist/helpers/field-crud-managers/BigIntFieldCrudManager.js.map +1 -1
  103. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.d.ts +0 -1
  104. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.d.ts.map +1 -1
  105. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.js +4 -9
  106. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.js.map +1 -1
  107. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.d.ts +0 -1
  108. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.d.ts.map +1 -1
  109. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.js +7 -8
  110. package/dist/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.js.map +1 -1
  111. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.d.ts +0 -1
  112. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.d.ts.map +1 -1
  113. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.js +4 -9
  114. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.js.map +1 -1
  115. package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -1
  116. package/dist/helpers/model-metadata-helper.service.js +6 -2
  117. package/dist/helpers/model-metadata-helper.service.js.map +1 -1
  118. package/dist/helpers/module-metadata-helper.service.d.ts +1 -0
  119. package/dist/helpers/module-metadata-helper.service.d.ts.map +1 -1
  120. package/dist/helpers/module-metadata-helper.service.js +9 -0
  121. package/dist/helpers/module-metadata-helper.service.js.map +1 -1
  122. package/dist/helpers/module.helper.d.ts +1 -0
  123. package/dist/helpers/module.helper.d.ts.map +1 -1
  124. package/dist/helpers/module.helper.js +29 -3
  125. package/dist/helpers/module.helper.js.map +1 -1
  126. package/dist/helpers/solid-registry.d.ts +14 -0
  127. package/dist/helpers/solid-registry.d.ts.map +1 -1
  128. package/dist/helpers/solid-registry.js +7 -0
  129. package/dist/helpers/solid-registry.js.map +1 -1
  130. package/dist/index.d.ts +12 -7
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +13 -8
  133. package/dist/index.js.map +1 -1
  134. package/dist/jobs/computed-field-evaluation-subscriber.service.d.ts +1 -0
  135. package/dist/jobs/computed-field-evaluation-subscriber.service.d.ts.map +1 -1
  136. package/dist/jobs/computed-field-evaluation-subscriber.service.js +16 -4
  137. package/dist/jobs/computed-field-evaluation-subscriber.service.js.map +1 -1
  138. package/dist/jobs/database/{sms-publisher-database.service.d.ts → msg91-sms-publisher-database.service.d.ts} +2 -2
  139. package/dist/jobs/database/msg91-sms-publisher-database.service.d.ts.map +1 -0
  140. package/dist/jobs/database/{sms-publisher-database.service.js → msg91-sms-publisher-database.service.js} +8 -8
  141. package/dist/jobs/database/msg91-sms-publisher-database.service.js.map +1 -0
  142. package/dist/jobs/database/{sms-queue-database-options.d.ts → msg91-sms-queue-database-options.d.ts} +1 -1
  143. package/dist/jobs/database/msg91-sms-queue-database-options.d.ts.map +1 -0
  144. package/dist/jobs/database/{sms-queue-database-options.js → msg91-sms-queue-database-options.js} +1 -1
  145. package/dist/jobs/database/msg91-sms-queue-database-options.js.map +1 -0
  146. package/dist/jobs/database/{sms-subscriber-database.service.d.ts → msg91-sms-subscriber-database.service.d.ts} +5 -5
  147. package/dist/jobs/database/msg91-sms-subscriber-database.service.d.ts.map +1 -0
  148. package/dist/jobs/database/{sms-subscriber-database.service.js → msg91-sms-subscriber-database.service.js} +14 -12
  149. package/dist/jobs/database/msg91-sms-subscriber-database.service.js.map +1 -0
  150. package/dist/jobs/database/otp-subscriber-database.service.d.ts +4 -4
  151. package/dist/jobs/database/otp-subscriber-database.service.d.ts.map +1 -1
  152. package/dist/jobs/database/otp-subscriber-database.service.js +6 -4
  153. package/dist/jobs/database/otp-subscriber-database.service.js.map +1 -1
  154. package/dist/jobs/database/twilio-sms-subscriber-database.service.d.ts +3 -3
  155. package/dist/jobs/database/twilio-sms-subscriber-database.service.d.ts.map +1 -1
  156. package/dist/jobs/database/twilio-sms-subscriber-database.service.js +6 -4
  157. package/dist/jobs/database/twilio-sms-subscriber-database.service.js.map +1 -1
  158. package/dist/jobs/{sms-publisher.service.d.ts → msg91-otp-publisher.service.d.ts} +2 -2
  159. package/dist/jobs/msg91-otp-publisher.service.d.ts.map +1 -0
  160. package/dist/jobs/{sms-publisher.service.js → msg91-otp-publisher.service.js} +8 -8
  161. package/dist/jobs/msg91-otp-publisher.service.js.map +1 -0
  162. package/dist/jobs/{sms-queue-options.d.ts → msg91-otp-queue-options.d.ts} +1 -1
  163. package/dist/jobs/msg91-otp-queue-options.d.ts.map +1 -0
  164. package/dist/jobs/{otp-queue-options.js → msg91-otp-queue-options.js} +1 -1
  165. package/dist/jobs/msg91-otp-queue-options.js.map +1 -0
  166. package/dist/jobs/{sms-subscriber.service.d.ts → msg91-otp-subscriber.service.d.ts} +6 -6
  167. package/dist/jobs/msg91-otp-subscriber.service.d.ts.map +1 -0
  168. package/dist/jobs/{otp-subscriber.service.js → msg91-otp-subscriber.service.js} +14 -12
  169. package/dist/jobs/msg91-otp-subscriber.service.js.map +1 -0
  170. package/dist/jobs/{otp-publisher.service.d.ts → msg91-sms-publisher.service.d.ts} +2 -2
  171. package/dist/jobs/msg91-sms-publisher.service.d.ts.map +1 -0
  172. package/dist/jobs/{otp-publisher.service.js → msg91-sms-publisher.service.js} +8 -8
  173. package/dist/jobs/msg91-sms-publisher.service.js.map +1 -0
  174. package/dist/jobs/{otp-queue-options.d.ts → msg91-sms-queue-options.d.ts} +1 -1
  175. package/dist/jobs/msg91-sms-queue-options.d.ts.map +1 -0
  176. package/dist/jobs/{sms-queue-options.js → msg91-sms-queue-options.js} +1 -1
  177. package/dist/jobs/msg91-sms-queue-options.js.map +1 -0
  178. package/dist/jobs/{otp-subscriber.service.d.ts → msg91-sms-subscriber.service.d.ts} +7 -7
  179. package/dist/jobs/msg91-sms-subscriber.service.d.ts.map +1 -0
  180. package/dist/jobs/{sms-subscriber.service.js → msg91-sms-subscriber.service.js} +14 -12
  181. package/dist/jobs/msg91-sms-subscriber.service.js.map +1 -0
  182. package/dist/jobs/twilio-sms-subscriber.service.d.ts +3 -3
  183. package/dist/jobs/twilio-sms-subscriber.service.d.ts.map +1 -1
  184. package/dist/jobs/twilio-sms-subscriber.service.js +6 -4
  185. package/dist/jobs/twilio-sms-subscriber.service.js.map +1 -1
  186. package/dist/repository/media.repository.d.ts.map +1 -1
  187. package/dist/repository/media.repository.js +4 -0
  188. package/dist/repository/media.repository.js.map +1 -1
  189. package/dist/repository/model-sequence.repository.d.ts +14 -0
  190. package/dist/repository/model-sequence.repository.d.ts.map +1 -0
  191. package/dist/repository/model-sequence.repository.js +103 -0
  192. package/dist/repository/model-sequence.repository.js.map +1 -0
  193. package/dist/seeders/module-metadata-seeder.service.d.ts +7 -12
  194. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  195. package/dist/seeders/module-metadata-seeder.service.js +87 -27
  196. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  197. package/dist/seeders/seed-data/solid-core-metadata.json +373 -52
  198. package/dist/seeders/system-fields-seeder.service.d.ts +1 -0
  199. package/dist/seeders/system-fields-seeder.service.d.ts.map +1 -1
  200. package/dist/seeders/system-fields-seeder.service.js +11 -2
  201. package/dist/seeders/system-fields-seeder.service.js.map +1 -1
  202. package/dist/seeders/user-seeder.service.d.ts.map +1 -1
  203. package/dist/seeders/user-seeder.service.js +5 -4
  204. package/dist/seeders/user-seeder.service.js.map +1 -1
  205. package/dist/services/action-metadata.service.d.ts.map +1 -1
  206. package/dist/services/action-metadata.service.js +1 -0
  207. package/dist/services/action-metadata.service.js.map +1 -1
  208. package/dist/services/ai-interaction.service.d.ts.map +1 -1
  209. package/dist/services/ai-interaction.service.js +1 -0
  210. package/dist/services/ai-interaction.service.js.map +1 -1
  211. package/dist/services/authentication.service.d.ts +6 -3
  212. package/dist/services/authentication.service.d.ts.map +1 -1
  213. package/dist/services/authentication.service.js +70 -27
  214. package/dist/services/authentication.service.js.map +1 -1
  215. package/dist/services/chatter-message-details.service.d.ts.map +1 -1
  216. package/dist/services/chatter-message-details.service.js +1 -0
  217. package/dist/services/chatter-message-details.service.js.map +1 -1
  218. package/dist/services/chatter-message.service.d.ts.map +1 -1
  219. package/dist/services/chatter-message.service.js +7 -3
  220. package/dist/services/chatter-message.service.js.map +1 -1
  221. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js +7 -5
  222. package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js.map +1 -1
  223. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts +15 -0
  224. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -0
  225. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +72 -0
  226. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -0
  227. package/dist/services/crud-helper.service.d.ts +23 -6
  228. package/dist/services/crud-helper.service.d.ts.map +1 -1
  229. package/dist/services/crud-helper.service.js +257 -45
  230. package/dist/services/crud-helper.service.js.map +1 -1
  231. package/dist/services/crud.service.d.ts +4 -3
  232. package/dist/services/crud.service.d.ts.map +1 -1
  233. package/dist/services/crud.service.js +53 -24
  234. package/dist/services/crud.service.js.map +1 -1
  235. package/dist/services/database/database-bootstrap.service.d.ts +12 -0
  236. package/dist/services/database/database-bootstrap.service.d.ts.map +1 -0
  237. package/dist/services/database/database-bootstrap.service.js +115 -0
  238. package/dist/services/database/database-bootstrap.service.js.map +1 -0
  239. package/dist/services/email-template.service.d.ts +7 -7
  240. package/dist/services/email-template.service.d.ts.map +1 -1
  241. package/dist/services/email-template.service.js +8 -7
  242. package/dist/services/email-template.service.js.map +1 -1
  243. package/dist/services/excel.service.d.ts +11 -0
  244. package/dist/services/excel.service.d.ts.map +1 -1
  245. package/dist/services/excel.service.js +104 -0
  246. package/dist/services/excel.service.js.map +1 -1
  247. package/dist/services/field-metadata.service.d.ts +4 -1
  248. package/dist/services/field-metadata.service.d.ts.map +1 -1
  249. package/dist/services/field-metadata.service.js +35 -30
  250. package/dist/services/field-metadata.service.js.map +1 -1
  251. package/dist/services/file.service.d.ts +1 -0
  252. package/dist/services/file.service.d.ts.map +1 -1
  253. package/dist/services/file.service.js +9 -0
  254. package/dist/services/file.service.js.map +1 -1
  255. package/dist/services/fixtures.service.d.ts +13 -0
  256. package/dist/services/fixtures.service.d.ts.map +1 -0
  257. package/dist/services/fixtures.service.js +95 -0
  258. package/dist/services/fixtures.service.js.map +1 -0
  259. package/dist/services/genai/ingest-metadata.service.d.ts.map +1 -1
  260. package/dist/services/genai/ingest-metadata.service.js +1 -1
  261. package/dist/services/genai/ingest-metadata.service.js.map +1 -1
  262. package/dist/services/import-transaction-error-log.service.d.ts.map +1 -1
  263. package/dist/services/import-transaction-error-log.service.js +1 -0
  264. package/dist/services/import-transaction-error-log.service.js.map +1 -1
  265. package/dist/services/import-transaction.service.d.ts.map +1 -1
  266. package/dist/services/import-transaction.service.js +7 -1
  267. package/dist/services/import-transaction.service.js.map +1 -1
  268. package/dist/services/list-of-values.service.d.ts +2 -2
  269. package/dist/services/list-of-values.service.d.ts.map +1 -1
  270. package/dist/services/list-of-values.service.js +2 -1
  271. package/dist/services/list-of-values.service.js.map +1 -1
  272. package/dist/services/locale.service.d.ts.map +1 -1
  273. package/dist/services/locale.service.js +1 -0
  274. package/dist/services/locale.service.js.map +1 -1
  275. package/dist/services/mail/smtp-email.service.js +0 -1
  276. package/dist/services/mail/smtp-email.service.js.map +1 -1
  277. package/dist/services/media.service.d.ts +3 -3
  278. package/dist/services/media.service.d.ts.map +1 -1
  279. package/dist/services/media.service.js +6 -4
  280. package/dist/services/media.service.js.map +1 -1
  281. package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts.map +1 -1
  282. package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +17 -6
  283. package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
  284. package/dist/services/mediaStorageProviders/file-storage-provider.d.ts.map +1 -1
  285. package/dist/services/mediaStorageProviders/file-storage-provider.js +0 -13
  286. package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
  287. package/dist/services/menu-item-metadata.service.d.ts.map +1 -1
  288. package/dist/services/menu-item-metadata.service.js +4 -0
  289. package/dist/services/menu-item-metadata.service.js.map +1 -1
  290. package/dist/services/model-metadata.service.d.ts +28 -1
  291. package/dist/services/model-metadata.service.d.ts.map +1 -1
  292. package/dist/services/model-metadata.service.js +111 -44
  293. package/dist/services/model-metadata.service.js.map +1 -1
  294. package/dist/services/model-sequence.service.d.ts +23 -0
  295. package/dist/services/model-sequence.service.d.ts.map +1 -0
  296. package/dist/services/model-sequence.service.js +55 -0
  297. package/dist/services/model-sequence.service.js.map +1 -0
  298. package/dist/services/module-metadata.service.d.ts +1 -0
  299. package/dist/services/module-metadata.service.d.ts.map +1 -1
  300. package/dist/services/module-metadata.service.js +35 -1
  301. package/dist/services/module-metadata.service.js.map +1 -1
  302. package/dist/services/permission-metadata.service.d.ts +5 -5
  303. package/dist/services/permission-metadata.service.d.ts.map +1 -1
  304. package/dist/services/permission-metadata.service.js +6 -5
  305. package/dist/services/permission-metadata.service.js.map +1 -1
  306. package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
  307. package/dist/services/queues/database-subscriber.service.js +2 -1
  308. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  309. package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
  310. package/dist/services/queues/rabbitmq-subscriber.service.js +2 -2
  311. package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
  312. package/dist/services/role-metadata.service.d.ts.map +1 -1
  313. package/dist/services/role-metadata.service.js +1 -0
  314. package/dist/services/role-metadata.service.js.map +1 -1
  315. package/dist/services/scheduled-job.service.d.ts +6 -6
  316. package/dist/services/scheduled-job.service.d.ts.map +1 -1
  317. package/dist/services/scheduled-job.service.js +8 -8
  318. package/dist/services/scheduled-job.service.js.map +1 -1
  319. package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
  320. package/dist/services/scheduled-jobs/scheduler.service.js +4 -0
  321. package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
  322. package/dist/services/security-rule.service.d.ts.map +1 -1
  323. package/dist/services/security-rule.service.js +1 -0
  324. package/dist/services/security-rule.service.js.map +1 -1
  325. package/dist/services/selection-providers/list-of-models-selection-provider.service.d.ts.map +1 -1
  326. package/dist/services/selection-providers/list-of-models-selection-provider.service.js +4 -0
  327. package/dist/services/selection-providers/list-of-models-selection-provider.service.js.map +1 -1
  328. package/dist/services/setting.service.d.ts +7 -5
  329. package/dist/services/setting.service.d.ts.map +1 -1
  330. package/dist/services/setting.service.js +28 -48
  331. package/dist/services/setting.service.js.map +1 -1
  332. package/dist/services/sms/Msg91BaseSMSService.js +6 -6
  333. package/dist/services/sms/Msg91BaseSMSService.js.map +1 -1
  334. package/dist/services/sms/Msg91OTPService.d.ts.map +1 -1
  335. package/dist/services/sms/Msg91OTPService.js +3 -1
  336. package/dist/services/sms/Msg91OTPService.js.map +1 -1
  337. package/dist/services/sms/Msg91SMSService.d.ts.map +1 -1
  338. package/dist/services/sms/Msg91SMSService.js +3 -1
  339. package/dist/services/sms/Msg91SMSService.js.map +1 -1
  340. package/dist/services/sms/TwilioSMSService.d.ts.map +1 -1
  341. package/dist/services/sms/TwilioSMSService.js +2 -0
  342. package/dist/services/sms/TwilioSMSService.js.map +1 -1
  343. package/dist/services/sms-template.service.d.ts +7 -7
  344. package/dist/services/sms-template.service.d.ts.map +1 -1
  345. package/dist/services/sms-template.service.js +8 -7
  346. package/dist/services/sms-template.service.js.map +1 -1
  347. package/dist/services/solid-introspect.service.d.ts +5 -13
  348. package/dist/services/solid-introspect.service.d.ts.map +1 -1
  349. package/dist/services/solid-introspect.service.js +18 -22
  350. package/dist/services/solid-introspect.service.js.map +1 -1
  351. package/dist/services/solid-ts-morph.service.js +2 -2
  352. package/dist/services/solid-ts-morph.service.js.map +1 -1
  353. package/dist/services/user-activity-history.service.d.ts.map +1 -1
  354. package/dist/services/user-activity-history.service.js +1 -0
  355. package/dist/services/user-activity-history.service.js.map +1 -1
  356. package/dist/services/user-view-metadata.service.d.ts.map +1 -1
  357. package/dist/services/user-view-metadata.service.js +3 -2
  358. package/dist/services/user-view-metadata.service.js.map +1 -1
  359. package/dist/services/user.service.d.ts.map +1 -1
  360. package/dist/services/user.service.js +1 -0
  361. package/dist/services/user.service.js.map +1 -1
  362. package/dist/services/view-metadata.service.d.ts +1 -1
  363. package/dist/services/view-metadata.service.d.ts.map +1 -1
  364. package/dist/services/view-metadata.service.js +3 -1
  365. package/dist/services/view-metadata.service.js.map +1 -1
  366. package/dist/solid-core-cli-db.module.d.ts.map +1 -1
  367. package/dist/solid-core-cli-db.module.js +5 -2
  368. package/dist/solid-core-cli-db.module.js.map +1 -1
  369. package/dist/solid-core-cli.module.js +1 -1
  370. package/dist/solid-core-cli.module.js.map +1 -1
  371. package/dist/solid-core.module.d.ts.map +1 -1
  372. package/dist/solid-core.module.js +40 -13
  373. package/dist/solid-core.module.js.map +1 -1
  374. package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
  375. package/dist/subscribers/audit.subscriber.js +5 -1
  376. package/dist/subscribers/audit.subscriber.js.map +1 -1
  377. package/dist/subscribers/computed-entity-field.subscriber.d.ts +4 -2
  378. package/dist/subscribers/computed-entity-field.subscriber.d.ts.map +1 -1
  379. package/dist/subscribers/computed-entity-field.subscriber.js +53 -12
  380. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  381. package/dist/subscribers/scheduled-job.subscriber.d.ts.map +1 -1
  382. package/dist/subscribers/scheduled-job.subscriber.js +1 -1
  383. package/dist/subscribers/scheduled-job.subscriber.js.map +1 -1
  384. package/dist/transformers/typeorm/local-date-time-transformer.d.ts +5 -0
  385. package/dist/transformers/typeorm/local-date-time-transformer.d.ts.map +1 -0
  386. package/dist/transformers/typeorm/local-date-time-transformer.js +48 -0
  387. package/dist/transformers/typeorm/local-date-time-transformer.js.map +1 -0
  388. package/dist/tsconfig.tsbuildinfo +1 -1
  389. package/docs/grouping-enhancements.md +89 -0
  390. package/package.json +1 -1
  391. package/src/commands/fixtures/fixtures-setup.command.ts +44 -0
  392. package/src/commands/fixtures/fixtures-tear-down.command.ts +45 -0
  393. package/src/commands/refresh-model.command.ts +3 -1
  394. package/src/config/cache.options.ts +6 -3
  395. package/src/config/iam.config.ts +2 -1
  396. package/src/constants/error-messages.ts +7 -1
  397. package/src/controllers/model-metadata.controller.ts +21 -1
  398. package/src/controllers/model-sequence.controller.ts +93 -0
  399. package/src/controllers/setting.controller.ts +62 -54
  400. package/src/decorators/sms-provider.decorator.ts +7 -0
  401. package/src/dtos/basic-filters.dto.ts +6 -1
  402. package/src/dtos/basic-group-filters.dto.ts +23 -0
  403. package/src/dtos/create-field-metadata.dto.ts +1 -1
  404. package/src/dtos/create-model-sequence.dto.ts +51 -0
  405. package/src/dtos/create-role-metadata.dto.ts +16 -3
  406. package/src/dtos/get-mcp-url.dto.ts +13 -0
  407. package/src/dtos/navigation.dto.ts +14 -0
  408. package/src/dtos/resolve-s3-url.dto.ts +9 -11
  409. package/src/dtos/sign-in.dto.ts +3 -3
  410. package/src/dtos/update-model-sequence.dto.ts +53 -0
  411. package/src/entities/common.entity.ts +8 -8
  412. package/src/entities/field-metadata.entity.ts +1 -1
  413. package/src/entities/legacy-common.entity.ts +8 -6
  414. package/src/entities/model-metadata.entity.ts +1 -1
  415. package/src/entities/model-sequence.entity.ts +32 -0
  416. package/src/factories/mail.factory.ts +0 -1
  417. package/src/factories/sms.factory.ts +43 -0
  418. package/src/helpers/date.helper.ts +38 -9
  419. package/src/helpers/field-crud-managers/BigIntFieldCrudManager.ts +18 -5
  420. package/src/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.ts +9 -9
  421. package/src/helpers/field-crud-managers/ManyToOneRelationFieldCrudManager.ts +16 -8
  422. package/src/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.ts +9 -9
  423. package/src/helpers/model-metadata-helper.service.ts +6 -4
  424. package/src/helpers/module-metadata-helper.service.ts +18 -1
  425. package/src/helpers/module.helper.ts +40 -5
  426. package/src/helpers/solid-registry.ts +23 -0
  427. package/src/index.ts +12 -7
  428. package/src/jobs/computed-field-evaluation-subscriber.service.ts +15 -4
  429. package/src/jobs/database/{sms-publisher-database.service.ts → msg91-sms-publisher-database.service.ts} +2 -2
  430. package/src/jobs/database/{sms-subscriber-database.service.ts → msg91-sms-subscriber-database.service.ts} +9 -4
  431. package/src/jobs/database/otp-subscriber-database.service.ts +8 -2
  432. package/src/jobs/database/twilio-sms-subscriber-database.service.ts +5 -2
  433. package/src/jobs/{otp-publisher.service.ts → msg91-otp-publisher.service.ts} +2 -2
  434. package/src/jobs/{otp-subscriber.service.ts → msg91-otp-subscriber.service.ts} +10 -4
  435. package/src/jobs/{sms-publisher.service.ts → msg91-sms-publisher.service.ts} +2 -2
  436. package/src/jobs/{sms-subscriber.service.ts → msg91-sms-subscriber.service.ts} +9 -4
  437. package/src/jobs/twilio-sms-subscriber.service.ts +6 -2
  438. package/src/repository/media.repository.ts +3 -2
  439. package/src/repository/model-sequence.repository.ts +97 -0
  440. package/src/seeders/module-metadata-seeder.service.ts +133 -34
  441. package/src/seeders/seed-data/email-templates/email-on-signup.handlebars.html +155 -0
  442. package/src/seeders/seed-data/sms-templates/text-on-signup.handlebars.txt +10 -0
  443. package/src/seeders/seed-data/solid-core-metadata.json +374 -53
  444. package/src/seeders/system-fields-seeder.service.ts +6 -2
  445. package/src/seeders/user-seeder.service.ts +5 -4
  446. package/src/services/action-metadata.service.ts +3 -2
  447. package/src/services/ai-interaction.service.ts +2 -1
  448. package/src/services/authentication.service.ts +119 -24
  449. package/src/services/chatter-message-details.service.ts +2 -1
  450. package/src/services/chatter-message.service.ts +10 -4
  451. package/src/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.ts +9 -9
  452. package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +86 -0
  453. package/src/services/crud-helper.service.ts +287 -49
  454. package/src/services/crud.service.ts +95 -45
  455. package/src/services/database/database-bootstrap.service.ts +91 -0
  456. package/src/services/email-template.service.ts +11 -13
  457. package/src/services/excel.service.ts +152 -3
  458. package/src/services/field-metadata.service.ts +102 -55
  459. package/src/services/file.service.ts +9 -0
  460. package/src/services/fixtures.service.ts +108 -0
  461. package/src/services/genai/ingest-metadata.service.ts +4 -3
  462. package/src/services/import-transaction-error-log.service.ts +2 -1
  463. package/src/services/import-transaction.service.ts +8 -4
  464. package/src/services/list-of-values.service.ts +4 -4
  465. package/src/services/locale.service.ts +2 -1
  466. package/src/services/mail/smtp-email.service.ts +1 -1
  467. package/src/services/media.service.ts +10 -11
  468. package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +22 -7
  469. package/src/services/mediaStorageProviders/file-storage-provider.ts +18 -13
  470. package/src/services/menu-item-metadata.service.ts +6 -2
  471. package/src/services/model-metadata.service.ts +201 -44
  472. package/src/services/model-sequence.service.ts +33 -0
  473. package/src/services/module-metadata.service.ts +49 -2
  474. package/src/services/permission-metadata.service.ts +8 -9
  475. package/src/services/queues/database-subscriber.service.ts +3 -1
  476. package/src/services/queues/rabbitmq-subscriber.service.ts +4 -2
  477. package/src/services/role-metadata.service.ts +1 -0
  478. package/src/services/scheduled-job.service.ts +9 -9
  479. package/src/services/scheduled-jobs/scheduler.service.ts +5 -0
  480. package/src/services/security-rule.service.ts +1 -0
  481. package/src/services/selection-providers/list-of-models-selection-provider.service.ts +5 -2
  482. package/src/services/setting.service.ts +42 -55
  483. package/src/services/sms/Msg91BaseSMSService.ts +6 -6
  484. package/src/services/sms/Msg91OTPService.ts +3 -2
  485. package/src/services/sms/Msg91SMSService.ts +3 -1
  486. package/src/services/sms/TwilioSMSService.ts +3 -3
  487. package/src/services/sms-template.service.ts +11 -13
  488. package/src/services/solid-introspect.service.ts +28 -19
  489. package/src/services/solid-ts-morph.service.ts +2 -2
  490. package/src/services/user-activity-history.service.ts +3 -2
  491. package/src/services/user-view-metadata.service.ts +4 -3
  492. package/src/services/user.service.ts +2 -1
  493. package/src/services/view-metadata.service.ts +5 -4
  494. package/src/solid-core-cli-db.module.ts +5 -4
  495. package/src/solid-core-cli.module.ts +2 -2
  496. package/src/solid-core.module.ts +42 -13
  497. package/src/subscribers/audit.subscriber.ts +3 -2
  498. package/src/subscribers/computed-entity-field.subscriber.ts +60 -17
  499. package/src/subscribers/scheduled-job.subscriber.ts +9 -2
  500. package/src/transformers/typeorm/local-date-time-transformer.ts +55 -0
  501. package/dist/jobs/database/sms-publisher-database.service.d.ts.map +0 -1
  502. package/dist/jobs/database/sms-publisher-database.service.js.map +0 -1
  503. package/dist/jobs/database/sms-queue-database-options.d.ts.map +0 -1
  504. package/dist/jobs/database/sms-queue-database-options.js.map +0 -1
  505. package/dist/jobs/database/sms-subscriber-database.service.d.ts.map +0 -1
  506. package/dist/jobs/database/sms-subscriber-database.service.js.map +0 -1
  507. package/dist/jobs/otp-publisher.service.d.ts.map +0 -1
  508. package/dist/jobs/otp-publisher.service.js.map +0 -1
  509. package/dist/jobs/otp-queue-options.d.ts.map +0 -1
  510. package/dist/jobs/otp-queue-options.js.map +0 -1
  511. package/dist/jobs/otp-subscriber.service.d.ts.map +0 -1
  512. package/dist/jobs/otp-subscriber.service.js.map +0 -1
  513. package/dist/jobs/sms-publisher.service.d.ts.map +0 -1
  514. package/dist/jobs/sms-publisher.service.js.map +0 -1
  515. package/dist/jobs/sms-queue-options.d.ts.map +0 -1
  516. package/dist/jobs/sms-queue-options.js.map +0 -1
  517. package/dist/jobs/sms-subscriber.service.d.ts.map +0 -1
  518. package/dist/jobs/sms-subscriber.service.js.map +0 -1
  519. /package/sql/{mssql → default/mssql}/proc_CleanupModelMetadata.sql +0 -0
  520. /package/sql/{mssql → default/mssql}/proc_CleanupModuleMetadata.sql +0 -0
  521. /package/sql/{mssql/scratchpad.sql → default/mssql/scratchpad.sql.txt} +0 -0
  522. /package/sql/{postgres → default/postgres}/proc_CleanupModelMetadata.sql +0 -0
  523. /package/sql/{postgres → default/postgres}/proc_CleanupModuleMetadata.sql +0 -0
  524. /package/sql/{postgres/scratchpad.sql → default/postgres/scratchpad.sql.txt} +0 -0
  525. /package/src/jobs/database/{sms-queue-database-options.ts → msg91-sms-queue-database-options.ts} +0 -0
  526. /package/src/jobs/{otp-queue-options.ts → msg91-otp-queue-options.ts} +0 -0
  527. /package/src/jobs/{sms-queue-options.ts → msg91-sms-queue-options.ts} +0 -0
@@ -24,11 +24,20 @@ export class CrudHelperService {
24
24
  private orderOptions(sort: any[] = []) {
25
25
  const orderOptions = {};
26
26
  sort.forEach((s: string) => {
27
- const [field, order] = s.split(':');
28
- orderOptions[field] = order?.toUpperCase() ?? 'ASC';
29
- if (!['ASC', 'DESC'].includes(orderOptions[field])) {
27
+ const parts = s.split(':');
28
+ let order: string | undefined;
29
+ let field: string;
30
+ if (parts.length > 1) {
31
+ order = parts.pop();
32
+ field = parts.join(':');
33
+ } else {
34
+ field = parts[0];
35
+ }
36
+ const normalizedOrder = order ? order.toUpperCase() : 'ASC';
37
+ if (!['ASC', 'DESC'].includes(normalizedOrder)) {
30
38
  throw new Error(`Invalid sort order provided: ${order}`);
31
39
  }
40
+ orderOptions[field] = normalizedOrder;
32
41
  });
33
42
  return orderOptions;
34
43
  }
@@ -185,10 +194,12 @@ export class CrudHelperService {
185
194
  internationalisation?: boolean,
186
195
  draftPublishWorkflow?: boolean,
187
196
  moduleRef?: any,
188
- filterCombinator: FilterCombinator = FilterCombinator.AND
197
+ filterCombinator: FilterCombinator = FilterCombinator.AND,
198
+ applyPagination: boolean = true,
199
+ applySorting: boolean = true
189
200
  ): SelectQueryBuilder<any> { // TODO : Check how to pass a type to SelectQueryBuilder instead of any
190
201
  let { limit, offset, showSoftDeleted, filters } = basicFilterDto;
191
- const { fields, sort, groupBy, populate = [], populateMedia = [], locale, status } = basicFilterDto;
202
+ const { fields, sort, populate = [], populateMedia = [], locale, status } = basicFilterDto;
192
203
 
193
204
  // Normalize the fields, sort, groupBy and populate options i.e (since they can be either a string or an array of strings, when coming from the request)
194
205
  const normalizedFields = this.normalize(fields);
@@ -201,10 +212,6 @@ export class CrudHelperService {
201
212
  normalizedAndFilteredPopulateAttributes.push(...additionalPopulate.filter((relation) => !normalizedAndFilteredPopulateAttributes.includes(relation)));
202
213
 
203
214
  const normalizedSort = this.normalize(sort);
204
- const normalizedGroupBy = this.normalize(groupBy);
205
- if (normalizedGroupBy.length > 1) {
206
- throw new Error(ERROR_MESSAGES.GROUP_BY_LIMIT);
207
- }
208
215
 
209
216
  // Depending upon the populate option, apply the join clause
210
217
  if (normalizedAndFilteredPopulateAttributes && normalizedAndFilteredPopulateAttributes.length) {
@@ -255,7 +262,7 @@ export class CrudHelperService {
255
262
  }
256
263
 
257
264
  // Depending upon the order option, apply the order by clause
258
- if (normalizedSort && normalizedSort.length) {
265
+ if (applySorting && normalizedSort && normalizedSort.length) {
259
266
  const orderOptions = this.orderOptions(normalizedSort);
260
267
  if (orderOptions) {
261
268
  const orderOptionKeys = Object.keys(orderOptions) as Array<keyof typeof orderOptions>;
@@ -276,16 +283,11 @@ export class CrudHelperService {
276
283
  qb.where(`${entityAlias}.deletedAt IS NOT NULL`);
277
284
  }
278
285
 
279
- // Apply the group by options
280
- if (normalizedGroupBy && normalizedGroupBy.length) {
281
- normalizedGroupBy.forEach((field: string) => {
282
- qb.addGroupBy(`${entityAlias}.${field}`);
283
- });
284
- }
285
-
286
286
  // Apply the pagination options & handle the case when the query has joins
287
- if (limit) this.hasJoins(qb) ? qb.take(limit) : qb.limit(limit);
288
- if (offset) this.hasJoins(qb) ? qb.skip(offset) : qb.offset(offset);
287
+ if (applyPagination) {
288
+ if (limit) this.hasJoins(qb) ? qb.take(limit) : qb.limit(limit);
289
+ if (offset) this.hasJoins(qb) ? qb.skip(offset) : qb.offset(offset);
290
+ }
289
291
  return qb;
290
292
  }
291
293
 
@@ -307,6 +309,185 @@ export class CrudHelperService {
307
309
  return qb;
308
310
  }
309
311
 
312
+ private sanitizeAlias(alias: string) {
313
+ return alias.replace(/[^a-zA-Z0-9_]/g, '_');
314
+ }
315
+
316
+ private isAliasJoined(queryBuilder: SelectQueryBuilder<any>, alias: string): boolean {
317
+ return queryBuilder.expressionMap.joinAttributes.some(join => join.alias?.name === alias);
318
+ }
319
+
320
+ private getExistingJoinAlias(qb: SelectQueryBuilder<any>, joinProperty: string): string | undefined {
321
+ const existingJoin = qb.expressionMap.joinAttributes.find(join => join.entityOrProperty === joinProperty);
322
+ return existingJoin?.alias?.name;
323
+ }
324
+
325
+ private ensureRelationPathJoined(qb: SelectQueryBuilder<any>, rootAlias: string, pathParts: string[]) {
326
+ const mainAlias =
327
+ qb.expressionMap?.mainAlias?.name ||
328
+ qb.expressionMap?.aliases?.find(a => a.metadata)?.name ||
329
+ qb.expressionMap?.aliases?.[0]?.name;
330
+ let parentAlias = mainAlias || rootAlias;
331
+ for (let i = 0; i < pathParts.length - 1; i++) {
332
+ const part = pathParts[i];
333
+ const joinProperty = `${parentAlias}.${part}`;
334
+ const existingAlias = this.getExistingJoinAlias(qb, joinProperty);
335
+ const joinAlias = existingAlias ?? this.sanitizeAlias(`${parentAlias}_${part}`);
336
+ if (!existingAlias && !this.isRelationJoined(qb, joinProperty) && !this.isAliasJoined(qb, joinAlias)) {
337
+ qb.leftJoin(joinProperty, joinAlias);
338
+ }
339
+ parentAlias = joinAlias;
340
+ }
341
+ return { alias: parentAlias, property: pathParts[pathParts.length - 1] };
342
+ }
343
+
344
+ private getDriver(qb: SelectQueryBuilder<any>) {
345
+ return qb.connection.options.type as string;
346
+ }
347
+
348
+ private buildDateGranularityExpression(driver: string, columnExpr: string, granularity: string) {
349
+ switch (driver) {
350
+ case 'postgres':
351
+ case 'cockroachdb':
352
+ return `DATE_TRUNC('${granularity}', ${columnExpr})`;
353
+ case 'mysql':
354
+ case 'mariadb':
355
+ switch (granularity) {
356
+ case 'day': return `DATE(${columnExpr})`;
357
+ case 'week': return `STR_TO_DATE(DATE_FORMAT(${columnExpr}, '%x-%v-1'), '%x-%v-%w')`;
358
+ case 'month': return `DATE_FORMAT(${columnExpr}, '%Y-%m-01')`;
359
+ case 'year': return `DATE_FORMAT(${columnExpr}, '%Y-01-01')`;
360
+ default: throw new Error(`Unsupported granularity ${granularity} for driver ${driver}`);
361
+ }
362
+ case 'mssql':
363
+ case 'sqlserver':
364
+ switch (granularity) {
365
+ case 'day': return `CONVERT(date, ${columnExpr})`;
366
+ case 'week': return `DATEADD(week, DATEDIFF(week, 0, ${columnExpr}), 0)`;
367
+ case 'month': return `DATEFROMPARTS(YEAR(${columnExpr}), MONTH(${columnExpr}), 1)`;
368
+ case 'year': return `DATEFROMPARTS(YEAR(${columnExpr}), 1, 1)`;
369
+ default: throw new Error(`Unsupported granularity ${granularity} for driver ${driver}`);
370
+ }
371
+ default:
372
+ throw new Error(`Granularity not supported for driver ${driver}`);
373
+ }
374
+ }
375
+
376
+ private buildGroupByExpression(qb: SelectQueryBuilder<any>, rootAlias: string, field: string) {
377
+ const parts = field.split(':');
378
+ const rawField = parts[0];
379
+ const granularity = parts[1];
380
+ const format = parts[2];
381
+ const pathParts = rawField.split('.');
382
+ const { alias, property } = this.ensureRelationPathJoined(qb, rootAlias, pathParts);
383
+ const columnExpr = `${alias}.${property}`;
384
+ const groupExpr = granularity ? this.buildDateGranularityExpression(this.getDriver(qb), columnExpr, granularity) : columnExpr;
385
+ const selectAlias = this.sanitizeAlias(`${rawField.replace(/\./g, '_')}${granularity ? '_' + granularity : ''}`);
386
+ return { groupExpr, selectAlias, sourceKey: field, format };
387
+ }
388
+
389
+ applyGroupBySelections(
390
+ qb: SelectQueryBuilder<any>,
391
+ groupBy: string[],
392
+ entityAlias: string
393
+ ) {
394
+ const aliasMap: Record<string, string> = {};
395
+ const formatMap: Record<string, string | undefined> = {};
396
+ const expressionMap: Record<string, string> = {};
397
+ qb.select([]);
398
+ groupBy.forEach((field) => {
399
+ const { groupExpr, selectAlias, sourceKey, format } = this.buildGroupByExpression(qb, entityAlias, field);
400
+ qb.addSelect(groupExpr, selectAlias);
401
+ qb.addGroupBy(groupExpr);
402
+ aliasMap[sourceKey] = selectAlias;
403
+ formatMap[selectAlias] = format;
404
+ expressionMap[selectAlias] = groupExpr;
405
+ });
406
+ return { aliasMap, formatMap, expressionMap };
407
+ }
408
+
409
+ private buildAggregateExpression(qb: SelectQueryBuilder<any>, rootAlias: string, aggregate: string) {
410
+ const [rawField, rawFn] = aggregate.split(':');
411
+ const fn = (rawFn || 'count').toLowerCase();
412
+ if ((!rawField || rawField.toLowerCase() === 'count') && fn === 'count') {
413
+ return { expression: 'COUNT(*)', selectAlias: 'count' };
414
+ }
415
+ if (!rawField) throw new Error(`Invalid aggregate specification: ${aggregate}`);
416
+ const pathParts = rawField.split('.');
417
+ const { alias, property } = this.ensureRelationPathJoined(qb, rootAlias, pathParts);
418
+ const columnExpr = `${alias}.${property}`;
419
+ const selectAlias = this.sanitizeAlias(`${rawField.replace(/\./g, '_')}_${fn}`);
420
+ let expression = '';
421
+ switch (fn) {
422
+ case 'count': expression = `COUNT(${columnExpr})`; break;
423
+ case 'count_distinct': expression = `COUNT(DISTINCT ${columnExpr})`; break;
424
+ case 'sum': expression = `SUM(${columnExpr})`; break;
425
+ case 'avg': expression = `AVG(${columnExpr})`; break;
426
+ case 'min': expression = `MIN(${columnExpr})`; break;
427
+ case 'max': expression = `MAX(${columnExpr})`; break;
428
+ default: throw new Error(`Unsupported aggregate function ${fn}`);
429
+ }
430
+ return { expression, selectAlias, sourceKey: aggregate };
431
+ }
432
+
433
+ applyAggregates(
434
+ qb: SelectQueryBuilder<any>,
435
+ aggregates: string[] | undefined,
436
+ entityAlias: string
437
+ ) {
438
+ const aggregateList = this.normalize(aggregates);
439
+ const aggregateAliasMap: Record<string, string> = {};
440
+ if (!aggregateList.length) {
441
+ qb.addSelect('COUNT(*)', 'count');
442
+ aggregateAliasMap['count'] = 'count';
443
+ return aggregateAliasMap;
444
+ }
445
+ aggregateList.forEach((agg) => {
446
+ const { expression, selectAlias, sourceKey } = this.buildAggregateExpression(qb, entityAlias, agg);
447
+ qb.addSelect(expression, selectAlias);
448
+ aggregateAliasMap[sourceKey] = selectAlias;
449
+ });
450
+ return aggregateAliasMap;
451
+ }
452
+
453
+ applyGroupSortingAndPagination(
454
+ qb: SelectQueryBuilder<any>,
455
+ sort: string[] | undefined,
456
+ aliasMap: Record<string, string>,
457
+ limit?: number,
458
+ offset?: number
459
+ ) {
460
+ const normalizedSort = this.normalize(sort);
461
+ if (normalizedSort.length) {
462
+ const orderOptions = this.orderOptions(normalizedSort);
463
+ const orderOptionKeys = Object.keys(orderOptions) as Array<keyof typeof orderOptions>;
464
+ orderOptionKeys.forEach((key) => {
465
+ const resolvedKey = aliasMap[key] || key as string;
466
+ const value = orderOptions[key] as 'ASC' | 'DESC';
467
+ qb.addOrderBy(`"${resolvedKey}"`, value);
468
+ });
469
+ }
470
+ const hasLimit = limit !== undefined && limit !== null;
471
+ const hasOffset = offset !== undefined && offset !== null;
472
+
473
+ // Use both take/skip and limit/offset to ensure pagination is applied even when joins are present.
474
+ if (hasLimit) {
475
+ qb.take(limit);
476
+ qb.limit(limit);
477
+ }
478
+ if (hasOffset) {
479
+ qb.skip(offset);
480
+ qb.offset(offset);
481
+ }
482
+ }
483
+
484
+ async countGroups(qb: SelectQueryBuilder<any>) {
485
+ const clone = qb.clone();
486
+ clone.limit(undefined).offset(undefined).take(undefined).skip(undefined);
487
+ const rows = await clone.getRawMany();
488
+ return rows.length;
489
+ }
490
+
310
491
  private buildJoinQueryForRelation(qb: SelectQueryBuilder<any>, entityAlias: string, relation: string) {
311
492
  // We split the joinProperty to get the alias of the entity we are joining
312
493
  const relationParts = relation.split('.');
@@ -341,46 +522,109 @@ export class CrudHelperService {
341
522
  return field.includes('(');
342
523
  }
343
524
 
344
- isAggregateFieldKey(key: string, alias: string): boolean {
345
- return !key.startsWith(`${alias}_`)
525
+ isAggregateFieldKey(key: string, aggregateAliases: Set<string>): boolean {
526
+ return aggregateAliases.has(key);
346
527
  }
347
528
 
348
529
  getFieldFromQueryFieldKey(queryFieldKey: string, alias: string): string {
349
530
  return queryFieldKey.replace(`${alias}_`, '');
350
531
  }
351
532
 
352
- buildGroupByRecordsQuery(qb: SelectQueryBuilder<any>, group: any, alias: string): SelectQueryBuilder<any> {
533
+ buildGroupByRecordsQuery(
534
+ qb: SelectQueryBuilder<any>,
535
+ group: any,
536
+ alias: string,
537
+ groupAliasMap: Record<string, string> = {},
538
+ aggregateAliasMap: Record<string, string> = {},
539
+ groupExpressionMap: Record<string, string> = {}
540
+ ): SelectQueryBuilder<any> {
541
+ const rootAlias = qb.expressionMap?.mainAlias?.name
542
+ ?? qb.expressionMap?.aliases?.find(a => a.metadata)?.name
543
+ ?? qb.expressionMap?.aliases?.[0]?.name
544
+ ?? (qb as any).alias
545
+ ?? alias;
353
546
  qb.andWhere(new Brackets(qb => {
547
+ const aggregateAliasSet = new Set(Object.values(aggregateAliasMap));
548
+ const reverseGroupAliasMap = Object.entries(groupAliasMap).reduce((acc, [sourceKey, aliasKey]) => {
549
+ acc[aliasKey] = sourceKey;
550
+ return acc;
551
+ }, {} as Record<string, string>);
354
552
  for (const key in group) {
355
- if (group.hasOwnProperty(key) && !this.isAggregateFieldKey(key, alias)) {
553
+ if (group.hasOwnProperty(key) && !this.isAggregateFieldKey(key, aggregateAliasSet)) {
356
554
  const value = group[key];
357
- const field = this.getFieldFromQueryFieldKey(key, alias);
358
- qb.andWhere(`${alias}.${field} = :${field}`, { [field]: value });
555
+ const sourceField = reverseGroupAliasMap[key] || key;
556
+ const cleanedField = sourceField.split(':')[0];
557
+ const pathParts = cleanedField.split('.');
558
+ const { alias: resolvedAlias, property } = this.ensureRelationPathJoined(qb as any, rootAlias, pathParts);
559
+ const paramKey = this.sanitizeAlias(`${resolvedAlias}_${property}_${key}`);
560
+ const expr = (sourceField.includes(':') && groupExpressionMap[key])
561
+ ? groupExpressionMap[key]
562
+ : `${resolvedAlias}.${property}`;
563
+ qb.andWhere(`${expr} = :${paramKey}`, { [paramKey]: value });
359
564
  }
360
565
  }
361
566
  }));
362
567
  return qb;
363
568
  }
364
569
 
365
- getGroupName(group: any, alias: string): string {
366
- return Object.keys(group)
367
- .filter(key => !this.isAggregateFieldKey(key, alias))
368
- .map(key => group[key])
369
- .join('_');
570
+ private formatGroupValue(value: any, format?: string) {
571
+ if (!format) return value;
572
+ if (value === null || value === undefined) return value;
573
+ const dateVal = value instanceof Date ? value : new Date(value);
574
+ if (isNaN(dateVal.getTime())) return value;
575
+ switch (format) {
576
+ case 'MMM':
577
+ return dateVal.toLocaleString('en', { month: 'short' });
578
+ case 'MMMM':
579
+ return dateVal.toLocaleString('en', { month: 'long' });
580
+ case 'YYYY':
581
+ return dateVal.getFullYear();
582
+ case 'YYYY-MM':
583
+ return `${dateVal.getFullYear()}-${String(dateVal.getMonth() + 1).padStart(2, '0')}`;
584
+ case 'YYYY-MM-DD':
585
+ return `${dateVal.getFullYear()}-${String(dateVal.getMonth() + 1).padStart(2, '0')}-${String(dateVal.getDate()).padStart(2, '0')}`;
586
+ default:
587
+ return value;
588
+ }
370
589
  }
371
590
 
372
- createGroupRecords(group: any, alias: string, groupData: any) {
373
- const groupName = this.getGroupName(group, alias);
591
+ getGroupName(
592
+ group: any,
593
+ aggregateAliases: Set<string>,
594
+ groupByFields: string[],
595
+ groupAliasMap: Record<string, string>,
596
+ groupFormatMap: Record<string, string | undefined>
597
+ ): string {
598
+ const orderedValues = groupByFields
599
+ .map(field => {
600
+ const alias = groupAliasMap[field] ?? this.sanitizeAlias(field.replace(/\./g, '_'));
601
+ const rawVal = group[alias] ?? group[field] ?? group[field.replace(/\./g, '_')];
602
+ return this.formatGroupValue(rawVal, groupFormatMap[alias]);
603
+ })
604
+ .filter(v => v !== undefined && v !== null);
605
+
606
+ if (orderedValues.length === 0) {
607
+ return Object.keys(group)
608
+ .filter(key => !this.isAggregateFieldKey(key, aggregateAliases))
609
+ .map(key => group[key])
610
+ .join('_');
611
+ }
612
+
613
+ return orderedValues.join('_');
614
+ }
615
+
616
+ createGroupRecords(group: any, aggregateAliases: Set<string>, groupData: any, groupByFields: string[], groupAliasMap: Record<string, string>, groupFormatMap: Record<string, string | undefined>) {
617
+ const groupName = this.getGroupName(group, aggregateAliases, groupByFields, groupAliasMap, groupFormatMap);
374
618
  return {
375
619
  groupName,
376
620
  groupData
377
621
  }
378
622
  }
379
- createGroupMeta(group: any, alias: string) {
380
- const groupName = this.getGroupName(group, alias);
623
+ createGroupMeta(group: any, aggregateAliases: Set<string>, groupByFields: string[], groupAliasMap: Record<string, string>, groupFormatMap: Record<string, string | undefined>) {
624
+ const groupName = this.getGroupName(group, aggregateAliases, groupByFields, groupAliasMap, groupFormatMap);
381
625
  const groupAggregateValues = {}
382
626
  for (const key in group) {
383
- if (group.hasOwnProperty(key) && this.isAggregateFieldKey(key, alias)) {
627
+ if (group.hasOwnProperty(key) && this.isAggregateFieldKey(key, aggregateAliases)) {
384
628
  const value = group[key];
385
629
  groupAggregateValues[key] = value;
386
630
  }
@@ -393,27 +637,21 @@ export class CrudHelperService {
393
637
 
394
638
  async countGroupedRecords(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string) { //TODO : Check how to pass a type to SelectQueryBuilder instead of any
395
639
  const { limit, offset, ...rest } = basicFilterDto;
396
-
397
640
  const filteredDto = { ...rest, limit: undefined, offset: undefined };
398
641
 
399
- const filteredQB = this.buildFilterQuery(qb, filteredDto as BasicFilterDto, entityAlias);
642
+ const filteredQB = this.buildFilterQuery(qb, filteredDto as BasicFilterDto, entityAlias, undefined, undefined, undefined, FilterCombinator.AND, false, false);
400
643
 
401
- // Select only the group field and count distinct rows
402
- const groupByField = filteredDto.groupBy;
644
+ const groupByFields = this.normalize(filteredDto.groupBy);
403
645
 
404
- if (!groupByField || (Array.isArray(groupByField) && groupByField.length !== 1)) {
646
+ if (!groupByFields || groupByFields.length === 0) {
405
647
  throw new Error(ERROR_MESSAGES.INVALID_GROUP_BY_COUNT);
406
648
  }
407
649
 
408
- const field = Array.isArray(groupByField) ? groupByField[0] : groupByField;
409
- const rawResults = await filteredQB
410
- .select([]) // Remove prior select fields
411
- .addSelect(`${entityAlias}.${field}`, 'groupField')
412
- .groupBy(`${entityAlias}.${field}`)
413
- .limit(undefined) // Important: prevent LIMIT 1 from propagating
414
- .offset(undefined)
415
- .getRawMany();
650
+ this.applyGroupBySelections(filteredQB, groupByFields, entityAlias);
651
+ this.applyAggregates(filteredQB, ['count'], entityAlias);
652
+ filteredQB.limit(undefined).offset(undefined).take(undefined).skip(undefined);
416
653
 
654
+ const rawResults = await filteredQB.getRawMany();
417
655
  return rawResults.length;
418
656
  }
419
657
 
@@ -465,4 +703,4 @@ export class CrudHelperService {
465
703
 
466
704
 
467
705
 
468
- }
706
+ }