@solidstarters/solid-core 1.2.93 → 1.2.95

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 (104) hide show
  1. package/dist/controllers/locale.controller.d.ts +41 -0
  2. package/dist/controllers/locale.controller.d.ts.map +1 -0
  3. package/dist/controllers/locale.controller.js +179 -0
  4. package/dist/controllers/locale.controller.js.map +1 -0
  5. package/dist/controllers/view-metadata.controller.d.ts +1 -0
  6. package/dist/controllers/view-metadata.controller.d.ts.map +1 -1
  7. package/dist/dtos/basic-filters.dto.d.ts +2 -0
  8. package/dist/dtos/basic-filters.dto.d.ts.map +1 -1
  9. package/dist/dtos/basic-filters.dto.js +11 -1
  10. package/dist/dtos/basic-filters.dto.js.map +1 -1
  11. package/dist/dtos/create-locale.dto.d.ts +6 -0
  12. package/dist/dtos/create-locale.dto.d.ts.map +1 -0
  13. package/dist/dtos/create-locale.dto.js +43 -0
  14. package/dist/dtos/create-locale.dto.js.map +1 -0
  15. package/dist/dtos/create-model-metadata.dto.d.ts +1 -0
  16. package/dist/dtos/create-model-metadata.dto.d.ts.map +1 -1
  17. package/dist/dtos/create-model-metadata.dto.js +7 -2
  18. package/dist/dtos/create-model-metadata.dto.js.map +1 -1
  19. package/dist/dtos/update-locale.dto.d.ts +7 -0
  20. package/dist/dtos/update-locale.dto.d.ts.map +1 -0
  21. package/dist/dtos/update-locale.dto.js +48 -0
  22. package/dist/dtos/update-locale.dto.js.map +1 -0
  23. package/dist/entities/common.entity.d.ts +3 -0
  24. package/dist/entities/common.entity.d.ts.map +1 -1
  25. package/dist/entities/common.entity.js +13 -1
  26. package/dist/entities/common.entity.js.map +1 -1
  27. package/dist/entities/locale.entity.d.ts +7 -0
  28. package/dist/entities/locale.entity.d.ts.map +1 -0
  29. package/dist/entities/locale.entity.js +43 -0
  30. package/dist/entities/locale.entity.js.map +1 -0
  31. package/dist/entities/model-metadata.entity.d.ts +1 -0
  32. package/dist/entities/model-metadata.entity.d.ts.map +1 -1
  33. package/dist/entities/model-metadata.entity.js +5 -1
  34. package/dist/entities/model-metadata.entity.js.map +1 -1
  35. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.d.ts.map +1 -1
  36. package/dist/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.js.map +1 -1
  37. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.d.ts.map +1 -1
  38. package/dist/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.js.map +1 -1
  39. package/dist/helpers/module-metadata-helper.service.d.ts.map +1 -1
  40. package/dist/helpers/module-metadata-helper.service.js.map +1 -1
  41. package/dist/helpers/solid-registry.d.ts +2 -0
  42. package/dist/helpers/solid-registry.d.ts.map +1 -1
  43. package/dist/helpers/solid-registry.js +5 -0
  44. package/dist/helpers/solid-registry.js.map +1 -1
  45. package/dist/index.d.ts +5 -0
  46. package/dist/index.d.ts.map +1 -1
  47. package/dist/index.js +5 -0
  48. package/dist/index.js.map +1 -1
  49. package/dist/seeders/seed-data/solid-core-metadata.json +203 -0
  50. package/dist/services/crud-helper.service.d.ts +1 -1
  51. package/dist/services/crud-helper.service.d.ts.map +1 -1
  52. package/dist/services/crud-helper.service.js +17 -2
  53. package/dist/services/crud-helper.service.js.map +1 -1
  54. package/dist/services/crud.service.d.ts.map +1 -1
  55. package/dist/services/crud.service.js +18 -5
  56. package/dist/services/crud.service.js.map +1 -1
  57. package/dist/services/locale.service.d.ts +26 -0
  58. package/dist/services/locale.service.d.ts.map +1 -0
  59. package/dist/services/locale.service.js +64 -0
  60. package/dist/services/locale.service.js.map +1 -0
  61. package/dist/services/mediaStorageProviders/file-storage-provider.js.map +1 -1
  62. package/dist/services/selection-providers/locale-list-selection-provider.service.d.ts +9 -0
  63. package/dist/services/selection-providers/locale-list-selection-provider.service.d.ts.map +1 -0
  64. package/dist/services/selection-providers/locale-list-selection-provider.service.js +87 -0
  65. package/dist/services/selection-providers/locale-list-selection-provider.service.js.map +1 -0
  66. package/dist/services/view-metadata.service.d.ts +3 -0
  67. package/dist/services/view-metadata.service.d.ts.map +1 -1
  68. package/dist/services/view-metadata.service.js +73 -7
  69. package/dist/services/view-metadata.service.js.map +1 -1
  70. package/dist/solid-core.module.d.ts.map +1 -1
  71. package/dist/solid-core.module.js +8 -0
  72. package/dist/solid-core.module.js.map +1 -1
  73. package/dist/subscribers/model.subscriber.d.ts.map +1 -1
  74. package/dist/subscribers/model.subscriber.js +24 -0
  75. package/dist/subscribers/model.subscriber.js.map +1 -1
  76. package/dist/transformers/datetime-transformer.d.ts +4 -0
  77. package/dist/transformers/datetime-transformer.d.ts.map +1 -0
  78. package/dist/transformers/datetime-transformer.js +11 -0
  79. package/dist/transformers/datetime-transformer.js.map +1 -0
  80. package/dist/tsconfig.tsbuildinfo +1 -1
  81. package/package.json +2 -1
  82. package/src/controllers/locale.controller.ts +94 -0
  83. package/src/dtos/basic-filters.dto.ts +13 -1
  84. package/src/dtos/create-locale.dto.ts +17 -0
  85. package/src/dtos/create-model-metadata.dto.ts +5 -1
  86. package/src/dtos/update-locale.dto.ts +23 -0
  87. package/src/entities/common.entity.ts +11 -1
  88. package/src/entities/locale.entity.ts +14 -0
  89. package/src/entities/model-metadata.entity.ts +3 -0
  90. package/src/helpers/field-crud-managers/ManyToManyRelationFieldCrudManager.ts +2 -1
  91. package/src/helpers/field-crud-managers/OneToManyRelationFieldCrudManager.ts +1 -0
  92. package/src/helpers/module-metadata-helper.service.ts +0 -1
  93. package/src/helpers/solid-registry.ts +11 -2
  94. package/src/index.ts +6 -3
  95. package/src/seeders/seed-data/solid-core-metadata.json +203 -0
  96. package/src/services/crud-helper.service.ts +30 -12
  97. package/src/services/crud.service.ts +50 -34
  98. package/src/services/locale.service.ts +37 -0
  99. package/src/services/mediaStorageProviders/file-storage-provider.ts +1 -1
  100. package/src/services/selection-providers/locale-list-selection-provider.service.ts +58 -0
  101. package/src/services/view-metadata.service.ts +179 -14
  102. package/src/solid-core.module.ts +8 -0
  103. package/src/subscribers/model.subscriber.ts +24 -0
  104. package/src/transformers/datetime-transformer.ts +12 -0
