@solidxai/core 0.1.11-beta.1 → 0.1.11-beta.12
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/commands/migrate-removed-fields.command.d.ts +19 -0
- package/dist/commands/migrate-removed-fields.command.d.ts.map +1 -0
- package/dist/commands/migrate-removed-fields.command.js +77 -0
- package/dist/commands/migrate-removed-fields.command.js.map +1 -0
- package/dist/controllers/datasource-introspection.controller.d.ts +46 -1
- package/dist/controllers/datasource-introspection.controller.d.ts.map +1 -1
- package/dist/controllers/datasource-introspection.controller.js +38 -0
- package/dist/controllers/datasource-introspection.controller.js.map +1 -1
- package/dist/controllers/service.controller.d.ts +1 -0
- package/dist/controllers/service.controller.d.ts.map +1 -1
- package/dist/controllers/service.controller.js +2 -2
- package/dist/controllers/service.controller.js.map +1 -1
- package/dist/dtos/datasource-introspection-mapping.dto.d.ts +5 -0
- package/dist/dtos/datasource-introspection-mapping.dto.d.ts.map +1 -1
- package/dist/dtos/datasource-introspection-mapping.dto.js +24 -2
- package/dist/dtos/datasource-introspection-mapping.dto.js.map +1 -1
- package/dist/entities/{legacy-common-with-id.entity.d.ts → legacy-common-with-generated-id.entity.d.ts} +2 -2
- package/dist/entities/legacy-common-with-generated-id.entity.d.ts.map +1 -0
- package/dist/entities/{legacy-common-with-id.entity.js → legacy-common-with-generated-id.entity.js} +4 -4
- package/dist/entities/legacy-common-with-generated-id.entity.js.map +1 -0
- package/dist/entities/{legacy-common.entity.d.ts → legacy-common.entity-with-existing-id.entity.d.ts} +1 -1
- package/dist/entities/legacy-common.entity-with-existing-id.entity.d.ts.map +1 -0
- package/dist/entities/{legacy-common.entity.js → legacy-common.entity-with-existing-id.entity.js} +1 -1
- package/dist/entities/legacy-common.entity-with-existing-id.entity.js.map +1 -0
- package/dist/helpers/command.service.d.ts +2 -0
- package/dist/helpers/command.service.d.ts.map +1 -1
- package/dist/helpers/command.service.js +6 -2
- package/dist/helpers/command.service.js.map +1 -1
- package/dist/helpers/environment.helper.d.ts +1 -0
- package/dist/helpers/environment.helper.d.ts.map +1 -1
- package/dist/helpers/environment.helper.js +4 -0
- package/dist/helpers/environment.helper.js.map +1 -1
- package/dist/helpers/field-crud-managers/IntFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/IntFieldCrudManager.js +4 -1
- package/dist/helpers/field-crud-managers/IntFieldCrudManager.js.map +1 -1
- package/dist/helpers/model-metadata-helper.service.d.ts +2 -1
- package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -1
- package/dist/helpers/model-metadata-helper.service.js +9 -5
- package/dist/helpers/model-metadata-helper.service.js.map +1 -1
- package/dist/helpers/module-metadata-helper.service.js +1 -1
- package/dist/helpers/module-metadata-helper.service.js.map +1 -1
- package/dist/helpers/nodemon-heartbeat.d.ts +5 -0
- package/dist/helpers/nodemon-heartbeat.d.ts.map +1 -0
- package/dist/helpers/nodemon-heartbeat.js +67 -0
- package/dist/helpers/nodemon-heartbeat.js.map +1 -0
- package/dist/helpers/solid-registry.d.ts +2 -1
- package/dist/helpers/solid-registry.d.ts.map +1 -1
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/helpers/typeorm-db-helper.d.ts +1 -0
- package/dist/helpers/typeorm-db-helper.d.ts.map +1 -1
- package/dist/helpers/typeorm-db-helper.js +12 -0
- package/dist/helpers/typeorm-db-helper.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces/datasource-introspection-provider.interface.d.ts +1 -0
- package/dist/interfaces/datasource-introspection-provider.interface.d.ts.map +1 -1
- package/dist/interfaces/datasource-introspection-provider.interface.js.map +1 -1
- package/dist/interfaces.d.ts +1 -0
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/repository/scheduled-job.repository.d.ts +2 -2
- package/dist/repository/scheduled-job.repository.d.ts.map +1 -1
- package/dist/repository/scheduled-job.repository.js +6 -3
- package/dist/repository/scheduled-job.repository.js.map +1 -1
- package/dist/repository/security-rule.repository.d.ts +2 -2
- package/dist/repository/security-rule.repository.d.ts.map +1 -1
- package/dist/repository/security-rule.repository.js +6 -3
- package/dist/repository/security-rule.repository.js.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts +11 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +163 -3
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/seed-data/solid-core-metadata.json +128 -34
- package/dist/services/api-key.service.d.ts.map +1 -1
- package/dist/services/api-key.service.js.map +1 -1
- package/dist/services/authentication.service.d.ts +2 -0
- package/dist/services/authentication.service.d.ts.map +1 -1
- package/dist/services/authentication.service.js +32 -11
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.d.ts.map +1 -1
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js +7 -5
- package/dist/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.js.map +1 -1
- package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.d.ts +4 -0
- package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.d.ts.map +1 -1
- package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.js +18 -1
- package/dist/services/computed-fields/entity/concat-entity-computed-field-provider.service.js.map +1 -1
- package/dist/services/crud-helper.service.d.ts.map +1 -1
- package/dist/services/crud-helper.service.js +25 -12
- package/dist/services/crud-helper.service.js.map +1 -1
- package/dist/services/crud.service.d.ts +1 -0
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +27 -0
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts.map +1 -1
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js +12 -0
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js.map +1 -1
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts.map +1 -1
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js +2 -0
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js.map +1 -1
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts.map +1 -1
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js +28 -15
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js.map +1 -1
- package/dist/services/datasource-introspection.service.d.ts +63 -2
- package/dist/services/datasource-introspection.service.d.ts.map +1 -1
- package/dist/services/datasource-introspection.service.js +665 -188
- package/dist/services/datasource-introspection.service.js.map +1 -1
- package/dist/services/import-transaction.service.d.ts.map +1 -1
- package/dist/services/import-transaction.service.js +3 -0
- package/dist/services/import-transaction.service.js.map +1 -1
- package/dist/services/locale.service.d.ts +14 -0
- package/dist/services/locale.service.d.ts.map +1 -1
- package/dist/services/locale.service.js +83 -0
- package/dist/services/locale.service.js.map +1 -1
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js +10 -10
- package/dist/services/mediaStorageProviders/file-s3-storage-provider.js.map +1 -1
- package/dist/services/menu-item-metadata.service.d.ts.map +1 -1
- package/dist/services/menu-item-metadata.service.js +1 -0
- package/dist/services/menu-item-metadata.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts +3 -0
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +78 -0
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/module-metadata.service.d.ts.map +1 -1
- package/dist/services/module-metadata.service.js +28 -0
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/removed-field-migration.service.d.ts +30 -0
- package/dist/services/removed-field-migration.service.d.ts.map +1 -0
- package/dist/services/removed-field-migration.service.js +319 -0
- package/dist/services/removed-field-migration.service.js.map +1 -0
- package/dist/services/role-metadata.service.d.ts +1 -0
- package/dist/services/role-metadata.service.d.ts.map +1 -1
- package/dist/services/role-metadata.service.js +23 -2
- package/dist/services/role-metadata.service.js.map +1 -1
- package/dist/services/settings/default-settings-provider.service.d.ts +244 -0
- package/dist/services/settings/default-settings-provider.service.d.ts.map +1 -1
- package/dist/services/settings/default-settings-provider.service.js +120 -0
- package/dist/services/settings/default-settings-provider.service.js.map +1 -1
- package/dist/services/solid-ts-morph.service.d.ts +6 -0
- package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
- package/dist/services/solid-ts-morph.service.js +43 -0
- package/dist/services/solid-ts-morph.service.js.map +1 -1
- package/dist/services/view-metadata.service.d.ts.map +1 -1
- package/dist/services/view-metadata.service.js +4 -7
- 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/subscribers/audit.subscriber.d.ts +5 -1
- package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
- package/dist/subscribers/audit.subscriber.js +76 -12
- package/dist/subscribers/audit.subscriber.js.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.d.ts +9 -1
- package/dist/subscribers/computed-entity-field.subscriber.d.ts.map +1 -1
- package/dist/subscribers/computed-entity-field.subscriber.js +45 -11
- package/dist/subscribers/computed-entity-field.subscriber.js.map +1 -1
- package/dist/subscribers/created-by-updated-by.subscriber.d.ts.map +1 -1
- package/dist/subscribers/created-by-updated-by.subscriber.js.map +1 -1
- package/dist/subscribers/field-metadata.subscriber.d.ts.map +1 -1
- package/dist/subscribers/field-metadata.subscriber.js.map +1 -1
- package/dist/subscribers/scheduled-job.subscriber.d.ts.map +1 -1
- package/dist/subscribers/scheduled-job.subscriber.js +3 -2
- package/dist/subscribers/scheduled-job.subscriber.js.map +1 -1
- package/dist/subscribers/security-rule.subscriber.d.ts.map +1 -1
- package/dist/subscribers/security-rule.subscriber.js +5 -3
- package/dist/subscribers/security-rule.subscriber.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/migrate-removed-fields.command.ts +81 -0
- package/src/controllers/datasource-introspection.controller.ts +27 -1
- package/src/controllers/service.controller.ts +3 -2
- package/src/dtos/datasource-introspection-mapping.dto.ts +15 -0
- package/src/entities/{legacy-common-with-id.entity.ts → legacy-common-with-generated-id.entity.ts} +1 -1
- package/src/helpers/command.service.ts +10 -2
- package/src/helpers/environment.helper.ts +11 -0
- package/src/helpers/field-crud-managers/IntFieldCrudManager.ts +4 -1
- package/src/helpers/model-metadata-helper.service.ts +8 -3
- package/src/helpers/module-metadata-helper.service.ts +1 -1
- package/src/helpers/nodemon-heartbeat.ts +59 -0
- package/src/helpers/solid-registry.ts +7 -1
- package/src/helpers/typeorm-db-helper.ts +15 -0
- package/src/index.ts +3 -2
- package/src/interfaces/datasource-introspection-provider.interface.ts +1 -0
- package/src/interfaces.ts +1 -0
- package/src/repository/scheduled-job.repository.ts +10 -4
- package/src/repository/security-rule.repository.ts +10 -4
- package/src/seeders/module-metadata-seeder.service.ts +192 -2
- package/src/seeders/seed-data/solid-core-metadata.json +128 -34
- package/src/services/api-key.service.ts +36 -36
- package/src/services/authentication.service.ts +46 -12
- package/src/services/computed-fields/entity/alpha-num-external-id-computed-field-provider.ts +11 -5
- package/src/services/computed-fields/entity/concat-entity-computed-field-provider.service.ts +15 -1
- package/src/services/crud-helper.service.ts +25 -12
- package/src/services/crud.service.ts +36 -11
- package/src/services/datasource-introspection/mssql-datasource-introspection-provider.service.ts +12 -0
- package/src/services/datasource-introspection/mysql-datasource-introspection-provider.service.ts +2 -0
- package/src/services/datasource-introspection/postgres-datasource-introspection-provider.service.ts +28 -15
- package/src/services/datasource-introspection.service.ts +827 -164
- package/src/services/import-transaction.service.ts +5 -0
- package/src/services/locale.service.ts +111 -3
- package/src/services/mediaStorageProviders/file-s3-storage-provider.ts +2 -2
- package/src/services/menu-item-metadata.service.ts +2 -1
- package/src/services/model-metadata.service.ts +109 -1
- package/src/services/module-metadata.service.ts +36 -0
- package/src/services/removed-field-migration.service.ts +334 -0
- package/src/services/role-metadata.service.ts +26 -2
- package/src/services/settings/default-settings-provider.service.ts +120 -0
- package/src/services/solid-ts-morph.service.ts +61 -1
- package/src/services/view-metadata.service.ts +4 -8
- package/src/solid-core.module.ts +4 -0
- package/src/subscribers/audit.subscriber.ts +101 -18
- package/src/subscribers/computed-entity-field.subscriber.ts +81 -28
- package/src/subscribers/created-by-updated-by.subscriber.ts +3 -0
- package/src/subscribers/field-metadata.subscriber.ts +3 -0
- package/src/subscribers/scheduled-job.subscriber.ts +3 -2
- package/src/subscribers/security-rule.subscriber.ts +8 -3
- package/dist/entities/legacy-common-with-id.entity.d.ts.map +0 -1
- package/dist/entities/legacy-common-with-id.entity.js.map +0 -1
- package/dist/entities/legacy-common.entity.d.ts.map +0 -1
- package/dist/entities/legacy-common.entity.js.map +0 -1
- /package/src/entities/{legacy-common.entity.ts → legacy-common.entity-with-existing-id.entity.ts} +0 -0
|
@@ -204,6 +204,11 @@ export class ImportTransactionService extends CRUDService<ImportTransaction> {
|
|
|
204
204
|
|
|
205
205
|
// Iterate through the fields and populate the standard instructions
|
|
206
206
|
for (const field of allFields) {
|
|
207
|
+
|
|
208
|
+
// Skip Computed fields
|
|
209
|
+
if (field.type === SolidFieldType.computed) {
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
207
212
|
// Skip system fields
|
|
208
213
|
if (systemFieldNames.includes(field.name)) {
|
|
209
214
|
continue;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common';
|
|
1
|
+
import { BadRequestException, Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common';
|
|
2
2
|
import { ModuleRef } from "@nestjs/core";
|
|
3
3
|
import { InjectEntityManager } from '@nestjs/typeorm';
|
|
4
|
-
import { EntityManager } from 'typeorm';
|
|
4
|
+
import { EntityManager, In, IsNull, Not } from 'typeorm';
|
|
5
5
|
|
|
6
6
|
import { Locale } from 'src/entities/locale.entity';
|
|
7
7
|
import { SolidRegistry } from 'src/helpers/solid-registry';
|
|
@@ -31,7 +31,115 @@ export class LocaleService extends CRUDService<Locale> implements OnApplicationB
|
|
|
31
31
|
// Load the security rules from the database
|
|
32
32
|
this.loadLocales();
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
|
|
35
|
+
private async assertCanSetAsDefault(currentLocaleId?: number) {
|
|
36
|
+
const defaultLocales = await this.repo.find({
|
|
37
|
+
where: {
|
|
38
|
+
isDefault: true,
|
|
39
|
+
} as any,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const conflictingDefaultLocale = defaultLocales.find(
|
|
43
|
+
(locale) => locale.id !== currentLocaleId
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if (conflictingDefaultLocale) {
|
|
47
|
+
throw new BadRequestException(
|
|
48
|
+
`Locale "${conflictingDefaultLocale.displayName}" is already marked as default. Mark it as non-default first.`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override async create(createDto: any, files: Express.Multer.File[] = [], solidRequestContext: any = {}): Promise<Locale> {
|
|
54
|
+
if (createDto?.isDefault === true) {
|
|
55
|
+
await this.assertCanSetAsDefault();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const savedLocale = await super.create(createDto, files, solidRequestContext);
|
|
59
|
+
await this.loadLocales();
|
|
60
|
+
return savedLocale;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override async insertMany(createDtos: any[], filesArray: Express.Multer.File[][] = [], solidRequestContext: any = {}): Promise<Locale[]> {
|
|
64
|
+
const defaultLocalesInPayload = (createDtos || []).filter((dto) => dto?.isDefault === true);
|
|
65
|
+
|
|
66
|
+
if (defaultLocalesInPayload.length > 1) {
|
|
67
|
+
throw new BadRequestException(`Only one locale can be marked as default.`);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if (defaultLocalesInPayload.length === 1) {
|
|
71
|
+
await this.assertCanSetAsDefault();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const savedLocales = await super.insertMany(createDtos, filesArray, solidRequestContext);
|
|
75
|
+
await this.loadLocales();
|
|
76
|
+
return savedLocales;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
override async update(id: number, updateDto: any, files: Express.Multer.File[] = [], isPartialUpdate: boolean = false, solidRequestContext: any = {}, isUpdate: boolean = false): Promise<Locale> {
|
|
80
|
+
if (updateDto?.isDefault === true) {
|
|
81
|
+
await this.assertCanSetAsDefault(id);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const savedLocale = await super.update(id, updateDto, files, isPartialUpdate, solidRequestContext, isUpdate);
|
|
85
|
+
await this.loadLocales();
|
|
86
|
+
return savedLocale;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
override async recover(id: number, solidRequestContext: any = {}) {
|
|
90
|
+
const localeToRecover = await this.repo.findOne({
|
|
91
|
+
where: {
|
|
92
|
+
id,
|
|
93
|
+
deletedAt: Not(IsNull()),
|
|
94
|
+
} as any,
|
|
95
|
+
withDeleted: true,
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
if (localeToRecover?.isDefault) {
|
|
99
|
+
await this.assertCanSetAsDefault(id);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const recoveredLocale = await super.recover(id, solidRequestContext);
|
|
103
|
+
await this.loadLocales();
|
|
104
|
+
return recoveredLocale;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
override async recoverMany(ids: number[], solidRequestContext: any = {}) {
|
|
108
|
+
const localesToRecover = await this.repo.find({
|
|
109
|
+
where: {
|
|
110
|
+
id: In(ids),
|
|
111
|
+
deletedAt: Not(IsNull()),
|
|
112
|
+
} as any,
|
|
113
|
+
withDeleted: true,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const defaultLocalesToRecover = localesToRecover.filter((locale) => locale.isDefault);
|
|
117
|
+
if (defaultLocalesToRecover.length > 1) {
|
|
118
|
+
throw new BadRequestException(`Only one locale can be marked as default.`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (defaultLocalesToRecover.length === 1) {
|
|
122
|
+
await this.assertCanSetAsDefault(defaultLocalesToRecover[0].id);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const recoveredLocales = await super.recoverMany(ids, solidRequestContext);
|
|
126
|
+
await this.loadLocales();
|
|
127
|
+
return recoveredLocales;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
override async delete(id: number, solidRequestContext: any = {}) {
|
|
131
|
+
const deletedLocale = await super.delete(id, solidRequestContext);
|
|
132
|
+
await this.loadLocales();
|
|
133
|
+
return deletedLocale;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
override async deleteMany(ids: number[], solidRequestContext: any = {}) {
|
|
137
|
+
const deletedLocales = await super.deleteMany(ids, solidRequestContext);
|
|
138
|
+
await this.loadLocales();
|
|
139
|
+
return deletedLocales;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async loadLocales() {
|
|
35
143
|
const locales = await this.repo.find();
|
|
36
144
|
this.logger.debug(`Loaded ${locales.length} locales into registry`);
|
|
37
145
|
this.solidRegistry.registerlocales(locales);
|
|
@@ -2,8 +2,8 @@ import { Injectable, Logger } from "@nestjs/common";
|
|
|
2
2
|
import { ConfigService } from "@nestjs/config";
|
|
3
3
|
import { CommonEntity } from "src/entities/common.entity";
|
|
4
4
|
import { FieldMetadata } from "src/entities/field-metadata.entity";
|
|
5
|
-
import { LegacyCommonEntityWithExistingId } from "src/entities/legacy-common.entity";
|
|
6
|
-
import { LegacyCommonEntityWithGeneratedId } from "src/entities/legacy-common-with-id.entity";
|
|
5
|
+
import { LegacyCommonEntityWithExistingId } from "src/entities/legacy-common.entity-with-existing-id.entity";
|
|
6
|
+
import { LegacyCommonEntityWithGeneratedId } from "src/entities/legacy-common-with-generated-id.entity";
|
|
7
7
|
import { Media } from "src/entities/media.entity";
|
|
8
8
|
import { MediaStorageProvider } from "src/interfaces";
|
|
9
9
|
import { DiskFileService, S3FileService } from "src/services/file";
|
|
@@ -154,7 +154,7 @@ export class MenuItemMetadataService extends CRUDService<MenuItemMetadata> {
|
|
|
154
154
|
if (!i.parentMenuItem) {
|
|
155
155
|
return true
|
|
156
156
|
} else {
|
|
157
|
-
if(i.action.type === 'custom'){
|
|
157
|
+
if (i.action.type === 'custom') {
|
|
158
158
|
return true;
|
|
159
159
|
}
|
|
160
160
|
return this.crudHelperService.hasReadPermissionOnModel(activeUser, i.action.model.singularName)
|
|
@@ -203,6 +203,7 @@ export class MenuItemMetadataService extends CRUDService<MenuItemMetadata> {
|
|
|
203
203
|
key: rootItem.name.toLowerCase().replace(/\s+/g, '-'),
|
|
204
204
|
icon: rootItem.iconName,
|
|
205
205
|
// iconVariant : rootItem.iconVariant
|
|
206
|
+
isSystem: (rootItem.action?.model?.isSystem ?? false) || rootItem.module?.name === "solid-core",
|
|
206
207
|
}
|
|
207
208
|
if (children.length > 0) {
|
|
208
209
|
data["children"] = await this.buildMenuTree(children, allMenuItems, activeUser);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { BadRequestException, forwardRef, Inject, Injectable, Logger, NotFoundException } from '@nestjs/common';
|
|
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
|
+
import { existsSync } from 'fs';
|
|
4
5
|
import * as path from 'path';
|
|
5
6
|
import { DataSource, EntityManager, In, Repository, SelectQueryBuilder } from 'typeorm';
|
|
6
7
|
import { CreateModelMetadataDto } from '../dtos/create-model-metadata.dto';
|
|
@@ -27,6 +28,8 @@ import { PermissionMetadata } from '../entities/permission-metadata.entity';
|
|
|
27
28
|
import { RoleMetadata } from '../entities/role-metadata.entity';
|
|
28
29
|
import { ViewMetadata } from '../entities/view-metadata.entity';
|
|
29
30
|
import { CommandService } from '../helpers/command.service';
|
|
31
|
+
import { isEmbeddedDb } from '../helpers/environment.helper';
|
|
32
|
+
import { startNodemonHeartbeat } from '../helpers/nodemon-heartbeat';
|
|
30
33
|
import {
|
|
31
34
|
REFRESH_MODEL_COMMAND,
|
|
32
35
|
REMOVE_FIELDS_COMMAND,
|
|
@@ -743,10 +746,72 @@ export class ModelMetadataService {
|
|
|
743
746
|
}
|
|
744
747
|
}
|
|
745
748
|
|
|
749
|
+
await this.cleanupAssociatedTypeormDatasourceFiles(modelEntity, modulePath);
|
|
750
|
+
|
|
746
751
|
// - | Drop database table | Removes the database table from the DB, this is a very risky step. Best to review all relations to other models etc and then do this manually | Manual (X)
|
|
747
752
|
|
|
748
753
|
}
|
|
749
754
|
|
|
755
|
+
private resolveSolidApiRoot(): string | null {
|
|
756
|
+
const cwd = process.cwd();
|
|
757
|
+
const candidates = [
|
|
758
|
+
cwd,
|
|
759
|
+
path.join(cwd, 'solid-api'),
|
|
760
|
+
];
|
|
761
|
+
|
|
762
|
+
for (const candidate of candidates) {
|
|
763
|
+
const srcRoot = path.join(candidate, 'src');
|
|
764
|
+
if (existsSync(srcRoot)) {
|
|
765
|
+
return candidate;
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
private async cleanupAssociatedTypeormDatasourceFiles(modelEntity: ModelMetadata, modulePath?: string | null) {
|
|
773
|
+
if (!modulePath) {
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
const solidApiRoot = this.resolveSolidApiRoot();
|
|
778
|
+
if (!solidApiRoot) {
|
|
779
|
+
this.logger.warn(`Unable to locate consuming solid-api workspace while cleaning datasource files for model '${modelEntity.singularName}'`);
|
|
780
|
+
return;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
const srcRoot = path.join(solidApiRoot, 'src');
|
|
784
|
+
const srcEntries = await fs.readdir(srcRoot).catch(() => []);
|
|
785
|
+
const datasourceFiles = srcEntries
|
|
786
|
+
.filter((entry) => /^typeorm-.*-datasource\.ts$/.test(entry))
|
|
787
|
+
.map((entry) => path.join(srcRoot, entry));
|
|
788
|
+
|
|
789
|
+
if (datasourceFiles.length === 0) {
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
const moduleDirName = path.basename(modulePath);
|
|
794
|
+
const entityClassName = classify(modelEntity.singularName);
|
|
795
|
+
const entityImportPath = `./${moduleDirName}/entities/${kebabCase(modelEntity.singularName)}.entity`;
|
|
796
|
+
|
|
797
|
+
this.logger.log(`Scanning ${datasourceFiles.length} TypeORM datasource file(s) for model '${modelEntity.singularName}' cleanup`);
|
|
798
|
+
|
|
799
|
+
try {
|
|
800
|
+
this.solidTsMorphService.begin();
|
|
801
|
+
for (const datasourceFile of datasourceFiles) {
|
|
802
|
+
this.solidTsMorphService.cleanupTypeormDatasourceEntity(
|
|
803
|
+
datasourceFile,
|
|
804
|
+
entityImportPath,
|
|
805
|
+
entityClassName,
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
await this.solidTsMorphService.commit();
|
|
809
|
+
} catch (error: any) {
|
|
810
|
+
this.solidTsMorphService.rollback();
|
|
811
|
+
this.logger.error(`Failed to clean datasource files for model '${modelEntity.singularName}':`, error);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
|
|
750
815
|
private async cleanupAssociatedViewsActionsAndMenus(modelId: number) {
|
|
751
816
|
const viewRepo = this.dataSource.getRepository(ViewMetadata);
|
|
752
817
|
const actionRepo = this.dataSource.getRepository(ActionMetadata);
|
|
@@ -967,6 +1032,26 @@ export class ModelMetadataService {
|
|
|
967
1032
|
@DisallowInProduction()
|
|
968
1033
|
async generateCodeViaCtl(modelId: number): Promise<string> {
|
|
969
1034
|
const model = await this.findOne(modelId);
|
|
1035
|
+
const isEmbedded = isEmbeddedDb();
|
|
1036
|
+
|
|
1037
|
+
// When using an embedded PGlite database, the single-connection limit means
|
|
1038
|
+
// a spawned `solid refresh-model` subprocess cannot get its own DB connection
|
|
1039
|
+
// while the API server is already holding it. Fall back to in-process code
|
|
1040
|
+
// generation (which reuses the existing connection).
|
|
1041
|
+
if (isEmbedded) {
|
|
1042
|
+
this.logger.log('Embedded database detected — generating API code in-process');
|
|
1043
|
+
// Prevent nodemon from restarting the server while schematics write files.
|
|
1044
|
+
const heartbeat = startNodemonHeartbeat(path.join(process.cwd(), 'src'));
|
|
1045
|
+
try {
|
|
1046
|
+
return await this.handleGenerateCode({
|
|
1047
|
+
modelUserKey: model.singularName,
|
|
1048
|
+
dryRun: false,
|
|
1049
|
+
});
|
|
1050
|
+
} finally {
|
|
1051
|
+
heartbeat.stop();
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
|
|
970
1055
|
return this.commandService.executeCommandWithArgs({
|
|
971
1056
|
command: 'npx',
|
|
972
1057
|
args: ['@solidxai/solidctl@latest', 'generate', 'model', `--name=${model.singularName}`],
|
|
@@ -1478,7 +1563,7 @@ export class ModelMetadataService {
|
|
|
1478
1563
|
//Filter out the fields by id
|
|
1479
1564
|
const fieldsForRemoval = model.fields.filter((field) => options.fieldIdsForRemoval.includes(+field.id));
|
|
1480
1565
|
const removeOutput = await this.executeRemoveFieldsCommand(model, fieldsForRemoval, options.dryRun);
|
|
1481
|
-
|
|
1566
|
+
const migrationOutput = await this.executeMigrationRemoveFieldsCommand(model, fieldsForRemoval, options.dryRun);
|
|
1482
1567
|
// Remove the fields from the database as well. This also checks, if the field is marked for removal
|
|
1483
1568
|
for (const field of fieldsForRemoval) {
|
|
1484
1569
|
if (field.isMarkedForRemoval) {
|
|
@@ -1515,6 +1600,13 @@ export class ModelMetadataService {
|
|
|
1515
1600
|
|
|
1516
1601
|
return removeOutput;
|
|
1517
1602
|
}
|
|
1603
|
+
// model-metadata.service.ts mein naya method add karo
|
|
1604
|
+
// async executeRemoveFieldsWithModel(model: ModelMetadata, fieldNames: string[], dryRun = false,) {
|
|
1605
|
+
// const fieldsForRemoval = model.fields.filter(
|
|
1606
|
+
// field => fieldNames.includes(field.name)
|
|
1607
|
+
// );
|
|
1608
|
+
// return this.executeRemoveFieldsCommand(model, fieldsForRemoval, dryRun);
|
|
1609
|
+
// }
|
|
1518
1610
|
|
|
1519
1611
|
async generateModelCode(options: CodeGenerationOptions): Promise<string> {
|
|
1520
1612
|
if (!options.modelId && !options.modelUserKey) {
|
|
@@ -1563,6 +1655,22 @@ export class ModelMetadataService {
|
|
|
1563
1655
|
return output;
|
|
1564
1656
|
}
|
|
1565
1657
|
|
|
1658
|
+
private async executeMigrationRemoveFieldsCommand(model: ModelMetadata, fieldsForRemoval: FieldMetadata[], dryRun: boolean = false,): Promise<string> {
|
|
1659
|
+
if (!fieldsForRemoval || fieldsForRemoval.length === 0) {
|
|
1660
|
+
return "";
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
const output = await this.commandService.executeCommandWithArgs({
|
|
1664
|
+
command: 'npx',
|
|
1665
|
+
args: ['@solidxai/solidctl@latest', 'migration', '-n', model.singularName, 'remove-field', ...(dryRun ? [] : ['--apply'])],
|
|
1666
|
+
cwd: path.join(process.cwd(), '..'),
|
|
1667
|
+
});
|
|
1668
|
+
|
|
1669
|
+
this.logger.debug(`Schematic output : ${output}`);
|
|
1670
|
+
return output;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
|
|
1566
1674
|
async updateUserKey(data: any) {
|
|
1567
1675
|
const { modelName, fieldName } = data;
|
|
1568
1676
|
|
|
@@ -26,6 +26,8 @@ import {
|
|
|
26
26
|
} from '../helpers/schematic.service';
|
|
27
27
|
import { CommandService } from '../helpers/command.service';
|
|
28
28
|
import { SolidRegistry } from '../helpers/solid-registry';
|
|
29
|
+
import { isEmbeddedDb } from '../helpers/environment.helper';
|
|
30
|
+
import { startNodemonHeartbeat } from '../helpers/nodemon-heartbeat';
|
|
29
31
|
import { CodeGenerationOptions, ModuleMetadataConfiguration } from '../interfaces';
|
|
30
32
|
import { CrudHelperService } from './crud-helper.service';
|
|
31
33
|
import { ModelMetadataService } from './model-metadata.service';
|
|
@@ -534,6 +536,40 @@ export class ModuleMetadataService {
|
|
|
534
536
|
@DisallowInProduction()
|
|
535
537
|
async generateCodeViaCtl(moduleId: number): Promise<string> {
|
|
536
538
|
const module = await this.findOne(moduleId);
|
|
539
|
+
const isEmbedded = isEmbeddedDb();
|
|
540
|
+
|
|
541
|
+
// When using an embedded PGlite database, the single-connection limit means
|
|
542
|
+
// a spawned `solid refresh-module` subprocess cannot get its own DB connection
|
|
543
|
+
// while the API server is already holding it. Fall back to in-process code
|
|
544
|
+
// generation (which reuses the existing connection) and only spawn solidctl
|
|
545
|
+
// for the UI module scaffold (which does not need a database connection).
|
|
546
|
+
if (isEmbedded) {
|
|
547
|
+
this.logger.log('Embedded database detected — generating API code in-process');
|
|
548
|
+
// Prevent nodemon from restarting the server while schematics write files.
|
|
549
|
+
// The heartbeat touches a watched file every 1.5 s (nodemon delay is 2 s),
|
|
550
|
+
// keeping the delay from expiring during DB queries between schematic runs.
|
|
551
|
+
const heartbeat = startNodemonHeartbeat(path.join(process.cwd(), 'src'));
|
|
552
|
+
try {
|
|
553
|
+
const apiOutput = await this.generateCode({
|
|
554
|
+
moduleUserKey: module.name,
|
|
555
|
+
dryRun: false,
|
|
556
|
+
});
|
|
557
|
+
let uiOutput = '';
|
|
558
|
+
try {
|
|
559
|
+
uiOutput = await this.commandService.executeCommandWithArgs({
|
|
560
|
+
command: 'npx',
|
|
561
|
+
args: ['@solidxai/solidctl@latest', 'generate', 'ui-module', `--name=${module.name}`],
|
|
562
|
+
cwd: path.join(process.cwd(), '..'),
|
|
563
|
+
});
|
|
564
|
+
} catch (error) {
|
|
565
|
+
this.logger.warn('UI module scaffold failed (solidctl may be outdated); API code was generated successfully.');
|
|
566
|
+
}
|
|
567
|
+
return `${apiOutput}\n${uiOutput}`;
|
|
568
|
+
} finally {
|
|
569
|
+
heartbeat.stop();
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
537
573
|
return this.commandService.executeCommandWithArgs({
|
|
538
574
|
command: 'npx',
|
|
539
575
|
args: ['@solidxai/solidctl@latest', 'generate', 'module', `--name=${module.name}`],
|