mongodb-dynamic-api 2.1.1 → 2.1.3

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 (57) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/package.json +1 -1
  3. package/src/builders/casl/casl-ability.builder.d.ts +2 -2
  4. package/src/builders/casl/casl-ability.builder.js +7 -4
  5. package/src/dtos/delete.presenter.d.ts +3 -0
  6. package/src/{routes/delete-one/delete-one.presenter.js → dtos/delete.presenter.js} +4 -4
  7. package/src/dtos/index.d.ts +1 -0
  8. package/src/dtos/index.js +1 -0
  9. package/src/guards/base-policies.guard.d.ts +2 -2
  10. package/src/helpers/controller-ability-predicates.helper.d.ts +2 -2
  11. package/src/helpers/controller-mixin.helper.d.ts +66 -0
  12. package/src/helpers/controller-mixin.helper.js +159 -0
  13. package/src/helpers/format.helper.d.ts +1 -0
  14. package/src/helpers/format.helper.js +5 -1
  15. package/src/interfaces/dynamic-api-casl-ability.interface.d.ts +8 -5
  16. package/src/interfaces/dynamic-api-casl-ability.interface.js +3 -0
  17. package/src/interfaces/dynamic-api-controller-options.interface.d.ts +2 -2
  18. package/src/interfaces/dynamic-api-policy-handler.interface.d.ts +3 -5
  19. package/src/interfaces/dynamic-api-route-config.interface.d.ts +2 -2
  20. package/src/mixins/create-policies-guard.mixin.d.ts +2 -2
  21. package/src/modules/auth/interfaces/auth-options.interface.d.ts +2 -2
  22. package/src/modules/auth/mixins/auth-register-policies-guard.mixin.d.ts +2 -2
  23. package/src/modules/auth/services/base-auth.service.d.ts +1 -0
  24. package/src/modules/auth/services/base-auth.service.js +7 -4
  25. package/src/routes/create-many/create-many-controller.mixin.d.ts +1 -1
  26. package/src/routes/create-many/create-many-controller.mixin.js +6 -54
  27. package/src/routes/create-one/create-one-controller.mixin.d.ts +1 -1
  28. package/src/routes/create-one/create-one-controller.mixin.js +6 -35
  29. package/src/routes/delete-many/base-delete-many.service.d.ts +2 -2
  30. package/src/routes/delete-many/base-delete-many.service.js +2 -2
  31. package/src/routes/delete-many/delete-many-controller.mixin.d.ts +1 -1
  32. package/src/routes/delete-many/delete-many-controller.mixin.js +4 -28
  33. package/src/routes/delete-many/index.d.ts +0 -1
  34. package/src/routes/delete-many/index.js +0 -1
  35. package/src/routes/delete-one/base-delete-one.service.d.ts +2 -2
  36. package/src/routes/delete-one/base-delete-one.service.js +2 -2
  37. package/src/routes/delete-one/delete-one-controller.mixin.d.ts +1 -1
  38. package/src/routes/delete-one/delete-one-controller.mixin.js +5 -37
  39. package/src/routes/delete-one/index.d.ts +0 -1
  40. package/src/routes/delete-one/index.js +0 -1
  41. package/src/routes/duplicate-many/duplicate-many-controller.mixin.d.ts +1 -1
  42. package/src/routes/duplicate-many/duplicate-many-controller.mixin.js +6 -35
  43. package/src/routes/duplicate-one/duplicate-one-controller.mixin.d.ts +1 -1
  44. package/src/routes/duplicate-one/duplicate-one-controller.mixin.js +6 -42
  45. package/src/routes/get-many/get-many-controller.mixin.d.ts +1 -1
  46. package/src/routes/get-many/get-many-controller.mixin.js +5 -35
  47. package/src/routes/get-one/get-one-controller.mixin.d.ts +1 -1
  48. package/src/routes/get-one/get-one-controller.mixin.js +5 -42
  49. package/src/routes/replace-one/replace-one-controller.mixin.d.ts +1 -1
  50. package/src/routes/replace-one/replace-one-controller.mixin.js +6 -43
  51. package/src/routes/update-many/update-many-controller.mixin.d.ts +1 -1
  52. package/src/routes/update-many/update-many-controller.mixin.js +5 -34
  53. package/src/routes/update-one/update-one-controller.mixin.d.ts +1 -1
  54. package/src/routes/update-one/update-one-controller.mixin.js +6 -43
  55. package/src/version.json +1 -1
  56. package/tsconfig.tsbuildinfo +1 -1
  57. package/src/routes/delete-one/delete-one.presenter.d.ts +0 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  Changelog
2
2
 
