@volontariapp/database 1.5.1-snapshot.7832680e7383 → 1.6.0-snap-e5122cd

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 (69) hide show
  1. package/CHANGELOG.md +6 -11
  2. package/dist/outbox/entities/outbox.entity.d.ts +12 -0
  3. package/dist/outbox/entities/outbox.entity.d.ts.map +1 -0
  4. package/dist/outbox/entities/outbox.entity.js +11 -0
  5. package/dist/outbox/entities/outbox.entity.js.map +1 -0
  6. package/dist/outbox/models/outbox.model.d.ts +12 -0
  7. package/dist/outbox/models/outbox.model.d.ts.map +1 -0
  8. package/dist/outbox/models/outbox.model.js +58 -0
  9. package/dist/outbox/models/outbox.model.js.map +1 -0
  10. package/dist/outbox/types/outbox.status.d.ts +7 -0
  11. package/dist/outbox/types/outbox.status.d.ts.map +1 -0
  12. package/dist/outbox/types/outbox.status.js +8 -0
  13. package/dist/outbox/types/outbox.status.js.map +1 -0
  14. package/dist/outbox/writer/outbox.writer.d.ts +15 -0
  15. package/dist/outbox/writer/outbox.writer.d.ts.map +1 -0
  16. package/dist/outbox/writer/outbox.writer.js +85 -0
  17. package/dist/outbox/writer/outbox.writer.js.map +1 -0
  18. package/dist/test/core/outbox.int.spec.d.ts +2 -0
  19. package/dist/test/core/outbox.int.spec.d.ts.map +1 -0
  20. package/dist/test/core/outbox.int.spec.js +165 -0
  21. package/dist/test/core/outbox.int.spec.js.map +1 -0
  22. package/dist/test/data-source.d.ts.map +1 -1
  23. package/dist/test/data-source.js +3 -1
  24. package/dist/test/data-source.js.map +1 -1
  25. package/dist/test/example/entities/extended-outbox.entity.d.ts +5 -0
  26. package/dist/test/example/entities/extended-outbox.entity.d.ts.map +1 -0
  27. package/dist/test/example/entities/extended-outbox.entity.js +5 -0
  28. package/dist/test/example/entities/extended-outbox.entity.js.map +1 -0
  29. package/dist/test/example/models/extended-outbox.model.d.ts +5 -0
  30. package/dist/test/example/models/extended-outbox.model.d.ts.map +1 -0
  31. package/dist/test/example/models/extended-outbox.model.js +23 -0
  32. package/dist/test/example/models/extended-outbox.model.js.map +1 -0
  33. package/dist/test/global-setup.d.ts +3 -0
  34. package/dist/test/global-setup.d.ts.map +1 -0
  35. package/dist/test/global-setup.js +29 -0
  36. package/dist/test/global-setup.js.map +1 -0
  37. package/dist/test/outbox/outbox.model.unit.spec.d.ts +2 -0
  38. package/dist/test/outbox/outbox.model.unit.spec.d.ts.map +1 -0
  39. package/dist/test/outbox/outbox.model.unit.spec.js +28 -0
  40. package/dist/test/outbox/outbox.model.unit.spec.js.map +1 -0
  41. package/dist/test/outbox/outbox.writer.unit.spec.d.ts +2 -0
  42. package/dist/test/outbox/outbox.writer.unit.spec.d.ts.map +1 -0
  43. package/dist/test/outbox/outbox.writer.unit.spec.js +116 -0
  44. package/dist/test/outbox/outbox.writer.unit.spec.js.map +1 -0
  45. package/dist/test/utils/extended-outbox-event.helper.d.ts +3 -0
  46. package/dist/test/utils/extended-outbox-event.helper.d.ts.map +1 -0
  47. package/dist/test/utils/extended-outbox-event.helper.js +15 -0
  48. package/dist/test/utils/extended-outbox-event.helper.js.map +1 -0
  49. package/dist/test/utils/logger-mock.helper.d.ts +10 -0
  50. package/dist/test/utils/logger-mock.helper.d.ts.map +1 -0
  51. package/dist/test/utils/logger-mock.helper.js +9 -0
  52. package/dist/test/utils/logger-mock.helper.js.map +1 -0
  53. package/dist/test/utils/outbox-event.helper.d.ts +3 -0
  54. package/dist/test/utils/outbox-event.helper.d.ts.map +1 -0
  55. package/dist/test/utils/outbox-event.helper.js +9 -0
  56. package/dist/test/utils/outbox-event.helper.js.map +1 -0
  57. package/dist/test/utils/outbox-extended-test.repository.d.ts +8 -0
  58. package/dist/test/utils/outbox-extended-test.repository.d.ts.map +1 -0
  59. package/dist/test/utils/outbox-extended-test.repository.js +15 -0
  60. package/dist/test/utils/outbox-extended-test.repository.js.map +1 -0
  61. package/dist/test/utils/outbox-test.repository.d.ts +8 -0
  62. package/dist/test/utils/outbox-test.repository.d.ts.map +1 -0
  63. package/dist/test/utils/outbox-test.repository.js +9 -0
  64. package/dist/test/utils/outbox-test.repository.js.map +1 -0
  65. package/dist/test/utils/outbox-writer-mock.helper.d.ts +7 -0
  66. package/dist/test/utils/outbox-writer-mock.helper.d.ts.map +1 -0
  67. package/dist/test/utils/outbox-writer-mock.helper.js +10 -0
  68. package/dist/test/utils/outbox-writer-mock.helper.js.map +1 -0
  69. package/package.json +4 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Added generic representation of an outbox model
8
+
3
9
  ## 1.5.1
4
10
 
5
11
  ### Patch Changes
@@ -9,17 +15,6 @@
9
15
  - Updated dependencies []:
10
16
  - @volontariapp/logger@0.2.3
11
17
 
12
- ## 1.5.0
13
-
14
- ### Minor Changes
15
-
16
- - patch database update
17
-
18
- ## 1.4.0
19
-
20
- ### Minor Changes
21
-
22
- - fix: update
23
18
 
24
19
  ## 1.3.0
25
20
 
