@solidstarters/solid-core 1.2.16 → 1.2.18

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 (28) hide show
  1. package/.vscode/launch.json +21 -0
  2. package/dist/dtos/create-field-metadata.dto.d.ts +3 -0
  3. package/dist/dtos/create-field-metadata.dto.d.ts.map +1 -1
  4. package/dist/dtos/create-field-metadata.dto.js +19 -4
  5. package/dist/dtos/create-field-metadata.dto.js.map +1 -1
  6. package/dist/entities/field-metadata.entity.d.ts +3 -0
  7. package/dist/entities/field-metadata.entity.d.ts.map +1 -1
  8. package/dist/entities/field-metadata.entity.js +13 -1
  9. package/dist/entities/field-metadata.entity.js.map +1 -1
  10. package/dist/helpers/schematic.service.d.ts.map +1 -1
  11. package/dist/helpers/schematic.service.js +2 -1
  12. package/dist/helpers/schematic.service.js.map +1 -1
  13. package/dist/seeders/seed-data/solid-core-metadata.json +42 -3
  14. package/dist/services/field-metadata.service.d.ts.map +1 -1
  15. package/dist/services/field-metadata.service.js +4 -1
  16. package/dist/services/field-metadata.service.js.map +1 -1
  17. package/dist/services/model-metadata.service.d.ts.map +1 -1
  18. package/dist/services/model-metadata.service.js +125 -99
  19. package/dist/services/model-metadata.service.js.map +1 -1
  20. package/dist/tsconfig.tsbuildinfo +1 -1
  21. package/package.json +2 -1
  22. package/src/dtos/create-field-metadata.dto.ts +15 -2
  23. package/src/entities/field-metadata.entity.ts +9 -0
  24. package/src/helpers/schematic.service.ts +2 -1
  25. package/src/seeders/seed-data/solid-core-metadata.json +42 -3
  26. package/src/services/field-metadata.service.ts +4 -1
  27. package/src/services/model-metadata.service.ts +243 -106
  28. package/src/services/1.js +0 -6
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidstarters/solid-core",
3
- "version": "1.2.16",
3
+ "version": "1.2.18",
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",
@@ -43,6 +43,7 @@
43
43
  "class-validator": "^0.14.1",
44
44
  "handlebars": "^4.7.8",
45
45
  "ioredis": "^5.4.1",
46
+ "lodash": "^4.17.21",
46
47
  "luxon": "^3.4.4",
47
48
  "mailgen": "^2.0.28",
48
49
  "mongoose": "^8.7.0",
@@ -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
  }
@@ -1,5 +1,6 @@
1
1
  import { Injectable, Logger } from '@nestjs/common';
2
2
  import { CommandService } from './command.service';
3
+ import { snakeCase } from "lodash";
3
4
 
4
5
  export const ADD_MODULE_COMMAND = 'add-module';
