@koalarx/nest 0.0.9 → 1.0.0

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 (146) hide show
  1. package/core/backgroud-services/cron-service/cron-job.d.ts +14 -0
  2. package/{common → core}/backgroud-services/cron-service/cron-job.js +18 -16
  3. package/core/backgroud-services/cron-service/cron-job.spec.d.ts +8 -0
  4. package/core/backgroud-services/cron-service/cron-job.spec.js +33 -0
  5. package/core/backgroud-services/event-service/event-class.d.ts +5 -0
  6. package/{common → core}/backgroud-services/event-service/event-class.js +3 -3
  7. package/core/backgroud-services/event-service/event-handler.d.ts +5 -0
  8. package/core/backgroud-services/event-service/event-job.d.ts +13 -0
  9. package/{common → core}/backgroud-services/event-service/event-job.js +4 -2
  10. package/{common → core}/backgroud-services/event-service/event-queue.js +9 -6
  11. package/core/backgroud-services/event-service/event-queue.spec.d.ts +1 -0
  12. package/core/backgroud-services/event-service/event-queue.spec.js +34 -0
  13. package/core/controllers/created-registre-response.base.d.ts +4 -0
  14. package/{common → core}/controllers/created-registre-response.base.js +5 -1
  15. package/{common → core}/controllers/list-response.base.js +5 -1
  16. package/core/controllers/schemas/boolean.schema.d.ts +2 -0
  17. package/core/controllers/schemas/boolean.schema.js +15 -0
  18. package/core/database/entity.base.d.ts +9 -0
  19. package/core/database/entity.base.js +39 -0
  20. package/{services/prisma → core/database}/prisma-transactional-client.d.ts +1 -2
  21. package/{services/prisma → core/database}/prisma.service.js +5 -1
  22. package/core/database/repository.base.d.ts +29 -13
  23. package/core/database/repository.base.js +142 -15
  24. package/core/koala-app.d.ts +10 -8
  25. package/core/koala-app.js +41 -8
  26. package/core/koala-global-vars.d.ts +7 -0
  27. package/core/koala-global-vars.js +9 -0
  28. package/core/koala-nest-database.module.d.ts +2 -2
  29. package/core/koala-nest-database.module.js +18 -18
  30. package/core/koala-nest-http.module.d.ts +5 -5
  31. package/core/koala-nest-http.module.js +8 -14
  32. package/core/koala-nest.module.d.ts +1 -3
  33. package/core/koala-nest.module.js +12 -18
  34. package/core/mapping/auto-mapping-class-context.d.ts +15 -0
  35. package/core/mapping/auto-mapping-class-context.js +18 -0
  36. package/core/mapping/auto-mapping-context.d.ts +11 -0
  37. package/core/mapping/auto-mapping-context.js +24 -0
  38. package/core/mapping/auto-mapping-list.d.ts +18 -0
  39. package/core/mapping/auto-mapping-list.js +46 -0
  40. package/core/mapping/auto-mapping-profile.d.ts +3 -0
  41. package/core/mapping/auto-mapping-profile.js +6 -0
  42. package/core/mapping/auto-mapping.decorator.d.ts +9 -0
  43. package/core/mapping/auto-mapping.decorator.js +27 -0
  44. package/core/mapping/auto-mapping.module.d.ts +5 -0
  45. package/core/mapping/auto-mapping.module.js +28 -0
  46. package/core/mapping/auto-mapping.service.d.ts +10 -0
  47. package/core/mapping/auto-mapping.service.js +93 -0
  48. package/core/mapping/create-map.d.ts +3 -0
  49. package/core/mapping/create-map.js +8 -0
  50. package/core/mapping/for-member.d.ts +5 -0
  51. package/core/mapping/for-member.js +9 -0
  52. package/{common → core}/models/pagination-params.d.ts +3 -0
  53. package/{common → core}/models/pagination-params.js +11 -4
  54. package/{common/mediator → core/request-overflow}/request-handler.base.d.ts +1 -1
  55. package/core/request-overflow/request-result.spec.d.ts +1 -0
  56. package/core/request-overflow/request-result.spec.js +21 -0
  57. package/{common/mediator → core/request-overflow}/request-validator.base.d.ts +1 -1
  58. package/{common/mediator → core/request-overflow}/request-validator.base.js +1 -1
  59. package/core/utils/assing-object.d.ts +2 -0
  60. package/core/utils/assing-object.js +7 -0
  61. package/core/utils/interfaces/icomparable.d.ts +1 -1
  62. package/core/utils/list.d.ts +17 -6
  63. package/core/utils/list.js +62 -15
  64. package/core/utils/list.spec.d.ts +1 -0
  65. package/core/utils/list.spec.js +42 -0
  66. package/{services/env → env}/env.d.ts +6 -6
  67. package/{services/env → env}/env.js +2 -2
  68. package/{services/env → env}/env.service.d.ts +2 -2
  69. package/{services/env → env}/env.service.js +6 -1
  70. package/filters/domain-errors.filter.d.ts +7 -7
  71. package/filters/domain-errors.filter.js +7 -7
  72. package/filters/global-exception.filter.js +5 -1
  73. package/package.json +10 -27
  74. package/services/redis/redis.service.d.ts +1 -1
  75. package/services/redis/redis.service.js +6 -1
  76. package/services/redlock/red-lock.service.js +6 -1
  77. package/test/koala-app-test-dependencies.d.ts +10 -0
  78. package/test/koala-app-test-dependencies.js +13 -0
  79. package/test/koala-app-test.d.ts +20 -0
  80. package/test/koala-app-test.js +66 -0
  81. package/test/repositories/in-memory-base.repository.d.ts +16 -0
  82. package/test/repositories/in-memory-base.repository.js +55 -0
  83. package/test/services/fake-logging.service.d.ts +4 -0
  84. package/test/services/fake-logging.service.js +9 -0
  85. package/test/services/fake-red-lock.service.d.ts +5 -0
  86. package/test/services/fake-red-lock.service.js +11 -0
  87. package/test/utils/create-e2e-database.d.ts +2 -0
  88. package/test/utils/create-e2e-database.js +27 -0
  89. package/test/utils/drop-e2e-database.d.ts +1 -0
  90. package/test/utils/drop-e2e-database.js +8 -0
  91. package/test/utils/wait-for.d.ts +1 -0
  92. package/test/utils/wait-for.js +22 -0
  93. package/tsconfig.lib.tsbuildinfo +1 -0
  94. package/common/backgroud-services/cron-service/cron-job.d.ts +0 -15
  95. package/common/backgroud-services/event-service/event-class.d.ts +0 -5
  96. package/common/backgroud-services/event-service/event-handler.d.ts +0 -5
  97. package/common/backgroud-services/event-service/event-job.d.ts +0 -10
  98. package/common/controllers/created-registre-response.base.d.ts +0 -4
  99. package/core/database/entity.d.ts +0 -8
  100. package/core/database/entity.js +0 -31
  101. package/decorators/is-cnpj.decorator.d.ts +0 -2
  102. package/decorators/is-cnpj.decorator.js +0 -71
  103. package/services/prisma/prisma.types.d.ts +0 -36
  104. package/services/prisma/prisma.types.js +0 -15
  105. /package/{common → core}/backgroud-services/event-service/event-handler.js +0 -0
  106. /package/{common → core}/backgroud-services/event-service/event-is-trigger.d.ts +0 -0
  107. /package/{common → core}/backgroud-services/event-service/event-is-trigger.js +0 -0
  108. /package/{common → core}/backgroud-services/event-service/event-queue.d.ts +0 -0
  109. /package/{common → core}/controllers/base.controller.d.ts +0 -0
  110. /package/{common → core}/controllers/base.controller.js +0 -0
  111. /package/{common → core}/controllers/list-response.base.d.ts +0 -0
  112. /package/{common → core}/controllers/router-config.base.d.ts +0 -0
  113. /package/{common → core}/controllers/router-config.base.js +0 -0
  114. /package/{common → core}/controllers/schemas/document-number.schema.d.ts +0 -0
  115. /package/{common → core}/controllers/schemas/document-number.schema.js +0 -0
  116. /package/{common → core}/controllers/schemas/email.schema.d.ts +0 -0
  117. /package/{common → core}/controllers/schemas/email.schema.js +0 -0
  118. /package/{common → core}/controllers/schemas/list-query.schema.d.ts +0 -0
  119. /package/{common → core}/controllers/schemas/list-query.schema.js +0 -0
  120. /package/{common → core}/controllers/schemas/native-enum.schema.d.ts +0 -0
  121. /package/{common → core}/controllers/schemas/native-enum.schema.js +0 -0
  122. /package/{services/prisma → core/database}/prisma-client-with-custom-transaction.interface.d.ts +0 -0
  123. /package/{services/prisma → core/database}/prisma-client-with-custom-transaction.interface.js +0 -0
  124. /package/{services/prisma → core/database}/prisma-transactional-client.js +0 -0
  125. /package/{services/prisma → core/database}/prisma.service.d.ts +0 -0
  126. /package/{common → core}/errors/bad-request.error.d.ts +0 -0
  127. /package/{common → core}/errors/bad-request.error.js +0 -0
  128. /package/{common → core}/errors/conflict.error.d.ts +0 -0
  129. /package/{common → core}/errors/conflict.error.js +0 -0
  130. /package/{common → core}/errors/no-content.error.d.ts +0 -0
  131. /package/{common → core}/errors/no-content.error.js +0 -0
  132. /package/{common → core}/errors/not-allowed.error.d.ts +0 -0
  133. /package/{common → core}/errors/not-allowed.error.js +0 -0
  134. /package/{common → core}/errors/resource-not-found.error.d.ts +0 -0
  135. /package/{common → core}/errors/resource-not-found.error.js +0 -0
  136. /package/{common → core}/errors/use-case-error.d.ts +0 -0
  137. /package/{common → core}/errors/use-case-error.js +0 -0
  138. /package/{common → core}/errors/user-already-exist.error.d.ts +0 -0
  139. /package/{common → core}/errors/user-already-exist.error.js +0 -0
  140. /package/{common → core}/errors/wrong-credentials.error.d.ts +0 -0
  141. /package/{common → core}/errors/wrong-credentials.error.js +0 -0
  142. /package/{common/mediator → core/request-overflow}/request-handler.base.js +0 -0
  143. /package/{common/mediator → core/request-overflow}/request-result.d.ts +0 -0
  144. /package/{common/mediator → core/request-overflow}/request-result.js +0 -0
  145. /package/{services/env → env}/env.module.d.ts +0 -0
  146. /package/{services/env → env}/env.module.js +0 -0