@@ -0,0 +1,12 @@
1
+ import type { OutboxStatus } from '../types/outbox.status.js';
2
+ export declare class OutboxEntity {
3
+ id: string;
4
+ status: OutboxStatus;
5
+ attempts: number;
6
+ lastError?: string;
7
+ type: string;
8
+ emitter: string;
9
+ createdAt: Date;
10
+ updatedAt?: Date;
11
+ }
12
+ //# sourceMappingURL=outbox.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.entity.d.ts","sourceRoot":"","sources":["../../../src/outbox/entities/outbox.entity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAE9D,qBAAa,YAAY;IACvB,EAAE,EAAG,MAAM,CAAC;IAGZ,MAAM,EAAG,YAAY,CAAC;IACtB,QAAQ,EAAG,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAG,MAAM,CAAC;IACd,OAAO,EAAG,MAAM,CAAC;IAEjB,SAAS,EAAG,IAAI,CAAC;IACjB,SAAS,CAAC,EAAE,IAAI,CAAC;CAClB"}
@@ -0,0 +1,11 @@
1
+ export class OutboxEntity {
2
+ id;
3
+ status;
4
+ attempts;
5
+ lastError;
6
+ type;
7
+ emitter;
8
+ createdAt;
9
+ updatedAt;
10
+ }
11
+ //# sourceMappingURL=outbox.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.entity.js","sourceRoot":"","sources":["../../../src/outbox/entities/outbox.entity.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,YAAY;IACvB,EAAE,CAAU;IAGZ,MAAM,CAAgB;IACtB,QAAQ,CAAU;IAClB,SAAS,CAAU;IAEnB,IAAI,CAAU;IACd,OAAO,CAAU;IAEjB,SAAS,CAAQ;IACjB,SAAS,CAAQ;CAClB"}
@@ -0,0 +1,12 @@
1
+ import { OutboxStatus } from '../types/outbox.status.js';
2
+ export declare class OutboxModel {
3
+ id: string;
4
+ status: OutboxStatus;
5
+ attempts: number;
6
+ lastError?: string;
7
+ type: string;
8
+ emitter: string;
9
+ updatedAt?: Date;
10
+ createdAt: Date;
11
+ }
12
+ //# sourceMappingURL=outbox.model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.model.d.ts","sourceRoot":"","sources":["../../../src/outbox/models/outbox.model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,qBACa,WAAW;IAEtB,EAAE,EAAG,MAAM,CAAC;IAIZ,MAAM,EAAE,YAAY,CAAwB;IAE5C,QAAQ,EAAE,MAAM,CAAK;IAErB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,IAAI,EAAG,MAAM,CAAC;IAEd,OAAO,EAAG,MAAM,CAAC;IAGjB,SAAS,CAAC,EAAE,IAAI,CAAC;IAEjB,SAAS,EAAE,IAAI,CAAc;CAC9B"}
@@ -0,0 +1,58 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
11
+ import { OutboxStatus } from '../types/outbox.status.js';
12
+ let OutboxModel = class OutboxModel {
13
+ id;
14
+ status = OutboxStatus.PENDING;
15
+ attempts = 0;
16
+ lastError;
17
+ type;
18
+ emitter;
19
+ updatedAt;
20
+ createdAt = new Date();
21
+ };
22
+ __decorate([
23
+ PrimaryGeneratedColumn('uuid'),
24
+ __metadata("design:type", String)
25
+ ], OutboxModel.prototype, "id", void 0);
26
+ __decorate([
27
+ Column({ type: 'varchar', length: 20, default: OutboxStatus.PENDING }),
28
+ __metadata("design:type", String)
29
+ ], OutboxModel.prototype, "status", void 0);
30
+ __decorate([
31
+ Column({ type: 'int', default: 0 }),
32
+ __metadata("design:type", Number)
33
+ ], OutboxModel.prototype, "attempts", void 0);
34
+ __decorate([
35
+ Column({ type: 'text', nullable: true }),
36
+ __metadata("design:type", String)
37
+ ], OutboxModel.prototype, "lastError", void 0);
38
+ __decorate([
39
+ Column({ type: 'varchar', length: 100 }),
40
+ __metadata("design:type", String)
41
+ ], OutboxModel.prototype, "type", void 0);
42
+ __decorate([
43
+ Column({ type: 'varchar', length: 100 }),
44
+ __metadata("design:type", String)
45
+ ], OutboxModel.prototype, "emitter", void 0);
46
+ __decorate([
47
+ Column({ name: 'updated_at', type: 'timestamp' }),
48
+ __metadata("design:type", Date)
49
+ ], OutboxModel.prototype, "updatedAt", void 0);
50
+ __decorate([
51
+ Column({ name: 'created_at', type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }),
52
+ __metadata("design:type", Date)
53
+ ], OutboxModel.prototype, "createdAt", void 0);
54
+ OutboxModel = __decorate([
55
+ Entity('outbox')
56
+ ], OutboxModel);
57
+ export { OutboxModel };
58
+ //# sourceMappingURL=outbox.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.model.js","sourceRoot":"","sources":["../../../src/outbox/models/outbox.model.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGlD,IAAM,WAAW,GAAjB,MAAM,WAAW;IAEtB,EAAE,CAAU;IAIZ,MAAM,GAAiB,YAAY,CAAC,OAAO,CAAC;IAE5C,QAAQ,GAAW,CAAC,CAAC;IAErB,SAAS,CAAU;IAGnB,IAAI,CAAU;IAEd,OAAO,CAAU;IAGjB,SAAS,CAAQ;IAEjB,SAAS,GAAS,IAAI,IAAI,EAAE,CAAC;CAC9B,CAAA;AAnBC;IADC,sBAAsB,CAAC,MAAM,CAAC;;uCACnB;AAIZ;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC;;2CAC3B;AAE5C;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;6CACf;AAErB;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;;8CACtB;AAGnB;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;;yCAC3B;AAEd;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;;4CACxB;AAGjB;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAC,CAAC;8BACrC,IAAI;8CAAC;AAEjB;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,mBAAmB,EAAE,CAAC;8BAC3E,IAAI;8CAAc;AApBlB,WAAW;IADvB,MAAM,CAAC,QAAQ,CAAC;GACJ,WAAW,CAqBvB"}
@@ -0,0 +1,7 @@
1
+ export declare enum OutboxStatus {
2
+ PENDING = "PENDING",
3
+ PROCESSING = "PROCESSING",
4
+ COMPLETED = "COMPLETED",
5
+ FAILED = "FAILED"
6
+ }
7
+ //# sourceMappingURL=outbox.status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.status.d.ts","sourceRoot":"","sources":["../../../src/outbox/types/outbox.status.ts"],"names":[],"mappings":"AAAA,oBAAY,YAAY;IACtB,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,SAAS,cAAc;IACvB,MAAM,WAAW;CAClB"}
@@ -0,0 +1,8 @@
1
+ export var OutboxStatus;
2
+ (function (OutboxStatus) {
3
+ OutboxStatus["PENDING"] = "PENDING";
4
+ OutboxStatus["PROCESSING"] = "PROCESSING";
5
+ OutboxStatus["COMPLETED"] = "COMPLETED";
6
+ OutboxStatus["FAILED"] = "FAILED";
7
+ })(OutboxStatus || (OutboxStatus = {}));
8
+ //# sourceMappingURL=outbox.status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.status.js","sourceRoot":"","sources":["../../../src/outbox/types/outbox.status.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,YAKX;AALD,WAAY,YAAY;IACtB,mCAAmB,CAAA;IACnB,yCAAyB,CAAA;IACzB,uCAAuB,CAAA;IACvB,iCAAiB,CAAA;AACnB,CAAC,EALW,YAAY,KAAZ,YAAY,QAKvB"}
@@ -0,0 +1,15 @@
1
+ import type { BaseRepository } from '../../core/base.repository.js';
2
+ import { OutboxEntity } from '../entities/outbox.entity.js';
3
+ import { OutboxModel } from '../models/outbox.model.js';
4
+ import { Logger } from '@volontariapp/logger';
5
+ export declare class OutboxWriter<TOutboxModel extends OutboxModel, TOutboxEntity extends OutboxEntity> {
6
+ private readonly logger;
7
+ private readonly repository;
8
+ constructor(logger: Logger, repository: BaseRepository<TOutboxModel, TOutboxEntity, string>);
9
+ private assertWritable;
10
+ create(outboxEntity: TOutboxEntity): Promise<void>;
11
+ createMany(outboxEntities: TOutboxEntity[]): Promise<void>;
12
+ update(outboxEntity: TOutboxEntity): Promise<void>;
13
+ delete(id: string): Promise<void>;
14
+ }
15
+ //# sourceMappingURL=outbox.writer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.writer.d.ts","sourceRoot":"","sources":["../../../src/outbox/writer/outbox.writer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAM9C,qBAAa,YAAY,CAAC,YAAY,SAAS,WAAW,EAAE,aAAa,SAAS,YAAY;IAE1F,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;gBADV,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,cAAc,CAAC,YAAY,EAAE,aAAa,EAAE,MAAM,CAAC;IAGlF,OAAO,CAAC,cAAc;IA4BhB,MAAM,CAAC,YAAY,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBlD,UAAU,CAAC,cAAc,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAa1D,MAAM,CAAC,YAAY,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAYlD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAWxC"}
@@ -0,0 +1,85 @@
1
+ import { UnprocessableEntityError } from '@volontariapp/errors';
2
+ import { OutboxEntity } from '../entities/outbox.entity.js';
3
+ import { OutboxModel } from '../models/outbox.model.js';
4
+ import { databaseMapper } from '../../core/mapper.service.js';
5
+ databaseMapper.registerBidirectional(OutboxModel, OutboxEntity);
6
+ export class OutboxWriter {
7
+ logger;
8
+ repository;
9
+ constructor(logger, repository) {
10
+ this.logger = logger;
11
+ this.repository = repository;
12
+ }
13
+ assertWritable(outboxModel) {
14
+ const createdAt = outboxModel.createdAt;
15
+ if (!(createdAt instanceof Date) || Number.isNaN(createdAt.getTime())) {
16
+ this.logger.warn('Rejected outbox event with invalid createdAt', {
17
+ type: outboxModel.type,
18
+ emitter: outboxModel.emitter,
19
+ createdAt,
20
+ });
21
+ throw new UnprocessableEntityError('Outbox createdAt must be a valid date', 'OUTBOX_INVALID_CREATED_AT', {
22
+ field: 'createdAt',
23
+ });
24
+ }
25
+ if (createdAt.getTime() > Date.now()) {
26
+ this.logger.warn('Rejected outbox event with future createdAt', {
27
+ type: outboxModel.type,
28
+ emitter: outboxModel.emitter,
29
+ createdAt: createdAt.toISOString(),
30
+ });
31
+ throw new UnprocessableEntityError('Outbox createdAt cannot be in the future', 'OUTBOX_FUTURE_CREATED_AT', { field: 'createdAt' });
32
+ }
33
+ }
34
+ async create(outboxEntity) {
35
+ this.logger.info('Creating outbox event', {
36
+ type: outboxEntity.type,
37
+ emitter: outboxEntity.emitter,
38
+ id: outboxEntity.id,
39
+ });
40
+ try {
41
+ this.assertWritable(outboxEntity);
42
+ await this.repository.create(outboxEntity);
43
+ this.logger.info('Outbox event created', { id: outboxEntity.id, type: outboxEntity.type });
44
+ }
45
+ catch (error) {
46
+ this.logger.error('Failed to create outbox event', error);
47
+ throw error;
48
+ }
49
+ }
50
+ async createMany(outboxEntities) {
51
+ this.logger.info('Creating outbox events batch', { count: outboxEntities.length });
52
+ try {
53
+ outboxEntities.forEach((outboxEntity) => this.assertWritable(outboxEntity));
54
+ await this.repository.createMany(outboxEntities);
55
+ this.logger.info('Outbox events batch created', { count: outboxEntities.length });
56
+ }
57
+ catch (error) {
58
+ this.logger.error('Failed to create outbox events batch', error);
59
+ throw error;
60
+ }
61
+ }
62
+ async update(outboxEntity) {
63
+ this.logger.info('Updating outbox event', { id: outboxEntity.id, type: outboxEntity.type });
64
+ try {
65
+ await this.repository.update(outboxEntity.id, outboxEntity);
66
+ this.logger.info('Outbox event updated', { id: outboxEntity.id });
67
+ }
68
+ catch (error) {
69
+ this.logger.error('Failed to update outbox event', error);
70
+ throw error;
71
+ }
72
+ }
73
+ async delete(id) {
74
+ this.logger.info('Deleting outbox event', { id });
75
+ try {
76
+ await this.repository.delete(id);
77
+ this.logger.info('Outbox event deleted', { id });
78
+ }
79
+ catch (error) {
80
+ this.logger.error('Failed to delete outbox event', error);
81
+ throw error;
82
+ }
83
+ }
84
+ }
85
+ //# sourceMappingURL=outbox.writer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.writer.js","sourceRoot":"","sources":["../../../src/outbox/writer/outbox.writer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outbox.int.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.int.spec.d.ts","sourceRoot":"","sources":["../../../src/test/core/outbox.int.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,165 @@
1
+ import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals';
2
+ import { testDataSource, initializeTestDb, closeTestDb } from '../data-source.js';
3
+ import { OutboxModel } from '../../outbox/models/outbox.model.js';
4
+ import { OutboxWriter } from '../../outbox/writer/outbox.writer.js';
5
+ import { OutboxStatus } from '../../outbox/types/outbox.status.js';
6
+ import { OutboxEntity } from '../../outbox/entities/outbox.entity.js';
7
+ import { databaseMapper } from '../../core/mapper.service.js';
8
+ import { makeOutboxEvent } from '../utils/outbox-event.helper.js';
9
+ import { makeExtendedOutboxEvent } from '../utils/extended-outbox-event.helper.js';
10
+ import { TestOutboxWriterRepository } from '../utils/outbox-test.repository.js';
11
+ import { TestExtendedOutboxWriter } from '../utils/outbox-extended-test.repository.js';
12
+ import { ExtendedOutboxEntity } from '../example/entities/extended-outbox.entity.js';
13
+ import { ExtendedOutboxModel } from '../example/models/extended-outbox.model.js';
14
+ describe('Outbox Writer (Full Integration)', () => {
15
+ let outboxWriter;
16
+ let repository;
17
+ const logger = {
18
+ info: () => undefined,
19
+ warn: () => undefined,
20
+ error: () => undefined,
21
+ };
22
+ beforeAll(async () => {
23
+ await initializeTestDb();
24
+ repository = new TestOutboxWriterRepository(testDataSource.getRepository(OutboxModel));
25
+ outboxWriter = new OutboxWriter(logger, repository);
26
+ });
27
+ afterAll(async () => {
28
+ await closeTestDb();
29
+ });
30
+ beforeEach(async () => {
31
+ await testDataSource.getRepository(OutboxModel).createQueryBuilder().delete().execute();
32
+ });
33
+ it('create() should persist event in database', async () => {
34
+ const event = makeOutboxEvent();
35
+ await outboxWriter.create(event);
36
+ const rows = await testDataSource.getRepository(OutboxModel).find();
37
+ expect(rows).toHaveLength(1);
38
+ expect(rows[0].type).toBe('user.created');
39
+ expect(rows[0].status).toBe(OutboxStatus.PENDING);
40
+ expect(rows[0].attempts).toBe(0);
41
+ expect(rows[0].id).toBeDefined();
42
+ });
43
+ it('createMany() should persist all events with provided structure', async () => {
44
+ const events = [
45
+ makeOutboxEvent({ type: 'user.created' }),
46
+ makeOutboxEvent({
47
+ type: 'user.updated',
48
+ status: OutboxStatus.PROCESSING,
49
+ attempts: 2,
50
+ }),
51
+ ];
52
+ await outboxWriter.createMany(events);
53
+ const rows = await testDataSource.getRepository(OutboxModel).find({ order: { type: 'ASC' } });
54
+ expect(rows).toHaveLength(2);
55
+ expect(rows[0].type).toBe('user.created');
56
+ expect(rows[1].type).toBe('user.updated');
57
+ expect(rows[1].status).toBe(OutboxStatus.PROCESSING);
58
+ expect(rows[1].attempts).toBe(2);
59
+ });
60
+ it('update() should persist outbox event updates in database', async () => {
61
+ const event = makeOutboxEvent({ attempts: 0, status: OutboxStatus.PENDING });
62
+ await outboxWriter.create(event);
63
+ const row = await testDataSource.getRepository(OutboxModel).findOneByOrFail({ type: event.type });
64
+ const toUpdate = Object.assign(new OutboxEntity(), row, {
65
+ status: OutboxStatus.PROCESSING,
66
+ attempts: 1,
67
+ });
68
+ await outboxWriter.update(toUpdate);
69
+ const updated = await testDataSource.getRepository(OutboxModel).findOneByOrFail({ id: row.id });
70
+ expect(updated.status).toBe(OutboxStatus.PROCESSING);
71
+ expect(updated.attempts).toBe(1);
72
+ });
73
+ it('delete() should remove outbox event from database', async () => {
74
+ const event = makeOutboxEvent({ type: 'user.deleted' });
75
+ await outboxWriter.create(event);
76
+ const row = await testDataSource.getRepository(OutboxModel).findOneByOrFail({ type: event.type });
77
+ await outboxWriter.delete(row.id);
78
+ const deleted = await testDataSource.getRepository(OutboxModel).findOneBy({ id: row.id });
79
+ expect(deleted).toBeNull();
80
+ });
81
+ });
82
+ describe('Outbox Writer with extended model/entity (Full Integration)', () => {
83
+ let outboxWriter;
84
+ const logger = {
85
+ info: () => undefined,
86
+ warn: () => undefined,
87
+ error: () => undefined,
88
+ };
89
+ beforeAll(async () => {
90
+ await initializeTestDb();
91
+ databaseMapper.registerBidirectional(ExtendedOutboxModel, ExtendedOutboxEntity);
92
+ outboxWriter = new TestExtendedOutboxWriter(logger, testDataSource.getRepository(ExtendedOutboxModel));
93
+ });
94
+ afterAll(async () => {
95
+ await closeTestDb();
96
+ });
97
+ beforeEach(async () => {
98
+ await testDataSource.getRepository(ExtendedOutboxModel).createQueryBuilder().delete().execute();
99
+ });
100
+ it('create() should persist an extended outbox entity', async () => {
101
+ const event = makeExtendedOutboxEvent({
102
+ type: 'extended.created',
103
+ channel: 'sms',
104
+ });
105
+ await outboxWriter.create(event);
106
+ const row = await testDataSource
107
+ .getRepository(ExtendedOutboxModel)
108
+ .findOneByOrFail({ type: 'extended.created' });
109
+ expect(row.channel).toBe('sms');
110
+ });
111
+ it('createMany() should persist extended outbox entities', async () => {
112
+ const events = [
113
+ makeExtendedOutboxEvent({
114
+ type: 'extended.created',
115
+ createdAt: new Date(Date.now() - 60_000),
116
+ channel: 'sms',
117
+ }),
118
+ makeExtendedOutboxEvent({
119
+ type: 'extended.updated',
120
+ createdAt: new Date(Date.now() - 30_000),
121
+ channel: 'email',
122
+ }),
123
+ ];
124
+ await outboxWriter.createMany(events);
125
+ const rows = await testDataSource.getRepository(ExtendedOutboxModel).find({ order: { type: 'ASC' } });
126
+ expect(rows).toHaveLength(2);
127
+ expect(rows[0].channel).toBe('sms');
128
+ expect(rows[1].channel).toBe('email');
129
+ });
130
+ it('update() should persist channel and status updates on extended entities', async () => {
131
+ const event = makeExtendedOutboxEvent({
132
+ type: 'extended.to-update',
133
+ channel: 'push',
134
+ });
135
+ await outboxWriter.create(event);
136
+ const created = await testDataSource
137
+ .getRepository(ExtendedOutboxModel)
138
+ .findOneByOrFail({ type: 'extended.to-update' });
139
+ const toUpdate = makeExtendedOutboxEvent({
140
+ ...created,
141
+ status: OutboxStatus.PROCESSING,
142
+ attempts: 2,
143
+ channel: 'sms',
144
+ });
145
+ await outboxWriter.update(toUpdate);
146
+ const updated = await testDataSource.getRepository(ExtendedOutboxModel).findOneByOrFail({ id: created.id });
147
+ expect(updated.status).toBe(OutboxStatus.PROCESSING);
148
+ expect(updated.attempts).toBe(2);
149
+ expect(updated.channel).toBe('sms');
150
+ });
151
+ it('delete() should remove an extended outbox entity', async () => {
152
+ const event = makeExtendedOutboxEvent({
153
+ type: 'extended.to-delete',
154
+ channel: 'sms',
155
+ });
156
+ await outboxWriter.create(event);
157
+ const created = await testDataSource
158
+ .getRepository(ExtendedOutboxModel)
159
+ .findOneByOrFail({ type: 'extended.to-delete' });
160
+ await outboxWriter.delete(created.id);
161
+ const deleted = await testDataSource.getRepository(ExtendedOutboxModel).findOneBy({ id: created.id });
162
+ expect(deleted).toBeNull();
163
+ });
164
+ });
165
+ //# sourceMappingURL=outbox.int.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.int.spec.js","sourceRoot":"","sources":["../../../src/test/core/outbox.int.spec.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"data-source.d.ts","sourceRoot":"","sources":["../../src/test/data-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIrC,eAAO,MAAM,cAAc,YAWzB,CAAC;AAEH,eAAO,MAAM,gBAAgB,qBAI5B,CAAC;AAEF,eAAO,MAAM,WAAW,qBAIvB,CAAC"}
1
+ {"version":3,"file":"data-source.d.ts","sourceRoot":"","sources":["../../src/test/data-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAMrC,eAAO,MAAM,cAAc,YAWzB,CAAC;AAEH,eAAO,MAAM,gBAAgB,qBAI5B,CAAC;AAEF,eAAO,MAAM,WAAW,qBAIvB,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import { DataSource } from 'typeorm';
2
2
  import { UserModel } from './example/models/user.model.js';
3
3
  import { ProfileModel } from './example/models/profile.model.js';
4
+ import { OutboxModel } from '../outbox/models/outbox.model.js';
5
+ import { ExtendedOutboxModel } from './example/models/extended-outbox.model.js';
4
6
  export const testDataSource = new DataSource({
5
7
  type: 'postgres',
6
8
  host: 'localhost',
@@ -8,7 +10,7 @@ export const testDataSource = new DataSource({
8
10
  username: 'testuser',
9
11
  password: 'testpassword',
10
12
  database: 'volontariapp_test',
11
- entities: [UserModel, ProfileModel],
13
+ entities: [UserModel, ProfileModel, OutboxModel, ExtendedOutboxModel],
12
14
  synchronize: true,
13
15
  logging: false,
14
16
  dropSchema: true,
@@ -1 +1 @@
1
- {"version":3,"file":"data-source.js","sourceRoot":"","sources":["../../src/test/data-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAEjE,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,UAAU,CAAC;IAC3C,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,cAAc;IACxB,QAAQ,EAAE,mBAAmB;IAC7B,QAAQ,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;IACnC,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,IAAI;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;IACzC,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,cAAc,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;IACpC,IAAI,cAAc,CAAC,aAAa,EAAE,CAAC;QACjC,MAAM,cAAc,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"data-source.js","sourceRoot":"","sources":["../../src/test/data-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AAEhF,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,UAAU,CAAC;IAC3C,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,WAAW;IACjB,IAAI,EAAE,IAAI;IACV,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,cAAc;IACxB,QAAQ,EAAE,mBAAmB;IAC7B,QAAQ,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,mBAAmB,CAAC;IACrE,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,IAAI;CACjB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;IACzC,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC;QAClC,MAAM,cAAc,CAAC,UAAU,EAAE,CAAC;IACpC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;IACpC,IAAI,cAAc,CAAC,aAAa,EAAE,CAAC;QACjC,MAAM,cAAc,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { OutboxEntity } from '../../../outbox/entities/outbox.entity.js';
2
+ export declare class ExtendedOutboxEntity extends OutboxEntity {
3
+ channel: string;
4
+ }
5
+ //# sourceMappingURL=extended-outbox.entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extended-outbox.entity.d.ts","sourceRoot":"","sources":["../../../../src/test/example/entities/extended-outbox.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AAEzE,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,OAAO,EAAE,MAAM,CAAa;CAC7B"}
@@ -0,0 +1,5 @@
1
+ import { OutboxEntity } from '../../../outbox/entities/outbox.entity.js';
2
+ export class ExtendedOutboxEntity extends OutboxEntity {
3
+ channel = 'default';
4
+ }
5
+ //# sourceMappingURL=extended-outbox.entity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extended-outbox.entity.js","sourceRoot":"","sources":["../../../../src/test/example/entities/extended-outbox.entity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAC;AAEzE,MAAM,OAAO,oBAAqB,SAAQ,YAAY;IACpD,OAAO,GAAW,SAAS,CAAC;CAC7B"}
@@ -0,0 +1,5 @@
1
+ import { OutboxModel } from '../../../outbox/models/outbox.model.js';
2
+ export declare class ExtendedOutboxModel extends OutboxModel {
3
+ channel: string;
4
+ }
5
+ //# sourceMappingURL=extended-outbox.model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extended-outbox.model.d.ts","sourceRoot":"","sources":["../../../../src/test/example/models/extended-outbox.model.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAErE,qBACa,mBAAoB,SAAQ,WAAW;IAElD,OAAO,EAAE,MAAM,CAAa;CAC7B"}
@@ -0,0 +1,23 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ 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;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Column, Entity } from 'typeorm';
11
+ import { OutboxModel } from '../../../outbox/models/outbox.model.js';
12
+ let ExtendedOutboxModel = class ExtendedOutboxModel extends OutboxModel {
13
+ channel = 'default';
14
+ };
15
+ __decorate([
16
+ Column({ type: 'varchar', length: 50, default: 'default' }),
17
+ __metadata("design:type", String)
18
+ ], ExtendedOutboxModel.prototype, "channel", void 0);
19
+ ExtendedOutboxModel = __decorate([
20
+ Entity('outbox_extended')
21
+ ], ExtendedOutboxModel);
22
+ export { ExtendedOutboxModel };
23
+ //# sourceMappingURL=extended-outbox.model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extended-outbox.model.js","sourceRoot":"","sources":["../../../../src/test/example/models/extended-outbox.model.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAC;AAG9D,IAAM,mBAAmB,GAAzB,MAAM,mBAAoB,SAAQ,WAAW;IAElD,OAAO,GAAW,SAAS,CAAC;CAC7B,CAAA;AADC;IADC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;;oDAChC;AAFjB,mBAAmB;IAD/B,MAAM,CAAC,iBAAiB,CAAC;GACb,mBAAmB,CAG/B"}
@@ -0,0 +1,3 @@
1
+ declare const _default: () => Promise<void>;
2
+ export default _default;
3
+ //# sourceMappingURL=global-setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-setup.d.ts","sourceRoot":"","sources":["../../src/test/global-setup.ts"],"names":[],"mappings":";AAIA,wBA0BE"}
@@ -0,0 +1,29 @@
1
+ import { PostgresProvider } from '@volontariapp/bridge';
2
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
3
+ export default async () => {
4
+ const provider = new PostgresProvider({
5
+ host: process.env.TEST_DB_HOST ?? 'localhost',
6
+ port: Number(process.env.TEST_DB_PORT ?? 5433),
7
+ username: process.env.TEST_DB_USER ?? 'testuser',
8
+ password: process.env.TEST_DB_PASSWORD ?? 'testpassword',
9
+ database: process.env.TEST_DB_NAME ?? 'volontariapp_test',
10
+ });
11
+ const maxAttempts = 20;
12
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
13
+ try {
14
+ await provider.connect();
15
+ const dataSource = provider.getDriver();
16
+ await dataSource.query('SELECT 1');
17
+ await provider.disconnect();
18
+ return;
19
+ }
20
+ catch {
21
+ await provider.disconnect().catch(() => undefined);
22
+ if (attempt === maxAttempts) {
23
+ throw new Error('Test database is not reachable. Start it before running tests.');
24
+ }
25
+ await sleep(500);
26
+ }
27
+ }
28
+ };
29
+ //# sourceMappingURL=global-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"global-setup.js","sourceRoot":"","sources":["../../src/test/global-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAEhF,eAAe,KAAK,IAAI,EAAE;IACxB,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CAAC;QACpC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,WAAW;QAC7C,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC;QAC9C,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,UAAU;QAChD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,cAAc;QACxD,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,mBAAmB;KAC1D,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,EAAE,CAAC;IAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,QAAQ,CAAC,OAAO,EAAE,CAAC;YACzB,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;YACxC,MAAM,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACnC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;YAC5B,OAAO;QACT,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YACnD,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;YACpF,CAAC;YACD,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outbox.model.unit.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.model.unit.spec.d.ts","sourceRoot":"","sources":["../../../src/test/outbox/outbox.model.unit.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ import { describe, expect, it } from '@jest/globals';
2
+ import { OutboxModel } from '../../outbox/models/outbox.model.js';
3
+ import { OutboxStatus } from '../../outbox/types/outbox.status.js';
4
+ describe('OutboxModel (Unit)', () => {
5
+ it('should initialize default attributes when instantiated', () => {
6
+ const model = new OutboxModel();
7
+ expect(model.status).toBe(OutboxStatus.PENDING);
8
+ expect(model.attempts).toBe(0);
9
+ expect(model.createdAt).toBeInstanceOf(Date);
10
+ expect(model.lastError).toBeUndefined();
11
+ });
12
+ it('should allow overriding defaults with explicit values', () => {
13
+ const createdAt = new Date('2026-01-01T00:00:00.000Z');
14
+ const model = Object.assign(new OutboxModel(), {
15
+ status: OutboxStatus.FAILED,
16
+ attempts: 3,
17
+ lastError: 'processing failed',
18
+ type: 'user.updated',
19
+ emitter: 'database-tests',
20
+ createdAt,
21
+ });
22
+ expect(model.status).toBe(OutboxStatus.FAILED);
23
+ expect(model.attempts).toBe(3);
24
+ expect(model.lastError).toBe('processing failed');
25
+ expect(model.createdAt).toBe(createdAt);
26
+ });
27
+ });
28
+ //# sourceMappingURL=outbox.model.unit.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.model.unit.spec.js","sourceRoot":"","sources":["../../../src/test/outbox/outbox.model.unit.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAEnE,QAAQ,CAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QAChE,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC;QAEhC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,0BAA0B,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,WAAW,EAAE,EAAE;YAC7C,MAAM,EAAE,YAAY,CAAC,MAAM;YAC3B,QAAQ,EAAE,CAAC;YACX,SAAS,EAAE,mBAAmB;YAC9B,IAAI,EAAE,cAAc;YACpB,OAAO,EAAE,gBAAgB;YACzB,SAAS;SACV,CAAC,CAAC;QAEH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAClD,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outbox.writer.unit.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.writer.unit.spec.d.ts","sourceRoot":"","sources":["../../../src/test/outbox/outbox.writer.unit.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,116 @@
1
+ import { describe, expect, it, beforeEach } from '@jest/globals';
2
+ import { OutboxWriter } from '../../outbox/writer/outbox.writer.js';
3
+ import { makeOutboxEvent } from '../utils/outbox-event.helper.js';
4
+ import { makeLoggerMock } from '../utils/logger-mock.helper.js';
5
+ import { makeExtendedOutboxEvent } from '../utils/extended-outbox-event.helper.js';
6
+ import { makeOutboxWriterRepositoryMock, } from '../utils/outbox-writer-mock.helper.js';
7
+ describe('OutboxWriter (Unit)', () => {
8
+ let writer;
9
+ let repository;
10
+ let logger;
11
+ beforeEach(() => {
12
+ repository = makeOutboxWriterRepositoryMock();
13
+ logger = makeLoggerMock();
14
+ writer = new OutboxWriter(logger, repository);
15
+ });
16
+ it('create() should delegate valid outbox events to the repository', async () => {
17
+ const event = makeOutboxEvent({ createdAt: new Date(Date.now() - 60_000) });
18
+ await writer.create(event);
19
+ expect(repository.create).toHaveBeenCalledWith(event);
20
+ });
21
+ it('create() should reject future createdAt values', async () => {
22
+ const event = makeOutboxEvent({ createdAt: new Date(Date.now() + 60_000) });
23
+ try {
24
+ await writer.create(event);
25
+ throw new Error('Expected create() to throw');
26
+ }
27
+ catch (error) {
28
+ expect(error.name).toBe('UnprocessableEntityError');
29
+ expect(error.message).toBe('Outbox createdAt cannot be in the future');
30
+ }
31
+ expect(repository.create).not.toHaveBeenCalled();
32
+ });
33
+ it('createMany() should reject the whole batch when one createdAt is in the future', async () => {
34
+ const events = [
35
+ makeOutboxEvent({ type: 'user.created', createdAt: new Date(Date.now() - 60_000) }),
36
+ makeOutboxEvent({ type: 'user.updated', createdAt: new Date(Date.now() + 60_000) }),
37
+ ];
38
+ await expect(writer.createMany(events)).rejects.toThrow('Outbox createdAt cannot be in the future');
39
+ expect(repository.createMany).not.toHaveBeenCalled();
40
+ expect(logger.warn).toHaveBeenCalled();
41
+ });
42
+ it('createMany() should delegate valid events to the repository', async () => {
43
+ const events = [
44
+ makeOutboxEvent({ type: 'user.created', createdAt: new Date(Date.now() - 60_000) }),
45
+ makeOutboxEvent({ type: 'user.updated', createdAt: new Date(Date.now() - 30_000) }),
46
+ ];
47
+ await writer.createMany(events);
48
+ expect(repository.createMany).toHaveBeenCalledWith(events);
49
+ });
50
+ it('update() should delegate to the repository', async () => {
51
+ const event = makeOutboxEvent({ id: 'event-id-1' });
52
+ await writer.update(event);
53
+ expect(repository.update).toHaveBeenCalledWith(event.id, event);
54
+ });
55
+ it('delete() should delegate to the repository', async () => {
56
+ await writer.delete('event-id-2');
57
+ expect(repository.delete).toHaveBeenCalledWith('event-id-2');
58
+ });
59
+ it('create() should log and rethrow repository errors', async () => {
60
+ const event = makeOutboxEvent({ createdAt: new Date(Date.now() - 60_000) });
61
+ const repositoryError = new Error('repository create failure');
62
+ repository.create.mockRejectedValueOnce(repositoryError);
63
+ await expect(writer.create(event)).rejects.toThrow('repository create failure');
64
+ expect(logger.error).toHaveBeenCalledWith('Failed to create outbox event', repositoryError);
65
+ });
66
+ it('createMany() should log and rethrow repository errors', async () => {
67
+ const events = [makeOutboxEvent({ createdAt: new Date(Date.now() - 60_000) })];
68
+ const repositoryError = new Error('repository createMany failure');
69
+ repository.createMany.mockRejectedValueOnce(repositoryError);
70
+ await expect(writer.createMany(events)).rejects.toThrow('repository createMany failure');
71
+ expect(logger.error).toHaveBeenCalledWith('Failed to create outbox events batch', repositoryError);
72
+ });
73
+ it('update() should log and rethrow repository errors', async () => {
74
+ const event = makeOutboxEvent({ id: 'event-id-3' });
75
+ const repositoryError = new Error('repository update failure');
76
+ repository.update.mockRejectedValueOnce(repositoryError);
77
+ await expect(writer.update(event)).rejects.toThrow('repository update failure');
78
+ expect(logger.error).toHaveBeenCalledWith('Failed to update outbox event', repositoryError);
79
+ });
80
+ it('delete() should log and rethrow repository errors', async () => {
81
+ const repositoryError = new Error('repository delete failure');
82
+ repository.delete.mockRejectedValueOnce(repositoryError);
83
+ await expect(writer.delete('event-id-4')).rejects.toThrow('repository delete failure');
84
+ expect(logger.error).toHaveBeenCalledWith('Failed to delete outbox event', repositoryError);
85
+ });
86
+ });
87
+ describe('OutboxWriter with extended types (Unit)', () => {
88
+ it('should support an extended outbox model/entity pair across all writer methods', async () => {
89
+ const repository = makeOutboxWriterRepositoryMock();
90
+ const logger = makeLoggerMock();
91
+ const writer = new OutboxWriter(logger, repository);
92
+ const event = makeExtendedOutboxEvent({
93
+ id: 'extended-1',
94
+ type: 'extended.created',
95
+ emitter: 'unit-tests',
96
+ channel: 'sms',
97
+ createdAt: new Date(Date.now() - 60_000),
98
+ });
99
+ const secondEvent = makeExtendedOutboxEvent({
100
+ id: 'extended-2',
101
+ type: 'extended.updated',
102
+ emitter: 'unit-tests',
103
+ channel: 'email',
104
+ createdAt: new Date(Date.now() - 30_000),
105
+ });
106
+ await writer.create(event);
107
+ await writer.createMany([event, secondEvent]);
108
+ await writer.update(makeExtendedOutboxEvent({ ...event, channel: 'push' }));
109
+ await writer.delete(event.id);
110
+ expect(repository.create).toHaveBeenCalledWith(event);
111
+ expect(repository.createMany).toHaveBeenCalledWith([event, secondEvent]);
112
+ expect(repository.update).toHaveBeenCalled();
113
+ expect(repository.delete).toHaveBeenCalledWith(event.id);
114
+ });
115
+ });
116
+ //# sourceMappingURL=outbox.writer.unit.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.writer.unit.spec.js","sourceRoot":"","sources":["../../../src/test/outbox/outbox.writer.unit.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AAIpE,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAuB,MAAM,gCAAgC,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,0CAA0C,CAAC;AAGnF,OAAO,EAAE,8BAA8B,GAA+B,MAAM,uCAAuC,CAAC;AAGpH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,IAAI,MAA+C,CAAC;IACpD,IAAI,UAAiE,CAAC;IACtE,IAAI,MAAsB,CAAC;IAE3B,UAAU,CAAC,GAAG,EAAE;QACd,UAAU,GAAG,8BAA8B,EAA6B,CAAC;QAEzE,MAAM,GAAG,cAAc,EAAE,CAAC;QAE1B,MAAM,GAAG,IAAI,YAAY,CACvB,MAAe,EACf,UAA0E,CAC3E,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,KAAK,IAAI,EAAE;QAC9E,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QAE5E,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE3B,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;QAC9D,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QAE5E,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAE,KAAe,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAC/D,MAAM,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QACpF,CAAC;QAED,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,MAAM,GAAG;YACb,eAAe,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;YACnF,eAAe,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;SACpF,CAAC;QAEF,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;QACpG,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACrD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB,EAAE,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6DAA6D,EAAE,KAAK,IAAI,EAAE;QAC3E,MAAM,MAAM,GAAG;YACb,eAAe,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;YACnF,eAAe,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;SACpF,CAAC;QAEF,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAEhC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;QAEpD,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE3B,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAElC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,YAAY,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC;QAC5E,MAAM,eAAe,GAAG,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/D,UAAU,CAAC,MAAM,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;QAEzD,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QAChF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAAC,+BAA+B,EAAE,eAAe,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,KAAK,IAAI,EAAE;QACrE,MAAM,MAAM,GAAG,CAAC,eAAe,CAAC,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/E,MAAM,eAAe,GAAG,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnE,UAAU,CAAC,UAAU,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;QAE7D,MAAM,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;QACzF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAAC,sCAAsC,EAAE,eAAe,CAAC,CAAC;IACrG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,KAAK,GAAG,eAAe,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;QACpD,MAAM,eAAe,GAAG,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/D,UAAU,CAAC,MAAM,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;QAEzD,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QAChF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAAC,+BAA+B,EAAE,eAAe,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;QACjE,MAAM,eAAe,GAAG,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/D,UAAU,CAAC,MAAM,CAAC,qBAAqB,CAAC,eAAe,CAAC,CAAC;QAEzD,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QACvF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,oBAAoB,CAAC,+BAA+B,EAAE,eAAe,CAAC,CAAC;IAC9F,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yCAAyC,EAAE,GAAG,EAAE;IACvD,EAAE,CAAC,+EAA+E,EAAE,KAAK,IAAI,EAAE;QAC7F,MAAM,UAAU,GAAG,8BAA8B,EAA6C,CAAC;QAC/F,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,YAAY,CAC7B,MAAe,EACf,UAA0F,CAC3F,CAAC;QACF,MAAM,KAAK,GAAG,uBAAuB,CAAC;YACpC,EAAE,EAAE,YAAY;YAChB,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,YAAY;YACrB,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;SACzC,CAAC,CAAC;QACH,MAAM,WAAW,GAAG,uBAAuB,CAAC;YAC1C,EAAE,EAAE,YAAY;YAChB,IAAI,EAAE,kBAAkB;YACxB,OAAO,EAAE,YAAY;YACrB,OAAO,EAAE,OAAO;YAChB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;SACzC,CAAC,CAAC;QAEH,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;QAC9C,MAAM,MAAM,CAAC,MAAM,CAAC,uBAAuB,CAAC,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5E,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAE9B,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACtD,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,oBAAoB,CAAC,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;QACzE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,gBAAgB,EAAE,CAAC;QAC7C,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { ExtendedOutboxEntity } from '../example/entities/extended-outbox.entity.js';
2
+ export declare const makeExtendedOutboxEvent: (overrides?: Partial<ExtendedOutboxEntity>) => ExtendedOutboxEntity;
3
+ //# sourceMappingURL=extended-outbox-event.helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extended-outbox-event.helper.d.ts","sourceRoot":"","sources":["../../../src/test/utils/extended-outbox-event.helper.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AAErF,eAAO,MAAM,uBAAuB,eACvB,OAAO,CAAC,oBAAoB,CAAC,KACvC,oBAWF,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { OutboxStatus } from '../../outbox/types/outbox.status.js';
2
+ import { ExtendedOutboxEntity } from '../example/entities/extended-outbox.entity.js';
3
+ export const makeExtendedOutboxEvent = (overrides = {}) => {
4
+ return Object.assign(new ExtendedOutboxEntity(), {
5
+ type: 'extended.created',
6
+ emitter: 'database-tests',
7
+ status: OutboxStatus.PENDING,
8
+ attempts: 0,
9
+ createdAt: new Date(Date.now() - 60_000),
10
+ updatedAt: new Date(),
11
+ channel: 'default',
12
+ ...overrides,
13
+ });
14
+ };
15
+ //# sourceMappingURL=extended-outbox-event.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extended-outbox-event.helper.js","sourceRoot":"","sources":["../../../src/test/utils/extended-outbox-event.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AAErF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CACrC,YAA2C,EAAE,EACvB,EAAE;IACxB,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,oBAAoB,EAAE,EAAE;QAC/C,IAAI,EAAE,kBAAkB;QACxB,OAAO,EAAE,gBAAgB;QACzB,MAAM,EAAE,YAAY,CAAC,OAAO;QAC5B,QAAQ,EAAE,CAAC;QACX,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;QACxC,SAAS,EAAE,IAAI,IAAI,EAAE;QACrB,OAAO,EAAE,SAAS;QAClB,GAAG,SAAS;KACb,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { jest } from '@jest/globals';
2
+ type LoggerLike = {
3
+ info: (...args: unknown[]) => void;
4
+ warn: (...args: unknown[]) => void;
5
+ error: (...args: unknown[]) => void;
6
+ };
7
+ export type TestLoggerMock = LoggerLike & jest.Mocked<Pick<LoggerLike, 'info' | 'warn' | 'error'>>;
8
+ export declare const makeLoggerMock: () => TestLoggerMock;
9
+ export {};
10
+ //# sourceMappingURL=logger-mock.helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-mock.helper.d.ts","sourceRoot":"","sources":["../../../src/test/utils/logger-mock.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,IAAI,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;IACnC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC;AAEnG,eAAO,MAAM,cAAc,QAAO,cAMjC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { jest } from '@jest/globals';
2
+ export const makeLoggerMock = () => {
3
+ return {
4
+ info: jest.fn(),
5
+ warn: jest.fn(),
6
+ error: jest.fn(),
7
+ };
8
+ };
9
+ //# sourceMappingURL=logger-mock.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-mock.helper.js","sourceRoot":"","sources":["../../../src/test/utils/logger-mock.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAUrC,MAAM,CAAC,MAAM,cAAc,GAAG,GAAmB,EAAE;IACjD,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;QACf,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE;QACf,KAAK,EAAE,IAAI,CAAC,EAAE,EAAE;KACY,CAAC;AACjC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { OutboxModel } from "../../outbox/models/outbox.model.js";
2
+ export declare const makeOutboxEvent: (overrides?: Partial<OutboxModel>) => OutboxModel;
3
+ //# sourceMappingURL=outbox-event.helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-event.helper.d.ts","sourceRoot":"","sources":["../../../src/test/utils/outbox-event.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAElE,eAAO,MAAM,eAAe,eAAe,OAAO,CAAC,WAAW,CAAC,KAAQ,WAMtE,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { OutboxModel } from "../../outbox/models/outbox.model.js";
2
+ export const makeOutboxEvent = (overrides = {}) => {
3
+ const event = new OutboxModel();
4
+ event.type = 'user.created';
5
+ event.emitter = 'database-tests';
6
+ event.updatedAt = new Date();
7
+ return Object.assign(event, overrides);
8
+ };
9
+ //# sourceMappingURL=outbox-event.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-event.helper.js","sourceRoot":"","sources":["../../../src/test/utils/outbox-event.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAElE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,YAAkC,EAAE,EAAe,EAAE;IACnF,MAAM,KAAK,GAAG,IAAI,WAAW,EAAE,CAAC;IAChC,KAAK,CAAC,IAAI,GAAG,cAAc,CAAC;IAC5B,KAAK,CAAC,OAAO,GAAG,gBAAgB,CAAC;IACjC,KAAK,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;IAC7B,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AACzC,CAAC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { Repository } from 'typeorm';
2
+ import { OutboxWriter } from '../../outbox/writer/outbox.writer.js';
3
+ import { ExtendedOutboxEntity } from '../example/entities/extended-outbox.entity.js';
4
+ import { ExtendedOutboxModel } from '../example/models/extended-outbox.model.js';
5
+ export declare class TestExtendedOutboxWriter extends OutboxWriter<ExtendedOutboxModel, ExtendedOutboxEntity> {
6
+ constructor(logger: unknown, repository: Repository<ExtendedOutboxModel>);
7
+ }
8
+ //# sourceMappingURL=outbox-extended-test.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-extended-test.repository.d.ts","sourceRoot":"","sources":["../../../src/test/utils/outbox-extended-test.repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAYjF,qBAAa,wBAAyB,SAAQ,YAAY,CACxD,mBAAmB,EACnB,oBAAoB,CACrB;gBACa,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC,mBAAmB,CAAC;CAGzE"}
@@ -0,0 +1,15 @@
1
+ import { BaseRepository } from '../../core/base.repository.js';
2
+ import { OutboxWriter } from '../../outbox/writer/outbox.writer.js';
3
+ import { ExtendedOutboxEntity } from '../example/entities/extended-outbox.entity.js';
4
+ import { ExtendedOutboxModel } from '../example/models/extended-outbox.model.js';
5
+ class ExtendedOutboxTestRepository extends BaseRepository {
6
+ constructor(repository) {
7
+ super(repository, ExtendedOutboxEntity, ExtendedOutboxModel);
8
+ }
9
+ }
10
+ export class TestExtendedOutboxWriter extends OutboxWriter {
11
+ constructor(logger, repository) {
12
+ super(logger, new ExtendedOutboxTestRepository(repository));
13
+ }
14
+ }
15
+ //# sourceMappingURL=outbox-extended-test.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-extended-test.repository.js","sourceRoot":"","sources":["../../../src/test/utils/outbox-extended-test.repository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EAAE,mBAAmB,EAAE,MAAM,4CAA4C,CAAC;AAEjF,MAAM,4BAA6B,SAAQ,cAI1C;IACC,YAAY,UAA2C;QACrD,KAAK,CAAC,UAAU,EAAE,oBAAoB,EAAE,mBAAmB,CAAC,CAAC;IAC/D,CAAC;CACF;AAED,MAAM,OAAO,wBAAyB,SAAQ,YAG7C;IACC,YAAY,MAAe,EAAE,UAA2C;QACtE,KAAK,CAAC,MAAe,EAAE,IAAI,4BAA4B,CAAC,UAAU,CAAC,CAAC,CAAC;IACvE,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ import { Repository } from "typeorm";
2
+ import { OutboxEntity } from "../../outbox/entities/outbox.entity.js";
3
+ import { OutboxModel } from "../../outbox/models/outbox.model.js";
4
+ import { BaseRepository } from "../../core/base.repository.js";
5
+ export declare class TestOutboxWriterRepository extends BaseRepository<OutboxModel, OutboxEntity, string> {
6
+ constructor(repository: Repository<OutboxModel>);
7
+ }
8
+ //# sourceMappingURL=outbox-test.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-test.repository.d.ts","sourceRoot":"","sources":["../../../src/test/utils/outbox-test.repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,qBAAa,0BAA2B,SAAQ,cAAc,CAAC,WAAW,EAAE,YAAY,EAAE,MAAM,CAAC;gBACnF,UAAU,EAAE,UAAU,CAAC,WAAW,CAAC;CAGhD"}
@@ -0,0 +1,9 @@
1
+ import { OutboxEntity } from "../../outbox/entities/outbox.entity.js";
2
+ import { OutboxModel } from "../../outbox/models/outbox.model.js";
3
+ import { BaseRepository } from "../../core/base.repository.js";
4
+ export class TestOutboxWriterRepository extends BaseRepository {
5
+ constructor(repository) {
6
+ super(repository, OutboxEntity, OutboxModel);
7
+ }
8
+ }
9
+ //# sourceMappingURL=outbox-test.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-test.repository.js","sourceRoot":"","sources":["../../../src/test/utils/outbox-test.repository.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,MAAM,OAAO,0BAA2B,SAAQ,cAAiD;IAC/F,YAAY,UAAmC;QAC7C,KAAK,CAAC,UAAU,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;IAC/C,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import { jest } from '@jest/globals';
2
+ import { BaseRepository } from '../../core/base.repository.js';
3
+ import { OutboxEntity } from "../../outbox/entities/outbox.entity.js";
4
+ import { OutboxModel } from "../../outbox/models/outbox.model.js";
5
+ export type OutboxWriterRepositoryMock<TModel extends OutboxModel, TEntity extends OutboxEntity> = jest.Mocked<Pick<BaseRepository<TModel, TEntity, string>, 'create' | 'createMany' | 'update' | 'delete'>>;
6
+ export declare const makeOutboxWriterRepositoryMock: <TModel extends OutboxModel, TEntity extends OutboxEntity>() => OutboxWriterRepositoryMock<TModel, TEntity>;
7
+ //# sourceMappingURL=outbox-writer-mock.helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-writer-mock.helper.d.ts","sourceRoot":"","sources":["../../../src/test/utils/outbox-writer-mock.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAElE,MAAM,MAAM,0BAA0B,CAAC,MAAM,SAAS,WAAW,EAAE,OAAO,SAAS,YAAY,IAAI,IAAI,CAAC,MAAM,CAC5G,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAC,CAC7F,CAAC;AAEF,eAAO,MAAM,8BAA8B,GACzC,MAAM,SAAS,WAAW,EAC1B,OAAO,SAAS,YAAY,OACzB,0BAA0B,CAAC,MAAM,EAAE,OAAO,CAO9C,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { jest } from '@jest/globals';
2
+ export const makeOutboxWriterRepositoryMock = () => {
3
+ return {
4
+ create: jest.fn(async () => ({})),
5
+ createMany: jest.fn(async () => []),
6
+ update: jest.fn(async () => ({})),
7
+ delete: jest.fn(async () => true),
8
+ };
9
+ };
10
+ //# sourceMappingURL=outbox-writer-mock.helper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox-writer-mock.helper.js","sourceRoot":"","sources":["../../../src/test/utils/outbox-writer-mock.helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AASrC,MAAM,CAAC,MAAM,8BAA8B,GAAG,GAGG,EAAE;IACjD,OAAO;QACL,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAc,CAAA,CAAC;QAC5C,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,EAAe,CAAC;QAChD,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,EAAc,CAAA,CAAC;QAC5C,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC;KACwB,CAAC;AAC9D,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@volontariapp/database",
3
- "version": "1.5.1-snapshot.7832680e7383",
3
+ "version": "1.6.0-snap-e5122cd",
4
4
  "publishConfig": {
5
5
  "access": "public",
6
6
  "provenance": true
@@ -36,7 +36,9 @@
36
36
  "db:down": "docker-compose -f ../../docker-compose.test.yml down"
37
37
  },
38
38
  "dependencies": {
39
- "@volontariapp/logger": "0.2.3-snapshot.299d42afa699",
39
+ "@volontariapp/bridge": "0.2.8",
40
+ "@volontariapp/errors": "0.4.4",
41
+ "@volontariapp/logger": "0.2.3",
40
42
  "class-transformer": "^0.5.1",
41
43
  "class-validator": "^0.14.1",
42
44
  "pg": "^8.20.0",