@solidxai/core 0.1.10-beta.25 → 0.1.10-beta.26
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/action-metadata.controller.d.ts +1 -20
- package/dist/controllers/action-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/agent-event.controller.d.ts +1 -20
- package/dist/controllers/agent-event.controller.d.ts.map +1 -1
- package/dist/controllers/agent-session.controller.d.ts +1 -20
- package/dist/controllers/agent-session.controller.d.ts.map +1 -1
- package/dist/controllers/ai-interaction.controller.d.ts +1 -20
- package/dist/controllers/ai-interaction.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message-details.controller.d.ts +1 -20
- package/dist/controllers/chatter-message-details.controller.d.ts.map +1 -1
- package/dist/controllers/chatter-message.controller.d.ts +1 -20
- package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
- package/dist/controllers/dashboard-user-layout.controller.d.ts +1 -20
- package/dist/controllers/dashboard-user-layout.controller.d.ts.map +1 -1
- package/dist/controllers/email-template.controller.d.ts +1 -20
- package/dist/controllers/email-template.controller.d.ts.map +1 -1
- package/dist/controllers/export-template.controller.d.ts +1 -20
- package/dist/controllers/export-template.controller.d.ts.map +1 -1
- package/dist/controllers/export-transaction.controller.d.ts +1 -20
- package/dist/controllers/export-transaction.controller.d.ts.map +1 -1
- package/dist/controllers/import-transaction-error-log.controller.d.ts +1 -20
- package/dist/controllers/import-transaction-error-log.controller.d.ts.map +1 -1
- package/dist/controllers/import-transaction.controller.d.ts +1 -20
- package/dist/controllers/import-transaction.controller.d.ts.map +1 -1
- package/dist/controllers/list-of-values.controller.d.ts +1 -20
- package/dist/controllers/list-of-values.controller.d.ts.map +1 -1
- package/dist/controllers/locale.controller.d.ts +1 -20
- package/dist/controllers/locale.controller.d.ts.map +1 -1
- package/dist/controllers/mcp-audit-log.controller.d.ts +1 -20
- package/dist/controllers/mcp-audit-log.controller.d.ts.map +1 -1
- package/dist/controllers/media.controller.d.ts +1 -20
- package/dist/controllers/media.controller.d.ts.map +1 -1
- package/dist/controllers/menu-item-metadata.controller.d.ts +1 -20
- package/dist/controllers/menu-item-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/model-metadata.controller.d.ts +10 -30
- package/dist/controllers/model-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/model-metadata.controller.js +2 -2
- package/dist/controllers/model-sequence.controller.d.ts +1 -20
- package/dist/controllers/model-sequence.controller.d.ts.map +1 -1
- package/dist/controllers/module-metadata-explorer.controller.d.ts +171 -0
- package/dist/controllers/module-metadata-explorer.controller.d.ts.map +1 -0
- package/dist/controllers/module-metadata-explorer.controller.js +143 -0
- package/dist/controllers/module-metadata-explorer.controller.js.map +1 -0
- package/dist/controllers/module-metadata.controller.d.ts +5 -0
- package/dist/controllers/module-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/module-metadata.controller.js +12 -0
- package/dist/controllers/module-metadata.controller.js.map +1 -1
- package/dist/controllers/module-package.controller.d.ts +622 -0
- package/dist/controllers/module-package.controller.d.ts.map +1 -0
- package/dist/controllers/module-package.controller.js +150 -0
- package/dist/controllers/module-package.controller.js.map +1 -0
- package/dist/controllers/mq-message-queue.controller.d.ts +1 -20
- package/dist/controllers/mq-message-queue.controller.d.ts.map +1 -1
- package/dist/controllers/mq-message.controller.d.ts +1 -20
- package/dist/controllers/mq-message.controller.d.ts.map +1 -1
- package/dist/controllers/permission-metadata.controller.d.ts +1 -20
- package/dist/controllers/permission-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/role-metadata.controller.d.ts +1 -20
- package/dist/controllers/role-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/saved-filters.controller.d.ts +1 -20
- package/dist/controllers/saved-filters.controller.d.ts.map +1 -1
- package/dist/controllers/scheduled-job.controller.d.ts +1 -20
- package/dist/controllers/scheduled-job.controller.d.ts.map +1 -1
- package/dist/controllers/security-rule.controller.d.ts +1 -20
- package/dist/controllers/security-rule.controller.d.ts.map +1 -1
- package/dist/controllers/sms-template.controller.d.ts +1 -20
- package/dist/controllers/sms-template.controller.d.ts.map +1 -1
- package/dist/controllers/user-activity-history.controller.d.ts +1 -20
- package/dist/controllers/user-activity-history.controller.d.ts.map +1 -1
- package/dist/controllers/user-view-metadata.controller.d.ts +1 -20
- package/dist/controllers/user-view-metadata.controller.d.ts.map +1 -1
- package/dist/controllers/user.controller.d.ts +1 -20
- package/dist/controllers/user.controller.d.ts.map +1 -1
- package/dist/controllers/view-metadata.controller.d.ts +1 -20
- package/dist/controllers/view-metadata.controller.d.ts.map +1 -1
- package/dist/dtos/confirm-module-package-import.dto.d.ts +4 -0
- package/dist/dtos/confirm-module-package-import.dto.d.ts.map +1 -0
- package/dist/dtos/confirm-module-package-import.dto.js +34 -0
- package/dist/dtos/confirm-module-package-import.dto.js.map +1 -0
- package/dist/dtos/metadata-explorer-references-query.dto.d.ts +10 -0
- package/dist/dtos/metadata-explorer-references-query.dto.d.ts.map +1 -0
- package/dist/dtos/metadata-explorer-references-query.dto.js +69 -0
- package/dist/dtos/metadata-explorer-references-query.dto.js.map +1 -0
- package/dist/dtos/metadata-explorer-search-query.dto.d.ts +8 -0
- package/dist/dtos/metadata-explorer-search-query.dto.d.ts.map +1 -0
- package/dist/dtos/metadata-explorer-search-query.dto.js +55 -0
- package/dist/dtos/metadata-explorer-search-query.dto.js.map +1 -0
- package/dist/dtos/metadata-explorer-write.dto.d.ts +4 -0
- package/dist/dtos/metadata-explorer-write.dto.d.ts.map +1 -0
- package/dist/dtos/metadata-explorer-write.dto.js +30 -0
- package/dist/dtos/metadata-explorer-write.dto.js.map +1 -0
- package/dist/dtos/run-module-package-build.dto.d.ts +5 -0
- package/dist/dtos/run-module-package-build.dto.d.ts.map +1 -0
- package/dist/dtos/run-module-package-build.dto.js +38 -0
- package/dist/dtos/run-module-package-build.dto.js.map +1 -0
- package/dist/dtos/run-module-package-seed.dto.d.ts +4 -0
- package/dist/dtos/run-module-package-seed.dto.d.ts.map +1 -0
- package/dist/dtos/run-module-package-seed.dto.js +34 -0
- package/dist/dtos/run-module-package-seed.dto.js.map +1 -0
- package/dist/helpers/command.service.js +1 -1
- package/dist/helpers/command.service.js.map +1 -1
- package/dist/helpers/module-metadata-helper.service.d.ts +2 -0
- package/dist/helpers/module-metadata-helper.service.d.ts.map +1 -1
- package/dist/helpers/module-metadata-helper.service.js +14 -12
- package/dist/helpers/module-metadata-helper.service.js.map +1 -1
- package/dist/helpers/module.helper.d.ts.map +1 -1
- package/dist/helpers/module.helper.js +11 -6
- package/dist/helpers/module.helper.js.map +1 -1
- package/dist/helpers/typeorm-migration-helpers.d.ts +12 -0
- package/dist/helpers/typeorm-migration-helpers.d.ts.map +1 -0
- package/dist/helpers/typeorm-migration-helpers.js +119 -0
- package/dist/helpers/typeorm-migration-helpers.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts +1 -0
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +57 -38
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/module-test-data.service.js +1 -1
- package/dist/seeders/module-test-data.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +2364 -1106
- package/dist/services/crud-helper.service.d.ts +18 -0
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +59 -0
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts +1 -21
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +9 -75
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/genai/ingest-metadata.service.js +2 -2
- package/dist/services/genai/ingest-metadata.service.js.map +1 -1
- package/dist/services/media.service.d.ts +1 -20
- package/dist/services/media.service.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +31 -2
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.d.ts.map +1 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.js +5 -1
- package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts +15 -30
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +249 -29
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/module-metadata-explorer.service.d.ts +161 -0
- package/dist/services/module-metadata-explorer.service.d.ts.map +1 -0
- package/dist/services/module-metadata-explorer.service.js +485 -0
- package/dist/services/module-metadata-explorer.service.js.map +1 -0
- package/dist/services/module-metadata.service.d.ts +7 -0
- package/dist/services/module-metadata.service.d.ts.map +1 -1
- package/dist/services/module-metadata.service.js +121 -2
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/module-package.service.d.ts +266 -0
- package/dist/services/module-package.service.d.ts.map +1 -0
- package/dist/services/module-package.service.js +980 -0
- package/dist/services/module-package.service.js.map +1 -0
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +10 -2
- 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/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/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 +2 -1
- package/src/controllers/module-metadata-explorer.controller.ts +83 -0
- package/src/controllers/module-metadata.controller.ts +6 -0
- package/src/controllers/module-package.controller.ts +102 -0
- package/src/dtos/confirm-module-package-import.dto.ts +12 -0
- package/src/dtos/metadata-explorer-references-query.dto.ts +39 -0
- package/src/dtos/metadata-explorer-search-query.dto.ts +28 -0
- package/src/dtos/metadata-explorer-write.dto.ts +11 -0
- package/src/dtos/run-module-package-build.dto.ts +14 -0
- package/src/dtos/run-module-package-seed.dto.ts +12 -0
- package/src/helpers/command.service.ts +1 -1
- package/src/helpers/module-metadata-helper.service.ts +19 -21
- package/src/helpers/module.helper.ts +12 -9
- package/src/helpers/typeorm-migration-helpers.ts +163 -0
- package/src/index.ts +8 -0
- package/src/seeders/module-metadata-seeder.service.ts +63 -38
- package/src/seeders/module-test-data.service.ts +1 -1
- package/src/seeders/seed-data/solid-core-metadata.json +2365 -1107
- package/src/services/crud-helper.service.ts +72 -0
- package/src/services/crud.service.ts +11 -104
- package/src/services/dashboard-providers/README.md +1 -1
- package/src/services/genai/ingest-metadata.service.ts +3 -3
- package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +37 -2
- package/src/services/mediaStorageProviders/file-storage-provider.ts +5 -1
- package/src/services/model-metadata.service.ts +302 -98
- package/src/services/module-metadata-explorer.service.ts +670 -0
- package/src/services/module-metadata.service.ts +136 -10
- package/src/services/module-package.service.ts +1171 -0
- package/src/solid-core.module.ts +10 -2
- package/.claude/settings.local.json +0 -15
- package/CLAUDE.md +0 -26
- package/dist/services/database/database-bootstrap.service.d.ts +0 -12
- package/dist/services/database/database-bootstrap.service.d.ts.map +0 -1
- package/dist/services/database/database-bootstrap.service.js +0 -115
- package/dist/services/database/database-bootstrap.service.js.map +0 -1
- package/sql/default/mariadb/proc_CleanupModelMetadata.sql +0 -153
- package/sql/default/mariadb/proc_CleanupModuleMetadata.sql +0 -56
- package/sql/default/mssql/proc_CleanupModuleMetadata.sql +0 -78
- package/sql/default/mysql/proc_CleanupModelMetadata.sql +0 -153
- package/sql/default/mysql/proc_CleanupModuleMetadata.sql +0 -56
- package/sql/default/postgres/proc_CleanupModelMetadata.sql +0 -148
- package/sql/default/postgres/proc_CleanupModuleMetadata.sql +0 -50
- package/sql/default/postgres/scratchpad.sql.txt +0 -12
- package/src/services/1.js +0 -6
- package/src/services/database/database-bootstrap.service.ts +0 -91
|
@@ -2,7 +2,7 @@ import { BadRequestException, forwardRef, Inject, Injectable, Logger, NotFoundEx
|
|
|
2
2
|
import { InjectDataSource } from '@nestjs/typeorm';
|
|
3
3
|
import * as fs from 'fs/promises'; // Use the Promise-based version of fs for async/await
|
|
4
4
|
import * as path from 'path';
|
|
5
|
-
import { DataSource, EntityManager, Repository, SelectQueryBuilder } from 'typeorm';
|
|
5
|
+
import { DataSource, EntityManager, In, Repository, SelectQueryBuilder } from 'typeorm';
|
|
6
6
|
import { CreateModelMetadataDto } from '../dtos/create-model-metadata.dto';
|
|
7
7
|
import { ModelMetadata } from '../entities/model-metadata.entity';
|
|
8
8
|
import { ModuleMetadata } from '../entities/module-metadata.entity';
|
|
@@ -19,7 +19,11 @@ import { BasicFilterDto } from '../dtos/basic-filters.dto';
|
|
|
19
19
|
import { UpdateModelMetaDataDto } from '../dtos/update-model-metadata.dto';
|
|
20
20
|
import { ActionMetadata } from '../entities/action-metadata.entity';
|
|
21
21
|
import { FieldMetadata } from '../entities/field-metadata.entity';
|
|
22
|
+
import { ImportTransactionErrorLog } from '../entities/import-transaction-error-log.entity';
|
|
23
|
+
import { ImportTransaction } from '../entities/import-transaction.entity';
|
|
22
24
|
import { MenuItemMetadata } from '../entities/menu-item-metadata.entity';
|
|
25
|
+
import { UserViewMetadata } from '../entities/user-view-metadata.entity';
|
|
26
|
+
import { PermissionMetadata } from '../entities/permission-metadata.entity';
|
|
23
27
|
import { ViewMetadata } from '../entities/view-metadata.entity';
|
|
24
28
|
import { CommandService } from '../helpers/command.service';
|
|
25
29
|
import {
|
|
@@ -29,7 +33,7 @@ import {
|
|
|
29
33
|
} from '../helpers/schematic.service';
|
|
30
34
|
import { classify } from '../helpers/string.helper';
|
|
31
35
|
import { CodeGenerationOptions } from '../interfaces';
|
|
32
|
-
import { CrudHelperService } from './crud-helper.service';
|
|
36
|
+
import { CrudHelperService, FilterCombinator } from './crud-helper.service';
|
|
33
37
|
import { CRUDService } from './crud.service';
|
|
34
38
|
import { FieldMetadataService } from './field-metadata.service';
|
|
35
39
|
import { MediaStorageProviderMetadataService } from './media-storage-provider-metadata.service';
|
|
@@ -68,36 +72,26 @@ export class ModelMetadataService {
|
|
|
68
72
|
return this.findMany(basicFilterDto);
|
|
69
73
|
}
|
|
70
74
|
|
|
71
|
-
async findMany(basicFilterDto: BasicFilterDto) {
|
|
75
|
+
async findMany(basicFilterDto: BasicFilterDto): Promise<any> {
|
|
72
76
|
const alias = 'modelMetadata';
|
|
73
|
-
|
|
74
|
-
let { limit, offset } = basicFilterDto;
|
|
77
|
+
const { limit, offset } = basicFilterDto;
|
|
75
78
|
|
|
76
|
-
|
|
77
|
-
var qb: SelectQueryBuilder<ModelMetadata> = await this.modelMetadataRepo.createSecurityRuleAwareQueryBuilder(alias)
|
|
78
|
-
qb = await this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias);
|
|
79
|
+
const qb: SelectQueryBuilder<ModelMetadata> = await this.modelMetadataRepo.createSecurityRuleAwareQueryBuilder(alias);
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
81
|
+
if (basicFilterDto.groupBy?.length) {
|
|
82
|
+
const groupFilterQb = this.crudHelperService.buildFilterQuery(
|
|
83
|
+
qb, basicFilterDto, alias, undefined, undefined, undefined,
|
|
84
|
+
FilterCombinator.AND, false, false
|
|
85
|
+
);
|
|
86
|
+
return this.crudHelperService.executeGroupPipeline(
|
|
87
|
+
groupFilterQb, basicFilterDto, alias,
|
|
88
|
+
() => this.modelMetadataRepo.createSecurityRuleAwareQueryBuilder(alias)
|
|
89
|
+
);
|
|
90
|
+
}
|
|
88
91
|
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
currentPage: currentPage,
|
|
93
|
-
nextPage: nextPage,
|
|
94
|
-
prevPage: prevPage,
|
|
95
|
-
totalPages: totalPages,
|
|
96
|
-
perPage: +limit,
|
|
97
|
-
},
|
|
98
|
-
records: entities
|
|
99
|
-
};
|
|
100
|
-
return r
|
|
92
|
+
const filteredQb = this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias);
|
|
93
|
+
const [entities, count] = await filteredQb.getManyAndCount();
|
|
94
|
+
return this.crudHelperService.pagedResponse(offset, limit, count, entities);
|
|
101
95
|
}
|
|
102
96
|
|
|
103
97
|
async findOne(id: any, query?: any) {
|
|
@@ -566,7 +560,7 @@ export class ModelMetadataService {
|
|
|
566
560
|
// @ts-ignore
|
|
567
561
|
id: modelEntityId,
|
|
568
562
|
},
|
|
569
|
-
relations: ['module']
|
|
563
|
+
relations: ['module', 'fields']
|
|
570
564
|
});
|
|
571
565
|
|
|
572
566
|
if (!modelEntity) {
|
|
@@ -622,72 +616,29 @@ export class ModelMetadataService {
|
|
|
622
616
|
await fs.unlink(fileToDelete);
|
|
623
617
|
this.logger.log(`Deleted file: ${fileToDelete}`);
|
|
624
618
|
} catch (error: any) {
|
|
619
|
+
if (error?.code === 'ENOENT') {
|
|
620
|
+
this.logger.warn(`File already absent, skipping delete: ${fileToDelete}`);
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
625
623
|
this.logger.error(`Error deleting file: ${fileToDelete}`, error);
|
|
626
624
|
}
|
|
627
625
|
}
|
|
628
626
|
}
|
|
629
627
|
|
|
630
|
-
await this.
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
);
|
|
634
|
-
|
|
635
|
-
// Delete the permissions, menu, actions & views related to this model.
|
|
636
|
-
// const controllerName = `${classify(modelEntity.singularName)}Controller`;
|
|
637
|
-
// const permissionNames = [
|
|
638
|
-
// `${controllerName}.delete`,
|
|
639
|
-
// `${controllerName}.deleteMany`,
|
|
640
|
-
// `${controllerName}.findOne`,
|
|
641
|
-
// `${controllerName}.findMany`,
|
|
642
|
-
// `${controllerName}.recover`,
|
|
643
|
-
// `${controllerName}.recoverMany`,
|
|
644
|
-
// `${controllerName}.partialUpdate`,
|
|
645
|
-
// `${controllerName}.update`,
|
|
646
|
-
// `${controllerName}.insertMany`,
|
|
647
|
-
// `${controllerName}.create`,
|
|
648
|
-
// ];
|
|
649
|
-
// const permissionsRepo = this.dataSource.getRepository(PermissionMetadata);
|
|
650
|
-
// const permissionsToDelete = await permissionsRepo.find({
|
|
651
|
-
// where: { name: In(permissionNames) },
|
|
652
|
-
// relations: ['roles'],
|
|
653
|
-
// });
|
|
654
|
-
|
|
655
|
-
// Remove role associations first
|
|
656
|
-
// for (const permission of permissionsToDelete) {
|
|
657
|
-
// if (permission.roles?.length) {
|
|
658
|
-
// await this.dataSource
|
|
659
|
-
// .createQueryBuilder()
|
|
660
|
-
// .relation(PermissionMetadata, 'roles')
|
|
661
|
-
// .of(permission) // permission instance or its ID
|
|
662
|
-
// .remove(permission.roles); // remove all linked roles
|
|
663
|
-
// }
|
|
664
|
-
// }
|
|
665
|
-
|
|
666
|
-
// await permissionsRepo.remove(permissionsToDelete);
|
|
667
|
-
|
|
668
|
-
// Delete actions
|
|
669
|
-
// const actionRepo = this.dataSource.getRepository(ActionMetadata);
|
|
670
|
-
// const action = await actionRepo.findOne({ where: { model: { id: modelEntity.id } } });
|
|
671
|
-
// await actionRepo.delete({ model: { id: modelEntity.id } });
|
|
672
|
-
|
|
673
|
-
// // Delete menu items
|
|
674
|
-
// const menuItemRepo = this.dataSource.getRepository(MenuItemMetadata);
|
|
675
|
-
// if (action) {
|
|
676
|
-
// const menuItems = await menuItemRepo.find({ where: { action: { id: action.id } } });
|
|
677
|
-
// for (let i = 0; i < menuItems.length; i++) {
|
|
678
|
-
// const menuItem = menuItems[i];
|
|
679
|
-
// await menuItemRepo.remove(menuItem);
|
|
680
|
-
// }
|
|
681
|
-
// }
|
|
682
|
-
|
|
683
|
-
// Delete view
|
|
684
|
-
// const viewRepo = this.dataSource.getRepository(ViewMetadata);
|
|
685
|
-
// await viewRepo.delete({ model: { id: modelEntity.id } })
|
|
628
|
+
const { removedActionNames, removedMenuNames, removedViewNames } = await this.cleanupAssociatedViewsActionsAndMenus(modelEntity.id);
|
|
629
|
+
await this.cleanupAssociatedImports(modelEntity.id);
|
|
630
|
+
await this.cleanupAssociatedPermissions(modelEntity.singularName);
|
|
631
|
+
await this.clearModelReferencesBeforeDelete(modelEntity);
|
|
686
632
|
|
|
687
633
|
// <moduleName>-metadata.json | Remove references to this model in the model metadata, menu, action & view sections. | Automatic
|
|
688
634
|
const filePath = await this.moduleMetadataHelperService.getModuleMetadataFilePath(modelEntity.module?.name);
|
|
689
635
|
const metaData = await this.moduleMetadataHelperService.getModuleMetadataConfiguration(filePath);
|
|
690
636
|
if (metaData) {
|
|
637
|
+
const moduleMetadata = metaData?.moduleMetadata ?? metaData;
|
|
638
|
+
const removedActionNameSet = new Set(removedActionNames);
|
|
639
|
+
const removedMenuNameSet = new Set(removedMenuNames);
|
|
640
|
+
const removedViewNameSet = new Set(removedViewNames);
|
|
641
|
+
|
|
691
642
|
const existingModelIndex = metaData.moduleMetadata.models.findIndex(
|
|
692
643
|
(existingModel: any) => existingModel.singularName === modelEntity.singularName
|
|
693
644
|
);
|
|
@@ -698,15 +649,51 @@ export class ModelMetadataService {
|
|
|
698
649
|
}
|
|
699
650
|
|
|
700
651
|
// Remove references to this model in the menu, action & view sections.
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
652
|
+
const existingViews = Array.isArray(moduleMetadata?.views) ? moduleMetadata.views : [];
|
|
653
|
+
moduleMetadata.views = existingViews.filter((view: any) => {
|
|
654
|
+
const shouldRemove = view?.modelUserKey === modelEntity.singularName || removedViewNameSet.has(view?.name);
|
|
655
|
+
if (shouldRemove && view?.name) {
|
|
656
|
+
removedViewNameSet.add(view.name);
|
|
657
|
+
}
|
|
658
|
+
return !shouldRemove;
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
const existingActions = Array.isArray(moduleMetadata?.actions) ? moduleMetadata.actions : [];
|
|
662
|
+
moduleMetadata.actions = existingActions.filter((action: any) => {
|
|
663
|
+
const shouldRemove =
|
|
664
|
+
action?.modelUserKey === modelEntity.singularName ||
|
|
665
|
+
removedActionNameSet.has(action?.name) ||
|
|
666
|
+
removedViewNameSet.has(action?.viewUserKey);
|
|
667
|
+
|
|
668
|
+
if (shouldRemove && action?.name) {
|
|
669
|
+
removedActionNameSet.add(action.name);
|
|
670
|
+
}
|
|
671
|
+
return !shouldRemove;
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
let pendingMenus = Array.isArray(moduleMetadata?.menus) ? [...moduleMetadata.menus] : [];
|
|
675
|
+
let menuRemovedOnPass = true;
|
|
676
|
+
while (menuRemovedOnPass) {
|
|
677
|
+
menuRemovedOnPass = false;
|
|
678
|
+
pendingMenus = pendingMenus.filter((menu: any) => {
|
|
679
|
+
const shouldRemove =
|
|
680
|
+
menu?.modelUserKey === modelEntity.singularName ||
|
|
681
|
+
removedMenuNameSet.has(menu?.name) ||
|
|
682
|
+
removedActionNameSet.has(menu?.actionUserKey) ||
|
|
683
|
+
removedMenuNameSet.has(menu?.parentMenuItemUserKey);
|
|
684
|
+
|
|
685
|
+
if (shouldRemove) {
|
|
686
|
+
if (menu?.name) {
|
|
687
|
+
removedMenuNameSet.add(menu.name);
|
|
688
|
+
}
|
|
689
|
+
menuRemovedOnPass = true;
|
|
690
|
+
return false;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
return true;
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
moduleMetadata.menus = pendingMenus;
|
|
710
697
|
|
|
711
698
|
const updatedContent = JSON.stringify(metaData, null, 2);
|
|
712
699
|
await fs.writeFile(filePath, updatedContent);
|
|
@@ -735,12 +722,229 @@ export class ModelMetadataService {
|
|
|
735
722
|
|
|
736
723
|
}
|
|
737
724
|
|
|
725
|
+
private async cleanupAssociatedViewsActionsAndMenus(modelId: number) {
|
|
726
|
+
const viewRepo = this.dataSource.getRepository(ViewMetadata);
|
|
727
|
+
const actionRepo = this.dataSource.getRepository(ActionMetadata);
|
|
728
|
+
const menuRepo = this.dataSource.getRepository(MenuItemMetadata);
|
|
729
|
+
const userViewRepo = this.dataSource.getRepository(UserViewMetadata);
|
|
730
|
+
|
|
731
|
+
const views = await viewRepo.find({
|
|
732
|
+
where: {
|
|
733
|
+
model: { id: modelId },
|
|
734
|
+
},
|
|
735
|
+
});
|
|
736
|
+
const viewIds = views.map((view) => view.id);
|
|
737
|
+
const removedViewNames = views.map((view) => view.name).filter(Boolean);
|
|
738
|
+
|
|
739
|
+
const actions = await actionRepo.find({
|
|
740
|
+
where: [
|
|
741
|
+
{
|
|
742
|
+
model: { id: modelId },
|
|
743
|
+
},
|
|
744
|
+
...(viewIds.length > 0
|
|
745
|
+
? [
|
|
746
|
+
{
|
|
747
|
+
view: { id: In(viewIds) },
|
|
748
|
+
},
|
|
749
|
+
]
|
|
750
|
+
: []),
|
|
751
|
+
],
|
|
752
|
+
relations: ['view'],
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
const uniqueActions = Array.from(
|
|
756
|
+
new Map(actions.map((action) => [action.id, action])).values(),
|
|
757
|
+
);
|
|
758
|
+
const actionIds = uniqueActions.map((action) => action.id);
|
|
759
|
+
const removedActionNames = uniqueActions.map((action) => action.name).filter(Boolean);
|
|
760
|
+
|
|
761
|
+
const menus = await this.findMenusForActionIds(actionIds);
|
|
762
|
+
const removedMenuNames = menus.map((menu) => menu.name).filter(Boolean);
|
|
763
|
+
|
|
764
|
+
if (menus.length > 0) {
|
|
765
|
+
const menuIds = menus.map((menu) => menu.id).filter(Boolean);
|
|
766
|
+
for (const menu of menus) {
|
|
767
|
+
if (menu.roles?.length) {
|
|
768
|
+
await this.dataSource
|
|
769
|
+
.createQueryBuilder()
|
|
770
|
+
.relation(MenuItemMetadata, 'roles')
|
|
771
|
+
.of(menu.id)
|
|
772
|
+
.remove(menu.roles.map((role) => role.id));
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
if (menuIds.length > 0) {
|
|
777
|
+
await menuRepo
|
|
778
|
+
.createQueryBuilder()
|
|
779
|
+
.update(MenuItemMetadata)
|
|
780
|
+
.set({ parentMenuItem: null as any })
|
|
781
|
+
.where('id IN (:...menuIds)', { menuIds })
|
|
782
|
+
.execute();
|
|
783
|
+
|
|
784
|
+
await menuRepo
|
|
785
|
+
.createQueryBuilder()
|
|
786
|
+
.delete()
|
|
787
|
+
.from(MenuItemMetadata)
|
|
788
|
+
.where('id IN (:...menuIds)', { menuIds })
|
|
789
|
+
.execute();
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
this.logger.log(`Deleted ${menus.length} menu metadata record(s) for model id ${modelId}`);
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
if (uniqueActions.length > 0) {
|
|
796
|
+
await actionRepo.remove(uniqueActions);
|
|
797
|
+
this.logger.log(`Deleted ${uniqueActions.length} action metadata record(s) for model id ${modelId}`);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
if (viewIds.length > 0) {
|
|
801
|
+
const userViews = await userViewRepo.find({
|
|
802
|
+
where: {
|
|
803
|
+
viewMetadata: { id: In(viewIds) },
|
|
804
|
+
},
|
|
805
|
+
relations: ['viewMetadata'],
|
|
806
|
+
});
|
|
807
|
+
if (userViews.length > 0) {
|
|
808
|
+
await userViewRepo.remove(userViews);
|
|
809
|
+
this.logger.log(`Deleted ${userViews.length} user view metadata record(s) for model id ${modelId}`);
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
await viewRepo.remove(views);
|
|
813
|
+
this.logger.log(`Deleted ${views.length} view metadata record(s) for model id ${modelId}`);
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
return {
|
|
817
|
+
removedActionNames,
|
|
818
|
+
removedMenuNames,
|
|
819
|
+
removedViewNames,
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
private async cleanupAssociatedImports(modelId: number) {
|
|
824
|
+
const importTransactionRepo = this.dataSource.getRepository(ImportTransaction);
|
|
825
|
+
const importTransactionErrorLogRepo = this.dataSource.getRepository(ImportTransactionErrorLog);
|
|
826
|
+
|
|
827
|
+
const importTransactions = await importTransactionRepo.find({
|
|
828
|
+
where: {
|
|
829
|
+
modelMetadata: { id: modelId },
|
|
830
|
+
},
|
|
831
|
+
});
|
|
832
|
+
|
|
833
|
+
if (importTransactions.length === 0) {
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
const importTransactionIds = importTransactions.map((transaction) => transaction.id);
|
|
838
|
+
const importTransactionErrorLogs = await importTransactionErrorLogRepo.find({
|
|
839
|
+
where: {
|
|
840
|
+
importTransaction: { id: In(importTransactionIds) },
|
|
841
|
+
},
|
|
842
|
+
relations: ['importTransaction'],
|
|
843
|
+
});
|
|
844
|
+
|
|
845
|
+
if (importTransactionErrorLogs.length > 0) {
|
|
846
|
+
await importTransactionErrorLogRepo.remove(importTransactionErrorLogs);
|
|
847
|
+
this.logger.log(`Deleted ${importTransactionErrorLogs.length} import transaction error log record(s) for model id ${modelId}`);
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
await importTransactionRepo.remove(importTransactions);
|
|
851
|
+
this.logger.log(`Deleted ${importTransactions.length} import transaction record(s) for model id ${modelId}`);
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
private async cleanupAssociatedPermissions(modelSingularName: string) {
|
|
855
|
+
const permissionsRepo = this.dataSource.getRepository(PermissionMetadata);
|
|
856
|
+
const controllerName = `${classify(modelSingularName)}Controller`;
|
|
857
|
+
const permissions = await permissionsRepo
|
|
858
|
+
.createQueryBuilder('permission')
|
|
859
|
+
.leftJoinAndSelect('permission.roles', 'role')
|
|
860
|
+
.where('permission.name LIKE :pattern', { pattern: `${controllerName}.%` })
|
|
861
|
+
.getMany();
|
|
862
|
+
|
|
863
|
+
if (permissions.length === 0) {
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
for (const permission of permissions) {
|
|
868
|
+
if (permission.roles?.length) {
|
|
869
|
+
await this.dataSource
|
|
870
|
+
.createQueryBuilder()
|
|
871
|
+
.relation(PermissionMetadata, 'roles')
|
|
872
|
+
.of(permission.id)
|
|
873
|
+
.remove(permission.roles.map((role) => role.id));
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
await permissionsRepo.remove(permissions);
|
|
878
|
+
this.logger.log(`Deleted ${permissions.length} permission metadata record(s) for model '${modelSingularName}'`);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
private async clearModelReferencesBeforeDelete(modelEntity: ModelMetadata) {
|
|
882
|
+
const modelRepo = this.dataSource.getRepository(ModelMetadata);
|
|
883
|
+
const fieldIds = (modelEntity.fields ?? []).map((field) => field.id).filter(Boolean);
|
|
884
|
+
|
|
885
|
+
if (fieldIds.length > 0) {
|
|
886
|
+
await modelRepo
|
|
887
|
+
.createQueryBuilder()
|
|
888
|
+
.update(ModelMetadata)
|
|
889
|
+
.set({ userKeyField: null as any })
|
|
890
|
+
.where('user_key_field_id IN (:...fieldIds)', { fieldIds })
|
|
891
|
+
.execute();
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
await modelRepo
|
|
895
|
+
.createQueryBuilder()
|
|
896
|
+
.update(ModelMetadata)
|
|
897
|
+
.set({ parentModel: null as any })
|
|
898
|
+
.where('parent_model_id = :modelId', { modelId: modelEntity.id })
|
|
899
|
+
.execute();
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
private async findMenusForActionIds(actionIds: number[]) {
|
|
903
|
+
if (!actionIds?.length) {
|
|
904
|
+
return [];
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
const menuRepo = this.dataSource.getRepository(MenuItemMetadata);
|
|
908
|
+
const menusById = new Map<number, MenuItemMetadata>();
|
|
909
|
+
|
|
910
|
+
const rootMenus = await menuRepo.find({
|
|
911
|
+
where: {
|
|
912
|
+
action: { id: In(actionIds) },
|
|
913
|
+
},
|
|
914
|
+
relations: ['roles', 'action', 'parentMenuItem'],
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
rootMenus.forEach((menu) => menusById.set(menu.id, menu));
|
|
918
|
+
|
|
919
|
+
let parentIds = rootMenus.map((menu) => menu.id);
|
|
920
|
+
while (parentIds.length > 0) {
|
|
921
|
+
const childMenus = await menuRepo.find({
|
|
922
|
+
where: {
|
|
923
|
+
parentMenuItem: { id: In(parentIds) },
|
|
924
|
+
},
|
|
925
|
+
relations: ['roles', 'action', 'parentMenuItem'],
|
|
926
|
+
});
|
|
927
|
+
|
|
928
|
+
const nextParentIds: number[] = [];
|
|
929
|
+
for (const childMenu of childMenus) {
|
|
930
|
+
if (!menusById.has(childMenu.id)) {
|
|
931
|
+
menusById.set(childMenu.id, childMenu);
|
|
932
|
+
nextParentIds.push(childMenu.id);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
parentIds = nextParentIds;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
return Array.from(menusById.values());
|
|
940
|
+
}
|
|
941
|
+
|
|
738
942
|
@DisallowInProduction()
|
|
739
943
|
async generateCodeViaCtl(modelId: number): Promise<string> {
|
|
740
944
|
const model = await this.findOne(modelId);
|
|
741
945
|
return this.commandService.executeCommandWithArgs({
|
|
742
946
|
command: 'npx',
|
|
743
|
-
args: ['@
|
|
947
|
+
args: ['@solidxai/solidctl@latest', 'generate', 'model', `--name=${model.singularName}`],
|
|
744
948
|
cwd: path.join(process.cwd(), '..'),
|
|
745
949
|
});
|
|
746
950
|
}
|
|
@@ -1239,11 +1443,11 @@ export class ModelMetadataService {
|
|
|
1239
1443
|
const removeOutput = await this.executeRemoveFieldsCommand(model, fieldsForRemoval, options.dryRun);
|
|
1240
1444
|
|
|
1241
1445
|
// Remove the fields from the database as well. This also checks, if the field is marked for removal
|
|
1242
|
-
|
|
1446
|
+
for (const field of fieldsForRemoval) {
|
|
1243
1447
|
if (field.isMarkedForRemoval) {
|
|
1244
|
-
this.fieldMetadataService.delete(field.id);
|
|
1448
|
+
await this.fieldMetadataService.delete(field.id);
|
|
1245
1449
|
}
|
|
1246
|
-
}
|
|
1450
|
+
}
|
|
1247
1451
|
|
|
1248
1452
|
// Remove the fields from metadata json file
|
|
1249
1453
|
|