@solidstarters/solid-core 1.2.95 → 1.2.97

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 (91) hide show
  1. package/dist/controllers/action-metadata.controller.d.ts +3 -1
  2. package/dist/controllers/action-metadata.controller.d.ts.map +1 -1
  3. package/dist/controllers/chatter-message-details.controller.d.ts +3 -1
  4. package/dist/controllers/chatter-message-details.controller.d.ts.map +1 -1
  5. package/dist/controllers/chatter-message.controller.d.ts +3 -1
  6. package/dist/controllers/chatter-message.controller.d.ts.map +1 -1
  7. package/dist/controllers/email-template.controller.d.ts +3 -1
  8. package/dist/controllers/email-template.controller.d.ts.map +1 -1
  9. package/dist/controllers/export-template.controller.d.ts +3 -1
  10. package/dist/controllers/export-template.controller.d.ts.map +1 -1
  11. package/dist/controllers/export-transaction.controller.d.ts +3 -1
  12. package/dist/controllers/export-transaction.controller.d.ts.map +1 -1
  13. package/dist/controllers/import-transaction-error-log.controller.d.ts +3 -1
  14. package/dist/controllers/import-transaction-error-log.controller.d.ts.map +1 -1
  15. package/dist/controllers/import-transaction.controller.d.ts +3 -1
  16. package/dist/controllers/import-transaction.controller.d.ts.map +1 -1
  17. package/dist/controllers/list-of-values.controller.d.ts +3 -1
  18. package/dist/controllers/list-of-values.controller.d.ts.map +1 -1
  19. package/dist/controllers/locale.controller.d.ts +3 -1
  20. package/dist/controllers/locale.controller.d.ts.map +1 -1
  21. package/dist/controllers/media.controller.d.ts +3 -1
  22. package/dist/controllers/media.controller.d.ts.map +1 -1
  23. package/dist/controllers/menu-item-metadata.controller.d.ts +3 -1
  24. package/dist/controllers/menu-item-metadata.controller.d.ts.map +1 -1
  25. package/dist/controllers/mq-message-queue.controller.d.ts +3 -1
  26. package/dist/controllers/mq-message-queue.controller.d.ts.map +1 -1
  27. package/dist/controllers/mq-message.controller.d.ts +3 -1
  28. package/dist/controllers/mq-message.controller.d.ts.map +1 -1
  29. package/dist/controllers/permission-metadata.controller.d.ts +3 -1
  30. package/dist/controllers/permission-metadata.controller.d.ts.map +1 -1
  31. package/dist/controllers/role-metadata.controller.d.ts +3 -1
  32. package/dist/controllers/role-metadata.controller.d.ts.map +1 -1
  33. package/dist/controllers/saved-filters.controller.d.ts +3 -1
  34. package/dist/controllers/saved-filters.controller.d.ts.map +1 -1
  35. package/dist/controllers/security-rule.controller.d.ts +3 -1
  36. package/dist/controllers/security-rule.controller.d.ts.map +1 -1
  37. package/dist/controllers/setting.controller.d.ts +3 -1
  38. package/dist/controllers/setting.controller.d.ts.map +1 -1
  39. package/dist/controllers/sms-template.controller.d.ts +3 -1
  40. package/dist/controllers/sms-template.controller.d.ts.map +1 -1
  41. package/dist/controllers/user-view-metadata.controller.d.ts +3 -1
  42. package/dist/controllers/user-view-metadata.controller.d.ts.map +1 -1
  43. package/dist/controllers/user.controller.d.ts +3 -1
  44. package/dist/controllers/user.controller.d.ts.map +1 -1
  45. package/dist/controllers/view-metadata.controller.d.ts +3 -1
  46. package/dist/controllers/view-metadata.controller.d.ts.map +1 -1
  47. package/dist/dtos/create-saved-filters.dto.d.ts +1 -1
  48. package/dist/dtos/create-saved-filters.dto.d.ts.map +1 -1
  49. package/dist/dtos/create-saved-filters.dto.js +3 -3
  50. package/dist/dtos/create-saved-filters.dto.js.map +1 -1
  51. package/dist/dtos/update-saved-filters.dto.d.ts +1 -1
  52. package/dist/dtos/update-saved-filters.dto.d.ts.map +1 -1
  53. package/dist/dtos/update-saved-filters.dto.js +3 -3
  54. package/dist/dtos/update-saved-filters.dto.js.map +1 -1
  55. package/dist/entities/saved-filters.entity.d.ts +1 -1
  56. package/dist/entities/saved-filters.entity.d.ts.map +1 -1
  57. package/dist/entities/saved-filters.entity.js +2 -2
  58. package/dist/entities/saved-filters.entity.js.map +1 -1
  59. package/dist/helpers/solid-registry.d.ts +6 -1
  60. package/dist/helpers/solid-registry.d.ts.map +1 -1
  61. package/dist/helpers/solid-registry.js +8 -0
  62. package/dist/helpers/solid-registry.js.map +1 -1
  63. package/dist/seeders/seed-data/solid-core-metadata.json +1 -8
  64. package/dist/services/crud-helper.service.d.ts +3 -1
  65. package/dist/services/crud-helper.service.d.ts.map +1 -1
  66. package/dist/services/crud-helper.service.js +30 -2
  67. package/dist/services/crud-helper.service.js.map +1 -1
  68. package/dist/services/crud.service.d.ts +3 -1
  69. package/dist/services/crud.service.d.ts.map +1 -1
  70. package/dist/services/crud.service.js +12 -4
  71. package/dist/services/crud.service.js.map +1 -1
  72. package/dist/services/locale.service.d.ts +8 -2
  73. package/dist/services/locale.service.d.ts.map +1 -1
  74. package/dist/services/locale.service.js +17 -4
  75. package/dist/services/locale.service.js.map +1 -1
  76. package/dist/services/media.service.d.ts +3 -1
  77. package/dist/services/media.service.d.ts.map +1 -1
  78. package/dist/transformers/datetime-transformer.d.ts.map +1 -1
  79. package/dist/transformers/datetime-transformer.js +3 -1
  80. package/dist/transformers/datetime-transformer.js.map +1 -1
  81. package/dist/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +1 -1
  83. package/src/dtos/create-saved-filters.dto.ts +3 -3
  84. package/src/dtos/update-saved-filters.dto.ts +3 -3
  85. package/src/entities/saved-filters.entity.ts +1 -1
  86. package/src/helpers/solid-registry.ts +12 -0
  87. package/src/seeders/seed-data/solid-core-metadata.json +1 -8
  88. package/src/services/crud-helper.service.ts +41 -10
  89. package/src/services/crud.service.ts +13 -4
  90. package/src/services/locale.service.ts +15 -4
  91. package/src/transformers/datetime-transformer.ts +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solidstarters/solid-core",