5
6
  export type GenerateModuleOptions = {
@@ -54,7 +55,7 @@ export class SchematicService {
54
55
  // console.log('fieldOptions', fieldOptions);
55
56
  let modelCommand = `${baseCommand} --module=${fieldOptions.module} --model=${fieldOptions.model}`;
56
57
  if (fieldOptions.moduleDisplayName) {
57
- modelCommand += ` --module-display-name=${fieldOptions.moduleDisplayName}`;
58
+ modelCommand += ` --module-display-name=${snakeCase(fieldOptions.moduleDisplayName)}`;
58
59
  }
59
60
 
60
61
  if (fieldOptions.table) {
@@ -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,
@@ -2770,7 +2809,7 @@
2770
2809
  "body": "",
2771
2810
  "confirmBtnLabel": "Generate Code",
2772
2811
  "cancelBtnLabel": "Cancel",
2773
- "customComponent": "core/extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction",
2812
+ "customComponent": "../extension/solid-core/moduleMetadata/list/GenerateModuleCodeRowAction",
2774
2813
  "customComponentIsSystem": true,
2775
2814
  "endpoint": ""
2776
2815
  }
@@ -2962,7 +3001,7 @@
2962
3001
  "body": "",
2963
3002
  "confirmBtnLabel": "Generate Code",
2964
3003
  "cancelBtnLabel": "Cancel",
2965
- "customComponent": "core/extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction",
3004
+ "customComponent": "../extension/solid-core/modelMetadata/list/GenerateModelCodeRowAction",
2966
3005
  "customComponentIsSystem": true,
2967
3006
  "endpoint": ""
2968
3007
  }
@@ -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:
@@ -23,6 +23,7 @@ import { ViewMetadata } from '../entities/view-metadata.entity';
23
23
  import { ActionMetadata } from '../entities/action-metadata.entity';
24
24
  import { MenuItemMetadata } from '../entities/menu-item-metadata.entity';
25
25
  import { RoleMetadataService } from './role-metadata.service';
26
+ import { PermissionMetadataSeederService } from 'src/seeders/permission-metadata-seeder.service';
26
27
 
27
28
  @Injectable()
28
29
  export class ModelMetadataService {
@@ -183,8 +184,8 @@ export class ModelMetadataService {
183
184
  if (fieldMetadata.isUserKey) {
184
185
  userKeyField = affectedField;
185
186
  }
186
- listViewLayout.push({ type: "field", attrs: { name: `${affectedField.name}`, label: `${affectedField.displayName}`, sortable: true, filterable: true } })
187
- 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}` } })
188
189
 
189
190
  }
190
191
 
@@ -195,104 +196,104 @@ export class ModelMetadataService {
195
196
  model = await manager.save(updatedModelMetadataDto);
196
197
  }
197
198
 
198
- const modelViews = [{
199
- name: `${model.singularName}-list-view`,
200
- displayName: `${model.displayName}`,
201
- type: 'list',
202
- context: "{}",
203
- module: resolvedModule,
204
- model: model,
205
- layout: JSON.stringify({
206
- type: "list",
207
- attrs: {
208
- pagination: true,
209
- pageSizeOptions: [
210
- 10,
211
- 25,
212
- 50
213
- ],
214
- enableGlobalSearch: true,
215
- create: true,
216
- edit: true,
217
- delete: true
218
- },
219
- children: listViewLayout
220
- }, null, 2)
221
- },
222
- {
223
- name: `${model.singularName}-form-view`,
224
- displayName: `${model.displayName}`,
225
- type: 'form',
226
- context: "{}",
227
- module: model.module,
228
- model: model,
229
- layout: JSON.stringify(
230
- {
231
- type: "form",
232
- attrs: { name: "form-1", label: `${model.displayName}`, className: "grid" },
233
- children: [
234
- {
235
- type: "sheet",
236
- attrs: { name: "sheet-1" },
237
- children: [
238
- {
239
- type: "row",
240
- attrs: { name: "group-1", label: "", className: "" },
241
- children: [
242
- {
243
- type: "column",
244
- attrs: { name: "group-1", label: "", className: "col-6" },
245
- children: formViewLayout
246
- }
247
- ]
248
- }
249
- ]
250
- }
251
- ]
252
- }, null, 2)
253
- }
254
- ];
255
- const viewRepo = manager.getRepository(ViewMetadata);
256
- for (let j = 0; j < modelViews.length; j++) {
257
- const view = modelViews[j];
258
- const createdView = await viewRepo.create(view);
259
- await viewRepo.save(createdView);
260
- }
261
-
262
- const view = await viewRepo.findOneBy({ name: `${model.singularName}-list-view` });
263
-
264
- const action = {
265
- displayName: `${model.displayName} List View`,
266
- name: `${model.singularName}-list-view`,
267
- type: "solid",
268
- domain: "",
269
- context: "",
270
- customComponent: `/admin/address-master/${model.singularName}/all`,
271
- customIsModal: true,
272
- serverEndpoint: "",
273
- view: view,
274
- module: resolvedModule,
275
- model: model
276
- };
277
- const actionRepo = manager.getRepository(ActionMetadata);
278
- const createdAction = await actionRepo.create(action);
279
- const newAction = await actionRepo.save(createdAction);
280
-
281
- const adminRole = await this.roleService.findRoleByName('Admin');
282
-
283
- const menu = {
284
- displayName: `${model.displayName}`,
285
- name: `${model.singularName}`,
286
- sequenceNumber: 1,
287
- action: newAction,
288
- module: resolvedModule,
289
- roles: [adminRole],
290
- parentMenuItemUserKey: ""
291
- };
292
-
293
- const menuRepo = manager.getRepository(MenuItemMetadata);
294
- const createdMenu = await menuRepo.create(menu);
295
- await menuRepo.save(createdMenu);
199
+ // const modelViews = [{
200
+ // name: `${model.singularName}-list-view`,
201
+ // displayName: `${model.displayName}`,
202
+ // type: 'list',
203
+ // context: "{}",
204
+ // module: resolvedModule,
205
+ // model: model,
206
+ // layout: JSON.stringify({
207
+ // type: "list",
208
+ // attrs: {
209
+ // pagination: true,
210
+ // pageSizeOptions: [
211
+ // 10,
212
+ // 25,
213
+ // 50
214
+ // ],
215
+ // enableGlobalSearch: true,
216
+ // create: true,
217
+ // edit: true,
218
+ // delete: true
219
+ // },
220
+ // children: listViewLayout
221
+ // }, null, 2)
222
+ // },
223
+ // {
224
+ // name: `${model.singularName}-form-view`,
225
+ // displayName: `${model.displayName}`,
226
+ // type: 'form',
227
+ // context: "{}",
228
+ // module: model.module,
229
+ // model: model,
230
+ // layout: JSON.stringify(
231
+ // {
232
+ // type: "form",
233
+ // attrs: { name: "form-1", label: `${model.displayName}`, className: "grid" },
234
+ // children: [
235
+ // {
236
+ // type: "sheet",
237
+ // attrs: { name: "sheet-1" },
238
+ // children: [
239
+ // {
240
+ // type: "row",
241
+ // attrs: { name: "group-1", label: "", className: "" },
242
+ // children: [
243
+ // {
244
+ // type: "column",
245
+ // attrs: { name: "group-1", label: "", className: "col-6" },
246
+ // children: formViewLayout
247
+ // }
248
+ // ]
249
+ // }
250
+ // ]
251
+ // }
252
+ // ]
253
+ // }, null, 2)
254
+ // }
255
+ // ];
256
+ // const viewRepo = manager.getRepository(ViewMetadata);
257
+ // for (let j = 0; j < modelViews.length; j++) {
258
+ // const view = modelViews[j];
259
+ // const createdView = await viewRepo.create(view);
260
+ // await viewRepo.save(createdView);
261
+ // }
262
+
263
+ // const view = await viewRepo.findOneBy({ name: `${model.singularName}-list-view` });
264
+
265
+ // const action = {
266
+ // displayName: `${model.displayName} List View`,
267
+ // name: `${model.singularName}-list-view`,
268
+ // type: "solid",
269
+ // domain: "",
270
+ // context: "",
271
+ // customComponent: `/admin/address-master/${model.singularName}/all`,
272
+ // customIsModal: true,
273
+ // serverEndpoint: "",
274
+ // view: view,
275
+ // module: resolvedModule,
276
+ // model: model
277
+ // };
278
+ // const actionRepo = manager.getRepository(ActionMetadata);
279
+ // const createdAction = await actionRepo.create(action);
280
+ // const newAction = await actionRepo.save(createdAction);
281
+
282
+ // const adminRole = await this.roleService.findRoleByName('Admin');
283
+
284
+ // const menu = {
285
+ // displayName: `${model.displayName}`,
286
+ // name: `${model.singularName}`,
287
+ // sequenceNumber: 1,
288
+ // action: newAction,
289
+ // module: resolvedModule,
290
+ // roles: [adminRole],
291
+ // parentMenuItemUserKey: ""
292
+ // };
293
+
294
+ // const menuRepo = manager.getRepository(MenuItemMetadata);
295
+ // const createdMenu = await menuRepo.create(menu);
296
+ // await menuRepo.save(createdMenu);
296
297
 
297
298
  return model;
298
299
  }
@@ -323,7 +324,7 @@ export class ModelMetadataService {
323
324
  fields: []
324
325
  }
325
326
 
326
- 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 } }];
327
328
  const formViewLayoutFields = [];
328
329
 
329
330
  for (let i = 0; i < model.fields.length; i++) {
@@ -338,8 +339,8 @@ export class ModelMetadataService {
338
339
  fieldObject[requiredField] = field[requiredField];
339
340
  });
340
341
  modelMetaData.fields.push(fieldObject);
341
- listViewLayoutFields.push({ type: "field", attrs: { name: `${field.name}`, label: `${field.displayName}`, sortable: true, filterable: true } })
342
- 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}` } })
343
344
 