3
+ ## [2.1.3](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v2.1.2...v2.1.3) (2024-03-29)
4
+
5
+ ## [2.1.2](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v2.1.1...v2.1.2) (2024-03-26)
6
+
7
+
8
+ * rename all custom dto to avoid swagger conflicts ([0bc7e5f](https://github.com/MikeDev75015/mongodb-dynamic-api/commit/0bc7e5fe85f3c44ce3382839e5a502d3232e5526))
9
+
3
10
  ## [2.1.1](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v2.1.0...v2.1.1) (2024-03-21)
4
11
 
5
12
  ## [2.1.0](https://github.com/MikeDev75015/mongodb-dynamic-api/compare/v2.0.0...v2.1.0) (2024-03-20)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mongodb-dynamic-api",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "Auto generated CRUD API for MongoDB using NestJS",
5
5
  "readmeFilename": "README.md",
6
6
  "main": "index.js",
@@ -1,5 +1,5 @@
1
1
  import { Type } from '@nestjs/common';
2
- import { AppAbility, DynamicApiRouteCaslAbilityPredicate, RouteType } from '../../interfaces';
2
+ import { AppAbility, RouteAbilityPredicate, RouteType } from '../../interfaces';
3
3
  import { BaseEntity } from '../../models';
4
- declare function CaslAbilityBuilder<Entity extends BaseEntity>(entity: Type<Entity>, routeType: RouteType, abilityPredicate: DynamicApiRouteCaslAbilityPredicate<Entity>, user: unknown): AppAbility<Entity>;
4
+ declare function CaslAbilityBuilder<Entity extends BaseEntity>(entity: Type<Entity>, routeType: RouteType, abilityPredicate: RouteAbilityPredicate<Entity>, user: unknown): AppAbility<Entity>;
5
5
  export { CaslAbilityBuilder };
@@ -2,13 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CaslAbilityBuilder = void 0;
4
4
  const ability_1 = require("@casl/ability");
5
+ const interfaces_1 = require("../../interfaces");
5
6
  function CaslAbilityBuilder(entity, routeType, abilityPredicate, user) {
6
- const { can, build } = new ability_1.AbilityBuilder(ability_1.createMongoAbility);
7
- if (abilityPredicate(new entity(), user)) {
8
- can(routeType, entity);
7
+ if (!entity || !routeType || !abilityPredicate || !user) {
8
+ throw new Error('Invalid parameters, cannot build ability');
9
9
  }
10
+ const { can, build } = new ability_1.AbilityBuilder(ability_1.PureAbility);
11
+ can(routeType, entity, (instance) => abilityPredicate(instance, user));
10
12
  return build({
11
- detectSubjectType: (object) => object.constructor
13
+ conditionsMatcher: interfaces_1.lambdaMatcher,
14
+ detectSubjectType: (object) => object.constructor,
12
15
  });
13
16
  }
14
17
  exports.CaslAbilityBuilder = CaslAbilityBuilder;
@@ -0,0 +1,3 @@
1
+ export declare class DeletePresenter {
2
+ deletedCount: number;
3
+ }
@@ -9,12 +9,12 @@ var __metadata = (this && this.__metadata) || function (k, v) {
9
9
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.DeleteOnePresenter = void 0;
12
+ exports.DeletePresenter = void 0;
13
13
  const swagger_1 = require("@nestjs/swagger");
14
- class DeleteOnePresenter {
14
+ class DeletePresenter {
15
15
  }
16
- exports.DeleteOnePresenter = DeleteOnePresenter;
16
+ exports.DeletePresenter = DeletePresenter;
17
17
  __decorate([
18
18
  (0, swagger_1.ApiProperty)(),
19
19
  __metadata("design:type", Number)
20
- ], DeleteOnePresenter.prototype, "deletedCount", void 0);
20
+ ], DeletePresenter.prototype, "deletedCount", void 0);
@@ -1,3 +1,4 @@
1
1
  export * from './delete-many-entity.query';
2
+ export * from './delete.presenter';
2
3
  export * from './entity.param';
3
4
  export * from './entity.query';
package/src/dtos/index.js CHANGED
@@ -15,5 +15,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./delete-many-entity.query"), exports);
18
+ __exportStar(require("./delete.presenter"), exports);
18
19
  __exportStar(require("./entity.param"), exports);
19
20
  __exportStar(require("./entity.query"), exports);
@@ -1,12 +1,12 @@
1
1
  import { CanActivate, ExecutionContext, Type } from '@nestjs/common';
2
2
  import { Reflector } from '@nestjs/core';
3
- import { DynamicApiRouteCaslAbilityPredicate, RouteType } from '../interfaces';
3
+ import { RouteAbilityPredicate, RouteType } from '../interfaces';
4
4
  import { BaseEntity } from '../models';
5
5
  export declare abstract class BasePoliciesGuard<Entity extends BaseEntity> implements CanActivate {
6
6
  protected readonly reflector: Reflector;
7
7
  protected routeType: RouteType;
8
8
  protected entity: Type<Entity>;
9
- protected abilityPredicate: DynamicApiRouteCaslAbilityPredicate<Entity> | undefined;
9
+ protected abilityPredicate: RouteAbilityPredicate<Entity> | undefined;
10
10
  protected constructor(reflector: Reflector);
11
11
  canActivate(context: ExecutionContext): boolean;
12
12
  private execPolicyHandler;
@@ -1,4 +1,4 @@
1
- import { DynamicApiControllerAbilityPredicate, DynamicApiRouteCaslAbilityPredicate, RouteType } from '../interfaces';
1
+ import { ControllerAbilityPredicate, RouteAbilityPredicate, RouteType } from '../interfaces';
2
2
  import { BaseEntity } from '../models';
3
- declare function getPredicateFromControllerAbilityPredicates<Entity extends BaseEntity>(controllerAbilityPredicates: DynamicApiControllerAbilityPredicate<Entity>[], route: RouteType): DynamicApiRouteCaslAbilityPredicate<Entity>;
3
+ declare function getPredicateFromControllerAbilityPredicates<Entity extends BaseEntity>(controllerAbilityPredicates: ControllerAbilityPredicate<Entity>[], route: RouteType): RouteAbilityPredicate<Entity>;
4
4
  export { getPredicateFromControllerAbilityPredicates };
@@ -0,0 +1,66 @@
1
+ import { Type } from '@nestjs/common';
2
+ import { EntityParam } from '../dtos';
3
+ import { DynamicApiControllerOptions, DynamicAPIRouteConfig } from '../interfaces';
4
+ import { BaseEntity } from '../models';
5
+ declare function getControllerMixinData<Entity extends BaseEntity>(entity: Type<Entity>, { path, apiTag, isPublic: isPublicController, abilityPredicates: controllerAbilityPredicates, }: DynamicApiControllerOptions<Entity>, { type: routeType, description, dTOs, isPublic: isPublicRoute, abilityPredicate: routeAbilityPredicate, }: DynamicAPIRouteConfig<Entity>, version?: string): {
6
+ routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
7
+ displayedName: string;
8
+ description: string;
9
+ isPublic: boolean;
10
+ abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
11
+ RouteBody: Type<any>;
12
+ RoutePresenter: Type<any>;
13
+ EntityParam?: undefined;
14
+ RouteQuery?: undefined;
15
+ } | {
16
+ routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
17
+ displayedName: string;
18
+ description: string;
19
+ isPublic: boolean;
20
+ abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
21
+ RoutePresenter: Type<any>;
22
+ RouteBody?: undefined;
23
+ EntityParam?: undefined;
24
+ RouteQuery?: undefined;
25
+ } | {
26
+ routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
27
+ displayedName: string;
28
+ description: string;
29
+ isPublic: boolean;
30
+ abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
31
+ EntityParam: typeof EntityParam;
32
+ RoutePresenter: Type<any>;
33
+ RouteBody?: undefined;
34
+ RouteQuery?: undefined;
35
+ } | {
36
+ routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
37
+ displayedName: string;
38
+ description: string;
39
+ isPublic: boolean;
40
+ abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
41
+ RouteBody: Type<any>;
42
+ RoutePresenter: Type<any>;
43
+ EntityParam: typeof EntityParam;
44
+ RouteQuery?: undefined;
45
+ } | {
46
+ routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
47
+ displayedName: string;
48
+ description: string;
49
+ isPublic: boolean;
50
+ abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
51
+ RouteQuery: Type<any>;
52
+ RoutePresenter: Type<any>;
53
+ RouteBody?: undefined;
54
+ EntityParam?: undefined;
55
+ } | {
56
+ routeType: import("../interfaces/dynamic-api-route-type.type").RouteType;
57
+ displayedName: string;
58
+ description: string;
59
+ isPublic: boolean;
60
+ abilityPredicate: import("../interfaces/dynamic-api-casl-ability.interface").RouteAbilityPredicate<Entity>;
61
+ EntityParam: typeof EntityParam;
62
+ RouteQuery: Type<any>;
63
+ RoutePresenter: Type<any>;
64
+ RouteBody?: undefined;
65
+ };
66
+ export { getControllerMixinData };
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.getControllerMixinData = void 0;
13
+ const swagger_1 = require("@nestjs/swagger");
14
+ const class_transformer_1 = require("class-transformer");
15
+ const class_validator_1 = require("class-validator");
16
+ const dtos_1 = require("../dtos");
17
+ const mixins_1 = require("../mixins");
18
+ const controller_ability_predicates_helper_1 = require("./controller-ability-predicates.helper");
19
+ const format_helper_1 = require("./format.helper");
20
+ const versioning_config_helper_1 = require("./versioning-config.helper");
21
+ function buildCreateManyBodyDTO(entity, displayedName, version, CustomBody) {
22
+ class DtoBody extends (0, mixins_1.EntityBodyMixin)(entity) {
23
+ }
24
+ Object.defineProperty(DtoBody, 'name', {
25
+ value: `${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Dto`,
26
+ writable: false,
27
+ });
28
+ class CreateManyBody {
29
+ }
30
+ __decorate([
31
+ (0, swagger_1.ApiProperty)({ type: [DtoBody] }),
32
+ (0, class_validator_1.ValidateNested)({ each: true }),
33
+ (0, class_validator_1.IsInstance)(DtoBody, { each: true }),
34
+ (0, class_validator_1.ArrayMinSize)(1),
35
+ (0, class_transformer_1.Type)(() => DtoBody),
36
+ __metadata("design:type", Array)
37
+ ], CreateManyBody.prototype, "list", void 0);
38
+ class RouteBody extends (0, swagger_1.PickType)(CustomBody ?? CreateManyBody, ['list']) {
39
+ }
40
+ Object.defineProperty(RouteBody, 'name', {
41
+ value: CustomBody ? CustomBody.name : `CreateMany${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Dto`,
42
+ writable: false,
43
+ });
44
+ return RouteBody;
45
+ }
46
+ function buildDeletePresenterDTO(displayedName, version, CustomPresenter) {
47
+ class RoutePresenter extends (CustomPresenter ?? dtos_1.DeletePresenter) {
48
+ }
49
+ Object.defineProperty(RoutePresenter, 'name', {
50
+ value: CustomPresenter ? CustomPresenter.name : `Delete${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Presenter`,
51
+ writable: false,
52
+ });
53
+ return RoutePresenter;
54
+ }
55
+ function buildDefaultRouteQuery(entity, routeType, displayedName, version, CustomQuery) {
56
+ class RouteQuery extends (CustomQuery ?? dtos_1.EntityQuery) {
57
+ }
58
+ Object.defineProperty(RouteQuery, 'name', {
59
+ value: CustomQuery ? CustomQuery.name : `${routeType}${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Query`,
60
+ writable: false,
61
+ });
62
+ return RouteQuery;
63
+ }
64
+ function buildDefaultRouteBody(entity, routeType, displayedName, version, CustomBody) {
65
+ const optionalBody = routeType !== 'CreateOne' && routeType !== 'ReplaceOne';
66
+ class RouteBody extends (CustomBody ?? (0, mixins_1.EntityBodyMixin)(entity, optionalBody)) {
67
+ }
68
+ Object.defineProperty(RouteBody, 'name', {
69
+ value: CustomBody ? CustomBody.name : `${routeType}${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Dto`,
70
+ writable: false,
71
+ });
72
+ return RouteBody;
73
+ }
74
+ function buildDefaultRoutePresenter(entity, routeType, displayedName, version, CustomPresenter) {
75
+ class RoutePresenter extends (CustomPresenter ?? (0, mixins_1.EntityPresenterMixin)(entity)) {
76
+ }
77
+ Object.defineProperty(RoutePresenter, 'name', {
78
+ value: CustomPresenter ? CustomPresenter.name : `${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Presenter`,
79
+ writable: false,
80
+ });
81
+ return RoutePresenter;
82
+ }
83
+ function getDTOsByRouteType(entity, routeType, displayedName, version, dTOs) {
84
+ const { query: CustomQuery, body: CustomBody, presenter: CustomPresenter, } = dTOs ?? {};
85
+ Object.defineProperty(dtos_1.EntityParam, 'name', {
86
+ value: `${displayedName}${(0, versioning_config_helper_1.addVersionSuffix)(version)}Param`,
87
+ writable: false,
88
+ });
89
+ const RouteQuery = buildDefaultRouteQuery(entity, routeType, displayedName, version, CustomQuery);
90
+ const RouteBody = buildDefaultRouteBody(entity, routeType, displayedName, version, CustomBody);
91
+ const RoutePresenter = buildDefaultRoutePresenter(entity, routeType, displayedName, version, CustomPresenter);
92
+ switch (routeType) {
93
+ case 'CreateMany':
94
+ return {
95
+ RouteBody: buildCreateManyBodyDTO(entity, displayedName, version, CustomBody),
96
+ RoutePresenter,
97
+ };
98
+ case 'DeleteMany':
99
+ return {
100
+ RoutePresenter: buildDeletePresenterDTO(displayedName, version, CustomPresenter),
101
+ };
102
+ case 'DeleteOne':
103
+ return {
104
+ EntityParam: dtos_1.EntityParam,
105
+ RoutePresenter: buildDeletePresenterDTO(displayedName, version, CustomPresenter),
106
+ };
107
+ case 'CreateOne':
108
+ case 'DuplicateMany':
109
+ case 'UpdateMany':
110
+ return {
111
+ RouteBody,
112
+ RoutePresenter,
113
+ };
114
+ case 'DuplicateOne':
115
+ case 'ReplaceOne':
116
+ case 'UpdateOne':
117
+ return {
118
+ RouteBody,
119
+ RoutePresenter,
120
+ EntityParam: dtos_1.EntityParam,
121
+ };
122
+ case 'GetMany':
123
+ return {
124
+ RouteQuery,
125
+ RoutePresenter,
126
+ };
127
+ case 'GetOne':
128
+ return {
129
+ EntityParam: dtos_1.EntityParam,
130
+ RouteQuery,
131
+ RoutePresenter,
132
+ };
133
+ default:
134
+ throw new Error(`Route type ${routeType} is not supported`);
135
+ }
136
+ }
137
+ function getControllerMixinData(entity, { path, apiTag, isPublic: isPublicController, abilityPredicates: controllerAbilityPredicates, }, { type: routeType, description, dTOs, isPublic: isPublicRoute, abilityPredicate: routeAbilityPredicate, }, version) {
138
+ const displayedName = (0, format_helper_1.getFormattedApiTag)(apiTag, entity.name);
139
+ let isPublic;
140
+ if (typeof isPublicRoute === 'boolean') {
141
+ isPublic = isPublicRoute;
142
+ }
143
+ else if (typeof isPublicController === 'boolean') {
144
+ isPublic = isPublicController;
145
+ }
146
+ else {
147
+ isPublic = false;
148
+ }
149
+ const abilityPredicate = routeAbilityPredicate ?? (0, controller_ability_predicates_helper_1.getPredicateFromControllerAbilityPredicates)(controllerAbilityPredicates, routeType);
150
+ return {
151
+ ...getDTOsByRouteType(entity, routeType, displayedName, version, dTOs),
152
+ routeType,
153
+ displayedName,
154
+ description,
155
+ isPublic,
156
+ abilityPredicate,
157
+ };
158
+ }
159
+ exports.getControllerMixinData = getControllerMixinData;
@@ -1,2 +1,3 @@
1
1
  export declare function pascalCase(str?: string): string;
2
2
  export declare function isValidVersion(version: string): boolean;
3
+ export declare function getFormattedApiTag<Entity>(apiTag: string | undefined, entityName: string): string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isValidVersion = exports.pascalCase = void 0;
3
+ exports.getFormattedApiTag = exports.isValidVersion = exports.pascalCase = void 0;
4
4
  const lodash_1 = require("lodash");
5
5
  function pascalCase(str) {
6
6
  return str ? (0, lodash_1.upperFirst)((0, lodash_1.camelCase)(str)) : undefined;
@@ -10,3 +10,7 @@ function isValidVersion(version) {
10
10
  return /^\d+$/.test(version);
11
11
  }
12
12
  exports.isValidVersion = isValidVersion;
13
+ function getFormattedApiTag(apiTag, entityName) {
14
+ return pascalCase(apiTag) ?? entityName;
15
+ }
16
+ exports.getFormattedApiTag = getFormattedApiTag;
@@ -1,9 +1,12 @@
1
+ import { AbilityTuple, MatchConditions, PureAbility } from '@casl/ability';
1
2
  import { BaseEntity } from '../models';
2
3
  import { RouteType } from './dynamic-api-route-type.type';
3
- type DynamicApiRouteCaslAbilityPredicate<Entity extends BaseEntity, T = any> = (entity: Entity, user?: T) => boolean;
4
- type DynamicApiRegisterAbilityPredicate<T = any> = (user?: T) => boolean;
5
- type DynamicApiControllerAbilityPredicate<Entity extends BaseEntity> = {
4
+ type AppAbility<Entity extends BaseEntity> = PureAbility<AbilityTuple, MatchConditions<Entity>>;
5
+ declare const lambdaMatcher: <Entity extends BaseEntity>(matchConditions: MatchConditions<Entity>) => MatchConditions<Entity>;
6
+ type RouteAbilityPredicate<Entity extends BaseEntity, User = any> = (entity: Entity, user: User) => boolean;
7
+ type RegisterAbilityPredicate<User = any> = (user: User) => boolean;
8
+ type ControllerAbilityPredicate<Entity extends BaseEntity> = {
6
9
  targets: RouteType[];
7
- predicate: DynamicApiRouteCaslAbilityPredicate<Entity>;
10
+ predicate: RouteAbilityPredicate<Entity>;
8
11
  };
9
- export { DynamicApiRouteCaslAbilityPredicate, DynamicApiRegisterAbilityPredicate, DynamicApiControllerAbilityPredicate, };
12
+ export { AppAbility, ControllerAbilityPredicate, RegisterAbilityPredicate, RouteAbilityPredicate, lambdaMatcher, };
@@ -1,2 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.lambdaMatcher = void 0;
4
+ const lambdaMatcher = (matchConditions) => matchConditions;
5
+ exports.lambdaMatcher = lambdaMatcher;
@@ -1,12 +1,12 @@
1
1
  import { ValidationPipeOptions } from '@nestjs/common';
2
2
  import { BaseEntity } from '../models';
3
- import { DynamicApiControllerAbilityPredicate } from './dynamic-api-casl-ability.interface';
3
+ import { ControllerAbilityPredicate } from './dynamic-api-casl-ability.interface';
4
4
  interface DynamicApiControllerOptions<Entity extends BaseEntity> {
5
5
  path: string;
6
6
  apiTag?: string;
7
7
  version?: string;
8
8
  isPublic?: boolean;
9
9
  validationPipeOptions?: ValidationPipeOptions;
10
- abilityPredicates?: DynamicApiControllerAbilityPredicate<Entity>[];
10
+ abilityPredicates?: ControllerAbilityPredicate<Entity>[];
11
11
  }
12
12
  export { DynamicApiControllerOptions };
@@ -1,9 +1,7 @@
1
- import { MongoAbility } from '@casl/ability/dist/types';
2
- import { ExecutionContext, Type } from '@nestjs/common';
1
+ import { ExecutionContext } from '@nestjs/common';
3
2
  import { Reflector } from '@nestjs/core';
4
3
  import { BaseEntity } from '../models';
5
- import { RouteType } from './dynamic-api-route-type.type';
6
- type AppAbility<Entity extends BaseEntity> = MongoAbility<[RouteType, Type<Entity>]>;
4
+ import { AppAbility } from './dynamic-api-casl-ability.interface';
7
5
  interface IPolicyHandler<Entity extends BaseEntity> {
8
6
  handle(ability: AppAbility<Entity>): boolean;
9
7
  }
@@ -13,4 +11,4 @@ interface PoliciesGuard<Entity extends BaseEntity> {
13
11
  canActivate(context: ExecutionContext): boolean;
14
12
  }
15
13
  type PoliciesGuardConstructor<Entity extends BaseEntity> = new (reflector: Reflector) => PoliciesGuard<Entity>;
16
- export { AppAbility, PolicyHandler, PoliciesGuardConstructor, PoliciesGuard };
14
+ export { PolicyHandler, PoliciesGuardConstructor, PoliciesGuard };
@@ -1,6 +1,6 @@
1
1
  import { ValidationPipeOptions } from '@nestjs/common';
2
2
  import { BaseEntity } from '../models';
3
- import { DynamicApiRouteCaslAbilityPredicate } from './dynamic-api-casl-ability.interface';
3
+ import { RouteAbilityPredicate } from './dynamic-api-casl-ability.interface';
4
4
  import { DTOsBundle } from './dynamic-api-route-dtos-bundle.type';
5
5
  import { RouteType } from './dynamic-api-route-type.type';
6
6
  interface DynamicAPIRouteConfig<Entity extends BaseEntity> {
@@ -10,6 +10,6 @@ interface DynamicAPIRouteConfig<Entity extends BaseEntity> {
10
10
  version?: string;
11
11
  dTOs?: DTOsBundle;
12
12
  validationPipeOptions?: ValidationPipeOptions;
13
- abilityPredicate?: DynamicApiRouteCaslAbilityPredicate<Entity>;
13
+ abilityPredicate?: RouteAbilityPredicate<Entity>;
14
14
  }
15
15
  export { DynamicAPIRouteConfig };
@@ -1,5 +1,5 @@
1
1
  import { Type } from '@nestjs/common';
2
- import { DynamicApiRouteCaslAbilityPredicate, PoliciesGuardConstructor, RouteType } from '../interfaces';
2
+ import { RouteAbilityPredicate, PoliciesGuardConstructor, RouteType } from '../interfaces';
3
3
  import { BaseEntity } from '../models';
4
- declare function CreatePoliciesGuardMixin<Entity extends BaseEntity>(entity: Type<Entity>, routeType: RouteType, version: string | undefined, abilityPredicate: DynamicApiRouteCaslAbilityPredicate<Entity> | undefined): PoliciesGuardConstructor<Entity>;
4
+ declare function CreatePoliciesGuardMixin<Entity extends BaseEntity>(entity: Type<Entity>, routeType: RouteType, version: string | undefined, abilityPredicate: RouteAbilityPredicate<Entity> | undefined): PoliciesGuardConstructor<Entity>;
5
5
  export { CreatePoliciesGuardMixin };
@@ -1,9 +1,9 @@
1
1
  import { Type } from '@nestjs/common';
2
- import { DynamicApiRegisterAbilityPredicate } from '../../../interfaces';
2
+ import { RegisterAbilityPredicate } from '../../../interfaces';
3
3
  import { BaseEntity } from '../../../models';
4
4
  type DynamicApiRegisterOptions<Entity extends BaseEntity = any> = {
5
5
  protected?: boolean;
6
- abilityPredicate?: DynamicApiRegisterAbilityPredicate;
6
+ abilityPredicate?: RegisterAbilityPredicate;
7
7
  additionalFields?: (keyof Entity | {
8
8
  name: keyof Entity;
9
9
  required?: boolean;
@@ -1,6 +1,6 @@
1
1
  import { Type } from '@nestjs/common';
2
- import { DynamicApiRegisterAbilityPredicate, PoliciesGuardConstructor, RouteType } from '../../../interfaces';
2
+ import { RegisterAbilityPredicate, PoliciesGuardConstructor, RouteType } from '../../../interfaces';
3
3
  import { BaseEntity } from '../../../models';
4
4
  declare const registerRouteType: RouteType;
5
- declare function AuthRegisterPoliciesGuardMixin<Entity extends BaseEntity>(entity: Type<Entity>, abilityPredicate: DynamicApiRegisterAbilityPredicate | undefined): PoliciesGuardConstructor<Entity>;
5
+ declare function AuthRegisterPoliciesGuardMixin<Entity extends BaseEntity>(entity: Type<Entity>, abilityPredicate: RegisterAbilityPredicate | undefined): PoliciesGuardConstructor<Entity>;
6
6
  export { AuthRegisterPoliciesGuardMixin, registerRouteType };
@@ -48,4 +48,5 @@ export declare abstract class BaseAuthService<Entity extends BaseEntity> extends
48
48
  accessToken: string;
49
49
  }>;
50
50
  private getUserById;
51
+ private buildUserFields;
51
52
  }
@@ -14,7 +14,7 @@ class BaseAuthService extends services_1.BaseService {
14
14
  }
15
15
  async validateUser(login, pass) {
16
16
  const user = (await this.model.findOne({ [this.loginField]: login }).lean().exec());
17
- if (!user || !await this.bcryptService.comparePassword(pass, user[this.passwordField])) {
17
+ if (!user || !(await this.bcryptService.comparePassword(pass, user[this.passwordField]))) {
18
18
  return null;
19
19
  }
20
20
  const fieldsToBuild = [
@@ -22,7 +22,7 @@ class BaseAuthService extends services_1.BaseService {
22
22
  this.loginField,
23
23
  ...this.additionalRequestFields,
24
24
  ];
25
- return this.buildInstance(fieldsToBuild.reduce((acc, field) => (user[field] ? { ...acc, [field]: user[field] } : acc), {}));
25
+ return this.buildUserFields(user, fieldsToBuild);
26
26
  }
27
27
  async login(user) {
28
28
  const fieldsToBuild = [
@@ -31,7 +31,7 @@ class BaseAuthService extends services_1.BaseService {
31
31
  this.loginField,
32
32
  ...this.additionalRequestFields,
33
33
  ];
34
- const payload = this.buildInstance(fieldsToBuild.reduce((acc, field) => (user[field] !== undefined ? { ...acc, [field]: user[field] } : acc), {}));
34
+ const payload = this.buildUserFields(user, fieldsToBuild);
35
35
  return {
36
36
  accessToken: this.jwtService.sign(payload),
37
37
  };
@@ -49,7 +49,7 @@ class BaseAuthService extends services_1.BaseService {
49
49
  this.loginField,
50
50
  ...this.additionalRequestFields,
51
51
  ];
52
- return this.buildInstance(fieldsToBuild.reduce((acc, field) => (user[field] !== undefined ? { ...acc, [field]: user[field] } : acc), {}));
52
+ return this.buildUserFields(user, fieldsToBuild);
53
53
  }
54
54
  async changePassword(userId, newPassword) {
55
55
  const hashedPassword = await this.bcryptService.hashPassword(newPassword);
@@ -60,5 +60,8 @@ class BaseAuthService extends services_1.BaseService {
60
60
  async getUserById(userId) {
61
61
  return (await this.model.findOne({ _id: userId }).lean().exec());
62
62
  }
63
+ buildUserFields(user, fieldsToBuild) {
64
+ return this.buildInstance(fieldsToBuild.reduce((acc, field) => (user[field] !== undefined ? { ...acc, [field]: user[field] } : acc), {}));
65
+ }
63
66
  }
64
67
  exports.BaseAuthService = BaseAuthService;
@@ -2,5 +2,5 @@ import { Type } from '@nestjs/common';
2
2
  import { DynamicApiControllerOptions, DynamicAPIRouteConfig } from '../../interfaces';
3
3
  import { BaseEntity } from '../../models';
4
4
  import { CreateManyControllerConstructor } from './create-many-controller.interface';
5
- declare function CreateManyControllerMixin<Entity extends BaseEntity>(entity: Type<Entity>, { path, apiTag, isPublic: isPublicController, abilityPredicates: controllerAbilityPredicates, }: DynamicApiControllerOptions<Entity>, { type: routeType, description, dTOs, isPublic: isPublicRoute, abilityPredicate: routeAbilityPredicate, }: DynamicAPIRouteConfig<Entity>, version?: string): CreateManyControllerConstructor<Entity>;
5
+ declare function CreateManyControllerMixin<Entity extends BaseEntity>(entity: Type<Entity>, controllerOptions: DynamicApiControllerOptions<Entity>, routeConfig: DynamicAPIRouteConfig<Entity>, version?: string): CreateManyControllerConstructor<Entity>;
6
6
  export { CreateManyControllerMixin };
@@ -14,66 +14,18 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.CreateManyControllerMixin = void 0;
16
16
  const common_1 = require("@nestjs/common");
17
- const swagger_1 = require("@nestjs/swagger");
18
- const class_transformer_1 = require("class-transformer");
19
- const class_validator_1 = require("class-validator");
20
17
  const builders_1 = require("../../builders");
21
18
  const decorators_1 = require("../../decorators");
22
19
  const helpers_1 = require("../../helpers");
23
- const controller_ability_predicates_helper_1 = require("../../helpers/controller-ability-predicates.helper");
20
+ const controller_mixin_helper_1 = require("../../helpers/controller-mixin.helper");
24
21
  const mixins_1 = require("../../mixins");
25
- function CreateManyControllerMixin(entity, { path, apiTag, isPublic: isPublicController, abilityPredicates: controllerAbilityPredicates, }, { type: routeType, description, dTOs, isPublic: isPublicRoute, abilityPredicate: routeAbilityPredicate, }, version) {
26
- const displayedName = (0, helpers_1.pascalCase)(apiTag) ?? entity.name;
27
- const { body: CustomBody, presenter: CustomPresenter } = dTOs ?? {};
28
- let isPublic;
29
- if (typeof isPublicRoute === 'boolean') {
30
- isPublic = isPublicRoute;
31
- }
32
- else if (typeof isPublicController === 'boolean') {
33
- isPublic = isPublicController;
34
- }
35
- else {
36
- isPublic = false;
37
- }
38
- class DtoBody extends (0, mixins_1.EntityBodyMixin)(entity) {
39
- }
40
- Object.defineProperty(DtoBody, 'name', {
41
- value: `${displayedName}${(0, helpers_1.addVersionSuffix)(version)}Dto`,
42
- writable: false,
43
- });
44
- class CreateManyBody {
45
- }
46
- __decorate([
47
- (0, swagger_1.ApiProperty)({ type: [DtoBody] }),
48
- (0, class_validator_1.ValidateNested)({ each: true }),
49
- (0, class_validator_1.IsInstance)(DtoBody, { each: true }),
50
- (0, class_validator_1.ArrayMinSize)(1),
51
- (0, class_transformer_1.Type)(() => DtoBody),
52
- __metadata("design:type", Array)
53
- ], CreateManyBody.prototype, "list", void 0);
54
- class RouteBody extends (0, swagger_1.PickType)(CustomBody ?? CreateManyBody, ['list']) {
55
- }
56
- if (!CustomBody) {
57
- Object.defineProperty(RouteBody, 'name', {
58
- value: `CreateMany${displayedName}${(0, helpers_1.addVersionSuffix)(version)}Dto`,
59
- writable: false,
60
- });
61
- }
62
- class RoutePresenter extends (CustomPresenter ?? (0, mixins_1.EntityPresenterMixin)(entity)) {
63
- }
64
- if (!CustomPresenter) {
65
- Object.defineProperty(RoutePresenter, 'name', {
66
- value: `${displayedName}${(0, helpers_1.addVersionSuffix)(version)}Presenter`,
67
- writable: false,
68
- });
69
- }
70
- const routeDecoratorsBuilder = new builders_1.RouteDecoratorsBuilder('CreateMany', entity, version, description, isPublic, {
71
- param: undefined,
72
- query: undefined,
22
+ function CreateManyControllerMixin(entity, controllerOptions, routeConfig, version) {
23
+ var _a;
24
+ const { routeType, description, isPublic, RouteBody, RoutePresenter, abilityPredicate, } = (0, controller_mixin_helper_1.getControllerMixinData)(entity, controllerOptions, routeConfig, version);
25
+ const routeDecoratorsBuilder = new builders_1.RouteDecoratorsBuilder(routeType, entity, version, description, isPublic, {
73
26
  body: RouteBody,
74
27
  presenter: RoutePresenter,
75
28
  });
76
- const abilityPredicate = routeAbilityPredicate ?? (0, controller_ability_predicates_helper_1.getPredicateFromControllerAbilityPredicates)(controllerAbilityPredicates, routeType);
77
29
  class CreateManyPoliciesGuard extends (0, mixins_1.CreatePoliciesGuardMixin)(entity, routeType, version, abilityPredicate) {
78
30
  }
79
31
  class BaseCreateManyController {
@@ -91,7 +43,7 @@ function CreateManyControllerMixin(entity, { path, apiTag, isPublic: isPublicCon
91
43
  (0, decorators_1.CheckPolicies)((ability) => ability.can(routeType, entity)),
92
44
  __param(0, (0, common_1.Body)()),
93
45
  __metadata("design:type", Function),
94
- __metadata("design:paramtypes", [RouteBody]),
46
+ __metadata("design:paramtypes", [typeof (_a = typeof RouteBody !== "undefined" && RouteBody) === "function" ? _a : Object]),
95
47
  __metadata("design:returntype", Promise)
96
48
  ], BaseCreateManyController.prototype, "createMany", null);
97
49
  Object.defineProperty(BaseCreateManyController, 'name', {
@@ -2,5 +2,5 @@ import { Type } from '@nestjs/common';
2
2
  import { DynamicApiControllerOptions, DynamicAPIRouteConfig } from '../../interfaces';
3
3
  import { BaseEntity } from '../../models';
4
4
  import { CreateOneControllerConstructor } from './create-one-controller.interface';
5
- declare function CreateOneControllerMixin<Entity extends BaseEntity>(entity: Type<Entity>, { path, apiTag, isPublic: isPublicController, abilityPredicates: controllerAbilityPredicates, }: DynamicApiControllerOptions<Entity>, { type: routeType, description, dTOs, isPublic: isPublicRoute, abilityPredicate: routeAbilityPredicate, }: DynamicAPIRouteConfig<Entity>, version?: string): CreateOneControllerConstructor<Entity>;
5
+ declare function CreateOneControllerMixin<Entity extends BaseEntity>(entity: Type<Entity>, controllerOptions: DynamicApiControllerOptions<Entity>, routeConfig: DynamicAPIRouteConfig<Entity>, version?: string): CreateOneControllerConstructor<Entity>;
6
6
  export { CreateOneControllerMixin };