@solidxai/core 0.1.6-beta.9 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (311) hide show
  1. package/.claude/settings.local.json +15 -0
  2. package/CHANGELOG.md +71 -0
  3. package/dist/controllers/dashboard-layout.controller.d.ts +47 -0
  4. package/dist/controllers/dashboard-layout.controller.d.ts.map +1 -0
  5. package/dist/controllers/dashboard-layout.controller.js +204 -0
  6. package/dist/controllers/dashboard-layout.controller.js.map +1 -0
  7. package/dist/dtos/create-dashboard-layout.dto.d.ts +8 -0
  8. package/dist/dtos/create-dashboard-layout.dto.d.ts.map +1 -0
  9. package/dist/dtos/create-dashboard-layout.dto.js +53 -0
  10. package/dist/dtos/create-dashboard-layout.dto.js.map +1 -0
  11. package/dist/dtos/create-dashboard-variable.dto.d.ts +1 -0
  12. package/dist/dtos/create-dashboard-variable.dto.d.ts.map +1 -1
  13. package/dist/dtos/create-dashboard-variable.dto.js +7 -1
  14. package/dist/dtos/create-dashboard-variable.dto.js.map +1 -1
  15. package/dist/dtos/update-dashboard-layout.dto.d.ts +8 -0
  16. package/dist/dtos/update-dashboard-layout.dto.d.ts.map +1 -0
  17. package/dist/dtos/update-dashboard-layout.dto.js +53 -0
  18. package/dist/dtos/update-dashboard-layout.dto.js.map +1 -0
  19. package/dist/dtos/update-dashboard-variable.dto.d.ts +1 -0
  20. package/dist/dtos/update-dashboard-variable.dto.d.ts.map +1 -1
  21. package/dist/dtos/update-dashboard-variable.dto.js +7 -1
  22. package/dist/dtos/update-dashboard-variable.dto.js.map +1 -1
  23. package/dist/entities/action-metadata.entity.d.ts.map +1 -1
  24. package/dist/entities/action-metadata.entity.js.map +1 -1
  25. package/dist/entities/ai-interaction.entity.d.ts.map +1 -1
  26. package/dist/entities/ai-interaction.entity.js +5 -4
  27. package/dist/entities/ai-interaction.entity.js.map +1 -1
  28. package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
  29. package/dist/entities/chatter-message-details.entity.js +4 -3
  30. package/dist/entities/chatter-message-details.entity.js.map +1 -1
  31. package/dist/entities/chatter-message.entity.d.ts.map +1 -1
  32. package/dist/entities/chatter-message.entity.js +4 -3
  33. package/dist/entities/chatter-message.entity.js.map +1 -1
  34. package/dist/entities/dashboard-layout.entity.d.ts +9 -0
  35. package/dist/entities/dashboard-layout.entity.d.ts.map +1 -0
  36. package/dist/entities/dashboard-layout.entity.js +41 -0
  37. package/dist/entities/dashboard-layout.entity.js.map +1 -0
  38. package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts.map +1 -1
  39. package/dist/entities/dashboard-question-sql-dataset-config.entity.js +5 -4
  40. package/dist/entities/dashboard-question-sql-dataset-config.entity.js.map +1 -1
  41. package/dist/entities/dashboard-question.entity.d.ts.map +1 -1
  42. package/dist/entities/dashboard-question.entity.js +5 -4
  43. package/dist/entities/dashboard-question.entity.js.map +1 -1
  44. package/dist/entities/dashboard-variable.entity.d.ts +1 -0
  45. package/dist/entities/dashboard-variable.entity.d.ts.map +1 -1
  46. package/dist/entities/dashboard-variable.entity.js +10 -4
  47. package/dist/entities/dashboard-variable.entity.js.map +1 -1
  48. package/dist/entities/dashboard.entity.d.ts +2 -0
  49. package/dist/entities/dashboard.entity.d.ts.map +1 -1
  50. package/dist/entities/dashboard.entity.js +9 -3
  51. package/dist/entities/dashboard.entity.js.map +1 -1
  52. package/dist/entities/email-attachment.entity.d.ts.map +1 -1
  53. package/dist/entities/email-attachment.entity.js +2 -1
  54. package/dist/entities/email-attachment.entity.js.map +1 -1
  55. package/dist/entities/email-template.entity.js +1 -1
  56. package/dist/entities/email-template.entity.js.map +1 -1
  57. package/dist/entities/export-transaction.entity.d.ts.map +1 -1
  58. package/dist/entities/export-transaction.entity.js +2 -1
  59. package/dist/entities/export-transaction.entity.js.map +1 -1
  60. package/dist/entities/field-metadata.entity.js +2 -2
  61. package/dist/entities/field-metadata.entity.js.map +1 -1
  62. package/dist/entities/import-transaction-error-log.entity.d.ts.map +1 -1
  63. package/dist/entities/import-transaction-error-log.entity.js +3 -2
  64. package/dist/entities/import-transaction-error-log.entity.js.map +1 -1
  65. package/dist/entities/import-transaction.entity.d.ts.map +1 -1
  66. package/dist/entities/import-transaction.entity.js +2 -1
  67. package/dist/entities/import-transaction.entity.js.map +1 -1
  68. package/dist/entities/mq-message-queue.entity.d.ts.map +1 -1
  69. package/dist/entities/mq-message-queue.entity.js.map +1 -1
  70. package/dist/entities/mq-message.entity.d.ts.map +1 -1
  71. package/dist/entities/mq-message.entity.js +5 -3
  72. package/dist/entities/mq-message.entity.js.map +1 -1
  73. package/dist/entities/saved-filters.entity.d.ts.map +1 -1
  74. package/dist/entities/saved-filters.entity.js +3 -2
  75. package/dist/entities/saved-filters.entity.js.map +1 -1
  76. package/dist/entities/security-rule.entity.d.ts.map +1 -1
  77. package/dist/entities/security-rule.entity.js +2 -1
  78. package/dist/entities/security-rule.entity.js.map +1 -1
  79. package/dist/entities/sms-template.entity.js +1 -1
  80. package/dist/entities/sms-template.entity.js.map +1 -1
  81. package/dist/entities/user-view-metadata.entity.d.ts.map +1 -1
  82. package/dist/entities/user-view-metadata.entity.js +2 -1
  83. package/dist/entities/user-view-metadata.entity.js.map +1 -1
  84. package/dist/entities/user.entity.d.ts.map +1 -1
  85. package/dist/entities/user.entity.js +2 -0
  86. package/dist/entities/user.entity.js.map +1 -1
  87. package/dist/entities/view-metadata.entity.d.ts.map +1 -1
  88. package/dist/entities/view-metadata.entity.js.map +1 -1
  89. package/dist/helpers/bootstrap.helper.d.ts +14 -0
  90. package/dist/helpers/bootstrap.helper.d.ts.map +1 -0
  91. package/dist/helpers/bootstrap.helper.js +132 -0
  92. package/dist/helpers/bootstrap.helper.js.map +1 -0
  93. package/dist/helpers/cache.helper.d.ts +2 -0
  94. package/dist/helpers/cache.helper.d.ts.map +1 -0
  95. package/dist/helpers/cache.helper.js +8 -0
  96. package/dist/helpers/cache.helper.js.map +1 -0
  97. package/dist/helpers/cors.helper.d.ts.map +1 -1
  98. package/dist/helpers/cors.helper.js +13 -4
  99. package/dist/helpers/cors.helper.js.map +1 -1
  100. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts +1 -0
  101. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
  102. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +8 -9
  103. package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js.map +1 -1
  104. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts +2 -2
  105. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts.map +1 -1
  106. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js +8 -5
  107. package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
  108. package/dist/helpers/solid-registry.d.ts +3 -0
  109. package/dist/helpers/solid-registry.d.ts.map +1 -1
  110. package/dist/helpers/solid-registry.js +7 -0
  111. package/dist/helpers/solid-registry.js.map +1 -1
  112. package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
  113. package/dist/helpers/typeorm-db-helper.js +21 -0
  114. package/dist/helpers/typeorm-db-helper.js.map +1 -1
  115. package/dist/index.d.ts +3 -0
  116. package/dist/index.d.ts.map +1 -1
  117. package/dist/index.js +3 -0
  118. package/dist/index.js.map +1 -1
  119. package/dist/interfaces.d.ts +2 -0
  120. package/dist/interfaces.d.ts.map +1 -1
  121. package/dist/interfaces.js.map +1 -1
  122. package/dist/jobs/chatter-queue-options.js +1 -1
  123. package/dist/jobs/chatter-queue-options.js.map +1 -1
  124. package/dist/jobs/chatter-queue-publisher.service.d.ts +9 -9
  125. package/dist/jobs/chatter-queue-publisher.service.d.ts.map +1 -1
  126. package/dist/jobs/chatter-queue-publisher.service.js +5 -5
  127. package/dist/jobs/chatter-queue-publisher.service.js.map +1 -1
  128. package/dist/jobs/chatter-queue-subscriber.service.d.ts +4 -4
  129. package/dist/jobs/chatter-queue-subscriber.service.d.ts.map +1 -1
  130. package/dist/jobs/chatter-queue-subscriber.service.js +11 -11
  131. package/dist/jobs/chatter-queue-subscriber.service.js.map +1 -1
  132. package/dist/jobs/computed-field-evaluation-queue-options.d.ts +2 -0
  133. package/dist/jobs/computed-field-evaluation-queue-options.d.ts.map +1 -1
  134. package/dist/jobs/computed-field-evaluation-queue-options.js +2 -0
  135. package/dist/jobs/computed-field-evaluation-queue-options.js.map +1 -1
  136. package/dist/jobs/database/chatter-queue-options-database.d.ts +8 -0
  137. package/dist/jobs/database/chatter-queue-options-database.d.ts.map +1 -0
  138. package/dist/jobs/database/chatter-queue-options-database.js +10 -0
  139. package/dist/jobs/database/chatter-queue-options-database.js.map +1 -0
  140. package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts +12 -0
  141. package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts.map +1 -0
  142. package/dist/jobs/database/chatter-queue-publisher-database.service.js +39 -0
  143. package/dist/jobs/database/chatter-queue-publisher-database.service.js.map +1 -0
  144. package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts +19 -0
  145. package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts.map +1 -0
  146. package/dist/jobs/database/chatter-queue-subscriber-database.service.js +62 -0
  147. package/dist/jobs/database/chatter-queue-subscriber-database.service.js.map +1 -0
  148. package/dist/repository/dashboard-layout.repository.d.ts +12 -0
  149. package/dist/repository/dashboard-layout.repository.d.ts.map +1 -0
  150. package/dist/repository/dashboard-layout.repository.js +34 -0
  151. package/dist/repository/dashboard-layout.repository.js.map +1 -0
  152. package/dist/repository/model-metadata.repository.d.ts +6 -1
  153. package/dist/repository/model-metadata.repository.d.ts.map +1 -1
  154. package/dist/repository/model-metadata.repository.js +41 -2
  155. package/dist/repository/model-metadata.repository.js.map +1 -1
  156. package/dist/seeders/module-metadata-seeder.service.js +4 -4
  157. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  158. package/dist/seeders/seed-data/solid-core-metadata.json +372 -32
  159. package/dist/services/chatter-message.service.d.ts +4 -4
  160. package/dist/services/chatter-message.service.d.ts.map +1 -1
  161. package/dist/services/chatter-message.service.js +33 -9
  162. package/dist/services/chatter-message.service.js.map +1 -1
  163. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts +7 -3
  164. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -1
  165. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +61 -22
  166. package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -1
  167. package/dist/services/crud.service.js +1 -1
  168. package/dist/services/crud.service.js.map +1 -1
  169. package/dist/services/dashboard-layout.service.d.ts +20 -0
  170. package/dist/services/dashboard-layout.service.d.ts.map +1 -0
  171. package/dist/services/dashboard-layout.service.js +120 -0
  172. package/dist/services/dashboard-layout.service.js.map +1 -0
  173. package/dist/services/dashboard.service.d.ts +2 -0
  174. package/dist/services/dashboard.service.d.ts.map +1 -1
  175. package/dist/services/dashboard.service.js +4 -0
  176. package/dist/services/dashboard.service.js.map +1 -1
  177. package/dist/services/model-metadata.service.d.ts +3 -1
  178. package/dist/services/model-metadata.service.d.ts.map +1 -1
  179. package/dist/services/model-metadata.service.js +21 -2
  180. package/dist/services/model-metadata.service.js.map +1 -1
  181. package/dist/services/permission-metadata.service.d.ts +5 -1
  182. package/dist/services/permission-metadata.service.d.ts.map +1 -1
  183. package/dist/services/permission-metadata.service.js +66 -20
  184. package/dist/services/permission-metadata.service.js.map +1 -1
  185. package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
  186. package/dist/services/queues/database-subscriber.service.js +6 -1
  187. package/dist/services/queues/database-subscriber.service.js.map +1 -1
  188. package/dist/services/queues/publisher-factory.service.js +0 -1
  189. package/dist/services/queues/publisher-factory.service.js.map +1 -1
  190. package/dist/services/queues/rabbitmq-publisher.service.d.ts +1 -0
  191. package/dist/services/queues/rabbitmq-publisher.service.d.ts.map +1 -1
  192. package/dist/services/queues/rabbitmq-publisher.service.js +6 -1
  193. package/dist/services/queues/rabbitmq-publisher.service.js.map +1 -1
  194. package/dist/services/queues/rabbitmq-subscriber.service.d.ts +5 -1
  195. package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
  196. package/dist/services/queues/rabbitmq-subscriber.service.js +84 -9
  197. package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
  198. package/dist/services/request-context.service.d.ts +2 -1
  199. package/dist/services/request-context.service.d.ts.map +1 -1
  200. package/dist/services/request-context.service.js.map +1 -1
  201. package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
  202. package/dist/services/scheduled-jobs/scheduler.service.js +20 -2
  203. package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
  204. package/dist/services/solid-introspect.service.d.ts +6 -1
  205. package/dist/services/solid-introspect.service.d.ts.map +1 -1
  206. package/dist/services/solid-introspect.service.js +27 -2
  207. package/dist/services/solid-introspect.service.js.map +1 -1
  208. package/dist/services/solid-ts-morph.service.d.ts +9 -0
  209. package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
  210. package/dist/services/solid-ts-morph.service.js +76 -0
  211. package/dist/services/solid-ts-morph.service.js.map +1 -1
  212. package/dist/solid-core.module.d.ts.map +1 -1
  213. package/dist/solid-core.module.js +16 -0
  214. package/dist/solid-core.module.js.map +1 -1
  215. package/dist/subscribers/audit.subscriber.d.ts +10 -7
  216. package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
  217. package/dist/subscribers/audit.subscriber.js +58 -85
  218. package/dist/subscribers/audit.subscriber.js.map +1 -1
  219. package/dist/subscribers/computed-entity-field.subscriber.js +3 -1
  220. package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
  221. package/dist/subscribers/created-by-updated-by.subscriber.d.ts +0 -1
  222. package/dist/subscribers/created-by-updated-by.subscriber.d.ts.map +1 -1
  223. package/dist/subscribers/created-by-updated-by.subscriber.js +3 -13
  224. package/dist/subscribers/created-by-updated-by.subscriber.js.map +1 -1
  225. package/dist/winston.logger.d.ts.map +1 -1
  226. package/dist/winston.logger.js +2 -1
  227. package/dist/winston.logger.js.map +1 -1
  228. package/package.json +3 -1
  229. package/sql/default/mariadb/proc_CleanupModelMetadata.sql +153 -0
  230. package/sql/default/mariadb/proc_CleanupModuleMetadata.sql +56 -0
  231. package/sql/default/mysql/proc_CleanupModelMetadata.sql +153 -0
  232. package/sql/default/mysql/proc_CleanupModuleMetadata.sql +56 -0
  233. package/src/controllers/dashboard-layout.controller.ts +106 -0
  234. package/src/dtos/create-dashboard-layout.dto.ts +31 -0
  235. package/src/dtos/create-dashboard-variable.dto.ts +4 -0
  236. package/src/dtos/update-dashboard-layout.dto.ts +30 -0
  237. package/src/dtos/update-dashboard-variable.dto.ts +5 -1
  238. package/src/entities/action-metadata.entity.ts +3 -2
  239. package/src/entities/ai-interaction.entity.ts +5 -4
  240. package/src/entities/chatter-message-details.entity.ts +4 -3
  241. package/src/entities/chatter-message.entity.ts +4 -3
  242. package/src/entities/dashboard-layout.entity.ts +18 -0
  243. package/src/entities/dashboard-question-sql-dataset-config.entity.ts +5 -4
  244. package/src/entities/dashboard-question.entity.ts +5 -4
  245. package/src/entities/dashboard-variable.entity.ts +9 -4
  246. package/src/entities/dashboard.entity.ts +7 -2
  247. package/src/entities/email-attachment.entity.ts +2 -1
  248. package/src/entities/email-template.entity.ts +1 -1
  249. package/src/entities/export-transaction.entity.ts +2 -1
  250. package/src/entities/field-metadata.entity.ts +2 -2
  251. package/src/entities/import-transaction-error-log.entity.ts +3 -2
  252. package/src/entities/import-transaction.entity.ts +2 -1
  253. package/src/entities/mq-message-queue.entity.ts +8 -8
  254. package/src/entities/mq-message.entity.ts +5 -3
  255. package/src/entities/saved-filters.entity.ts +3 -2
  256. package/src/entities/security-rule.entity.ts +2 -1
  257. package/src/entities/sms-template.entity.ts +1 -1
  258. package/src/entities/user-view-metadata.entity.ts +2 -1
  259. package/src/entities/user.entity.ts +37 -2
  260. package/src/entities/view-metadata.entity.ts +3 -0
  261. package/src/helpers/bootstrap.helper.ts +222 -0
  262. package/src/helpers/cache.helper.ts +5 -0
  263. package/src/helpers/cors.helper.ts +26 -6
  264. package/src/helpers/field-crud-managers/MediaFieldCrudManager.ts +9 -9
  265. package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +9 -6
  266. package/src/helpers/solid-registry.ts +10 -5
  267. package/src/helpers/typeorm-db-helper.ts +26 -0
  268. package/src/index.ts +3 -0
  269. package/src/interfaces.ts +3 -0
  270. package/src/jobs/chatter-queue-options.ts +1 -1
  271. package/src/jobs/chatter-queue-publisher.service.ts +11 -11
  272. package/src/jobs/chatter-queue-subscriber.service.ts +13 -8
  273. package/src/jobs/computed-field-evaluation-queue-options.ts +2 -0
  274. package/src/jobs/database/chatter-queue-options-database.ts +9 -0
  275. package/src/jobs/database/chatter-queue-publisher-database.service.ts +24 -0
  276. package/src/jobs/database/chatter-queue-subscriber-database.service.ts +53 -0
  277. package/src/repository/dashboard-layout.repository.ts +17 -0
  278. package/src/repository/model-metadata.repository.ts +45 -2
  279. package/src/seeders/module-metadata-seeder.service.ts +5 -5
  280. package/src/seeders/seed-data/solid-core-metadata.json +373 -33
  281. package/src/services/1.js +6 -0
  282. package/src/services/chatter-message.service.ts +41 -9
  283. package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +79 -40
  284. package/src/services/crud.service.ts +1 -1
  285. package/src/services/dashboard-layout.service.ts +111 -0
  286. package/src/services/dashboard.service.ts +7 -0
  287. package/src/services/model-metadata.service.ts +22 -43
  288. package/src/services/permission-metadata.service.ts +73 -20
  289. package/src/services/queues/database-subscriber.service.ts +7 -1
  290. package/src/services/queues/publisher-factory.service.ts +1 -1
  291. package/src/services/queues/rabbitmq-publisher.service.ts +8 -2
  292. package/src/services/queues/rabbitmq-subscriber.service.ts +127 -10
  293. package/src/services/request-context.service.ts +2 -1
  294. package/src/services/scheduled-jobs/scheduler.service.ts +22 -4
  295. package/src/services/solid-introspect.service.ts +28 -0
  296. package/src/services/solid-ts-morph.service.ts +98 -0
  297. package/src/solid-core.module.ts +21 -2
  298. package/src/subscribers/audit.subscriber.ts +63 -271
  299. package/src/subscribers/computed-entity-field.subscriber.ts +3 -3
  300. package/src/subscribers/created-by-updated-by.subscriber.ts +22 -16
  301. package/src/winston.logger.ts +2 -1
  302. package/dist-tests/api/authenticate.spec.js +0 -119
  303. package/dist-tests/api/authenticate.spec.js.map +0 -1
  304. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +0 -97
  305. package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +0 -1
  306. package/dist-tests/api/ping.spec.js +0 -21
  307. package/dist-tests/api/ping.spec.js.map +0 -1
  308. package/dist-tests/helpers/auth.js +0 -41
  309. package/dist-tests/helpers/auth.js.map +0 -1
  310. package/dist-tests/helpers/env.js +0 -11
  311. package/dist-tests/helpers/env.js.map +0 -1