344
345
  }
345
346
  }
@@ -680,13 +681,149 @@ export class ModelMetadataService {
680
681
 
681
682
  async generateCode(options: CodeGenerationOptions): Promise<string> {
682
683
  const query = {
683
- populate: ["module", "fields"]
684
+ populate: ["module", "fields"]
684
685
  };
685
- const model = options.modelId ? await this.findOne(options.modelId, query) : await this.findOneByUserKey(options.modelUserKey, query.populate);
686
- 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);
687
694
 
688
695
  const refreshModelCodeOutput = await this.generateModelCode(options);
689
696
  const removeFieldCodeOuput = await this.generateRemoveFieldsCode(options);
697
+
698
+ const listViewLayout = model.fields.map(field => ({
699
+ type: "field",
700
+ attrs: {
701
+ name: `${field.name}`,
702
+ sortable: true,
703
+ filterable: true
704
+ }
705
+ }));
706
+
707
+ const formViewLayout = model.fields.map(field => ({
708
+ type: "field",
709
+ attrs: {
710
+ name: `${field.name}`
711
+ }
712
+ }));
713
+
714
+ const resolvedModule = await this.dataSource.getRepository(ModuleMetadata).findOne({
715
+ where: { id: model.module.id }
716
+ });
717
+
718
+ const viewRepo = this.dataSource.getRepository(ViewMetadata);
719
+ const actionRepo = this.dataSource.getRepository(ActionMetadata);
720
+ const menuRepo = this.dataSource.getRepository(MenuItemMetadata);
721
+
722
+ const modelViews = [
723
+ {
724
+ name: `${model.singularName}-list-view`,
725
+ displayName: `${model.displayName}`,
726
+ type: 'list',
727
+ context: "{}",
728
+ module: resolvedModule,
729
+ model: model,
730
+ layout: JSON.stringify({
731
+ type: "list",
732
+ attrs: {
733
+ pagination: true,
734
+ pageSizeOptions: [10, 25, 50],
735
+ enableGlobalSearch: true,
736
+ create: true,
737
+ edit: true,
738
+ delete: true
739
+ },
740
+ children: listViewLayout
741
+ }, null, 3)
742
+ },
743
+ {
744
+ name: `${model.singularName}-form-view`,
745
+ displayName: `${model.displayName}`,
746
+ type: 'form',
747
+ context: "{}",
748
+ module: resolvedModule,
749
+ model: model,
750
+ layout: JSON.stringify({
751
+ type: "form",
752
+ attrs: { name: "form-1", label: `${model.displayName}`, className: "grid" },
753
+ children: [
754
+ {
755
+ type: "sheet",
756
+ attrs: { name: "sheet-1" },
757
+ children: [
758
+ {
759
+ type: "row",
760
+ attrs: { name: "group-1", label: "", className: "" },
761
+ children: [
762
+ {
763
+ type: "column",
764
+ attrs: { name: "group-1", label: "", className: "col-6" },
765
+ children: formViewLayout
766
+ }
767
+ ]
768
+ }
769
+ ]
770
+ }
771
+ ]
772
+ }, null, 3)
773
+ }
774
+ ];
775
+
776
+ for (const view of modelViews) {
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
+ }
783
+ }
784
+
785
+ let view = await viewRepo.findOne({ where: { name: `${model.singularName}-list-view` } });
786
+
787
+ const actionData = {
788
+ displayName: `${model.displayName} List View`,
789
+ name: `${model.singularName}-list-view`,
790
+ type: "solid",
791
+ domain: "" as any,
792
+ context: "" as any,
793
+ customComponent: `/admin/address-master/${model.singularName}/all`,
794
+ customIsModal: true,
795
+ serverEndpoint: "",
796
+ view: view,
797
+ module: resolvedModule,
798
+ model: model
799
+ };
800
+
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
+ }
807
+
808
+ const adminRole = await this.roleService.findRoleByName('Admin');
809
+
810
+ const menuData = {
811
+ displayName: `${model.displayName}`,
812
+ name: `${model.singularName}-menu-item`,
813
+ sequenceNumber: 1,
814
+ action: existingAction,
815
+ module: resolvedModule,
816
+ roles: [adminRole],
817
+ parentMenuItemUserKey: ""
818
+ };
819
+
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
+
690
827
  return `${removeFieldCodeOuput} \n ${refreshModelCodeOutput}`;
691
828
  }
692
829
 
package/src/services/1.js DELETED
@@ -1,6 +0,0 @@
1
- 1. Do i need to create a storeStreams method for aws service too?
2
- - Handle later
3
- 2. queues handling -> if queues is enabled by default, i.e triggerExport(exportTransactionEntity.id).
4
- - startExport should either return the data or return the transaction id
5
- 3. How to handle scenarios wherein, nested related exist.(do i need to only get the userkey)
6
- - show the userKey