@woltz/rich-domain 0.2.2 → 1.1.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 (148) hide show
  1. package/CHANGELOG.md +23 -75
  2. package/LICENSE +20 -20
  3. package/README.md +37 -20
  4. package/dist/base-entity.d.ts +2 -2
  5. package/dist/base-entity.d.ts.map +1 -1
  6. package/dist/base-entity.js +6 -4
  7. package/dist/base-entity.js.map +1 -1
  8. package/dist/criteria.d.ts +5 -11
  9. package/dist/criteria.d.ts.map +1 -1
  10. package/dist/criteria.js +4 -3
  11. package/dist/criteria.js.map +1 -1
  12. package/dist/deep-proxy.d.ts +3 -1
  13. package/dist/deep-proxy.d.ts.map +1 -1
  14. package/dist/deep-proxy.js +116 -29
  15. package/dist/deep-proxy.js.map +1 -1
  16. package/dist/domain-event-bus.d.ts +5 -6
  17. package/dist/domain-event-bus.d.ts.map +1 -1
  18. package/dist/domain-event-bus.js +3 -11
  19. package/dist/domain-event-bus.js.map +1 -1
  20. package/dist/domain-event.d.ts +1 -31
  21. package/dist/domain-event.d.ts.map +1 -1
  22. package/dist/domain-event.js +2 -1
  23. package/dist/domain-event.js.map +1 -1
  24. package/dist/entity.d.ts +2 -2
  25. package/dist/entity.js +1 -1
  26. package/dist/exceptions.d.ts +251 -0
  27. package/dist/exceptions.d.ts.map +1 -0
  28. package/dist/exceptions.js +321 -0
  29. package/dist/exceptions.js.map +1 -0
  30. package/dist/id.d.ts +3 -3
  31. package/dist/id.d.ts.map +1 -1
  32. package/dist/id.js +15 -4
  33. package/dist/id.js.map +1 -1
  34. package/dist/index.d.ts +2 -5
  35. package/dist/index.d.ts.map +1 -1
  36. package/dist/index.js +2 -8
  37. package/dist/index.js.map +1 -1
  38. package/dist/paginated-result.d.ts.map +1 -1
  39. package/dist/paginated-result.js +12 -1
  40. package/dist/paginated-result.js.map +1 -1
  41. package/dist/repository/index.d.ts +2 -39
  42. package/dist/repository/index.d.ts.map +1 -1
  43. package/dist/repository/index.js +2 -39
  44. package/dist/repository/index.js.map +1 -1
  45. package/dist/repository/unit-of-work.d.ts +0 -11
  46. package/dist/repository/unit-of-work.d.ts.map +1 -1
  47. package/dist/repository/unit-of-work.js +0 -35
  48. package/dist/repository/unit-of-work.js.map +1 -1
  49. package/dist/types/criteria.d.ts +6 -2
  50. package/dist/types/criteria.d.ts.map +1 -1
  51. package/dist/types/criteria.js +1 -1
  52. package/dist/types/criteria.js.map +1 -1
  53. package/dist/types/domain-event.d.ts +32 -0
  54. package/dist/types/domain-event.d.ts.map +1 -0
  55. package/dist/types/domain-event.js +2 -0
  56. package/dist/types/domain-event.js.map +1 -0
  57. package/dist/types/domain.d.ts +2 -2
  58. package/dist/types/domain.d.ts.map +1 -1
  59. package/dist/types/history-tracker.d.ts +1 -1
  60. package/dist/types/history-tracker.d.ts.map +1 -1
  61. package/dist/types/index.d.ts +1 -0
  62. package/dist/types/index.d.ts.map +1 -1
  63. package/dist/types/index.js +1 -0
  64. package/dist/types/index.js.map +1 -1
  65. package/dist/value-object.d.ts +1 -1
  66. package/dist/value-object.d.ts.map +1 -1
  67. package/dist/value-object.js +2 -5
  68. package/dist/value-object.js.map +1 -1
  69. package/eslint.config.js +3 -3
  70. package/jest.config.js +1 -1
  71. package/package.json +14 -20
  72. package/src/base-entity.ts +6 -5
  73. package/src/criteria.ts +11 -11
  74. package/src/deep-proxy.ts +447 -339
  75. package/src/domain-event-bus.ts +152 -166
  76. package/src/domain-event.ts +53 -90
  77. package/src/entity.ts +16 -16
  78. package/src/exceptions.ts +435 -0
  79. package/src/id.ts +107 -94
  80. package/src/index.ts +26 -9
  81. package/src/paginated-result.ts +14 -1
  82. package/src/repository/index.ts +2 -44
  83. package/src/repository/unit-of-work.ts +1 -44
  84. package/src/types/criteria.ts +7 -2
  85. package/src/types/domain-event.ts +38 -0
  86. package/src/types/domain.ts +2 -3
  87. package/src/types/history-tracker.ts +1 -1
  88. package/src/types/index.ts +1 -0
  89. package/src/validation-error.ts +97 -97
  90. package/src/value-object.ts +3 -6
  91. package/tests/criteria.test.ts +8 -0
  92. package/tests/domain-events.test.ts +431 -445
  93. package/tests/entity-validation.test.ts +2 -2
  94. package/tests/entity.test.ts +33 -33
  95. package/tests/history-tracker.spec.ts +57 -17
  96. package/tests/id.test.ts +341 -341
  97. package/tests/repository.test.ts +8 -4
  98. package/tests/to-json.test.ts +103 -91
  99. package/tests/utils.ts +254 -151
  100. package/tests/value-object-validation.test.ts +0 -9
  101. package/tests/value-objects.test.ts +52 -52
  102. package/tsconfig.json +2 -24
  103. package/.github/workflows/ci.yml +0 -40
  104. package/.husky/commit-msg +0 -1
  105. package/.husky/pre-commit +0 -1
  106. package/.vscode/settings.json +0 -3
  107. package/commitlint.config.js +0 -23
  108. package/dist/filtering.d.ts +0 -107
  109. package/dist/filtering.d.ts.map +0 -1
  110. package/dist/filtering.js +0 -202
  111. package/dist/filtering.js.map +0 -1
  112. package/dist/ordering.d.ts +0 -93
  113. package/dist/ordering.d.ts.map +0 -1
  114. package/dist/ordering.js +0 -154
  115. package/dist/ordering.js.map +0 -1
  116. package/dist/pagination.d.ts +0 -218
  117. package/dist/pagination.d.ts.map +0 -1
  118. package/dist/pagination.js +0 -281
  119. package/dist/pagination.js.map +0 -1
  120. package/dist/repository/in-memory-repository.d.ts +0 -50
  121. package/dist/repository/in-memory-repository.d.ts.map +0 -1
  122. package/dist/repository/in-memory-repository.js +0 -93
  123. package/dist/repository/in-memory-repository.js.map +0 -1
  124. package/dist/repository/mapper.d.ts +0 -56
  125. package/dist/repository/mapper.d.ts.map +0 -1
  126. package/dist/repository/mapper.js +0 -15
  127. package/dist/repository/mapper.js.map +0 -1
  128. package/dist/repository/types.d.ts +0 -87
  129. package/dist/repository/types.d.ts.map +0 -1
  130. package/dist/repository/types.js +0 -6
  131. package/dist/repository/types.js.map +0 -1
  132. package/dist/repository.d.ts +0 -2
  133. package/dist/repository.d.ts.map +0 -1
  134. package/dist/repository.js +0 -21
  135. package/dist/repository.js.map +0 -1
  136. package/dist/specification.d.ts +0 -102
  137. package/dist/specification.d.ts.map +0 -1
  138. package/dist/specification.js +0 -187
  139. package/dist/specification.js.map +0 -1
  140. package/dist/types/repository.d.ts +0 -43
  141. package/dist/types/repository.d.ts.map +0 -1
  142. package/dist/types/repository.js +0 -2
  143. package/dist/types/repository.js.map +0 -1
  144. package/dist/types.d.ts +0 -88
  145. package/dist/types.d.ts.map +0 -1
  146. package/dist/types.js +0 -12
  147. package/dist/types.js.map +0 -1
  148. package/src/repository/in-memory-repository.ts +0 -116
