@solidxai/core 0.1.6-beta.2 → 0.1.6-beta.21
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/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.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/field-crud-managers/MediaFieldCrudManager.d.ts +1 -0
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.js +8 -9
- package/dist/helpers/field-crud-managers/MediaFieldCrudManager.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.map +1 -1
- 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 +5 -1
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/jobs/computed-field-evaluation-queue-options.d.ts +1 -0
- package/dist/jobs/computed-field-evaluation-queue-options.d.ts.map +1 -1
- package/dist/jobs/computed-field-evaluation-queue-options.js +1 -0
- package/dist/jobs/computed-field-evaluation-queue-options.js.map +1 -1
- 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/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 +44 -21
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/chatter-message.service.d.ts +0 -1
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +22 -19
- 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 +6 -1
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +151 -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 -6
- package/dist/services/queues/publisher-factory.service.js.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts +8 -3
- package/dist/services/queues/rabbitmq-subscriber.service.d.ts.map +1 -1
- package/dist/services/queues/rabbitmq-subscriber.service.js +78 -6
- package/dist/services/queues/rabbitmq-subscriber.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-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 +8 -0
- package/dist/solid-core.module.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/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-tests/api/authenticate.spec.js +119 -0
- package/dist-tests/api/authenticate.spec.js.map +1 -0
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js +97 -0
- package/dist-tests/api/crud-service.findOne.cityMaster.spec.js.map +1 -0
- package/dist-tests/api/ping.spec.js +21 -0
- package/dist-tests/api/ping.spec.js.map +1 -0
- package/dist-tests/helpers/auth.js +41 -0
- package/dist-tests/helpers/auth.js.map +1 -0
- package/dist-tests/helpers/env.js +11 -0
- package/dist-tests/helpers/env.js.map +1 -0
- 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.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/field-crud-managers/MediaFieldCrudManager.ts +9 -9
- package/src/helpers/field-crud-managers/SelectionDynamicFieldCrudManager.ts +9 -6
- package/src/helpers/solid-registry.ts +1 -5
- package/src/helpers/typeorm-db-helper.ts +26 -0
- package/src/index.ts +3 -0
- package/src/interfaces.ts +9 -1
- package/src/jobs/computed-field-evaluation-queue-options.ts +1 -0
- package/src/repository/dashboard-layout.repository.ts +17 -0
- 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 +46 -24
- package/src/services/chatter-message.service.ts +21 -21
- 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 +173 -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 +8 -6
- package/src/services/queues/rabbitmq-subscriber.service.ts +123 -6
- 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-ts-morph.service.ts +98 -0
- package/src/solid-core.module.ts +13 -0
- package/src/subscribers/computed-entity-field.subscriber.ts +3 -3
- package/src/transformers/typeorm/local-date-time-transformer.ts +41 -33
- package/.claude/settings.local.json +0 -15
- package/src/services/1.js +0 -6
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { BadRequestException, forwardRef, Inject, Injectable, Logger, NotFoundException } from '@nestjs/common';
|
|
2
|
+
import { CACHE_MANAGER } from '@nestjs/cache-manager';
|
|
2
3
|
import { InjectDataSource } from '@nestjs/typeorm';
|
|
3
4
|
import * as fs from 'fs/promises'; // Use the Promise-based version of fs for async/await
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import { Cache } from 'cache-manager';
|
|
4
7
|
import { DataSource, EntityManager, In, Repository, SelectQueryBuilder } from 'typeorm';
|
|
5
8
|
import { CreateModelMetadataDto } from '../dtos/create-model-metadata.dto';
|
|
6
9
|
import { ModelMetadata } from '../entities/model-metadata.entity';
|
|
@@ -11,6 +14,7 @@ import { ERROR_MESSAGES } from 'src/constants/error-messages';
|
|
|
11
14
|
import { DisallowInProduction } from 'src/decorators/disallow-in-production.decorator';
|
|
12
15
|
import { SolidFieldType } from 'src/dtos/create-field-metadata.dto';
|
|
13
16
|
import { PermissionMetadata } from 'src/entities/permission-metadata.entity';
|
|
17
|
+
import { shouldUseCache } from 'src/helpers/cache.helper';
|
|
14
18
|
import { ModuleMetadataHelperService } from 'src/helpers/module-metadata-helper.service';
|
|
15
19
|
import { FieldMetadataRepository } from 'src/repository/field-metadata.repository';
|
|
16
20
|
import { ModelMetadataRepository } from 'src/repository/model-metadata.repository';
|
|
@@ -33,6 +37,7 @@ import { RoleMetadataService } from './role-metadata.service';
|
|
|
33
37
|
import { NavigationDto } from 'src/dtos/navigation.dto';
|
|
34
38
|
import { SolidIntrospectService } from './solid-introspect.service';
|
|
35
39
|
import { CRUDService } from './crud.service';
|
|
40
|
+
import { SolidTsMorphService } from './solid-ts-morph.service';
|
|
36
41
|
|
|
37
42
|
@Injectable()
|
|
38
43
|
export class ModelMetadataService {
|
|
@@ -54,8 +59,10 @@ export class ModelMetadataService {
|
|
|
54
59
|
private readonly roleService: RoleMetadataService,
|
|
55
60
|
private readonly moduleMetadataHelperService: ModuleMetadataHelperService,
|
|
56
61
|
readonly introspectService: SolidIntrospectService,
|
|
62
|
+
private readonly solidTsMorphService: SolidTsMorphService,
|
|
63
|
+
@Inject(CACHE_MANAGER) private readonly cacheManager: Cache,
|
|
57
64
|
|
|
58
|
-
// No longer used.
|
|
65
|
+
// No longer used.
|
|
59
66
|
// private readonly generateCodePublihser: GenerateCodePublisherDatabase,
|
|
60
67
|
) { }
|
|
61
68
|
|
|
@@ -109,7 +116,23 @@ export class ModelMetadataService {
|
|
|
109
116
|
return entity;
|
|
110
117
|
}
|
|
111
118
|
|
|
119
|
+
private buildModelBySingularNameCacheKey(singularName: string): string {
|
|
120
|
+
return `modelMetadata:singularName:${singularName}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
112
123
|
async findOneBySingularName(singularName: string, relations = {}) {
|
|
124
|
+
const useCache = shouldUseCache();
|
|
125
|
+
const cacheKey = this.buildModelBySingularNameCacheKey(singularName);
|
|
126
|
+
|
|
127
|
+
if (useCache) {
|
|
128
|
+
const cached = await this.cacheManager.get<ModelMetadata>(cacheKey);
|
|
129
|
+
if (cached) {
|
|
130
|
+
// this.logger.debug(`Cache hit for findOneBySingularName: key=${cacheKey}`);
|
|
131
|
+
return cached;
|
|
132
|
+
}
|
|
133
|
+
// this.logger.debug(`Cache miss for findOneBySingularName: key=${cacheKey}`);
|
|
134
|
+
}
|
|
135
|
+
|
|
113
136
|
const entity = await this.modelMetadataRepo.findOne({
|
|
114
137
|
where: {
|
|
115
138
|
singularName: singularName,
|
|
@@ -119,10 +142,27 @@ export class ModelMetadataService {
|
|
|
119
142
|
if (!entity) {
|
|
120
143
|
throw new NotFoundException(ERROR_MESSAGES.ENTITY_NOT_FOUND(singularName));
|
|
121
144
|
}
|
|
145
|
+
|
|
146
|
+
if (useCache) {
|
|
147
|
+
await this.cacheManager.set(cacheKey, entity);
|
|
148
|
+
}
|
|
149
|
+
|
|
122
150
|
return entity;
|
|
123
151
|
}
|
|
124
152
|
|
|
125
153
|
async findOneByUserKey(singularName: string, relations = {}) {
|
|
154
|
+
const useCache = shouldUseCache();
|
|
155
|
+
const cacheKey = this.buildModelBySingularNameCacheKey(singularName);
|
|
156
|
+
|
|
157
|
+
if (useCache) {
|
|
158
|
+
const cached = await this.cacheManager.get<ModelMetadata>(cacheKey);
|
|
159
|
+
if (cached) {
|
|
160
|
+
// this.logger.debug(`Cache hit for findOneByUserKey: key=${cacheKey}`);
|
|
161
|
+
return cached;
|
|
162
|
+
}
|
|
163
|
+
// this.logger.debug(`Cache miss for findOneByUserKey: key=${cacheKey}`);
|
|
164
|
+
}
|
|
165
|
+
|
|
126
166
|
const entity = await this.modelMetadataRepo.findOne({
|
|
127
167
|
where: {
|
|
128
168
|
singularName: singularName,
|
|
@@ -132,6 +172,11 @@ export class ModelMetadataService {
|
|
|
132
172
|
if (!entity) {
|
|
133
173
|
throw new NotFoundException(ERROR_MESSAGES.ENTITY_NOT_FOUND(singularName));
|
|
134
174
|
}
|
|
175
|
+
|
|
176
|
+
if (useCache) {
|
|
177
|
+
await this.cacheManager.set(cacheKey, entity);
|
|
178
|
+
}
|
|
179
|
+
|
|
135
180
|
return entity;
|
|
136
181
|
}
|
|
137
182
|
|
|
@@ -225,6 +270,7 @@ export class ModelMetadataService {
|
|
|
225
270
|
let userKeyField = null;
|
|
226
271
|
const listViewLayout = [];
|
|
227
272
|
const formViewLayout = [];
|
|
273
|
+
const treeViewLayout = [];
|
|
228
274
|
|
|
229
275
|
for (let k = 0; k < fieldsMetadata.length; k++) {
|
|
230
276
|
const fieldMetadata = fieldsMetadata[k];
|
|
@@ -245,6 +291,7 @@ export class ModelMetadataService {
|
|
|
245
291
|
}
|
|
246
292
|
listViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}` } })
|
|
247
293
|
formViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}` } })
|
|
294
|
+
treeViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}` } })
|
|
248
295
|
|
|
249
296
|
}
|
|
250
297
|
|
|
@@ -705,48 +752,24 @@ export class ModelMetadataService {
|
|
|
705
752
|
await fs.writeFile(filePath, updatedContent);
|
|
706
753
|
}
|
|
707
754
|
|
|
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.
|
|
755
|
+
// <moduleName>.module.ts | Remove all references and imports of the deleted model files. | Automatic
|
|
756
|
+
if (modulePath) {
|
|
757
|
+
const moduleFilePath = path.resolve(modulePath, `${dasherize(modelEntity.module?.name)}.module.ts`);
|
|
758
|
+
this.logger.log(`Removing model '${modelEntity.singularName}' references from module file: ${moduleFilePath}`);
|
|
759
|
+
try {
|
|
760
|
+
this.solidTsMorphService.begin();
|
|
761
|
+
const modelPathSegment = `/${dasherize(modelEntity.singularName)}.`;
|
|
762
|
+
const { removedIdentifiers } = this.solidTsMorphService.removeImports(
|
|
763
|
+
moduleFilePath,
|
|
764
|
+
spec => spec.includes(modelPathSegment)
|
|
765
|
+
);
|
|
766
|
+
this.solidTsMorphService.removeModuleMembers(moduleFilePath, removedIdentifiers);
|
|
767
|
+
await this.solidTsMorphService.commit();
|
|
768
|
+
} catch (error) {
|
|
769
|
+
this.solidTsMorphService.rollback();
|
|
770
|
+
this.logger.error(`Failed to clean up module file for model '${modelEntity.singularName}':`, error);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
750
773
|
|
|
751
774
|
// - | 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
775
|
|
|
@@ -818,6 +841,7 @@ export class ModelMetadataService {
|
|
|
818
841
|
const metaData = await this.moduleMetadataHelperService.getModuleMetadataConfiguration(filePath);
|
|
819
842
|
|
|
820
843
|
const listViewLayoutFields = [{ type: "field", attrs: { name: `id` } }];
|
|
844
|
+
const treeViewLayoutFields = [{ type: "field", attrs: { name: `id` } }];
|
|
821
845
|
const formViewLayoutFields = [];
|
|
822
846
|
|
|
823
847
|
for (let i = 0; i < model.fields.length; i++) {
|
|
@@ -825,8 +849,9 @@ export class ModelMetadataService {
|
|
|
825
849
|
if (field.isSystem) continue;
|
|
826
850
|
listViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}` } })
|
|
827
851
|
formViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}` } })
|
|
852
|
+
treeViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}` } })
|
|
828
853
|
}
|
|
829
|
-
this.populateVAMConfigInFileInternal(formViewLayoutFields, model, listViewLayoutFields, metaData);
|
|
854
|
+
this.populateVAMConfigInFileInternal(formViewLayoutFields, model, listViewLayoutFields, treeViewLayoutFields, metaData);
|
|
830
855
|
// Write the updated object back to the file
|
|
831
856
|
const updatedContent = JSON.stringify(metaData, null, 2);
|
|
832
857
|
await fs.writeFile(filePath, updatedContent);
|
|
@@ -839,7 +864,7 @@ export class ModelMetadataService {
|
|
|
839
864
|
}
|
|
840
865
|
|
|
841
866
|
// 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) {
|
|
867
|
+
private populateVAMConfigInFileInternal(formViewLayoutFields: any[], model: ModelMetadata, listViewLayoutFields: { type: string; attrs: { name: string; }; }[], treeViewLayoutFields: { type: string; attrs: { name: string; }; }[], metaData: any) {
|
|
843
868
|
const column1Fields = [];
|
|
844
869
|
const column2Fields = [];
|
|
845
870
|
|
|
@@ -852,7 +877,9 @@ export class ModelMetadataService {
|
|
|
852
877
|
}
|
|
853
878
|
}
|
|
854
879
|
const actionName = `${model.singularName}-list-action`;
|
|
855
|
-
const
|
|
880
|
+
const treeViewActionName = `${model.singularName}-tree-view-action`;
|
|
881
|
+
const listViewName = `${model.singularName}-list-view`;
|
|
882
|
+
const treeViewName = `${model.singularName}-tree-view`;
|
|
856
883
|
const formViewName = `${model.singularName}-form-view`;
|
|
857
884
|
const menuName = `${model.singularName}-menu-item`;
|
|
858
885
|
|
|
@@ -865,7 +892,21 @@ export class ModelMetadataService {
|
|
|
865
892
|
customComponent: ``,
|
|
866
893
|
customIsModal: true,
|
|
867
894
|
serverEndpoint: "",
|
|
868
|
-
viewUserKey:
|
|
895
|
+
viewUserKey: listViewName,
|
|
896
|
+
moduleUserKey: `${model.module.name}`,
|
|
897
|
+
modelUserKey: `${model.singularName}`
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
const treeViewAction = {
|
|
901
|
+
displayName: `${model.displayName} Tree View Action`,
|
|
902
|
+
name: treeViewActionName,
|
|
903
|
+
type: "solid",
|
|
904
|
+
domain: "",
|
|
905
|
+
context: "",
|
|
906
|
+
customComponent: ``,
|
|
907
|
+
customIsModal: true,
|
|
908
|
+
serverEndpoint: "",
|
|
909
|
+
viewUserKey: treeViewName,
|
|
869
910
|
moduleUserKey: `${model.module.name}`,
|
|
870
911
|
modelUserKey: `${model.singularName}`
|
|
871
912
|
};
|
|
@@ -877,11 +918,11 @@ export class ModelMetadataService {
|
|
|
877
918
|
actionUserKey: actionName,
|
|
878
919
|
moduleUserKey: `${model.module.name}`,
|
|
879
920
|
parentMenuItemUserKey: "",
|
|
880
|
-
iconName
|
|
921
|
+
iconName: ""
|
|
881
922
|
};
|
|
882
923
|
|
|
883
924
|
const modelListview = {
|
|
884
|
-
name:
|
|
925
|
+
name: listViewName,
|
|
885
926
|
displayName: `${model.displayName}`,
|
|
886
927
|
type: "list",
|
|
887
928
|
context: "{}",
|
|
@@ -905,6 +946,31 @@ export class ModelMetadataService {
|
|
|
905
946
|
}
|
|
906
947
|
};
|
|
907
948
|
|
|
949
|
+
const modelTreeview = {
|
|
950
|
+
name: treeViewName,
|
|
951
|
+
displayName: `${model.displayName}`,
|
|
952
|
+
type: "tree",
|
|
953
|
+
context: "{}",
|
|
954
|
+
moduleUserKey: `${model.module.name}`,
|
|
955
|
+
modelUserKey: `${model.singularName}`,
|
|
956
|
+
layout: {
|
|
957
|
+
type: "tree",
|
|
958
|
+
attrs: {
|
|
959
|
+
pagination: true,
|
|
960
|
+
pageSizeOptions: [
|
|
961
|
+
10,
|
|
962
|
+
25,
|
|
963
|
+
50
|
|
964
|
+
],
|
|
965
|
+
enableGlobalSearch: true,
|
|
966
|
+
create: true,
|
|
967
|
+
edit: true,
|
|
968
|
+
delete: true
|
|
969
|
+
},
|
|
970
|
+
children: treeViewLayoutFields
|
|
971
|
+
}
|
|
972
|
+
};
|
|
973
|
+
|
|
908
974
|
|
|
909
975
|
const modelFormView = {
|
|
910
976
|
name: formViewName,
|
|
@@ -954,10 +1020,18 @@ export class ModelMetadataService {
|
|
|
954
1020
|
metaData.actions.push(action);
|
|
955
1021
|
}
|
|
956
1022
|
|
|
957
|
-
if (notExists(metaData.
|
|
1023
|
+
if (notExists(metaData.actions, treeViewActionName)) {
|
|
1024
|
+
metaData.actions.push(treeViewAction);
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
if (notExists(metaData.views, listViewName)) {
|
|
958
1028
|
metaData.views.push(modelListview);
|
|
959
1029
|
}
|
|
960
1030
|
|
|
1031
|
+
if (notExists(metaData.views, treeViewName)) {
|
|
1032
|
+
metaData.views.push(modelTreeview);
|
|
1033
|
+
}
|
|
1034
|
+
|
|
961
1035
|
if (notExists(metaData.views, formViewName)) {
|
|
962
1036
|
metaData.views.push(modelFormView);
|
|
963
1037
|
}
|
|
@@ -979,6 +1053,14 @@ export class ModelMetadataService {
|
|
|
979
1053
|
}
|
|
980
1054
|
}));
|
|
981
1055
|
|
|
1056
|
+
const treeViewLayout = jsonFieldsList.map(field => ({
|
|
1057
|
+
type: "field",
|
|
1058
|
+
attrs: {
|
|
1059
|
+
name: `${field.name}`,
|
|
1060
|
+
isSearchable: true,
|
|
1061
|
+
}
|
|
1062
|
+
}));
|
|
1063
|
+
|
|
982
1064
|
const formViewLayout = jsonFieldsList.map(field => ({
|
|
983
1065
|
type: "field",
|
|
984
1066
|
attrs: {
|
|
@@ -1019,6 +1101,26 @@ export class ModelMetadataService {
|
|
|
1019
1101
|
children: listViewLayout
|
|
1020
1102
|
}, null, 3)
|
|
1021
1103
|
},
|
|
1104
|
+
{
|
|
1105
|
+
name: `${model.singularName}-tree-view`,
|
|
1106
|
+
displayName: `${model.displayName}`,
|
|
1107
|
+
type: 'tree',
|
|
1108
|
+
context: "{}",
|
|
1109
|
+
module: resolvedModule,
|
|
1110
|
+
model: model,
|
|
1111
|
+
layout: JSON.stringify({
|
|
1112
|
+
type: "tree",
|
|
1113
|
+
attrs: {
|
|
1114
|
+
pagination: true,
|
|
1115
|
+
pageSizeOptions: [10, 25, 50],
|
|
1116
|
+
enableGlobalSearch: true,
|
|
1117
|
+
create: true,
|
|
1118
|
+
edit: true,
|
|
1119
|
+
delete: true
|
|
1120
|
+
},
|
|
1121
|
+
children: treeViewLayout
|
|
1122
|
+
}, null, 3)
|
|
1123
|
+
},
|
|
1022
1124
|
{
|
|
1023
1125
|
name: `${model.singularName}-form-view`,
|
|
1024
1126
|
displayName: `${model.displayName}`,
|
|
@@ -1067,6 +1169,7 @@ export class ModelMetadataService {
|
|
|
1067
1169
|
}
|
|
1068
1170
|
|
|
1069
1171
|
let view = await viewRepo.findOne({ where: { name: `${model.singularName}-list-view` } });
|
|
1172
|
+
let treeView = await viewRepo.findOne({ where: { name: `${model.singularName}-tree-view` } });
|
|
1070
1173
|
|
|
1071
1174
|
const actionData = {
|
|
1072
1175
|
displayName: `${model.displayName} List Action`,
|
|
@@ -1082,13 +1185,33 @@ export class ModelMetadataService {
|
|
|
1082
1185
|
model: model
|
|
1083
1186
|
};
|
|
1084
1187
|
|
|
1188
|
+
const treeViewActionData = {
|
|
1189
|
+
displayName: `${model.displayName} Tree View Action`,
|
|
1190
|
+
name: `${model.singularName}-tree-view-action`,
|
|
1191
|
+
type: "solid",
|
|
1192
|
+
domain: "",
|
|
1193
|
+
context: "",
|
|
1194
|
+
customComponent: ``,
|
|
1195
|
+
customIsModal: true,
|
|
1196
|
+
serverEndpoint: "",
|
|
1197
|
+
view: treeView,
|
|
1198
|
+
module: resolvedModule,
|
|
1199
|
+
model: model
|
|
1200
|
+
};
|
|
1201
|
+
|
|
1085
1202
|
let existingAction = await actionRepo.findOne({ where: { name: actionData.name } });
|
|
1203
|
+
let existingTreeViewAction = await actionRepo.findOne({ where: { name: treeViewActionData.name } });
|
|
1086
1204
|
|
|
1087
1205
|
if (!existingAction) {
|
|
1088
1206
|
const createdAction = actionRepo.create(actionData);
|
|
1089
1207
|
existingAction = await actionRepo.save(createdAction);
|
|
1090
1208
|
}
|
|
1091
1209
|
|
|
1210
|
+
if (!existingTreeViewAction) {
|
|
1211
|
+
const createdTreeViewAction = actionRepo.create(treeViewActionData);
|
|
1212
|
+
existingTreeViewAction = await actionRepo.save(createdTreeViewAction);
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1092
1215
|
const adminRole = await this.roleService.findRoleByName('Admin');
|
|
1093
1216
|
|
|
1094
1217
|
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,14 +23,16 @@ 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
|