@solidstarters/solid-core 1.2.17 → 1.2.19

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.
@@ -0,0 +1,43 @@
1
+ // many-to-one field
2
+ // {
3
+ // "name": "module",
4
+ // "displayName": "Module",
5
+ // "type": "relation",
6
+ // "required": true,
7
+ // "unique": false,
8
+ // "index": true,
9
+ // "private": false,
10
+ // "encrypt": false,
11
+ // "relationType": "many-to-one",
12
+ // "relationModelSingularName": "moduleMetadata",
13
+ // "relationCreateInverse": true,
14
+ // "relationCascade": "set null",
15
+ // "relationModelModuleName": "solid-core",
16
+ // "isSystem": true
17
+ // },
18
+
19
+ // one-to-many field
20
+ // {
21
+ // "name": field.relationModelField,
22
+ // Logic to create a oneToMany field definition
23
+ // return [
24
+ // "name",
25
+ // "displayName",
26
+ // "description",
27
+ // "type",
28
+ // "ormType",
29
+ // "isSystem",
30
+ // "relationType",
31
+ // "relationModelFieldName",
32
+ // "relationCreateInverse",
33
+ // "relationModelSingularName",
34
+ // "relationModelModuleName",
35
+ // "required",
36
+ // "unique",
37
+ // "index",
38
+ // "private",
39
+ // "encrypt",
40
+ // "encryptionType",
41
+ // "decryptWhen",
42
+ // "columnName"
43
+ // ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidstarters/solid-core",
3
- "version": "1.2.17",
3
+ "version": "1.2.19",
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",
@@ -256,8 +256,6 @@ export class CreateFieldMetadataDto {
256
256
  @ApiProperty({ description: 'for text fields, this is length. for numeric fields, this is the range of values allowed. Only for type=shortText,longText,richText,json,int,decimal,date,dateTime,time', })
257
257
  @IsInt()
258
258
  @IsOptional()
259
- @Transform(({ obj }) => obj.length ?? undefined) // Automatically sets max = length
260
- @ValidateIf((obj) => obj.length !== undefined) // Only validate if length is provided
261
259
  max: number;
262
260
 
263
261
  @ApiProperty({ description: 'for text fields, this is length. for numeric fields, this is the range of values allowed. Only for type=shortText,longText,richText,json,int,decimal,date,dateTime,time', })
@@ -387,4 +385,19 @@ export class CreateFieldMetadataDto {
387
385
  @IsOptional()
388
386
  @IsBoolean()
389
387
  readonly isUserKey: boolean
388
+
389
+ @ApiProperty({ description: 'Relation Join Column Name of Field', })
390
+ @IsString()
391
+ @IsOptional()
392
+ relationJoinColumnName: string
393
+
394
+ @ApiProperty({ description: 'Join Column Name of Field', })
395
+ @IsString()
396
+ @IsOptional()
397
+ joinColumnName: string
398
+
399
+ @ApiProperty({ description: 'Relation Join Table Name of Field', })
400
+ @IsString()
401
+ @IsOptional()
402
+ relationJoinTableName: string
390
403
  }
@@ -137,4 +137,13 @@ export class FieldMetadata extends CommonEntity {
137
137
 
138
138
  @Column({ name: "isUserKey", default: false })
139
139
  isUserKey: boolean;
140
+
141
+ @Column({ name: 'relation_join_column_name', nullable: true })
142
+ relationJoinColumnName: string;
143
+
144
+ @Column({ name: 'join_column_name', nullable: true })
145
+ joinColumnName: string;
146
+
147
+ @Column({ name: 'relation_join_table_name', nullable: true })
148
+ relationJoinTableName: string;
140
149
  }
@@ -843,6 +843,45 @@
843
843
  "encrypt": false,
844
844
  "columnName": "required",
845
845
  "isSystem": true
846
+ },
847
+ {
848
+ "name": "relationJoinColumnName",
849
+ "displayName": "Relation Join Column Name",
850
+ "type": "shortText",
851
+ "ormType": "varchar",
852
+ "required": false,
853
+ "unique": false,
854
+ "index": false,
855
+ "private": false,
856
+ "encrypt": false,
857
+ "columnName": "relation_join_column_name",
858
+ "isSystem": true
859
+ },
860
+ {
861
+ "name": "joinColumnName",
862
+ "displayName": "Join Column Name",
863
+ "type": "shortText",
864
+ "ormType": "varchar",
865
+ "required": false,
866
+ "unique": false,
867
+ "index": false,
868
+ "private": false,
869
+ "encrypt": false,
870
+ "columnName": "join_column_name",
871
+ "isSystem": true
872
+ },
873
+ {
874
+ "name": "relationJoinTableName",
875
+ "displayName": "Relation Join Table Name",
876
+ "type": "shortText",
877
+ "ormType": "varchar",
878
+ "required": false,
879
+ "unique": false,
880
+ "index": false,
881
+ "private": false,
882
+ "encrypt": false,
883
+ "columnName": "relation_join_table_name",
884
+ "isSystem": true
846
885
  }
