@solidxai/core 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/dist/controllers/dashboard-layout.controller.d.ts +47 -0
- package/dist/controllers/dashboard-layout.controller.d.ts.map +1 -0
- package/dist/controllers/dashboard-layout.controller.js +204 -0
- package/dist/controllers/dashboard-layout.controller.js.map +1 -0
- package/dist/controllers/scheduled-job.controller.d.ts +1 -0
- package/dist/controllers/scheduled-job.controller.d.ts.map +1 -1
- package/dist/controllers/scheduled-job.controller.js +12 -0
- package/dist/controllers/scheduled-job.controller.js.map +1 -1
- package/dist/dtos/create-dashboard-layout.dto.d.ts +8 -0
- package/dist/dtos/create-dashboard-layout.dto.d.ts.map +1 -0
- package/dist/dtos/create-dashboard-layout.dto.js +53 -0
- package/dist/dtos/create-dashboard-layout.dto.js.map +1 -0
- package/dist/dtos/create-dashboard-variable.dto.d.ts +1 -0
- package/dist/dtos/create-dashboard-variable.dto.d.ts.map +1 -1
- package/dist/dtos/create-dashboard-variable.dto.js +7 -1
- package/dist/dtos/create-dashboard-variable.dto.js.map +1 -1
- package/dist/dtos/update-dashboard-layout.dto.d.ts +8 -0
- package/dist/dtos/update-dashboard-layout.dto.d.ts.map +1 -0
- package/dist/dtos/update-dashboard-layout.dto.js +53 -0
- package/dist/dtos/update-dashboard-layout.dto.js.map +1 -0
- package/dist/dtos/update-dashboard-variable.dto.d.ts +1 -0
- package/dist/dtos/update-dashboard-variable.dto.d.ts.map +1 -1
- package/dist/dtos/update-dashboard-variable.dto.js +7 -1
- package/dist/dtos/update-dashboard-variable.dto.js.map +1 -1
- package/dist/entities/action-metadata.entity.d.ts.map +1 -1
- package/dist/entities/action-metadata.entity.js.map +1 -1
- package/dist/entities/ai-interaction.entity.d.ts.map +1 -1
- package/dist/entities/ai-interaction.entity.js +5 -4
- package/dist/entities/ai-interaction.entity.js.map +1 -1
- package/dist/entities/chatter-message-details.entity.d.ts +1 -0
- package/dist/entities/chatter-message-details.entity.d.ts.map +1 -1
- package/dist/entities/chatter-message-details.entity.js +9 -4
- package/dist/entities/chatter-message-details.entity.js.map +1 -1
- package/dist/entities/chatter-message.entity.d.ts.map +1 -1
- package/dist/entities/chatter-message.entity.js +4 -3
- package/dist/entities/chatter-message.entity.js.map +1 -1
- package/dist/entities/common.entity.js +1 -1
- package/dist/entities/common.entity.js.map +1 -1
- package/dist/entities/dashboard-layout.entity.d.ts +9 -0
- package/dist/entities/dashboard-layout.entity.d.ts.map +1 -0
- package/dist/entities/dashboard-layout.entity.js +41 -0
- package/dist/entities/dashboard-layout.entity.js.map +1 -0
- package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts.map +1 -1
- package/dist/entities/dashboard-question-sql-dataset-config.entity.js +5 -4
- package/dist/entities/dashboard-question-sql-dataset-config.entity.js.map +1 -1
- package/dist/entities/dashboard-question.entity.d.ts.map +1 -1
- package/dist/entities/dashboard-question.entity.js +5 -4
- package/dist/entities/dashboard-question.entity.js.map +1 -1
- package/dist/entities/dashboard-variable.entity.d.ts +1 -0
- package/dist/entities/dashboard-variable.entity.d.ts.map +1 -1
- package/dist/entities/dashboard-variable.entity.js +10 -4
- package/dist/entities/dashboard-variable.entity.js.map +1 -1
- package/dist/entities/dashboard.entity.d.ts +2 -0
- package/dist/entities/dashboard.entity.d.ts.map +1 -1
- package/dist/entities/dashboard.entity.js +9 -3
- package/dist/entities/dashboard.entity.js.map +1 -1
- package/dist/entities/email-attachment.entity.d.ts.map +1 -1
- package/dist/entities/email-attachment.entity.js +2 -1
- package/dist/entities/email-attachment.entity.js.map +1 -1
- package/dist/entities/email-template.entity.js +1 -1
- package/dist/entities/email-template.entity.js.map +1 -1
- package/dist/entities/export-transaction.entity.d.ts.map +1 -1
- package/dist/entities/export-transaction.entity.js +2 -1
- package/dist/entities/export-transaction.entity.js.map +1 -1
- package/dist/entities/field-metadata.entity.js +2 -2
- package/dist/entities/field-metadata.entity.js.map +1 -1
- package/dist/entities/import-transaction-error-log.entity.d.ts.map +1 -1
- package/dist/entities/import-transaction-error-log.entity.js +3 -2
- package/dist/entities/import-transaction-error-log.entity.js.map +1 -1
- package/dist/entities/import-transaction.entity.d.ts.map +1 -1
- package/dist/entities/import-transaction.entity.js +2 -1
- package/dist/entities/import-transaction.entity.js.map +1 -1
- package/dist/entities/legacy-common.entity.d.ts.map +1 -1
- package/dist/entities/legacy-common.entity.js +1 -1
- package/dist/entities/legacy-common.entity.js.map +1 -1
- package/dist/entities/mq-message-queue.entity.d.ts.map +1 -1
- package/dist/entities/mq-message-queue.entity.js.map +1 -1
- package/dist/entities/mq-message.entity.d.ts.map +1 -1
- package/dist/entities/mq-message.entity.js +5 -3
- package/dist/entities/mq-message.entity.js.map +1 -1
- package/dist/entities/saved-filters.entity.d.ts.map +1 -1
- package/dist/entities/saved-filters.entity.js +3 -2
- package/dist/entities/saved-filters.entity.js.map +1 -1
- package/dist/entities/security-rule.entity.d.ts.map +1 -1
- package/dist/entities/security-rule.entity.js +2 -1
- package/dist/entities/security-rule.entity.js.map +1 -1
- package/dist/entities/sms-template.entity.js +1 -1
- package/dist/entities/sms-template.entity.js.map +1 -1
- package/dist/entities/user-view-metadata.entity.d.ts.map +1 -1
- package/dist/entities/user-view-metadata.entity.js +2 -1
- package/dist/entities/user-view-metadata.entity.js.map +1 -1
- package/dist/entities/user.entity.d.ts.map +1 -1
- package/dist/entities/user.entity.js +2 -0
- package/dist/entities/user.entity.js.map +1 -1
- package/dist/entities/view-metadata.entity.d.ts.map +1 -1
- package/dist/entities/view-metadata.entity.js.map +1 -1
- package/dist/helpers/bootstrap.helper.d.ts +14 -0
- package/dist/helpers/bootstrap.helper.d.ts.map +1 -0
- package/dist/helpers/bootstrap.helper.js +132 -0
- package/dist/helpers/bootstrap.helper.js.map +1 -0
- package/dist/helpers/cache.helper.d.ts +2 -0
- package/dist/helpers/cache.helper.d.ts.map +1 -0
- package/dist/helpers/cache.helper.js +8 -0
- package/dist/helpers/cache.helper.js.map +1 -0
- package/dist/helpers/cors.helper.d.ts.map +1 -1
- package/dist/helpers/cors.helper.js +13 -4
- package/dist/helpers/cors.helper.js.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts +2 -2
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js +8 -5
- package/dist/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.js.map +1 -1
- package/dist/helpers/solid-registry.d.ts +3 -0
- package/dist/helpers/solid-registry.d.ts.map +1 -1
- package/dist/helpers/solid-registry.js +7 -0
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
- package/dist/helpers/typeorm-db-helper.js +21 -0
- package/dist/helpers/typeorm-db-helper.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +6 -1
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/jobs/chatter-queue-options.js +1 -1
- package/dist/jobs/chatter-queue-options.js.map +1 -1
- package/dist/jobs/chatter-queue-publisher.service.d.ts +9 -9
- package/dist/jobs/chatter-queue-publisher.service.d.ts.map +1 -1
- package/dist/jobs/chatter-queue-publisher.service.js +5 -5
- package/dist/jobs/chatter-queue-publisher.service.js.map +1 -1
- package/dist/jobs/chatter-queue-subscriber.service.d.ts +4 -4
- package/dist/jobs/chatter-queue-subscriber.service.d.ts.map +1 -1
- package/dist/jobs/chatter-queue-subscriber.service.js +11 -11
- package/dist/jobs/chatter-queue-subscriber.service.js.map +1 -1
- package/dist/jobs/computed-field-evaluation-queue-options.d.ts +2 -0
- package/dist/jobs/computed-field-evaluation-queue-options.d.ts.map +1 -1
- package/dist/jobs/computed-field-evaluation-queue-options.js +2 -0
- package/dist/jobs/computed-field-evaluation-queue-options.js.map +1 -1
- package/dist/jobs/database/chatter-queue-options-database.d.ts +8 -0
- package/dist/jobs/database/chatter-queue-options-database.d.ts.map +1 -0
- package/dist/jobs/database/chatter-queue-options-database.js +10 -0
- package/dist/jobs/database/chatter-queue-options-database.js.map +1 -0
- package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts +12 -0
- package/dist/jobs/database/chatter-queue-publisher-database.service.d.ts.map +1 -0
- package/dist/jobs/database/chatter-queue-publisher-database.service.js +39 -0
- package/dist/jobs/database/chatter-queue-publisher-database.service.js.map +1 -0
- package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts +19 -0
- package/dist/jobs/database/chatter-queue-subscriber-database.service.d.ts.map +1 -0
- package/dist/jobs/database/chatter-queue-subscriber-database.service.js +62 -0
- package/dist/jobs/database/chatter-queue-subscriber-database.service.js.map +1 -0
- package/dist/repository/dashboard-layout.repository.d.ts +12 -0
- package/dist/repository/dashboard-layout.repository.d.ts.map +1 -0
- package/dist/repository/dashboard-layout.repository.js +34 -0
- package/dist/repository/dashboard-layout.repository.js.map +1 -0
- package/dist/repository/model-metadata.repository.d.ts +6 -1
- package/dist/repository/model-metadata.repository.d.ts.map +1 -1
- package/dist/repository/model-metadata.repository.js +41 -2
- package/dist/repository/model-metadata.repository.js.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +4 -4
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +445 -35
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +45 -21
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts +4 -4
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +59 -9
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts +7 -3
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.d.ts.map +1 -1
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js +61 -22
- package/dist/services/computed-fields/entity/sequence-num-computed-field-provider.js.map +1 -1
- package/dist/services/crud.service.js +1 -1
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/dashboard-layout.service.d.ts +20 -0
- package/dist/services/dashboard-layout.service.d.ts.map +1 -0
- package/dist/services/dashboard-layout.service.js +120 -0
- package/dist/services/dashboard-layout.service.js.map +1 -0
- package/dist/services/dashboard-question.service.d.ts +4 -0
- package/dist/services/dashboard-question.service.d.ts.map +1 -1
- package/dist/services/dashboard-question.service.js +22 -8
- package/dist/services/dashboard-question.service.js.map +1 -1
- package/dist/services/dashboard.service.d.ts +2 -0
- package/dist/services/dashboard.service.d.ts.map +1 -1
- package/dist/services/dashboard.service.js +4 -0
- package/dist/services/dashboard.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts +3 -1
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +122 -8
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/permission-metadata.service.d.ts +5 -1
- package/dist/services/permission-metadata.service.d.ts.map +1 -1
- package/dist/services/permission-metadata.service.js +66 -20
- package/dist/services/permission-metadata.service.js.map +1 -1
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts +2 -4
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts.map +1 -1
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js +2 -1
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js.map +1 -1
- package/dist/services/question-data-providers/interfaces.d.ts +1 -0
- package/dist/services/question-data-providers/interfaces.d.ts.map +1 -0
- package/dist/services/question-data-providers/interfaces.js +1 -0
- package/dist/services/question-data-providers/interfaces.js.map +1 -0
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts +2 -5
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts.map +1 -1
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js +2 -1
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js.map +1 -1
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts +2 -5
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts.map +1 -1
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js +2 -1
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js.map +1 -1
- package/dist/services/queues/database-subscriber.service.d.ts +4 -2
- package/dist/services/queues/database-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/database-subscriber.service.js +15 -2
- package/dist/services/queues/database-subscriber.service.js.map +1 -1
- package/dist/services/queues/publisher-factory.service.d.ts.map +1 -1
- package/dist/services/queues/publisher-factory.service.js +4 -7
- package/dist/services/queues/publisher-factory.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-publisher.service.d.ts +1 -0
- package/dist/services/queues/rabbitmq-publisher.service.d.ts.map +1 -1
- package/dist/services/queues/rabbitmq-publisher.service.js +6 -1
- package/dist/services/queues/rabbitmq-publisher.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts +9 -3
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.js +93 -10
- package/dist/services/queues/rabbitmq-subscriber.service.js.map +1 -1
- package/dist/services/request-context.service.d.ts +2 -1
- package/dist/services/request-context.service.d.ts.map +1 -1
- package/dist/services/request-context.service.js.map +1 -1
- package/dist/services/scheduled-job.service.d.ts +6 -1
- package/dist/services/scheduled-job.service.d.ts.map +1 -1
- package/dist/services/scheduled-job.service.js +26 -2
- package/dist/services/scheduled-job.service.js.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.interface.d.ts +2 -0
- package/dist/services/scheduled-jobs/scheduler.interface.d.ts.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.interface.js.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.d.ts +6 -2
- package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.js +75 -17
- package/dist/services/scheduled-jobs/scheduler.service.js.map +1 -1
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.d.ts.map +1 -1
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js +4 -1
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js.map +1 -1
- package/dist/services/solid-introspect.service.d.ts +6 -1
- package/dist/services/solid-introspect.service.d.ts.map +1 -1
- package/dist/services/solid-introspect.service.js +27 -2
- package/dist/services/solid-introspect.service.js.map +1 -1
- package/dist/services/solid-ts-morph.service.d.ts +9 -0
- package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
- package/dist/services/solid-ts-morph.service.js +76 -0
- package/dist/services/solid-ts-morph.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +16 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/audit.subscriber.d.ts +10 -7
- package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
- package/dist/subscribers/audit.subscriber.js +58 -85
- package/dist/subscribers/audit.subscriber.js.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.js +3 -1
- package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
- package/dist/subscribers/created-by-updated-by.subscriber.d.ts +0 -1
- package/dist/subscribers/created-by-updated-by.subscriber.d.ts.map +1 -1
- package/dist/subscribers/created-by-updated-by.subscriber.js +3 -13
- package/dist/subscribers/created-by-updated-by.subscriber.js.map +1 -1
- package/dist/transformers/typeorm/local-date-time-transformer.d.ts +4 -4
- package/dist/transformers/typeorm/local-date-time-transformer.d.ts.map +1 -1
- package/dist/transformers/typeorm/local-date-time-transformer.js +25 -28
- package/dist/transformers/typeorm/local-date-time-transformer.js.map +1 -1
- package/dist/winston.logger.d.ts.map +1 -1
- package/dist/winston.logger.js +2 -1
- package/dist/winston.logger.js.map +1 -1
- package/package.json +3 -1
- package/sql/default/mariadb/proc_CleanupModelMetadata.sql +153 -0
- package/sql/default/mariadb/proc_CleanupModuleMetadata.sql +56 -0
- package/sql/default/mysql/proc_CleanupModelMetadata.sql +153 -0
- package/sql/default/mysql/proc_CleanupModuleMetadata.sql +56 -0
- package/src/controllers/dashboard-layout.controller.ts +106 -0
- package/src/controllers/scheduled-job.controller.ts +6 -0
- package/src/dtos/create-dashboard-layout.dto.ts +31 -0
- package/src/dtos/create-dashboard-variable.dto.ts +4 -0
- package/src/dtos/update-dashboard-layout.dto.ts +30 -0
- package/src/dtos/update-dashboard-variable.dto.ts +5 -1
- package/src/entities/action-metadata.entity.ts +3 -2
- package/src/entities/ai-interaction.entity.ts +5 -4
- package/src/entities/chatter-message-details.entity.ts +7 -3
- package/src/entities/chatter-message.entity.ts +4 -3
- package/src/entities/common.entity.ts +2 -2
- package/src/entities/dashboard-layout.entity.ts +18 -0
- package/src/entities/dashboard-question-sql-dataset-config.entity.ts +5 -4
- package/src/entities/dashboard-question.entity.ts +5 -4
- package/src/entities/dashboard-variable.entity.ts +9 -4
- package/src/entities/dashboard.entity.ts +7 -2
- package/src/entities/email-attachment.entity.ts +2 -1
- package/src/entities/email-template.entity.ts +1 -1
- package/src/entities/export-transaction.entity.ts +2 -1
- package/src/entities/field-metadata.entity.ts +2 -2
- package/src/entities/import-transaction-error-log.entity.ts +3 -2
- package/src/entities/import-transaction.entity.ts +2 -1
- package/src/entities/legacy-common.entity.ts +3 -4
- package/src/entities/mq-message-queue.entity.ts +8 -8
- package/src/entities/mq-message.entity.ts +5 -3
- package/src/entities/saved-filters.entity.ts +3 -2
- package/src/entities/security-rule.entity.ts +2 -1
- package/src/entities/sms-template.entity.ts +1 -1
- package/src/entities/user-view-metadata.entity.ts +2 -1
- package/src/entities/user.entity.ts +37 -2
- package/src/entities/view-metadata.entity.ts +3 -0
- package/src/helpers/bootstrap.helper.ts +222 -0
- package/src/helpers/cache.helper.ts +5 -0
- package/src/helpers/cors.helper.ts +26 -6
- package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +9 -6
- package/src/helpers/solid-registry.ts +10 -5
- package/src/helpers/typeorm-db-helper.ts +26 -0
- package/src/index.ts +3 -0
- package/src/interfaces.ts +10 -1
- package/src/jobs/chatter-queue-options.ts +1 -1
- package/src/jobs/chatter-queue-publisher.service.ts +11 -11
- package/src/jobs/chatter-queue-subscriber.service.ts +13 -8
- package/src/jobs/computed-field-evaluation-queue-options.ts +2 -0
- package/src/jobs/database/chatter-queue-options-database.ts +9 -0
- package/src/jobs/database/chatter-queue-publisher-database.service.ts +24 -0
- package/src/jobs/database/chatter-queue-subscriber-database.service.ts +53 -0
- package/src/repository/dashboard-layout.repository.ts +17 -0
- package/src/repository/model-metadata.repository.ts +45 -2
- package/src/seeders/module-metadata-seeder.service.ts +5 -5
- package/src/seeders/seed-data/solid-core-metadata.json +446 -36
- package/src/services/authentication.service.ts +47 -24
- package/src/services/chatter-message.service.ts +67 -9
- package/src/services/computed-fields/entity/sequence-num-computed-field-provider.ts +79 -40
- package/src/services/crud.service.ts +1 -1
- package/src/services/dashboard-layout.service.ts +111 -0
- package/src/services/dashboard-question.service.ts +23 -4
- package/src/services/dashboard.service.ts +7 -0
- package/src/services/model-metadata.service.ts +131 -50
- package/src/services/permission-metadata.service.ts +73 -20
- package/src/services/question-data-providers/chartjs-sql-data-provider.service.ts +3 -7
- package/src/services/question-data-providers/interfaces.ts +0 -0
- package/src/services/question-data-providers/prime-react-datatable-sql-data-provider.service.ts +4 -8
- package/src/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.ts +4 -8
- package/src/services/queues/database-subscriber.service.ts +19 -2
- package/src/services/queues/publisher-factory.service.ts +9 -7
- package/src/services/queues/rabbitmq-publisher.service.ts +8 -2
- package/src/services/queues/rabbitmq-subscriber.service.ts +139 -11
- package/src/services/request-context.service.ts +2 -1
- package/src/services/scheduled-job.service.ts +31 -2
- package/src/services/scheduled-jobs/scheduler.interface.ts +4 -1
- package/src/services/scheduled-jobs/scheduler.service.ts +82 -20
- package/src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts +4 -1
- package/src/services/solid-introspect.service.ts +28 -0
- package/src/services/solid-ts-morph.service.ts +98 -0
- package/src/solid-core.module.ts +21 -2
- package/src/subscribers/audit.subscriber.ts +63 -271
- package/src/subscribers/computed-entity-field.subscriber.ts +3 -3
- package/src/subscribers/created-by-updated-by.subscriber.ts +22 -16
- package/src/transformers/typeorm/local-date-time-transformer.ts +41 -33
- package/src/winston.logger.ts +2 -1
|
@@ -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
|
-
|
|
19
|
+
|
|
20
|
+
@Index()
|
|
19
21
|
@Column({ type: "varchar", nullable: true })
|
|
20
22
|
@Expose()
|
|
21
23
|
email: string;
|
|
22
|
-
|
|
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
|
+
}
|
|
@@ -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
|
-
|
|
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)
|
|
27
|
-
|
|
28
|
-
|
|
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}:
|
|
@@ -7,7 +7,7 @@ export interface SelectionDynamicFieldOptions {
|
|
|
7
7
|
selectionDynamicProvider: string;
|
|
8
8
|
selectionValueType: SelectionValueType;
|
|
9
9
|
required: boolean | undefined | null;
|
|
10
|
-
selectionDynamicProviderCtxt:
|
|
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
|
|
89
|
-
|
|
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,
|
|
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('',
|
|
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
|
|
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)[];
|
|
@@ -9,6 +9,29 @@ const LONG_TEXT_MAP: Record<DatasourceType, ColumnOptions> = {
|
|
|
9
9
|
[DatasourceType.oracle]: { type: "clob" },
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
+
// For simple-json columns that may contain large payloads: on MySQL/MariaDB the default
|
|
13
|
+
// TEXT backing store is limited to 64 KB, so we override the type to longtext and supply
|
|
14
|
+
// an explicit JSON transformer so TypeORM still serialises/deserialises correctly.
|
|
15
|
+
const SIMPLE_JSON_LARGE_TEXT_MAP: Record<DatasourceType, ColumnOptions> = {
|
|
16
|
+
[DatasourceType.postgres]: {},
|
|
17
|
+
[DatasourceType.mssql]: {},
|
|
18
|
+
[DatasourceType.mysql]: {
|
|
19
|
+
type: "longtext",
|
|
20
|
+
transformer: {
|
|
21
|
+
to: (value: any) => (value !== undefined && value !== null ? JSON.stringify(value) : value),
|
|
22
|
+
from: (value: any) => (value !== null && value !== undefined ? JSON.parse(value) : value),
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
[DatasourceType.mariadb]: {
|
|
26
|
+
type: "longtext",
|
|
27
|
+
transformer: {
|
|
28
|
+
to: (value: any) => (value !== undefined && value !== null ? JSON.stringify(value) : value),
|
|
29
|
+
from: (value: any) => (value !== null && value !== undefined ? JSON.parse(value) : value),
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
[DatasourceType.oracle]: { type: "clob" },
|
|
33
|
+
};
|
|
34
|
+
|
|
12
35
|
const solidCoreDbType: DatasourceType =
|
|
13
36
|
Object.values(DatasourceType).includes(process.env.SOLID_CORE_DB_TYPE as DatasourceType)
|
|
14
37
|
? (process.env.SOLID_CORE_DB_TYPE as DatasourceType)
|
|
@@ -20,6 +43,9 @@ export function getColumnType(solidType: string): ColumnOptions {
|
|
|
20
43
|
case "richText":
|
|
21
44
|
return LONG_TEXT_MAP[solidCoreDbType];
|
|
22
45
|
|
|
46
|
+
case "simpleJsonLargeText":
|
|
47
|
+
return SIMPLE_JSON_LARGE_TEXT_MAP[solidCoreDbType];
|
|
48
|
+
|
|
23
49
|
default:
|
|
24
50
|
return {};
|
|
25
51
|
}
|
package/src/index.ts
CHANGED
|
@@ -137,6 +137,7 @@ export * from './entities/user-activity-history.entity'
|
|
|
137
137
|
export * from './entities/dashboard.entity'
|
|
138
138
|
export * from './entities/dashboard-variable.entity'
|
|
139
139
|
export * from './entities/dashboard-question.entity'
|
|
140
|
+
export * from './entities/dashboard-layout.entity'
|
|
140
141
|
export * from './entities/dashboard-question-sql-dataset-config.entity'
|
|
141
142
|
export * from './entities/ai-interaction.entity'
|
|
142
143
|
export * from './entities/model-sequence.entity'
|
|
@@ -175,7 +176,9 @@ export * from './helpers/field-crud-managers/SelectionDynamicFieldCrudManager' /
|
|
|
175
176
|
export * from './helpers/field-crud-managers/SelectionStaticFieldCrudManager' //rename
|
|
176
177
|
export * from './helpers/field-crud-managers/ShortTextFieldCrudManager' //rename
|
|
177
178
|
export * from './helpers/field-crud-managers/UUIDFieldCrudManager' //rename
|
|
179
|
+
export * from './helpers/bootstrap.helper'
|
|
178
180
|
export * from './helpers/environment.helper'
|
|
181
|
+
export * from './helpers/cache.helper'
|
|
179
182
|
export * from './helpers/cors.helper'
|
|
180
183
|
export * from './helpers/security.helper'
|
|
181
184
|
export * from './helpers/model-metadata-helper.service'
|
package/src/interfaces.ts
CHANGED
|
@@ -111,6 +111,8 @@ export interface ISelectionProviderContext {
|
|
|
111
111
|
limit: number;
|
|
112
112
|
offset: number;
|
|
113
113
|
formValues: Record<string, any>;
|
|
114
|
+
//Attribute to control the validation on creating the record
|
|
115
|
+
validateOnSave?: boolean;
|
|
114
116
|
// query: string;
|
|
115
117
|
}
|
|
116
118
|
|
|
@@ -136,12 +138,18 @@ export interface IMcpToolResponseHandler {
|
|
|
136
138
|
apply(aiInteraction: AiInteraction);
|
|
137
139
|
}
|
|
138
140
|
|
|
141
|
+
export interface QuestionSqlDataProviderContext {
|
|
142
|
+
// questionSqlDatasetConfig: QuestionSqlDatasetConfig;
|
|
143
|
+
// questionId: number;
|
|
144
|
+
// question: Question;
|
|
145
|
+
expressions?: SqlExpression[]
|
|
146
|
+
}
|
|
139
147
|
export interface IDashboardQuestionDataProvider<TContext, TData> {
|
|
140
148
|
help(): string;
|
|
141
149
|
|
|
142
150
|
name(): string;
|
|
143
151
|
|
|
144
|
-
getData(question: DashboardQuestion,
|
|
152
|
+
getData(question: DashboardQuestion, ctxt?: TContext): Promise<TData[] | TData>;
|
|
145
153
|
}
|
|
146
154
|
|
|
147
155
|
/**
|
|
@@ -263,6 +271,7 @@ export interface QueuesModuleOptions {
|
|
|
263
271
|
type: BrokerType;
|
|
264
272
|
queueName: string;
|
|
265
273
|
prefetch?: number;
|
|
274
|
+
persistToDatabase?: boolean;
|
|
266
275
|
}
|
|
267
276
|
|
|
268
277
|
export type MediaWithFullUrl = Media & {
|
|
@@ -7,21 +7,21 @@ import { MqMessageService } from '../services/mq-message.service';
|
|
|
7
7
|
import { QueuesModuleOptions } from "../interfaces";
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
export type
|
|
10
|
+
export type AuditEventType = 'insert' | 'update' | 'delete';
|
|
11
11
|
|
|
12
|
-
export interface
|
|
13
|
-
eventType:
|
|
14
|
-
|
|
15
|
-
entityId: string
|
|
16
|
-
occurredAt: string;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
userId?:
|
|
12
|
+
export interface AuditQueuePayload {
|
|
13
|
+
eventType: AuditEventType;
|
|
14
|
+
modelName: string; // TypeORM entity class name (e.g. 'Order')
|
|
15
|
+
entityId: string | number | null;
|
|
16
|
+
occurredAt: string; // ISO timestamp, captured at event time
|
|
17
|
+
after?: any; // entity state after operation (insert/update)
|
|
18
|
+
before?: any; // entity state before operation (update/delete)
|
|
19
|
+
updatedColumnNames?: string[]; // propertyNames of changed columns (update only)
|
|
20
|
+
userId?: number | null; // active user captured at event time
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
@Injectable()
|
|
24
|
-
export class
|
|
24
|
+
export class ChatterQueuePublisherRabbitmq extends RabbitMqPublisher<AuditQueuePayload> {
|
|
25
25
|
constructor(
|
|
26
26
|
protected readonly mqMessageService: MqMessageService,
|
|
27
27
|
protected readonly mqMessageQueueService: MqMessageQueueService,
|