@punks/backend-entity-manager 0.0.164 → 0.0.166

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.
@@ -8,6 +8,9 @@ import { IEntitiesDeleteResult } from "../../../abstractions/repository";
8
8
  import { QueryClauseBuilder } from "./queryClauseBuilder";
9
9
  import { BooleanFacetsType, FacetType, NumberFacetsType, StringFacetsType } from "./facets";
10
10
  import { QueryBuilderOperation } from "../../../templates/queryBuilder";
11
+ export type FacetRelations = {
12
+ columns: string[];
13
+ };
11
14
  export declare abstract class TypeOrmQueryBuilder<TEntity extends ObjectLiteral, TEntityId, TEntitySearchParameters extends IEntitySearchParameters<TEntity, TSorting, number>, TSorting extends SortingType, TFacets extends IEntityFacets, TUserContext> extends QueryBuilderBase<TEntity, TEntityId, TEntitySearchParameters, TSorting, number, TFacets, TUserContext> {
12
15
  private readonly services;
13
16
  private repository;
@@ -32,11 +35,16 @@ export declare abstract class TypeOrmQueryBuilder<TEntity extends ObjectLiteral,
32
35
  protected countQueryResults(request: TEntitySearchParameters, context?: IAuthenticationContext<TUserContext>): Promise<number>;
33
36
  protected abstract buildSortingClause(request: TEntitySearchParameters): FindOptionsOrder<TEntity>;
34
37
  protected abstract buildWhereClause(request: TEntitySearchParameters): FindOptionsWhere<TEntity>[] | FindOptionsWhere<TEntity>;
38
+ protected buildTextSearchClause(request: TEntitySearchParameters): FindOptionsWhere<TEntity>[] | FindOptionsWhere<TEntity>;
35
39
  protected abstract buildContextFilter(context?: IAuthenticationContext<TUserContext>): FindOptionsWhere<TEntity>[] | FindOptionsWhere<TEntity>;
36
40
  protected abstract calculateFacets(request: TEntitySearchParameters, context?: IAuthenticationContext<TUserContext>): Promise<TFacets>;
37
- protected calculateFacet<TField extends keyof TEntity, TValue>(field: TField, request: TEntitySearchParameters, context: IAuthenticationContext<TUserContext> | undefined): Promise<FacetType<TValue>>;
38
- protected calculateStringFieldFacets(field: keyof TEntity, request: TEntitySearchParameters, context: IAuthenticationContext<TUserContext> | undefined): Promise<StringFacetsType>;
39
- protected calculateNumericFieldFacets(field: keyof TEntity, request: TEntitySearchParameters, context: IAuthenticationContext<TUserContext> | undefined): Promise<NumberFacetsType>;
40
- protected calculateBooleanFieldFacets(field: keyof TEntity, request: TEntitySearchParameters, context: IAuthenticationContext<TUserContext> | undefined): Promise<BooleanFacetsType>;
41
+ protected calculateFacet<TField extends keyof TEntity, TValue>(field: TField, request: TEntitySearchParameters, context: IAuthenticationContext<TUserContext> | undefined, relations?: FacetRelations): Promise<FacetType<TValue>>;
42
+ protected calculateStringFieldFacets(field: keyof TEntity, request: TEntitySearchParameters, context: IAuthenticationContext<TUserContext> | undefined, relations?: FacetRelations): Promise<StringFacetsType>;
43
+ protected calculateNumericFieldFacets(field: keyof TEntity, request: TEntitySearchParameters, context: IAuthenticationContext<TUserContext> | undefined, relations?: FacetRelations): Promise<NumberFacetsType>;
44
+ protected calculateBooleanFieldFacets(field: keyof TEntity, request: TEntitySearchParameters, context: IAuthenticationContext<TUserContext> | undefined, relations?: FacetRelations): Promise<BooleanFacetsType>;
41
45
  protected getRepository(): TypeOrmRepository<TEntity, unknown>;
46
+ private buildSearchRelations;
47
+ private buildWhere;
48
+ private mergeWhereClauses;
49
+ private mergeWheres;
42
50
  }