847
886
  ]
848
887
  },
@@ -1311,7 +1350,7 @@
1311
1350
  "name": "action",
1312
1351
  "displayName": "Action",
1313
1352
  "type": "relation",
1314
- "required": true,
1353
+ "required": false,
1315
1354
  "unique": false,
1316
1355
  "index": true,
1317
1356
  "private": false,
@@ -311,7 +311,7 @@ export class CRUDService<T> { //Add two generic value i.e Person,CreatePersonDto
311
311
  const manyToOneOptions: ManyToOneRelationFieldOptions = {
312
312
  ...commonOptions,
313
313
  relationModelSingularName: fieldMetadata.relationModelSingularName,
314
- modelUserKeyFieldName: fieldMetadata.model.userKeyField.name,
314
+ modelUserKeyFieldName: fieldMetadata.model.userKeyField?.name,
315
315
  modelSingularName: fieldMetadata.model.singularName,
316
316
  entityManager,
317
317
  }
@@ -583,7 +583,10 @@ export class FieldMetadataService {
583
583
  "encrypt",
584
584
  "encryptionType",
585
585
  "decryptWhen",
586
- "columnName"
586
+ "columnName",
587
+ "relationJoinColumnName",
588
+ "joinColumnName",
589
+ "relationJoinTableName"
587
590
  ];
588
591
 
589
592
  case SolidFieldType.mediaSingle:
@@ -184,8 +184,8 @@ export class ModelMetadataService {
184
184
  if (fieldMetadata.isUserKey) {
185
185
  userKeyField = affectedField;
186
186
  }
187
- listViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}`, label: `${affectedField.displayName}`, sortable: true, filterable: true } })
188
- formViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}`, label: `${affectedField.displayName}` } })
187
+ listViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}`, sortable: true, filterable: true } })
188
+ formViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}` } })
189
189
 
190
190
  }
191
191
 
@@ -324,7 +324,7 @@ export class ModelMetadataService {
324
324
  fields: []
325
325
  }
326
326
 
327
- const listViewLayoutFields = [{ type: "field", attrs: { name: `id`, label: `Id`, sortable: true, filterable: true } }];
327
+ const listViewLayoutFields = [{ type: "field", attrs: { name: `id`, sortable: true, filterable: true } }];
328
328
  const formViewLayoutFields = [];
329
329
 
330
330
  for (let i = 0; i < model.fields.length; i++) {
@@ -339,8 +339,8 @@ export class ModelMetadataService {
339
339
  fieldObject[requiredField] = field[requiredField];
340
340
  });
341
341
  modelMetaData.fields.push(fieldObject);
342
- listViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}`, label: `${field.displayName}`, sortable: true, filterable: true } })
343
- formViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}`, label: `${field.displayName}` } })
342
+ listViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}`, sortable: true, filterable: true } })
343
+ formViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}` } })
344
344
 
345
345
  }
346
346
  }
@@ -681,20 +681,24 @@ export class ModelMetadataService {
681
681
 
682
682
  async generateCode(options: CodeGenerationOptions): Promise<string> {
683
683
  const query = {
684
- populate: ["module", "fields"]
684
+ populate: ["module", "fields"]
685
685
  };
686
- const model = options.modelId ? await this.findOne(options.modelId, query) : await this.findOneByUserKey(options.modelUserKey, query.populate);
687
- options.fieldIdsForRemoval = model.fields.filter((field) => field.isMarkedForRemoval).map((field) => field.id);
686
+
687
+ const model = options.modelId
688
+ ? await this.findOne(options.modelId, query)
689
+ : await this.findOneByUserKey(options.modelUserKey, query.populate);
690
+
691
+ options.fieldIdsForRemoval = model.fields
692
+ .filter(field => field.isMarkedForRemoval)
693
+ .map(field => field.id);
688
694
 
689
695
  const refreshModelCodeOutput = await this.generateModelCode(options);
690
696
  const removeFieldCodeOuput = await this.generateRemoveFieldsCode(options);
691
697
 
692
- // Extract listViewLayout and formViewLayout from model fields
693
698
  const listViewLayout = model.fields.map(field => ({
694
699
  type: "field",
695
700
  attrs: {
696
701
  name: `${field.name}`,
697
- label: `${field.displayName}`,
698
702
  sortable: true,
699
703
  filterable: true
700
704
  }
@@ -703,17 +707,18 @@ export class ModelMetadataService {
703
707
  const formViewLayout = model.fields.map(field => ({
704
708
  type: "field",
705
709
  attrs: {
706
- name: `${field.name}`,
707
- label: `${field.displayName}`
710
+ name: `${field.name}`
708
711
  }
709
712
  }));
710
713
 
711
- // Fetch module data
712
714
  const resolvedModule = await this.dataSource.getRepository(ModuleMetadata).findOne({
713
715
  where: { id: model.module.id }
714
716
  });
715
717
 
716
- // Generate model views
718
+ const viewRepo = this.dataSource.getRepository(ViewMetadata);
719
+ const actionRepo = this.dataSource.getRepository(ActionMetadata);
720
+ const menuRepo = this.dataSource.getRepository(MenuItemMetadata);
721
+
717
722
  const modelViews = [
718
723
  {
719
724
  name: `${model.singularName}-list-view`,
@@ -733,7 +738,7 @@ export class ModelMetadataService {
733
738
  delete: true
734
739
  },
735
740
  children: listViewLayout
736
- }, null, 2)
741
+ }, null, 3)
737
742
  },
738
743
  {
739
744
  name: `${model.singularName}-form-view`,
@@ -764,27 +769,27 @@ export class ModelMetadataService {
764
769
  ]
765
770
  }
766
771
  ]
767
- }, null, 2)
772
+ }, null, 3)
768
773
  }
