@solidstarters/solid-core 1.2.140 → 1.2.141
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/repository/view-metadata.repository.d.ts +9 -0
- package/dist/repository/view-metadata.repository.d.ts.map +1 -0
- package/dist/repository/view-metadata.repository.js +42 -0
- package/dist/repository/view-metadata.repository.js.map +1 -0
- package/dist/seeders/module-metadata-seeder.service.d.ts +1 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +22 -8
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.d.ts +14 -0
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.d.ts.map +1 -0
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js +66 -0
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js.map +1 -0
- package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.d.ts +14 -1
- package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.d.ts.map +1 -1
- package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.js +81 -5
- package/dist/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.js.map +1 -1
- package/dist/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.d.ts +12 -0
- package/dist/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.d.ts.map +1 -0
- package/dist/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.js +36 -0
- package/dist/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.js.map +1 -0
- package/dist/services/view-metadata.service.d.ts +3 -2
- package/dist/services/view-metadata.service.d.ts.map +1 -1
- package/dist/services/view-metadata.service.js +2 -3
- package/dist/services/view-metadata.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +4 -0
- package/dist/solid-core.module.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/repository/view-metadata.repository.ts +31 -0
- package/src/seeders/module-metadata-seeder.service.ts +23 -17
- package/src/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.ts +70 -0
- package/src/services/mcp-tool-response-handlers/solid-create-dashboard-mcp-tool-response-handler.service.ts +83 -9
- package/src/services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service.ts +34 -0
- package/src/services/view-metadata.service.ts +3 -2
- package/src/solid-core.module.ts +4 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidstarters/solid-core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.141",
|
|
4
4
|
"description": "This module is a NestJS module containing all the required core providers required by a Solid application",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Injectable, Logger } from "@nestjs/common";
|
|
2
|
+
import { Dashboard } from "src/entities/dashboard.entity";
|
|
3
|
+
import { ViewMetadata } from "src/entities/view-metadata.entity";
|
|
4
|
+
import { DataSource, Repository, View } from "typeorm";
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class ViewMetadataRepository extends Repository<ViewMetadata> {
|
|
8
|
+
private readonly logger = new Logger(this.constructor.name);
|
|
9
|
+
|
|
10
|
+
constructor(
|
|
11
|
+
private dataSource: DataSource,
|
|
12
|
+
) {
|
|
13
|
+
super(ViewMetadata, dataSource.createEntityManager());
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// Custom repository methods can be added here if needed
|
|
17
|
+
async findByNameAndModelNameAndModuleName(name: string, modelUserKey: string, moduleUserKey: string): Promise<ViewMetadata | null> {
|
|
18
|
+
const viewMetadata = await this.findOne({
|
|
19
|
+
where: {
|
|
20
|
+
name,
|
|
21
|
+
model: {
|
|
22
|
+
singularName: modelUserKey,
|
|
23
|
+
module: {
|
|
24
|
+
name: moduleUserKey
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return viewMetadata;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -189,7 +189,7 @@ export class ModuleMetadataSeederService {
|
|
|
189
189
|
// Email templates
|
|
190
190
|
this.logger.debug(`[Start] Processing email templates for ${moduleMetadata.name}`);
|
|
191
191
|
const emailTemplates: CreateEmailTemplateDto[] = overallMetadata.emailTemplates;
|
|
192
|
-
await this.seedEmailTemplates(emailTemplates);
|
|
192
|
+
await this.seedEmailTemplates(emailTemplates, moduleMetadata);
|
|
193
193
|
this.logger.debug(`[End] Processing email templates for ${moduleMetadata.name}`);
|
|
194
194
|
|
|
195
195
|
// Sms templates
|
|
@@ -255,10 +255,11 @@ export class ModuleMetadataSeederService {
|
|
|
255
255
|
'SavedFiltersController.partialUpdate',
|
|
256
256
|
'SavedFiltersController.update',
|
|
257
257
|
'SavedFiltersController.insertMany',
|
|
258
|
-
'SavedFiltersController.create'
|
|
258
|
+
'SavedFiltersController.create',
|
|
259
|
+
'AuthenticationController.logout'
|
|
259
260
|
]
|
|
260
261
|
await this.roleService.addPermissionToRole('Internal User', internalRolePermission);
|
|
261
|
-
await this.roleService.addPermissionToRole('Public', ['SettingController.wrapSettings']);
|
|
262
|
+
await this.roleService.addPermissionToRole('Public', ['SettingController.wrapSettings','AuthenticationController.logout']);
|
|
262
263
|
this.logger.log(`All Seeders finished`);
|
|
263
264
|
this.logger.log(`Newly created username is: ${usersDetail?.length > 0 ? usersDetail[0]?.username : ''} and password is ${usersDetail?.length > 0 ? usersDetail[0]?.password : ''}`);
|
|
264
265
|
}
|
|
@@ -313,7 +314,7 @@ export class ModuleMetadataSeederService {
|
|
|
313
314
|
}
|
|
314
315
|
}
|
|
315
316
|
|
|
316
|
-
async seedEmailTemplates(emailTemplates: CreateEmailTemplateDto[]) {
|
|
317
|
+
async seedEmailTemplates(emailTemplates: CreateEmailTemplateDto[], moduleMetadata: CreateModuleMetadataDto) {
|
|
317
318
|
if (!emailTemplates) {
|
|
318
319
|
return;
|
|
319
320
|
}
|
|
@@ -323,19 +324,24 @@ export class ModuleMetadataSeederService {
|
|
|
323
324
|
this.logger.log(`Found ${emailTemplate.name} email template`);
|
|
324
325
|
|
|
325
326
|
// We need to load the actual template contents.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
327
|
+
if (moduleMetadata.name === 'solid-core') {
|
|
328
|
+
const modulePath = path.dirname(require.resolve('@solidstarters/solid-core'));
|
|
329
|
+
const seedDataPath = path.join(modulePath, '../src/seeders/seed-data/email-templates');
|
|
330
|
+
const filePath = path.join(seedDataPath, emailTemplate.body);
|
|
331
|
+
this.logger.log(`Seeding email template from solid-core at path: ${filePath}`);
|
|
332
|
+
if (fs.existsSync(filePath)) {
|
|
333
|
+
emailTemplate.body = fs.readFileSync(filePath, 'utf-8').toString();
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
// Check if file exists
|
|
338
|
+
const emailTemplateHandlebar = `module-metadata/${moduleMetadata.name}/email-templates/${emailTemplate.body}`
|
|
339
|
+
const fullPath = path.join(process.cwd(), emailTemplateHandlebar);
|
|
340
|
+
this.logger.log(`Seeding custom email template from consuming model at path: ${fullPath}`);
|
|
341
|
+
if (fs.existsSync(fullPath)) {
|
|
342
|
+
emailTemplate.body = fs.readFileSync(fullPath, 'utf-8').toString();
|
|
343
|
+
}
|
|
344
|
+
}
|
|
339
345
|
|
|
340
346
|
// Save to DB.
|
|
341
347
|
await this.emailTemplateService.removeByName(emailTemplate.name);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Injectable } from '@nestjs/common';
|
|
2
|
+
import { InjectEntityManager } from '@nestjs/typeorm';
|
|
3
|
+
import { ComputedFieldProvider } from 'src/decorators/computed-field-provider.decorator';
|
|
4
|
+
import { ComputedFieldMetadata } from 'src/helpers/solid-registry';
|
|
5
|
+
import { IEntityPreComputeFieldProvider } from 'src/interfaces';
|
|
6
|
+
// import {
|
|
7
|
+
// ComputedFieldMetadata,
|
|
8
|
+
// ComputedFieldProvider,
|
|
9
|
+
// IEntityPreComputeFieldProvider,
|
|
10
|
+
// } from '@solidstarters/solid-core';
|
|
11
|
+
import { EntityManager } from 'typeorm';
|
|
12
|
+
// import { Agreement } from '../entities/agreement.entity';
|
|
13
|
+
|
|
14
|
+
@ComputedFieldProvider()
|
|
15
|
+
@Injectable()
|
|
16
|
+
export class AgreementIdComputationProvider implements IEntityPreComputeFieldProvider<any, any, string> {
|
|
17
|
+
constructor(
|
|
18
|
+
@InjectEntityManager()
|
|
19
|
+
private readonly entityManager: EntityManager
|
|
20
|
+
) { }
|
|
21
|
+
|
|
22
|
+
generateRandomCode(length = 5): string {
|
|
23
|
+
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
24
|
+
let result = '';
|
|
25
|
+
for (let i = 0; i < length; i++) {
|
|
26
|
+
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async isAgreementIdUnique(agreementId: string): Promise<boolean> {
|
|
32
|
+
// const count = await this.entityManager.count(Agreement, {
|
|
33
|
+
// where: { agreementId },
|
|
34
|
+
// });
|
|
35
|
+
// return count === 0;
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async generateUniqueAgreementId(codeLength: number): Promise<string> {
|
|
40
|
+
const maxAttempts = 10;
|
|
41
|
+
|
|
42
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
43
|
+
const newId = this.generateRandomCode(codeLength);
|
|
44
|
+
|
|
45
|
+
const isUnique = await this.isAgreementIdUnique(newId);
|
|
46
|
+
|
|
47
|
+
if (isUnique) {
|
|
48
|
+
return newId;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
throw new Error('Failed to generate a unique agreement ID after multiple attempts');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async preComputeValue(triggerEntity: any, computedFieldMetadata: ComputedFieldMetadata<any>): Promise<string> {
|
|
56
|
+
const prefix = computedFieldMetadata.computedFieldValueProviderCtxt['prefix'];
|
|
57
|
+
const codeLength = computedFieldMetadata.computedFieldValueProviderCtxt['length'] || 5;
|
|
58
|
+
const uniqueCode = await this.generateUniqueAgreementId(codeLength);
|
|
59
|
+
return `${prefix}-${uniqueCode}`;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
name(): string {
|
|
63
|
+
return 'AgreementIdComputationProvider';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
help(): string {
|
|
67
|
+
return 'Provider used to compute values for the agreement id field on save.';
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
}
|
|
@@ -1,15 +1,27 @@
|
|
|
1
1
|
import { Injectable } from "@nestjs/common";
|
|
2
2
|
import { plainToInstance } from "class-transformer";
|
|
3
3
|
import { CreateDashboardDto } from "src/dtos/create-dashboard.dto";
|
|
4
|
+
import { UpdateMenuItemMetadataDto } from "src/dtos/update-menu-item-metadata.dto";
|
|
4
5
|
import { AiInteraction } from "src/entities/ai-interaction.entity";
|
|
6
|
+
import { Dashboard } from "src/entities/dashboard.entity";
|
|
5
7
|
import { IMcpToolResponseHandler } from "../../interfaces";
|
|
8
|
+
import { ActionMetadataService } from "../action-metadata.service";
|
|
6
9
|
import { DashboardService } from "../dashboard.service";
|
|
10
|
+
import { MenuItemMetadataService } from "../menu-item-metadata.service";
|
|
11
|
+
import { ModelMetadataService } from "../model-metadata.service";
|
|
12
|
+
import { ModuleMetadataService } from "../module-metadata.service";
|
|
13
|
+
import { RoleMetadataService } from "../role-metadata.service";
|
|
7
14
|
|
|
8
15
|
@Injectable()
|
|
9
16
|
export class SolidCreateDashboardMcpToolResponseHandler implements IMcpToolResponseHandler {
|
|
10
17
|
|
|
11
18
|
constructor(
|
|
12
19
|
private readonly dashboardService: DashboardService,
|
|
20
|
+
private readonly actionMetadataService: ActionMetadataService,
|
|
21
|
+
private readonly menuItemMetadataService: MenuItemMetadataService,
|
|
22
|
+
private readonly moduleMetadataService: ModuleMetadataService,
|
|
23
|
+
private readonly modelMetadataService: ModelMetadataService,
|
|
24
|
+
private readonly roleService: RoleMetadataService, // Assuming roleService is a Mongoose model, adjust as necessary
|
|
13
25
|
) {
|
|
14
26
|
}
|
|
15
27
|
|
|
@@ -17,17 +29,11 @@ export class SolidCreateDashboardMcpToolResponseHandler implements IMcpToolRespo
|
|
|
17
29
|
const escapedMessage = aiInteraction.message.replace(/\\'/g, "'");
|
|
18
30
|
const aiResponseMessage = JSON.parse(escapedMessage);
|
|
19
31
|
|
|
20
|
-
|
|
32
|
+
const { dashboardDto, dashboard } = await this.createDashboard(aiResponseMessage);
|
|
21
33
|
|
|
22
|
-
|
|
23
|
-
// This is a workaround for now, until we find a better solution.
|
|
24
|
-
// const aiResponseMessageReplaced = aiResponse['message'].replace(/\\'/g, "'");
|
|
25
|
-
|
|
26
|
-
const dashboardDto = plainToInstance(CreateDashboardDto, aiResponseMessage);
|
|
27
|
-
dashboardDto['layoutJson'] = JSON.stringify(dashboardDto['layoutJson']);
|
|
34
|
+
const { moduleUserKey, actionMetadataEntity } = await this.createActionMetadataEntry(dashboardDto, dashboard);
|
|
28
35
|
|
|
29
|
-
|
|
30
|
-
const dashboard = await this.dashboardService.create(dashboardDto, []);
|
|
36
|
+
await this.createMenuItemEntry(dashboard, moduleUserKey, actionMetadataEntity);
|
|
31
37
|
|
|
32
38
|
// TODO: decide on some shape to return hre...
|
|
33
39
|
return {
|
|
@@ -36,4 +42,72 @@ export class SolidCreateDashboardMcpToolResponseHandler implements IMcpToolRespo
|
|
|
36
42
|
}
|
|
37
43
|
}
|
|
38
44
|
|
|
45
|
+
|
|
46
|
+
private async createMenuItemEntry(dashboard: Dashboard, moduleUserKey: string, actionMetadataEntity: any) {
|
|
47
|
+
const menuData = {
|
|
48
|
+
displayName: dashboard.displayName || dashboard.name,
|
|
49
|
+
name: `${moduleUserKey}-${dashboard.name}-dashboard-menu-item`,
|
|
50
|
+
sequenceNumber: 1,
|
|
51
|
+
actionUserKey: actionMetadataEntity.name,
|
|
52
|
+
moduleUserKey: moduleUserKey,
|
|
53
|
+
parentMenuItemUserKey: '',
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const adminRole = await this.roleService.findRoleByName('Admin');
|
|
57
|
+
const specifiedRoles = menuData['roles'];
|
|
58
|
+
|
|
59
|
+
// If the developer has specified roles, then resolve them, making sure that admin role is also given.
|
|
60
|
+
const specifiedRoleObjects = [adminRole];
|
|
61
|
+
if (specifiedRoles) {
|
|
62
|
+
for (let i = 0; i < specifiedRoles.length; i++) {
|
|
63
|
+
const specifiedRole = specifiedRoles[i];
|
|
64
|
+
const specifiedRoleObject = await this.roleService.findRoleByName(specifiedRole);
|
|
65
|
+
if (!specifiedRoleObject) {
|
|
66
|
+
throw new Error(`Invalid role: (${specifiedRole}) specified against menu with display name ${menuData.displayName}.`);
|
|
67
|
+
}
|
|
68
|
+
specifiedRoleObjects.push(specifiedRoleObject);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
menuData['roles'] = specifiedRoleObjects;
|
|
73
|
+
menuData['action'] = await this.actionMetadataService.findOneByUserKey(menuData.actionUserKey);
|
|
74
|
+
menuData['module'] = await this.moduleMetadataService.findOneByUserKey(menuData.moduleUserKey);
|
|
75
|
+
|
|
76
|
+
if (menuData.parentMenuItemUserKey) {
|
|
77
|
+
menuData['parentMenuItem'] = await this.menuItemMetadataService.findOneByUserKey(menuData.parentMenuItemUserKey);
|
|
78
|
+
} else {
|
|
79
|
+
menuData['parentMenuItem'] = null;
|
|
80
|
+
}
|
|
81
|
+
await this.menuItemMetadataService.upsert(menuData as unknown as UpdateMenuItemMetadataDto);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private async createActionMetadataEntry(dashboardDto: CreateDashboardDto, dashboard: Dashboard) {
|
|
85
|
+
const moduleUserKey = dashboardDto.moduleUserKey;
|
|
86
|
+
const actionMetadata = {
|
|
87
|
+
name: `${dashboard.name}-view`,
|
|
88
|
+
displayName: dashboard.displayName || dashboard.name,
|
|
89
|
+
type: 'custom',
|
|
90
|
+
domain: "{}",
|
|
91
|
+
context: "{}",
|
|
92
|
+
customComponent: `/admin/core/${moduleUserKey}/dashboards?dashboardName=${dashboard.name}`,
|
|
93
|
+
customIsModal: true,
|
|
94
|
+
serverEndpoint: '',
|
|
95
|
+
moduleUserKey: moduleUserKey,
|
|
96
|
+
modelUserKey: '',
|
|
97
|
+
viewUserKey: `${dashboard.name}-view`,
|
|
98
|
+
};
|
|
99
|
+
actionMetadata['module'] = await this.moduleMetadataService.findOneByUserKey(actionMetadata.moduleUserKey);
|
|
100
|
+
if (actionMetadata.modelUserKey) {
|
|
101
|
+
actionMetadata['model'] = await this.modelMetadataService.findOneByUserKey(actionMetadata.modelUserKey);
|
|
102
|
+
}
|
|
103
|
+
const actionMetadataEntity = await this.actionMetadataService.upsert(actionMetadata);
|
|
104
|
+
return { moduleUserKey, actionMetadataEntity };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private async createDashboard(aiResponseMessage: any) {
|
|
108
|
+
const dashboardDto = plainToInstance(CreateDashboardDto, aiResponseMessage);
|
|
109
|
+
dashboardDto['layoutJson'] = JSON.stringify(dashboardDto['layoutJson']);
|
|
110
|
+
const dashboard = await this.dashboardService.create(dashboardDto, []);
|
|
111
|
+
return { dashboardDto, dashboard };
|
|
112
|
+
}
|
|
39
113
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Injectable } from "@nestjs/common";
|
|
2
|
+
import { AiInteraction } from "src/entities/ai-interaction.entity";
|
|
3
|
+
import { ViewMetadataRepository } from "src/repository/view-metadata.repository";
|
|
4
|
+
import { IMcpToolResponseHandler } from "../../interfaces";
|
|
5
|
+
|
|
6
|
+
@Injectable()
|
|
7
|
+
export class SolidCreateModelLayoutMcpToolResponseHandler implements IMcpToolResponseHandler {
|
|
8
|
+
|
|
9
|
+
constructor(
|
|
10
|
+
private readonly viewMetadataRepository: ViewMetadataRepository,
|
|
11
|
+
) {
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async apply(aiInteraction: AiInteraction) {
|
|
15
|
+
const aiResponse = JSON.parse(aiInteraction.message);
|
|
16
|
+
|
|
17
|
+
// Get the data for resolving the view metadata
|
|
18
|
+
const {name, modelUserKey, moduleUserKey, layout} = aiResponse;
|
|
19
|
+
|
|
20
|
+
// Fetch the view metadata for the given model and module and the view name
|
|
21
|
+
const viewMetadata = await this.viewMetadataRepository.findByNameAndModelNameAndModuleName(name, modelUserKey, moduleUserKey);
|
|
22
|
+
|
|
23
|
+
viewMetadata.layout = JSON.stringify(layout);
|
|
24
|
+
// Save the updated view metadata
|
|
25
|
+
await this.viewMetadataRepository.save(viewMetadata);
|
|
26
|
+
|
|
27
|
+
// TODO: decide on some shape to return hre...
|
|
28
|
+
return {
|
|
29
|
+
seedingRequired: false,
|
|
30
|
+
serverRebooting: false,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
}
|
|
@@ -20,6 +20,7 @@ import { ViewMetadata } from '../entities/view-metadata.entity';
|
|
|
20
20
|
import { ActionMetadataService } from './action-metadata.service';
|
|
21
21
|
import { SolidIntrospectService } from './solid-introspect.service';
|
|
22
22
|
import { UserViewMetadataService } from './user-view-metadata.service';
|
|
23
|
+
import { ViewMetadataRepository } from 'src/repository/view-metadata.repository';
|
|
23
24
|
|
|
24
25
|
@Injectable()
|
|
25
26
|
export class ViewMetadataService extends CRUDService<ViewMetadata> {
|
|
@@ -35,8 +36,8 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
|
|
|
35
36
|
readonly userViewMetadataService: UserViewMetadataService,
|
|
36
37
|
@InjectEntityManager()
|
|
37
38
|
readonly entityManager: EntityManager,
|
|
38
|
-
@InjectRepository(ViewMetadata, 'default')
|
|
39
|
-
readonly repo:
|
|
39
|
+
// @InjectRepository(ViewMetadata, 'default')
|
|
40
|
+
readonly repo: ViewMetadataRepository,
|
|
40
41
|
@InjectRepository(FieldMetadata)
|
|
41
42
|
private readonly fieldMetadataRepo: Repository<FieldMetadata>,
|
|
42
43
|
@InjectRepository(ModelMetadata)
|
package/src/solid-core.module.ts
CHANGED
|
@@ -255,6 +255,8 @@ import { ViewMetadataSubsciber } from './subscribers/view-metadata.subscriber';
|
|
|
255
255
|
import { SolidCreateDashboardWidgetMcpToolResponseHandler } from './services/mcp-tool-response-handlers/solid-create-dashboard-widget-mcp-tool-response-handler.service';
|
|
256
256
|
import { SolidCreateModelWithFieldsMcpToolResponseHandler } from './services/mcp-tool-response-handlers/solid-create-model-with-fields-mcp-tool-response-handler.service';
|
|
257
257
|
import { SolidAddFieldMcpToolResponseHandler } from './services/mcp-tool-response-handlers/solid-add-field-mcp-tool-response-handler.service';
|
|
258
|
+
import { ViewMetadataRepository } from './repository/view-metadata.repository';
|
|
259
|
+
import { SolidCreateModelLayoutMcpToolResponseHandler } from './services/mcp-tool-response-handlers/solid-save-model-layout-mcp-tool-response-handler.service';
|
|
258
260
|
|
|
259
261
|
|
|
260
262
|
@Global()
|
|
@@ -540,6 +542,8 @@ import { SolidAddFieldMcpToolResponseHandler } from './services/mcp-tool-respons
|
|
|
540
542
|
SolidCreateDashboardWidgetMcpToolResponseHandler,
|
|
541
543
|
SolidCreateModelWithFieldsMcpToolResponseHandler,
|
|
542
544
|
SolidAddFieldMcpToolResponseHandler,
|
|
545
|
+
ViewMetadataRepository,
|
|
546
|
+
SolidCreateModelLayoutMcpToolResponseHandler,
|
|
543
547
|
],
|
|
544
548
|
exports: [
|
|
545
549
|
ModuleMetadataService,
|