@solidstarters/solid-core 1.2.97 → 1.2.99
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.js +1 -1
- package/dist/controllers/action-metadata.controller.js.map +1 -1
- package/dist/controllers/export-template.controller.js +1 -1
- package/dist/controllers/export-template.controller.js.map +1 -1
- package/dist/controllers/export-transaction.controller.js +1 -1
- package/dist/controllers/export-transaction.controller.js.map +1 -1
- package/dist/controllers/menu-item-metadata.controller.js +1 -1
- package/dist/controllers/menu-item-metadata.controller.js.map +1 -1
- package/dist/controllers/permission-metadata.controller.js +1 -1
- package/dist/controllers/permission-metadata.controller.js.map +1 -1
- package/dist/controllers/role-metadata.controller.js +1 -1
- package/dist/controllers/role-metadata.controller.js.map +1 -1
- package/dist/controllers/service.controller.d.ts +4 -0
- package/dist/controllers/service.controller.d.ts.map +1 -1
- package/dist/controllers/service.controller.js +30 -2
- package/dist/controllers/service.controller.js.map +1 -1
- package/dist/controllers/setting.controller.d.ts +1 -1
- package/dist/controllers/setting.controller.d.ts.map +1 -1
- package/dist/controllers/setting.controller.js +6 -4
- package/dist/controllers/setting.controller.js.map +1 -1
- package/dist/controllers/test.controller.d.ts +0 -3
- package/dist/controllers/test.controller.d.ts.map +1 -1
- package/dist/controllers/test.controller.js +0 -24
- package/dist/controllers/test.controller.js.map +1 -1
- package/dist/controllers/user.controller.js +1 -1
- package/dist/controllers/user.controller.js.map +1 -1
- package/dist/controllers/view-metadata.controller.js +1 -1
- package/dist/controllers/view-metadata.controller.js.map +1 -1
- package/dist/dtos/update-settings.dto.d.ts.map +1 -1
- package/dist/dtos/update-settings.dto.js +1 -2
- package/dist/dtos/update-settings.dto.js.map +1 -1
- package/dist/entities/common.entity.d.ts +3 -0
- package/dist/entities/common.entity.d.ts.map +1 -1
- package/dist/entities/common.entity.js +9 -1
- package/dist/entities/common.entity.js.map +1 -1
- package/dist/entities/menu-item-metadata.entity.js +1 -1
- package/dist/entities/menu-item-metadata.entity.js.map +1 -1
- package/dist/helpers/field-crud-managers/PasswordFieldCrudManager.d.ts +1 -0
- package/dist/helpers/field-crud-managers/PasswordFieldCrudManager.d.ts.map +1 -1
- package/dist/helpers/field-crud-managers/PasswordFieldCrudManager.js +3 -1
- package/dist/helpers/field-crud-managers/PasswordFieldCrudManager.js.map +1 -1
- package/dist/helpers/model-metadata-helper.service.d.ts +8 -0
- package/dist/helpers/model-metadata-helper.service.d.ts.map +1 -0
- package/dist/helpers/model-metadata-helper.service.js +118 -0
- package/dist/helpers/model-metadata-helper.service.js.map +1 -0
- package/dist/helpers/schematic.service.d.ts +4 -1
- package/dist/helpers/schematic.service.d.ts.map +1 -1
- package/dist/helpers/schematic.service.js +8 -10
- package/dist/helpers/schematic.service.js.map +1 -1
- package/dist/helpers/solid-registry.d.ts +3 -1
- package/dist/helpers/solid-registry.d.ts.map +1 -1
- package/dist/helpers/solid-registry.js +4 -0
- package/dist/helpers/solid-registry.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +3 -6
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
- package/dist/seeders/module-metadata-seeder.service.js +1 -1
- package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
- package/dist/seeders/system-fields-seeder.service.d.ts +13 -0
- package/dist/seeders/system-fields-seeder.service.d.ts.map +1 -0
- package/dist/seeders/system-fields-seeder.service.js +56 -0
- package/dist/seeders/system-fields-seeder.service.js.map +1 -0
- package/dist/services/authentication.service.js +4 -4
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/computed-fields/concat-computed-field-provider.service.d.ts.map +1 -1
- package/dist/services/computed-fields/concat-computed-field-provider.service.js +3 -0
- package/dist/services/computed-fields/concat-computed-field-provider.service.js.map +1 -1
- package/dist/services/crud.service.d.ts +1 -1
- package/dist/services/crud.service.d.ts.map +1 -1
- package/dist/services/crud.service.js +7 -6
- package/dist/services/crud.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +3 -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 +25 -2
- package/dist/services/module-metadata.service.js.map +1 -1
- package/dist/services/setting.service.d.ts +1 -1
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +27 -1
- package/dist/services/setting.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +8 -2
- package/dist/solid-core.module.js.map +1 -1
- package/dist/subscribers/audit.subscriber.d.ts +4 -5
- package/dist/subscribers/audit.subscriber.d.ts.map +1 -1
- package/dist/subscribers/audit.subscriber.js +12 -12
- package/dist/subscribers/audit.subscriber.js.map +1 -1
- package/dist/subscribers/created-by-updated-by.subscriber.d.ts +12 -0
- package/dist/subscribers/created-by-updated-by.subscriber.d.ts.map +1 -0
- package/dist/subscribers/created-by-updated-by.subscriber.js +67 -0
- package/dist/subscribers/created-by-updated-by.subscriber.js.map +1 -0
- package/dist/subscribers/model.subscriber.d.ts +4 -1
- package/dist/subscribers/model.subscriber.d.ts.map +1 -1
- package/dist/subscribers/model.subscriber.js +20 -67
- package/dist/subscribers/model.subscriber.js.map +1 -1
- package/dist/subscribers/{softDeleteAwareEventSubscriber.subscriber.d.ts → soft-delete-aware-event.subscriber.d.ts} +1 -1
- package/dist/subscribers/soft-delete-aware-event.subscriber.d.ts.map +1 -0
- package/dist/subscribers/{softDeleteAwareEventSubscriber.subscriber.js → soft-delete-aware-event.subscriber.js} +1 -1
- package/dist/subscribers/soft-delete-aware-event.subscriber.js.map +1 -0
- package/dist/subscribers/view-metadata.subscriber.d.ts.map +1 -1
- package/dist/subscribers/view-metadata.subscriber.js +16 -14
- package/dist/subscribers/view-metadata.subscriber.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/controllers/action-metadata.controller.ts +1 -1
- package/src/controllers/export-template.controller.ts +1 -1
- package/src/controllers/export-transaction.controller.ts +1 -1
- package/src/controllers/menu-item-metadata.controller.ts +1 -1
- package/src/controllers/permission-metadata.controller.ts +1 -1
- package/src/controllers/role-metadata.controller.ts +1 -1
- package/src/controllers/service.controller.ts +20 -1
- package/src/controllers/setting.controller.ts +4 -3
- package/src/controllers/test.controller.ts +16 -16
- package/src/controllers/user.controller.ts +1 -1
- package/src/controllers/view-metadata.controller.ts +1 -1
- package/src/dtos/update-settings.dto.ts +2 -3
- package/src/entities/common.entity.ts +8 -2
- package/src/entities/menu-item-metadata.entity.ts +1 -1
- package/src/helpers/field-crud-managers/PasswordFieldCrudManager.ts +5 -1
- package/src/helpers/model-metadata-helper.service.ts +109 -0
- package/src/helpers/schematic.service.ts +10 -11
- package/src/helpers/solid-registry.ts +6 -1
- package/src/index.ts +2 -2
- package/src/interfaces.ts +3 -3
- package/src/seeders/module-metadata-seeder.service.ts +3 -1
- package/src/seeders/system-fields-seeder.service.ts +53 -0
- package/src/services/authentication.service.ts +4 -4
- package/src/services/computed-fields/concat-computed-field-provider.service.ts +3 -0
- package/src/services/crud.service.ts +7 -6
- package/src/services/model-metadata.service.ts +17 -15
- package/src/services/module-metadata.service.ts +28 -4
- package/src/services/setting.service.ts +30 -1
- package/src/solid-core.module.ts +8 -1
- package/src/subscribers/audit.subscriber.ts +10 -11
- package/src/subscribers/created-by-updated-by.subscriber.ts +54 -0
- package/src/subscribers/model.subscriber.ts +16 -70
- package/src/subscribers/view-metadata.subscriber.ts +19 -15
- package/dist/subscribers/softDeleteAwareEventSubscriber.subscriber.d.ts.map +0 -1
- package/dist/subscribers/softDeleteAwareEventSubscriber.subscriber.js.map +0 -1
- package/src/services/pending_import_issues +0 -3
- /package/src/subscribers/{softDeleteAwareEventSubscriber.subscriber.ts → soft-delete-aware-event.subscriber.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidstarters/solid-core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.99",
|
|
4
4
|
"description": "This module is a NestJS module containing all the required core providers required by a Solid application",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -7,7 +7,7 @@ import { UpdateActionMetadataDto } from '../dtos/update-action-metadata.dto';
|
|
|
7
7
|
import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
|
|
8
8
|
import { SolidRequestContextDecorator } from 'src/decorators/solid-request-context.decorator';
|
|
9
9
|
|
|
10
|
-
@ApiTags('App')
|
|
10
|
+
@ApiTags('App Builder')
|
|
11
11
|
@Controller('action-metadata') //FIXME: Change this to the model plural name
|
|
12
12
|
export class ActionMetadataController {
|
|
13
13
|
constructor(private readonly service: ActionMetadataService) { }
|
|
@@ -7,7 +7,7 @@ import { UpdateExportTemplateDto } from '../dtos/update-export-template.dto';
|
|
|
7
7
|
import { Response } from 'express';
|
|
8
8
|
import { StartExportSyncDto } from 'src/dtos/export.dto';
|
|
9
9
|
|
|
10
|
-
@ApiTags('Solid')
|
|
10
|
+
@ApiTags('Solid Core')
|
|
11
11
|
@Controller('export-template') //FIXME: Change this to the model plural name
|
|
12
12
|
export class ExportTemplateController {
|
|
13
13
|
constructor(private readonly service: ExportTemplateService) {}
|
|
@@ -5,7 +5,7 @@ import { ExportTransactionService } from '../services/export-transaction.service
|
|
|
5
5
|
import { CreateExportTransactionDto } from '../dtos/create-export-transaction.dto';
|
|
6
6
|
import { UpdateExportTransactionDto } from '../dtos/update-export-transaction.dto';
|
|
7
7
|
|
|
8
|
-
@ApiTags('Solid')
|
|
8
|
+
@ApiTags('Solid Core')
|
|
9
9
|
@Controller('export-transaction') //FIXME: Change this to the model plural name
|
|
10
10
|
export class ExportTransactionController {
|
|
11
11
|
constructor(private readonly service: ExportTransactionService) {}
|
|
@@ -9,7 +9,7 @@ import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
|
|
|
9
9
|
import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
|
|
10
10
|
import { SolidRequestContextDecorator } from 'src/decorators/solid-request-context.decorator';
|
|
11
11
|
|
|
12
|
-
@ApiTags('App')
|
|
12
|
+
@ApiTags('App Builder')
|
|
13
13
|
@Controller('menu-item-metadata') //FIXME: Change this to the model plural name
|
|
14
14
|
export class MenuItemMetadataController {
|
|
15
15
|
constructor(private readonly service: MenuItemMetadataService) { }
|
|
@@ -7,7 +7,7 @@ import { UpdatePermissionMetadataDto } from '../dtos/update-permission-metadata.
|
|
|
7
7
|
import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
|
|
8
8
|
import { SolidRequestContextDecorator } from 'src/decorators/solid-request-context.decorator';
|
|
9
9
|
|
|
10
|
-
@ApiTags('Solid')
|
|
10
|
+
@ApiTags('Solid Core')
|
|
11
11
|
@Controller('permission-metadata') //FIXME: Change this to the model plural name
|
|
12
12
|
export class PermissionMetadataController {
|
|
13
13
|
constructor(private readonly service: PermissionMetadataService) { }
|
|
@@ -7,7 +7,7 @@ import { UpdateRoleMetadataDto } from '../dtos/update-role-metadata.dto';
|
|
|
7
7
|
import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
|
|
8
8
|
import { SolidRequestContextDecorator } from 'src/decorators/solid-request-context.decorator';
|
|
9
9
|
|
|
10
|
-
@ApiTags('Solid')
|
|
10
|
+
@ApiTags('Solid Core')
|
|
11
11
|
@Controller('role-metadata') //FIXME: Change this to the model plural name
|
|
12
12
|
export class RoleMetadataController {
|
|
13
13
|
constructor(private readonly service: RoleMetadataService) {}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Controller, Get } from '@nestjs/common';
|
|
1
|
+
import { Body, Controller, Get, Logger, Post } from '@nestjs/common';
|
|
2
2
|
import { DiscoveryService, MetadataScanner, Reflector } from '@nestjs/core';
|
|
3
3
|
import { Public } from 'src/decorators/public.decorator';
|
|
4
4
|
import { SolidRegistry } from '../helpers/solid-registry';
|
|
@@ -8,6 +8,8 @@ import { ApiTags } from '@nestjs/swagger';
|
|
|
8
8
|
@Controller('')
|
|
9
9
|
@ApiTags("Common")
|
|
10
10
|
export class ServiceController {
|
|
11
|
+
private readonly logger = new Logger(ServiceController.name);
|
|
12
|
+
|
|
11
13
|
constructor(
|
|
12
14
|
private readonly solidRegistry: SolidRegistry,
|
|
13
15
|
) { }
|
|
@@ -18,6 +20,23 @@ export class ServiceController {
|
|
|
18
20
|
return { pong: 'v1.0.2' };
|
|
19
21
|
}
|
|
20
22
|
|
|
23
|
+
@Public()
|
|
24
|
+
@Post('seed')
|
|
25
|
+
async seedData(@Body() seedData: any) {
|
|
26
|
+
const seeder = this.solidRegistry
|
|
27
|
+
.getSeeders()
|
|
28
|
+
.filter((seeder) => seeder.name === seedData.seeder)
|
|
29
|
+
.map((seeder) => seeder.instance)
|
|
30
|
+
.pop();
|
|
31
|
+
if (!seeder) {
|
|
32
|
+
this.logger.error(`Seeder service ${seedData.seeder} not found. Does your service have a seed() method?`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
this.logger.log(`Running the seed() method for seeder :${seeder.constructor.name}`);
|
|
36
|
+
await seeder.seed();
|
|
37
|
+
return { message: `seed data for ${seedData.seeder}` };
|
|
38
|
+
}
|
|
39
|
+
|
|
21
40
|
// @Public()
|
|
22
41
|
// @Get('play')
|
|
23
42
|
// play() {
|
|
@@ -8,7 +8,7 @@ import { SolidRequestContextDecorator } from 'src/decorators/solid-request-conte
|
|
|
8
8
|
import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
|
|
9
9
|
import { UpdateSettingsDto } from 'src/dtos/update-settings.dto';
|
|
10
10
|
|
|
11
|
-
@ApiTags('Solid')
|
|
11
|
+
@ApiTags('Solid Core')
|
|
12
12
|
@Controller('setting') //FIXME: Change this to the model plural name
|
|
13
13
|
export class SettingController {
|
|
14
14
|
constructor(private readonly service: SettingService) {}
|
|
@@ -88,7 +88,8 @@ export class SettingController {
|
|
|
88
88
|
|
|
89
89
|
@ApiBearerAuth("jwt")
|
|
90
90
|
@Post('/bulk-update')
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
@UseInterceptors(AnyFilesInterceptor())
|
|
92
|
+
async updateSettings(@Body() updateSettingsDto: UpdateSettingsDto, @UploadedFiles() files: Array<Express.Multer.File>) {
|
|
93
|
+
return this.service.updateSettings(updateSettingsDto.settings, files);
|
|
93
94
|
}
|
|
94
95
|
}
|
|
@@ -34,21 +34,21 @@ export class TestController {
|
|
|
34
34
|
return { filename: file.originalname };
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
@Public()
|
|
38
|
-
@Post('seed')
|
|
39
|
-
async seedData(@Body() seedData: any) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
37
|
+
// @Public()
|
|
38
|
+
// @Post('seed')
|
|
39
|
+
// async seedData(@Body() seedData: any) {
|
|
40
|
+
// const seeder = this.solidRegistry
|
|
41
|
+
// .getSeeders()
|
|
42
|
+
// .filter((seeder) => seeder.name === seedData.seeder)
|
|
43
|
+
// .map((seeder) => seeder.instance)
|
|
44
|
+
// .pop();
|
|
45
|
+
// if (!seeder) {
|
|
46
|
+
// this.logger.error(`Seeder service ${seedData.seeder} not found. Does your service have a seed() method?`);
|
|
47
|
+
// return;
|
|
48
|
+
// }
|
|
49
|
+
// this.logger.log(`Running the seed() method for seeder :${seeder.constructor.name}`);
|
|
50
|
+
// await seeder.seed();
|
|
51
|
+
// return { message: `seed data for ${seedData.seeder}` };
|
|
52
|
+
// }
|
|
53
53
|
|
|
54
54
|
}
|
|
@@ -11,7 +11,7 @@ import { ActiveUserData } from '../interfaces/active-user-data.interface';
|
|
|
11
11
|
import { SolidRequestContextDecorator } from 'src/decorators/solid-request-context.decorator';
|
|
12
12
|
import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
|
|
13
13
|
|
|
14
|
-
@ApiTags('Solid')
|
|
14
|
+
@ApiTags('Solid Core')
|
|
15
15
|
@Controller('user') //FIXME: Change this to the model plural name
|
|
16
16
|
export class UserController {
|
|
17
17
|
constructor(private readonly service: UserService) { }
|
|
@@ -9,7 +9,7 @@ import { SolidRequestContextDto } from 'src/dtos/solid-request-context.dto';
|
|
|
9
9
|
import { ActiveUser } from 'src/decorators/active-user.decorator';
|
|
10
10
|
import { ActiveUserData } from 'src/interfaces/active-user-data.interface';
|
|
11
11
|
|
|
12
|
-
@ApiTags('App')
|
|
12
|
+
@ApiTags('App Builder')
|
|
13
13
|
@Controller('view-metadata') //FIXME: Change this to the model plural name
|
|
14
14
|
export class ViewMetadataController {
|
|
15
15
|
constructor(private readonly service: ViewMetadataService) { }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { Column, CreateDateColumn, DeleteDateColumn, ManyToOne, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
|
|
2
|
+
import type { User } from "./user.entity";
|
|
3
3
|
|
|
4
4
|
export abstract class CommonEntity {
|
|
5
5
|
@PrimaryGeneratedColumn({ type: 'integer' })
|
|
@@ -25,4 +25,10 @@ export abstract class CommonEntity {
|
|
|
25
25
|
|
|
26
26
|
@Column({ type: "int", name: 'default_entity_locale_id', default: null })
|
|
27
27
|
defaultEntityLocaleId: number;
|
|
28
|
+
|
|
29
|
+
@ManyToOne(() => require('./user.entity').User?.default ?? require('./user.entity').User, { nullable: true })
|
|
30
|
+
createdBy: User;
|
|
31
|
+
|
|
32
|
+
@ManyToOne(() => require('./user.entity').User?.default ?? require('./user.entity').User, { nullable: true })
|
|
33
|
+
updatedBy: User;
|
|
28
34
|
}
|
|
@@ -23,7 +23,7 @@ export class MenuItemMetadata extends CommonEntity {
|
|
|
23
23
|
@ManyToOne(() => ActionMetadata, { onDelete: "CASCADE", nullable: true })
|
|
24
24
|
@JoinColumn({ referencedColumnName: 'id' })
|
|
25
25
|
action: ActionMetadata;
|
|
26
|
-
@ManyToMany(() => RoleMetadata, roleMetadata => roleMetadata.
|
|
26
|
+
@ManyToMany(() => RoleMetadata, roleMetadata => roleMetadata.menuItems, { cascade: true })
|
|
27
27
|
@JoinTable()
|
|
28
28
|
roles: RoleMetadata[];
|
|
29
29
|
@Column({ name: "sequence_number", type: "int", nullable: true })
|
|
@@ -9,6 +9,7 @@ export interface PasswordFieldOptions {
|
|
|
9
9
|
required: boolean | undefined | null;
|
|
10
10
|
regexPattern: string | undefined | null;
|
|
11
11
|
fieldName: string | undefined | null;
|
|
12
|
+
isUpdate: Boolean;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
export class PasswordFieldCrudManager implements FieldCrudManager {
|
|
@@ -24,7 +25,10 @@ export class PasswordFieldCrudManager implements FieldCrudManager {
|
|
|
24
25
|
|
|
25
26
|
private applyValidations(fieldValue: any, dto: any): ValidationError[] {
|
|
26
27
|
const errors: ValidationError[] = [];
|
|
27
|
-
this.isApplyRequiredValidation() && isEmpty(fieldValue)
|
|
28
|
+
if (!this.options?.isUpdate && this.isApplyRequiredValidation() && isEmpty(fieldValue)) {
|
|
29
|
+
errors.push({ field: this.options.fieldName, error: `Field: ${this.options.fieldName} is required` });
|
|
30
|
+
}
|
|
31
|
+
// this.isApplyRequiredValidation() && isEmpty(fieldValue) ? errors.push({ field: this.options.fieldName, error: `Field: ${this.options.fieldName} is required` }): "no errors";
|
|
28
32
|
if (isNotEmpty(fieldValue)) {
|
|
29
33
|
errors.push(...this.applyFormatValidations(fieldValue, dto));
|
|
30
34
|
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
// Return the system fields metadata for a model
|
|
2
|
+
|
|
3
|
+
import { Injectable, Logger } from "@nestjs/common";
|
|
4
|
+
import { SolidRegistry } from "./solid-registry";
|
|
5
|
+
import { In } from "typeorm";
|
|
6
|
+
|
|
7
|
+
@Injectable()
|
|
8
|
+
export class ModelMetadataHelperService {
|
|
9
|
+
private readonly logger = new Logger(ModelMetadataHelperService.name);
|
|
10
|
+
|
|
11
|
+
constructor(private readonly registry: SolidRegistry) {
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
getSystemFieldsMetadata(): any[] {
|
|
15
|
+
const systemFieldsMetadata = [
|
|
16
|
+
{
|
|
17
|
+
name: "id",
|
|
18
|
+
displayName: "Id",
|
|
19
|
+
type: "int",
|
|
20
|
+
ormType: "bigint",
|
|
21
|
+
isSystem: true,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "createdAt",
|
|
25
|
+
displayName: "Created At",
|
|
26
|
+
type: "datetime",
|
|
27
|
+
ormType: "timestamp",
|
|
28
|
+
isSystem: true,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "updatedAt",
|
|
32
|
+
displayName: "Updated At",
|
|
33
|
+
type: "datetime",
|
|
34
|
+
ormType: "timestamp",
|
|
35
|
+
isSystem: true,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: "deletedAt",
|
|
39
|
+
displayName: "Deleted At",
|
|
40
|
+
type: "datetime",
|
|
41
|
+
ormType: "timestamp",
|
|
42
|
+
isSystem: true,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: "deletedTracker",
|
|
46
|
+
displayName: "Deleted Tracker",
|
|
47
|
+
type: "shortText",
|
|
48
|
+
ormType: "varchar",
|
|
49
|
+
isSystem: true,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
name: "publishedAt",
|
|
53
|
+
displayName: "Published At",
|
|
54
|
+
type: "datetime",
|
|
55
|
+
ormType: "timestamp",
|
|
56
|
+
isSystem: true,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "localeName",
|
|
60
|
+
displayName: "Locale",
|
|
61
|
+
type: "shortText",
|
|
62
|
+
ormType: "varchar",
|
|
63
|
+
isSystem: true,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: "defaultEntityLocaleId",
|
|
67
|
+
displayName: "Default Entity Locale Id",
|
|
68
|
+
type: "int",
|
|
69
|
+
ormType: "integer",
|
|
70
|
+
isSystem: true,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "createdBy",
|
|
74
|
+
displayName: "Created By",
|
|
75
|
+
type: "relation",
|
|
76
|
+
ormType: "int",
|
|
77
|
+
isSystem: true,
|
|
78
|
+
relationType: "many-to-one",
|
|
79
|
+
relationCoModelSingularName: "user",
|
|
80
|
+
relationCreateInverse: false,
|
|
81
|
+
relationCascade: "restrict",
|
|
82
|
+
relationModelModuleName: "solid-core"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "updatedBy",
|
|
86
|
+
displayName: "Updated By",
|
|
87
|
+
type: "relation",
|
|
88
|
+
ormType: "int",
|
|
89
|
+
isSystem: true,
|
|
90
|
+
relationType: "many-to-one",
|
|
91
|
+
relationCoModelSingularName: "user",
|
|
92
|
+
relationCreateInverse: false,
|
|
93
|
+
relationCascade: "restrict",
|
|
94
|
+
relationModelModuleName: "solid-core"
|
|
95
|
+
},
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
// Do an additional check and add a warning if the common entity keys and system field metadata keys don't match exactly
|
|
99
|
+
const commonEntityKeys = this.registry.getCommonEntityKeys();
|
|
100
|
+
const systemFieldNames = systemFieldsMetadata.map(field => field.name);
|
|
101
|
+
const missingKeys = commonEntityKeys.filter(key => !systemFieldNames.includes(key));
|
|
102
|
+
if (missingKeys.length > 0) {
|
|
103
|
+
this.logger.warn(`Missing system fields metadata for common entity keys: ${missingKeys.join(', ')}`);
|
|
104
|
+
}
|
|
105
|
+
return systemFieldsMetadata;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Injectable, Logger } from '@nestjs/common';
|
|
2
2
|
import { CommandService } from './command.service';
|
|
3
3
|
import { snakeCase } from "lodash";
|
|
4
|
+
import { CommonEntity } from 'src/entities/common.entity';
|
|
5
|
+
import { SolidRegistry } from './solid-registry';
|
|
4
6
|
|
|
5
7
|
export const ADD_MODULE_COMMAND = 'add-module';
|
|
6
8
|
export type GenerateModuleOptions = {
|
|
@@ -14,25 +16,19 @@ type FieldOptions = {
|
|
|
14
16
|
dataSource: string;
|
|
15
17
|
fields: any[]; //FIXME This type can be improved
|
|
16
18
|
modelEnableSoftDelete?: boolean;
|
|
17
|
-
parentModel?: string;
|
|
19
|
+
parentModel?: string;
|
|
18
20
|
parentModule?: string;
|
|
21
|
+
draftPublishWorkflowEnabled?: boolean;
|
|
19
22
|
};
|
|
20
23
|
export const REMOVE_FIELDS_COMMAND = 'remove-fields';
|
|
21
24
|
export const REFRESH_MODEL_COMMAND = 'refresh-model';
|
|
22
25
|
|
|
23
|
-
enum SYSTEM_FIELDS_TO_IGNORE_FOR_CODE_GENERATION {
|
|
24
|
-
ID = 'id',
|
|
25
|
-
CREATED_AT = 'createdAt',
|
|
26
|
-
UPDATED_AT = 'updatedAt',
|
|
27
|
-
DELETED_AT = 'deletedAt'
|
|
28
|
-
}
|
|
29
|
-
|
|
30
26
|
//TODO Rename to CodeBuilder service
|
|
31
27
|
@Injectable()
|
|
32
28
|
export class SchematicService {
|
|
33
29
|
private readonly logger = new Logger(SchematicService.name);
|
|
34
30
|
private readonly SCHEMATIC_PROJECT = '@solidstarters/solid-code-builder';
|
|
35
|
-
constructor(private readonly commandService: CommandService) { }
|
|
31
|
+
constructor(private readonly commandService: CommandService, private readonly solidRegistry: SolidRegistry) { }
|
|
36
32
|
|
|
37
33
|
async executeSchematicCommand(
|
|
38
34
|
command: string,
|
|
@@ -79,9 +75,13 @@ export class SchematicService {
|
|
|
79
75
|
modelCommand += ` --parent-module=${fieldOptions.parentModule}`;
|
|
80
76
|
}
|
|
81
77
|
|
|
78
|
+
if (fieldOptions.draftPublishWorkflowEnabled) {
|
|
79
|
+
modelCommand += ` --draft-publish-workflow-enabled=${fieldOptions.draftPublishWorkflowEnabled}`;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
82
|
let fieldCommand = fieldOptions.fields
|
|
83
83
|
.filter((field) => {
|
|
84
|
-
return !
|
|
84
|
+
return !this.solidRegistry.getCommonEntityKeys().includes(field.name);
|
|
85
85
|
})
|
|
86
86
|
.map((field) => {
|
|
87
87
|
return `--fields='${JSON.stringify(field)}'`;
|
|
@@ -101,5 +101,4 @@ export class SchematicService {
|
|
|
101
101
|
throw new Error('Schematic command not supported.');
|
|
102
102
|
}
|
|
103
103
|
}
|
|
104
|
-
|
|
105
104
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Injectable } from '@nestjs/common';
|
|
2
2
|
import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
|
|
3
|
-
import {
|
|
3
|
+
import { CommonEntity } from 'src/entities/common.entity';
|
|
4
4
|
import { SecurityRule } from 'src/entities/security-rule.entity';
|
|
5
5
|
import { EntityManager } from 'typeorm';
|
|
6
|
+
import { ISelectionProvider, ISelectionProviderContext } from "../interfaces";
|
|
6
7
|
import { Locale } from 'src/entities/locale.entity';
|
|
7
8
|
|
|
8
9
|
type ControllerMetadata = {
|
|
@@ -147,4 +148,8 @@ export class SolidRegistry {
|
|
|
147
148
|
return entityMetadata.target;
|
|
148
149
|
}
|
|
149
150
|
|
|
151
|
+
getCommonEntityKeys(): (keyof CommonEntity) [] {
|
|
152
|
+
return Reflect.getMetadataKeys(CommonEntity.prototype) as (keyof CommonEntity)[];
|
|
153
|
+
}
|
|
154
|
+
|
|
150
155
|
}
|
package/src/index.ts
CHANGED
|
@@ -242,7 +242,7 @@ export * from './repository/field.repository'
|
|
|
242
242
|
|
|
243
243
|
//softDeleteAwareEventSubscriber.subscriber.ts
|
|
244
244
|
export * from './subscribers/model.subscriber'
|
|
245
|
-
export * from './subscribers/
|
|
245
|
+
export * from './subscribers/soft-delete-aware-event.subscriber' //rename
|
|
246
246
|
export * from './subscribers/view-metadata.subscriber' //rename
|
|
247
247
|
export * from './subscribers/audit.subscriber'
|
|
248
248
|
|
|
@@ -259,4 +259,4 @@ export * from './interfaces'
|
|
|
259
259
|
export * from './solid-core.module'
|
|
260
260
|
|
|
261
261
|
export * from './winston.logger'
|
|
262
|
-
export
|
|
262
|
+
export { default as datetimeTransformer } from './transformers/datetime-transformer'
|
package/src/interfaces.ts
CHANGED
|
@@ -43,9 +43,9 @@ export interface ModuleMetadataConfiguration {
|
|
|
43
43
|
moduleMetadata?: CreateModuleMetadataDto,
|
|
44
44
|
roles?: CreateRoleMetadataDto[],
|
|
45
45
|
users?: SignUpDto[],
|
|
46
|
-
actions?:
|
|
47
|
-
menus?:
|
|
48
|
-
views?:
|
|
46
|
+
actions?: any[],
|
|
47
|
+
menus?: any[],
|
|
48
|
+
views?: any[],
|
|
49
49
|
emailTemplates?: CreateEmailTemplateDto[],
|
|
50
50
|
smsTemplates?: CreateSmsTemplateDto[],
|
|
51
51
|
mediaStorageProviders?: CreateMediaStorageProviderMetadataDto[]
|
|
@@ -409,8 +409,10 @@ export class ModuleMetadataSeederService {
|
|
|
409
409
|
viewData['model'] = await this.modelMetadataService.findOneByUserKey(viewData.modelUserKey);
|
|
410
410
|
// await this.solidViewService.upsert(viewData);
|
|
411
411
|
// First check if module already exists using name
|
|
412
|
-
await this.solidViewService.createIfNotPresent(viewData);
|
|
413
412
|
|
|
413
|
+
// Changed the below to upsert as now we are saving modifications to the view json to file system also.
|
|
414
|
+
// await this.solidViewService.createIfNotPresent(viewData);
|
|
415
|
+
await this.solidViewService.upsert(viewData);
|
|
414
416
|
}
|
|
415
417
|
}
|
|
416
418
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// This class will add the system fields in the field-metadata table if they are missing.
|
|
2
|
+
// Fetch all the models and their fields metadata and check if the system fields are present.
|
|
3
|
+
|
|
4
|
+
import { InjectRepository } from "@nestjs/typeorm";
|
|
5
|
+
import { ModelMetadata } from "src/entities/model-metadata.entity";
|
|
6
|
+
import { ModelMetadataHelperService } from "src/helpers/model-metadata-helper.service";
|
|
7
|
+
import { FieldRepository } from "src/repository/field.repository";
|
|
8
|
+
import { Repository } from "typeorm";
|
|
9
|
+
|
|
10
|
+
export class SystemFieldsSeederService {
|
|
11
|
+
// This service is responsible for seeding the system fields metadata for all models.
|
|
12
|
+
// It will check if the system fields are already present in the field-metadata table.
|
|
13
|
+
// If not, it will add them.
|
|
14
|
+
constructor(
|
|
15
|
+
private readonly modelHelperService: ModelMetadataHelperService,
|
|
16
|
+
@InjectRepository(ModelMetadata)
|
|
17
|
+
private readonly modelRepository: Repository<ModelMetadata>, // Replace with actual model repository type
|
|
18
|
+
@InjectRepository(FieldRepository)
|
|
19
|
+
private readonly fieldRepository: Repository<FieldRepository>, // Replace with actual field repository type
|
|
20
|
+
) {}
|
|
21
|
+
|
|
22
|
+
async seed() {
|
|
23
|
+
// Get the model repo
|
|
24
|
+
const models = await this.modelRepository.find({
|
|
25
|
+
relations: ['fields'], // Assuming 'fields' is the relation to field metadata
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
for (const model of models) {
|
|
29
|
+
// Check if the system fields are already present
|
|
30
|
+
await this.seedMissingSystemFields(model);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private async seedMissingSystemFields(model: ModelMetadata) {
|
|
35
|
+
const existingSystemFields = model.fields.filter(field => field.isSystem);
|
|
36
|
+
const systemFieldsMetadata = this.modelHelperService.getSystemFieldsMetadata();
|
|
37
|
+
|
|
38
|
+
// Find out which system fields are missing
|
|
39
|
+
const missingFields = systemFieldsMetadata.filter(
|
|
40
|
+
sysField => !existingSystemFields.some(field => field.name === sysField.name)
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// If there are missing fields, add them
|
|
44
|
+
if (missingFields.length > 0) {
|
|
45
|
+
const newFields = missingFields.map(field => ({
|
|
46
|
+
...field,
|
|
47
|
+
model: model, // Associate the field with the current model
|
|
48
|
+
}));
|
|
49
|
+
await this.fieldRepository.save(newFields);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
@@ -362,7 +362,7 @@ export class AuthenticationService {
|
|
|
362
362
|
solidAppName: process.env.SOLID_APP_NAME,
|
|
363
363
|
solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,
|
|
364
364
|
firstName: user.username,
|
|
365
|
-
fullName: user.fullName,
|
|
365
|
+
fullName: user.fullName ? user.fullName : user.username,
|
|
366
366
|
emailVerificationTokenOnRegistration: user.emailVerificationTokenOnRegistration,
|
|
367
367
|
},
|
|
368
368
|
this.commonConfiguration.shouldQueueEmails,
|
|
@@ -379,7 +379,7 @@ export class AuthenticationService {
|
|
|
379
379
|
otp: user.mobileVerificationTokenOnRegistration,
|
|
380
380
|
mobileVerificationTokenOnRegistration: user.mobileVerificationTokenOnRegistration,
|
|
381
381
|
firstName: user.username,
|
|
382
|
-
fullName: user.fullName,
|
|
382
|
+
fullName: user.fullName ? user.fullName : user.username,
|
|
383
383
|
}
|
|
384
384
|
);
|
|
385
385
|
}
|
|
@@ -544,7 +544,7 @@ export class AuthenticationService {
|
|
|
544
544
|
solidAppWebsiteUrl: process.env.SOLID_APP_WEBSITE_URL,
|
|
545
545
|
firstName: user.username,
|
|
546
546
|
emailVerificationTokenOnLogin: user.emailVerificationTokenOnLogin,
|
|
547
|
-
fullName: user.fullName,
|
|
547
|
+
fullName: user.fullName ? user.fullName : user.username,
|
|
548
548
|
},
|
|
549
549
|
this.commonConfiguration.shouldQueueEmails,
|
|
550
550
|
'user',
|
|
@@ -560,7 +560,7 @@ export class AuthenticationService {
|
|
|
560
560
|
otp: user.mobileVerificationTokenOnLogin,
|
|
561
561
|
mobileVerificationTokenOnLogin: user.mobileVerificationTokenOnLogin,
|
|
562
562
|
firstName: user.username,
|
|
563
|
-
fullName: user.fullName,
|
|
563
|
+
fullName: user.fullName ? user.fullName : user.username,
|
|
564
564
|
}
|
|
565
565
|
);
|
|
566
566
|
}
|
|
@@ -25,6 +25,9 @@ export class ConcatComputedFieldProvider implements IComputedFieldProvider<any>
|
|
|
25
25
|
const fields = ctxt.fields;
|
|
26
26
|
const slugify = ctxt.slugify || false;
|
|
27
27
|
|
|
28
|
+
if (!Array.isArray(fields) || fields?.length === 0) {
|
|
29
|
+
return '';
|
|
30
|
+
}
|
|
28
31
|
let concatenatedString = '';
|
|
29
32
|
for (let i = 0; i < fields.length; i++) {
|
|
30
33
|
const field = fields[i];
|
|
@@ -109,8 +109,8 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
109
109
|
});
|
|
110
110
|
}
|
|
111
111
|
|
|
112
|
-
private async validateAndTransformDto(field: FieldMetadata, dto: any, files: Express.Multer.File[], hasMediaFields: boolean, isPartialUpdate: boolean = false) {
|
|
113
|
-
const fieldManager: FieldCrudManager = this.fieldCrudManager(field, this.entityManager, isPartialUpdate);
|
|
112
|
+
private async validateAndTransformDto(field: FieldMetadata, dto: any, files: Express.Multer.File[], hasMediaFields: boolean, isPartialUpdate: boolean = false, isUpdate: boolean = false) {
|
|
113
|
+
const fieldManager: FieldCrudManager = this.fieldCrudManager(field, this.entityManager, isPartialUpdate, isUpdate);
|
|
114
114
|
const validationErrors = fieldManager.validate(dto, files);
|
|
115
115
|
const errors = (validationErrors instanceof Promise) ? await validationErrors : validationErrors;
|
|
116
116
|
if (errors.length > 0) {
|
|
@@ -150,10 +150,11 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
150
150
|
}
|
|
151
151
|
|
|
152
152
|
//TODO: Will the updates be partial i.e PATCH or full i.e PUT
|
|
153
|
-
async update(id: number, updateDto: any, files: Express.Multer.File[] = [], isPartialUpdate: boolean = false, solidRequestContext: any = {}): Promise<T> {
|
|
153
|
+
async update(id: number, updateDto: any, files: Express.Multer.File[] = [], isPartialUpdate: boolean = false, solidRequestContext: any = {}, isUpdate: boolean = false): Promise<T> {
|
|
154
154
|
if (!id) {
|
|
155
155
|
throw new Error('Id is required for update');
|
|
156
156
|
}
|
|
157
|
+
isUpdate = true;
|
|
157
158
|
const model = await this.loadModel();
|
|
158
159
|
// Check wheather user has update permission for model
|
|
159
160
|
if (solidRequestContext.activeUser) {
|
|
@@ -185,7 +186,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
185
186
|
// 2. Loop through the fields with a switch statement
|
|
186
187
|
// 3. Handle the fields based on field type
|
|
187
188
|
for (const field of fieldsToProcess) {
|
|
188
|
-
const transformed = await this.validateAndTransformDto(field, updateDto, files, hasMediaFields, isPartialUpdate);
|
|
189
|
+
const transformed = await this.validateAndTransformDto(field, updateDto, files, hasMediaFields, isPartialUpdate, isUpdate);
|
|
189
190
|
updateDto = transformed.dto;
|
|
190
191
|
hasMediaFields = transformed.hasMediaFields;
|
|
191
192
|
}
|
|
@@ -257,8 +258,8 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
|
|
|
257
258
|
}
|
|
258
259
|
}
|
|
259
260
|
|
|
260
|
-
private fieldCrudManager(fieldMetadata: FieldMetadata, entityManager: EntityManager, isPartialUpdate: boolean = false): FieldCrudManager {
|
|
261
|
-
const commonOptions = { required: fieldMetadata.required && !isPartialUpdate, fieldName: fieldMetadata.name };
|
|
261
|
+
private fieldCrudManager(fieldMetadata: FieldMetadata, entityManager: EntityManager, isPartialUpdate: boolean = false, isUpdate: boolean = false): FieldCrudManager {
|
|
262
|
+
const commonOptions = { required: fieldMetadata.required && !isPartialUpdate, fieldName: fieldMetadata.name, isUpdate};
|
|
262
263
|
switch (fieldMetadata.type) {
|
|
263
264
|
case SolidFieldType.shortText: {
|
|
264
265
|
const options = { ...commonOptions, length: fieldMetadata.max, regexPattern: fieldMetadata.regexPattern };
|