@@ -155,10 +155,9 @@ export class CrudHelperService {
155
155
  return queryBuilder.expressionMap.joinAttributes.length > 0;
156
156
  }
157
157
 
158
-
159
- buildFilterQuery(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string): SelectQueryBuilder<any> { //TODO : Check how to pass a type to SelectQueryBuilder instead of any
158
+ buildFilterQuery(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string, internationalisation?: boolean, draftPublishWorkflow?: boolean): SelectQueryBuilder<any> { // TODO : Check how to pass a type to SelectQueryBuilder instead of any
160
159
  let { limit, offset, showSoftDeleted, filters } = basicFilterDto;
161
- const { fields, sort, groupBy, populate = [], populateMedia=[] } = basicFilterDto;
160
+ const { fields, sort, groupBy, populate = [], populateMedia = [], locale, status } = basicFilterDto;
162
161
 
163
162
  // 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)
164
163
  const normalizedFields = this.normalize(fields);
@@ -187,6 +186,25 @@ export class CrudHelperService {
187
186
  }));
188
187
  }
189
188
 
189
+ let finalLocale = locale
190
+ if (internationalisation) {
191
+ // If locale is not provided in the filter dto, then assume it is the default locale to be used.
192
+ if (!finalLocale) {
193
+ // TODO: get the default locale from the database.
194
+ // This should be replaced with the actual default locale from the database, make sure to cache this request.
195
+ // @Sundaram consult with Oswald and use a registry based approach to fetch the default locale, making sure that it gets cached and we don't have to query again and again.
196
+ finalLocale = 'en';
197
+ }
198
+ qb.andWhere(`${entityAlias}.localeName = :locale`, { locale: finalLocale });
199
+ }
200
+
201
+ if (draftPublishWorkflow && status) {
202
+ if (basicFilterDto.status === 'published') {
203
+ qb.andWhere(`${entityAlias}.publishedAt IS NOT NULL`);
204
+ } else if (basicFilterDto.status === 'draft') {
205
+ qb.andWhere(`${entityAlias}.publishedAt IS NULL`);
206
+ }
207
+ }
190
208
  // Depending upon the select option, apply the select clause