769
774
  ];
770
775
 
771
- // Save views
772
- const viewRepo = this.dataSource.getRepository(ViewMetadata);
773
776
  for (const view of modelViews) {
774
- const createdView = viewRepo.create(view);
775
- await viewRepo.save(createdView);
777
+ const existingView = await viewRepo.findOne({ where: { name: view.name } });
778
+
779
+ if (!existingView) {
780
+ const createdView = viewRepo.create(view);
781
+ await viewRepo.save(createdView);
782
+ }
776
783
  }
777
784
 
778
- // Fetch the list view
779
- const view = await viewRepo.findOneBy({ name: `${model.singularName}-list-view` });
785
+ let view = await viewRepo.findOne({ where: { name: `${model.singularName}-list-view` } });
780
786
 
781
- // Generate action
782
- const action = {
787
+ const actionData = {
783
788
  displayName: `${model.displayName} List View`,
784
789
  name: `${model.singularName}-list-view`,
785
790
  type: "solid",
786
- domain: "",
787
- context: "",
791
+ domain: "" as any,
792
+ context: "" as any,
788
793
  customComponent: `/admin/address-master/${model.singularName}/all`,
789
794
  customIsModal: true,
790
795
  serverEndpoint: "",
@@ -793,33 +798,35 @@ export class ModelMetadataService {
793
798
  model: model
794
799
  };
795
800
 
796
- // Save action
797
- const actionRepo = this.dataSource.getRepository(ActionMetadata);
798
- const createdAction = actionRepo.create(action);
799
- const newAction = await actionRepo.save(createdAction);
801
+ let existingAction = await actionRepo.findOne({ where: { name: actionData.name } });
802
+
803
+ if (!existingAction) {
804
+ const createdAction = actionRepo.create(actionData);
805
+ existingAction = await actionRepo.save(createdAction);
806
+ }
800
807
 
801
- // Fetch Admin Role
802
808
  const adminRole = await this.roleService.findRoleByName('Admin');
803
809
 
804
- // Generate menu
805
- const menu = {
810
+ const menuData = {
806
811
  displayName: `${model.displayName}`,
807
- name: `${model.singularName}`,
812
+ name: `${model.singularName}-menu-item`,
808
813
  sequenceNumber: 1,
809
- action: newAction,
814
+ action: existingAction,
810
815
  module: resolvedModule,
811
816
  roles: [adminRole],
812
817
  parentMenuItemUserKey: ""
813
818
  };
814
819
 
815
- // Save menu
816
- const menuRepo = this.dataSource.getRepository(MenuItemMetadata);
817
- const createdMenu = menuRepo.create(menu);
818
- await menuRepo.save(createdMenu);
820
+ let existingMenu = await menuRepo.findOne({ where: { name: menuData.name } });
821
+
822
+ if (!existingMenu) {
823
+ const createdMenu = menuRepo.create(menuData);
824
+ await menuRepo.save(createdMenu);
825
+ }
826
+
819
827
  return `${removeFieldCodeOuput} \n ${refreshModelCodeOutput}`;
820
828
  }
821
829
 
822
-
823
830
  async generateRemoveFieldsCode(options: CodeGenerationOptions): Promise<string> {
824
831
  if (!options.modelId && !options.modelUserKey) {
825
832
  throw new BadRequestException('Model ID or Model Name is required for generating code');