3
- "version": "1.2.95",
3
+ "version": "1.2.97",
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",
@@ -1,12 +1,12 @@
1
1
  import { ApiProperty } from '@nestjs/swagger';
2
2
  import { IsString } from 'class-validator';
3
- import { IsOptional, IsNotEmpty, IsBoolean, IsInt } from 'class-validator';
3
+ import { IsOptional, IsNotEmpty, IsBoolean, IsInt, IsJSON } from 'class-validator';
4
4
 
5
5
  export class CreateSavedFiltersDto {
6
6
  @IsOptional()
7
- @IsString()
7
+ @IsJSON()
8
8
  @ApiProperty()
9
- filterQueryJson: string;
9
+ filterQueryJson: any;
10
10
  @IsNotEmpty()
11
11
  @IsString()
12
12
  @ApiProperty()
@@ -1,4 +1,4 @@
1
- import { IsInt,IsOptional, IsString, IsNotEmpty, IsBoolean } from 'class-validator';
1
+ import { IsInt,IsOptional, IsString, IsNotEmpty, IsBoolean, IsJSON } from 'class-validator';
2
2
  import { ApiProperty } from '@nestjs/swagger';
3
3
 
4
4
  export class UpdateSavedFiltersDto {
@@ -6,9 +6,9 @@ export class UpdateSavedFiltersDto {
6
6
  @IsInt()
7
7
  id: number;
8
8
  @IsOptional()
9
- @IsString()
9
+ @IsJSON()
10
10
  @ApiProperty()
11
- filterQueryJson: string;
11
+ filterQueryJson: any;
12
12
  @IsNotEmpty()
13
13
  @IsOptional()
14
14
  @IsString()
@@ -7,7 +7,7 @@ import { ViewMetadata } from 'src/entities/view-metadata.entity'
7
7
  @Entity("ss_saved_fitlers")
8
8
  export class SavedFilters extends CommonEntity {
9
9
  @Column({ type: "text", nullable: true })
10
- filterQueryJson: string;
10
+ filterQueryJson: any;
11
11
  @Column({ type: "varchar" })
12
12
  name: string;
13
13
  @Column({ type: "boolean", nullable: true, default: false })
@@ -3,6 +3,7 @@ import { InstanceWrapper } from '@nestjs/core/injector/instance-wrapper';
3
3
  import { ISelectionProvider, ISelectionProviderContext } from "../interfaces";
4
4
  import { SecurityRule } from 'src/entities/security-rule.entity';
5
5
  import { EntityManager } from 'typeorm';
6
+ import { Locale } from 'src/entities/locale.entity';
6
7
 
7
8
  type ControllerMetadata = {
8
9
  name: string;
@@ -33,6 +34,7 @@ export enum RESERVED_SOLID_KEYWORDS {
33
34
  userPasswordHistory = "userPasswordHistory",
34
35
  userMetadata = "userMetadata",
35
36
  user = "user",
37
+ locale = "locale"
36
38
  }
37
39
 
38
40
  @Injectable()
@@ -44,6 +46,7 @@ export class SolidRegistry {
44
46
  private controllers: Set<ControllerMetadata> = new Set();
45
47
  private modules: Set<InstanceWrapper> = new Set();
46
48
  private securityRules: SecurityRule[] = [];
49
+ private locales : Locale[] = [];
47
50
 
48
51
  registerController(name: string, methodNames: string[]): void {
49
52
  this.controllers.add({ name: name, methods: methodNames });
@@ -117,6 +120,15 @@ export class SolidRegistry {
117
120
  this.securityRules = securityRules;
118
121
  }
119
122
 
123
+ registerlocales(locales : Locale[]){
124
+ this.locales = locales;
125
+ }
126
+
127
+ //TODO:getlocales from locale model and return default locale where isDefault:true
128
+ getDefaultLocale(): Locale | null {
129
+ return this.locales.find(locale => locale.isDefault === true) || null;
130
+ }
131
+
120
132
  getSecurityRules(modelSingularName: string, roleNames: string[] = []): SecurityRule[] {
121
133
  // If no role is provided, return all security rules for the model
122
134
  if (roleNames.length === 0) {
@@ -2536,7 +2536,7 @@
2536
2536
  {
2537
2537
  "name": "filterQueryJson",
2538
2538
  "displayName": "Filter Query Json",
2539
- "type": "longText",
2539
+ "type": "json",
2540
2540
  "ormType": "text",
2541
2541
  "required": false,
2542
2542
  "unique": false,
@@ -4886,13 +4886,6 @@
4886
4886
  "name": "view",
4887
4887
  "isSearchable": true
4888
4888
  }
4889
- },
4890
- {
4891
- "type": "field",
4892
- "attrs": {
4893
- "name": "filterQueryJson",
4894
- "isSearchable": true
4895
- }
4896
4889
  }
4897
4890
  ]
4898
4891
  }
@@ -2,12 +2,14 @@ import { Brackets, SelectQueryBuilder, WhereExpressionBuilder } from "typeorm";
2
2
  import { BasicFilterDto } from "../dtos/basic-filters.dto";
3
3
  import { classify } from "@angular-devkit/core/src/utils/strings";
4
4
  import { ActiveUserData } from "src/interfaces/active-user-data.interface";
5
+ import { SolidRegistry } from "src/helpers/solid-registry";
6
+ import { Logger } from "@nestjs/common";
7
+
5
8
 
6
9
  export class CrudHelperService {
7
10
  constructor(
8
-
9
11
  ) { }
10
-
12
+ private readonly logger = new Logger(CrudHelperService.name);
11
13
 
12
14
  private orderOptions(sort: any[] = []) {
13
15
  const orderOptions = {};
@@ -53,7 +55,7 @@ export class CrudHelperService {
53
55
  }
54
56
  else { // Recursively call the applyFilters method to handle nested conditions
55
57
  const joinField = `${alias}.${key}`;
56
- if (!this.isRelationJoined(selectQb, joinField)) selectQb.leftJoin(joinField, key);
58
+ if (!this.isRelationJoined(selectQb, joinField)) selectQb.leftJoin(joinField, key);
57
59
  this.applyFilters(qb, primaryFilterObj, key, selectQb);
58
60
  }
59
61
  });
@@ -154,8 +156,8 @@ export class CrudHelperService {
154
156
  private hasJoins(queryBuilder: SelectQueryBuilder<any>): boolean {
155
157
  return queryBuilder.expressionMap.joinAttributes.length > 0;
156
158
  }
157
-
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
159
+
160
+ buildFilterQuery(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string, internationalisation?: boolean, draftPublishWorkflow?: boolean,moduleRef?:any): SelectQueryBuilder<any> { // TODO : Check how to pass a type to SelectQueryBuilder instead of any
159
161
  let { limit, offset, showSoftDeleted, filters } = basicFilterDto;
160
162
  const { fields, sort, groupBy, populate = [], populateMedia = [], locale, status } = basicFilterDto;
161
163
 
@@ -190,10 +192,14 @@ export class CrudHelperService {
190
192
  if (internationalisation) {
191
193
  // If locale is not provided in the filter dto, then assume it is the default locale to be used.
192
194
  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';
195
+ //Get default locale from registry
196
+ const solidRegistry = moduleRef.get(SolidRegistry, { strict: false });
197
+ const defaultLocale = solidRegistry.getDefaultLocale();
198
+ if(defaultLocale){
199
+ finalLocale = defaultLocale.locale;
200
+ }else{
201
+ finalLocale = 'en';
202
+ }
197
203
  }
198
204
  qb.andWhere(`${entityAlias}.localeName = :locale`, { locale: finalLocale });
199
205
  }
@@ -280,7 +286,7 @@ export class CrudHelperService {
280
286
  else {
281
287
  // Since in populate, we are create a unique alias based on the relation path
282
288
  //If the join is already present, it is probably because of the relation being passed in the where filter i.e applyFilters method
283
- qb.addSelect(`${part}`);
289
+ qb.addSelect(`${part}`);
284
290
  }
285
291
  parentAlias = part; // Update the parent alias for the next iteration
286
292
  });
@@ -350,6 +356,31 @@ export class CrudHelperService {
350
356
  };
351
357
  }
352
358
 
359
+ async countGroupedRecords(qb: SelectQueryBuilder<any>, basicFilterDto: BasicFilterDto, entityAlias: string) { //TODO : Check how to pass a type to SelectQueryBuilder instead of any
360
+ const { limit, offset, ...rest } = basicFilterDto;
361
+
362
+ const filteredDto = { ...rest, limit: undefined, offset: undefined };
363
+
364
+ const filteredQB = this.buildFilterQuery(qb, filteredDto as BasicFilterDto, entityAlias);
365
+
366
+ // Select only the group field and count distinct rows
367
+ const groupByField = filteredDto.groupBy;
368
+
369
+ if (!groupByField || (Array.isArray(groupByField) && groupByField.length !== 1)) {
370
+ throw new Error('Exactly one groupBy field is required to count grouped records.');
371
+ }
372
+
373
+ const field = Array.isArray(groupByField) ? groupByField[0] : groupByField;
374
+ const rawResults = await filteredQB
375
+ .select([]) // Remove prior select fields
376
+ .addSelect(`${entityAlias}.${field}`, 'groupField')
377
+ .groupBy(`${entityAlias}.${field}`)
378
+ .limit(undefined) // Important: prevent LIMIT 1 from propagating
379
+ .offset(undefined)
380
+ .getRawMany();
381
+
382
+ return rawResults.length;
383
+ }
353
384
 
354
385
  hasReadPermissionOnModel = (activeUser: ActiveUserData, modelName: string) => {
355
386
  const permissionNames = [`${classify(modelName)}Controller.findOne`, `${classify(modelName)}Controller.findMany`];
@@ -425,12 +425,21 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
425
425
 
426
426
  // Create above query on pincode table using query builder
427
427
  var qb: SelectQueryBuilder<T> = this.repo.createQueryBuilder(alias)
428
- qb = this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias, internationalisation, draftPublishWorkflow);
428
+ qb = this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias);
429
+ if(internationalisation && draftPublishWorkflow){
430
+ qb = this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias,internationalisation, draftPublishWorkflow,this.moduleRef);
431
+ }
429
432
 
430
433
  if (basicFilterDto.groupBy) {
431
434
  // Get the records and the count
432
- const { groupMeta, groupRecords } = await this.handleGroupFind(qb, groupFilter, populateGroup, alias, populateMedia, internationalisation, draftPublishWorkflow);
435
+ const { groupMeta, groupRecords } = await this.handleGroupFind(qb, groupFilter, populateGroup, alias, populateMedia);
436
+ const totalGroups = await this.crudHelperService.countGroupedRecords(qb, basicFilterDto, alias);
437
+ qb = this.crudHelperService.buildFilterQuery(qb, basicFilterDto, alias);
438
+
433
439
  return {
440
+ meta: {
441
+ "totalRecords": totalGroups
442
+ },
434
443
  groupMeta,
435
444
  groupRecords,
436
445
  }
@@ -456,7 +465,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
456
465
  return this.wrapFindResponse(offset, limit, count, entities);
457
466
  }
458
467
 
459
- private async handleGroupFind(qb: SelectQueryBuilder<T>, groupFilter: BasicFilterDto, populateGroup: boolean, alias: string, populateMedia: string[], internationalisation: boolean, draftPublishWorkflow: boolean) {
468
+ private async handleGroupFind(qb: SelectQueryBuilder<T>, groupFilter: BasicFilterDto, populateGroup: boolean, alias: string, populateMedia: string[]) {
460
469
  const groupByResult = await qb.getRawMany();
461
470
 
462
471
  const groupMeta = [];
@@ -465,7 +474,7 @@ export class CRUDService<T> { // Add two generic value i.e Person,CreatePersonDt
465
474
  for (const group of groupByResult) {
466
475
  if (populateGroup) {
467
476
  let groupByQb: SelectQueryBuilder<T> = this.repo.createQueryBuilder(alias);
468
- groupByQb = this.crudHelperService.buildFilterQuery(groupByQb, groupFilter, alias, internationalisation, draftPublishWorkflow);
477
+ groupByQb = this.crudHelperService.buildFilterQuery(groupByQb, groupFilter, alias);
469
478
  groupByQb = this.crudHelperService.buildGroupByRecordsQuery(groupByQb, group, alias);
470
479
  const [entities, count] = await groupByQb.getManyAndCount();
471
480
 
@@ -1,4 +1,4 @@
1
- import { Injectable } from '@nestjs/common';
1
+ import { Injectable, Logger, OnApplicationBootstrap } from '@nestjs/common';
2
2
  import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
3
3
  import { DiscoveryService, ModuleRef } from "@nestjs/core";
4
4
  import { EntityManager, Repository } from 'typeorm';
@@ -12,8 +12,9 @@ import { CrudHelperService } from 'src/services/crud-helper.service';
12
12
  import { ModelMetadata } from 'src/entities/model-metadata.entity';
13
13
  import { RequestContextService } from './request-context.service';
14
14
  import { Locale } from 'src/entities/locale.entity';
15
+ import { SolidRegistry } from 'src/helpers/solid-registry';
15
16
  @Injectable()
16
- export class LocaleService extends CRUDService<Locale>{
17
+ export class LocaleService extends CRUDService<Locale> implements OnApplicationBootstrap{
17
18
  constructor(
18
19
  readonly modelMetadataService: ModelMetadataService,
19
20
  readonly moduleMetadataService: ModuleMetadataService,
@@ -29,9 +30,19 @@ export class LocaleService extends CRUDService<Locale>{
29
30
  readonly moduleRef: ModuleRef,
30
31
  @InjectRepository(ModelMetadata)
31
32
  private readonly modelMetadataRepo: Repository<ModelMetadata>,
32
- readonly requestContextService: RequestContextService
33
+ readonly requestContextService: RequestContextService,
34
+ readonly solidRegistry: SolidRegistry,
33
35
  ) {
34
36
  super(modelMetadataService, moduleMetadataService, configService, fileService, discoveryService, crudHelperService,entityManager, repo, 'locale', 'solid-core', moduleRef);
35
37
  }
36
-
38
+ private readonly logger = new Logger(LocaleService.name)
39
+ onApplicationBootstrap() {
40
+ // Load the security rules from the database
41
+ this.loadLocales();
42
+ }
43
+ async loadLocales() {
44
+ const locales = await this.repo.find();
45
+ this.logger.debug(`Loaded ${locales.length} locales into registry`);
46
+ this.solidRegistry.registerlocales(locales);
47
+ }
37
48
  }
@@ -1,8 +1,8 @@
1
+ import { Logger } from '@nestjs/common';
1
2
  import { TransformFnParams } from 'class-transformer';
2
-
3
+ const logger = new Logger('datetimeTransformer');
3
4
  const datetimeTransformer = ({ value }: TransformFnParams): Date | null => {
4
- console.log("date time transformer debug", value);
5
-
5
+ logger.debug("date time transformer debug", value);
6
6
  if (value === '' || value === undefined || value === null) return null;
7
7
 
8
8
  const parsed = new Date(value);