@punks/backend-entity-manager 0.0.131 → 0.0.133

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.
@@ -1,7 +1,7 @@
1
1
  import { IEntityManagerServiceRoot } from "../../abstractions/configuration";
2
2
  import { IEntityConverter } from "../../abstractions/converters";
3
3
  import { IEntitiesQueryBuilder } from "../../abstractions/queries";
4
- import { IEntitySearchParameters } from "../../abstractions/searchParameters";
4
+ import { IEntitySearchParameters, ISearchSorting } from "../../abstractions/searchParameters";
5
5
  import { IEntitiesSearchResults } from "../../models";
6
6
  import { EntityServiceLocator } from "../../providers/services";
7
7
  import { InMemoryRepository } from "../../testing/mocks/repository";
@@ -35,6 +35,10 @@ export interface FooFacets {
35
35
  export declare class FooQueryBuilder implements IEntitiesQueryBuilder<FooEntity, string, FooSearchParameters, FooSorting, FooCursor, FooFacets, unknown> {
36
36
  private readonly repository;
37
37
  constructor(services: EntityServiceLocator<FooEntity, string>);
38
+ find(request?: {
39
+ filters?: FooSearchFilters | undefined;
40
+ sorting?: ISearchSorting<FooSorting> | undefined;
41
+ } | undefined, context?: IAuthenticationContext<unknown> | undefined): Promise<FooEntity>;
38
42
  get(id: string): Promise<FooEntity | undefined>;
39
43
  exists(filters: FooSearchFilters, context?: IAuthenticationContext<unknown> | undefined): Promise<boolean>;
40
44
  count(filters: FooSearchFilters, context?: IAuthenticationContext<unknown> | undefined): Promise<number>;
@@ -7,7 +7,8 @@ export declare enum EntityOperationType {
7
7
  Update = 1,
8
8
  Delete = 2,
9
9
  Read = 3,
10
- Search = 4
10
+ Search = 4,
11
+ Find = 5
11
12
  }
12
13
  export declare abstract class EntityManagerUnauthorizedException extends EntityManagerException {
13
14
  constructor(message: string);
@@ -10,6 +10,12 @@ export interface IEntitiesSearchQuery<TEntity, TEntitySearchParameters extends I
10
10
  export interface IEntityGetQuery<TEntity, TEntityId> {
11
11
  execute(id: TEntityId): Promise<TEntity | undefined>;
12
12
  }
13
+ export interface IEntitiesFindQuery<TEntity, TEntitySearchParameters extends IEntitySearchParameters<TSorting, TCursor>, TSorting extends SortingType, TCursor> {
14
+ execute(request: {
15
+ filters?: TEntitySearchParameters["filters"];
16
+ sorting?: TEntitySearchParameters["sorting"];
17
+ }): Promise<TEntity>;
18
+ }
13
19
  export interface IEntityExistsQuery<TEntity, TEntityFilters extends ISearchFilters> {
14
20
  execute(filters: TEntityFilters): Promise<boolean>;
15
21
  }
@@ -21,6 +27,10 @@ export interface IEntityVersionsSearchQuery<TEntity, TCursor> {
21
27
  }
22
28
  export interface IEntitiesQueryBuilder<TEntity, TEntityId, TEntitySearchParameters extends IEntitySearchParameters<TSorting, TCursor>, TSorting extends SortingType, TCursor, TFacets extends IEntityFacets, TUserContext> {
23
29
  get(id: TEntityId, context?: IAuthenticationContext<TUserContext>): Promise<TEntity | undefined>;
30
+ find(request?: {
31
+ filters?: TEntitySearchParameters["filters"];
32
+ sorting?: TEntitySearchParameters["sorting"];
33
+ }, context?: IAuthenticationContext<TUserContext>): Promise<TEntity>;
24
34
  search(request: TEntitySearchParameters, context?: IAuthenticationContext<TUserContext>): Promise<IEntitiesSearchResults<TEntitySearchParameters, TEntity, TSorting, TCursor, TFacets>>;
25
35
  exists(filters: NonNullable<TEntitySearchParameters["filters"]>, context?: IAuthenticationContext<TUserContext>): Promise<boolean>;
26
36
  count(filters: NonNullable<TEntitySearchParameters["filters"]>, context?: IAuthenticationContext<TUserContext>): Promise<number>;
@@ -2,7 +2,7 @@ import { IEntitiesCountAction, IEntitiesDeleteAction, IEntitiesExportAction, IEn
2
2
  import { IEntitiesDeleteCommand, IEntitiesDeleteParameters, IEntitiesExportCommand, IEntitiesImportCommand, IEntitiesSampleDownloadCommand, IEntityCreateCommand, IEntityDeleteCommand, IEntityUpdateCommand, IEntityUpsertCommand } from "../abstractions/commands";
3
3
  import { SortingType } from "../abstractions/common";
4
4
  import { IEntityManager } from "../abstractions/manager";
5
- import { IEntitiesCountQuery, IEntitiesSearchQuery, IEntityExistsQuery, IEntityGetQuery, IEntityVersionsSearchQuery } from "../abstractions/queries";
5
+ import { IEntitiesCountQuery, IEntitiesFindQuery, IEntitiesSearchQuery, IEntityExistsQuery, IEntityGetQuery, IEntityVersionsSearchQuery } from "../abstractions/queries";
6
6
  import { IEntitySearchParameters } from "../abstractions/searchParameters";
7
7
  import { IEntityFacets } from "../abstractions/searchResults";
8
8
  import { EntityServiceLocator } from "../providers/services";
@@ -14,6 +14,7 @@ export declare class EntityManager<TEntity, TEntityId, TEntityCreateData, TEntit
14
14
  get deleteItems(): IEntitiesDeleteCommand<TEntity, TEntitiesDeleteParameters, TSorting>;
15
15
  get get(): IEntityGetQuery<TEntity, TEntityId>;
16
16
  get search(): IEntitiesSearchQuery<TEntity, TEntitySearchParameters, TSorting, TCursor, TFacets>;
17
+ get find(): IEntitiesFindQuery<TEntity, TEntitySearchParameters, TSorting, TCursor>;
17
18
  get create(): IEntityCreateCommand<TEntity, TEntityCreateData>;
18
19
  get update(): IEntityUpdateCommand<TEntity, TEntityId, TEntityUpdateData>;
19
20
  get upsert(): IEntityUpsertCommand<TEntity, TEntityId, TEntityUpdateData>;
@@ -17,6 +17,10 @@ export declare abstract class TypeOrmQueryBuilder<TEntity extends ObjectLiteral,
17
17
  exists(filters: NonNullable<TEntitySearchParameters["filters"]>, context?: IAuthenticationContext<TUserContext> | undefined): Promise<boolean>;
18
18
  count(filters: NonNullable<TEntitySearchParameters["filters"]>, context?: IAuthenticationContext<TUserContext> | undefined): Promise<number>;
19
19
  delete(filters: NonNullable<TEntitySearchParameters["filters"]>, context?: IAuthenticationContext<TUserContext> | undefined): Promise<IEntitiesDeleteResult>;
20
+ find(request: {
21
+ filters?: TEntitySearchParameters["filters"];
22
+ sorting?: TEntitySearchParameters["sorting"];
23
+ }, context?: IAuthenticationContext<TUserContext>): Promise<TEntity>;
20
24
  search(request: TEntitySearchParameters, context?: IAuthenticationContext<TUserContext>): Promise<IEntitiesSearchResults<TEntitySearchParameters, TEntity, TSorting, number, TFacets>>;
21
25
  protected getFieldFacet(): Promise<void>;
22
26
  protected findPagedQueryResults(request: TEntitySearchParameters, context?: IAuthenticationContext<TUserContext>): Promise<TEntity[]>;
@@ -9,7 +9,7 @@ import { IEntityConverter } from "../abstractions/converters";
9
9
  import { IEntityEventsManager, IEventEmitter } from "../abstractions/events";
10
10
  import { IEntityManager } from "../abstractions/manager";
11
11
  import { IPipelinesController } from "../abstractions/pipelines";
12
- import { IEntitiesCountQuery, IEntitiesQueryBuilder, IEntitiesSearchQuery, IEntityExistsQuery, IEntityGetQuery, IEntityVersionsSearchQuery } from "../abstractions/queries";
12
+ import { IEntitiesCountQuery, IEntitiesFindQuery, IEntitiesQueryBuilder, IEntitiesSearchQuery, IEntityExistsQuery, IEntityGetQuery, IEntityVersionsSearchQuery } from "../abstractions/queries";
13
13
  import { IEntityReplicaDeleteManager, IEntityReplicaSyncManager, IReplicasConfiguration } from "../abstractions/replication";
14
14
  import { IEntityRepository } from "../abstractions/repository";
15
15
  import { IEntitySearchParameters, ISearchFilters } from "../abstractions/searchParameters";
@@ -42,6 +42,7 @@ export declare class EntityServiceLocator<TEntity, TEntityId> {
42
42
  resolveCountQuery<TEntityFilters extends ISearchFilters>(): IEntitiesCountQuery<TEntity, TEntityFilters>;
43
43
  resolveVersionsSearchQuery<TCursor>(): IEntityVersionsSearchQuery<TEntity, TCursor>;
44
44
  resolveSearchQuery<TEntitySearchParameters extends IEntitySearchParameters<TSorting, TCursor>, TSorting extends SortingType, TCursor, TFacets extends IEntityFacets>(): IEntitiesSearchQuery<TEntity, TEntitySearchParameters, TSorting, TCursor, TFacets>;
45
+ resolveFindQuery<TEntitySearchParameters extends IEntitySearchParameters<TSorting, TCursor>, TSorting extends SortingType, TCursor>(): IEntitiesFindQuery<TEntity, TEntitySearchParameters, TSorting, TCursor>;
45
46
  resolveCreateCommand<TEntityCreateData>(): IEntityCreateCommand<TEntity, TEntityCreateData>;
46
47
  resolveUpdateCommand<TEntityUpdateData>(): IEntityUpdateCommand<TEntity, TEntityId, TEntityUpdateData>;
47
48
  resolveUpsertCommand<TEntityUpdateData>(): IEntityUpsertCommand<TEntity, TEntityId, TEntityUpdateData>;
@@ -128,6 +129,8 @@ export declare class EntitiesServiceLocator {
128
129
  registerGetQuery<TEntity, TEntityId>(entityName: string, instance: IEntityGetQuery<TEntity, TEntityId>): void;
129
130
  resolveSearchQuery<TEntity, TEntitySearchParameters extends IEntitySearchParameters<TSorting, TCursor>, TSorting extends SortingType, TCursor, TFacets extends IEntityFacets>(entityName: string): IEntitiesSearchQuery<TEntity, TEntitySearchParameters, TSorting, TCursor, TFacets>;
130
131
  registerSearchQuery<TEntity, TEntitySearchParameters extends IEntitySearchParameters<TSorting, TCursor>, TSorting extends SortingType, TCursor, TFacets extends IEntityFacets>(entityName: string, instance: IEntitiesSearchQuery<TEntity, TEntitySearchParameters, TSorting, TCursor, TFacets>): void;
132
+ resolveFindQuery<TEntity, TEntitySearchParameters extends IEntitySearchParameters<TSorting, TCursor>, TSorting extends SortingType, TCursor>(entityName: string): IEntitiesFindQuery<TEntity, TEntitySearchParameters, TSorting, TCursor>;
133
+ registerFindQuery<TEntity, TEntitySearchParameters extends IEntitySearchParameters<TSorting, TCursor>, TSorting extends SortingType, TCursor>(entityName: string, instance: IEntitiesFindQuery<TEntity, TEntitySearchParameters, TSorting, TCursor>): void;
131
134
  resolveExistsQuery<TEntity, TEntityFilters extends ISearchFilters>(entityName: string): IEntityExistsQuery<TEntity, TEntityFilters>;
132
135
  registerExistsQuery<TEntity, TEntityFilters extends ISearchFilters>(entityName: string, instance: IEntityExistsQuery<TEntity, TEntityFilters>): void;
133
136
  resolveCountQuery<TEntity, TEntityFilters extends ISearchFilters>(entityName: string): IEntitiesCountQuery<TEntity, TEntityFilters>;
@@ -0,0 +1,12 @@
1
+ import { SortingType } from "../abstractions/common";
2
+ import { IEntitiesFindQuery } from "../abstractions/queries";
3
+ import { IEntitySearchParameters } from "../abstractions/searchParameters";
4
+ import { EntityServiceLocator } from "../providers/services";
5
+ export declare class EntitiesFindQuery<TEntity, TEntityId, TEntitySearchParameters extends IEntitySearchParameters<TSorting, TCursor>, TSorting extends SortingType, TCursor, TUserContext> implements IEntitiesFindQuery<TEntity, TEntitySearchParameters, TSorting, TCursor> {
6
+ private readonly services;
7
+ constructor(services: EntityServiceLocator<TEntity, TEntityId>);
8
+ execute(request: TEntitySearchParameters): Promise<TEntity>;
9
+ private getContext;
10
+ private filterAllowedEntities;
11
+ private authorizeSearch;
12
+ }
@@ -46,6 +46,7 @@ export declare const EntityServices: {
46
46
  IEntityCountQuery: string;
47
47
  IEntityExistsQuery: string;
48
48
  IEntityGetQuery: string;
49
+ IEntitiesFindQuery: string;
49
50
  IEntitiesSearchQuery: string;
50
51
  IEntitiesQueryBuilder: string;
51
52
  IEntityVersionsSearchQuery: string;
@@ -12,6 +12,10 @@ export declare abstract class QueryBuilderBase<TEntity, TEntityId, TEntitySearch
12
12
  abstract count(filters: NonNullable<TEntitySearchParameters["filters"]>, context?: IAuthenticationContext<TUserContext> | undefined): Promise<number>;
13
13
  abstract delete(filters: NonNullable<TEntitySearchParameters["filters"]>, context?: IAuthenticationContext<TUserContext> | undefined): Promise<IEntitiesDeleteResult>;
14
14
  abstract search(request: TEntitySearchParameters, context?: IAuthenticationContext<TUserContext>): Promise<IEntitiesSearchResults<TEntitySearchParameters, TEntity, TSorting, TCursor, TFacets>>;
15
+ abstract find(request: {
16
+ filters?: TEntitySearchParameters["filters"];
17
+ sorting?: TEntitySearchParameters["sorting"];
18
+ }, context?: IAuthenticationContext<TUserContext>): Promise<TEntity>;
15
19
  protected getIndexBasedPagingResult({ paging, totResults, currentPageResults, }: {
16
20
  paging?: ISearchRequestPaging<number>;
17
21
  totResults: number;
package/dist/esm/index.js CHANGED
@@ -35,6 +35,7 @@ var EntityOperationType;
35
35
  EntityOperationType[EntityOperationType["Delete"] = 2] = "Delete";
36
36
  EntityOperationType[EntityOperationType["Read"] = 3] = "Read";
37
37
  EntityOperationType[EntityOperationType["Search"] = 4] = "Search";
38
+ EntityOperationType[EntityOperationType["Find"] = 5] = "Find";
38
39
  })(EntityOperationType || (EntityOperationType = {}));
39
40
  class EntityManagerUnauthorizedException extends EntityManagerException {
40
41
  constructor(message) {
@@ -911,6 +912,9 @@ class EntityManager {
911
912
  get search() {
912
913
  return this.services.resolveSearchQuery();
913
914
  }
915
+ get find() {
916
+ return this.services.resolveFindQuery();
917
+ }
914
918
  get create() {
915
919
  return this.services.resolveCreateCommand();
916
920
  }
@@ -1095,6 +1099,7 @@ const EntityServices = {
1095
1099
  IEntityCountQuery: "IEntityCountQuery",
1096
1100
  IEntityExistsQuery: "IEntityExistsQuery",
1097
1101
  IEntityGetQuery: "IEntityGetQuery",
1102
+ IEntitiesFindQuery: "IEntitiesFindQuery",
1098
1103
  IEntitiesSearchQuery: "IEntitiesSearchQuery",
1099
1104
  IEntitiesQueryBuilder: "IEntitiesQueryBuilder",
1100
1105
  IEntityVersionsSearchQuery: "IEntityVersionsSearchQuery",
@@ -1217,6 +1222,9 @@ class EntityServiceLocator {
1217
1222
  resolveSearchQuery() {
1218
1223
  return this.services.resolveSearchQuery(this.entityName);
1219
1224
  }
1225
+ resolveFindQuery() {
1226
+ return this.services.resolveFindQuery(this.entityName);
1227
+ }
1220
1228
  resolveCreateCommand() {
1221
1229
  return this.services.resolveCreateCommand(this.entityName);
1222
1230
  }
@@ -1483,6 +1491,12 @@ class EntitiesServiceLocator {
1483
1491
  registerSearchQuery(entityName, instance) {
1484
1492
  this.provider.registerEntityService(EntityServices.Queries.IEntitiesSearchQuery, entityName, instance);
1485
1493
  }
1494
+ resolveFindQuery(entityName) {
1495
+ return this.provider.resolveEntityService(EntityServices.Queries.IEntitiesSearchQuery, entityName);
1496
+ }
1497
+ registerFindQuery(entityName, instance) {
1498
+ this.provider.registerEntityService(EntityServices.Queries.IEntitiesFindQuery, entityName, instance);
1499
+ }
1486
1500
  resolveExistsQuery(entityName) {
1487
1501
  return this.provider.resolveEntityService(EntityServices.Queries.IEntityExistsQuery, entityName);
1488
1502
  }
@@ -1697,6 +1711,53 @@ class EntityExistsQuery {
1697
1711
  }
1698
1712
  }
1699
1713
 
1714
+ class EntitiesFindQuery {
1715
+ constructor(services) {
1716
+ this.services = services;
1717
+ }
1718
+ async execute(request) {
1719
+ const context = await this.getContext();
1720
+ await this.authorizeSearch(context);
1721
+ const result = await this.services
1722
+ .resolveQueryBuilder()
1723
+ .find(request, context);
1724
+ const filteredEntities = await this.filterAllowedEntities([result], context);
1725
+ return filteredEntities[0];
1726
+ }
1727
+ async getContext() {
1728
+ const authorization = this.services.resolveAuthorizationMiddleware();
1729
+ if (!authorization) {
1730
+ return undefined;
1731
+ }
1732
+ const contextService = this.services.resolveAuthenticationContextProvider();
1733
+ return await contextService?.getContext();
1734
+ }
1735
+ async filterAllowedEntities(entities, context) {
1736
+ const authorization = this.services.resolveAuthorizationMiddleware();
1737
+ if (!authorization) {
1738
+ return entities;
1739
+ }
1740
+ const filteredEntities = await Promise.all(entities.map(async (entity) => {
1741
+ const authorizationResult = await authorization.canRead(entity, context);
1742
+ if (!authorizationResult.isAuthorized) {
1743
+ return null;
1744
+ }
1745
+ return entity;
1746
+ }));
1747
+ return filteredEntities.filter((entity) => entity !== null);
1748
+ }
1749
+ async authorizeSearch(context) {
1750
+ const authorization = this.services.resolveAuthorizationMiddleware();
1751
+ if (!authorization) {
1752
+ return;
1753
+ }
1754
+ const { isAuthorized } = await authorization.canSearch(context);
1755
+ if (!isAuthorized) {
1756
+ throw new EntityOperationUnauthorizedException(EntityOperationType.Find, this.services.getEntityName());
1757
+ }
1758
+ }
1759
+ }
1760
+
1700
1761
  class EntityGetQuery {
1701
1762
  constructor(services) {
1702
1763
  this.services = services;
@@ -2096,6 +2157,7 @@ class EntityManagerServiceCollection {
2096
2157
  return this;
2097
2158
  }
2098
2159
  mapSearch({ queryBuilder, }) {
2160
+ this.locator.registerFindQuery(this.entityName, new EntitiesFindQuery(this.resolver));
2099
2161
  this.locator.registerSearchQuery(this.entityName, new EntitiesSearchQuery(this.resolver));
2100
2162
  this.locator.registerSearchAction(this.entityName, new EntitiesSearchAction(this.resolver));
2101
2163
  this.locator.registerQueryBuilder(this.entityName, queryBuilder);
@@ -22055,6 +22117,16 @@ class TypeOrmQueryBuilder extends QueryBuilderBase {
22055
22117
  ...this.buildWhereClause(request),
22056
22118
  });
22057
22119
  }
22120
+ async find(request, context) {
22121
+ const results = await this.findPagedQueryResults({
22122
+ filters: request.filters,
22123
+ sorting: request.sorting,
22124
+ paging: {
22125
+ pageSize: 1,
22126
+ },
22127
+ }, context);
22128
+ return results[0];
22129
+ }
22058
22130
  async search(request, context) {
22059
22131
  // todo: execute inside read transaction in order to perform the three queries on the same dataset
22060
22132
  const queryResults = await this.countQueryResults(request, context);