@@ -1,11 +1,13 @@
1
1
  import { AppOrganizationEntity } from "./appOrganization.entity";
2
2
  import { IMultiOrganizationEntity } from "../../../../../extensions";
3
+ import { FooEntity } from "./foo.entity";
3
4
  export declare class CrmContactEntity implements IMultiOrganizationEntity {
4
5
  id: string;
5
6
  email: string;
6
7
  firstName: string;
7
8
  lastName: string;
8
9
  organization: AppOrganizationEntity;
10
+ foos?: FooEntity[];
9
11
  createdOn: Date;
10
12
  updatedOn: Date;
11
13
  }
@@ -1,4 +1,5 @@
1
1
  import { AppTenantEntity } from "./appTenant.entity";
2
+ import { CrmContactEntity } from "./crmContact.entity";
2
3
  export type FooEntityId = string;
3
4
  export declare class FooEntity {
4
5
  id: FooEntityId;
@@ -6,5 +7,6 @@ export declare class FooEntity {
6
7
  uid?: string;
7
8
  age?: number;
8
9
  tenant?: AppTenantEntity;
10
+ contact: CrmContactEntity;
9
11
  updatedOn: Date;
10
12
  }
@@ -6,6 +6,7 @@ import { EntityManagerRegistry } from "../../../../ioc/registry";
6
6
  import { AppUserContext, AppAuthContext } from "../../infrastructure/authentication";
7
7
  export declare class FooQueryBuilder extends NestTypeOrmQueryBuilder<FooEntity, FooEntityId, FooSearchParameters, FooSorting, FooFacets, AppUserContext> {
8
8
  constructor(registry: EntityManagerRegistry);
9
+ protected buildTextSearchClause(request: FooSearchParameters): FindOptionsWhere<FooEntity> | FindOptionsWhere<FooEntity>[];
9
10
  protected buildContextFilter(context?: AppAuthContext | undefined): FindOptionsWhere<FooEntity> | FindOptionsWhere<FooEntity>[];
10
11
  protected buildSortingClause(request: FooSearchParameters): FindOptionsOrder<FooEntity>;
11
12
  protected buildWhereClause(request: FooSearchParameters): FindOptionsWhere<FooEntity> | FindOptionsWhere<FooEntity>[];
package/dist/esm/index.js CHANGED
@@ -440,9 +440,8 @@ class EntitiesSearchAction {
440
440
  this.services = services;
441
441
  }
442
442
  async execute(request) {
443
- const results = await this.services
444
- .resolveSearchQuery()
445
- .execute(request);
443
+ const searchQuery = this.services.resolveSearchQuery();
444
+ const results = await searchQuery.execute(request);
446
445
  const converter = this.services.resolveConverter();
447
446
  return {
448
447
  facets: results.facets,
@@ -625,7 +624,7 @@ class EntitiesDeleteCommand {
625
624
  return undefined;
626
625
  }
627
626
  const contextService = this.services.resolveAuthenticationContextProvider();
628
- return await contextService.getContext();
627
+ return await contextService?.getContext();
629
628
  }
630
629
  async authorize() {
631
630
  const authorization = this.services.resolveAuthorizationMiddleware();
@@ -1715,7 +1714,7 @@ class EntitiesCountQuery {
1715
1714
  return undefined;
1716
1715
  }
1717
1716
  const contextService = this.services.resolveAuthenticationContextProvider();
1718
- return await contextService.getContext();
1717
+ return await contextService?.getContext();
1719
1718
  }
1720
1719
  async authorizeSearch(context) {
1721
1720
  const authorization = this.services.resolveAuthorizationMiddleware();
@@ -1746,7 +1745,7 @@ class EntityExistsQuery {
1746
1745
  return undefined;
1747
1746
  }
1748
1747
  const contextService = this.services.resolveAuthenticationContextProvider();
1749
- return await contextService.getContext();
1748
+ return await contextService?.getContext();
1750
1749
  }
1751
1750
  async authorizeSearch(context) {
1752
1751
  const authorization = this.services.resolveAuthorizationMiddleware();
@@ -1852,9 +1851,8 @@ class EntitiesSearchQuery {
1852
1851
  async execute(request) {
1853
1852
  const context = await this.getContext();
1854
1853
  await this.authorizeSearch(context);
1855
- const result = await this.services
1856
- .resolveQueryBuilder()
1857
- .search(request, context);
1854
+ const queryBuilder = this.services.resolveQueryBuilder();
1855
+ const result = await queryBuilder.search(request, context);
1858
1856
  const filteredEntities = await this.filterAllowedEntities(result.items, context);
1859
1857
  return {
1860
1858
  ...result,
@@ -1921,7 +1919,7 @@ class EntityVersionsSearchQuery {
1921
1919
  return undefined;
1922
1920
  }
1923
1921
  const contextService = this.services.resolveAuthenticationContextProvider();
1924
- return await contextService.getContext();
1922
+ return await contextService?.getContext();
1925
1923
  }
1926
1924
  async authorizeSearch(context) {
1927
1925
  const authorization = this.services.resolveAuthorizationMiddleware();
@@ -22214,10 +22212,7 @@ class TypeOrmQueryBuilder extends QueryBuilderBase {
22214
22212
  const request = {
22215
22213
  filters,
22216
22214
  };
22217
- return await this.getRepository().deleteBy({
22218
- ...(context ? this.buildContextFilter(context) : {}),
22219
- ...this.buildWhereClause(request),
22220
- });
22215
+ return await this.getRepository().deleteBy(this.buildWhere(request, context));
22221
22216
  }
22222
22217
  async find(request, context) {
22223
22218
  const results = await this.findPagedQueryResults({
@@ -22249,20 +22244,13 @@ class TypeOrmQueryBuilder extends QueryBuilderBase {
22249
22244
  }
22250
22245
  async getFieldDistinctValues(field, request, context) {
22251
22246
  return await this.getRepository().distinct(field, {
22252
- where: {
22253
- ...(context ? this.buildContextFilter(context) : {}),
22254
- ...this.buildWhereClause(request),
22255
- },
22247
+ where: this.buildWhere(request, context),
22256
22248
  });
22257
22249
  }
22258
22250
  async findPagedQueryResults(request, context) {
22259
22251
  return await this.getRepository().find({
22260
- where: {
22261
- ...(context ? this.buildContextFilter(context) : {}),
22262
- ...this.buildWhereClause(request),
22263
- },
22264
- relations: request.relations ??
22265
- this.getRelationsToLoad(request, context, QueryBuilderOperation.Search),
22252
+ where: this.buildWhere(request, context),
22253
+ relations: this.buildSearchRelations(request, context),
22266
22254
  order: this.buildSortingClause(request),
22267
22255
  ...this.buildPagingParameters(request),
22268
22256
  });
@@ -22280,23 +22268,23 @@ class TypeOrmQueryBuilder extends QueryBuilderBase {
22280
22268
  }
22281
22269
  async countQueryResults(request, context) {
22282
22270
  return await this.getRepository().count({
22283
- where: {
22284
- ...(context ? this.buildContextFilter(context) : {}),
22285
- ...this.buildWhereClause(request),
22286
- },
22271
+ where: this.buildWhere(request, context),
22287
22272
  });
22288
22273
  }
22289
- async calculateFacet(field, request, context) {
22290
- const where = {
22291
- ...(context ? this.buildContextFilter(context) : {}),
22292
- ...this.buildWhereClause(request),
22293
- };
22294
- const results = await this.getRepository()
22274
+ buildTextSearchClause(request) {
22275
+ return {};
22276
+ }
22277
+ async calculateFacet(field, request, context, relations) {
22278
+ let query = this.getRepository()
22295
22279
  .getInnerRepository()
22296
- .createQueryBuilder()
22280
+ .createQueryBuilder("entity");
22281
+ for (const relation of relations?.columns ?? []) {
22282
+ query = query.leftJoin(`entity.${relation}`, relation);
22283
+ }
22284
+ const results = await query
22297
22285
  .select(field, "value")
22298
22286
  .addSelect(`COUNT(${field})`, "count")
22299
- .where(where)
22287
+ .where(this.buildWhere(request, context))
22300
22288
  .addGroupBy(field)
22301
22289
  .orderBy(field)
22302
22290
  .getRawMany();
@@ -22307,34 +22295,67 @@ class TypeOrmQueryBuilder extends QueryBuilderBase {
22307
22295
  })),
22308
22296
  };
22309
22297
  }
22310
- async calculateStringFieldFacets(field, request, context) {
22311
- return await this.calculateFacet(field, request, context);
22312
- }
22313
- async calculateNumericFieldFacets(field, request, context) {
22314
- return await this.calculateFacet(field, request, context);
22315
- }
22316
- async calculateBooleanFieldFacets(field, request, context) {
22317
- return await this.calculateFacet(field, request, context);
22318
- }
22319
- // protected async calculateFacet<TField extends keyof TEntity, TValue>(
22320
- // field: TField,
22321
- // request: TEntitySearchParameters,
22322
- // context: IAuthenticationContext<TUserContext> | undefined
22323
- // ): Promise<Facet<TValue>> {
22324
- // const values = await this.getRepository().distinct<TField, TValue>(field, {
22325
- // ...(context ? this.buildContextFilter(context) : {}),
22326
- // ...this.buildWhereClause(request),
22327
- // } as any)
22328
- // return {
22329
- // values,
22330
- // }
22331
- // }
22298
+ async calculateStringFieldFacets(field, request, context, relations) {
22299
+ return await this.calculateFacet(field, request, context, relations);
22300
+ }
22301
+ async calculateNumericFieldFacets(field, request, context, relations) {
22302
+ return await this.calculateFacet(field, request, context, relations);
22303
+ }
22304
+ async calculateBooleanFieldFacets(field, request, context, relations) {
22305
+ return await this.calculateFacet(field, request, context, relations);
22306
+ }
22332
22307
  getRepository() {
22333
22308
  if (!this.repository) {
22334
22309
  this.repository = this.services.resolveRepository();
22335
22310
  }
22336
22311
  return this.repository;
22337
22312
  }
22313
+ buildSearchRelations(request, context) {
22314
+ return (request.relations ??
22315
+ this.getRelationsToLoad(request, context, QueryBuilderOperation.Search));
22316
+ }
22317
+ buildWhere(request, context) {
22318
+ return this.mergeWhereClauses(context ? this.buildContextFilter(context) : {}, this.buildWhereClause(request), this.buildTextSearchClause(request));
22319
+ }
22320
+ mergeWhereClauses(...clauses) {
22321
+ return clauses.reduce((a, b) => this.mergeWheres(a, b));
22322
+ }
22323
+ mergeWheres(a, b) {
22324
+ if (Array.isArray(a) && Array.isArray(b)) {
22325
+ const result = [];
22326
+ for (const x of a) {
22327
+ for (const y of b) {
22328
+ result.push({
22329
+ ...x,
22330
+ ...y,
22331
+ });
22332
+ }
22333
+ }
22334
+ return result;
22335
+ }
22336
+ if (!Array.isArray(a) && !Array.isArray(b)) {
22337
+ return {
22338
+ ...a,
22339
+ ...b,
22340
+ };
22341
+ }
22342
+ if (Array.isArray(a) && !Array.isArray(b)) {
22343
+ return a.map((x) => ({
22344
+ ...x,
22345
+ ...b,
22346
+ }));
22347
+ }
22348
+ if (!Array.isArray(a) && Array.isArray(b)) {
22349
+ return b.map((x) => ({
22350
+ ...a,
22351
+ ...x,
22352
+ }));
22353
+ }
22354
+ return {
22355
+ ...a,
22356
+ ...b,
22357
+ };
22358
+ }
22338
22359
  }
22339
22360
 
22340
22361
  class TypeOrmRepository {