@@ -0,0 +1,14 @@
1
+ import { ILoggingService } from '../../../services/logging/ilogging.service';
2
+ import { IRedLockService } from '../../../services/redlock/ired-lock.service';
3
+ import { RequestResult } from '../../request-overflow/request-result';
4
+ export type CronJobResponse = RequestResult<Error, null>;
5
+ export declare abstract class CronJob {
6
+ private readonly redlockService;
7
+ private readonly loggingService;
8
+ private readonly _timeout;
9
+ constructor(redlockService: IRedLockService, loggingService: ILoggingService);
10
+ protected abstract run(): Promise<CronJobResponse>;
11
+ protected abstract isActive(): Promise<boolean>;
12
+ protected abstract defineTimeInMinutes(): number;
13
+ start(): Promise<void>;
14
+ }
@@ -2,27 +2,24 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CronJob = void 0;
4
4
  const delay_1 = require("@koalarx/utils/operators/delay");
5
+ const koala_global_vars_1 = require("../../koala-global-vars");
5
6
  class CronJob {
6
7
  redlockService;
7
8
  loggingService;
8
- loggedUsername;
9
- appName;
10
- timeout;
11
- constructor(redlockService, loggingService, loggedUsername, appName, timeInMinutes) {
9
+ _timeout;
10
+ constructor(redlockService, loggingService) {
12
11
  this.redlockService = redlockService;
13
12
  this.loggingService = loggingService;
14
- this.loggedUsername = loggedUsername;
15
- this.appName = appName;
16
- this.timeout = timeInMinutes * 60 * 1000;
13
+ this._timeout = this.defineTimeInMinutes() * 60 * 1000;
17
14
  }
18
- async start(job) {
15
+ async start() {
19
16
  const name = this.constructor.name;
20
17
  while (true) {
21
18
  if (await this.isActive()) {
22
- const ttlSecondsLock = this.timeout / 1000;
19
+ const ttlSecondsLock = this._timeout / 1000;
23
20
  const acquiredLock = await this.redlockService.acquiredLock(name, ttlSecondsLock);
24
21
  if (acquiredLock) {
25
- const error = await job()
22
+ const error = await this.run()
26
23
  .then((result) => {
27
24
  if (result.isFailure()) {
28
25
  return result.value;
@@ -31,15 +28,20 @@ class CronJob {
31
28
  })
32
29
  .catch((error) => error);
33
30
  if (error) {
34
- this.loggingService.report({
35
- error,
36
- packageName: this.appName,
37
- loggedUsername: this.loggedUsername,
38
- });
31
+ try {
32
+ await this.loggingService.report({
33
+ error,
34
+ packageName: koala_global_vars_1.KoalaGlobalVars.appName,
35
+ loggedUsername: koala_global_vars_1.KoalaGlobalVars.internalUserName,
36
+ });
37
+ }
38
+ catch {
39
+ console.error(error);
40
+ }
39
41
  }
40
42
  }
41
43
  }
42
- await (0, delay_1.klDelay)(this.timeout);
44
+ await (0, delay_1.klDelay)(this._timeout);
43
45
  await this.redlockService.releaseLock(name);
44
46
  }
45
47
  }
@@ -0,0 +1,8 @@
1
+ import { CronJob, CronJobResponse } from './cron-job';
2
+ export declare class CronJobTest extends CronJob {
3
+ constructor();
4
+ static isCalled(): Promise<CronJobResponse>;
5
+ protected run(): Promise<CronJobResponse>;
6
+ protected isActive(): Promise<boolean>;
7
+ protected defineTimeInMinutes(): number;
8
+ }
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CronJobTest = void 0;
4
+ const delay_1 = require("@koalarx/utils/operators/delay");
5
+ const vitest_1 = require("vitest");
6
+ const fake_logging_service_1 = require("../../../test/services/fake-logging.service");
7
+ const fake_red_lock_service_1 = require("../../../test/services/fake-red-lock.service");
8
+ const request_result_1 = require("../../request-overflow/request-result");
9
+ const cron_job_1 = require("./cron-job");
10
+ class CronJobTest extends cron_job_1.CronJob {
11
+ constructor() {
12
+ super(new fake_red_lock_service_1.FakeRedLockService(), new fake_logging_service_1.FakeLoggingService());
13
+ }
14
+ static async isCalled() {
15
+ return (0, request_result_1.ok)(null);
16
+ }
17
+ run() {
18
+ return CronJobTest.isCalled();
19
+ }
20
+ async isActive() {
21
+ return true;
22
+ }
23
+ defineTimeInMinutes() {
24
+ return 0.01;
25
+ }
26
+ }
27
+ exports.CronJobTest = CronJobTest;
28
+ test('cron job', async () => {
29
+ const callbackSpy = vitest_1.vi.spyOn(CronJobTest, 'isCalled');
30
+ new CronJobTest().start();
31
+ await (0, delay_1.klDelay)(100);
32
+ expect(callbackSpy).toHaveBeenCalled();
33
+ });
@@ -0,0 +1,5 @@
1
+ export declare abstract class EventClass<TEntity = any> {
2
+ data?: TEntity | undefined;
3
+ ocurredAt: Date;
4
+ constructor(data?: TEntity | undefined);
5
+ }
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventClass = void 0;
4
4
  class EventClass {
5
- eventJob;
5
+ data;
6
6
  ocurredAt = new Date();
7
- constructor(eventJob) {
8
- this.eventJob = eventJob;
7
+ constructor(data) {
8
+ this.data = data;
9
9
  }
10
10
  }
11
11
  exports.EventClass = EventClass;
@@ -0,0 +1,5 @@
1
+ import { EventClass } from './event-class';
2
+ export declare abstract class EventHandler<TEvent extends EventClass<any>> {
3
+ setupSubscriptions(): void;
4
+ abstract handleEvent(event: TEvent): Promise<void>;
5
+ }
@@ -0,0 +1,13 @@
1
+ import { Type } from '@nestjs/common';
2
+ import { EventClass } from './event-class';
3
+ import { EventHandler } from './event-handler';
4
+ import { EventQueue } from './event-queue';
5
+ export declare abstract class EventJob<TEntity> {
6
+ _id: `${string}-${string}-${string}-${string}-${string}`;
7
+ private _eventQueue;
8
+ constructor();
9
+ abstract defineHandlers(): Array<Type<EventHandler<any>>>;
10
+ get eventQueue(): EventQueue[];
11
+ clearQueue(): void;
12
+ addEvent(event: EventClass<TEntity>): void;
13
+ }
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EventJob = void 0;
4
- const entity_1 = require("../../../core/database/entity");
5
4
  const event_queue_1 = require("./event-queue");
6
- class EventJob extends entity_1.Entity {
5
+ const node_crypto_1 = require("node:crypto");
6
+ class EventJob {
7
+ _id = (0, node_crypto_1.randomUUID)();
7
8
  _eventQueue = [];
9
+ constructor() { }
8
10
  get eventQueue() {
9
11
  return this._eventQueue;
10
12
  }
@@ -5,7 +5,7 @@ class EventQueue {
5
5
  static handlersMap = {};
6
6
  static markedAggregates = [];
7
7
  static markAggregateForDispatch(aggregate) {
8
- const aggregateFound = !!this.findMarkedAggregateByID(aggregate.id);
8
+ const aggregateFound = !!this.findMarkedAggregateByID(aggregate._id);
9
9
  if (!aggregateFound) {
10
10
  this.markedAggregates.push(aggregate);
11
11
  }
@@ -35,17 +35,20 @@ class EventQueue {
35
35
  aggregate.eventQueue.forEach((event) => this.dispatch(event));
36
36
  }
37
37
  static removeAggregateFromMarkedDispatchList(aggregate) {
38
- const index = this.markedAggregates.findIndex((a) => a.equals(aggregate));
38
+ const index = this.markedAggregates.findIndex((a) => a._id === aggregate._id);
39
39
  this.markedAggregates.splice(index, 1);
40
40
  }
41
41
  static findMarkedAggregateByID(id) {
42
- return this.markedAggregates.find((aggregate) => aggregate.id === id);
42
+ return this.markedAggregates.find((aggregate) => aggregate._id === id);
43
43
  }
44
44
  static dispatch(event) {
45
- const eventClassName = event.constructor.name;
46
- const isEventRegistered = eventClassName in this.handlersMap;
45
+ const eventJobHandlers = this.markedAggregates.find((a) => a.eventQueue.find((e) => e === event));
46
+ const eventHandler = Object.keys(this.handlersMap).find((handlerName) => eventJobHandlers
47
+ ?.defineHandlers()
48
+ .find((handler) => handler.name === handlerName));
49
+ const isEventRegistered = !!eventHandler;
47
50
  if (isEventRegistered) {
48
- const handlers = this.handlersMap[eventClassName];
51
+ const handlers = this.handlersMap[eventHandler];
49
52
  for (const handler of handlers) {
50
53
  handler(event);
51
54
  }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const vitest_1 = require("vitest");
4
+ const event_class_1 = require("./event-class");
5
+ const event_handler_1 = require("./event-handler");
6
+ const event_job_1 = require("./event-job");
7
+ const event_queue_1 = require("./event-queue");
8
+ class CustomEvent extends event_class_1.EventClass {
9
+ }
10
+ class CustomEventHandler extends event_handler_1.EventHandler {
11
+ static async isCalled() {
12
+ return null;
13
+ }
14
+ async handleEvent(event) {
15
+ await CustomEventHandler.isCalled();
16
+ }
17
+ }
18
+ class CustomEventJob extends event_job_1.EventJob {
19
+ defineHandlers() {
20
+ return [CustomEventHandler];
21
+ }
22
+ }
23
+ describe('event queue', () => {
24
+ it('should be able to dispatch and listen to events', () => {
25
+ const callbackSpy = vitest_1.vi.spyOn(CustomEventHandler, 'isCalled');
26
+ new CustomEventHandler().setupSubscriptions();
27
+ const jobs = new CustomEventJob();
28
+ jobs.addEvent(new CustomEvent());
29
+ expect(jobs.eventQueue).toHaveLength(1);
30
+ event_queue_1.EventQueue.dispatchEventsForAggregate(jobs._id);
31
+ expect(callbackSpy).toHaveBeenCalled();
32
+ expect(jobs.eventQueue).toHaveLength(0);
33
+ });
34
+ });
@@ -0,0 +1,4 @@
1
+ import { IComparableId } from '../../core/utils/interfaces/icomparable';
2
+ export declare abstract class CreatedRegistreResponseBase<TId = IComparableId> {
3
+ id: TId;
4
+ }
@@ -5,6 +5,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
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
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
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
+ };
8
11
  Object.defineProperty(exports, "__esModule", { value: true });
9
12
  exports.CreatedRegistreResponseBase = void 0;
10
13
  const swagger_1 = require("@nestjs/swagger");
@@ -13,5 +16,6 @@ class CreatedRegistreResponseBase {
13
16
  }
14
17
  exports.CreatedRegistreResponseBase = CreatedRegistreResponseBase;
15
18
  __decorate([
16
- (0, swagger_1.ApiProperty)()
19
+ (0, swagger_1.ApiProperty)({ type: 'string' }),
20
+ __metadata("design:type", Object)
17
21
  ], CreatedRegistreResponseBase.prototype, "id", void 0);
@@ -5,6 +5,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
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
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
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
+ };
8
11
  Object.defineProperty(exports, "__esModule", { value: true });
9
12
  exports.ListResponseBase = void 0;
10
13
  const swagger_1 = require("@nestjs/swagger");
@@ -13,5 +16,6 @@ class ListResponseBase {
13
16
  }
14
17
  exports.ListResponseBase = ListResponseBase;
15
18
  __decorate([
16
- (0, swagger_1.ApiProperty)()
19
+ (0, swagger_1.ApiProperty)(),
20
+ __metadata("design:type", Number)
17
21
  ], ListResponseBase.prototype, "count", void 0);
@@ -0,0 +1,2 @@
1
+ import { z } from 'zod';
2
+ export declare function booleanSchema(): z.ZodEffects<z.ZodString, boolean | undefined, string>;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.booleanSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ function booleanSchema() {
6
+ return zod_1.z.coerce
7
+ .string()
8
+ .transform((value) => {
9
+ if (value !== undefined) {
10
+ return value === 'true';
11
+ }
12
+ return undefined;
13
+ });
14
+ }
15
+ exports.booleanSchema = booleanSchema;
@@ -0,0 +1,9 @@
1
+ import { IComparable, IComparableId } from '../utils/interfaces/icomparable';
2
+ export type EntityProps<T extends IComparable<T>> = Omit<{
3
+ [K in keyof T as T[K] extends Function ? never : K]: T[K];
4
+ }, '_id'>;
5
+ export declare abstract class EntityBase<T extends IComparable<T>> implements IComparable<T> {
6
+ _id: IComparableId;
7
+ automap(props?: EntityProps<T>): void;
8
+ equals(obj: EntityBase<T>): boolean;
9
+ }
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EntityBase = void 0;
4
+ const list_1 = require("../utils/list");
5
+ class EntityBase {
6
+ _id;
7
+ automap(props) {
8
+ if (props) {
9
+ for (const key of Object.keys(props)) {
10
+ if (Array.isArray(props[key]) && this[key] instanceof list_1.List) {
11
+ let value = props[key];
12
+ if (this[key].entityType) {
13
+ value = value.map((item) => {
14
+ const entity = new this[key].entityType();
15
+ entity.automap(item);
16
+ return entity;
17
+ });
18
+ }
19
+ this[key].setList(value);
20
+ }
21
+ else if (this[key] instanceof EntityBase) {
22
+ const entity = new this[key].constructor();
23
+ entity.automap(props[key]);
24
+ this[key] = entity;
25
+ }
26
+ else {
27
+ if (key === 'id') {
28
+ this._id = props[key];
29
+ }
30
+ this[key] = props[key];
31
+ }
32
+ }
33
+ }
34
+ }
35
+ equals(obj) {
36
+ return obj._id === this._id;
37
+ }
38
+ }
39
+ exports.EntityBase = EntityBase;
@@ -1,6 +1,5 @@
1
1
  import { Prisma, PrismaPromise } from '@prisma/client';
2
- import { PrismaClientWithCustomTransaction } from './prisma-client-with-custom-transaction.interface';
3
- export declare class PrismaTransactionalClient implements PrismaClientWithCustomTransaction {
2
+ export declare abstract class PrismaTransactionalClient {
4
3
  protected readonly transactionalClient: Prisma.TransactionClient;
5
4
  constructor(transactionalClient: Prisma.TransactionClient);
6
5
  withTransaction<F>(fn: (prisma: Prisma.TransactionClient) => Promise<F>): Promise<F>;
@@ -5,6 +5,9 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
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
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
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
+ };
8
11
  Object.defineProperty(exports, "__esModule", { value: true });
9
12
  exports.PrismaService = void 0;
10
13
  const common_1 = require("@nestjs/common");
@@ -34,5 +37,6 @@ let PrismaService = exports.PrismaService = class PrismaService extends client_1
34
37
  }
35
38
  };
36
39
  exports.PrismaService = PrismaService = __decorate([
37
- (0, common_1.Injectable)()
40
+ (0, common_1.Injectable)(),
41
+ __metadata("design:paramtypes", [])
38
42
  ], PrismaService);
@@ -1,17 +1,33 @@
1
- import { PaginationParams } from '../../common/models/pagination-params';
2
- import { PrismaClientWithCustomTransaction } from '../../services/prisma/prisma-client-with-custom-transaction.interface';
3
- import { PrismaTransactionalClient } from '../../services/prisma/prisma-transactional-client';
4
- import { ModelName } from '../../services/prisma/prisma.types';
5
- import { Entity } from './entity';
6
- export interface FindAllProps<TPaginateAndOrdering extends PaginationParams, TWhere, TInclude = any> {
7
- where: TWhere;
8
- paginateAndOrderingProps?: TPaginateAndOrdering;
9
- include?: TInclude;
1
+ import { Type } from '@nestjs/common';
2
+ import { ListResponse } from '../@types';
3
+ import { PaginationParams } from '../models/pagination-params';
4
+ import { IComparableId } from '../utils/interfaces/icomparable';
5
+ import { EntityBase } from './entity.base';
6
+ import { PrismaTransactionalClient } from './prisma-transactional-client';
7
+ type RepositoryInclude<TEntity> = {
8
+ [key in keyof TEntity]?: boolean | RepositoryInclude<TEntity[keyof TEntity]>;
9
+ };
10
+ interface RepositoryInitProps<TEntity> {
11
+ context: PrismaTransactionalClient;
12
+ modelName: Type<TEntity>;
13
+ transactionContext?: Type<PrismaTransactionalClient>;
14
+ include?: RepositoryInclude<TEntity>;
10
15
  }
11
- export declare abstract class RepositoryBase<TEntity extends Entity<TEntity>> {
12
- protected prisma: PrismaClientWithCustomTransaction;
16
+ export declare abstract class RepositoryBase<TEntity extends EntityBase<TEntity>> {
17
+ protected _context: PrismaTransactionalClient;
13
18
  private readonly _modelName;
14
- constructor(prisma: PrismaClientWithCustomTransaction, _modelName: ModelName);
19
+ private readonly _include?;
20
+ constructor({ context, modelName, include, }: RepositoryInitProps<TEntity>);
15
21
  withTransaction(fn: (prisma: PrismaTransactionalClient) => Promise<any>): Promise<any>;
16
- protected repository(transactionalClient?: PrismaTransactionalClient): import(".prisma/client").Prisma.TestDelegate<import("@prisma/client/runtime/library").DefaultArgs>;
22
+ protected findById(id: IComparableId): Promise<TEntity | null>;
23
+ protected findMany<T>(where: T, pagination?: PaginationParams): Promise<any>;
24
+ protected findManyAndCount<T>(where: T, pagination?: PaginationParams): Promise<ListResponse<TEntity>>;
25
+ protected saveChanges(entity: TEntity): any;
26
+ protected delete(id: IComparableId): any;
27
+ private listToRelationActionList;
28
+ private entityToPrisma;
29
+ private context;
30
+ private findManySchema;
31
+ private createEntity;
17
32
  }
33
+ export {};
@@ -1,27 +1,154 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RepositoryBase = void 0;
4
- const prisma_transactional_client_1 = require("../../services/prisma/prisma-transactional-client");
5
- const prisma_types_1 = require("../../services/prisma/prisma.types");
4
+ const string_1 = require("@koalarx/utils/operators/string");
5
+ const koala_global_vars_1 = require("../koala-global-vars");
6
+ const pagination_params_1 = require("../models/pagination-params");
7
+ const list_1 = require("../utils/list");
8
+ const entity_base_1 = require("./entity.base");
6
9
  class RepositoryBase {
7
- prisma;
10
+ _context;
8
11
  _modelName;
9
- constructor(prisma, _modelName) {
10
- this.prisma = prisma;
11
- this._modelName = _modelName;
12
+ _include;
13
+ constructor({ context, modelName, include, }) {
14
+ this._context = context;
15
+ this._modelName = modelName;
16
+ this._include = include;
12
17
  }
13
18
  withTransaction(fn) {
14
- return this.prisma.withTransaction(async (client) => {
15
- return fn(new prisma_transactional_client_1.PrismaTransactionalClient(client));
19
+ return this._context.withTransaction(async (client) => {
20
+ return fn(new koala_global_vars_1.KoalaGlobalVars.dbTransactionContext(client));
16
21
  });
17
22
  }
18
- repository(transactionalClient) {
19
- const modelName = this._modelName;
20
- const prisma = (transactionalClient ?? this.prisma);
21
- const repository = (0, prisma_types_1.getPrismaDelegate)(modelName, prisma);
22
- if (!repository)
23
- throw new Error('Entidade não mapeada no repositório do prisma');
24
- return repository;
23
+ async findById(id) {
24
+ return this.context()
25
+ .findFirst({
26
+ include: this._include,
27
+ where: { id },
28
+ })
29
+ .then((response) => {
30
+ if (response) {
31
+ return this.createEntity(response);
32
+ }
33
+ return null;
34
+ });
35
+ }
36
+ async findMany(where, pagination) {
37
+ return this.context()
38
+ .findMany(this.findManySchema(where, pagination))
39
+ .then((result) => result.map((response) => this.createEntity(response)));
40
+ }
41
+ async findManyAndCount(where, pagination) {
42
+ const count = await this.context().count({ where });
43
+ if (count > 0) {
44
+ const items = await this.findMany(where, Object.assign(new pagination_params_1.PaginationParams(), pagination));
45
+ return { items, count };
46
+ }
47
+ return { items: [], count };
48
+ }
49
+ saveChanges(entity) {
50
+ const prismaEntity = this.entityToPrisma(entity);
51
+ const isCreate = !entity._id;
52
+ if (isCreate) {
53
+ return this.context().create({
54
+ data: prismaEntity,
55
+ });
56
+ }
57
+ else {
58
+ return this.withTransaction((client) => this.context(client)
59
+ .update({
60
+ where: { id: entity._id },
61
+ data: prismaEntity,
62
+ })
63
+ .then(() => {
64
+ const { relationUpdates, relationDeletes } = this.listToRelationActionList(entity);
65
+ return Promise.all([
66
+ ...relationUpdates.map((relation) => client[relation.modelName].updateMany(relation.schema)),
67
+ ...relationDeletes.map((relation) => client[relation.modelName].deleteMany(relation.schema)),
68
+ ]);
69
+ }));
70
+ }
71
+ }
72
+ delete(id) {
73
+ return this.context().delete({
74
+ where: { id },
75
+ });
76
+ }
77
+ listToRelationActionList(entity) {
78
+ const relationUpdates = [];
79
+ const relationDeletes = [];
80
+ Object.keys(entity).forEach((key) => {
81
+ if (entity[key] instanceof list_1.List) {
82
+ const list = entity[key];
83
+ const modelName = list.entityType?.name;
84
+ if (modelName) {
85
+ list.toArray('removed').forEach((item) => {
86
+ relationDeletes.push({
87
+ modelName: (0, string_1.toCamelCase)(modelName),
88
+ schema: { where: { id: item._id } },
89
+ });
90
+ });
91
+ list.toArray('updated').forEach((item) => {
92
+ relationUpdates.push({
93
+ modelName: (0, string_1.toCamelCase)(modelName),
94
+ schema: {
95
+ where: { id: item._id },
96
+ data: this.entityToPrisma(item),
97
+ },
98
+ });
99
+ });
100
+ }
101
+ }
102
+ });
103
+ return { relationUpdates, relationDeletes };
104
+ }
105
+ entityToPrisma(entity) {
106
+ const prismaSchema = {};
107
+ Object.keys(entity)
108
+ .filter((key) => key !== 'id' && key !== '_id')
109
+ .forEach((key) => {
110
+ if (entity[key] instanceof list_1.List) {
111
+ if (entity[key].toArray('added').length > 0) {
112
+ prismaSchema[key] = {
113
+ createMany: {
114
+ data: entity[key].toArray('added').map((item) => {
115
+ return this.entityToPrisma(item);
116
+ }),
117
+ },
118
+ };
119
+ }
120
+ }
121
+ else if (entity[key] instanceof entity_base_1.EntityBase) {
122
+ prismaSchema[key] = this.entityToPrisma(entity[key]);
123
+ }
124
+ else {
125
+ prismaSchema[key] = entity[key];
126
+ }
127
+ });
128
+ return prismaSchema;
129
+ }
130
+ context(transactionalClient) {
131
+ const modelName = this._modelName.name;
132
+ if (!modelName)
133
+ throw new Error('modelName não informado no contrutor do repositorio');
134
+ if (transactionalClient) {
135
+ return transactionalClient[(0, string_1.toCamelCase)(modelName)];
136
+ }
137
+ return this._context[modelName];
138
+ }
139
+ findManySchema(where, pagination) {
140
+ return {
141
+ include: this._include,
142
+ where,
143
+ orderBy: pagination?.generateOrderBy(),
144
+ skip: pagination?.skip(),
145
+ take: (pagination?.limit ?? 0) > 0 ? pagination?.limit : undefined,
146
+ };
147
+ }
148
+ createEntity(data) {
149
+ const entity = new this._modelName();
150
+ entity.automap(data);
151
+ return entity;
25
152
  }
26
153
  }
27
154
  exports.RepositoryBase = RepositoryBase;