@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
|
@@ -15,6 +15,7 @@ import { SolidRegistry } from 'src/helpers/solid-registry';
|
|
|
15
15
|
import { DashboardMapper } from 'src/mappers/dashboard-mapper';
|
|
16
16
|
import { DashboardRepository } from 'src/repository/dashboard.repository';
|
|
17
17
|
import { Dashboard } from '../entities/dashboard.entity';
|
|
18
|
+
import { CreateDashboardDto } from 'src/dtos/create-dashboard.dto';
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
export const SQL_DYNAMIC_PROVIDER_NAME = 'DashboardVariableSQLDynamicProvider';
|
|
@@ -33,6 +34,12 @@ export class DashboardService extends CRUDService<Dashboard> {
|
|
|
33
34
|
super(entityManager, repo, 'dashboard', 'solid-core', moduleRef);
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
|
|
38
|
+
async create(createDto: CreateDashboardDto, files: Express.Multer.File[]) {
|
|
39
|
+
createDto.name = createDto.name.trim().replace(/\s+/g, '-').toLowerCase();
|
|
40
|
+
return super.create(createDto, files);
|
|
41
|
+
}
|
|
42
|
+
|
|
36
43
|
async getSelectionDynamicValues(query: DashboardVariableSelectionDynamicQueryDto) {
|
|
37
44
|
// Get the dashboard variable repo
|
|
38
45
|
const dashboardVariable = await this.loadDashboardVariable(query.variableId);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BadRequestException, forwardRef, Inject, Injectable, Logger, NotFoundException } from '@nestjs/common';
|
|
2
2
|
import { InjectDataSource } from '@nestjs/typeorm';
|
|
3
3
|
import * as fs from 'fs/promises'; // Use the Promise-based version of fs for async/await
|
|
4
|
+
import * as path from 'path';
|
|
4
5
|
import { DataSource, EntityManager, In, Repository, SelectQueryBuilder } from 'typeorm';
|
|
5
6
|
import { CreateModelMetadataDto } from '../dtos/create-model-metadata.dto';
|
|
6
7
|
import { ModelMetadata } from '../entities/model-metadata.entity';
|
|
@@ -33,6 +34,7 @@ import { RoleMetadataService } from './role-metadata.service';
|
|
|
33
34
|
import { NavigationDto } from 'src/dtos/navigation.dto';
|
|
34
35
|
import { SolidIntrospectService } from './solid-introspect.service';
|
|
35
36
|
import { CRUDService } from './crud.service';
|
|
37
|
+
import { SolidTsMorphService } from './solid-ts-morph.service';
|
|
36
38
|
|
|
37
39
|
@Injectable()
|
|
38
40
|
export class ModelMetadataService {
|
|
@@ -54,8 +56,9 @@ export class ModelMetadataService {
|
|
|
54
56
|
private readonly roleService: RoleMetadataService,
|
|
55
57
|
private readonly moduleMetadataHelperService: ModuleMetadataHelperService,
|
|
56
58
|
readonly introspectService: SolidIntrospectService,
|
|
59
|
+
private readonly solidTsMorphService: SolidTsMorphService,
|
|
57
60
|
|
|
58
|
-
// No longer used.
|
|
61
|
+
// No longer used.
|
|
59
62
|
// private readonly generateCodePublihser: GenerateCodePublisherDatabase,
|
|
60
63
|
) { }
|
|
61
64
|
|
|
@@ -225,6 +228,7 @@ export class ModelMetadataService {
|
|
|
225
228
|
let userKeyField = null;
|
|
226
229
|
const listViewLayout = [];
|
|
227
230
|
const formViewLayout = [];
|
|
231
|
+
const treeViewLayout = [];
|
|
228
232
|
|
|
229
233
|
for (let k = 0; k < fieldsMetadata.length; k++) {
|
|
230
234
|
const fieldMetadata = fieldsMetadata[k];
|
|
@@ -245,6 +249,7 @@ export class ModelMetadataService {
|
|
|
245
249
|
}
|
|
246
250
|
listViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}` } })
|
|
247
251
|
formViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}` } })
|
|
252
|
+
treeViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}` } })
|
|
248
253
|
|
|
249
254
|
}
|
|
250
255
|
|
|
@@ -705,48 +710,24 @@ export class ModelMetadataService {
|
|
|
705
710
|
await fs.writeFile(filePath, updatedContent);
|
|
706
711
|
}
|
|
707
712
|
|
|
708
|
-
// <moduleName>.module.ts | Remove all references and imports of the
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
// const objectLiteral = moduleDecorator?.getCallExpression()?.getArguments()?.[0];
|
|
727
|
-
|
|
728
|
-
// if (objectLiteral && objectLiteral.getKind() === SyntaxKind.ObjectLiteralExpression) {
|
|
729
|
-
// const objectLiteralExpr = objectLiteral.asKindOrThrow(SyntaxKind.ObjectLiteralExpression);
|
|
730
|
-
|
|
731
|
-
// for (const propName of ['imports', 'providers', 'controllers', 'exports']) {
|
|
732
|
-
// const prop = objectLiteralExpr.getProperty(propName);
|
|
733
|
-
// if (prop && prop.getKind() === SyntaxKind.PropertyAssignment) {
|
|
734
|
-
// const elements = prop.getFirstDescendantByKind(SyntaxKind.ArrayLiteralExpression);
|
|
735
|
-
// elements?.getElements().forEach(el => {
|
|
736
|
-
// const text = el.getText();
|
|
737
|
-
// if (filesToDelete.some(file => text.toLowerCase().includes(file.split('.')[0]))) {
|
|
738
|
-
// // @ts-ignore
|
|
739
|
-
// el.remove();
|
|
740
|
-
// }
|
|
741
|
-
// });
|
|
742
|
-
// }
|
|
743
|
-
// }
|
|
744
|
-
// }
|
|
745
|
-
|
|
746
|
-
// // Save changes
|
|
747
|
-
// sourceFile.saveSync();
|
|
748
|
-
|
|
749
|
-
// Run seeder to reflect the removal.
|
|
713
|
+
// <moduleName>.module.ts | Remove all references and imports of the deleted model files. | Automatic
|
|
714
|
+
if (modulePath) {
|
|
715
|
+
const moduleFilePath = path.resolve(modulePath, `${dasherize(modelEntity.module?.name)}.module.ts`);
|
|
716
|
+
this.logger.log(`Removing model '${modelEntity.singularName}' references from module file: ${moduleFilePath}`);
|
|
717
|
+
try {
|
|
718
|
+
this.solidTsMorphService.begin();
|
|
719
|
+
const modelPathSegment = `/${dasherize(modelEntity.singularName)}.`;
|
|
720
|
+
const { removedIdentifiers } = this.solidTsMorphService.removeImports(
|
|
721
|
+
moduleFilePath,
|
|
722
|
+
spec => spec.includes(modelPathSegment)
|
|
723
|
+
);
|
|
724
|
+
this.solidTsMorphService.removeModuleMembers(moduleFilePath, removedIdentifiers);
|
|
725
|
+
await this.solidTsMorphService.commit();
|
|
726
|
+
} catch (error) {
|
|
727
|
+
this.solidTsMorphService.rollback();
|
|
728
|
+
this.logger.error(`Failed to clean up module file for model '${modelEntity.singularName}':`, error);
|
|
729
|
+
}
|
|
730
|
+
}
|
|
750
731
|
|
|
751
732
|
// - | Drop database table | Removes the database table from the DB, this is a very risky step. Best to review all relations to other models etc and then do this manually | Manual (X)
|
|
752
733
|
|
|
@@ -818,6 +799,7 @@ export class ModelMetadataService {
|
|
|
818
799
|
const metaData = await this.moduleMetadataHelperService.getModuleMetadataConfiguration(filePath);
|
|
819
800
|
|
|
820
801
|
const listViewLayoutFields = [{ type: "field", attrs: { name: `id` } }];
|
|
802
|
+
const treeViewLayoutFields = [{ type: "field", attrs: { name: `id` } }];
|
|
821
803
|
const formViewLayoutFields = [];
|
|
822
804
|
|
|
823
805
|
for (let i = 0; i < model.fields.length; i++) {
|
|
@@ -825,8 +807,9 @@ export class ModelMetadataService {
|
|
|
825
807
|
if (field.isSystem) continue;
|
|
826
808
|
listViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}` } })
|
|
827
809
|
formViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}` } })
|
|
810
|
+
treeViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}` } })
|
|
828
811
|
}
|
|
829
|
-
this.populateVAMConfigInFileInternal(formViewLayoutFields, model, listViewLayoutFields, metaData);
|
|
812
|
+
this.populateVAMConfigInFileInternal(formViewLayoutFields, model, listViewLayoutFields, treeViewLayoutFields, metaData);
|
|
830
813
|
// Write the updated object back to the file
|
|
831
814
|
const updatedContent = JSON.stringify(metaData, null, 2);
|
|
832
815
|
await fs.writeFile(filePath, updatedContent);
|
|
@@ -839,7 +822,7 @@ export class ModelMetadataService {
|
|
|
839
822
|
}
|
|
840
823
|
|
|
841
824
|
// Populate the View, Actions and Menus in the config file
|
|
842
|
-
private populateVAMConfigInFileInternal(formViewLayoutFields: any[], model: ModelMetadata, listViewLayoutFields: { type: string; attrs: { name: string; }; }[], metaData: any) {
|
|
825
|
+
private populateVAMConfigInFileInternal(formViewLayoutFields: any[], model: ModelMetadata, listViewLayoutFields: { type: string; attrs: { name: string; }; }[], treeViewLayoutFields: { type: string; attrs: { name: string; }; }[], metaData: any) {
|
|
843
826
|
const column1Fields = [];
|
|
844
827
|
const column2Fields = [];
|
|
845
828
|
|
|
@@ -852,7 +835,9 @@ export class ModelMetadataService {
|
|
|
852
835
|
}
|
|
853
836
|
}
|
|
854
837
|
const actionName = `${model.singularName}-list-action`;
|
|
855
|
-
const
|
|
838
|
+
const treeViewActionName = `${model.singularName}-tree-view-action`;
|
|
839
|
+
const listViewName = `${model.singularName}-list-view`;
|
|
840
|
+
const treeViewName = `${model.singularName}-tree-view`;
|
|
856
841
|
const formViewName = `${model.singularName}-form-view`;
|
|
857
842
|
const menuName = `${model.singularName}-menu-item`;
|
|
858
843
|
|
|
@@ -865,7 +850,21 @@ export class ModelMetadataService {
|
|
|
865
850
|
customComponent: ``,
|
|
866
851
|
customIsModal: true,
|
|
867
852
|
serverEndpoint: "",
|
|
868
|
-
viewUserKey:
|
|
853
|
+
viewUserKey: listViewName,
|
|
854
|
+
moduleUserKey: `${model.module.name}`,
|
|
855
|
+
modelUserKey: `${model.singularName}`
|
|
856
|
+
};
|
|
857
|
+
|
|
858
|
+
const treeViewAction = {
|
|
859
|
+
displayName: `${model.displayName} Tree View Action`,
|
|
860
|
+
name: treeViewActionName,
|
|
861
|
+
type: "solid",
|
|
862
|
+
domain: "",
|
|
863
|
+
context: "",
|
|
864
|
+
customComponent: ``,
|
|
865
|
+
customIsModal: true,
|
|
866
|
+
serverEndpoint: "",
|
|
867
|
+
viewUserKey: treeViewName,
|
|
869
868
|
moduleUserKey: `${model.module.name}`,
|
|
870
869
|
modelUserKey: `${model.singularName}`
|
|
871
870
|
};
|
|
@@ -877,11 +876,11 @@ export class ModelMetadataService {
|
|
|
877
876
|
actionUserKey: actionName,
|
|
878
877
|
moduleUserKey: `${model.module.name}`,
|
|
879
878
|
parentMenuItemUserKey: "",
|
|
880
|
-
iconName
|
|
879
|
+
iconName: ""
|
|
881
880
|
};
|
|
882
881
|
|
|
883
882
|
const modelListview = {
|
|
884
|
-
name:
|
|
883
|
+
name: listViewName,
|
|
885
884
|
displayName: `${model.displayName}`,
|
|
886
885
|
type: "list",
|
|
887
886
|
context: "{}",
|
|
@@ -905,6 +904,31 @@ export class ModelMetadataService {
|
|
|
905
904
|
}
|
|
906
905
|
};
|
|
907
906
|
|
|
907
|
+
const modelTreeview = {
|
|
908
|
+
name: treeViewName,
|
|
909
|
+
displayName: `${model.displayName}`,
|
|
910
|
+
type: "tree",
|
|
911
|
+
context: "{}",
|
|
912
|
+
moduleUserKey: `${model.module.name}`,
|
|
913
|
+
modelUserKey: `${model.singularName}`,
|
|
914
|
+
layout: {
|
|
915
|
+
type: "tree",
|
|
916
|
+
attrs: {
|
|
917
|
+
pagination: true,
|
|
918
|
+
pageSizeOptions: [
|
|
919
|
+
10,
|
|
920
|
+
25,
|
|
921
|
+
50
|
|
922
|
+
],
|
|
923
|
+
enableGlobalSearch: true,
|
|
924
|
+
create: true,
|
|
925
|
+
edit: true,
|
|
926
|
+
delete: true
|
|
927
|
+
},
|
|
928
|
+
children: treeViewLayoutFields
|
|
929
|
+
}
|
|
930
|
+
};
|
|
931
|
+
|
|
908
932
|
|
|
909
933
|
const modelFormView = {
|
|
910
934
|
name: formViewName,
|
|
@@ -954,10 +978,18 @@ export class ModelMetadataService {
|
|
|
954
978
|
metaData.actions.push(action);
|
|
955
979
|
}
|
|
956
980
|
|
|
957
|
-
if (notExists(metaData.
|
|
981
|
+
if (notExists(metaData.actions, treeViewActionName)) {
|
|
982
|
+
metaData.actions.push(treeViewAction);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
if (notExists(metaData.views, listViewName)) {
|
|
958
986
|
metaData.views.push(modelListview);
|
|
959
987
|
}
|
|
960
988
|
|
|
989
|
+
if (notExists(metaData.views, treeViewName)) {
|
|
990
|
+
metaData.views.push(modelTreeview);
|
|
991
|
+
}
|
|
992
|
+
|
|
961
993
|
if (notExists(metaData.views, formViewName)) {
|
|
962
994
|
metaData.views.push(modelFormView);
|
|
963
995
|
}
|
|
@@ -979,6 +1011,14 @@ export class ModelMetadataService {
|
|
|
979
1011
|
}
|
|
980
1012
|
}));
|
|
981
1013
|
|
|
1014
|
+
const treeViewLayout = jsonFieldsList.map(field => ({
|
|
1015
|
+
type: "field",
|
|
1016
|
+
attrs: {
|
|
1017
|
+
name: `${field.name}`,
|
|
1018
|
+
isSearchable: true,
|
|
1019
|
+
}
|
|
1020
|
+
}));
|
|
1021
|
+
|
|
982
1022
|
const formViewLayout = jsonFieldsList.map(field => ({
|
|
983
1023
|
type: "field",
|
|
984
1024
|
attrs: {
|
|
@@ -1019,6 +1059,26 @@ export class ModelMetadataService {
|
|
|
1019
1059
|
children: listViewLayout
|
|
1020
1060
|
}, null, 3)
|
|
1021
1061
|
},
|
|
1062
|
+
{
|
|
1063
|
+
name: `${model.singularName}-tree-view`,
|
|
1064
|
+
displayName: `${model.displayName}`,
|
|
1065
|
+
type: 'tree',
|
|
1066
|
+
context: "{}",
|
|
1067
|
+
module: resolvedModule,
|
|
1068
|
+
model: model,
|
|
1069
|
+
layout: JSON.stringify({
|
|
1070
|
+
type: "tree",
|
|
1071
|
+
attrs: {
|
|
1072
|
+
pagination: true,
|
|
1073
|
+
pageSizeOptions: [10, 25, 50],
|
|
1074
|
+
enableGlobalSearch: true,
|
|
1075
|
+
create: true,
|
|
1076
|
+
edit: true,
|
|
1077
|
+
delete: true
|
|
1078
|
+
},
|
|
1079
|
+
children: treeViewLayout
|
|
1080
|
+
}, null, 3)
|
|
1081
|
+
},
|
|
1022
1082
|
{
|
|
1023
1083
|
name: `${model.singularName}-form-view`,
|
|
1024
1084
|
displayName: `${model.displayName}`,
|
|
@@ -1067,6 +1127,7 @@ export class ModelMetadataService {
|
|
|
1067
1127
|
}
|
|
1068
1128
|
|
|
1069
1129
|
let view = await viewRepo.findOne({ where: { name: `${model.singularName}-list-view` } });
|
|
1130
|
+
let treeView = await viewRepo.findOne({ where: { name: `${model.singularName}-tree-view` } });
|
|
1070
1131
|
|
|
1071
1132
|
const actionData = {
|
|
1072
1133
|
displayName: `${model.displayName} List Action`,
|
|
@@ -1082,13 +1143,33 @@ export class ModelMetadataService {
|
|
|
1082
1143
|
model: model
|
|
1083
1144
|
};
|
|
1084
1145
|
|
|
1146
|
+
const treeViewActionData = {
|
|
1147
|
+
displayName: `${model.displayName} Tree View Action`,
|
|
1148
|
+
name: `${model.singularName}-tree-view-action`,
|
|
1149
|
+
type: "solid",
|
|
1150
|
+
domain: "",
|
|
1151
|
+
context: "",
|
|
1152
|
+
customComponent: ``,
|
|
1153
|
+
customIsModal: true,
|
|
1154
|
+
serverEndpoint: "",
|
|
1155
|
+
view: treeView,
|
|
1156
|
+
module: resolvedModule,
|
|
1157
|
+
model: model
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1085
1160
|
let existingAction = await actionRepo.findOne({ where: { name: actionData.name } });
|
|
1161
|
+
let existingTreeViewAction = await actionRepo.findOne({ where: { name: treeViewActionData.name } });
|
|
1086
1162
|
|
|
1087
1163
|
if (!existingAction) {
|
|
1088
1164
|
const createdAction = actionRepo.create(actionData);
|
|
1089
1165
|
existingAction = await actionRepo.save(createdAction);
|
|
1090
1166
|
}
|
|
1091
1167
|
|
|
1168
|
+
if (!existingTreeViewAction) {
|
|
1169
|
+
const createdTreeViewAction = actionRepo.create(treeViewActionData);
|
|
1170
|
+
existingTreeViewAction = await actionRepo.save(createdTreeViewAction);
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1092
1173
|
const adminRole = await this.roleService.findRoleByName('Admin');
|
|
1093
1174
|
|
|
1094
1175
|
const menuData = {
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { Injectable } from '@nestjs/common';
|
|
1
|
+
import { Inject, Injectable, Logger } from '@nestjs/common';
|
|
2
|
+
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
|
2
3
|
import { ModuleRef } from "@nestjs/core";
|
|
3
4
|
import { InjectEntityManager } from '@nestjs/typeorm';
|
|
5
|
+
import { Cache } from 'cache-manager';
|
|
4
6
|
import { CRUDService } from 'src/services/crud.service';
|
|
7
|
+
import { shouldUseCache } from 'src/helpers/cache.helper';
|
|
5
8
|
import { EntityManager, In } from 'typeorm';
|
|
6
9
|
|
|
7
10
|
|
|
@@ -10,42 +13,92 @@ import { PermissionMetadata } from '../entities/permission-metadata.entity';
|
|
|
10
13
|
|
|
11
14
|
@Injectable()
|
|
12
15
|
export class PermissionMetadataService extends CRUDService<PermissionMetadata> {
|
|
16
|
+
private readonly logger = new Logger(PermissionMetadataService.name);
|
|
13
17
|
constructor(
|
|
14
18
|
@InjectEntityManager()
|
|
15
19
|
readonly entityManager: EntityManager,
|
|
16
20
|
// @InjectRepository(PermissionMetadata, 'default')
|
|
17
21
|
// readonly repo: Repository<PermissionMetadata>,
|
|
18
22
|
readonly repo: PermissionMetadataRepository,
|
|
19
|
-
readonly moduleRef: ModuleRef
|
|
20
|
-
|
|
23
|
+
readonly moduleRef: ModuleRef,
|
|
24
|
+
@Inject(CACHE_MANAGER) private readonly cacheManager: Cache,
|
|
21
25
|
) {
|
|
22
26
|
super(entityManager, repo, 'permissionMetadata', 'solid-core',moduleRef);
|
|
23
27
|
}
|
|
24
28
|
|
|
29
|
+
private buildPermissionsByRoleCacheKey(roleName: string): string {
|
|
30
|
+
return `permissions:role:${roleName}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async findAllUsingRoles(roles: string[]): Promise<PermissionMetadata[]> {
|
|
34
|
+
const useCache = shouldUseCache();
|
|
35
|
+
const cached: PermissionMetadata[] = [];
|
|
36
|
+
const uncachedRoles: string[] = [];
|
|
25
37
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
if (useCache) {
|
|
39
|
+
for (const role of roles) {
|
|
40
|
+
const cacheKey = this.buildPermissionsByRoleCacheKey(role);
|
|
41
|
+
const hit = await this.cacheManager.get<PermissionMetadata[]>(cacheKey);
|
|
42
|
+
if (hit) {
|
|
43
|
+
// this.logger.debug(`Cache hit for findAllUsingRoles: key=${cacheKey}`);
|
|
44
|
+
cached.push(...hit);
|
|
45
|
+
} else {
|
|
46
|
+
// this.logger.debug(`Cache miss for findAllUsingRoles: key=${cacheKey}`);
|
|
47
|
+
uncachedRoles.push(role);
|
|
31
48
|
}
|
|
32
|
-
}
|
|
33
|
-
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
uncachedRoles.push(...roles);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (uncachedRoles.length === 0) {
|
|
55
|
+
return cached;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const fromDb = await this.repo.find({
|
|
59
|
+
where: { roles: { name: In(uncachedRoles) } },
|
|
60
|
+
relations: { roles: true },
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
if (useCache) {
|
|
64
|
+
for (const role of uncachedRoles) {
|
|
65
|
+
const permsForRole = fromDb.filter(p => p.roles?.some(r => r.name === role));
|
|
66
|
+
await this.cacheManager.set(this.buildPermissionsByRoleCacheKey(role), permsForRole);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const seen = new Set<number>();
|
|
71
|
+
return [...cached, ...fromDb].filter(p => {
|
|
72
|
+
if (seen.has(p.id)) return false;
|
|
73
|
+
seen.add(p.id);
|
|
74
|
+
return true;
|
|
34
75
|
});
|
|
35
76
|
}
|
|
36
77
|
|
|
37
|
-
permissionExistsInRole(role: string, permission: string
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
78
|
+
async permissionExistsInRole(role: string, permission: string): Promise<PermissionMetadata[]> {
|
|
79
|
+
const useCache = shouldUseCache();
|
|
80
|
+
const cacheKey = this.buildPermissionsByRoleCacheKey(role);
|
|
81
|
+
|
|
82
|
+
if (useCache) {
|
|
83
|
+
const hit = await this.cacheManager.get<PermissionMetadata[]>(cacheKey);
|
|
84
|
+
if (hit) {
|
|
85
|
+
// this.logger.debug(`Cache hit for permissionExistsInRole: key=${cacheKey}`);
|
|
86
|
+
return hit.filter(p => p.name === permission);
|
|
87
|
+
}
|
|
88
|
+
// this.logger.debug(`Cache miss for permissionExistsInRole: key=${cacheKey}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const fromDb = await this.repo.find({
|
|
92
|
+
where: { roles: { name: role } },
|
|
93
|
+
relations: { roles: true },
|
|
46
94
|
});
|
|
95
|
+
|
|
96
|
+
if (useCache) {
|
|
97
|
+
await this.cacheManager.set(cacheKey, fromDb);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return fromDb.filter(p => p.name === permission);
|
|
47
101
|
}
|
|
48
102
|
|
|
49
103
|
}
|
|
50
104
|
|
|
51
|
-
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import { Injectable, Logger } from "@nestjs/common";
|
|
2
2
|
import { DashboardQuestionDataProvider } from "src/decorators/dashboard-question-data-provider.decorator";
|
|
3
3
|
import { DashboardQuestion } from "src/entities/dashboard-question.entity";
|
|
4
|
-
import { IDashboardQuestionDataProvider } from "src/interfaces";
|
|
4
|
+
import { IDashboardQuestionDataProvider, QuestionSqlDataProviderContext } from "src/interfaces";
|
|
5
5
|
import { EntityManager } from "typeorm";
|
|
6
6
|
import { SqlExpressionResolverService } from "../sql-expression-resolver.service";
|
|
7
7
|
import { getKpi, getLabels } from "./helpers";
|
|
8
8
|
|
|
9
|
-
export interface QuestionSqlDataProviderContext {
|
|
10
|
-
// questionSqlDatasetConfig: QuestionSqlDatasetConfig;
|
|
11
|
-
// questionId: number;
|
|
12
|
-
// question: Question;
|
|
13
|
-
}
|
|
14
9
|
|
|
15
10
|
export enum SqlExpressionOperator {
|
|
16
11
|
EQUALS = '$equals',
|
|
@@ -49,7 +44,8 @@ export class ChartJsSqlDataProvider implements IDashboardQuestionDataProvider<Qu
|
|
|
49
44
|
return "ChartJsSqlDataProvider";
|
|
50
45
|
}
|
|
51
46
|
|
|
52
|
-
async getData(question: DashboardQuestion,
|
|
47
|
+
async getData(question: DashboardQuestion, context?: QuestionSqlDataProviderContext): Promise<any> {
|
|
48
|
+
const expressions: SqlExpression[] = context?.expressions || [];
|
|
53
49
|
// TODO: put some validation to check if the results of each SQL in each dataset returns the same number of rows
|
|
54
50
|
|
|
55
51
|
// This is what we have to return.
|
|
File without changes
|
package/src/services/question-data-providers/prime-react-datatable-sql-data-provider.service.ts
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import { Injectable } from "@nestjs/common";
|
|
2
2
|
import { DashboardQuestionDataProvider } from "src/decorators/dashboard-question-data-provider.decorator";
|
|
3
3
|
import { DashboardQuestion } from "src/entities/dashboard-question.entity";
|
|
4
|
-
import { IDashboardQuestionDataProvider } from "src/interfaces";
|
|
4
|
+
import { IDashboardQuestionDataProvider, QuestionSqlDataProviderContext } from "src/interfaces";
|
|
5
5
|
import { EntityManager } from "typeorm";
|
|
6
6
|
import { SqlExpressionResolverService } from "../sql-expression-resolver.service";
|
|
7
7
|
import { Logger } from '@nestjs/common';
|
|
8
8
|
import { SqlExpression } from "./chartjs-sql-data-provider.service";
|
|
9
9
|
import { getKpi } from "./helpers";
|
|
10
10
|
|
|
11
|
-
export interface QuestionSqlDataProviderContext {
|
|
12
|
-
// questionSqlDatasetConfig: QuestionSqlDatasetConfig;
|
|
13
|
-
// questionId: number;
|
|
14
|
-
// question: Question;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
11
|
@DashboardQuestionDataProvider()
|
|
18
12
|
@Injectable()
|
|
19
13
|
export class PrimeReactDatatableSqlDataProvider implements IDashboardQuestionDataProvider<QuestionSqlDataProviderContext, any> {
|
|
@@ -29,7 +23,9 @@ export class PrimeReactDatatableSqlDataProvider implements IDashboardQuestionDat
|
|
|
29
23
|
return "PrimeReactDatatableSqlDataProvider";
|
|
30
24
|
}
|
|
31
25
|
|
|
32
|
-
async getData(question: DashboardQuestion,
|
|
26
|
+
async getData(question: DashboardQuestion, context?: QuestionSqlDataProviderContext): Promise<any> {
|
|
27
|
+
const expressions: SqlExpression[] = context?.expressions || [];
|
|
28
|
+
|
|
33
29
|
// TODO: put some validation to check if the results of each SQL in each dataset returns the same number of rows
|
|
34
30
|
|
|
35
31
|
// Check the expected response for prime react data tables to understand what is going on here...
|
package/src/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.ts
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import { Injectable } from "@nestjs/common";
|
|
2
2
|
import { DashboardQuestionDataProvider } from "src/decorators/dashboard-question-data-provider.decorator";
|
|
3
3
|
import { DashboardQuestion } from "src/entities/dashboard-question.entity";
|
|
4
|
-
import { IDashboardQuestionDataProvider } from "src/interfaces";
|
|
4
|
+
import { IDashboardQuestionDataProvider, QuestionSqlDataProviderContext } from "src/interfaces";
|
|
5
5
|
import { EntityManager } from "typeorm";
|
|
6
6
|
import { SqlExpressionResolverService } from "../sql-expression-resolver.service";
|
|
7
7
|
import { Logger } from '@nestjs/common';
|
|
8
8
|
import { SqlExpression } from "./chartjs-sql-data-provider.service";
|
|
9
9
|
import { getKpi } from "./helpers";
|
|
10
10
|
|
|
11
|
-
export interface QuestionSqlDataProviderContext {
|
|
12
|
-
// questionSqlDatasetConfig: QuestionSqlDatasetConfig;
|
|
13
|
-
// questionId: number;
|
|
14
|
-
// question: Question;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
11
|
@DashboardQuestionDataProvider()
|
|
18
12
|
@Injectable()
|
|
19
13
|
export class PrimeReactMeterGroupSqlDataProvider implements IDashboardQuestionDataProvider<QuestionSqlDataProviderContext, any> {
|
|
@@ -58,7 +52,9 @@ export class PrimeReactMeterGroupSqlDataProvider implements IDashboardQuestionDa
|
|
|
58
52
|
return colors;
|
|
59
53
|
}
|
|
60
54
|
|
|
61
|
-
async getData(question: DashboardQuestion,
|
|
55
|
+
async getData(question: DashboardQuestion, context?: QuestionSqlDataProviderContext): Promise<any> {
|
|
56
|
+
const expressions: SqlExpression[] = context?.expressions || [];
|
|
57
|
+
|
|
62
58
|
// TODO: put some validation to check if the results of each SQL in each dataset returns the same number of rows
|
|
63
59
|
|
|
64
60
|
// This is what we have to return.
|
|
@@ -7,7 +7,7 @@ import { PollerService } from '../poller.service';
|
|
|
7
7
|
import { buildNamespacedQueueName } from './common';
|
|
8
8
|
|
|
9
9
|
export abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscriber<T> {
|
|
10
|
-
private
|
|
10
|
+
private _loggerInstance?: Logger;
|
|
11
11
|
private readonly url: string;
|
|
12
12
|
private readonly serviceRole: string;
|
|
13
13
|
|
|
@@ -23,6 +23,17 @@ export abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
23
23
|
// this.logger.debug(`DatabaseSubscriber instance created with options: ${JSON.stringify(this.options())}`);
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
protected get loggerContext(): string {
|
|
27
|
+
return this.constructor.name;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
protected get logger(): Logger {
|
|
31
|
+
if (!this._loggerInstance) {
|
|
32
|
+
this._loggerInstance = new Logger(this.loggerContext);
|
|
33
|
+
}
|
|
34
|
+
return this._loggerInstance;
|
|
35
|
+
}
|
|
36
|
+
|
|
26
37
|
abstract subscribe(message: QueueMessage<T>);
|
|
27
38
|
|
|
28
39
|
abstract options(): QueuesModuleOptions;
|
|
@@ -78,9 +89,15 @@ export abstract class DatabaseSubscriber<T> implements OnModuleInit, QueueSubscr
|
|
|
78
89
|
const defaultBroker = process.env.QUEUES_DEFAULT_BROKER || 'database';
|
|
79
90
|
const solidCliRunning = process.env.SOLID_CLI_RUNNING || "false";
|
|
80
91
|
const queueNameRegex = (process.env.QUEUES_QUEUE_NAME_REGEX_TO_ENABLE || '').trim();
|
|
92
|
+
const roleAllowed = ['both', 'subscriber'].includes(this.serviceRole);
|
|
93
|
+
|
|
94
|
+
if (!roleAllowed) {
|
|
95
|
+
this.logger.log(`DatabaseSubscriber is disabled because QUEUES_SERVICE_ROLE is "${this.serviceRole}". Expected "both" or "subscriber".`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
81
98
|
|
|
82
99
|
// we will start subscriber only if the current service role is subscriber.
|
|
83
|
-
if (
|
|
100
|
+
if (defaultBroker === 'database' && solidCliRunning === "false") {
|
|
84
101
|
const options = this.options();
|
|
85
102
|
const queueName = options.queueName;
|
|
86
103
|
|
|
@@ -23,19 +23,21 @@ export class PublisherFactory<T> {
|
|
|
23
23
|
// Register all ISolidDatabaseModules implementations
|
|
24
24
|
let actualPublisherToUse = this.solidIntrospectionService.getProvider(resolvedPublisherName);
|
|
25
25
|
if (!actualPublisherToUse) {
|
|
26
|
+
// Relaxed extra check in place to make sure we do not have to refactor old publishers or publishers named without the ____RabbitMq or ____Database convention
|
|
27
|
+
actualPublisherToUse = this.solidIntrospectionService.getProvider(publisherName);
|
|
26
28
|
|
|
27
29
|
// Extra check in place to make sure we do not have to refactor old publishers which have been created earlier.
|
|
28
|
-
if (defaultBrokerToUse === 'rabbitmq') {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
30
|
+
// if (defaultBrokerToUse === 'rabbitmq') {
|
|
31
|
+
// actualPublisherToUse = this.solidIntrospectionService.getProvider(publisherName);
|
|
32
|
+
// }
|
|
33
|
+
}
|
|
34
|
+
if (!actualPublisherToUse) {
|
|
35
|
+
throw new Error(`Unable to locate publisher with name ${resolvedPublisherName}`);
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
// type safe
|
|
37
39
|
const typedActualPublisher: QueuePublisher<T> = actualPublisherToUse.instance;
|
|
38
|
-
this.logger.debug(`Resolved publisher with name ${actualPublisherToUse.name}, and with options: ${JSON.stringify(typedActualPublisher.options())}`);
|
|
40
|
+
// this.logger.debug(`Resolved publisher with name ${actualPublisherToUse.name}, and with options: ${JSON.stringify(typedActualPublisher.options())}`);
|
|
39
41
|
|
|
40
42
|
return typedActualPublisher.publish(message);
|
|
41
43
|
}
|
|
@@ -34,6 +34,10 @@ export abstract class RabbitMqPublisher<T> implements OnModuleDestroy, QueuePubl
|
|
|
34
34
|
|
|
35
35
|
abstract options(): QueuesModuleOptions;
|
|
36
36
|
|
|
37
|
+
protected shouldPersistToDatabase(): boolean {
|
|
38
|
+
return this.options().persistToDatabase ?? true;
|
|
39
|
+
}
|
|
40
|
+
|
|
37
41
|
private async ensureConnectionAndChannel(): Promise<amqp.Channel> {
|
|
38
42
|
if (this.channel) {
|
|
39
43
|
return this.channel;
|
|
@@ -170,7 +174,9 @@ export abstract class RabbitMqPublisher<T> implements OnModuleDestroy, QueuePubl
|
|
|
170
174
|
message.messageId = uuidv4();
|
|
171
175
|
|
|
172
176
|
// Save the message to the DB so that we can then change its status in the subscriber...
|
|
173
|
-
|
|
177
|
+
if (this.shouldPersistToDatabase()) {
|
|
178
|
+
await this.persistToDatabase(namespacedQueueName, message);
|
|
179
|
+
}
|
|
174
180
|
|
|
175
181
|
// wait for the channel to confirm
|
|
176
182
|
try {
|
|
@@ -199,7 +205,7 @@ export abstract class RabbitMqPublisher<T> implements OnModuleDestroy, QueuePubl
|
|
|
199
205
|
|
|
200
206
|
private async persistToDatabase(queueName: string, message: QueueMessage<T>) {
|
|
201
207
|
|
|
202
|
-
//
|
|
208
|
+
// make an entry in the relevant database table, generate a unique id earlier.
|
|
203
209
|
try {
|
|
204
210
|
// 1. resolve the queue first
|
|
205
211
|
const mqMessageQueue = await this.mqMessageQueueService.resolveQueue(queueName);
|