@solidstarters/solid-core 1.2.21 → 1.2.23

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.
Files changed (77) hide show
  1. package/dist/controllers/model-metadata.controller.d.ts +4 -0
  2. package/dist/controllers/model-metadata.controller.d.ts.map +1 -1
  3. package/dist/controllers/model-metadata.controller.js +12 -0
  4. package/dist/controllers/model-metadata.controller.js.map +1 -1
  5. package/dist/controllers/test.controller.d.ts.map +1 -1
  6. package/dist/controllers/test.controller.js +2 -2
  7. package/dist/controllers/test.controller.js.map +1 -1
  8. package/dist/dtos/basic-filters.dto.d.ts +5 -2
  9. package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
  10. package/dist/dtos/basic-filters.dto.js +13 -9
  11. package/dist/dtos/basic-filters.dto.js.map +1 -1
  12. package/dist/dtos/create-user.dto.d.ts.map +1 -1
  13. package/dist/dtos/create-user.dto.js +2 -2
  14. package/dist/dtos/create-user.dto.js.map +1 -1
  15. package/dist/helpers/schematic.service.js +1 -1
  16. package/dist/helpers/schematic.service.js.map +1 -1
  17. package/dist/index.d.ts +0 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +0 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/jobs/queue-test-subscriber.service.d.ts +1 -0
  22. package/dist/jobs/queue-test-subscriber.service.d.ts.map +1 -1
  23. package/dist/jobs/queue-test-subscriber.service.js +5 -3
  24. package/dist/jobs/queue-test-subscriber.service.js.map +1 -1
  25. package/dist/seeders/module-metadata-seeder.service.d.ts.map +1 -1
  26. package/dist/seeders/module-metadata-seeder.service.js +31 -24
  27. package/dist/seeders/module-metadata-seeder.service.js.map +1 -1
  28. package/dist/seeders/seed-data/solid-core-metadata.json +6 -5
  29. package/dist/services/crud-helper.service.d.ts.map +1 -1
  30. package/dist/services/crud-helper.service.js +6 -4
  31. package/dist/services/crud-helper.service.js.map +1 -1
  32. package/dist/services/field-metadata.service.d.ts.map +1 -1
  33. package/dist/services/field-metadata.service.js +40 -7
  34. package/dist/services/field-metadata.service.js.map +1 -1
  35. package/dist/services/mediaStorageProviders/file-storage-provider.js +1 -1
  36. package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
  37. package/dist/services/model-metadata.service.d.ts +4 -0
  38. package/dist/services/model-metadata.service.d.ts.map +1 -1
  39. package/dist/services/model-metadata.service.js +48 -7
  40. package/dist/services/model-metadata.service.js.map +1 -1
  41. package/dist/services/module-metadata.service.d.ts.map +1 -1
  42. package/dist/services/module-metadata.service.js +4 -4
  43. package/dist/services/module-metadata.service.js.map +1 -1
  44. package/dist/services/solid-introspect.service.d.ts.map +1 -1
  45. package/dist/services/solid-introspect.service.js +9 -1
  46. package/dist/services/solid-introspect.service.js.map +1 -1
  47. package/dist/services/view-metadata.service.d.ts +1 -0
  48. package/dist/services/view-metadata.service.d.ts.map +1 -1
  49. package/dist/services/view-metadata.service.js +9 -0
  50. package/dist/services/view-metadata.service.js.map +1 -1
  51. package/dist/subscribers/softDeleteAwareEventSubscriber.subscriber.d.ts.map +1 -1
  52. package/dist/subscribers/softDeleteAwareEventSubscriber.subscriber.js +1 -1
  53. package/dist/subscribers/softDeleteAwareEventSubscriber.subscriber.js.map +1 -1
  54. package/dist/tsconfig.tsbuildinfo +1 -1
  55. package/package.json +1 -1
  56. package/src/controllers/model-metadata.controller.ts +6 -0
  57. package/src/controllers/test.controller.ts +4 -2
  58. package/src/dtos/basic-filters.dto.ts +11 -7
  59. package/src/dtos/create-user.dto.ts +1 -1
  60. package/src/helpers/schematic.service.ts +1 -1
  61. package/src/index.ts +0 -1
  62. package/src/jobs/queue-test-subscriber.service.ts +4 -2
  63. package/src/seeders/module-metadata-seeder.service.ts +38 -31
  64. package/src/seeders/seed-data/solid-core-metadata.json +6 -5
  65. package/src/services/crud-helper.service.ts +8 -6
  66. package/src/services/field-metadata.service.ts +42 -13
  67. package/src/services/mediaStorageProviders/file-storage-provider.ts +1 -1
  68. package/src/services/model-metadata.service.ts +174 -120
  69. package/src/services/module-metadata.service.ts +8 -4
  70. package/src/services/solid-introspect.service.ts +17 -15
  71. package/src/services/view-metadata.service.ts +13 -0
  72. package/src/subscribers/softDeleteAwareEventSubscriber.subscriber.ts +2 -1
  73. package/dist/commands/basic.command.d.ts +0 -19
  74. package/dist/commands/basic.command.d.ts.map +0 -1
  75. package/dist/commands/basic.command.js +0 -79
  76. package/dist/commands/basic.command.js.map +0 -1
  77. package/src/commands/basic.command.ts +0 -60
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidstarters/solid-core",
3
- "version": "1.2.21",
3
+ "version": "1.2.23",
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",
@@ -60,6 +60,12 @@ export class ModelMetadataController {
60
60
  return this.modelMetadataService.create(createDto);
61
61
  }