191
209
  if (normalizedFields && normalizedFields.length) {
192
210
  qb.select(normalizedFields.map(field => {
@@ -223,22 +241,22 @@ export class CrudHelperService {
223
241
  qb.addGroupBy(`${entityAlias}.${field}`);
224
242
  });
225
243
  }
226
-
244
+
227
245
  // Apply the pagination options & handle the case when the query has joins
228
246
  if (limit) this.hasJoins(qb) ? qb.take(limit) : qb.limit(limit);
229
- if (offset) this.hasJoins(qb) ? qb.skip(offset): qb.offset(offset);
247
+ if (offset) this.hasJoins(qb) ? qb.skip(offset) : qb.offset(offset);
230
248
  return qb;
231
249
  }
232
250
 
233
251
  additionalRelationsRequiredForMediaPopulation(normalizedPopulateMedia: string[]) {
234
252
  // Populate relations containing the media field
235
253
  return normalizedPopulateMedia
236
- .filter(pm => pm.includes("."))
237
- .map((pm) => {
238
- const mediaPathParts = pm.split('.');
239
- if (mediaPathParts.length <= 1) return pm;
240
- return mediaPathParts.slice(0, -1).join('.');
241
- });
254
+ .filter(pm => pm.includes("."))
255
+ .map((pm) => {
256
+ const mediaPathParts = pm.split('.');
257
+ if (mediaPathParts.length <= 1) return pm;
258
+ return mediaPathParts.slice(0, -1).join('.');
259
+ });
242
260
  }
243
261
 
244
262
  private buildPopulateQuery(normalizedPopulate: string[], entityAlias: string, qb: SelectQueryBuilder<any>) {
@@ -257,7 +275,7 @@ export class CrudHelperService {
257
275
  // Check if the relation is already joined, if not then join it
258
276
  if (!this.isRelationJoined(qb, joinProperty)) {
259
277
  const joinAlias = relationParts.slice(0, i + 1).join('_');
260
- qb.leftJoinAndSelect(joinProperty, joinAlias);
278
+ qb.leftJoinAndSelect(joinProperty, joinAlias);
261
279
  }
262
280
  else {
263
281
  // Since in populate, we are create a unique alias based on the relation path
@@ -52,7 +52,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
52
52
  //We can just have the Model Entity here
53
53
  ) { }
54
54
 
55
- async create(createDto: any, files: Express.Multer.File[] = [],solidRequestContext :any = {}): Promise<T> {
55
+ async create(createDto: any, files: Express.Multer.File[] = [], solidRequestContext: any = {}): Promise<T> {
56
56
  // This class will be extended by the generated service class i.e PersonService
57
57
  // The data required to identify the model and module name will be passed from the generate CrudService subclass
58
58
  //TODO: Algorithm to create the entity
@@ -215,7 +215,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
215
215
  throw new BadRequestException('Forbidden');
216
216
  }
217
217
  }
218
-
218
+
219
219
  const model = await this.modelMetadataService.findOneBySingularName(this.modelName, {
220
220
  fields: {
221
221
  model: true,
@@ -232,10 +232,26 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
232
232
  if (!entity) {
233
233
  throw new Error(`Entity [${this.moduleName}.${this.modelName}] with id ${id} not found`);
234
234
  }
235
+
236
+ // If the model has internationalisation enabled, delete children with defaultEntityLocaleId === this entity's id
237
+ if (model.internationalisation) {
238
+ // Find all child entities where defaultEntityLocaleId === this entity's id
239
+ const childEntities = await this.repo.find({
240
+ where: { defaultEntityLocaleId: id } as any
241
+ });
242
+
243
+ if (childEntities.length > 0) {
244
+ if (model.enableSoftDelete === true) {
245
+ await this.repo.softRemove(childEntities);
246
+ } else {
247
+ await this.repo.remove(childEntities);
248
+ }
249
+ }
250
+ }
251
+
235
252
  if (model.enableSoftDelete === true) {
236
253
  await this.repo.softRemove(entity);
237
254
  return this.repo.save(entity);
238
-
239
255
  } else {
240
256
  return this.repo.remove(entity);
241
257
  }
@@ -365,7 +381,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
365
381
  // Validation against the selectionStatic values. No transformation is required
366
382
  // If the value is not in the selectionStatic values, then throw
367
383
  // Also validate against the selectionType
368
- const options = { ...commonOptions, selectionStaticValues: fieldMetadata.selectionStaticValues, selectionValueType: fieldMetadata.selectionValueType as SelectionValueType, isMultiSelect: fieldMetadata.isMultiSelect};
384
+ const options = { ...commonOptions, selectionStaticValues: fieldMetadata.selectionStaticValues, selectionValueType: fieldMetadata.selectionValueType as SelectionValueType, isMultiSelect: fieldMetadata.isMultiSelect };
369
385
  return new SelectionStaticFieldCrudManager(options);
370
386
  }
371
387
  case SolidFieldType.selectionDynamic: {// [HOLD]
@@ -374,7 +390,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
374
390
  // dataSource: string; // The name of the selection provider
375
391
  // filterSchema : json // This is a custom json object that every data source will handle accordingly. We could validate the query against the selection provider
376
392
  // values : string[]; // The values returned by the selection provider
377
- const options = { ...commonOptions, selectionDynamicProvider: fieldMetadata.selectionDynamicProvider, selectionDynamicProviderCtxt: fieldMetadata.selectionDynamicProviderCtxt, selectionValueType: fieldMetadata.selectionValueType as SelectionValueType, discoveryService: this.discoveryService, isMultiSelect: fieldMetadata.isMultiSelect};
393
+ const options = { ...commonOptions, selectionDynamicProvider: fieldMetadata.selectionDynamicProvider, selectionDynamicProviderCtxt: fieldMetadata.selectionDynamicProviderCtxt, selectionValueType: fieldMetadata.selectionValueType as SelectionValueType, discoveryService: this.discoveryService, isMultiSelect: fieldMetadata.isMultiSelect };
378
394
  return new SelectionDynamicFieldCrudManager(options);
379
395
  }
380
396
  case SolidFieldType.uuid: {
@@ -398,7 +414,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
398
414
  const alias = 'entity';
399
415
  // Extract the required keys from the input query
400
416
  let { limit, offset, populateMedia, populateGroup, groupFilter } = basicFilterDto;
401
- const {singularName} = await this.loadModel();
417
+ const { singularName, internationalisation, draftPublishWorkflow } = await this.loadModel();
402
418
  // Check wheather user has update permission for model
403
419
  if (solidRequestContext.activeUser) {
404
420
  const hasPermission = this.crudHelperService.hasReadPermissionOnModel(solidRequestContext.activeUser, singularName);
@@ -409,11 +425,11 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
409
425
 
410
426
  // Create above query on pincode table using query builder
411
427
  var qb: SelectQueryBuilder<T> = this.repo.createQueryBuilder(alias)
412
- qb = this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias);
413
-
428
+ qb = this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias, internationalisation, draftPublishWorkflow);
429
+
414
430
  if (basicFilterDto.groupBy) {
415
431
  // Get the records and the count
416
- const { groupMeta, groupRecords } = await this.handleGroupFind(qb, groupFilter, populateGroup, alias, populateMedia);
432
+ const { groupMeta, groupRecords } = await this.handleGroupFind(qb, groupFilter, populateGroup, alias, populateMedia, internationalisation, draftPublishWorkflow);
417
433
  return {
418
434
  groupMeta,
419
435
  groupRecords,
@@ -440,7 +456,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
440
456
  return this.wrapFindResponse(offset, limit, count, entities);
441
457
  }
442
458
 
443
- private async handleGroupFind(qb: SelectQueryBuilder<T>, groupFilter: BasicFilterDto, populateGroup: boolean, alias: string, populateMedia: string[]) {
459
+ private async handleGroupFind(qb: SelectQueryBuilder<T>, groupFilter: BasicFilterDto, populateGroup: boolean, alias: string, populateMedia: string[], internationalisation: boolean, draftPublishWorkflow: boolean) {
444
460
  const groupByResult = await qb.getRawMany();
445
461
 
446
462
  const groupMeta = [];
@@ -449,7 +465,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
449
465
  for (const group of groupByResult) {
450
466
  if (populateGroup) {
451
467
  let groupByQb: SelectQueryBuilder<T> = this.repo.createQueryBuilder(alias);
452
- groupByQb = this.crudHelperService.buildFilterQuery(groupByQb, groupFilter, alias);
468
+ groupByQb = this.crudHelperService.buildFilterQuery(groupByQb, groupFilter, alias, internationalisation, draftPublishWorkflow);
453
469
  groupByQb = this.crudHelperService.buildGroupByRecordsQuery(groupByQb, group, alias);
454
470
  const [entities, count] = await groupByQb.getManyAndCount();
455
471
 
@@ -486,12 +502,12 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
486
502
  return r;
487
503
  }
488
504
 
489
- private async handlePopulateMedia(populateMedia: string[], entities: T[]) {
505
+ private async handlePopulateMedia(populateMedia: string[], entities: T[]) {
490
506
  const model = await this.entityManager.getRepository(ModelMetadata).findOne({
491
507
  where: {
492
508
  singularName: this.modelName,
493
509
  },
494
- relations: ['fields', 'fields.mediaStorageProvider', 'fields.model','module'],
510
+ relations: ['fields', 'fields.mediaStorageProvider', 'fields.model', 'module'],
495
511
  });
496
512
 
497
513
  // Will iterate through every entity & all populateMedia & call getMediaDetails for each field
@@ -501,7 +517,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
501
517
  }
502
518
  }
503
519
  return entities;
504
- }
520
+ }
505
521
 
506
522
  // Adds the media with full URL to the entity / nested entity
507
523
  private async populateMediaObject(mediaFieldPath: string, model: ModelMetadata, entity: T) {
@@ -515,12 +531,12 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
515
531
  // We can assume that the media field entity model is already populated as part of the entity data
516
532
  const mediaFieldEntities = this.getMediaFieldEntities(entity, pathParts);
517
533
  if (!mediaFieldEntities || mediaFieldEntities.length === 0) {
518
- return ;//no need to populate data if relation not exists
534
+ return;//no need to populate data if relation not exists
519
535
  }
520
536
  // Populate the media field entities with the full URL
521
537
  for (const mediaFieldEntity of mediaFieldEntities) {
522
538
  const mediaWithFullUrl = await this.getMediaWithFullUrl(mediaFieldEntity, mediaFieldMetadata);
523
- this.appendMediaKey(mediaWithFullUrl, mediaFieldEntity, mediaFieldMetadata.name);
539
+ this.appendMediaKey(mediaWithFullUrl, mediaFieldEntity, mediaFieldMetadata.name);
524
540
  // mediaFieldEntity['_media'][mediaFieldPath] = mediaWithFullUrl
525
541
  }
526
542
  }
@@ -546,7 +562,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
546
562
  entity['_media'] = {
547
563
  [mediaFieldPath]: mediaWithFullUrl
548
564
  };
549
- }
565
+ }
550
566
  }
551
567
 
552
568
  private getMediaFieldEntities(entity: T, mediaPathParts: string[]): T[] {
@@ -562,12 +578,12 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
562
578
  return isArray(entityPart) ? entityPart : [entityPart];
563
579
  }
564
580
 
565
- async getMediaWithFullUrl(mediaEntity: any, mediaFieldMetadata: FieldMetadata): Promise<MediaWithFullUrl[]>{
566
- const storageProviderMetadata = mediaFieldMetadata.mediaStorageProvider;
567
- const storageProviderType = storageProviderMetadata.type as MediaStorageProviderType;
568
- const storageProvider = await getMediaStorageProvider(this.moduleRef, storageProviderType);
569
- const mediaDetails = await storageProvider.retrieve(mediaEntity, mediaFieldMetadata);
570
- return mediaDetails as MediaWithFullUrl[];
581
+ async getMediaWithFullUrl(mediaEntity: any, mediaFieldMetadata: FieldMetadata): Promise<MediaWithFullUrl[]> {
582
+ const storageProviderMetadata = mediaFieldMetadata.mediaStorageProvider;
583
+ const storageProviderType = storageProviderMetadata.type as MediaStorageProviderType;
584
+ const storageProvider = await getMediaStorageProvider(this.moduleRef, storageProviderType);
585
+ const mediaDetails = await storageProvider.retrieve(mediaEntity, mediaFieldMetadata);
586
+ return mediaDetails as MediaWithFullUrl[];
571
587
  }
572
588
 
573
589
  async findOne(id: number, query: any, solidRequestContext: any = {}) {
@@ -610,7 +626,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
610
626
  return entity;
611
627
  }
612
628
 
613
- async insertMany(createDtos: any[], filesArray: Express.Multer.File[][] = [],solidRequestContext: any = {}): Promise<T[]> {
629
+ async insertMany(createDtos: any[], filesArray: Express.Multer.File[][] = [], solidRequestContext: any = {}): Promise<T[]> {
614
630
 
615
631
 
616
632
  // if (createDtos.length !== filesArray.length) {
@@ -669,7 +685,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
669
685
  return savedEntities;
670
686
  }
671
687
 
672
- async deleteMany(ids: number[],solidRequestContext: any = {}): Promise<any> {
688
+ async deleteMany(ids: number[], solidRequestContext: any = {}): Promise<any> {
673
689
 
674
690
  if (!ids || ids.length === 0) {
675
691
  throw new Error('At least one ID is required for deletion');
@@ -713,7 +729,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
713
729
  // return removedEntities
714
730
  }
715
731
 
716
- async recover(id: number,solidRequestContext: any = {}) {
732
+ async recover(id: number, solidRequestContext: any = {}) {
717
733
  try {
718
734
  const loadedmodel = await this.loadModel();
719
735
  // Check wheather user has update permission for model
@@ -753,7 +769,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
753
769
  }
754
770
  }
755
771
 
756
- async recoverMany(ids: number[],solidRequestContext: any = {}) {
772
+ async recoverMany(ids: number[], solidRequestContext: any = {}) {
757
773
  try {
758
774
  const loadedmodel = await this.loadModel();
759
775
  // Check wheather user has update permission for model
@@ -808,32 +824,32 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
808
824
  if (!pathParts || pathParts.length === 0) {
809
825
  throw new BadRequestException('Path parts cannot be empty');
810
826
  }
811
-
827
+
812
828
  const [currentPart, ...remainingParts] = pathParts;
813
829
  const field = fields.find(field => field.name === currentPart);
814
-
830
+
815
831
  if (!field) {
816
832
  throw new BadRequestException(`Field ${currentPart} not found in model ${this.modelName}`);
817
833
  }
818
-
834
+
819
835
  // Base case: last part, return the field
820
836
  if (remainingParts.length === 0) {
821
837
  return field;
822
838
  }
823
-
839
+
824
840
  if (!field.relationCoModelSingularName) {
825
841
  throw new BadRequestException(`Field ${field.name} does not define a relationCoModelSingularName`);
826
842
  }
827
-
843
+
828
844
  const relationCoModel = await this.entityManager.getRepository(ModelMetadata).findOne({
829
845
  where: { singularName: field.relationCoModelSingularName },
830
846
  relations: ['fields', 'fields.mediaStorageProvider', 'fields.model'],
831
847
  });
832
-
848
+
833
849
  if (!relationCoModel) {
834
850
  throw new BadRequestException(`Model ${field.relationCoModelSingularName} not found`);
835
851
  }
836
-
852
+
837
853
  return this.getFieldMetadataRecursively(remainingParts, relationCoModel.fields);
838
854
  }
839
855
  }
@@ -0,0 +1,37 @@
1
+ import { Injectable } from '@nestjs/common';
2
+ import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
3
+ import { DiscoveryService, ModuleRef } from "@nestjs/core";
4
+ import { EntityManager, Repository } from 'typeorm';
5
+
6
+ import { CRUDService } from 'src/services/crud.service';
7
+ import { ModelMetadataService } from 'src/services/model-metadata.service';
8
+ import { ModuleMetadataService } from 'src/services/module-metadata.service';
9
+ import { ConfigService } from '@nestjs/config';
10
+ import { FileService } from 'src/services/file.service';
11
+ import { CrudHelperService } from 'src/services/crud-helper.service';
12
+ import { ModelMetadata } from 'src/entities/model-metadata.entity';
13
+ import { RequestContextService } from './request-context.service';
14
+ import { Locale } from 'src/entities/locale.entity';
15
+ @Injectable()
16
+ export class LocaleService extends CRUDService<Locale>{
17
+ constructor(
18
+ readonly modelMetadataService: ModelMetadataService,
19
+ readonly moduleMetadataService: ModuleMetadataService,
20
+ readonly configService: ConfigService,
21
+ readonly fileService: FileService,
22
+ readonly discoveryService: DiscoveryService,
23
+ readonly crudHelperService: CrudHelperService,
24
+ @InjectEntityManager()
25
+ readonly entityManager: EntityManager,
26
+ @InjectRepository(Locale, 'default')
27
+ readonly repo: Repository<Locale>,
28
+ @InjectRepository(Locale, 'default')
29
+ readonly moduleRef: ModuleRef,
30
+ @InjectRepository(ModelMetadata)
31
+ private readonly modelMetadataRepo: Repository<ModelMetadata>,
32
+ readonly requestContextService: RequestContextService
33
+ ) {
34
+ super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService,entityManager, repo, 'locale', 'solid-core', moduleRef);
35
+ }
36
+
37
+ }
@@ -45,7 +45,7 @@ export class FileStorageProvider<T> implements MediaStorageProvider<T> {
45
45
  await this.fileService.deleteFile(file.path);
46
46
 
47
47
  // Create an entry in the media table
48
- const mediaEntity = await this.mediaRepository.createMedia({
48
+ const mediaEntity = await this.mediaRepository.createMedia({
49
49
  entityId: entity.id,
50
50
  modelMetadataId: mediaFieldMetadata.model.id,
51
51
  relativeUri: this.getFileName(file),
@@ -0,0 +1,58 @@
1
+ import { Injectable } from "@nestjs/common";
2
+ import { ModelMetadataService } from "src/services/model-metadata.service";
3
+ import { SelectionProvider } from "src/decorators/selection-provider.decorator";
4
+ import { ISelectionProvider, ISelectionProviderContext, ISelectionProviderValues } from "../../interfaces";
5
+ // import localeCodes from 'locale-codes';
6
+ import * as locale from 'locale-codes'
7
+
8
+
9
+ @SelectionProvider()
10
+ @Injectable()
11
+ export class LocaleListSelectionProvider implements ISelectionProvider<ISelectionProviderContext> {
12
+
13
+ constructor() {
14
+ }
15
+
16
+ help(): string {
17
+ return "# Gets all locales available to the user";
18
+ }
19
+
20
+ name(): string {
21
+ return 'LocaleListSelectionProvider';
22
+ }
23
+
24
+ async value(optionValue: string, ctxt: ISelectionProviderContext): Promise<ISelectionProviderValues | any> {
25
+ const locales = locale.all
26
+ .filter(code => code.tag === optionValue)
27
+ .map(code => ({ label: `${code.name} (${code.tag})`, value: code.tag }));
28
+
29
+ return locales.length > 0 ? locales[0] : null;
30
+ }
31
+
32
+ async values(query: string, ctxt: ISelectionProviderContext): Promise<readonly ISelectionProviderValues[]> {
33
+
34
+ const locales = locale.all
35
+ .filter(code => {
36
+ // Look at the documentation here - https://www.npmjs.com/package/locale-codes
37
+ // In this if you check the section - https://www.npmjs.com/package/locale-codes#locale-list
38
+
39
+ // We disabled this because this was not returning the basic locale codes like 'en', 'fr', etc.
40
+ // We are only interested in the locales that have a tag with a hyphen (-) in it.
41
+ // if (code.tag.includes('-')) {
42
+ if (query) {
43
+ const lowerCaseQuery = query.toLowerCase();
44
+ return code.name.toLowerCase().includes(lowerCaseQuery) || code.tag.toLowerCase().includes(lowerCaseQuery);
45
+ }
46
+ return true;
47
+ // }
48
+ return false;
49
+ })
50
+ .map(code => ({
51
+ label: `${code.name} (${code.tag})`,
52
+ value: code.tag,
53
+ }));
54
+
55
+ return locales;
56
+
57
+ }
58
+ }