@@ -1,50 +0,0 @@
1
- import type { Aggregate } from "../entity";
2
- import type { Criteria } from "../criteria";
3
- import { PaginatedResult } from "../paginated-result";
4
- import { Repository } from "./base-repository";
5
- import { Mapper } from "../mapper";
6
- /**
7
- * In-memory repository implementation
8
- * Perfect for unit tests and prototyping
9
- *
10
- * @example
11
- * ```ts
12
- * const userRepo = new InMemoryRepository<User>();
13
- *
14
- * await userRepo.save(user);
15
- * const found = await userRepo.findById(user.id);
16
- * const active = await userRepo.find(
17
- * Criteria.create<User>().whereEquals('status', 'active')
18
- * );
19
- * ```
20
- */
21
- export declare class InMemoryRepository<TDomain extends Aggregate<any>> extends Repository<TDomain> {
22
- protected readonly mapperToDomain: Mapper<unknown, TDomain>;
23
- protected readonly mapperToPersistence: Mapper<TDomain, unknown>;
24
- protected items: Map<string, TDomain>;
25
- constructor(mapperToDomain: Mapper<unknown, TDomain>, mapperToPersistence: Mapper<TDomain, unknown>);
26
- get model(): any;
27
- findById(id: string): Promise<TDomain | null>;
28
- find(criteria: Criteria<TDomain>): Promise<PaginatedResult<TDomain>>;
29
- findAll(criteria?: Criteria<TDomain>): Promise<TDomain[]>;
30
- findOne(criteria: Criteria<TDomain>): Promise<TDomain | null>;
31
- create(aggregate: TDomain): Promise<void>;
32
- update(entity: TDomain): Promise<void>;
33
- createMany(aggregates: TDomain[]): Promise<void>;
34
- delete(aggregate: TDomain): Promise<void>;
35
- exists(id: string): Promise<boolean>;
36
- count(criteria?: Criteria<TDomain>): Promise<number>;
37
- /**
38
- * Clear all items (useful for test cleanup)
39
- */
40
- clear(): void;
41
- /**
42
- * Get all items as array (useful for debugging)
43
- */
44
- getAll(): TDomain[];
45
- /**
46
- * Get items count
47
- */
48
- size(): number;
49
- }
50
- //# sourceMappingURL=in-memory-repository.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"in-memory-repository.d.ts","sourceRoot":"","sources":["../../src/repository/in-memory-repository.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC;;;;;;;;;;;;;;GAcG;AACH,qBAAa,kBAAkB,CAC7B,OAAO,SAAS,SAAS,CAAC,GAAG,CAAC,CAC9B,SAAQ,UAAU,CAAC,OAAO,CAAC;IAIzB,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;IAC3D,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;IAJlE,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAa;gBAG7B,cAAc,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,EACxC,mBAAmB,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC;IAKlE,IAAI,KAAK,IAAI,GAAG,CAGf;IAEK,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAI7C,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAKpE,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IASzD,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAK7D,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAItC,UAAU,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIpC,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAQ1D;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,MAAM,IAAI,OAAO,EAAE;IAInB;;OAEG;IACH,IAAI,IAAI,MAAM;CAGf"}
@@ -1,93 +0,0 @@
1
- // ============================================================================
2
- // In-Memory Repository - Perfect for testing
3
- // ============================================================================
4
- import { PaginatedResult } from "../paginated-result";
5
- import { Repository } from "./base-repository";
6
- /**
7
- * In-memory repository implementation
8
- * Perfect for unit tests and prototyping
9
- *
10
- * @example
11
- * ```ts
12
- * const userRepo = new InMemoryRepository<User>();
13
- *
14
- * await userRepo.save(user);
15
- * const found = await userRepo.findById(user.id);
16
- * const active = await userRepo.find(
17
- * Criteria.create<User>().whereEquals('status', 'active')
18
- * );
19
- * ```
20
- */
21
- export class InMemoryRepository extends Repository {
22
- constructor(mapperToDomain, mapperToPersistence) {
23
- super();
24
- this.mapperToDomain = mapperToDomain;
25
- this.mapperToPersistence = mapperToPersistence;
26
- this.items = new Map();
27
- }
28
- get model() {
29
- // your database table name
30
- return "inMemory";
31
- }
32
- async findById(id) {
33
- return this.items.get(id) || null;
34
- }
35
- async find(criteria) {
36
- const allItems = Array.from(this.items.values());
37
- return PaginatedResult.fromArray(allItems, criteria);
38
- }
39
- async findAll(criteria) {
40
- if (criteria) {
41
- const result = await this.find(criteria);
42
- return result.data;
43
- }
44
- return Array.from(this.items.values());
45
- }
46
- async findOne(criteria) {
47
- const result = await this.find(criteria.clone().limit(1));
48
- return result.data.length > 0 ? result.data[0] : null;
49
- }
50
- async create(aggregate) {
51
- this.items.set(aggregate.id.value, aggregate);
52
- }
53
- async update(entity) {
54
- this.items.set(entity.id.value, entity);
55
- }
56
- async createMany(aggregates) {
57
- for (const aggregate of aggregates) {
58
- await this.create(aggregate);
59
- }
60
- }
61
- async delete(aggregate) {
62
- this.items.delete(aggregate.id.value);
63
- }
64
- async exists(id) {
65
- return this.items.has(id);
66
- }
67
- async count(criteria) {
68
- if (criteria) {
69
- const result = await this.find(criteria);
70
- return result.meta.total;
71
- }
72
- return this.items.size;
73
- }
74
- /**
75
- * Clear all items (useful for test cleanup)
76
- */
77
- clear() {
78
- this.items.clear();
79
- }
80
- /**
81
- * Get all items as array (useful for debugging)
82
- */
83
- getAll() {
84
- return Array.from(this.items.values());
85
- }
86
- /**
87
- * Get items count
88
- */
89
- size() {
90
- return this.items.size;
91
- }
92
- }
93
- //# sourceMappingURL=in-memory-repository.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"in-memory-repository.js","sourceRoot":"","sources":["../../src/repository/in-memory-repository.ts"],"names":[],"mappings":"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"}
@@ -1,56 +0,0 @@
1
- import type { Aggregate } from "../entity";
2
- /**
3
- * Mapper interface for converting between Domain and Persistence models
4
- *
5
- * @template TDomain - Domain aggregate/entity
6
- * @template TPersistence - Database model (Prisma, TypeORM, etc.)
7
- *
8
- * @example
9
- * ```ts
10
- * class UserMapper implements IMapper<User, PrismaUser> {
11
- * toDomain(persistence: PrismaUser): User {
12
- * return new User({
13
- * id: Id.from(persistence.id),
14
- * name: persistence.name,
15
- * email: persistence.email,
16
- * });
17
- * }
18
- *
19
- * toPersistence(domain: User): PrismaUser {
20
- * return {
21
- * id: domain.id.value,
22
- * name: domain.props.name,
23
- * email: domain.props.email,
24
- * };
25
- * }
26
- * }
27
- * ```
28
- */
29
- export interface IMapper<TDomain extends Aggregate<any>, TPersistence = any> {
30
- /**
31
- * Convert from persistence model to domain aggregate
32
- */
33
- toDomain(persistence: TPersistence): TDomain;
34
- /**
35
- * Convert from domain aggregate to persistence model
36
- */
37
- toPersistence(domain: TDomain): TPersistence;
38
- /**
39
- * Convert array of persistence models to domain aggregates
40
- */
41
- toDomainList?(persistence: TPersistence[]): TDomain[];
42
- /**
43
- * Convert array of domain aggregates to persistence models
44
- */
45
- toPersistenceList?(domain: TDomain[]): TPersistence[];
46
- }
47
- /**
48
- * Base mapper with default array implementations
49
- */
50
- export declare abstract class BaseMapper<TDomain extends Aggregate<any>, TPersistence = any> implements IMapper<TDomain, TPersistence> {
51
- abstract toDomain(persistence: TPersistence): TDomain;
52
- abstract toPersistence(domain: TDomain): TPersistence;
53
- toDomainList(persistence: TPersistence[]): TDomain[];
54
- toPersistenceList(domain: TDomain[]): TPersistence[];
55
- }
56
- //# sourceMappingURL=mapper.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mapper.d.ts","sourceRoot":"","sources":["../../src/repository/mapper.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,OAAO,CAAC,OAAO,SAAS,SAAS,CAAC,GAAG,CAAC,EAAE,YAAY,GAAG,GAAG;IACzE;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,OAAO,CAAC;IAE7C;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY,CAAC;IAE7C;;OAEG;IACH,YAAY,CAAC,CAAC,WAAW,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE,CAAC;IAEtD;;OAEG;IACH,iBAAiB,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,CAAC;CACvD;AAED;;GAEG;AACH,8BAAsB,UAAU,CAC9B,OAAO,SAAS,SAAS,CAAC,GAAG,CAAC,EAC9B,YAAY,GAAG,GAAG,CAClB,YAAW,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC;IAEzC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,YAAY,GAAG,OAAO;IACrD,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,GAAG,YAAY;IAErD,YAAY,CAAC,WAAW,EAAE,YAAY,EAAE,GAAG,OAAO,EAAE;IAIpD,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE;CAGrD"}
@@ -1,15 +0,0 @@
1
- // ============================================================================
2
- // Mapper - Domain ↔ Persistence
3
- // ============================================================================
4
- /**
5
- * Base mapper with default array implementations
6
- */
7
- export class BaseMapper {
8
- toDomainList(persistence) {
9
- return persistence.map((p) => this.toDomain(p));
10
- }
11
- toPersistenceList(domain) {
12
- return domain.map((d) => this.toPersistence(d));
13
- }
14
- }
15
- //# sourceMappingURL=mapper.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mapper.js","sourceRoot":"","sources":["../../src/repository/mapper.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;AAqD/E;;GAEG;AACH,MAAM,OAAgB,UAAU;IAQ9B,YAAY,CAAC,WAA2B;QACtC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,iBAAiB,CAAC,MAAiB;QACjC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IAClD,CAAC;CACF"}
@@ -1,87 +0,0 @@
1
- import type { Id } from "../id";
2
- import type { Aggregate } from "../entity";
3
- import type { Criteria } from "../criteria";
4
- import type { PaginatedResult } from "../paginated-result";
5
- /**
6
- * Base repository interface
7
- * Keep it minimal - only what you actually need
8
- */
9
- export interface IRepository<TDomain extends Aggregate<any>> {
10
- /**
11
- * Find by ID
12
- */
13
- findById(id: Id): Promise<TDomain | null>;
14
- /**
15
- * Find using criteria (filtering, ordering, pagination)
16
- */
17
- find(criteria: Criteria<TDomain>): Promise<PaginatedResult<TDomain>>;
18
- /**
19
- * Find all (with optional criteria)
20
- */
21
- findAll(criteria?: Criteria<TDomain>): Promise<TDomain[]>;
22
- /**
23
- * Find one (first matching criteria)
24
- */
25
- findOne(criteria: Criteria<TDomain>): Promise<TDomain | null>;
26
- /**
27
- * Save (insert or update based on aggregate.isNew)
28
- */
29
- save(aggregate: TDomain): Promise<void>;
30
- /**
31
- * Save multiple aggregates
32
- */
33
- saveMany(aggregates: TDomain[]): Promise<void>;
34
- /**
35
- * Delete aggregate
36
- */
37
- delete(aggregate: TDomain): Promise<void>;
38
- /**
39
- * Delete by ID
40
- */
41
- deleteById(id: Id): Promise<void>;
42
- /**
43
- * Check if exists
44
- */
45
- exists(id: Id): Promise<boolean>;
46
- /**
47
- * Count matching criteria
48
- */
49
- count(criteria?: Criteria<TDomain>): Promise<number>;
50
- }
51
- /**
52
- * Transaction context for Unit of Work
53
- */
54
- export interface TransactionContext {
55
- /**
56
- * Commit all changes
57
- */
58
- commit(): Promise<void>;
59
- /**
60
- * Rollback all changes
61
- */
62
- rollback(): Promise<void>;
63
- /**
64
- * Check if transaction is active
65
- */
66
- isActive(): boolean;
67
- }
68
- /**
69
- * Unit of Work interface
70
- * Manages transactions across multiple repositories
71
- */
72
- export interface IUnitOfWork {
73
- /**
74
- * Start a new transaction
75
- */
76
- begin(): Promise<TransactionContext>;
77
- /**
78
- * Execute work within a transaction
79
- * Auto-commits on success, rolls back on error
80
- */
81
- transaction<T>(work: (ctx: TransactionContext) => Promise<T>): Promise<T>;
82
- /**
83
- * Get repository within transaction context
84
- */
85
- getRepository<TDomain extends Aggregate<any>>(repository: new (...args: any[]) => IRepository<TDomain>): IRepository<TDomain>;
86
- }
87
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/repository/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAG3D;;;GAGG;AACH,MAAM,WAAW,WAAW,CAAC,OAAO,SAAS,SAAS,CAAC,GAAG,CAAC;IACzD;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE1C;;OAEG;IACH,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAErE;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAE1D;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAE9D;;OAEG;IACH,IAAI,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C;;OAEG;IACH,MAAM,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElC;;OAEG;IACH,MAAM,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjC;;OAEG;IACH,KAAK,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACtD;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAExB;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1B;;OAEG;IACH,QAAQ,IAAI,OAAO,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAErC;;;OAGG;IACH,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,kBAAkB,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAE1E;;OAEG;IACH,aAAa,CAAC,OAAO,SAAS,SAAS,CAAC,GAAG,CAAC,EAC1C,UAAU,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,WAAW,CAAC,OAAO,CAAC,GACvD,WAAW,CAAC,OAAO,CAAC,CAAC;CACzB"}
@@ -1,6 +0,0 @@
1
- "use strict";
2
- // ============================================================================
3
- // Repository Types - Simple and Type-Safe
4
- // ============================================================================
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/repository/types.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,0CAA0C;AAC1C,+EAA+E"}
@@ -1,2 +0,0 @@
1
- export * from "./repository/index";
2
- //# sourceMappingURL=repository.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"AAIA,cAAc,oBAAoB,CAAC"}
@@ -1,21 +0,0 @@
1
- "use strict";
2
- // ============================================================================
3
- // Repository - Main export (backward compatibility)
4
- // ============================================================================
5
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- var desc = Object.getOwnPropertyDescriptor(m, k);
8
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
- desc = { enumerable: true, get: function() { return m[k]; } };
10
- }
11
- Object.defineProperty(o, k2, desc);
12
- }) : (function(o, m, k, k2) {
13
- if (k2 === undefined) k2 = k;
14
- o[k2] = m[k];
15
- }));
16
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
- };
19
- Object.defineProperty(exports, "__esModule", { value: true });
20
- __exportStar(require("./repository/index"), exports);
21
- //# sourceMappingURL=repository.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"repository.js","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,oDAAoD;AACpD,+EAA+E;;;;;;;;;;;;;;;;AAE/E,qDAAmC"}
@@ -1,102 +0,0 @@
1
- import type { BaseProps } from "./types";
2
- /**
3
- * Abstract base class for Specification pattern
4
- * Specifications encapsulate business rules and can be composed together
5
- *
6
- * @example
7
- * ```typescript
8
- * class AdultSpecification extends BaseSpecification<User> {
9
- * isSatisfiedBy(user: User): boolean {
10
- * return user.age >= 18;
11
- * }
12
- * }
13
- *
14
- * const spec = new AdultSpecification();
15
- * const adults = users.filter(u => spec.isSatisfiedBy(u));
16
- * ```
17
- */
18
- export declare abstract class BaseSpecification<T extends BaseProps> {
19
- /**
20
- * Checks if the given entity satisfies this specification
21
- * Must be implemented by concrete specifications
22
- */
23
- abstract isSatisfiedBy(entity: T): boolean;
24
- /**
25
- * Combines this specification with another using AND logic
26
- * Both specifications must be satisfied
27
- */
28
- and(other: BaseSpecification<T>): BaseSpecification<T>;
29
- /**
30
- * Combines this specification with another using OR logic
31
- * At least one specification must be satisfied
32
- */
33
- or(other: BaseSpecification<T>): BaseSpecification<T>;
34
- /**
35
- * Negates this specification
36
- * Returns true if this specification is NOT satisfied
37
- */
38
- not(): BaseSpecification<T>;
39
- /**
40
- * Creates a predicate function for use with Array.filter()
41
- */
42
- asPredicate(): (entity: T) => boolean;
43
- }
44
- /**
45
- * Specification that is always satisfied
46
- * Useful as a starting point for building complex specifications
47
- */
48
- export declare class TrueSpecification<T extends BaseProps> extends BaseSpecification<T> {
49
- isSatisfiedBy(_entity: T): boolean;
50
- }
51
- /**
52
- * Specification that is never satisfied
53
- * Useful for testing or as a placeholder
54
- */
55
- export declare class FalseSpecification<T extends BaseProps> extends BaseSpecification<T> {
56
- isSatisfiedBy(_entity: T): boolean;
57
- }
58
- /**
59
- * Specification based on a predicate function
60
- * Allows creating specifications from lambda expressions
61
- *
62
- * @example
63
- * ```typescript
64
- * const adultSpec = new PredicateSpecification<User>(
65
- * user => user.age >= 18
66
- * );
67
- * ```
68
- */
69
- export declare class PredicateSpecification<T extends BaseProps> extends BaseSpecification<T> {
70
- private readonly predicate;
71
- constructor(predicate: (entity: T) => boolean);
72
- isSatisfiedBy(entity: T): boolean;
73
- }
74
- /**
75
- * Specification that checks if a property equals a specific value
76
- *
77
- * @example
78
- * ```typescript
79
- * const activeSpec = new PropertyEqualsSpecification<User>('status', 'active');
80
- * ```
81
- */
82
- export declare class PropertyEqualsSpecification<T extends BaseProps> extends BaseSpecification<T> {
83
- private readonly property;
84
- private readonly value;
85
- constructor(property: keyof T, value: any);
86
- isSatisfiedBy(entity: T): boolean;
87
- }
88
- /**
89
- * Specification that checks if a property is in a set of values
90
- *
91
- * @example
92
- * ```typescript
93
- * const validStatusSpec = new PropertyInSpecification<User>('status', ['active', 'pending']);
94
- * ```
95
- */
96
- export declare class PropertyInSpecification<T extends BaseProps> extends BaseSpecification<T> {
97
- private readonly property;
98
- private readonly values;
99
- constructor(property: keyof T, values: any[]);
100
- isSatisfiedBy(entity: T): boolean;
101
- }
102
- //# sourceMappingURL=specification.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"specification.d.ts","sourceRoot":"","sources":["../src/specification.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAMzC;;;;;;;;;;;;;;;GAeG;AACH,8BAAsB,iBAAiB,CAAC,CAAC,SAAS,SAAS;IACzD;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO;IAE1C;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC;IAItD;;;OAGG;IACH,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC;IAIrD;;;OAGG;IACH,GAAG,IAAI,iBAAiB,CAAC,CAAC,CAAC;IAI3B;;OAEG;IACH,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO;CAGtC;AA4DD;;;GAGG;AACH,qBAAa,iBAAiB,CAAC,CAAC,SAAS,SAAS,CAAE,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IAC9E,aAAa,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO;CAGnC;AAED;;;GAGG;AACH,qBAAa,kBAAkB,CAAC,CAAC,SAAS,SAAS,CAAE,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IAC/E,aAAa,CAAC,OAAO,EAAE,CAAC,GAAG,OAAO;CAGnC;AAED;;;;;;;;;;GAUG;AACH,qBAAa,sBAAsB,CAAC,CAAC,SAAS,SAAS,CAAE,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO;IAI9D,aAAa,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO;CAGlC;AAED;;;;;;;GAOG;AACH,qBAAa,2BAA2B,CAAC,CAAC,SAAS,SAAS,CAAE,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IAEtF,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,QAAQ,EAAE,MAAM,CAAC,EACjB,KAAK,EAAE,GAAG;IAK7B,aAAa,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO;CAGlC;AAED;;;;;;;GAOG;AACH,qBAAa,uBAAuB,CAAC,CAAC,SAAS,SAAS,CAAE,SAAQ,iBAAiB,CAAC,CAAC,CAAC;IAElF,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,QAAQ,EAAE,MAAM,CAAC,EACjB,MAAM,EAAE,GAAG,EAAE;IAKhC,aAAa,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO;CAGlC"}
@@ -1,187 +0,0 @@
1
- "use strict";
2
- // ============================================================================
3
- // Specification Pattern
4
- // ============================================================================
5
- // Implements the Specification pattern from Domain-Driven Design
6
- // Allows encapsulating business rules and composing them with AND/OR/NOT logic
7
- // Primarily for in-memory validation, but can be extended for persistence queries
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.PropertyInSpecification = exports.PropertyEqualsSpecification = exports.PredicateSpecification = exports.FalseSpecification = exports.TrueSpecification = exports.BaseSpecification = void 0;
10
- // ============================================================================
11
- // BaseSpecification Class
12
- // ============================================================================
13
- /**
14
- * Abstract base class for Specification pattern
15
- * Specifications encapsulate business rules and can be composed together
16
- *
17
- * @example
18
- * ```typescript
19
- * class AdultSpecification extends BaseSpecification<User> {
20
- * isSatisfiedBy(user: User): boolean {
21
- * return user.age >= 18;
22
- * }
23
- * }
24
- *
25
- * const spec = new AdultSpecification();
26
- * const adults = users.filter(u => spec.isSatisfiedBy(u));
27
- * ```
28
- */
29
- class BaseSpecification {
30
- /**
31
- * Combines this specification with another using AND logic
32
- * Both specifications must be satisfied
33
- */
34
- and(other) {
35
- return new AndSpecification(this, other);
36
- }
37
- /**
38
- * Combines this specification with another using OR logic
39
- * At least one specification must be satisfied
40
- */
41
- or(other) {
42
- return new OrSpecification(this, other);
43
- }
44
- /**
45
- * Negates this specification
46
- * Returns true if this specification is NOT satisfied
47
- */
48
- not() {
49
- return new NotSpecification(this);
50
- }
51
- /**
52
- * Creates a predicate function for use with Array.filter()
53
- */
54
- asPredicate() {
55
- return (entity) => this.isSatisfiedBy(entity);
56
- }
57
- }
58
- exports.BaseSpecification = BaseSpecification;
59
- // ============================================================================
60
- // Composite Specifications (Internal)
61
- // ============================================================================
62
- // These are created automatically by and(), or(), not() methods
63
- // Users typically don't instantiate these directly
64
- /**
65
- * AND specification - both specifications must be satisfied
66
- * @internal
67
- */
68
- class AndSpecification extends BaseSpecification {
69
- constructor(left, right) {
70
- super();
71
- this.left = left;
72
- this.right = right;
73
- }
74
- isSatisfiedBy(entity) {
75
- return this.left.isSatisfiedBy(entity) && this.right.isSatisfiedBy(entity);
76
- }
77
- }
78
- /**
79
- * OR specification - at least one specification must be satisfied
80
- * @internal
81
- */
82
- class OrSpecification extends BaseSpecification {
83
- constructor(left, right) {
84
- super();
85
- this.left = left;
86
- this.right = right;
87
- }
88
- isSatisfiedBy(entity) {
89
- return this.left.isSatisfiedBy(entity) || this.right.isSatisfiedBy(entity);
90
- }
91
- }
92
- /**
93
- * NOT specification - specification must NOT be satisfied
94
- * @internal
95
- */
96
- class NotSpecification extends BaseSpecification {
97
- constructor(spec) {
98
- super();
99
- this.spec = spec;
100
- }
101
- isSatisfiedBy(entity) {
102
- return !this.spec.isSatisfiedBy(entity);
103
- }
104
- }
105
- // ============================================================================
106
- // Common Specification Implementations
107
- // ============================================================================
108
- /**
109
- * Specification that is always satisfied
110
- * Useful as a starting point for building complex specifications
111
- */
112
- class TrueSpecification extends BaseSpecification {
113
- isSatisfiedBy(_entity) {
114
- return true;
115
- }
116
- }
117
- exports.TrueSpecification = TrueSpecification;
118
- /**
119
- * Specification that is never satisfied
120
- * Useful for testing or as a placeholder
121
- */
122
- class FalseSpecification extends BaseSpecification {
123
- isSatisfiedBy(_entity) {
124
- return false;
125
- }
126
- }
127
- exports.FalseSpecification = FalseSpecification;
128
- /**
129
- * Specification based on a predicate function
130
- * Allows creating specifications from lambda expressions
131
- *
132
- * @example
133
- * ```typescript
134
- * const adultSpec = new PredicateSpecification<User>(
135
- * user => user.age >= 18
136
- * );
137
- * ```
138
- */
139
- class PredicateSpecification extends BaseSpecification {
140
- constructor(predicate) {
141
- super();
142
- this.predicate = predicate;
143
- }
144
- isSatisfiedBy(entity) {
145
- return this.predicate(entity);
146
- }
147
- }
148
- exports.PredicateSpecification = PredicateSpecification;
149
- /**
150
- * Specification that checks if a property equals a specific value
151
- *
152
- * @example
153
- * ```typescript
154
- * const activeSpec = new PropertyEqualsSpecification<User>('status', 'active');
155
- * ```
156
- */
157
- class PropertyEqualsSpecification extends BaseSpecification {
158
- constructor(property, value) {
159
- super();
160
- this.property = property;
161
- this.value = value;
162
- }
163
- isSatisfiedBy(entity) {
164
- return entity[this.property] === this.value;
165
- }
166
- }
167
- exports.PropertyEqualsSpecification = PropertyEqualsSpecification;
168
- /**
169
- * Specification that checks if a property is in a set of values
170
- *
171
- * @example
172
- * ```typescript
173
- * const validStatusSpec = new PropertyInSpecification<User>('status', ['active', 'pending']);
174
- * ```
175
- */
176
- class PropertyInSpecification extends BaseSpecification {
177
- constructor(property, values) {
178
- super();
179
- this.property = property;
180
- this.values = values;
181
- }
182
- isSatisfiedBy(entity) {
183
- return this.values.includes(entity[this.property]);
184
- }
185
- }
186
- exports.PropertyInSpecification = PropertyInSpecification;
187
- //# sourceMappingURL=specification.js.map