62
62
 
63
+ @Public()
64
+ @Post('/update-user-key')
65
+ updateUserKey(@Body() data: any) {
66
+ return this.modelMetadataService.updateUserKey(data);
67
+ }
68
+
63
69
  @ApiBearerAuth("jwt")
64
70
  @Post(':id/generate-code')
65
71
  generateCode(@Param('id', ParseIntPipe) id: number) {
@@ -27,8 +27,10 @@ export class TestController {
27
27
  @Post('upload')
28
28
  @UseInterceptors(FileInterceptor('file')) // 'file' here is the name of the field in the form
29
29
  uploadFile(@UploadedFile() file: Express.Multer.File, @Body() body: any) {
30
- console.log(file);
31
- console.log(body);
30
+ // console.log(file);
31
+ this.logger.debug(file);
32
+ // console.log(body);
33
+ this.logger.debug(body);
32
34
  return { filename: file.originalname };
33
35
  }
34
36
 
@@ -1,8 +1,12 @@
1
1
 
2
2
  import { ApiProperty } from "@nestjs/swagger";
3
- import { IsOptional } from "class-validator";
3
+ import { IsEnum, IsOptional } from "class-validator";
4
4
  import { PaginationQueryDto } from "./pagination-query.dto";
5
5
 
6
+ export enum SoftDeleteFilter {
7
+ INCLUSIVE = "inclusive",
8
+ EXCLUSIVE = "exclusive",
9
+ }
6
10
 
7
11
  export class BasicFilterDto extends PaginationQueryDto {
8
12
 
@@ -34,12 +38,12 @@ export class BasicFilterDto extends PaginationQueryDto {
34
38
  // readonly filters: any[];
35
39
 
36
40
  @IsOptional()
37
- @ApiProperty({ description: "showSoftDeleted" })
38
- readonly showSoftDeleted?: boolean;
39
-
40
- @IsOptional()
41
- @ApiProperty({ description: "showOnlySoftDeleted" })
42
- readonly showOnlySoftDeleted?: boolean;
41
+ @IsEnum(SoftDeleteFilter)
42
+ @ApiProperty({
43
+ description: "showSoftDeleted",
44
+ enum: SoftDeleteFilter,
45
+ })
46
+ readonly showSoftDeleted?: SoftDeleteFilter;
43
47
 
44
48
  @IsOptional()
45
49
  @ApiProperty({ description: "populateGroup" })
@@ -29,7 +29,7 @@ export class CreateUserDto {
29
29
 
30
30
  @IsOptional()
31
31
  @IsBoolean()
32
- forcePasswordChange: boolean = true;
32
+ forcePasswordChange: boolean = false;
33
33
 
34
34
  @IsNotEmpty()
35
35
  @IsString()
@@ -82,7 +82,7 @@ export class SchematicService {
82
82
  // console.log('moduleOptions', moduleOptions);
83
83
  const schematicCommand = ` ${baseCommand} --module=${moduleOptions.module}`;
84
84
  // console.log('schematicCommand', schematicCommand);
85
- this.logger.log('schematicCommand', schematicCommand);
85
+ this.logger.debug('schematicCommand', schematicCommand);
86
86
  return schematicCommand;
87
87
  } else {
88
88
  throw new Error('Schematic command not supported.');
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- export * from './commands/basic.command'
2
1
  export * from './commands/helper'
3
2
  export * from './commands/refresh-model.command'
4
3
  export * from './commands/refresh-module.command'
@@ -1,4 +1,4 @@
1
- import { Injectable } from '@nestjs/common';
1
+ import { Injectable, Logger } from '@nestjs/common';
2
2
 
3
3
  import { RabbitMqSubscriber } from 'src/services/rabbitmq-subscriber.service';
4
4
  import { QueueMessage } from 'src/interfaces/mq';
@@ -9,6 +9,7 @@ import { QueuesModuleOptions } from "../interfaces";
9
9
 
10
10
  @Injectable()
11
11
  export class TestQueueSubscriber extends RabbitMqSubscriber<any> {
12
+ private readonly testQueueLogger = new Logger(TestQueueSubscriber.name);
12
13
  constructor(
13
14
  readonly mqMessageService: MqMessageService,
14
15
  readonly mqMessageQueueService: MqMessageQueueService,
@@ -23,6 +24,7 @@ export class TestQueueSubscriber extends RabbitMqSubscriber<any> {
23
24
  }
24
25
 
25
26
  subscribe(message: QueueMessage<any>) {
26
- console.log(`Received message ${JSON.stringify(message)}`);
27
+ // console.log(`Received message ${JSON.stringify(message)}`);
28
+ this.testQueueLogger.debug(`Received message: ${JSON.stringify(message)}`);
27
29
  }
28
30
  }
@@ -88,9 +88,11 @@ export class ModuleMetadataSeederService {
88
88
 
89
89
  // Run the permissions seeder.
90
90
  // await this.permissionsSeederService.seed();
91
+ this.logger.log(`Seeding permissions`);
91
92
  await this.seedPermissions();
92
93
 
93
94
  // TODO: move this also the main loop processing. Generate the media storage providers required by default
95
+ this.logger.log(`Seeding media storage providers`);
94
96
  await this.mediaStorageProviderSeederService.seed();
95
97
 
96
98
  // Read the module metadata from a file specified in the .env
@@ -105,8 +107,9 @@ export class ModuleMetadataSeederService {
105
107
  // ...coreModules.map(module => `src/${module}/seeders/seed-data/${module}-metadata.json`),
106
108
  typedSolidCoreMetadata
107
109
  ];
108
-
110
+ this.logger.debug(`getting dynamics modules`);
109
111
  const enabledModules = getDynamicModuleNames();
112
+ this.logger.log(`Seeding metadata`);
110
113
 
111
114
  for (let i = 0; i < enabledModules.length; i++) {
112
115
  const enabledModule = enabledModules[i];
@@ -119,8 +122,8 @@ export class ModuleMetadataSeederService {
119
122
  }
120
123
  }
121
124
 
122
- this.logger.log(`Seed data files are: ${seedDataFiles}`);
123
-
125
+ this.logger.debug(`Seed data files are: ${seedDataFiles}`);
126
+ let usersDetail;
124
127
  for (let i = 0; i < seedDataFiles.length; i++) {
125
128
 
126
129
  // Module, model & field handling.
@@ -134,76 +137,77 @@ export class ModuleMetadataSeederService {
134
137
 
135
138
  // Process module metadata first.
136
139
  const moduleMetadata: CreateModuleMetadataDto = overallMetadata.moduleMetadata;
137
- this.logger.log(`[Start] Processing module metadata for ${moduleMetadata.name}`)
140
+ this.logger.debug(`[Start] Processing module metadata for ${moduleMetadata.name}`)
138
141
  await this.seedModuleModelFields(moduleMetadata);
139
- this.logger.log(`[End] Processing module metadata for ${moduleMetadata.name}`)
142
+ this.logger.debug(`[End] Processing module metadata for ${moduleMetadata.name}`)
140
143
 
141
144
  // Media Storage provider templates
142
- this.logger.log(`[Start] Processing Media Storage Provider for ${moduleMetadata.name}`);
145
+ this.logger.debug(`[Start] Processing Media Storage Provider for ${moduleMetadata.name}`);
143
146
  const mediaStorageProviders = overallMetadata.mediaStorageProviders;
144
147
  await this.seedMediaStorageProviders(mediaStorageProviders);
145
- this.logger.log(`[End] Processing Media Storage Provider for ${moduleMetadata.name}`);
148
+ this.logger.debug(`[End] Processing Media Storage Provider for ${moduleMetadata.name}`);
146
149
 
147
150
  // TODO: Custom role handling
148
- this.logger.log(`[End] Processing roles for ${moduleMetadata.name}`)
151
+ this.logger.debug(`[End] Processing roles for ${moduleMetadata.name}`)
149
152
  const roles = overallMetadata.roles;
150
153
  await this.roleService.createRolesIfNotExists(roles);
151
- this.logger.log(`[End] Processing roles for ${moduleMetadata.name}`)
154
+ this.logger.debug(`[End] Processing roles for ${moduleMetadata.name}`)
152
155
 
153
156
  // Custom user handling
154
- this.logger.log(`[Start] Processing users for ${moduleMetadata.name}`);
157
+ this.logger.debug(`[Start] Processing users for ${moduleMetadata.name}`);
155
158
  const users = overallMetadata.users;
159
+ usersDetail = users;
156
160
  await this.seedUsers(users);
157
- this.logger.log(`[End] Processing users for ${moduleMetadata.name}`)
161
+ this.logger.debug(`[End] Processing users for ${moduleMetadata.name}`)
158
162
 
159
163
  // Application Module View handling
160
- this.logger.log(`[Start] Processing views for ${moduleMetadata.name}`);
164
+ this.logger.debug(`[Start] Processing views for ${moduleMetadata.name}`);
161
165
  const views = overallMetadata.views;
162
166
  await this.seedViews(views);
163
- this.logger.log(`[End] Processing views for ${moduleMetadata.name}`)
167
+ this.logger.debug(`[End] Processing views for ${moduleMetadata.name}`)
164
168
 
165
169
  // Application Module Action handling
166
- this.logger.log(`[Start] Processing actions for ${moduleMetadata.name}`);
170
+ this.logger.debug(`[Start] Processing actions for ${moduleMetadata.name}`);
167
171
  const actions = overallMetadata.actions;
168
172
  await this.seedActions(actions);
169
- this.logger.log(`[End] Processing actions for ${moduleMetadata.name}`)
173
+ this.logger.debug(`[End] Processing actions for ${moduleMetadata.name}`)
170
174
 
171
175
  // Application Module Menu handling
172
- this.logger.log(`[Start] Processing menus for ${moduleMetadata.name}`);
176
+ this.logger.debug(`[Start] Processing menus for ${moduleMetadata.name}`);
173
177
  const menus = overallMetadata.menus;
174
178
  await this.seedMenus(menus);
175
- this.logger.log(`[End] Processing menus for ${moduleMetadata.name}`)
179
+ this.logger.debug(`[End] Processing menus for ${moduleMetadata.name}`)
176
180
 
177
181
  // Email templates
178
- this.logger.log(`[Start] Processing email templates for ${moduleMetadata.name}`);
182
+ this.logger.debug(`[Start] Processing email templates for ${moduleMetadata.name}`);
179
183
  const emailTemplates: CreateEmailTemplateDto[] = overallMetadata.emailTemplates;
180
184
  await this.seedEmailTemplates(emailTemplates);
181
- this.logger.log(`[End] Processing email templates for ${moduleMetadata.name}`);
185
+ this.logger.debug(`[End] Processing email templates for ${moduleMetadata.name}`);
182
186
 
183
187
  // Sms templates
184
- this.logger.log(`[Start] Processing sms templates for ${moduleMetadata.name}`);
188
+ this.logger.debug(`[Start] Processing sms templates for ${moduleMetadata.name}`);
185
189
  const smsTemplates: CreateSmsTemplateDto[] = overallMetadata.smsTemplates;
186
190
  await this.seedSmsTemplates(smsTemplates);
187
- this.logger.log(`[End] Processing sms templates for ${moduleMetadata.name}`);
191
+ this.logger.debug(`[End] Processing sms templates for ${moduleMetadata.name}`);
188
192
 
189
193
  // Sms templates
190
- this.logger.log(`[Start] Processing settings for ${moduleMetadata.name}`);
194
+ this.logger.debug(`[Start] Processing settings for ${moduleMetadata.name}`);
191
195
  await this.seedSettings(settingsSeederData);
192
- this.logger.log(`[End] Processing settings for ${moduleMetadata.name}`);
196
+ this.logger.debug(`[End] Processing settings for ${moduleMetadata.name}`);
193
197
 
194
- this.logger.log(`[End] module seed data: ${overallMetadata}`);
198
+ this.logger.debug(`[End] module seed data: ${overallMetadata}`);
195
199
 
196
200
  }
197
201
 
198
202
  // Post seed data file processing.
199
203
 
200
204
  // 1. Give all permissions to the Admin role.
201
- this.logger.log(`About to add all permissions to the Admin role`);
205
+ this.logger.debug(`About to add all permissions to the Admin role`);
202
206
  await this.roleService.addAllPermissionsToRole("Admin");
203
207
  // 2. Give wrapSettings permissions to the Public role.
204
208
  await this.roleService.addPermissionToRole('Public', 'SettingController.wrapSettings');
205
209
  this.logger.log(`All Seeders finished`);
206
-
210
+ this.logger.log(`Newly created username is: ${usersDetail?.length > 0 ? usersDetail[0]?.username : ''} and password is ${usersDetail?.length > 0 ? usersDetail[0]?.password : ''}`);
207
211
  }
208
212
 
209
213
 
@@ -300,16 +304,16 @@ export class ModuleMetadataSeederService {
300
304
  if (smsTemplate.body) {
301
305
  // const smsTemplateFilePath = path.join(process.cwd(), smsTemplate.body);
302
306
  // smsTemplate.body = fs.readFileSync(smsTemplateFilePath, 'utf-8').toString()
303
-
307
+
304
308
  const modulePath = path.dirname(require.resolve('@solidstarters/solid-core'));
305
309
 
306
310
  // Resolve the `src` folder
307
311
  const seedDataPath = path.join(modulePath, '../src/seeders/seed-data/sms-templates');
308
-
312
+
309
313
  // Example usage
310
314
  const filePath = path.join(seedDataPath, smsTemplate.body);
311
-
312
-
315
+
316
+
313
317
  smsTemplate.body = fs.readFileSync(filePath, 'utf-8').toString();
314
318
 
315
319
  }
@@ -372,7 +376,10 @@ export class ModuleMetadataSeederService {
372
376
 
373
377
  viewData['module'] = await this.moduleMetadataService.findOneByUserKey(viewData.moduleUserKey);
374
378
  viewData['model'] = await this.modelMetadataService.findOneByUserKey(viewData.modelUserKey);
375
- await this.solidViewService.upsert(viewData);
379
+ // await this.solidViewService.upsert(viewData);
380
+ // First check if module already exists using name
381
+ await this.solidViewService.createIfNotPresent(viewData);
382
+
376
383
  }
377
384
  }
378
385
 
@@ -2417,7 +2417,7 @@
2417
2417
  "username": "admin@example.service.com",
2418
2418
  "email": "admin@example.service.com",
2419
2419
  "password": "Admin@3214$",
2420
- "forcePasswordChange": false,
2420
+ "forcePasswordChange": true,
2421
2421
  "fullName": "Default Admin"
2422
2422
  }
2423
2423
  ],
@@ -2802,7 +2802,7 @@
2802
2802
  {
2803
2803
  "attrs": {
2804
2804
  "className": "pi pi-cog",
2805
- "label": ""
2805
+ "label": "Generate Code"
2806
2806
  },
2807
2807
  "action": {
2808
2808
  "title": "",
@@ -2819,7 +2819,7 @@
2819
2819
  {
2820
2820
  "attrs": {
2821
2821
  "className": "pi pi-cog",
2822
- "label": ""
2822
+ "label": "Generate Code"
2823
2823
  },
2824
2824
  "action": {
2825
2825
  "title": "",
@@ -2987,6 +2987,7 @@
2987
2987
  50
2988
2988
  ],
2989
2989
  "enableGlobalSearch": true,
2990
+ "truncateAfter": 50,
2990
2991
  "create": true,
2991
2992
  "edit": true,
2992
2993
  "delete": true,
@@ -2994,7 +2995,7 @@
2994
2995
  {
2995
2996
  "attrs": {
2996
2997
  "className": "pi pi-cog",
2997
- "label": ""
2998
+ "label": "Generate Code"
2998
2999
  },
2999
3000
  "action": {
3000
3001
  "title": "",
@@ -3011,7 +3012,7 @@
3011
3012
  {
3012
3013
  "attrs": {
3013
3014
  "className": "pi pi-cog",
3014
- "label": ""
3015
+ "label": "Generate Code"
3015
3016
  },
3016
3017
  "action": {
3017
3018
  "title": "",
@@ -149,7 +149,7 @@ export class CrudHelperService {
149
149
  }
150
150
 
151
151
  buildFilterQuery(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string): SelectQueryBuilder<any> { //TODO : Check how to pass a type to SelectQueryBuilder instead of any
152
- let { limit, offset, showSoftDeleted, showOnlySoftDeleted, filters } = basicFilterDto;
152
+ let { limit, offset, showSoftDeleted, filters } = basicFilterDto;
153
153
  const { fields, sort, groupBy, populate = [] } = basicFilterDto;
154
154
 
155
155
  // Normalize the fields, sort, groupBy and populate options i.e (since they can be either a string or an array of strings, when coming from the request)
@@ -197,11 +197,14 @@ export class CrudHelperService {
197
197
  }
198
198
 
199
199
 
200
- // Apply the soft delete options
201
- if (showSoftDeleted || showOnlySoftDeleted) qb.withDeleted(); // Display the soft deleted records default condition
202
- if (showOnlySoftDeleted) { // Add the condition to show only soft deleted records
203
- qb.andWhere(`${entityAlias}.deletedAt IS NOT NULL`);
200
+ if (showSoftDeleted === 'inclusive') {
201
+ qb.withDeleted();
204
202
  }
203
+
204
+ if (showSoftDeleted === 'exclusive') {
205
+ qb.withDeleted();
206
+ qb.where(`${entityAlias}.deletedAt IS NOT NULL`);
207
+ }
205
208
 
206
209
  // Apply the group by options
207
210
  if (normalizedGroupBy && normalizedGroupBy.length) {
@@ -209,7 +212,6 @@ export class CrudHelperService {
209
212
  qb.addGroupBy(`${entityAlias}.${field}`);
210
213
  });
211
214
  }
212
-
213
215
  // Apply the pagination options
214
216
  if (limit) qb.limit(limit);
215
217
  if (offset) qb.offset(offset);
@@ -12,6 +12,7 @@ import { FieldMetadata } from '../entities/field-metadata.entity';
12
12
  import { ModelMetadata } from '../entities/model-metadata.entity';
13
13
  import { ISelectionProviderValues } from '../interfaces';
14
14
  import { CrudHelperService } from './crud-helper.service';
15
+ import { classify } from '@angular-devkit/core/src/utils/strings';
15
16
 
16
17
 
17
18
  @Injectable()
@@ -47,11 +48,12 @@ export class FieldMetadataService {
47
48
  // const {id, createdAt, updatedAt, deletedAt, ...fieldKeys} = field;
48
49
  switch (field.relationType) {
49
50
  case RelationType.manyToOne: {
51
+ const fieldName = field.relationModelFieldName || `${modelName}s`;
50
52
  const inverseField: FieldMetadata = {
51
53
  ...field,
52
- name: field.relationModelFieldName ?? `${modelName}s`,
53
- displayName: `Inverse ${field.displayName}`,
54
- description: `Inverse field for ${field.displayName}`,
54
+ name: fieldName,
55
+ displayName: classify(fieldName),
56
+ description: classify(fieldName),
55
57
  type: SolidFieldType.relation,
56
58
  isSystem: field.isSystem,
57
59
  relationType: RelationType.oneToMany,
@@ -71,9 +73,38 @@ export class FieldMetadataService {
71
73
  relationJoinColumnName: null,
72
74
  joinColumnName: null,
73
75
  id : null,
74
- // createdAt: null,
75
- // updatedAt: null,
76
- // deletedAt: null,
76
+ }
77
+
78
+ // Load the inverse field,
79
+ const savedField = await this.saveInverseField(fieldRepository, relationModel, inverseField);
80
+ return savedField;
81
+ }
82
+ case RelationType.oneToMany: {
83
+ const fieldName = field.relationModelFieldName || `${modelName}`;
84
+ const inverseField: FieldMetadata = {
85
+ ...field,
86
+ name: fieldName,
87
+ displayName: classify(fieldName),
88
+ description: classify(fieldName),
89
+ type: SolidFieldType.relation,
90
+ isSystem: field.isSystem,
91
+ relationType: RelationType.manyToOne,
92
+ relationModelSingularName: modelName,
93
+ relationCreateInverse: true,
94
+ relationCascade: null,
95
+ relationModelModuleName: moduleName,
96
+ relationModelFieldName: field.name,
97
+ required: false,
98
+ unique: false,
99
+ index: false,
100
+ private: false,
101
+ encrypt: false,
102
+ model: relationModel,
103
+ columnName:null,
104
+ relationJoinTableName: null,
105
+ relationJoinColumnName: null,
106
+ joinColumnName: null,
107
+ id : null,
77
108
  }
78
109
 
79
110
  // Load the inverse field,
@@ -81,18 +112,19 @@ export class FieldMetadataService {
81
112
  return savedField;
82
113
  }
83
114
  case RelationType.manyTomany: {
115
+ const fieldName = field.relationModelFieldName;
84
116
  // Logic to create a manyToMany inverse field definition
85
117
  const inverseFieldManyToMany: FieldMetadata = {
86
118
  ...field,
87
- name: field.relationModelFieldName,
88
- displayName: `Inverse ${field.displayName}`,
89
- description: `Inverse field for ${field.displayName}`,
119
+ name: fieldName,
120
+ displayName: classify(fieldName),
121
+ description: classify(fieldName),
90
122
  type: SolidFieldType.relation,
91
123
  isSystem: field.isSystem,
92
124
  relationType: RelationType.manyTomany,
93
125
  relationModelSingularName: modelName,
94
126
  relationCreateInverse: true,
95
- relationCascade: field.relationCascade,
127
+ relationCascade: null,
96
128
  relationModelModuleName: moduleName,
97
129
  relationModelFieldName: field.name,
98
130
  required: false,
@@ -107,9 +139,6 @@ export class FieldMetadataService {
107
139
  joinColumnName: null,
108
140
  isRelationManyToManyOwner: false,
109
141
  id : null,
110
- // createdAt: null,
111
- // updatedAt: null,
112
- // deletedAt: null,
113
142
  }
114
143
  const savedField = await this.saveInverseField(fieldRepository, relationModel, inverseFieldManyToMany);
115
144
  return savedField;
@@ -67,7 +67,7 @@ export class FileStorageProvider<T> implements MediaStorageProvider<T> {
67
67
  }
68
68
 
69
69
  private getFullFilePath(fileName: string): string {
70
- return `${this.configService.get('app-builder.fileStorageDir')}/${fileName}`;
70
+ return `${process.env.BASE_URL}/${this.configService.get('app-builder.fileStorageDir')}/${fileName}`;
71
71
  }
72
72
 
73
73
  private getFileName(file: Express.Multer.File): string {