@@ -3,10 +3,11 @@ import { Entity, Column, JoinColumn, ManyToOne, Index } from 'typeorm';
3
3
  import { User } from 'src/entities/user.entity';
4
4
  import { ModelMetadata } from 'src/entities/model-metadata.entity';
5
5
  import { ViewMetadata } from 'src/entities/view-metadata.entity'
6
+ import { getColumnType } from 'src/helpers/typeorm-db-helper';
6
7
 
7
8
  @Entity("ss_saved_fitlers")
8
9
  export class SavedFilters extends CommonEntity {
9
- @Column({ type: "text", nullable: true })
10
+ @Column({ nullable: true, ...getColumnType('longText') })
10
11
  filterQueryJson: any;
11
12
 
12
13
  @Index({ unique: true })
@@ -28,7 +29,7 @@ export class SavedFilters extends CommonEntity {
28
29
  @JoinColumn()
29
30
  view: ViewMetadata;
30
31
 
31
- @Column({ name: "description", type: "text", nullable: true })
32
+ @Column({ name: "description", nullable: true })
32
33
  description: string;
33
34
 
34
35
  @Column({ nullable: true, default: false })
@@ -2,6 +2,7 @@ import { CommonEntity } from 'src/entities/common.entity';
2
2
  import { ModelMetadata } from 'src/entities/model-metadata.entity';
3
3
  import { RoleMetadata } from 'src/entities/role-metadata.entity';
4
4
  import { Column, Entity, Index, JoinColumn, ManyToOne } from 'typeorm';
5
+ import { getColumnType } from 'src/helpers/typeorm-db-helper';
5
6
 
6
7
  @Entity("ss_security_rule")
7
8
  export class SecurityRule extends CommonEntity {
@@ -22,7 +23,7 @@ export class SecurityRule extends CommonEntity {
22
23
  @JoinColumn()
23
24
  modelMetadata: ModelMetadata;
24
25
 
25
- @Column({ type: "text" })
26
+ @Column({ ...getColumnType('longText'), nullable: true })
26
27
  securityRuleConfig: any;
27
28
 
28
29
  @Column({ type: "varchar", nullable: true })
@@ -12,7 +12,7 @@ export class SmsTemplate extends CommonEntity {
12
12
  body: string;
13
13
  @Column({ type: "varchar", nullable: true })
14
14
  smsProviderTemplateId: string;
15
- @Column({ name: "description", type: "text", nullable: true })
15
+ @Column({ name: "description", nullable: true })
16
16
  description: string;
17
17
  @Column({ name: "active", nullable: true, default: true })
18
18
  active: boolean = true;
@@ -1,5 +1,6 @@
1
1
  import { CommonEntity } from 'src/entities/common.entity'
2
2
  import { Entity, JoinColumn, ManyToOne, Index, Column } from 'typeorm';
3
+ import { getColumnType } from 'src/helpers/typeorm-db-helper';
3
4
  import { ViewMetadata } from 'src/entities/view-metadata.entity';
4
5
  import { User } from 'src/entities/user.entity'
5
6
 
@@ -9,7 +10,7 @@ export class UserViewMetadata extends CommonEntity {
9
10
  @ManyToOne(() => User, { nullable: false })
10
11
  @JoinColumn()
11
12
  user: User;
12
- @Column({ name: "layout", type: "text", nullable: true })
13
+ @Column({ name: "layout", nullable: true, ...getColumnType('longText') })
13
14
  layout: any = "{}";
14
15
  @Index()
15
16
  @ManyToOne(() => ViewMetadata, { nullable: false })
@@ -11,109 +11,144 @@ export class User extends CommonEntity {
11
11
  @Column({ type: "varchar", nullable: true })
12
12
  @Expose()
13
13
  fullName: string;
14
+
14
15
  @Index({ unique: true })
15
16
  @Column({ type: "varchar" })
16
17
  @Expose()
17
18
  username: string;
18
- // @Index({ unique: true })
19
+
20
+ @Index()
19
21
  @Column({ type: "varchar", nullable: true })
20
22
  @Expose()
21
23
  email: string;
22
- // @Index({ unique: true })
24
+
25
+ @Index()
23
26
  @Column({ type: "varchar", nullable: true })
24
27
  @Expose()
25
28
  mobile: string;
29
+
26
30
  @Column({ type: "varchar", nullable: true })
27
31
  // don't send to client
28
32
  password: string;
33
+
29
34
  @Column({ nullable: true, default: true })
30
35
  @Expose()
31
36
  forcePasswordChange: boolean = true;
37
+
32
38
  @Column({ type: "varchar", default: "local" })
33
39
  // don't send to client
34
40
  lastLoginProvider: string = "local";
41
+
35
42
  @Column({ type: "varchar", nullable: true })
36
43
  // don't send to client (test)
37
44
  accessCode: string;
45
+
38
46
  @Column({ type: "varchar", nullable: true })
39
47
  // don't send to client
40
48
  googleAccessToken: string;
49
+
41
50
  @Column({ type: "varchar", nullable: true })
42
51
  // don't send to client
43
52
  googleId: string;
53
+
44
54
  @Column({ type: "varchar", nullable: true })
45
55
  // don't send to client
46
56
  googleProfilePicture: string;
57
+
47
58
  @Column({ default: true })
48
59
  @Expose()
49
60
  active: boolean = true;
61
+
50
62
  @Column({ nullable: true })
51
63
  // don't send to client
52
64
  forgotPasswordConfirmedAt: Date;
65
+
53
66
  @Column({ type: "varchar", nullable: true })
54
67
  // don't send to client
55
68
  verificationTokenOnForgotPassword: string;
69
+
56
70
  @Column({ nullable: true })
57
71
  // don't send to client
58
72
  verificationTokenOnForgotPasswordExpiresAt: Date;
73
+
59
74
  @Column({ nullable: true })
60
75
  // don't send to client
61
76
  emailVerifiedOnRegistrationAt: Date;
77
+
62
78
  @Column({ type: "varchar", nullable: true })
63
79
  // don't send to client
64
80
  emailVerificationTokenOnRegistration: string;
81
+
65
82
  @Column({ nullable: true })
66
83
  // don't send to client
67
84
  emailVerificationTokenOnRegistrationExpiresAt: Date;
85
+
68
86
  @Column({ nullable: true })
69
87
  // don't send to client
70
88
  mobileVerifiedOnRegistrationAt: Date;
89
+
71
90
  @Column({ type: "varchar", nullable: true })
72
91
  // don't send to client
73
92
  mobileVerificationTokenOnRegistration: string;
93
+
74
94
  @Column({ nullable: true })
75
95
  // don't send to client
76
96
  mobileVerificationTokenOnRegistrationExpiresAt: Date;
97
+
77
98
  @Column({ nullable: true })
78
99
  // don't send to client
79
100
  emailVerifiedOnLoginAt: Date;
101
+
80
102
  @Column({ type: "varchar", nullable: true })
81
103
  // don't send to client
82
104
  emailVerificationTokenOnLogin: string;
105
+
83
106
  @Column({ nullable: true })
84
107
  // don't send to client
85
108
  emailVerificationTokenOnLoginExpiresAt: Date;
109
+
86
110
  @Column({ nullable: true })
87
111
  // don't send to client
88
112
  mobileVerifiedOnLoginAt: Date;
113
+
89
114
  @Column({ type: "varchar", nullable: true })
90
115
  // don't send to client
91
116
  mobileVerificationTokenOnLogin: string;
117
+
92
118
  @Column({ nullable: true })
93
119
  // don't send to client
94
120
  mobileVerificationTokenOnLoginExpiresAt: Date;
121
+
95
122
  @Column({ type: "varchar", nullable: true })
96
123
  @Expose()
97
124
  customPayload: string;
125
+
98
126
  @ManyToMany(() => RoleMetadata, roleMetadata => roleMetadata.users, { cascade: true })
99
127
  @JoinTable()
100
128
  @Expose()
101
129
  roles: RoleMetadata[];
130
+
102
131
  @OneToMany(() => UserViewMetadata, userViewMetadata => userViewMetadata.user, { cascade: true })
103
132
  // don't send to client
104
133
  userViewMetadata: UserViewMetadata[];
134
+
105
135
  // dont send to client
106
136
  @Column({ type: "varchar", default: "bcrypt" })
107
137
  passwordScheme: string;
138
+
108
139
  // dont send to client
109
140
  @Column({ type: "int", default: 1 })
110
141
  passwordSchemeVersion: number;
142
+
111
143
  // dont send to client
112
144
  @Column({ nullable: true })
113
145
  rehashedAt: Date;
146
+
114
147
  // dont send to client
115
148
  @Column({ type: "int", default: 0 })
116
149
  failedLoginAttempts: number = 0;
150
+
117
151
  @Expose()
118
152
  _media: any;
153
+
119
154
  }
@@ -1,5 +1,6 @@
1
1
  import { CommonEntity } from "src/entities/common.entity"
2
2
  import { Entity, Column, ManyToOne, Index, JoinColumn, OneToMany } from "typeorm";
3
+ import { getColumnType } from 'src/helpers/typeorm-db-helper';
3
4
  import { ModuleMetadata } from 'src/entities/module-metadata.entity';
4
5
  import { ModelMetadata } from 'src/entities/model-metadata.entity';
5
6
  import { UserViewMetadata } from 'src/entities/user-view-metadata.entity'
@@ -16,9 +17,11 @@ export class ViewMetadata extends CommonEntity {
16
17
  @Column({ name: "type", type: "varchar" })
17
18
  type: string;
18
19
 
20
+ //TODO: To make this truly cross db compatible, we should avoid setting a db type
19
21
  @Column({ name: "context", type: "text" })
20
22
  context: any = "{}";
21
23
 
24
+ //TODO: To make this truly cross db compatible, we should avoid setting a db type
22
25
  @Column({ name: "layout", type: "text" })
23
26
  layout: any;
24
27
 
@@ -0,0 +1,222 @@
1
+ import { ValidationPipe } from '@nestjs/common';
2
+ import { NestFactory } from '@nestjs/core';
3
+ import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
4
+ import { NextFunction, Request, Response } from 'express';
5
+ import helmet from 'helmet';
6
+ import qs from 'qs';
7
+ import { existsSync } from 'fs';
8
+ import { resolve } from 'path';
9
+ import { WINSTON_MODULE_NEST_PROVIDER } from 'nest-winston';
10
+ import { CommandFactory } from 'nest-commander';
11
+ import { WrapResponseInterceptor } from '../interceptors/wrap-response.interceptor';
12
+ import { buildDefaultCorsOptions } from './cors.helper';
13
+ import { buildDefaultSecurityHeaderOptions, buildPermissionsPolicyHeader, PermissionsPolicyConfig } from './security.helper';
14
+ import { parseBooleanEnv } from './environment.helper';
15
+
16
+ // ---- Shared process handlers ----
17
+
18
+ function registerGlobalProcessHandlers() {
19
+ process.on('unhandledRejection', (reason, promise) => {
20
+ console.error('Unhandled Rejection at:', promise, 'reason:', reason);
21
+ });
22
+
23
+ process.on('uncaughtException', (err) => {
24
+ console.error('Uncaught Exception thrown:', err);
25
+ });
26
+
27
+ // Suppress pg deprecation warning caused by TypeORM's internal query scheduling
28
+ process.on('warning', (warning) => {
29
+ if (warning.name === 'DeprecationWarning' && (warning.message.includes('client.query()') || warning.message.includes('punycode'))) {
30
+ return;
31
+ }
32
+ console.warn(warning);
33
+ });
34
+ }
35
+
36
+ // ---- HTTP server bootstrap ----
37
+
38
+ export interface SolidSwaggerOptions {
39
+ title?: string;
40
+ description?: string;
41
+ version?: string;
42
+ }
43
+
44
+ export interface SolidBootstrapOptions {
45
+ /** Global API prefix. Defaults to 'api'. Set to '' to disable. */
46
+ globalPrefix?: string;
47
+ /** Swagger configuration. Set to false to disable Swagger entirely. */
48
+ swagger?: SolidSwaggerOptions | false;
49
+ /** Permissions-Policy header overrides (merged with defaults). */
50
+ permissionsPolicyOverrides?: Partial<PermissionsPolicyConfig>;
51
+ }
52
+
53
+ /**
54
+ * Bootstraps a SolidX NestJS HTTP application with sensible defaults:
55
+ * security headers, CORS, Winston logger, ValidationPipe,
56
+ * WrapResponseInterceptor, qs deep query parsing, Swagger, and the
57
+ * pg BIGINT type parser.
58
+ *
59
+ * @example
60
+ * // main.ts
61
+ * bootstrapSolidApp(() => AppModule.forRoot(), {
62
+ * swagger: { title: 'My API', description: 'My API description' },
63
+ * });
64
+ */
65
+ export async function bootstrapSolidApp(
66
+ appModuleFactory: () => Promise<any>,
67
+ options: SolidBootstrapOptions = {},
68
+ ): Promise<void> {
69
+ registerGlobalProcessHandlers();
70
+
71
+ const { globalPrefix = 'api', swagger = {}, permissionsPolicyOverrides = {} } = options;
72
+
73
+ const appModule = await appModuleFactory();
74
+ const app = await NestFactory.create(appModule);
75
+
76
+ const apiEnabled = parseBooleanEnv('API_ENABLED', true);
77
+
78
+ if (!apiEnabled) {
79
+ await app.init();
80
+ app
81
+ .get(WINSTON_MODULE_NEST_PROVIDER)
82
+ .log('API server disabled via API_ENABLED=false. Skipping HTTP listen.', 'Bootstrap');
83
+ return;
84
+ }
85
+
86
+ // Health check at root path
87
+ const server = app.getHttpAdapter().getInstance();
88
+ server.get('/', (_req, res) => res.status(200).send('SOLID OK'));
89
+
90
+ // Security headers
91
+ app.use(helmet(buildDefaultSecurityHeaderOptions()));
92
+
93
+ // Permissions-Policy header
94
+ app.use((_req: Request, res: Response, next: NextFunction) => {
95
+ res.setHeader('Permissions-Policy', buildPermissionsPolicyHeader(permissionsPolicyOverrides));
96
+ next();
97
+ });
98
+
99
+ // Winston logger
100
+ app.useLogger(app.get(WINSTON_MODULE_NEST_PROVIDER));
101
+
102
+ const port = process.env.PORT || 3000;
103
+
104
+ if (globalPrefix) {
105
+ app.setGlobalPrefix(globalPrefix);
106
+ }
107
+
108
+ // qs-based deep query parsing (dot notation, nested objects, arrays)
109
+ app.use((req: Request, _res: Response, next: NextFunction) => {
110
+ if (req.query) {
111
+ req.query = qs.parse(req.url.split('?')[1], {
112
+ allowDots: true,
113
+ depth: 20,
114
+ arrayLimit: 100,
115
+ });
116
+ }
117
+ next();
118
+ });
119
+
120
+ // Global ValidationPipe
121
+ app.useGlobalPipes(
122
+ new ValidationPipe({
123
+ transform: true,
124
+ transformOptions: { enableImplicitConversion: true },
125
+ }),
126
+ );
127
+
128
+ // Swagger
129
+ if (swagger !== false) {
130
+ const { title = 'Solid Starters', description = 'Solid Starters API', version = '1.0' } = swagger;
131
+ const swaggerConfig = new DocumentBuilder()
132
+ .setTitle(title)
133
+ .setDescription(description)
134
+ .setVersion(version)
135
+ .setExternalDoc('Postman Collection', '/docs-json')
136
+ .addBearerAuth(
137
+ {
138
+ description: 'Please enter token in following format: Bearer <JWT>',
139
+ name: 'Authorization',
140
+ bearerFormat: 'Bearer',
141
+ scheme: 'Bearer',
142
+ type: 'http',
143
+ in: 'Header',
144
+ },
145
+ 'jwt',
146
+ )
147
+ .build();
148
+ const document = SwaggerModule.createDocument(app, swaggerConfig);
149
+ SwaggerModule.setup('/docs', app, document);
150
+ }
151
+
152
+ // Global interceptor
153
+ app.useGlobalInterceptors(new WrapResponseInterceptor());
154
+
155
+ // CORS
156
+ app.enableCors(buildDefaultCorsOptions());
157
+
158
+ // Fix pg returning BIGINT columns as strings
159
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
160
+ const types = require('pg').types;
161
+ types.setTypeParser(types.builtins.INT8, (val: string) => parseInt(val));
162
+
163
+ await app.listen(port);
164
+ }
165
+
166
+ // ---- CLI bootstrap ----
167
+
168
+ /**
169
+ * Bootstraps a SolidX NestJS CLI application using nest-commander.
170
+ * Handles verbose flag stripping, project root validation, and clean process exit.
171
+ *
172
+ * @example
173
+ * // main-cli.ts
174
+ * #!/usr/bin/env node
175
+ * import { bootstrapSolidCli } from '@solidxai/core';
176
+ * import { AppModule } from './app.module';
177
+ *
178
+ * bootstrapSolidCli(() => AppModule.forRoot());
179
+ */
180
+ export async function bootstrapSolidCli(
181
+ appModuleFactory: () => Promise<any>,
182
+ ): Promise<void> {
183
+ registerGlobalProcessHandlers();
184
+
185
+ process.on('exit', (code) => {
186
+ if (code !== 0) {
187
+ console.error(`Exiting with error status code: ${code}`);
188
+ }
189
+ });
190
+
191
+ // Validate that cwd is a valid Solid API project
192
+ const packageJsonPath = resolve(process.cwd(), 'package.json');
193
+ if (!existsSync(packageJsonPath)) {
194
+ console.error('Does not seem to be a valid solid-api project.');
195
+ console.error('Exit reason: missing package.json in the current directory.');
196
+ process.exit(1);
197
+ }
198
+
199
+ // Strip --verbose / -v before nest-commander processes argv
200
+ const showLogs = process.argv.includes('--verbose') || process.argv.includes('-v');
201
+ for (const flag of ['--verbose', '-v']) {
202
+ const idx = process.argv.indexOf(flag);
203
+ if (idx !== -1) process.argv.splice(idx, 1);
204
+ }
205
+
206
+ const appModule = await appModuleFactory();
207
+ process.env.SOLID_CLI_RUNNING = 'true';
208
+
209
+ // @ts-ignore
210
+ const app = await CommandFactory.createWithoutRunning(appModule, {
211
+ logger: showLogs ? ['debug', 'error', 'fatal', 'log', 'verbose', 'warn'] : false,
212
+ });
213
+
214
+ try {
215
+ await CommandFactory.runApplication(app);
216
+ } catch (e) {
217
+ console.error('CLI exited abruptly due to an error:', e);
218
+ process.exit(1);
219
+ }
220
+
221
+ process.exit(0);
222
+ }
@@ -0,0 +1,5 @@
1
+ export function shouldUseCache(): boolean {
2
+ const env = (process.env.ENV ?? process.env.NODE_ENV ?? '').toLowerCase();
3
+ return env === 'prod' || env === 'production';
4
+ }
5
+
@@ -1,8 +1,12 @@
1
+ import { Logger } from '@nestjs/common';
1
2
  import { CorsOptions } from 'cors';
2
3
 
4
+ const logger = new Logger('CorsHelper');
5
+
3
6
  /** Build CorsOptions from env; supports wildcards like https://*.example.com */
4
7
  export function buildDefaultCorsOptions(): CorsOptions {
5
8
  const rawOrigins = process.env.SECURITY_CORS_ORIGINS ?? '*';
9
+ logger.log(`CORS allowed origins: ${rawOrigins}`);
6
10
 
7
11
  const allowed = rawOrigins.split(',').map(s => s.trim()).filter(Boolean);
8
12
 
@@ -18,17 +22,33 @@ export function buildDefaultCorsOptions(): CorsOptions {
18
22
  };
19
23
 
20
24
  const matchers = allowed.map(patternToRegex);
21
- const isAllowed = (origin: string) =>
22
- matchers.length > 0 && matchers.some(rx => rx.test(origin));
25
+ logger.log(`CORS regexes: ${matchers.map(r => r.toString()).join(', ')}`);
23
26
 
24
27
  return {
25
28
  origin: (origin, cb) => {
26
- if (!origin) return cb(null, true); // allow no-origin (CLI/mobile/internal)
27
- if (isAllowed(origin)) return cb(null, true);
28
- return cb(new Error(`Origin ${origin} not allowed by CORS`), false);
29
+ if (!origin) {
30
+ logger.debug('CORS origin callback skipped regex evaluation because origin was empty');
31
+ // allow no-origin (CLI/mobile/internal)
32
+ return cb(null, true);
33
+ }
34
+
35
+ const matchingRegex = matchers.find(rx => rx.test(origin));
36
+ if (matchingRegex) {
37
+ logger.debug(`CORS origin matched: origin=${origin}; regex=${matchingRegex.toString()}`);
38
+ return cb(null, true);
39
+ }
40
+
41
+ logger.debug(`CORS origin did not match any regex: origin=${origin}; regexes=${matchers.map(r => r.toString()).join(', ')}`);
42
+ return cb(new Error(`Origin ${origin} not allowed by CORS. Allowed origins: ${allowed.join(', ')}`), false);
29
43
  },
30
44
  methods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
31
45
  allowedHeaders: ['Content-Type', 'Authorization'],
32
46
  credentials: true,
33
47
  };
34
- }
48
+ }
49
+
50
+
51
+ // [2026-04-07T08:27:19.943Z] INFO: CORS allowed origins: leadyatra.indusindnipponlife.com
52
+ // [2026-04-07T08:27:19.944Z] INFO: CORS regexes: /^https?:\/\/leadyatra\.indusindnipponlife\.com(?::\d+)?$/i
53
+ // [2026-04-07T08:27:19.947Z] DEBUG: Mounting ClsMiddleware to *
54
+ // [2026-04-07T08:27:19.950Z] INFO: CityMasterController {/api/city-master}:
@@ -11,6 +11,7 @@ export interface MediaFieldOptions {
11
11
  fieldName: string | undefined | null;
12
12
  mediaMaxSizeKb: number | undefined | null;
13
13
  mediaTypes: string[];
14
+ isUpdate: boolean | undefined | null;
14
15
  }
15
16
 
16
17
  type MediaType = 'image' | 'audio' | 'video' | 'file' | 'pdf';
@@ -119,25 +120,24 @@ export class MediaFieldCrudManager implements FieldCrudManager {
119
120
  }
120
121
 
121
122
  validate(dto: any, files: Array<Express.Multer.File>): ValidationError[] {
122
- const isValidateForUpdate = dto.id !== undefined; //FIXME: This is a hack, since we are using PUT for update. Once we support PATCH, this will be removed
123
123
  const fieldFiles = files.filter(file => file.fieldname === this.options.fieldName);
124
- return this.applyValidations(fieldFiles, isValidateForUpdate);
124
+ return this.applyValidations(fieldFiles);
125
125
  }
126
126
 
127
- private applyValidations(fieldFiles: Array<Express.Multer.File>, isValidateForUpdate: boolean): ValidationError[] {
127
+ private applyValidations(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
128
128
  switch (this.options.type) {
129
129
  case SolidMediaType.mediaSingle:
130
- return this.validateMediaSingle(fieldFiles, isValidateForUpdate);
130
+ return this.validateMediaSingle(fieldFiles);
131
131
  case SolidMediaType.mediaMultiple:
132
- return this.validateMediaMultiple(fieldFiles, isValidateForUpdate);
132
+ return this.validateMediaMultiple(fieldFiles);
133
133
  default:
134
134
  return [];
135
135
  }
136
136
  }
137
137
 
138
- private validateMediaSingle(fieldFiles: Array<Express.Multer.File>, isValidateForUpdate: boolean): ValidationError[] {
138
+ private validateMediaSingle(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
139
139
  const errors: ValidationError[] = [];
140
- if (!isValidateForUpdate && this.options.required && fieldFiles.length === 0) {
140
+ if (!this.options.isUpdate && this.options.required && fieldFiles.length === 0) {
141
141
  errors.push({
142
142
  field: this.options.fieldName,
143
143
  error: `${this.options.fieldName} is required`
@@ -184,9 +184,9 @@ export class MediaFieldCrudManager implements FieldCrudManager {
184
184
  return errors;
185
185
  }
186
186
 
187
- private validateMediaMultiple(fieldFiles: Array<Express.Multer.File>, isValidateForUpdate: boolean): ValidationError[] {
187
+ private validateMediaMultiple(fieldFiles: Array<Express.Multer.File>): ValidationError[] {
188
188
  const errors: ValidationError[] = [];
189
- if (!isValidateForUpdate && this.options.required && fieldFiles.length === 0) {
189
+ if (!this.options.isUpdate && this.options.required && fieldFiles.length === 0) {
190
190
  errors.push({
191
191
  field: this.options.fieldName,
192
192
  error: `${this.options.fieldName} is required`
@@ -7,7 +7,7 @@ export interface SelectionDynamicFieldOptions {
7
7
  selectionDynamicProvider: string;
8
8
  selectionValueType: SelectionValueType;
9
9
  required: boolean | undefined | null;
10
- selectionDynamicProviderCtxt: any;
10
+ selectionDynamicProviderCtxt: ISelectionProviderContext;
11
11
  fieldName: string;
12
12
  discoveryService: DiscoveryService;
13
13
  isMultiSelect: boolean | undefined | null;
@@ -85,8 +85,11 @@ export class SelectionDynamicFieldCrudManager implements FieldCrudManager {
85
85
  private async applyFormatValidations(fieldValue: any): Promise<ValidationError[]> {
86
86
  const errors: ValidationError[] = [];
87
87
  !this.isValidSelectionValueType(fieldValue, this.options.selectionValueType) ? errors.push({ field: this.options.fieldName, error: 'Field value type is invalid' }) : "no errors";
88
- const _isValidSelectionValue = await this.isValidSelectionValue(fieldValue, this.options.selectionDynamicProvider)
89
- !_isValidSelectionValue ? errors.push({ field: this.options.fieldName, error: 'Field value is invalid' }) : "no errors";
88
+ const ctxt = this.options.selectionDynamicProviderCtxt;
89
+ if (ctxt.validateOnSave !== false) {
90
+ const _isValidSelectionValue = await this.isValidSelectionValue(fieldValue, this.options.selectionDynamicProvider, ctxt);
91
+ !_isValidSelectionValue ? errors.push({ field: this.options.fieldName, error: 'Field value is invalid' }) : "no errors";
92
+ }
90
93
  return errors;
91
94
  }
92
95
 
@@ -106,11 +109,11 @@ export class SelectionDynamicFieldCrudManager implements FieldCrudManager {
106
109
  }
107
110
  }
108
111
 
109
- private async isValidSelectionValue(fieldValue: any, selectionDynamicProvider: string): Promise<boolean> {
112
+ private async isValidSelectionValue(fieldValue: any, selectionDynamicProvider: string, ctxt: ISelectionProviderContext): Promise<boolean> {
110
113
  const providerInstance = this.providerInstance<any>(selectionDynamicProvider);
111
114
  try {
112
115
  // Use the value method first
113
- const valueOption = await providerInstance.value(fieldValue, JSON.parse(this.options.selectionDynamicProviderCtxt));
116
+ const valueOption = await providerInstance.value(fieldValue, ctxt);
114
117
  if (valueOption && valueOption.value === fieldValue) {
115
118
  return true;
116
119
  }
@@ -118,7 +121,7 @@ export class SelectionDynamicFieldCrudManager implements FieldCrudManager {
118
121
  }
119
122
  catch (error) {
120
123
  // Use the values method as a fallback, if the value method is not implemented
121
- const values = await providerInstance.values('', JSON.parse(this.options.selectionDynamicProviderCtxt));
124
+ const values = await providerInstance.values('', ctxt);
122
125
  const isValid = values.some(v => v.value === fieldValue);
123
126
  return isValid;
124
127
  }
@@ -5,12 +5,8 @@ import { CommonEntity } from 'src/entities/common.entity';
5
5
  import { Locale } from 'src/entities/locale.entity';
6
6
  import { SecurityRule } from 'src/entities/security-rule.entity';
7
7
  import { IScheduledJob } from 'src/services/scheduled-jobs/scheduled-job.interface';
8
- import { IDashboardQuestionDataProvider, IDashboardVariableSelectionProvider, IErrorCodeProvider, ISecurityRuleConfigProvider, ISelectionProvider, ISelectionProviderContext, ISolidDatabaseModule, ISettingsProvider, SettingDefinition } from "../interfaces";
9
- import { DatasourceType } from 'src/dtos/create-model-metadata.dto';
8
+ import { IDashboardQuestionDataProvider, IDashboardVariableSelectionProvider, IErrorCodeProvider, ISecurityRuleConfigProvider, ISelectionProvider, ISelectionProviderContext, ISolidDatabaseModule } from "../interfaces";
10
9
  import { ObjectLiteral } from 'typeorm';
11
- import { ColumnMetadata } from 'typeorm/metadata/ColumnMetadata';
12
- import { RelationMetadata } from 'typeorm/metadata/RelationMetadata';
13
- import { Setting } from 'src/entities/setting.entity';
14
10
 
15
11
  type ControllerMetadata = {
16
12
  name: string;
@@ -86,6 +82,7 @@ export class SolidRegistry {
86
82
  private securityRuleConfigProviders: Set<InstanceWrapper> = new Set();
87
83
  private errorCodeProviders: Set<InstanceWrapper> = new Set();
88
84
  private settingsProviders: Set<InstanceWrapper> = new Set();
85
+ private auditableModels: Set<string> = new Set();
89
86
 
90
87
  registerErrorCodeProvider(errorCodeProvider: InstanceWrapper): void {
91
88
  this.errorCodeProviders.add(errorCodeProvider);
@@ -342,6 +339,14 @@ export class SolidRegistry {
342
339
  });
343
340
  }
344
341
 
342
+ registerAuditableModels(models: Set<string>): void {
343
+ this.auditableModels = models;
344
+ }
345
+
346
+ isAuditableModel(modelSingularName: string): boolean {
347
+ return this.auditableModels.has(modelSingularName.toLowerCase());
348
+ }
349
+
345
350
  getCommonEntityKeys(): (keyof CommonEntity | 'createdBy' | 'updatedBy')[] {
346
351
  return ['id', 'createdAt', 'updatedAt', 'deletedAt', 'createdBy', 'updatedBy', 'deletedTracker', 'localeName', 'defaultEntityLocaleId', 'publishedAt'];
347
352
  // return Reflect.getMetadataKeys(CommonEntity.prototype) as (keyof CommonEntity)[];