@solidxai/core 0.1.10 → 0.1.11-beta.1
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/datasource-introspection.controller.d.ts +234 -0
- package/dist/controllers/datasource-introspection.controller.d.ts.map +1 -0
- package/dist/controllers/datasource-introspection.controller.js +98 -0
- package/dist/controllers/datasource-introspection.controller.js.map +1 -0
- package/dist/controllers/datasource-management.controller.d.ts +18 -0
- package/dist/controllers/datasource-management.controller.d.ts.map +1 -0
- package/dist/controllers/datasource-management.controller.js +55 -0
- package/dist/controllers/datasource-management.controller.js.map +1 -0
- package/dist/dtos/create-datasource-management.dto.d.ts +25 -0
- package/dist/dtos/create-datasource-management.dto.d.ts.map +1 -0
- package/dist/dtos/create-datasource-management.dto.js +169 -0
- package/dist/dtos/create-datasource-management.dto.js.map +1 -0
- package/dist/dtos/datasource-introspection-mapping.dto.d.ts +45 -0
- package/dist/dtos/datasource-introspection-mapping.dto.d.ts.map +1 -0
- package/dist/dtos/datasource-introspection-mapping.dto.js +233 -0
- package/dist/dtos/datasource-introspection-mapping.dto.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/datasource-introspection-provider.interface.d.ts +26 -0
- package/dist/interfaces/datasource-introspection-provider.interface.d.ts.map +1 -0
- package/dist/interfaces/datasource-introspection-provider.interface.js +3 -0
- package/dist/interfaces/datasource-introspection-provider.interface.js.map +1 -0
- package/dist/repository/scheduled-job.repository.d.ts +3 -0
- package/dist/repository/scheduled-job.repository.d.ts.map +1 -1
- package/dist/repository/scheduled-job.repository.js +60 -0
- package/dist/repository/scheduled-job.repository.js.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts +32 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +1011 -230
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +21 -0
- package/dist/services/action-metadata.service.d.ts +7 -0
- package/dist/services/action-metadata.service.d.ts.map +1 -1
- package/dist/services/action-metadata.service.js +76 -3
- package/dist/services/action-metadata.service.js.map +1 -1
- package/dist/services/authentication.service.js +1 -1
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.d.ts.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.js +2 -2
- package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.js.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.d.ts.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.js +2 -2
- package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.js.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-provider-utils.d.ts +3 -0
- package/dist/services/dashboard-providers/mq-dashboard-provider-utils.d.ts.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-provider-utils.js +71 -0
- package/dist/services/dashboard-providers/mq-dashboard-provider-utils.js.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.d.ts.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.js +3 -3
- package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.js.map +1 -1
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts +11 -0
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts.map +1 -0
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js +181 -0
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js.map +1 -0
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts +11 -0
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts.map +1 -0
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js +90 -0
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js.map +1 -0
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts +11 -0
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts.map +1 -0
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js +156 -0
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js.map +1 -0
- package/dist/services/datasource-introspection.service.d.ts +288 -0
- package/dist/services/datasource-introspection.service.d.ts.map +1 -0
- package/dist/services/datasource-introspection.service.js +1278 -0
- package/dist/services/datasource-introspection.service.js.map +1 -0
- package/dist/services/datasource-management.service.d.ts +60 -0
- package/dist/services/datasource-management.service.d.ts.map +1 -0
- package/dist/services/datasource-management.service.js +461 -0
- package/dist/services/datasource-management.service.js.map +1 -0
- package/dist/services/field-metadata.service.d.ts.map +1 -1
- package/dist/services/field-metadata.service.js +19 -0
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts +1 -3
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +47 -15
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/role-metadata.service.d.ts +5 -0
- package/dist/services/role-metadata.service.d.ts.map +1 -1
- package/dist/services/role-metadata.service.js +85 -31
- package/dist/services/role-metadata.service.js.map +1 -1
- package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.d.ts.map +1 -1
- package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.js +2 -3
- package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.js.map +1 -1
- package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.d.ts.map +1 -1
- package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.js +2 -3
- package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.js.map +1 -1
- package/dist/services/setting.service.d.ts +1 -0
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +32 -8
- package/dist/services/setting.service.js.map +1 -1
- package/dist/services/solid-ts-morph.service.d.ts +1 -1
- package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
- package/dist/services/solid-ts-morph.service.js.map +1 -1
- package/dist/services/view-metadata.service.d.ts +6 -0
- package/dist/services/view-metadata.service.d.ts.map +1 -1
- package/dist/services/view-metadata.service.js +66 -1
- 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 +16 -0
- package/dist/solid-core.module.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/docs/agent-hub-grooming.md +301 -0
- package/docs/dashboards/AGENTIC_DASHBOARD_IMPLEMENTATION_PLAN.md +438 -0
- package/docs/dashboards/dashboard-curl-smoke-tests.txt +146 -0
- package/docs/dashboards/delete-legacy-dashboard-metadata.sql +172 -0
- package/docs/datasource-introspection-ddl-analysis.md +326 -0
- package/docs/datasource-introspection-implementation-plan.md +306 -0
- package/docs/grouping-enhancements.md +89 -0
- package/docs/java-spring/README.md +3 -0
- package/docs/java-spring/solid-core-module-deep-dive-report.md +1317 -0
- package/docs/module-package-import-handoff.md +691 -0
- package/docs/seed-changes.md +65 -0
- package/docs/test-data-workflow.md +200 -0
- package/docs/type-declaration-import-issue.md +24 -0
- package/package.json +1 -1
- package/src/controllers/datasource-introspection.controller.ts +58 -0
- package/src/controllers/datasource-management.controller.ts +24 -0
- package/src/dtos/create-datasource-management.dto.ts +139 -0
- package/src/dtos/datasource-introspection-mapping.dto.ts +182 -0
- package/src/index.ts +5 -0
- package/src/interfaces/datasource-introspection-provider.interface.ts +28 -0
- package/src/repository/scheduled-job.repository.ts +73 -0
- package/src/seeders/module-metadata-seeder.service.ts +1223 -262
- package/src/seeders/seed-data/solid-core-metadata.json +22 -1
- package/src/services/action-metadata.service.ts +87 -2
- package/src/services/authentication.service.ts +1 -1
- package/src/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.ts +9 -4
- package/src/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.ts +9 -4
- package/src/services/dashboard-providers/mq-dashboard-provider-utils.ts +82 -0
- package/src/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.ts +10 -4
- package/src/services/datasource-introspection/mssql-datasource-introspection-provider.service.ts +185 -0
- package/src/services/datasource-introspection/mysql-datasource-introspection-provider.service.ts +95 -0
- package/src/services/datasource-introspection/postgres-datasource-introspection-provider.service.ts +160 -0
- package/src/services/datasource-introspection.service.ts +1536 -0
- package/src/services/datasource-management.service.ts +566 -0
- package/src/services/field-metadata.service.ts +21 -1
- package/src/services/model-metadata.service.ts +50 -13
- package/src/services/role-metadata.service.ts +100 -47
- package/src/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.ts +2 -4
- package/src/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.ts +2 -4
- package/src/services/setting.service.ts +43 -12
- package/src/services/solid-ts-morph.service.ts +2 -2
- package/src/services/view-metadata.service.ts +79 -1
- package/src/solid-core.module.ts +16 -0
- package/.claude/settings.local.json +0 -15
- package/src/services/1.js +0 -6
|
@@ -24,6 +24,7 @@ import { ImportTransaction } from '../entities/import-transaction.entity';
|
|
|
24
24
|
import { MenuItemMetadata } from '../entities/menu-item-metadata.entity';
|
|
25
25
|
import { UserViewMetadata } from '../entities/user-view-metadata.entity';
|
|
26
26
|
import { PermissionMetadata } from '../entities/permission-metadata.entity';
|
|
27
|
+
import { RoleMetadata } from '../entities/role-metadata.entity';
|
|
27
28
|
import { ViewMetadata } from '../entities/view-metadata.entity';
|
|
28
29
|
import { CommandService } from '../helpers/command.service';
|
|
29
30
|
import {
|
|
@@ -37,7 +38,6 @@ import { CrudHelperService, FilterCombinator } from './crud-helper.service';
|
|
|
37
38
|
import { CRUDService } from './crud.service';
|
|
38
39
|
import { FieldMetadataService } from './field-metadata.service';
|
|
39
40
|
import { MediaStorageProviderMetadataService } from './media-storage-provider-metadata.service';
|
|
40
|
-
import { RoleMetadataService } from './role-metadata.service';
|
|
41
41
|
import { SolidIntrospectService } from './solid-introspect.service';
|
|
42
42
|
import { SolidTsMorphService } from './solid-ts-morph.service';
|
|
43
43
|
|
|
@@ -59,7 +59,6 @@ export class ModelMetadataService {
|
|
|
59
59
|
private readonly crudHelperService: CrudHelperService,
|
|
60
60
|
private readonly mediaStorageProviderMetadataService: MediaStorageProviderMetadataService,
|
|
61
61
|
private readonly fieldMetadataService: FieldMetadataService,
|
|
62
|
-
private readonly roleService: RoleMetadataService,
|
|
63
62
|
private readonly moduleMetadataHelperService: ModuleMetadataHelperService,
|
|
64
63
|
readonly introspectService: SolidIntrospectService,
|
|
65
64
|
private readonly solidTsMorphService: SolidTsMorphService,
|
|
@@ -501,6 +500,27 @@ export class ModelMetadataService {
|
|
|
501
500
|
|
|
502
501
|
// if found
|
|
503
502
|
if (existingModelMetadata) {
|
|
503
|
+
const hasChanges = Object.entries(updateDto).some(([key, value]) => {
|
|
504
|
+
if (key === 'module' || key === 'parentModel' || key === 'userKeyField') {
|
|
505
|
+
return existingModelMetadata[key]?.id !== value?.id;
|
|
506
|
+
}
|
|
507
|
+
if (key === 'fields') {
|
|
508
|
+
return JSON.stringify(existingModelMetadata.fields ?? null) !== JSON.stringify(value ?? null);
|
|
509
|
+
}
|
|
510
|
+
const currentValue = existingModelMetadata[key];
|
|
511
|
+
if (Array.isArray(currentValue) || Array.isArray(value)) {
|
|
512
|
+
return JSON.stringify(currentValue ?? null) !== JSON.stringify(value ?? null);
|
|
513
|
+
}
|
|
514
|
+
if (value && typeof value === 'object') {
|
|
515
|
+
return JSON.stringify(currentValue ?? null) !== JSON.stringify(value ?? null);
|
|
516
|
+
}
|
|
517
|
+
return currentValue !== value;
|
|
518
|
+
});
|
|
519
|
+
|
|
520
|
+
if (!hasChanges) {
|
|
521
|
+
return existingModelMetadata;
|
|
522
|
+
}
|
|
523
|
+
|
|
504
524
|
const updatedModelMetadata = { ...existingModelMetadata, ...updateDto };
|
|
505
525
|
const updatedModel = await this.modelMetadataRepo.save(updatedModelMetadata);
|
|
506
526
|
return updatedModel
|
|
@@ -635,22 +655,27 @@ export class ModelMetadataService {
|
|
|
635
655
|
const metaData = await this.moduleMetadataHelperService.getModuleMetadataConfiguration(filePath);
|
|
636
656
|
if (metaData) {
|
|
637
657
|
const moduleMetadata = metaData?.moduleMetadata ?? metaData;
|
|
658
|
+
const vamMetadata =
|
|
659
|
+
Array.isArray(metaData?.views) || Array.isArray(metaData?.actions) || Array.isArray(metaData?.menus)
|
|
660
|
+
? metaData
|
|
661
|
+
: moduleMetadata;
|
|
638
662
|
const removedActionNameSet = new Set(removedActionNames);
|
|
639
663
|
const removedMenuNameSet = new Set(removedMenuNames);
|
|
640
664
|
const removedViewNameSet = new Set(removedViewNames);
|
|
641
665
|
|
|
642
|
-
const
|
|
666
|
+
const existingModels = Array.isArray(moduleMetadata?.models) ? moduleMetadata.models : [];
|
|
667
|
+
const existingModelIndex = existingModels.findIndex(
|
|
643
668
|
(existingModel: any) => existingModel.singularName === modelEntity.singularName
|
|
644
669
|
);
|
|
645
670
|
|
|
646
671
|
// Remove the model to be deleted from the metadata
|
|
647
672
|
if (existingModelIndex !== -1) {
|
|
648
|
-
|
|
673
|
+
existingModels.splice(existingModelIndex, 1);
|
|
649
674
|
}
|
|
650
675
|
|
|
651
676
|
// Remove references to this model in the menu, action & view sections.
|
|
652
|
-
const existingViews = Array.isArray(
|
|
653
|
-
|
|
677
|
+
const existingViews = Array.isArray(vamMetadata?.views) ? vamMetadata.views : [];
|
|
678
|
+
vamMetadata.views = existingViews.filter((view: any) => {
|
|
654
679
|
const shouldRemove = view?.modelUserKey === modelEntity.singularName || removedViewNameSet.has(view?.name);
|
|
655
680
|
if (shouldRemove && view?.name) {
|
|
656
681
|
removedViewNameSet.add(view.name);
|
|
@@ -658,8 +683,8 @@ export class ModelMetadataService {
|
|
|
658
683
|
return !shouldRemove;
|
|
659
684
|
});
|
|
660
685
|
|
|
661
|
-
const existingActions = Array.isArray(
|
|
662
|
-
|
|
686
|
+
const existingActions = Array.isArray(vamMetadata?.actions) ? vamMetadata.actions : [];
|
|
687
|
+
vamMetadata.actions = existingActions.filter((action: any) => {
|
|
663
688
|
const shouldRemove =
|
|
664
689
|
action?.modelUserKey === modelEntity.singularName ||
|
|
665
690
|
removedActionNameSet.has(action?.name) ||
|
|
@@ -671,7 +696,7 @@ export class ModelMetadataService {
|
|
|
671
696
|
return !shouldRemove;
|
|
672
697
|
});
|
|
673
698
|
|
|
674
|
-
let pendingMenus = Array.isArray(
|
|
699
|
+
let pendingMenus = Array.isArray(vamMetadata?.menus) ? [...vamMetadata.menus] : [];
|
|
675
700
|
let menuRemovedOnPass = true;
|
|
676
701
|
while (menuRemovedOnPass) {
|
|
677
702
|
menuRemovedOnPass = false;
|
|
@@ -693,7 +718,7 @@ export class ModelMetadataService {
|
|
|
693
718
|
return true;
|
|
694
719
|
});
|
|
695
720
|
}
|
|
696
|
-
|
|
721
|
+
vamMetadata.menus = pendingMenus;
|
|
697
722
|
|
|
698
723
|
const updatedContent = JSON.stringify(metaData, null, 2);
|
|
699
724
|
await fs.writeFile(filePath, updatedContent);
|
|
@@ -1386,7 +1411,15 @@ export class ModelMetadataService {
|
|
|
1386
1411
|
existingTreeViewAction = await actionRepo.save(createdTreeViewAction);
|
|
1387
1412
|
}
|
|
1388
1413
|
|
|
1389
|
-
const
|
|
1414
|
+
const roleRepo = this.dataSource.getRepository(RoleMetadata);
|
|
1415
|
+
const adminRole = await roleRepo.findOne({
|
|
1416
|
+
where: { name: 'Admin' },
|
|
1417
|
+
select: { id: true, name: true }
|
|
1418
|
+
});
|
|
1419
|
+
|
|
1420
|
+
if (!adminRole) {
|
|
1421
|
+
throw new NotFoundException(`Entity #Admin not found`);
|
|
1422
|
+
}
|
|
1390
1423
|
|
|
1391
1424
|
const menuData = {
|
|
1392
1425
|
displayName: `${model.displayName}`,
|
|
@@ -1394,7 +1427,6 @@ export class ModelMetadataService {
|
|
|
1394
1427
|
sequenceNumber: 1,
|
|
1395
1428
|
action: existingAction,
|
|
1396
1429
|
module: resolvedModule,
|
|
1397
|
-
roles: [adminRole],
|
|
1398
1430
|
parentMenuItemUserKey: ""
|
|
1399
1431
|
};
|
|
1400
1432
|
|
|
@@ -1402,7 +1434,12 @@ export class ModelMetadataService {
|
|
|
1402
1434
|
|
|
1403
1435
|
if (!existingMenu) {
|
|
1404
1436
|
const createdMenu = menuRepo.create(menuData);
|
|
1405
|
-
await menuRepo.save(createdMenu);
|
|
1437
|
+
existingMenu = await menuRepo.save(createdMenu);
|
|
1438
|
+
await menuRepo
|
|
1439
|
+
.createQueryBuilder()
|
|
1440
|
+
.relation(MenuItemMetadata, 'roles')
|
|
1441
|
+
.of(existingMenu.id)
|
|
1442
|
+
.add(adminRole.id);
|
|
1406
1443
|
}
|
|
1407
1444
|
}
|
|
1408
1445
|
|
|
@@ -14,6 +14,7 @@ import { RoleMetadata } from '../entities/role-metadata.entity';
|
|
|
14
14
|
@Injectable()
|
|
15
15
|
export class RoleMetadataService extends CRUDService<RoleMetadata> {
|
|
16
16
|
private readonly logger = new Logger(RoleMetadataService.name);
|
|
17
|
+
private readonly permissionAssignmentBatchSize = 500;
|
|
17
18
|
|
|
18
19
|
constructor(
|
|
19
20
|
@InjectEntityManager()
|
|
@@ -45,6 +46,20 @@ export class RoleMetadataService extends CRUDService<RoleMetadata> {
|
|
|
45
46
|
return entity;
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
async assertRoleExistsByName(roleName: string): Promise<void> {
|
|
50
|
+
const entity = await this.repo.findOne({
|
|
51
|
+
where: {
|
|
52
|
+
name: roleName
|
|
53
|
+
},
|
|
54
|
+
select: {
|
|
55
|
+
id: true
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
if (!entity) {
|
|
59
|
+
throw new NotFoundException(`Entity #${roleName} not found`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
48
63
|
// OK
|
|
49
64
|
async createRolesIfNotExists(roles: CreateRoleMetadataDto[]) {
|
|
50
65
|
for (let id = 0; id < roles.length; id++) {
|
|
@@ -112,66 +127,47 @@ export class RoleMetadataService extends CRUDService<RoleMetadata> {
|
|
|
112
127
|
private async _addPermissionsToRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {
|
|
113
128
|
const role = await this.repo.findOne({
|
|
114
129
|
where: { name: roleName },
|
|
115
|
-
|
|
116
|
-
|
|
130
|
+
select: {
|
|
131
|
+
id: true,
|
|
132
|
+
name: true,
|
|
117
133
|
}
|
|
118
134
|
});
|
|
119
135
|
if (!role) {
|
|
120
136
|
throw new Error(`Role '${roleName}' not found.`);
|
|
121
137
|
}
|
|
122
138
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
// The new set of permissions which are to be added to this role.
|
|
126
|
-
let newPermissions: PermissionMetadata[];
|
|
139
|
+
const joinInfo = this.getRolePermissionJoinInfo();
|
|
140
|
+
const targetPermissions = await this.loadTargetPermissions(permissionNames);
|
|
127
141
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
142
|
+
if (!permissionNames || permissionNames.length === 0) {
|
|
143
|
+
await this.entityManager
|
|
144
|
+
.createQueryBuilder()
|
|
145
|
+
.delete()
|
|
146
|
+
.from(joinInfo.tableName)
|
|
147
|
+
.where(`${joinInfo.roleIdColumn} = :roleId`, { roleId: role.id })
|
|
148
|
+
.execute();
|
|
131
149
|
|
|
132
|
-
|
|
133
|
-
if (newPermissions.length !== permissionNames.length) {
|
|
134
|
-
throw new Error(`One or more permissions not found.`);
|
|
135
|
-
}
|
|
150
|
+
await this.insertRolePermissionMappings(role.id, targetPermissions.map((permission) => permission.id), joinInfo);
|
|
136
151
|
}
|
|
137
152
|
else {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
for (let i = 0; i < newPermissions.length; i++) {
|
|
153
|
-
const newPermission = newPermissions[i];
|
|
154
|
-
let newPermissionFound = true;
|
|
155
|
-
for (let j = 0; j < role.permissions.length; j++) {
|
|
156
|
-
const existingPermission = role.permissions[j];
|
|
157
|
-
if (existingPermission.name === newPermission.name) {
|
|
158
|
-
newPermissionFound = false;
|
|
159
|
-
break;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (newPermissionFound) {
|
|
164
|
-
role.permissions.push(newPermission);
|
|
165
|
-
}
|
|
153
|
+
const existingRows = await this.entityManager
|
|
154
|
+
.createQueryBuilder()
|
|
155
|
+
.select(joinInfo.permissionIdColumn, 'permissionId')
|
|
156
|
+
.from(joinInfo.tableName, 'role_permission')
|
|
157
|
+
.where(`${joinInfo.roleIdColumn} = :roleId`, { roleId: role.id })
|
|
158
|
+
.getRawMany();
|
|
159
|
+
|
|
160
|
+
const existingPermissionIds = new Set(existingRows.map((row) => Number(row.permissionId)));
|
|
161
|
+
const missingPermissionIds = targetPermissions
|
|
162
|
+
.map((permission) => permission.id)
|
|
163
|
+
.filter((permissionId) => !existingPermissionIds.has(permissionId));
|
|
164
|
+
|
|
165
|
+
if (missingPermissionIds.length > 0) {
|
|
166
|
+
await this.insertRolePermissionMappings(role.id, missingPermissionIds, joinInfo);
|
|
166
167
|
}
|
|
167
|
-
|
|
168
|
-
}
|
|
169
|
-
// else we create a new permissions set.
|
|
170
|
-
else {
|
|
171
|
-
role.permissions = newPermissions;
|
|
172
168
|
}
|
|
173
169
|
|
|
174
|
-
return await this.
|
|
170
|
+
return await this.findRoleByName(roleName);
|
|
175
171
|
}
|
|
176
172
|
|
|
177
173
|
async removePermissionsFromRole(roleName: string, permissionNames: string[]): Promise<RoleMetadata> {
|
|
@@ -206,5 +202,62 @@ export class RoleMetadataService extends CRUDService<RoleMetadata> {
|
|
|
206
202
|
return existingPermission;
|
|
207
203
|
}
|
|
208
204
|
|
|
205
|
+
private async loadTargetPermissions(permissionNames: string[] | null): Promise<PermissionMetadata[]> {
|
|
206
|
+
if (permissionNames && permissionNames.length !== 0) {
|
|
207
|
+
const uniquePermissionNames = [...new Set(permissionNames)];
|
|
208
|
+
const permissions = await this.permissionRepository.find({ where: { name: In(uniquePermissionNames) } });
|
|
209
|
+
if (permissions.length !== uniquePermissionNames.length) {
|
|
210
|
+
throw new Error(`One or more permissions not found.`);
|
|
211
|
+
}
|
|
212
|
+
return permissions;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const permissions = await this.permissionRepository.find();
|
|
216
|
+
if (permissions.length === 0) {
|
|
217
|
+
throw new Error(`No permissions configured in the system. Did you forget to run the PermissionSeederService?`);
|
|
218
|
+
}
|
|
219
|
+
return permissions;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
private getRolePermissionJoinInfo(): { tableName: string; roleIdColumn: string; permissionIdColumn: string } {
|
|
223
|
+
const relation = this.repo.metadata.relations.find((candidate) => candidate.propertyName === 'permissions');
|
|
224
|
+
if (!relation?.junctionEntityMetadata) {
|
|
225
|
+
throw new Error('Role-permission join table metadata not found.');
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const roleIdColumn = relation.joinColumns[0]?.databaseName;
|
|
229
|
+
const permissionIdColumn = relation.inverseJoinColumns[0]?.databaseName;
|
|
230
|
+
if (!roleIdColumn || !permissionIdColumn) {
|
|
231
|
+
throw new Error('Role-permission join table column metadata not found.');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
tableName: relation.junctionEntityMetadata.tableName,
|
|
236
|
+
roleIdColumn,
|
|
237
|
+
permissionIdColumn,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
private async insertRolePermissionMappings(
|
|
242
|
+
roleId: number,
|
|
243
|
+
permissionIds: number[],
|
|
244
|
+
joinInfo: { tableName: string; roleIdColumn: string; permissionIdColumn: string },
|
|
245
|
+
): Promise<void> {
|
|
246
|
+
for (let index = 0; index < permissionIds.length; index += this.permissionAssignmentBatchSize) {
|
|
247
|
+
const batch = permissionIds.slice(index, index + this.permissionAssignmentBatchSize);
|
|
248
|
+
await this.entityManager
|
|
249
|
+
.createQueryBuilder()
|
|
250
|
+
.insert()
|
|
251
|
+
.into(joinInfo.tableName)
|
|
252
|
+
.values(
|
|
253
|
+
batch.map((permissionId) => ({
|
|
254
|
+
[joinInfo.roleIdColumn]: roleId,
|
|
255
|
+
[joinInfo.permissionIdColumn]: permissionId,
|
|
256
|
+
})),
|
|
257
|
+
)
|
|
258
|
+
.execute();
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
209
262
|
|
|
210
263
|
}
|
|
@@ -2,6 +2,7 @@ import { Injectable } from "@nestjs/common";
|
|
|
2
2
|
import { SelectionProvider } from "src/decorators/selection-provider.decorator";
|
|
3
3
|
import { MqMessageRepository } from "src/repository/mq-message.repository";
|
|
4
4
|
import { ISelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from "src/interfaces";
|
|
5
|
+
import { applyCaseInsensitiveContainsFilter } from "src/services/dashboard-providers/mq-dashboard-provider-utils";
|
|
5
6
|
|
|
6
7
|
@SelectionProvider()
|
|
7
8
|
@Injectable()
|
|
@@ -31,9 +32,7 @@ export class MqDashboardMessageBrokerVariableOptionsProvider implements ISelecti
|
|
|
31
32
|
qb.select("DISTINCT mqMessage.messageBroker", "value")
|
|
32
33
|
.where("mqMessage.messageBroker IS NOT NULL");
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
qb.andWhere("mqMessage.messageBroker ILIKE :query", { query: `%${query}%` });
|
|
36
|
-
}
|
|
35
|
+
applyCaseInsensitiveContainsFilter(qb, "mqMessage.messageBroker", query, "query");
|
|
37
36
|
|
|
38
37
|
const rows = await qb
|
|
39
38
|
.orderBy("value", "ASC")
|
|
@@ -49,4 +48,3 @@ export class MqDashboardMessageBrokerVariableOptionsProvider implements ISelecti
|
|
|
49
48
|
}));
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
|
-
|
|
@@ -2,6 +2,7 @@ import { Injectable } from "@nestjs/common";
|
|
|
2
2
|
import { SelectionProvider } from "src/decorators/selection-provider.decorator";
|
|
3
3
|
import { MqMessageQueueRepository } from "src/repository/mq-message-queue.repository";
|
|
4
4
|
import { ISelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from "src/interfaces";
|
|
5
|
+
import { applyCaseInsensitiveContainsFilter } from "src/services/dashboard-providers/mq-dashboard-provider-utils";
|
|
5
6
|
|
|
6
7
|
@SelectionProvider()
|
|
7
8
|
@Injectable()
|
|
@@ -32,9 +33,7 @@ export class MqDashboardQueueNameVariableOptionsProvider implements ISelectionPr
|
|
|
32
33
|
const limit = Math.min(Math.max(ctxt?.limit ?? 25, 1), 200);
|
|
33
34
|
const offset = Math.max(ctxt?.offset ?? 0, 0);
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
qb.andWhere("mqMessageQueue.name ILIKE :query", { query: `%${query}%` });
|
|
37
|
-
}
|
|
36
|
+
applyCaseInsensitiveContainsFilter(qb, "mqMessageQueue.name", query, "query");
|
|
38
37
|
|
|
39
38
|
const records = await qb
|
|
40
39
|
.select(["mqMessageQueue.name"])
|
|
@@ -48,4 +47,3 @@ export class MqDashboardQueueNameVariableOptionsProvider implements ISelectionPr
|
|
|
48
47
|
.map((r) => ({ label: r.name, value: r.name }));
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
|
-
|
|
@@ -51,6 +51,10 @@ export class SettingService {
|
|
|
51
51
|
return settings;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
private async getSettingsFromDbForSeeding(): Promise<Setting[]> {
|
|
55
|
+
return this.repo.find({ relations: ['moduleMetadata'] });
|
|
56
|
+
}
|
|
57
|
+
|
|
54
58
|
private parseSettingValue(value: string, key: string): any {
|
|
55
59
|
try {
|
|
56
60
|
return JSON.parse(value);
|
|
@@ -194,15 +198,30 @@ export class SettingService {
|
|
|
194
198
|
const saEditableAndAbove = this.getAllSettingsFromProviders().filter(i => [SettingLevel.SystemAdminEditable, SettingLevel.InternalUser].includes(i.level));
|
|
195
199
|
|
|
196
200
|
// Get hold of the current values from the database.
|
|
197
|
-
const existingSettingsFromDb: Setting[] = await this.
|
|
201
|
+
const existingSettingsFromDb: Setting[] = await this.getSettingsFromDbForSeeding();
|
|
198
202
|
|
|
199
203
|
// const existingKeysFromDb = new Set(existingSettingsFromDb.map(s => s.key));
|
|
200
204
|
const existingSettingsFromDbByKey = new Map(existingSettingsFromDb.map(setting => [setting.key, setting]));
|
|
201
|
-
const
|
|
202
|
-
|
|
205
|
+
const settingsToCreate: Setting[] = [];
|
|
206
|
+
const settingsToUpdate: Setting[] = [];
|
|
207
|
+
const moduleNames = Array.from(
|
|
208
|
+
new Set(
|
|
209
|
+
saEditableAndAbove
|
|
210
|
+
.map(setting => setting.moduleName)
|
|
211
|
+
.filter((moduleName): moduleName is string => !!moduleName)
|
|
212
|
+
)
|
|
213
|
+
);
|
|
214
|
+
const moduleMetadataByName = new Map<string, Awaited<ReturnType<ModuleMetadataRepository['findOneBy']>>>();
|
|
215
|
+
|
|
216
|
+
await Promise.all(
|
|
217
|
+
moduleNames.map(async (moduleName) => {
|
|
218
|
+
const moduleMetadata = await this.moduleMetadataRepo.findOneBy({ name: moduleName });
|
|
219
|
+
moduleMetadataByName.set(moduleName, moduleMetadata);
|
|
220
|
+
})
|
|
221
|
+
);
|
|
203
222
|
|
|
204
223
|
for (const { key, value, level, moduleName, encrypted } of saEditableAndAbove) {
|
|
205
|
-
const moduleMetadata =
|
|
224
|
+
const moduleMetadata = moduleName ? moduleMetadataByName.get(moduleName) : null;
|
|
206
225
|
if (!existingSettingsFromDbByKey.has(key)) {
|
|
207
226
|
const setting = new Setting();
|
|
208
227
|
setting.key = key;
|
|
@@ -227,24 +246,36 @@ export class SettingService {
|
|
|
227
246
|
}
|
|
228
247
|
setting.value = rawValue;
|
|
229
248
|
|
|
230
|
-
|
|
249
|
+
settingsToCreate.push(setting);
|
|
231
250
|
}
|
|
232
251
|
else {
|
|
233
252
|
const setting = existingSettingsFromDbByKey.get(key);
|
|
253
|
+
const existingModuleMetadataId = setting.moduleMetadata?.id ?? null;
|
|
254
|
+
const nextModuleMetadataId = moduleMetadata?.id ?? null;
|
|
255
|
+
const levelChanged = setting.level !== level;
|
|
256
|
+
const encryptedChanged = setting.encrypted !== !!encrypted;
|
|
257
|
+
const moduleChanged = !!moduleMetadata && existingModuleMetadataId !== nextModuleMetadataId;
|
|
258
|
+
|
|
259
|
+
if (!levelChanged && !encryptedChanged && !moduleChanged) {
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
|
|
234
263
|
setting.level = level;
|
|
235
264
|
setting.encrypted = !!encrypted;
|
|
236
|
-
if (moduleMetadata)
|
|
265
|
+
if (moduleMetadata) {
|
|
237
266
|
setting.moduleMetadata = moduleMetadata;
|
|
238
|
-
|
|
267
|
+
}
|
|
268
|
+
settingsToUpdate.push(setting);
|
|
239
269
|
}
|
|
240
270
|
}
|
|
241
271
|
|
|
242
|
-
if (
|
|
243
|
-
await this.repo.save(
|
|
272
|
+
if (settingsToCreate.length > 0) {
|
|
273
|
+
await this.repo.save(settingsToCreate);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (settingsToUpdate.length > 0) {
|
|
277
|
+
await this.repo.save(settingsToUpdate);
|
|
244
278
|
}
|
|
245
|
-
// if (settingsToUpdate.length > 0) {
|
|
246
|
-
// await this.repo.save(settingsToUpdate);
|
|
247
|
-
// }
|
|
248
279
|
}
|
|
249
280
|
|
|
250
281
|
/**
|
|
@@ -5,7 +5,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
|
5
5
|
import { Project, Node, ObjectLiteralExpression, ArrayLiteralExpression, QuoteKind, IndentationText } from "ts-morph";
|
|
6
6
|
import { MethodDeclarationStructure, StructureKind } from "ts-morph";
|
|
7
7
|
|
|
8
|
-
type Bucket = "providers" | "exports";
|
|
8
|
+
type Bucket = "imports" | "providers" | "exports";
|
|
9
9
|
|
|
10
10
|
// interface SolidTsMorphOptions {
|
|
11
11
|
// /** Absolute path to monorepo root. Defaults to auto-detect or ENV. */
|
|
@@ -470,4 +470,4 @@ export class SolidTsMorphService {
|
|
|
470
470
|
|
|
471
471
|
|
|
472
472
|
|
|
473
|
-
}
|
|
473
|
+
}
|
|
@@ -21,6 +21,74 @@ import { MenuItemMetadata } from 'src/entities/menu-item-metadata.entity';
|
|
|
21
21
|
|
|
22
22
|
@Injectable()
|
|
23
23
|
export class ViewMetadataService extends CRUDService<ViewMetadata> {
|
|
24
|
+
private readonly comparableFields = [
|
|
25
|
+
'name',
|
|
26
|
+
'displayName',
|
|
27
|
+
'type',
|
|
28
|
+
'context',
|
|
29
|
+
'layout',
|
|
30
|
+
'module',
|
|
31
|
+
'model',
|
|
32
|
+
] as const;
|
|
33
|
+
private readonly relationCompareFields = new Set(['module', 'model']);
|
|
34
|
+
private readonly jsonCompareFields = new Set(['layout', 'context']);
|
|
35
|
+
|
|
36
|
+
private normalizeJsonFieldValue(value: any): any {
|
|
37
|
+
if (typeof value === 'string') {
|
|
38
|
+
const trimmedValue = value.trim();
|
|
39
|
+
if (
|
|
40
|
+
(trimmedValue.startsWith('{') && trimmedValue.endsWith('}')) ||
|
|
41
|
+
(trimmedValue.startsWith('[') && trimmedValue.endsWith(']'))
|
|
42
|
+
) {
|
|
43
|
+
try {
|
|
44
|
+
return this.normalizeJsonFieldValue(JSON.parse(trimmedValue));
|
|
45
|
+
} catch {
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return value;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (Array.isArray(value)) {
|
|
53
|
+
return value.map((item) => this.normalizeJsonFieldValue(item));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (value && typeof value === 'object') {
|
|
57
|
+
return Object.keys(value)
|
|
58
|
+
.sort()
|
|
59
|
+
.reduce((result, key) => {
|
|
60
|
+
result[key] = this.normalizeJsonFieldValue(value[key]);
|
|
61
|
+
return result;
|
|
62
|
+
}, {} as Record<string, any>);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private getCanonicalJsonFieldString(value: any): string {
|
|
69
|
+
return JSON.stringify(this.normalizeJsonFieldValue(value) ?? null);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private hasChanges(existingSolidView: ViewMetadata, updateSolidViewDto: UpdateViewMetadataDto): boolean {
|
|
73
|
+
return this.comparableFields.some((key) => {
|
|
74
|
+
const value = (updateSolidViewDto as any)[key];
|
|
75
|
+
if (typeof value === 'undefined') {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (this.relationCompareFields.has(key)) {
|
|
80
|
+
const relationValue = value as any;
|
|
81
|
+
return (existingSolidView as any)[key]?.id !== relationValue?.id;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (this.jsonCompareFields.has(key)) {
|
|
85
|
+
return this.getCanonicalJsonFieldString((existingSolidView as any)[key]) !== this.getCanonicalJsonFieldString(value);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return (existingSolidView as any)[key] !== value;
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
24
92
|
constructor(
|
|
25
93
|
readonly actionMetadataService: ActionMetadataService,
|
|
26
94
|
readonly menuItemMetadataService: MenuItemMetadataService,
|
|
@@ -438,10 +506,20 @@ export class ViewMetadataService extends CRUDService<ViewMetadata> {
|
|
|
438
506
|
|
|
439
507
|
async upsert(updateSolidViewDto: UpdateViewMetadataDto) {
|
|
440
508
|
// First check if module already exists using name
|
|
441
|
-
const existingSolidView = await this.findOneByUserKey(updateSolidViewDto.name
|
|
509
|
+
const existingSolidView = await this.findOneByUserKey(updateSolidViewDto.name, {
|
|
510
|
+
module: true,
|
|
511
|
+
model: true,
|
|
512
|
+
});
|
|
442
513
|
|
|
443
514
|
// if found
|
|
444
515
|
if (existingSolidView) {
|
|
516
|
+
const hasChanges = this.hasChanges(existingSolidView, updateSolidViewDto);
|
|
517
|
+
|
|
518
|
+
if (!hasChanges) {
|
|
519
|
+
this.logger.debug(`Skipping view upsert for ${updateSolidViewDto.name}; no changes detected.`);
|
|
520
|
+
return existingSolidView;
|
|
521
|
+
}
|
|
522
|
+
|
|
445
523
|
const updatedSolidViewDto = { ...existingSolidView, ...updateSolidViewDto };
|
|
446
524
|
return this.repo.save(updatedSolidViewDto);
|
|
447
525
|
}
|
package/src/solid-core.module.ts
CHANGED
|
@@ -20,6 +20,8 @@ import { ModelMetadataController } from "./controllers/model-metadata.controller
|
|
|
20
20
|
import { ModuleMetadataExplorerController } from "./controllers/module-metadata-explorer.controller";
|
|
21
21
|
import { ModuleMetadataController } from "./controllers/module-metadata.controller";
|
|
22
22
|
import { ModulePackageController } from "./controllers/module-package.controller";
|
|
23
|
+
import { DatasourceManagementController } from "./controllers/datasource-management.controller";
|
|
24
|
+
import { DatasourceIntrospectionController } from "./controllers/datasource-introspection.controller";
|
|
23
25
|
import { TestController } from "./controllers/test.controller";
|
|
24
26
|
import { FieldMetadata } from "./entities/field-metadata.entity";
|
|
25
27
|
import { ListOfValues } from "./entities/list-of-values.entity";
|
|
@@ -36,6 +38,8 @@ import { PseudoForeignKeySelectionProvider } from "./services/selection-provider
|
|
|
36
38
|
import { ModuleMetadataSeederService } from "./seeders/module-metadata-seeder.service";
|
|
37
39
|
import { ModuleTestDataService } from "./seeders/module-test-data.service";
|
|
38
40
|
import { CrudHelperService } from "./services/crud-helper.service";
|
|
41
|
+
import { DatasourceManagementService } from "./services/datasource-management.service";
|
|
42
|
+
import { DatasourceIntrospectionService } from "./services/datasource-introspection.service";
|
|
39
43
|
import { FieldMetadataService } from "./services/field-metadata.service";
|
|
40
44
|
import { DashboardRuntimeService } from "./services/dashboard-runtime.service";
|
|
41
45
|
import { ListOfValuesService } from "./services/list-of-values.service";
|
|
@@ -379,6 +383,9 @@ import { DashboardUserLayout } from './entities/dashboard-user-layout.entity';
|
|
|
379
383
|
import { DashboardUserLayoutService } from './services/dashboard-user-layout.service';
|
|
380
384
|
import { DashboardUserLayoutController } from './controllers/dashboard-user-layout.controller';
|
|
381
385
|
import { DashboardUserLayoutRepository } from './repositories/dashboard-user-layout.repository';
|
|
386
|
+
import { MssqlDatasourceIntrospectionProviderService } from "./services/datasource-introspection/mssql-datasource-introspection-provider.service";
|
|
387
|
+
import { MysqlDatasourceIntrospectionProviderService } from "./services/datasource-introspection/mysql-datasource-introspection-provider.service";
|
|
388
|
+
import { PostgresDatasourceIntrospectionProviderService } from "./services/datasource-introspection/postgres-datasource-introspection-provider.service";
|
|
382
389
|
|
|
383
390
|
@Global()
|
|
384
391
|
@Module({
|
|
@@ -463,6 +470,8 @@ import { DashboardUserLayoutRepository } from './repositories/dashboard-user-lay
|
|
|
463
470
|
ExportTransactionController,
|
|
464
471
|
FieldMetadataController,
|
|
465
472
|
DashboardController,
|
|
473
|
+
DatasourceManagementController,
|
|
474
|
+
DatasourceIntrospectionController,
|
|
466
475
|
GoogleAuthenticationController,
|
|
467
476
|
FacebookAuthenticationController,
|
|
468
477
|
MicrosoftAuthenticationController,
|
|
@@ -526,6 +535,8 @@ import { DashboardUserLayoutRepository } from './repositories/dashboard-user-lay
|
|
|
526
535
|
useClass: HttpExceptionFilter,
|
|
527
536
|
},
|
|
528
537
|
ModuleMetadataService,
|
|
538
|
+
DatasourceManagementService,
|
|
539
|
+
DatasourceIntrospectionService,
|
|
529
540
|
ModuleMetadataExplorerService,
|
|
530
541
|
ModuleMetadataHelperService,
|
|
531
542
|
ModulePackageService,
|
|
@@ -723,7 +734,11 @@ import { DashboardUserLayoutRepository } from './repositories/dashboard-user-lay
|
|
|
723
734
|
ExportTransactionService,
|
|
724
735
|
ExcelService,
|
|
725
736
|
CsvService,
|
|
737
|
+
DatasourceManagementService,
|
|
726
738
|
DashboardRuntimeService,
|
|
739
|
+
MssqlDatasourceIntrospectionProviderService,
|
|
740
|
+
MysqlDatasourceIntrospectionProviderService,
|
|
741
|
+
PostgresDatasourceIntrospectionProviderService,
|
|
727
742
|
ImportTransactionService,
|
|
728
743
|
ImportTransactionErrorLogService,
|
|
729
744
|
CreatedByUpdatedBySubscriber,
|
|
@@ -823,6 +838,7 @@ import { DashboardUserLayoutRepository } from './repositories/dashboard-user-lay
|
|
|
823
838
|
ModelMetadataHelperService,
|
|
824
839
|
ModelMetadataService,
|
|
825
840
|
ModuleMetadataService,
|
|
841
|
+
DatasourceIntrospectionService,
|
|
826
842
|
ModuleMetadataExplorerService,
|
|
827
843
|
ModulePackageService,
|
|
828
844
|
MqMessageQueueService,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"permissions": {
|
|
3
|
-
"allow": [
|
|
4
|
-
"Bash(node -e:*)",
|
|
5
|
-
"WebFetch(domain:docs.solidxai.com)",
|
|
6
|
-
"WebFetch(domain:github.com)",
|
|
7
|
-
"Read(//Users/oswald/projects/Solid_Starters/solidctl/**)",
|
|
8
|
-
"Read(//Users/oswald/projects/Solid_Starters/**)",
|
|
9
|
-
"Bash(find /Users/oswald/projects/Solid_Starters/solid-core-module -type d -name migration* -o -name *database*)"
|
|
10
|
-
],
|
|
11
|
-
"additionalDirectories": [
|
|
12
|
-
"/Users/oswald/projects/Solid_Starters/solidctl"
|
|
13
|
-
]
|
|
14
|
-
}
|
|
15
|
-
}
|