@solidstarters/solid-core 1.2.134 → 1.2.136
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/ai-interaction.controller.d.ts +46 -0
- package/dist/controllers/ai-interaction.controller.d.ts.map +1 -0
- package/dist/controllers/ai-interaction.controller.js +204 -0
- package/dist/controllers/ai-interaction.controller.js.map +1 -0
- package/dist/controllers/dashboard-question-sql-dataset-config.controller.d.ts +43 -0
- package/dist/controllers/dashboard-question-sql-dataset-config.controller.d.ts.map +1 -0
- package/dist/controllers/dashboard-question-sql-dataset-config.controller.js +179 -0
- package/dist/controllers/dashboard-question-sql-dataset-config.controller.js.map +1 -0
- package/dist/controllers/dashboard-question.controller.d.ts +45 -0
- package/dist/controllers/dashboard-question.controller.d.ts.map +1 -0
- package/dist/controllers/dashboard-question.controller.js +194 -0
- package/dist/controllers/dashboard-question.controller.js.map +1 -0
- package/dist/controllers/dashboard-variable.controller.d.ts +43 -0
- package/dist/controllers/dashboard-variable.controller.d.ts.map +1 -0
- package/dist/controllers/dashboard-variable.controller.js +179 -0
- package/dist/controllers/dashboard-variable.controller.js.map +1 -0
- package/dist/controllers/dashboard.controller.d.ts +45 -0
- package/dist/controllers/dashboard.controller.d.ts.map +1 -0
- package/dist/controllers/dashboard.controller.js +192 -0
- package/dist/controllers/dashboard.controller.js.map +1 -0
- package/dist/controllers/test.controller.d.ts.map +1 -1
- package/dist/controllers/test.controller.js.map +1 -1
- package/dist/decorators/dashboard-question-data-provider.decorator.d.ts +3 -0
- package/dist/decorators/dashboard-question-data-provider.decorator.d.ts.map +1 -0
- package/dist/decorators/dashboard-question-data-provider.decorator.js +11 -0
- package/dist/decorators/dashboard-question-data-provider.decorator.js.map +1 -0
- package/dist/decorators/dashboard-selection-provider.decorator.d.ts +3 -0
- package/dist/decorators/dashboard-selection-provider.decorator.d.ts.map +1 -0
- package/dist/decorators/dashboard-selection-provider.decorator.js +11 -0
- package/dist/decorators/dashboard-selection-provider.decorator.js.map +1 -0
- package/dist/dtos/create-ai-interaction.dto.d.ts +14 -0
- package/dist/dtos/create-ai-interaction.dto.d.ts.map +1 -0
- package/dist/dtos/create-ai-interaction.dto.js +90 -0
- package/dist/dtos/create-ai-interaction.dto.js.map +1 -0
- package/dist/dtos/create-dashboard-question-sql-dataset-config.dto.d.ts +12 -0
- package/dist/dtos/create-dashboard-question-sql-dataset-config.dto.d.ts.map +1 -0
- package/dist/dtos/create-dashboard-question-sql-dataset-config.dto.js +77 -0
- package/dist/dtos/create-dashboard-question-sql-dataset-config.dto.js.map +1 -0
- package/dist/dtos/create-dashboard-question.dto.d.ts +17 -0
- package/dist/dtos/create-dashboard-question.dto.d.ts.map +1 -0
- package/dist/dtos/create-dashboard-question.dto.js +105 -0
- package/dist/dtos/create-dashboard-question.dto.js.map +1 -0
- package/dist/dtos/create-dashboard-variable.dto.d.ts +18 -0
- package/dist/dtos/create-dashboard-variable.dto.d.ts.map +1 -0
- package/dist/dtos/create-dashboard-variable.dto.js +97 -0
- package/dist/dtos/create-dashboard-variable.dto.js.map +1 -0
- package/dist/dtos/create-dashboard.dto.d.ts +15 -0
- package/dist/dtos/create-dashboard.dto.d.ts.map +1 -0
- package/dist/dtos/create-dashboard.dto.js +90 -0
- package/dist/dtos/create-dashboard.dto.js.map +1 -0
- package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.d.ts +8 -0
- package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.d.ts.map +1 -0
- package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.js +52 -0
- package/dist/dtos/dashboard-variable-selection-dynamic-query.dto.js.map +1 -0
- package/dist/dtos/invoke-ai-prompt.dto.d.ts +4 -0
- package/dist/dtos/invoke-ai-prompt.dto.d.ts.map +1 -0
- package/dist/dtos/invoke-ai-prompt.dto.js +25 -0
- package/dist/dtos/invoke-ai-prompt.dto.js.map +1 -0
- package/dist/dtos/update-ai-interaction.dto.d.ts +15 -0
- package/dist/dtos/update-ai-interaction.dto.d.ts.map +1 -0
- package/dist/dtos/update-ai-interaction.dto.js +96 -0
- package/dist/dtos/update-ai-interaction.dto.js.map +1 -0
- package/dist/dtos/update-dashboard-question-sql-dataset-config.dto.d.ts +13 -0
- package/dist/dtos/update-dashboard-question-sql-dataset-config.dto.d.ts.map +1 -0
- package/dist/dtos/update-dashboard-question-sql-dataset-config.dto.js +86 -0
- package/dist/dtos/update-dashboard-question-sql-dataset-config.dto.js.map +1 -0
- package/dist/dtos/update-dashboard-question.dto.d.ts +18 -0
- package/dist/dtos/update-dashboard-question.dto.d.ts.map +1 -0
- package/dist/dtos/update-dashboard-question.dto.js +112 -0
- package/dist/dtos/update-dashboard-question.dto.js.map +1 -0
- package/dist/dtos/update-dashboard-variable.dto.d.ts +15 -0
- package/dist/dtos/update-dashboard-variable.dto.d.ts.map +1 -0
- package/dist/dtos/update-dashboard-variable.dto.js +95 -0
- package/dist/dtos/update-dashboard-variable.dto.js.map +1 -0
- package/dist/dtos/update-dashboard.dto.d.ts +16 -0
- package/dist/dtos/update-dashboard.dto.d.ts.map +1 -0
- package/dist/dtos/update-dashboard.dto.js +96 -0
- package/dist/dtos/update-dashboard.dto.js.map +1 -0
- package/dist/entities/ai-interaction.entity.d.ts +15 -0
- package/dist/entities/ai-interaction.entity.d.ts.map +1 -0
- package/dist/entities/ai-interaction.entity.js +70 -0
- package/dist/entities/ai-interaction.entity.js.map +1 -0
- package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts +13 -0
- package/dist/entities/dashboard-question-sql-dataset-config.entity.d.ts.map +1 -0
- package/dist/entities/dashboard-question-sql-dataset-config.entity.js +60 -0
- package/dist/entities/dashboard-question-sql-dataset-config.entity.js.map +1 -0
- package/dist/entities/dashboard-question.entity.d.ts +16 -0
- package/dist/entities/dashboard-question.entity.d.ts.map +1 -0
- package/dist/entities/dashboard-question.entity.js +71 -0
- package/dist/entities/dashboard-question.entity.js.map +1 -0
- package/dist/entities/dashboard-variable.entity.d.ts +15 -0
- package/dist/entities/dashboard-variable.entity.d.ts.map +1 -0
- package/dist/entities/dashboard-variable.entity.js +73 -0
- package/dist/entities/dashboard-variable.entity.js.map +1 -0
- package/dist/entities/dashboard.entity.d.ts +12 -0
- package/dist/entities/dashboard.entity.d.ts.map +1 -0
- package/dist/entities/dashboard.entity.js +50 -0
- package/dist/entities/dashboard.entity.js.map +1 -0
- package/dist/helpers/solid-registry.d.ts +9 -1
- package/dist/helpers/solid-registry.d.ts.map +1 -1
- package/dist/helpers/solid-registry.js +32 -0
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +26 -1
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/jobs/database/trigger-mcp-client-publisher-database.service.d.ts +11 -0
- package/dist/jobs/database/trigger-mcp-client-publisher-database.service.d.ts.map +1 -0
- package/dist/jobs/database/trigger-mcp-client-publisher-database.service.js +39 -0
- package/dist/jobs/database/trigger-mcp-client-publisher-database.service.js.map +1 -0
- package/dist/jobs/database/trigger-mcp-client-queue-options.d.ts +8 -0
- package/dist/jobs/database/trigger-mcp-client-queue-options.d.ts.map +1 -0
- package/dist/jobs/database/trigger-mcp-client-queue-options.js +10 -0
- package/dist/jobs/database/trigger-mcp-client-queue-options.js.map +1 -0
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts +16 -0
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.d.ts.map +1 -0
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js +71 -0
- package/dist/jobs/database/trigger-mcp-client-subscriber-database.service.js.map +1 -0
- package/dist/mappers/dashboard-mapper.d.ts +6 -0
- package/dist/mappers/dashboard-mapper.d.ts.map +1 -0
- package/dist/mappers/dashboard-mapper.js +60 -0
- package/dist/mappers/dashboard-mapper.js.map +1 -0
- package/dist/repository/dashboard.repository.d.ts +9 -0
- package/dist/repository/dashboard.repository.d.ts.map +1 -0
- package/dist/repository/dashboard.repository.js +98 -0
- package/dist/repository/dashboard.repository.js.map +1 -0
- package/dist/seeders/module-metadata-seeder.service.d.ts +5 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +18 -2
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +4172 -2411
- package/dist/services/ai-interaction.service.d.ts +31 -0
- package/dist/services/ai-interaction.service.d.ts.map +1 -0
- package/dist/services/ai-interaction.service.js +182 -0
- package/dist/services/ai-interaction.service.js.map +1 -0
- package/dist/services/chatter-message.service.d.ts.map +1 -1
- package/dist/services/chatter-message.service.js +8 -6
- package/dist/services/chatter-message.service.js.map +1 -1
- package/dist/services/dashboard-question-sql-dataset-config.service.d.ts +22 -0
- package/dist/services/dashboard-question-sql-dataset-config.service.d.ts.map +1 -0
- package/dist/services/dashboard-question-sql-dataset-config.service.js +56 -0
- package/dist/services/dashboard-question-sql-dataset-config.service.js.map +1 -0
- package/dist/services/dashboard-question.service.d.ts +29 -0
- package/dist/services/dashboard-question.service.d.ts.map +1 -0
- package/dist/services/dashboard-question.service.js +117 -0
- package/dist/services/dashboard-question.service.js.map +1 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.d.ts +12 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.d.ts.map +1 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.js +55 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.js.map +1 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.d.ts +11 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.d.ts.map +1 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.js +45 -0
- package/dist/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.js.map +1 -0
- package/dist/services/dashboard-variable.service.d.ts +23 -0
- package/dist/services/dashboard-variable.service.d.ts.map +1 -0
- package/dist/services/dashboard-variable.service.js +57 -0
- package/dist/services/dashboard-variable.service.js.map +1 -0
- package/dist/services/dashboard.service.d.ts +38 -0
- package/dist/services/dashboard.service.d.ts.map +1 -0
- package/dist/services/dashboard.service.js +179 -0
- package/dist/services/dashboard.service.js.map +1 -0
- package/dist/services/field-metadata.service.d.ts.map +1 -1
- package/dist/services/field-metadata.service.js +1 -0
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/import-transaction.service.d.ts +3 -1
- package/dist/services/import-transaction.service.d.ts.map +1 -1
- package/dist/services/import-transaction.service.js +22 -0
- package/dist/services/import-transaction.service.js.map +1 -1
- package/dist/services/list-of-values.service.d.ts +1 -0
- package/dist/services/list-of-values.service.d.ts.map +1 -1
- package/dist/services/list-of-values.service.js +3 -0
- package/dist/services/list-of-values.service.js.map +1 -1
- package/dist/services/menu-item-metadata.service.d.ts.map +1 -1
- package/dist/services/menu-item-metadata.service.js +1 -1
- package/dist/services/menu-item-metadata.service.js.map +1 -1
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts +36 -0
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.d.ts.map +1 -0
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js +89 -0
- package/dist/services/question-data-providers/chartjs-sql-data-provider.service.js.map +1 -0
- package/dist/services/question-data-providers/helpers.d.ts +7 -0
- package/dist/services/question-data-providers/helpers.d.ts.map +1 -0
- package/dist/services/question-data-providers/helpers.js +25 -0
- package/dist/services/question-data-providers/helpers.js.map +1 -0
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts +17 -0
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.d.ts.map +1 -0
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js +70 -0
- package/dist/services/question-data-providers/prime-react-datatable-sql-data-provider.service.js.map +1 -0
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts +19 -0
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.d.ts.map +1 -0
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js +92 -0
- package/dist/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.js.map +1 -0
- package/dist/services/queues/publisher-factory.service.js +1 -1
- package/dist/services/queues/publisher-factory.service.js.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.d.ts.map +1 -1
- package/dist/services/scheduled-jobs/scheduler.service.js +22 -11
- 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 +11 -0
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.d.ts.map +1 -0
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js +46 -0
- package/dist/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.js.map +1 -0
- package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.d.ts +11 -0
- package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.d.ts.map +1 -0
- package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.js +47 -0
- package/dist/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.js.map +1 -0
- package/dist/services/solid-introspect.service.d.ts +2 -0
- package/dist/services/solid-introspect.service.d.ts.map +1 -1
- package/dist/services/solid-introspect.service.js +28 -0
- package/dist/services/solid-introspect.service.js.map +1 -1
- package/dist/services/sql-expression-resolver.service.d.ts +9 -0
- package/dist/services/sql-expression-resolver.service.d.ts.map +1 -0
- package/dist/services/sql-expression-resolver.service.js +105 -0
- package/dist/services/sql-expression-resolver.service.js.map +1 -0
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +75 -1
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/dashboard-question-sql-dataset-config.subscriber.d.ts +16 -0
- package/dist/subscribers/dashboard-question-sql-dataset-config.subscriber.d.ts.map +1 -0
- package/dist/subscribers/dashboard-question-sql-dataset-config.subscriber.js +72 -0
- package/dist/subscribers/dashboard-question-sql-dataset-config.subscriber.js.map +1 -0
- package/dist/subscribers/dashboard-question.subscriber.d.ts +16 -0
- package/dist/subscribers/dashboard-question.subscriber.d.ts.map +1 -0
- package/dist/subscribers/dashboard-question.subscriber.js +72 -0
- package/dist/subscribers/dashboard-question.subscriber.js.map +1 -0
- package/dist/subscribers/dashboard-variable.subscriber.d.ts +16 -0
- package/dist/subscribers/dashboard-variable.subscriber.d.ts.map +1 -0
- package/dist/subscribers/dashboard-variable.subscriber.js +72 -0
- package/dist/subscribers/dashboard-variable.subscriber.js.map +1 -0
- package/dist/subscribers/dashboard.subscriber.d.ts +15 -0
- package/dist/subscribers/dashboard.subscriber.d.ts.map +1 -0
- package/dist/subscribers/dashboard.subscriber.js +56 -0
- package/dist/subscribers/dashboard.subscriber.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/controllers/ai-interaction.controller.ts +104 -0
- package/src/controllers/dashboard-question-sql-dataset-config.controller.ts +93 -0
- package/src/controllers/dashboard-question.controller.ts +104 -0
- package/src/controllers/dashboard-variable.controller.ts +93 -0
- package/src/controllers/dashboard.controller.ts +99 -0
- package/src/controllers/test.controller.ts +1 -2
- package/src/decorators/dashboard-question-data-provider.decorator.ts +7 -0
- package/src/decorators/dashboard-selection-provider.decorator.ts +7 -0
- package/src/dtos/create-ai-interaction.dto.ts +60 -0
- package/src/dtos/create-dashboard-question-sql-dataset-config.dto.ts +42 -0
- package/src/dtos/create-dashboard-question.dto.ts +63 -0
- package/src/dtos/create-dashboard-variable.dto.ts +56 -0
- package/src/dtos/create-dashboard.dto.ts +53 -0
- package/src/dtos/dashboard-variable-selection-dynamic-query.dto.ts +29 -0
- package/src/dtos/invoke-ai-prompt.dto.ts +6 -0
- package/src/dtos/update-ai-interaction.dto.ts +65 -0
- package/src/dtos/update-dashboard-question-sql-dataset-config.dto.ts +49 -0
- package/src/dtos/update-dashboard-question.dto.ts +68 -0
- package/src/dtos/update-dashboard-variable.dto.ts +54 -0
- package/src/dtos/update-dashboard.dto.ts +57 -0
- package/src/entities/ai-interaction.entity.ts +39 -0
- package/src/entities/dashboard-question-sql-dataset-config.entity.ts +25 -0
- package/src/entities/dashboard-question.entity.ts +33 -0
- package/src/entities/dashboard-variable.entity.ts +30 -0
- package/src/entities/dashboard.entity.ts +21 -0
- package/src/helpers/solid-registry.ts +44 -2
- package/src/index.ts +10 -2
- package/src/interfaces.ts +57 -29
- package/src/jobs/database/trigger-mcp-client-publisher-database.service.ts +22 -0
- package/src/jobs/database/trigger-mcp-client-queue-options.ts +9 -0
- package/src/jobs/database/trigger-mcp-client-subscriber-database.service.ts +71 -0
- package/src/mappers/dashboard-mapper.ts +52 -0
- package/src/repository/dashboard.repository.ts +101 -0
- package/src/seeders/module-metadata-seeder.service.ts +21 -1
- package/src/seeders/seed-data/solid-core-metadata.json +4175 -2414
- package/src/services/ai-interaction.service.ts +163 -0
- package/src/services/chatter-message.service.ts +12 -6
- package/src/services/dashboard-question-sql-dataset-config.service.ts +34 -0
- package/src/services/dashboard-question.service.ts +115 -0
- package/src/services/dashboard-selection-providers/dashboard-variable-sql-dynamic-provider.service.ts +56 -0
- package/src/services/dashboard-selection-providers/dashboard-variable-test-dynamic-provider.service.ts +37 -0
- package/src/services/dashboard-variable.service.ts +36 -0
- package/src/services/dashboard.service.ts +147 -0
- package/src/services/field-metadata.service.ts +1 -0
- package/src/services/import-transaction.service.ts +29 -1
- package/src/services/list-of-values.service.ts +5 -0
- package/src/services/menu-item-metadata.service.ts +2 -1
- package/src/services/question-data-providers/chartjs-sql-data-provider.service.ts +125 -0
- package/src/services/question-data-providers/helpers.ts +30 -0
- package/src/services/question-data-providers/prime-react-datatable-sql-data-provider.service.ts +78 -0
- package/src/services/question-data-providers/prime-react-meter-group-sql-data-provider.service.ts +119 -0
- package/src/services/question-data-providers/test.sql +1 -0
- package/src/services/queues/publisher-factory.service.ts +1 -1
- package/src/services/scheduled-jobs/scheduler.service.ts +32 -64
- package/src/services/selection-providers/list-of-dashboard-question-providers-selection-provider.service.ts +41 -0
- package/src/services/selection-providers/list-of-dashboard-variable-providers-selection-provider.service.ts +41 -0
- package/src/services/solid-introspect.service.ts +42 -0
- package/src/services/sql-expression-resolver.service.ts +125 -0
- package/src/solid-core.module.ts +77 -2
- package/src/subscribers/dashboard-question-sql-dataset-config.subscriber.ts +61 -0
- package/src/subscribers/dashboard-question.subscriber.ts +62 -0
- package/src/subscribers/dashboard-variable.subscriber.ts +63 -0
- package/src/subscribers/dashboard.subscriber.ts +43 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { BadRequestException, Logger, Injectable } from '@nestjs/common';
|
|
2
|
+
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
|
|
3
|
+
import { DiscoveryService, ModuleRef } from "@nestjs/core";
|
|
4
|
+
import { EntityManager, Repository } from 'typeorm';
|
|
5
|
+
|
|
6
|
+
import { CRUDService } from 'src/services/crud.service';
|
|
7
|
+
import { ModelMetadataService } from 'src/services/model-metadata.service';
|
|
8
|
+
import { ModuleMetadataService } from 'src/services/module-metadata.service';
|
|
9
|
+
import { ConfigService } from '@nestjs/config';
|
|
10
|
+
import { FileService } from 'src/services/file.service';
|
|
11
|
+
import { CrudHelperService } from 'src/services/crud-helper.service';
|
|
12
|
+
import { spawn } from 'child_process';
|
|
13
|
+
import { AiInteraction } from '../entities/ai-interaction.entity';
|
|
14
|
+
import * as fs from 'fs/promises';
|
|
15
|
+
import { McpResponse, TriggerMcpClientOptions } from 'src/interfaces';
|
|
16
|
+
import { PublisherFactory } from './queues/publisher-factory.service';
|
|
17
|
+
import { RequestContextService } from './request-context.service';
|
|
18
|
+
import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
|
|
19
|
+
|
|
20
|
+
@Injectable()
|
|
21
|
+
export class AiInteractionService extends CRUDService<AiInteraction> {
|
|
22
|
+
private readonly logger = new Logger(AiInteractionService.name);
|
|
23
|
+
|
|
24
|
+
constructor(
|
|
25
|
+
readonly modelMetadataService: ModelMetadataService,
|
|
26
|
+
readonly moduleMetadataService: ModuleMetadataService,
|
|
27
|
+
readonly configService: ConfigService,
|
|
28
|
+
readonly fileService: FileService,
|
|
29
|
+
readonly discoveryService: DiscoveryService,
|
|
30
|
+
readonly crudHelperService: CrudHelperService,
|
|
31
|
+
@InjectEntityManager()
|
|
32
|
+
readonly entityManager: EntityManager,
|
|
33
|
+
@InjectRepository(AiInteraction, 'default')
|
|
34
|
+
readonly repo: Repository<AiInteraction>,
|
|
35
|
+
readonly moduleRef: ModuleRef,
|
|
36
|
+
readonly publisherFactory: PublisherFactory<TriggerMcpClientOptions>,
|
|
37
|
+
readonly requestContextService: RequestContextService,
|
|
38
|
+
|
|
39
|
+
) {
|
|
40
|
+
super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'aiInteraction', 'solid-core', moduleRef);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async triggerMcpClientJob(prompt: string): Promise<string> {
|
|
44
|
+
const activeUser: ActiveUserData = this.requestContextService.getActiveUser();
|
|
45
|
+
|
|
46
|
+
const aiInteraction = await this.create({
|
|
47
|
+
userId: activeUser.sub,
|
|
48
|
+
threadId: `thread-${activeUser.sub}`,
|
|
49
|
+
role: 'human',
|
|
50
|
+
message: prompt,
|
|
51
|
+
contentType: '',
|
|
52
|
+
errorMessage: '',
|
|
53
|
+
modelUsed: '',
|
|
54
|
+
responseTimeMs: 0,
|
|
55
|
+
metadata: ''
|
|
56
|
+
});
|
|
57
|
+
const m = {
|
|
58
|
+
payload: {
|
|
59
|
+
aiInteractionId: aiInteraction.id,
|
|
60
|
+
},
|
|
61
|
+
parentEntity: 'aiInteraction',
|
|
62
|
+
parentEntityId: aiInteraction.id,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
return await this.publisherFactory.publish(m, 'TriggerMcpClientPublisher');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Runs the Python MCP client with a prompt and returns the parsed JSON embedded in the 'response'.
|
|
70
|
+
* @param prompt - The question or instruction to send to the MCP client.
|
|
71
|
+
* @returns The parsed object inside the 'response' field of the JSON output.
|
|
72
|
+
*/
|
|
73
|
+
async runMcpPrompt(prompt: string): Promise<McpResponse> {
|
|
74
|
+
const pythonExecutable = process.env.MCP_PYTHON_EXECUTABLE;
|
|
75
|
+
const mcpClient = process.env.MCP_CLIENT;
|
|
76
|
+
|
|
77
|
+
// TODO: We can return an error if the above env variables are not properly setup...
|
|
78
|
+
if (!pythonExecutable || !mcpClient) {
|
|
79
|
+
throw new BadRequestException('SolidX AI MCP python executable or client path not configured.');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Check if both paths are valid and accessible
|
|
83
|
+
try {
|
|
84
|
+
const [pyStat, clientStat] = await Promise.all([
|
|
85
|
+
fs.stat(pythonExecutable),
|
|
86
|
+
fs.stat(mcpClient),
|
|
87
|
+
]);
|
|
88
|
+
|
|
89
|
+
if (!pyStat.isFile()) {
|
|
90
|
+
throw new BadRequestException(`MCP_PYTHON_EXECUTABLE path is not a file: ${pythonExecutable}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!clientStat.isFile()) {
|
|
94
|
+
throw new BadRequestException(`MCP_CLIENT path is not a file: ${mcpClient}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
} catch (err: any) {
|
|
98
|
+
throw new BadRequestException(`Invalid MCP executable or client path: ${err.message}`);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// TODO: Refactor to use the command.service.ts instead...
|
|
102
|
+
return new Promise((resolve, reject) => {
|
|
103
|
+
this.logger.log(`Attempting to run command:`)
|
|
104
|
+
this.logger.log(`${pythonExecutable} ${mcpClient} ${prompt}`);
|
|
105
|
+
|
|
106
|
+
const python = spawn(pythonExecutable, [mcpClient, prompt]);
|
|
107
|
+
|
|
108
|
+
let stdout = '';
|
|
109
|
+
let stderr = '';
|
|
110
|
+
|
|
111
|
+
python.stdout.on('data', (data) => {
|
|
112
|
+
stdout += data.toString();
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
python.stderr.on('data', (data) => {
|
|
116
|
+
stderr += data.toString();
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
python.on('close', (code) => {
|
|
120
|
+
this.logger.log(`Python script exited with code ${code}`);
|
|
121
|
+
|
|
122
|
+
if (code !== 0) {
|
|
123
|
+
this.logger.error(`Python script exited with a non-zero exit code: ${stderr}`);
|
|
124
|
+
return reject(new Error(`Python script exited with a non-zero exit code: ${stderr}`));
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
try {
|
|
128
|
+
this.logger.log(`Python script exited with zero exit code: ${stdout}`);
|
|
129
|
+
const raw: McpResponse = JSON.parse(stdout);
|
|
130
|
+
|
|
131
|
+
// if (!raw.success) {
|
|
132
|
+
// return reject(new Error(`MCP error: ${raw.errors?.join(', ')}`));
|
|
133
|
+
// }
|
|
134
|
+
// let cleaned = raw.response.trim();
|
|
135
|
+
|
|
136
|
+
// Don't need to re-parse this...
|
|
137
|
+
// const parsed = JSON.parse(cleaned);
|
|
138
|
+
// resolve(cleaned);
|
|
139
|
+
|
|
140
|
+
resolve(raw);
|
|
141
|
+
} catch (err: any) {
|
|
142
|
+
reject(new Error(`Mcp Invocation Failed: ${err.message}`));
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
cleanResponse(response: string) {
|
|
149
|
+
this.logger.log(`mcp server response is: ${response}`);
|
|
150
|
+
|
|
151
|
+
// Remove markdown-style code block wrapper
|
|
152
|
+
if (response.startsWith('```json')) {
|
|
153
|
+
response = response.replace(/^```json/, '').trim();
|
|
154
|
+
}
|
|
155
|
+
if (response.endsWith('```')) {
|
|
156
|
+
response = response.replace(/```$/, '').trim();
|
|
157
|
+
}
|
|
158
|
+
this.logger.log(`mcp server response after removing doc tags is: ${response}`);
|
|
159
|
+
|
|
160
|
+
return response;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
}
|
|
@@ -125,7 +125,7 @@ export class ChatterMessageService extends CRUDService<ChatterMessage>{
|
|
|
125
125
|
|
|
126
126
|
for (const field of auditFields) {
|
|
127
127
|
const fieldValue = entity[field.name];
|
|
128
|
-
if (fieldValue !== undefined && fieldValue !== null) {
|
|
128
|
+
if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '') {
|
|
129
129
|
const messageDetail = new ChatterMessageDetails();
|
|
130
130
|
messageDetail.chatterMessage = savedMessage;
|
|
131
131
|
messageDetail.fieldName = field.name;
|
|
@@ -289,19 +289,25 @@ private formatFieldValueDisplay(field: any, value: any): string {
|
|
|
289
289
|
}
|
|
290
290
|
|
|
291
291
|
private hasValueChanged(newValue: any, oldValue: any): boolean {
|
|
292
|
-
if (
|
|
292
|
+
if (
|
|
293
|
+
(newValue === null || newValue === undefined) &&
|
|
294
|
+
(oldValue === null || oldValue === undefined)
|
|
295
|
+
) {
|
|
293
296
|
return false;
|
|
294
297
|
}
|
|
295
298
|
|
|
296
|
-
if (newValue ===
|
|
299
|
+
if (newValue === oldValue) {
|
|
297
300
|
return false;
|
|
298
301
|
}
|
|
299
302
|
|
|
300
|
-
if (newValue
|
|
301
|
-
return
|
|
303
|
+
if (Array.isArray(newValue) && Array.isArray(oldValue)) {
|
|
304
|
+
return JSON.stringify(newValue) !== JSON.stringify(oldValue);
|
|
302
305
|
}
|
|
303
306
|
|
|
304
|
-
if (
|
|
307
|
+
if (
|
|
308
|
+
typeof newValue === 'object' && newValue !== null &&
|
|
309
|
+
typeof oldValue === 'object' && oldValue !== null
|
|
310
|
+
) {
|
|
305
311
|
return JSON.stringify(newValue) !== JSON.stringify(oldValue);
|
|
306
312
|
}
|
|
307
313
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
|
|
3
|
+
import { DiscoveryService, ModuleRef } from "@nestjs/core";
|
|
4
|
+
import { EntityManager, Repository } from 'typeorm';
|
|
5
|
+
|
|
6
|
+
import { CRUDService } from 'src/services/crud.service';
|
|
7
|
+
import { ModelMetadataService } from 'src/services/model-metadata.service';
|
|
8
|
+
import { ModuleMetadataService } from 'src/services/module-metadata.service';
|
|
9
|
+
import { ConfigService } from '@nestjs/config';
|
|
10
|
+
import { FileService } from 'src/services/file.service';
|
|
11
|
+
import { CrudHelperService } from 'src/services/crud-helper.service';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import { DashboardQuestionSqlDatasetConfig } from '../entities/dashboard-question-sql-dataset-config.entity';
|
|
15
|
+
|
|
16
|
+
@Injectable()
|
|
17
|
+
export class DashboardQuestionSqlDatasetConfigService extends CRUDService<DashboardQuestionSqlDatasetConfig>{
|
|
18
|
+
constructor(
|
|
19
|
+
readonly modelMetadataService: ModelMetadataService,
|
|
20
|
+
readonly moduleMetadataService: ModuleMetadataService,
|
|
21
|
+
readonly configService: ConfigService,
|
|
22
|
+
readonly fileService: FileService,
|
|
23
|
+
readonly discoveryService: DiscoveryService,
|
|
24
|
+
readonly crudHelperService: CrudHelperService,
|
|
25
|
+
@InjectEntityManager()
|
|
26
|
+
readonly entityManager: EntityManager,
|
|
27
|
+
@InjectRepository(DashboardQuestionSqlDatasetConfig, 'default')
|
|
28
|
+
readonly repo: Repository<DashboardQuestionSqlDatasetConfig>,
|
|
29
|
+
readonly moduleRef: ModuleRef
|
|
30
|
+
|
|
31
|
+
) {
|
|
32
|
+
super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService,entityManager, repo, 'dashboardQuestionSqlDatasetConfig', 'solid-core', moduleRef);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { BadRequestException, Injectable, Logger, NotImplementedException } from '@nestjs/common';
|
|
2
|
+
import { DiscoveryService, ModuleRef } from "@nestjs/core";
|
|
3
|
+
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
|
|
4
|
+
import { EntityManager, Repository } from 'typeorm';
|
|
5
|
+
|
|
6
|
+
import { ConfigService } from '@nestjs/config';
|
|
7
|
+
import { CrudHelperService } from 'src/services/crud-helper.service';
|
|
8
|
+
import { CRUDService } from 'src/services/crud.service';
|
|
9
|
+
import { FileService } from 'src/services/file.service';
|
|
10
|
+
import { ModelMetadataService } from 'src/services/model-metadata.service';
|
|
11
|
+
import { ModuleMetadataService } from 'src/services/module-metadata.service';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import { DashboardVariable } from 'src/entities/dashboard-variable.entity';
|
|
15
|
+
import { SolidRegistry } from 'src/helpers/solid-registry';
|
|
16
|
+
import { DashboardQuestion } from '../entities/dashboard-question.entity';
|
|
17
|
+
import { SqlExpression, SqlExpressionOperator } from './question-data-providers/chartjs-sql-data-provider.service';
|
|
18
|
+
import { DashboardService } from './dashboard.service';
|
|
19
|
+
import { Dashboard } from 'src/entities/dashboard.entity';
|
|
20
|
+
|
|
21
|
+
enum SOURCE_TYPE {
|
|
22
|
+
SQL = 'sql',
|
|
23
|
+
PROVIDER = 'provider',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const CHARTJS_SQL_DATA_PROVIDER_NAME = 'ChartJsSqlDataProvider';
|
|
27
|
+
const PRIME_REACT_METER_GROUP_SQL_DATA_PROVIDER_NAME = 'PrimeReactMeterGroupSqlDataProvider';
|
|
28
|
+
const PRIME_REACT_DATATABLE_SQL_DATA_PROVIDER_NAME = 'PrimeReactDatatableSqlDataProvider';
|
|
29
|
+
|
|
30
|
+
@Injectable()
|
|
31
|
+
export class DashboardQuestionService extends CRUDService<DashboardQuestion> {
|
|
32
|
+
private readonly logger = new Logger(this.constructor.name);
|
|
33
|
+
constructor(
|
|
34
|
+
readonly modelMetadataService: ModelMetadataService,
|
|
35
|
+
readonly moduleMetadataService: ModuleMetadataService,
|
|
36
|
+
readonly configService: ConfigService,
|
|
37
|
+
readonly fileService: FileService,
|
|
38
|
+
readonly discoveryService: DiscoveryService,
|
|
39
|
+
readonly crudHelperService: CrudHelperService,
|
|
40
|
+
@InjectEntityManager()
|
|
41
|
+
readonly entityManager: EntityManager,
|
|
42
|
+
@InjectRepository(DashboardQuestion, 'default')
|
|
43
|
+
readonly repo: Repository<DashboardQuestion>,
|
|
44
|
+
readonly moduleRef: ModuleRef,
|
|
45
|
+
readonly solidRegistry: SolidRegistry, // Assuming solidRegistry is injected for data providers
|
|
46
|
+
) {
|
|
47
|
+
super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'dashboardQuestion', 'solid-core', moduleRef);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Get the data for a specific question
|
|
51
|
+
async getData(id: number, inputExpressions: SqlExpression[] = [], isPreview = false): Promise<any> {
|
|
52
|
+
// Load the question
|
|
53
|
+
const question = await this.loadQuestion(id);
|
|
54
|
+
if (!question) {
|
|
55
|
+
throw new BadRequestException(`Question with id ${id} not found`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Get the dashbbard variables from the question
|
|
59
|
+
const dashboardVariables = question.dashboard?.dashboardVariables || [];
|
|
60
|
+
const expressions: SqlExpression[] = this.getExpressions(isPreview, dashboardVariables, inputExpressions);
|
|
61
|
+
|
|
62
|
+
// Try to resolve the dataProvider based on a combination of sourceType and visualisedAs
|
|
63
|
+
let dataProvider = null;
|
|
64
|
+
|
|
65
|
+
if (question.sourceType === SOURCE_TYPE.SQL && ['bar', 'pie', 'line', 'donut'].includes(question.visualisedAs)) {
|
|
66
|
+
dataProvider = this.solidRegistry.getDashboardQuestionDataProviderInstance(CHARTJS_SQL_DATA_PROVIDER_NAME);
|
|
67
|
+
}
|
|
68
|
+
if (question.sourceType === SOURCE_TYPE.SQL && ['prime-meter-group'].includes(question.visualisedAs)) {
|
|
69
|
+
dataProvider = this.solidRegistry.getDashboardQuestionDataProviderInstance(PRIME_REACT_METER_GROUP_SQL_DATA_PROVIDER_NAME);
|
|
70
|
+
}
|
|
71
|
+
if (question.sourceType === SOURCE_TYPE.SQL && ['prime-datatable'].includes(question.visualisedAs)) {
|
|
72
|
+
dataProvider = this.solidRegistry.getDashboardQuestionDataProviderInstance(PRIME_REACT_DATATABLE_SQL_DATA_PROVIDER_NAME);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
if (!dataProvider) {
|
|
76
|
+
throw new NotImplementedException(`Invalid data source type ${question.sourceType}`);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return await dataProvider.getData(question, expressions);
|
|
80
|
+
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
private getExpressions(isPreview: boolean, dashboardVariables: DashboardVariable[], inputExpressions: SqlExpression[]) {
|
|
84
|
+
const expressions: SqlExpression[] = [];
|
|
85
|
+
if (isPreview) {
|
|
86
|
+
// Convert the dashboard variables into objects of interface type SqlExpression using the default value, default operator and the variable name
|
|
87
|
+
const expr: SqlExpression[] = dashboardVariables.map(variable => {
|
|
88
|
+
return {
|
|
89
|
+
variableName: variable.variableName,
|
|
90
|
+
operator: variable.defaultOperator as SqlExpressionOperator, // Assuming defaultOperator is a valid SqlExpressionOperator
|
|
91
|
+
value: JSON.parse(variable.defaultValue || '[]'), // Assuming defaultValue is a string or can be converted to a string array
|
|
92
|
+
};
|
|
93
|
+
});
|
|
94
|
+
expressions.push(...expr);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
expressions.push(...inputExpressions);
|
|
98
|
+
}
|
|
99
|
+
return expressions;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
private async loadQuestion(id: number) {
|
|
103
|
+
const repo = this.entityManager.getRepository(DashboardQuestion);
|
|
104
|
+
|
|
105
|
+
// Load the dashboard record using the field
|
|
106
|
+
const question = await repo.findOne({
|
|
107
|
+
where: {
|
|
108
|
+
id,
|
|
109
|
+
},
|
|
110
|
+
relations: ['questionSqlDatasetConfigs', 'dashboard', 'dashboard.dashboardVariables'],
|
|
111
|
+
});
|
|
112
|
+
return question;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { Injectable } from "@nestjs/common";
|
|
2
|
+
import { IDashboardVariableSelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from "../../interfaces";
|
|
3
|
+
// import localeCodes from 'locale-codes';
|
|
4
|
+
import { EntityManager } from "typeorm";
|
|
5
|
+
import { DashboardVariableSelectionProvider } from "src/decorators/dashboard-selection-provider.decorator";
|
|
6
|
+
|
|
7
|
+
@DashboardVariableSelectionProvider()
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class DashboardVariableSQLDynamicProvider implements IDashboardVariableSelectionProvider<ISelectionProviderContext> {
|
|
10
|
+
|
|
11
|
+
constructor(private readonly entityManager: EntityManager) {
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
help(): string {
|
|
15
|
+
return "# Get the dashboard variable after executing the SQL query configured for the dashboard variable.\n";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
name(): string {
|
|
19
|
+
return 'DashboardVariableSQLDynamicProvider';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async value(optionValue: string, ctxt: ISelectionProviderContext): Promise<ISelectionProviderValues | any> {
|
|
23
|
+
throw new Error("DashboardVariableSQLDynamicProvider does not support value method. Use values method instead.");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async values(query: string, ctxt: ISelectionProviderContext): Promise<readonly ISelectionProviderValues[]> {
|
|
27
|
+
const { sql, limit, offset } = ctxt as unknown as { sql: string, limit?: number, offset?: number };
|
|
28
|
+
if (!sql) {
|
|
29
|
+
throw new Error("DashboardVariableSQLDynamicProvider requires a SQL query to be provided in the context.");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Here you would execute the SQL query against your database
|
|
33
|
+
// For demonstration, let's assume we have a mock database function that executes the SQL query
|
|
34
|
+
const results = await this.entityManager.query(this.appendLimitOffset(sql), [limit, offset]);
|
|
35
|
+
|
|
36
|
+
// Transform the results into the expected format
|
|
37
|
+
return results.map((result: any) => {
|
|
38
|
+
const transformedResult: ISelectionProviderValues = {
|
|
39
|
+
value: result.value, // Assuming the result has a 'value' field
|
|
40
|
+
label: result.label, // Assuming the result has a 'label' field
|
|
41
|
+
// Add any other fields you need to transform here
|
|
42
|
+
};
|
|
43
|
+
return transformedResult;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
appendLimitOffset(sql: string): string {
|
|
48
|
+
// Strip trailing semicolon if present
|
|
49
|
+
const trimmedSql = sql.trim().replace(/;$/, '');
|
|
50
|
+
|
|
51
|
+
// Append the LIMIT/OFFSET
|
|
52
|
+
const finalSql = `${trimmedSql} LIMIT $1 OFFSET $2`; // FIXME This works with PostgreSQL. for mysql use ?. For this we will need to identify the datasource using the model for the particular dashboard variable
|
|
53
|
+
|
|
54
|
+
return finalSql;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Injectable } from "@nestjs/common";
|
|
2
|
+
import { IDashboardVariableSelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from "../../interfaces";
|
|
3
|
+
// import localeCodes from 'locale-codes';
|
|
4
|
+
import { EntityManager } from "typeorm";
|
|
5
|
+
import { DashboardVariableSelectionProvider } from "src/decorators/dashboard-selection-provider.decorator";
|
|
6
|
+
|
|
7
|
+
@DashboardVariableSelectionProvider()
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class DasbhoardVariableTestDynamicProvider implements IDashboardVariableSelectionProvider<ISelectionProviderContext> {
|
|
10
|
+
|
|
11
|
+
constructor(private readonly entityManager: EntityManager) {
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
help(): string {
|
|
15
|
+
return "# Get the dashboard variable values.\n";
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
name(): string {
|
|
19
|
+
return 'DasbhoardVariableTestDynamicProvider';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async value(optionValue: string, ctxt: ISelectionProviderContext): Promise<ISelectionProviderValues | any> {
|
|
23
|
+
throw new Error("DasbhoardVariableTestDynamicProvider does not support value method. Use values method instead.");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async values(query: string, ctxt: ISelectionProviderContext): Promise<readonly ISelectionProviderValues[]> {
|
|
27
|
+
// Return some dummy data for testing
|
|
28
|
+
const { sql, limit, offset } = ctxt as unknown as { sql: string, limit?: number, offset?: number };
|
|
29
|
+
return [
|
|
30
|
+
{ value: '1', label: 'Option 1' },
|
|
31
|
+
{ value: '2', label: 'Option 2' },
|
|
32
|
+
{ value: '3', label: 'Option 3' },
|
|
33
|
+
{ value: '4', label: 'Option 4' },
|
|
34
|
+
];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Injectable, Logger } from '@nestjs/common';
|
|
2
|
+
import { DiscoveryService, ModuleRef } from "@nestjs/core";
|
|
3
|
+
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
|
|
4
|
+
import { EntityManager, Repository } from 'typeorm';
|
|
5
|
+
|
|
6
|
+
import { ConfigService } from '@nestjs/config';
|
|
7
|
+
import { CrudHelperService } from 'src/services/crud-helper.service';
|
|
8
|
+
import { CRUDService } from 'src/services/crud.service';
|
|
9
|
+
import { FileService } from 'src/services/file.service';
|
|
10
|
+
import { ModelMetadataService } from 'src/services/model-metadata.service';
|
|
11
|
+
import { ModuleMetadataService } from 'src/services/module-metadata.service';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import { DashboardVariable } from '../entities/dashboard-variable.entity';
|
|
15
|
+
|
|
16
|
+
@Injectable()
|
|
17
|
+
export class DashboardVariableService extends CRUDService<DashboardVariable> {
|
|
18
|
+
private readonly logger = new Logger(this.constructor.name);
|
|
19
|
+
constructor(
|
|
20
|
+
readonly modelMetadataService: ModelMetadataService,
|
|
21
|
+
readonly moduleMetadataService: ModuleMetadataService,
|
|
22
|
+
readonly configService: ConfigService,
|
|
23
|
+
readonly fileService: FileService,
|
|
24
|
+
readonly discoveryService: DiscoveryService,
|
|
25
|
+
readonly crudHelperService: CrudHelperService,
|
|
26
|
+
@InjectEntityManager()
|
|
27
|
+
readonly entityManager: EntityManager,
|
|
28
|
+
@InjectRepository(DashboardVariable, 'default')
|
|
29
|
+
readonly repo: Repository<DashboardVariable>,
|
|
30
|
+
readonly moduleRef: ModuleRef,
|
|
31
|
+
) {
|
|
32
|
+
super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'dashboardVariable', 'solid-core', moduleRef);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { Injectable, Logger, NotFoundException } from '@nestjs/common';
|
|
2
|
+
import { DiscoveryService, ModuleRef } from "@nestjs/core";
|
|
3
|
+
import { InjectEntityManager } from '@nestjs/typeorm';
|
|
4
|
+
import { EntityManager } from 'typeorm';
|
|
5
|
+
|
|
6
|
+
import { ConfigService } from '@nestjs/config';
|
|
7
|
+
import { CrudHelperService } from 'src/services/crud-helper.service';
|
|
8
|
+
import { CRUDService } from 'src/services/crud.service';
|
|
9
|
+
import { FileService } from 'src/services/file.service';
|
|
10
|
+
import { ModelMetadataService } from 'src/services/model-metadata.service';
|
|
11
|
+
import { ModuleMetadataService } from 'src/services/module-metadata.service';
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import * as fs from 'fs/promises'; // Use the Promise-based version of fs for async/await
|
|
15
|
+
import { SelectionDynamicSourceType } from 'src/dtos/create-dashboard-variable.dto';
|
|
16
|
+
import { DashboardVariableSelectionDynamicQueryDto } from 'src/dtos/dashboard-variable-selection-dynamic-query.dto';
|
|
17
|
+
import { DashboardVariable } from 'src/entities/dashboard-variable.entity';
|
|
18
|
+
import { ModuleMetadataHelperService } from 'src/helpers/module-metadata-helper.service';
|
|
19
|
+
import { SolidRegistry } from 'src/helpers/solid-registry';
|
|
20
|
+
import { DashboardMapper } from 'src/mappers/dashboard-mapper';
|
|
21
|
+
import { DashboardRepository } from 'src/repository/dashboard.repository';
|
|
22
|
+
import { Dashboard } from '../entities/dashboard.entity';
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
export const SQL_DYNAMIC_PROVIDER_NAME = 'DashboardVariableSQLDynamicProvider';
|
|
26
|
+
@Injectable()
|
|
27
|
+
export class DashboardService extends CRUDService<Dashboard> {
|
|
28
|
+
private readonly logger = new Logger(this.constructor.name);
|
|
29
|
+
constructor(
|
|
30
|
+
readonly modelMetadataService: ModelMetadataService,
|
|
31
|
+
readonly moduleMetadataService: ModuleMetadataService,
|
|
32
|
+
readonly configService: ConfigService,
|
|
33
|
+
readonly fileService: FileService,
|
|
34
|
+
readonly discoveryService: DiscoveryService,
|
|
35
|
+
readonly crudHelperService: CrudHelperService,
|
|
36
|
+
@InjectEntityManager()
|
|
37
|
+
readonly entityManager: EntityManager,
|
|
38
|
+
readonly repo: DashboardRepository, // Assuming you have a DashboardRepository for custom queries
|
|
39
|
+
readonly moduleRef: ModuleRef,
|
|
40
|
+
readonly solidRegistry: SolidRegistry, // Assuming solidRegistry is injected for selection providers
|
|
41
|
+
readonly moduleMetadataHelperService: ModuleMetadataHelperService,
|
|
42
|
+
readonly dashboardMapper: DashboardMapper,
|
|
43
|
+
) {
|
|
44
|
+
super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService, entityManager, repo, 'dashboard', 'solid-core', moduleRef);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async getSelectionDynamicValues(query: DashboardVariableSelectionDynamicQueryDto) {
|
|
48
|
+
// Get the dashboard variable repo
|
|
49
|
+
const dashboardVariable = await this.loadDashboardVariable(query.variableId);
|
|
50
|
+
|
|
51
|
+
// Get the providerName and context for the dashboard variable
|
|
52
|
+
const [providerName, context] = this.getProviderNameAndContext(dashboardVariable, query);
|
|
53
|
+
|
|
54
|
+
// Get hold of the provider instance from the SolidRegistry
|
|
55
|
+
const selectionProviderInstance = this.solidRegistry.getDashboardVariableSelectionProviderInstance(providerName);
|
|
56
|
+
if (!selectionProviderInstance) {
|
|
57
|
+
throw new NotFoundException(`Field incorrectly configured. No provider with name ${providerName} registered in backend.`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 4. Call the provider's getSelectionDynamicValues method
|
|
61
|
+
return selectionProviderInstance.values(query.query, context);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
private getProviderNameAndContext(dashboardVariable: DashboardVariable, query: DashboardVariableSelectionDynamicQueryDto): [string, any] {
|
|
66
|
+
const sourceType = dashboardVariable.selectionDynamicSourceType;
|
|
67
|
+
|
|
68
|
+
// Get the appropriate provide name based on the source type
|
|
69
|
+
let providerName: string;
|
|
70
|
+
const context = { limit: query.limit, offset: query.offset };
|
|
71
|
+
switch (sourceType) {
|
|
72
|
+
case SelectionDynamicSourceType.SQL:
|
|
73
|
+
providerName = SQL_DYNAMIC_PROVIDER_NAME;
|
|
74
|
+
context['sql'] = dashboardVariable.selectionDynamicSQL;
|
|
75
|
+
break;
|
|
76
|
+
case SelectionDynamicSourceType.PROVIDER:
|
|
77
|
+
providerName = dashboardVariable.selectionDynamicProviderName;
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
throw new Error(`Unsupported selection dynamic source type: ${sourceType}`);
|
|
81
|
+
}
|
|
82
|
+
return [providerName, context];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
private async loadDashboardVariable(variableId: number) {
|
|
86
|
+
const dashboardVariableRepo = this.entityManager.getRepository(DashboardVariable);
|
|
87
|
+
|
|
88
|
+
// Load the dashboard record using the field
|
|
89
|
+
const dashboardVariable = await dashboardVariableRepo.findOne({
|
|
90
|
+
where: {
|
|
91
|
+
id: variableId,
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
return dashboardVariable;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async saveDashboardToConfig(entity: Dashboard) {
|
|
98
|
+
if (!entity) {
|
|
99
|
+
this.logger.debug('No entity found in the DashboardSubscriber saveDashboardToConfig method');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Validate dashboard details
|
|
104
|
+
const dashboard = entity as Dashboard;
|
|
105
|
+
const moduleMetadata = entity.module;
|
|
106
|
+
if (!moduleMetadata) {
|
|
107
|
+
throw new Error(`Module metadata not found for dashboard id ${entity.id}`);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Get config file details
|
|
111
|
+
const { filePath, metaData } = await this.getConfigFileDetails(moduleMetadata.name);
|
|
112
|
+
if (!filePath || !metaData) {
|
|
113
|
+
throw new Error(`Configuration details not found for module: ${moduleMetadata.name}`);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Write the dashboard to the config file
|
|
117
|
+
await this.writeToConfig(metaData, dashboard, filePath);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private async getConfigFileDetails(moduleName: string): Promise<{ filePath: string; metaData: any }> {
|
|
121
|
+
const filePath = await this.moduleMetadataHelperService.getModuleMetadataFilePath(moduleName);
|
|
122
|
+
try {
|
|
123
|
+
await fs.access(filePath);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
throw new Error(`Configuration file not found for module: ${moduleName}`);
|
|
126
|
+
}
|
|
127
|
+
const metaData = await this.moduleMetadataHelperService.getModuleMetadataConfiguration(filePath);
|
|
128
|
+
return { filePath, metaData };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private async writeToConfig(metaData: any, dashboard: Dashboard, filePath: string) {
|
|
132
|
+
if (metaData.dashboards) {
|
|
133
|
+
const dashboardIndex = metaData.dashboards?.findIndex((dashboardFromFile: { name: string; }) => dashboardFromFile.name === dashboard.name);
|
|
134
|
+
const dto = await this.dashboardMapper.toDto(dashboard);
|
|
135
|
+
metaData.dashboards[dashboardIndex] = dto;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
const dashboards = [];
|
|
139
|
+
const dto = await this.dashboardMapper.toDto(dashboard);
|
|
140
|
+
dashboards.push(dto);
|
|
141
|
+
metaData.dashboards = dashboards;
|
|
142
|
+
}
|
|
143
|
+
// Write the updated object back to the file
|
|
144
|
+
const updatedContent = JSON.stringify(metaData, null, 2);
|
|
145
|
+
await fs.writeFile(filePath, updatedContent);
|
|
146
|
+
}
|
|
147
|
+
}
|