@woltz/rich-domain 1.1.0 → 1.2.1
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.
- package/CHANGELOG.md +87 -21
- package/dist/aggregate-changes.d.ts +164 -0
- package/dist/aggregate-changes.d.ts.map +1 -0
- package/dist/aggregate-changes.js +281 -0
- package/dist/aggregate-changes.js.map +1 -0
- package/dist/base-entity.d.ts +32 -8
- package/dist/base-entity.d.ts.map +1 -1
- package/dist/base-entity.js +117 -86
- package/dist/base-entity.js.map +1 -1
- package/dist/criteria.d.ts +31 -15
- package/dist/criteria.d.ts.map +1 -1
- package/dist/criteria.js +151 -61
- package/dist/criteria.js.map +1 -1
- package/dist/crypto.d.ts +3 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +29 -0
- package/dist/crypto.js.map +1 -0
- package/dist/entity-changes.d.ts +84 -0
- package/dist/entity-changes.d.ts.map +1 -0
- package/dist/entity-changes.js +135 -0
- package/dist/entity-changes.js.map +1 -0
- package/dist/entity-schema-registry.d.ts +148 -0
- package/dist/entity-schema-registry.d.ts.map +1 -0
- package/dist/entity-schema-registry.js +219 -0
- package/dist/entity-schema-registry.js.map +1 -0
- package/dist/history-tracker.d.ts +97 -0
- package/dist/history-tracker.d.ts.map +1 -0
- package/dist/history-tracker.js +805 -0
- package/dist/history-tracker.js.map +1 -0
- package/dist/id.d.ts +11 -10
- package/dist/id.d.ts.map +1 -1
- package/dist/id.js +4 -28
- package/dist/id.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/mapper.d.ts +1 -1
- package/dist/mapper.d.ts.map +1 -1
- package/dist/mapper.js.map +1 -1
- package/dist/paginated-result.d.ts.map +1 -1
- package/dist/paginated-result.js +7 -6
- package/dist/paginated-result.js.map +1 -1
- package/dist/repository/base-repository.d.ts +6 -32
- package/dist/repository/base-repository.d.ts.map +1 -1
- package/dist/repository/base-repository.js +0 -27
- package/dist/repository/base-repository.js.map +1 -1
- package/dist/repository/unit-of-work.d.ts +0 -25
- package/dist/repository/unit-of-work.d.ts.map +1 -1
- package/dist/repository/unit-of-work.js +0 -25
- package/dist/repository/unit-of-work.js.map +1 -1
- package/dist/types/change-tracker.d.ts +186 -0
- package/dist/types/change-tracker.d.ts.map +1 -0
- package/dist/types/change-tracker.js +2 -0
- package/dist/types/change-tracker.js.map +1 -0
- package/dist/types/criteria.d.ts +31 -7
- package/dist/types/criteria.d.ts.map +1 -1
- package/dist/types/history-tracker.d.ts +11 -0
- package/dist/types/history-tracker.d.ts.map +1 -1
- package/dist/types/utils.d.ts +0 -1
- package/dist/types/utils.d.ts.map +1 -1
- package/dist/utils/criteria-operator-validation.d.ts +5 -0
- package/dist/utils/criteria-operator-validation.d.ts.map +1 -0
- package/dist/utils/criteria-operator-validation.js +143 -0
- package/dist/utils/criteria-operator-validation.js.map +1 -0
- package/dist/utils/helpers.d.ts +2 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +10 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/validation-error.d.ts.map +1 -1
- package/dist/validation-error.js +0 -3
- package/dist/validation-error.js.map +1 -1
- package/dist/value-object.d.ts +57 -8
- package/dist/value-object.d.ts.map +1 -1
- package/dist/value-object.js +49 -21
- package/dist/value-object.js.map +1 -1
- package/eslint.config.js +6 -0
- package/package.json +2 -1
- package/src/aggregate-changes.ts +335 -0
- package/src/base-entity.ts +140 -100
- package/src/criteria.ts +264 -82
- package/src/crypto.ts +31 -0
- package/src/entity-changes.ts +151 -0
- package/src/entity-schema-registry.ts +275 -0
- package/src/history-tracker.ts +1114 -0
- package/src/id.ts +17 -26
- package/src/index.ts +8 -2
- package/src/mapper.ts +4 -1
- package/src/paginated-result.ts +7 -8
- package/src/repository/base-repository.ts +6 -37
- package/src/repository/unit-of-work.ts +0 -25
- package/src/types/change-tracker.ts +221 -0
- package/src/types/criteria.ts +95 -17
- package/src/types/history-tracker.ts +13 -0
- package/src/types/utils.ts +0 -9
- package/src/utils/criteria-operator-validation.ts +171 -0
- package/src/utils/helpers.ts +6 -0
- package/src/validation-error.ts +0 -4
- package/src/value-object.ts +84 -23
- package/tests/aggregate-changes.test.ts +284 -0
- package/tests/criteria.test.ts +366 -90
- package/tests/entity-equality.test.ts +38 -61
- package/tests/entity-schema-registry.test.ts +382 -0
- package/tests/entity-validation.test.ts +7 -94
- package/tests/history-tracker.spec.ts +349 -617
- package/tests/id.test.ts +41 -44
- package/tests/load-test/data.json +346041 -0
- package/tests/load-test/entities.ts +97 -0
- package/tests/load-test/generate-data.ts +81 -0
- package/tests/load-test/lead-to-domain.mapper.ts +24 -0
- package/tests/load-test/load.test.ts +38 -0
- package/tests/repository.test.ts +30 -54
- package/tests/to-json.test.ts +14 -18
- package/tests/utils.ts +138 -102
- package/tests/value-objects.test.ts +57 -29
- package/dist/deep-proxy.d.ts +0 -36
- package/dist/deep-proxy.d.ts.map +0 -1
- package/dist/deep-proxy.js +0 -384
- package/dist/deep-proxy.js.map +0 -1
- package/src/deep-proxy.ts +0 -447
- package/tests/entity.test.ts +0 -33
package/CHANGELOG.md
CHANGED
|
@@ -2,40 +2,106 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### [1.2.1](https://github.com/tarcisioandrade/rich-domain/compare/v1.2.0...v1.2.1) (2025-11-29)
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
### Features
|
|
9
9
|
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* implement custom UUID generation in crypto module ([4fc732a](https://github.com/tarcisioandrade/rich-domain/commit/4fc732a00237a9d63e320555acf4a8a14c941f13))
|
|
11
|
+
* introduce TypedOrder and enhance Criteria to support nested object field paths ([9857624](https://github.com/tarcisioandrade/rich-domain/commit/9857624608eda1320ec813b165e9183f1e28a0d1))
|
|
12
|
+
* new history-tracker structure ([aaea6d4](https://github.com/tarcisioandrade/rich-domain/commit/aaea6d4c8aed575f50917cba41936d1b1560ed3d))
|
|
13
|
+
* update Id constructor to handle optional isNew parameter ([0aae58b](https://github.com/tarcisioandrade/rich-domain/commit/0aae58b02da69e0cb7421663335ac305ade5afa7))
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
### Bug Fixes
|
|
17
17
|
|
|
18
|
-
*
|
|
19
|
-
*
|
|
18
|
+
* aggregate-changes type inference ([aa62138](https://github.com/tarcisioandrade/rich-domain/commit/aa62138b31cdedb63c0e1be8a19271f4ada2e71c))
|
|
19
|
+
* history tracker not tracking when nested created ([2900e20](https://github.com/tarcisioandrade/rich-domain/commit/2900e20c18da7aa0ee960c9e5d0f5e2524e3d6f3))
|
|
20
|
+
* uow in persistence fastify example ([fcef611](https://github.com/tarcisioandrade/rich-domain/commit/fcef61103f160c0b1adbee9cbce821ce047189eb))
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
### Refactoring
|
|
23
24
|
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* remove
|
|
28
|
-
*
|
|
25
|
+
* change prisma example to new architecture ([92dc179](https://github.com/tarcisioandrade/rich-domain/commit/92dc1798ee5a64439d6633ab5b0cc77b42265ed6))
|
|
26
|
+
* improve deepClone method for better object handling and error management ([52ae893](https://github.com/tarcisioandrade/rich-domain/commit/52ae8930d112ba018f7944f69837edea82d45309))
|
|
27
|
+
* prisma example unit of work with async local storage ([ca6fc16](https://github.com/tarcisioandrade/rich-domain/commit/ca6fc1663ca251dac020939080b126f3984b0eae))
|
|
28
|
+
* remove unnosed code from ancient architecture ([19a41b1](https://github.com/tarcisioandrade/rich-domain/commit/19a41b121b4adaaea5525da20b068f43cc674db8))
|
|
29
|
+
* update repository methods to use 'save' consistently across use cases ([aab323b](https://github.com/tarcisioandrade/rich-domain/commit/aab323be2fff86246dc0c1a14cb7ba56bf11efa7))
|
|
30
|
+
* update repository methods to use 'save' instead of 'create' and 'update' ([6766970](https://github.com/tarcisioandrade/rich-domain/commit/6766970019781215019b492963e020ef4babcd89))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Tests
|
|
34
|
+
|
|
35
|
+
* add load test ([9bd07fb](https://github.com/tarcisioandrade/rich-domain/commit/9bd07fb019e2cc0eef3f0573af8f4dad1d8b385f))
|
|
36
|
+
* new history-tracker structure ([d31ad0b](https://github.com/tarcisioandrade/rich-domain/commit/d31ad0b109bfa5e5ff62743d70dd51bb64107f10))
|
|
37
|
+
|
|
38
|
+
## [1.2.0](https://github.com/tarcisioandrade/rich-domain/compare/v1.1.0...v1.2.0) (2025-11-23)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
### Features
|
|
42
|
+
|
|
43
|
+
* add getFilterByField and getSortByField methods to useCriteria hook ([8db041a](https://github.com/tarcisioandrade/rich-domain/commit/8db041a8fbe359ec6fe3ff70e22ac87a6c221686))
|
|
44
|
+
* add options parameter to addFilter method for enhanced filtering capabilities ([c43c164](https://github.com/tarcisioandrade/rich-domain/commit/c43c164f56831b9f0b06f2e5981ba3f540cf3378))
|
|
45
|
+
* add quantifier support to Criteria class for enhanced filtering options ([322adf3](https://github.com/tarcisioandrade/rich-domain/commit/322adf36dfedcdc21ae6fc85c3577e1fb2835019))
|
|
46
|
+
* criteria adapter implementation ([f387f0b](https://github.com/tarcisioandrade/rich-domain/commit/f387f0bcd601a69da74d5fff33b9d9872e049179))
|
|
47
|
+
* enhance criteria operators with new types and validation functions ([8d30c14](https://github.com/tarcisioandrade/rich-domain/commit/8d30c1448e3d25c790d667b43d17546a441e710d))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Bug Fixes
|
|
51
|
+
|
|
52
|
+
* FieldPath infer type to array methods ([844a56e](https://github.com/tarcisioandrade/rich-domain/commit/844a56ef2cdc65fac0cb228c6936808a92ffa440))
|
|
53
|
+
* search filter not reset page ([c8c9d8b](https://github.com/tarcisioandrade/rich-domain/commit/c8c9d8b1fecc1ce8c568f43710c8748ad9ad1f1e))
|
|
54
|
+
* types in react-with-react-query ([6eeeb74](https://github.com/tarcisioandrade/rich-domain/commit/6eeeb74715bef50d3c5dec8dcc3e37484e0f511b))
|
|
29
55
|
|
|
30
56
|
|
|
31
57
|
### Chores
|
|
32
58
|
|
|
33
|
-
* add
|
|
34
|
-
* enhance
|
|
35
|
-
*
|
|
36
|
-
* update
|
|
37
|
-
* update
|
|
38
|
-
* update
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
59
|
+
* add TypeScript check script and enhance ([9f6347c](https://github.com/tarcisioandrade/rich-domain/commit/9f6347c4707adebb9e03bcdc952791a9c3279038))
|
|
60
|
+
* enhance useCriteria hook and update TypeScript types for better type safety ([2bbc699](https://github.com/tarcisioandrade/rich-domain/commit/2bbc699aab415a52502ad50e7fbf67bcd52ae222))
|
|
61
|
+
* refactor frontend example to integrate useCriteria hook ([48dccc7](https://github.com/tarcisioandrade/rich-domain/commit/48dccc7df870024f280902c22c77dcf531702781))
|
|
62
|
+
* update ESLint configurations to include tsconfigRootDir ([b019884](https://github.com/tarcisioandrade/rich-domain/commit/b01988496b91c6c9d3e6d3d89597cf9f23e54729))
|
|
63
|
+
* update rich domain version in examples app ([4be8a1b](https://github.com/tarcisioandrade/rich-domain/commit/4be8a1bdd4473d8274c0ec8bec1d4ec1d70109ea))
|
|
64
|
+
* update target paths in registry.json and use-criteria.json for improved file structure ([d2f9348](https://github.com/tarcisioandrade/rich-domain/commit/d2f93486158e465d8878d92f1d80e259cc62f701))
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
### Refactoring
|
|
68
|
+
|
|
69
|
+
* criteria adapter in fastify-with-prisma example ([8adef1e](https://github.com/tarcisioandrade/rich-domain/commit/8adef1e0c62ab94bd3665f91ca6ea29d568ea24f))
|
|
70
|
+
|
|
71
|
+
## [1.1.0](https://github.com/tarcisioandrade/rich-domain/compare/v1.0.0...v1.1.0) (2025-11-22)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
### Features
|
|
75
|
+
|
|
76
|
+
* add examples in monorepo ([2cba30e](https://github.com/tarcisioandrade/rich-domain/commit/2cba30e318be2575b007c8b4f9a00e35561eec5e))
|
|
77
|
+
* add react-with-react-query example ([439589e](https://github.com/tarcisioandrade/rich-domain/commit/439589e1abbc47b1b03efab3b9dde53fe8d6253c))
|
|
78
|
+
* domain execeptions ([e206274](https://github.com/tarcisioandrade/rich-domain/commit/e206274d8a93c09cc91b2c0514be62cb986caaa3))
|
|
79
|
+
* implement useCriteria hook ([c00441a](https://github.com/tarcisioandrade/rich-domain/commit/c00441a105391fd06ef39b8c7e3aa0907c3ff508))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
### Bug Fixes
|
|
83
|
+
|
|
84
|
+
* infinite loop when multiples order are add ([2c13dc4](https://github.com/tarcisioandrade/rich-domain/commit/2c13dc472d009bf328ad45222ea1c921f588ff9a))
|
|
85
|
+
* search not working in fromArray PaginatedResult method ([b79b2aa](https://github.com/tarcisioandrade/rich-domain/commit/b79b2aa2aa17e8b98bf2c2fcb4823452db99dcc1))
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
### Refactoring
|
|
89
|
+
|
|
90
|
+
* clean exports ([3f8e16a](https://github.com/tarcisioandrade/rich-domain/commit/3f8e16a2103514ef7a2a928dff20f674d1e39506))
|
|
91
|
+
* migrate eslint configuration to ES module syntax ([3ea4366](https://github.com/tarcisioandrade/rich-domain/commit/3ea43667b0857b7ae2afcbad858c16384035dc50))
|
|
92
|
+
* monorepo implementation ([e0b1e68](https://github.com/tarcisioandrade/rich-domain/commit/e0b1e683d5ee95b54b79510d43dd957af49c65e2))
|
|
93
|
+
* remove defaultValues from value objects ([0523479](https://github.com/tarcisioandrade/rich-domain/commit/0523479c6f272d7ea5d678638fa666e3fde71c7a))
|
|
94
|
+
* streamline domain event imports and consolidate IDomainEvent interface ([573c689](https://github.com/tarcisioandrade/rich-domain/commit/573c689a762baecd9fb8791e66300f663d7a58c1))
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
### Chores
|
|
98
|
+
|
|
99
|
+
* add postinstall script to generate Prisma client ([ffbe310](https://github.com/tarcisioandrade/rich-domain/commit/ffbe310db4ff9e6918d4e55096b8939c1f8f4543))
|
|
100
|
+
* enhance linting setup for react-rich-domain and update package.json ([ac2803b](https://github.com/tarcisioandrade/rich-domain/commit/ac2803bac0d907c0513d249fc5e14390418c7530))
|
|
101
|
+
* modify check script to target specific workspace ([d39d6d8](https://github.com/tarcisioandrade/rich-domain/commit/d39d6d8ef3a04d17207a3a0e795027040b3cf707))
|
|
102
|
+
* update clean script to remove node_modules in backend and rich-domain packages ([2a10cab](https://github.com/tarcisioandrade/rich-domain/commit/2a10cab193ba00e504a9a301cc00cda4b68b8573))
|
|
103
|
+
* update module entry points in package.json for react-rich-domain ([03be9ac](https://github.com/tarcisioandrade/rich-domain/commit/03be9aced05160c97eb74f771b770283c07e046b))
|
|
104
|
+
* update package configuration and add new dependencies ([4135393](https://github.com/tarcisioandrade/rich-domain/commit/4135393ae78b1b8e6b0c9306f0ac0872971ddb3f))
|
|
105
|
+
* update package.json scripts to target specific workspace ([8f46868](https://github.com/tarcisioandrade/rich-domain/commit/8f468688017f49cae58dff5d1a9818fe64b38017))
|
|
106
|
+
* update package.json with homepage and repository detail ([bfb387c](https://github.com/tarcisioandrade/rich-domain/commit/bfb387cb2076989a808f25be09337a24ed3a8ff6))
|
|
107
|
+
* update test script to target specific workspace ([6783208](https://github.com/tarcisioandrade/rich-domain/commit/678320803828a43ef588c366e59bf62c2851c126))
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { Operation, CreateOperation, UpdateOperation, DeleteOperation, BatchOperations } from "./types/change-tracker";
|
|
2
|
+
import { EntityChanges } from "./entity-changes";
|
|
3
|
+
/**
|
|
4
|
+
* Manages and organizes the changes of an Aggregate.
|
|
5
|
+
*
|
|
6
|
+
* Responsibilities:
|
|
7
|
+
* - Stores all operations (create, update, delete)
|
|
8
|
+
* - Orders operations respecting FK dependencies
|
|
9
|
+
* - Groups operations by entity for batch execution
|
|
10
|
+
* - Provides query and iteration methods
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Define an entity map for type-safe operations
|
|
15
|
+
* type UserEntities = {
|
|
16
|
+
* User: User;
|
|
17
|
+
* Post: Post;
|
|
18
|
+
* Comment: Comment;
|
|
19
|
+
* };
|
|
20
|
+
*
|
|
21
|
+
* // Getting changes with types
|
|
22
|
+
* const changes = user.getChanges<UserEntities>();
|
|
23
|
+
*
|
|
24
|
+
* // Filtering by entity with autocompletion
|
|
25
|
+
* const postChanges = changes.for('Post'); // 'Post' autocompletes
|
|
26
|
+
* postChanges.creates.forEach(post => {
|
|
27
|
+
* console.log(post.title); // 'post' is typed as Post
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare class AggregateChanges<TEntityMap = Record<string, any>> {
|
|
32
|
+
private ops;
|
|
33
|
+
constructor(operations?: Operation[]);
|
|
34
|
+
/**
|
|
35
|
+
* Adds a create operation.
|
|
36
|
+
*/
|
|
37
|
+
addCreate<T>(entity: string, data: T, depth: number, parentId?: string, parentEntity?: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Adds an update operation.
|
|
40
|
+
*/
|
|
41
|
+
addUpdate<T>(entity: string, id: string, data: T, changedFields: Record<string, any>, depth: number): void;
|
|
42
|
+
/**
|
|
43
|
+
* Adds a delete operation.
|
|
44
|
+
*/
|
|
45
|
+
addDelete<T>(entity: string, id: string, data: T, depth: number): void;
|
|
46
|
+
/**
|
|
47
|
+
* Returns all create operations, sorted by ascending depth (root → leaf).
|
|
48
|
+
*/
|
|
49
|
+
creates(): CreateOperation[];
|
|
50
|
+
/**
|
|
51
|
+
* Returns all update operations.
|
|
52
|
+
*/
|
|
53
|
+
updates(): UpdateOperation[];
|
|
54
|
+
/**
|
|
55
|
+
* Returns all delete operations, sorted by descending depth (leaf → root).
|
|
56
|
+
*/
|
|
57
|
+
deletes(): DeleteOperation[];
|
|
58
|
+
/**
|
|
59
|
+
* Iterator that returns operations in the correct execution order:
|
|
60
|
+
* 1. Deletes (leaf → root)
|
|
61
|
+
* 2. Creates (root → leaf)
|
|
62
|
+
* 3. Updates
|
|
63
|
+
*/
|
|
64
|
+
operations(): Generator<Operation>;
|
|
65
|
+
/**
|
|
66
|
+
* Returns all operations as an array in execution order.
|
|
67
|
+
*/
|
|
68
|
+
toArray(): Operation[];
|
|
69
|
+
/**
|
|
70
|
+
* Converts the changes into BatchOperations for optimized execution.
|
|
71
|
+
*
|
|
72
|
+
* Groups operations by entity and sorts by depth:
|
|
73
|
+
* - Deletes: depth DESC (leaf → root)
|
|
74
|
+
* - Creates: depth ASC (root → leaf)
|
|
75
|
+
* - Updates: grouped by entity
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const batch = changes.toBatchOperations();
|
|
80
|
+
*
|
|
81
|
+
* // Run deletes
|
|
82
|
+
* for (const del of batch.deletes) {
|
|
83
|
+
* await tx[del.entity].deleteMany({ where: { id: { in: del.ids } } });
|
|
84
|
+
* }
|
|
85
|
+
*
|
|
86
|
+
* // Run creates
|
|
87
|
+
* for (const create of batch.creates) {
|
|
88
|
+
* await tx[create.entity].createMany({ data: create.items });
|
|
89
|
+
* }
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
toBatchOperations(): BatchOperations;
|
|
93
|
+
/**
|
|
94
|
+
* Groups deletes by entity, sorted by descending depth.
|
|
95
|
+
*/
|
|
96
|
+
private groupDeletes;
|
|
97
|
+
/**
|
|
98
|
+
* Groups creates by entity, sorted by ascending depth.
|
|
99
|
+
*/
|
|
100
|
+
private groupCreates;
|
|
101
|
+
/**
|
|
102
|
+
* Groups updates by entity.
|
|
103
|
+
*/
|
|
104
|
+
private groupUpdates;
|
|
105
|
+
/**
|
|
106
|
+
* Filters changes by entity name.
|
|
107
|
+
*
|
|
108
|
+
* @param entityName - Name of the entity (e.g., 'Post', 'Comment')
|
|
109
|
+
* @returns EntityChanges containing only the operations for this entity
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* const postChanges = changes.for('Post');
|
|
114
|
+
*
|
|
115
|
+
* if (postChanges.hasCreates()) {
|
|
116
|
+
* postChanges.creates.forEach(post => {
|
|
117
|
+
* console.log('New post:', post.title);
|
|
118
|
+
* });
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
for<K extends keyof TEntityMap>(entityName: K): EntityChanges<TEntityMap[K]>;
|
|
123
|
+
/**
|
|
124
|
+
* Checks if there are create operations.
|
|
125
|
+
*/
|
|
126
|
+
hasCreates(): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Checks if there are update operations.
|
|
129
|
+
*/
|
|
130
|
+
hasUpdates(): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* Checks if there are delete operations.
|
|
133
|
+
*/
|
|
134
|
+
hasDeletes(): boolean;
|
|
135
|
+
/**
|
|
136
|
+
* Checks if there are any operations.
|
|
137
|
+
*/
|
|
138
|
+
hasChanges(): boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Checks if there are no operations.
|
|
141
|
+
*/
|
|
142
|
+
isEmpty(): boolean;
|
|
143
|
+
/**
|
|
144
|
+
* Returns the total number of operations.
|
|
145
|
+
*/
|
|
146
|
+
get count(): number;
|
|
147
|
+
/**
|
|
148
|
+
* Returns the raw operations (for debug/testing).
|
|
149
|
+
*/
|
|
150
|
+
get rawOperations(): Operation[];
|
|
151
|
+
/**
|
|
152
|
+
* Lists all entities that have changes.
|
|
153
|
+
*/
|
|
154
|
+
getAffectedEntities(): string[];
|
|
155
|
+
/**
|
|
156
|
+
* Clears all operations.
|
|
157
|
+
*/
|
|
158
|
+
clear(): void;
|
|
159
|
+
/**
|
|
160
|
+
* Creates a copy of the changes.
|
|
161
|
+
*/
|
|
162
|
+
clone(): AggregateChanges<TEntityMap>;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=aggregate-changes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregate-changes.d.ts","sourceRoot":"","sources":["../src/aggregate-changes.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,eAAe,EACf,eAAe,EACf,eAAe,EACf,eAAe,EAGhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,gBAAgB,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC5D,OAAO,CAAC,GAAG,CAAmB;gBAElB,UAAU,GAAE,SAAS,EAAO;IAIxC;;OAEG;IACH,SAAS,CAAC,CAAC,EACT,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,YAAY,CAAC,EAAE,MAAM,GACpB,IAAI;IAWP;;OAEG;IACH,SAAS,CAAC,CAAC,EACT,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,CAAC,EACP,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAClC,KAAK,EAAE,MAAM,GACZ,IAAI;IAWP;;OAEG;IACH,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAUtE;;OAEG;IACH,OAAO,IAAI,eAAe,EAAE;IAM5B;;OAEG;IACH,OAAO,IAAI,eAAe,EAAE;IAI5B;;OAEG;IACH,OAAO,IAAI,eAAe,EAAE;IAM5B;;;;;OAKG;IACF,UAAU,IAAI,SAAS,CAAC,SAAS,CAAC;IAMnC;;OAEG;IACH,OAAO,IAAI,SAAS,EAAE;IAItB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,iBAAiB,IAAI,eAAe;IAQpC;;OAEG;IACH,OAAO,CAAC,YAAY;IAgBpB;;OAEG;IACH,OAAO,CAAC,YAAY;IAsBpB;;OAEG;IACH,OAAO,CAAC,YAAY;IAoBpB;;;;;;;;;;;;;;;;OAgBG;IACH,GAAG,CAAC,CAAC,SAAS,MAAM,UAAU,EAAE,UAAU,EAAE,CAAC,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAK5E;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,UAAU,IAAI,OAAO;IAIrB;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,SAAS,EAAE,CAE/B;IAED;;OAEG;IACH,mBAAmB,IAAI,MAAM,EAAE;IAM/B;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,KAAK,IAAI,gBAAgB,CAAC,UAAU,CAAC;CAGtC"}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import { EntityChanges } from "./entity-changes";
|
|
2
|
+
/**
|
|
3
|
+
* Manages and organizes the changes of an Aggregate.
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* - Stores all operations (create, update, delete)
|
|
7
|
+
* - Orders operations respecting FK dependencies
|
|
8
|
+
* - Groups operations by entity for batch execution
|
|
9
|
+
* - Provides query and iteration methods
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Define an entity map for type-safe operations
|
|
14
|
+
* type UserEntities = {
|
|
15
|
+
* User: User;
|
|
16
|
+
* Post: Post;
|
|
17
|
+
* Comment: Comment;
|
|
18
|
+
* };
|
|
19
|
+
*
|
|
20
|
+
* // Getting changes with types
|
|
21
|
+
* const changes = user.getChanges<UserEntities>();
|
|
22
|
+
*
|
|
23
|
+
* // Filtering by entity with autocompletion
|
|
24
|
+
* const postChanges = changes.for('Post'); // 'Post' autocompletes
|
|
25
|
+
* postChanges.creates.forEach(post => {
|
|
26
|
+
* console.log(post.title); // 'post' is typed as Post
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export class AggregateChanges {
|
|
31
|
+
constructor(operations = []) {
|
|
32
|
+
this.ops = [];
|
|
33
|
+
this.ops = [...operations];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Adds a create operation.
|
|
37
|
+
*/
|
|
38
|
+
addCreate(entity, data, depth, parentId, parentEntity) {
|
|
39
|
+
this.ops.push({
|
|
40
|
+
type: "create",
|
|
41
|
+
entity,
|
|
42
|
+
data,
|
|
43
|
+
depth,
|
|
44
|
+
parentId,
|
|
45
|
+
parentEntity,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Adds an update operation.
|
|
50
|
+
*/
|
|
51
|
+
addUpdate(entity, id, data, changedFields, depth) {
|
|
52
|
+
this.ops.push({
|
|
53
|
+
type: "update",
|
|
54
|
+
entity,
|
|
55
|
+
id,
|
|
56
|
+
data,
|
|
57
|
+
changedFields,
|
|
58
|
+
depth,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Adds a delete operation.
|
|
63
|
+
*/
|
|
64
|
+
addDelete(entity, id, data, depth) {
|
|
65
|
+
this.ops.push({
|
|
66
|
+
type: "delete",
|
|
67
|
+
entity,
|
|
68
|
+
id,
|
|
69
|
+
data,
|
|
70
|
+
depth,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Returns all create operations, sorted by ascending depth (root → leaf).
|
|
75
|
+
*/
|
|
76
|
+
creates() {
|
|
77
|
+
return this.ops
|
|
78
|
+
.filter((op) => op.type === "create")
|
|
79
|
+
.sort((a, b) => a.depth - b.depth);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Returns all update operations.
|
|
83
|
+
*/
|
|
84
|
+
updates() {
|
|
85
|
+
return this.ops.filter((op) => op.type === "update");
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Returns all delete operations, sorted by descending depth (leaf → root).
|
|
89
|
+
*/
|
|
90
|
+
deletes() {
|
|
91
|
+
return this.ops
|
|
92
|
+
.filter((op) => op.type === "delete")
|
|
93
|
+
.sort((a, b) => b.depth - a.depth);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Iterator that returns operations in the correct execution order:
|
|
97
|
+
* 1. Deletes (leaf → root)
|
|
98
|
+
* 2. Creates (root → leaf)
|
|
99
|
+
* 3. Updates
|
|
100
|
+
*/
|
|
101
|
+
*operations() {
|
|
102
|
+
yield* this.deletes();
|
|
103
|
+
yield* this.creates();
|
|
104
|
+
yield* this.updates();
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Returns all operations as an array in execution order.
|
|
108
|
+
*/
|
|
109
|
+
toArray() {
|
|
110
|
+
return [...this.operations()];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Converts the changes into BatchOperations for optimized execution.
|
|
114
|
+
*
|
|
115
|
+
* Groups operations by entity and sorts by depth:
|
|
116
|
+
* - Deletes: depth DESC (leaf → root)
|
|
117
|
+
* - Creates: depth ASC (root → leaf)
|
|
118
|
+
* - Updates: grouped by entity
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```typescript
|
|
122
|
+
* const batch = changes.toBatchOperations();
|
|
123
|
+
*
|
|
124
|
+
* // Run deletes
|
|
125
|
+
* for (const del of batch.deletes) {
|
|
126
|
+
* await tx[del.entity].deleteMany({ where: { id: { in: del.ids } } });
|
|
127
|
+
* }
|
|
128
|
+
*
|
|
129
|
+
* // Run creates
|
|
130
|
+
* for (const create of batch.creates) {
|
|
131
|
+
* await tx[create.entity].createMany({ data: create.items });
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
toBatchOperations() {
|
|
136
|
+
return {
|
|
137
|
+
deletes: this.groupDeletes(),
|
|
138
|
+
creates: this.groupCreates(),
|
|
139
|
+
updates: this.groupUpdates(),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Groups deletes by entity, sorted by descending depth.
|
|
144
|
+
*/
|
|
145
|
+
groupDeletes() {
|
|
146
|
+
const deleteOps = this.deletes();
|
|
147
|
+
const grouped = new Map();
|
|
148
|
+
for (const op of deleteOps) {
|
|
149
|
+
if (!grouped.has(op.entity)) {
|
|
150
|
+
grouped.set(op.entity, { depth: op.depth, ids: [] });
|
|
151
|
+
}
|
|
152
|
+
grouped.get(op.entity).ids.push(op.id);
|
|
153
|
+
}
|
|
154
|
+
return Array.from(grouped.entries())
|
|
155
|
+
.map(([entity, { depth, ids }]) => ({ entity, depth, ids }))
|
|
156
|
+
.sort((a, b) => b.depth - a.depth);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Groups creates by entity, sorted by ascending depth.
|
|
160
|
+
*/
|
|
161
|
+
groupCreates() {
|
|
162
|
+
const createOps = this.creates();
|
|
163
|
+
const grouped = new Map();
|
|
164
|
+
for (const op of createOps) {
|
|
165
|
+
if (!grouped.has(op.entity)) {
|
|
166
|
+
grouped.set(op.entity, { depth: op.depth, items: [] });
|
|
167
|
+
}
|
|
168
|
+
grouped.get(op.entity).items.push({
|
|
169
|
+
data: op.data,
|
|
170
|
+
parentId: op.parentId,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
return Array.from(grouped.entries())
|
|
174
|
+
.map(([entity, { depth, items }]) => ({ entity, depth, items }))
|
|
175
|
+
.sort((a, b) => a.depth - b.depth);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Groups updates by entity.
|
|
179
|
+
*/
|
|
180
|
+
groupUpdates() {
|
|
181
|
+
const updateOps = this.updates();
|
|
182
|
+
const grouped = new Map();
|
|
183
|
+
for (const op of updateOps) {
|
|
184
|
+
if (!grouped.has(op.entity)) {
|
|
185
|
+
grouped.set(op.entity, []);
|
|
186
|
+
}
|
|
187
|
+
grouped.get(op.entity).push({
|
|
188
|
+
id: op.id,
|
|
189
|
+
changedFields: op.changedFields,
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
return Array.from(grouped.entries()).map(([entity, items]) => ({
|
|
193
|
+
entity,
|
|
194
|
+
items,
|
|
195
|
+
}));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Filters changes by entity name.
|
|
199
|
+
*
|
|
200
|
+
* @param entityName - Name of the entity (e.g., 'Post', 'Comment')
|
|
201
|
+
* @returns EntityChanges containing only the operations for this entity
|
|
202
|
+
*
|
|
203
|
+
* @example
|
|
204
|
+
* ```typescript
|
|
205
|
+
* const postChanges = changes.for('Post');
|
|
206
|
+
*
|
|
207
|
+
* if (postChanges.hasCreates()) {
|
|
208
|
+
* postChanges.creates.forEach(post => {
|
|
209
|
+
* console.log('New post:', post.title);
|
|
210
|
+
* });
|
|
211
|
+
* }
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
for(entityName) {
|
|
215
|
+
const filtered = this.ops.filter((op) => op.entity === entityName);
|
|
216
|
+
return new EntityChanges(filtered);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Checks if there are create operations.
|
|
220
|
+
*/
|
|
221
|
+
hasCreates() {
|
|
222
|
+
return this.ops.some((op) => op.type === "create");
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Checks if there are update operations.
|
|
226
|
+
*/
|
|
227
|
+
hasUpdates() {
|
|
228
|
+
return this.ops.some((op) => op.type === "update");
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Checks if there are delete operations.
|
|
232
|
+
*/
|
|
233
|
+
hasDeletes() {
|
|
234
|
+
return this.ops.some((op) => op.type === "delete");
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Checks if there are any operations.
|
|
238
|
+
*/
|
|
239
|
+
hasChanges() {
|
|
240
|
+
return this.ops.length > 0;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Checks if there are no operations.
|
|
244
|
+
*/
|
|
245
|
+
isEmpty() {
|
|
246
|
+
return this.ops.length === 0;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Returns the total number of operations.
|
|
250
|
+
*/
|
|
251
|
+
get count() {
|
|
252
|
+
return this.ops.length;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Returns the raw operations (for debug/testing).
|
|
256
|
+
*/
|
|
257
|
+
get rawOperations() {
|
|
258
|
+
return [...this.ops];
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Lists all entities that have changes.
|
|
262
|
+
*/
|
|
263
|
+
getAffectedEntities() {
|
|
264
|
+
const entities = new Set();
|
|
265
|
+
this.ops.forEach((op) => entities.add(op.entity));
|
|
266
|
+
return Array.from(entities);
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Clears all operations.
|
|
270
|
+
*/
|
|
271
|
+
clear() {
|
|
272
|
+
this.ops = [];
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Creates a copy of the changes.
|
|
276
|
+
*/
|
|
277
|
+
clone() {
|
|
278
|
+
return new AggregateChanges([...this.ops]);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=aggregate-changes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregate-changes.js","sourceRoot":"","sources":["../src/aggregate-changes.ts"],"names":[],"mappings":"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"}
|
package/dist/base-entity.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { Id } from "./id";
|
|
2
2
|
import { ValidationError } from "./validation-error";
|
|
3
3
|
import { IDomainEvent } from ".";
|
|
4
|
-
import { BaseProps,
|
|
4
|
+
import { BaseProps, HistoryEntry, DeepJsonResult, EntityHooks, EntityValidation } from "./types";
|
|
5
5
|
import { DomainEventBus } from "./domain-event-bus";
|
|
6
|
+
import { AggregateChanges } from "./aggregate-changes";
|
|
6
7
|
export declare abstract class BaseEntity<T extends BaseProps> {
|
|
7
8
|
private _props;
|
|
8
|
-
private
|
|
9
|
+
private tracker;
|
|
9
10
|
private proxiedProps;
|
|
10
11
|
private snapshot;
|
|
11
12
|
private validationConfig;
|
|
@@ -19,6 +20,10 @@ export declare abstract class BaseEntity<T extends BaseProps> {
|
|
|
19
20
|
});
|
|
20
21
|
private validateProps;
|
|
21
22
|
private extractPathKey;
|
|
23
|
+
/**
|
|
24
|
+
* Setup validation that runs on every property change.
|
|
25
|
+
* Uses the HistoryTracker's onChangeValidator callback.
|
|
26
|
+
*/
|
|
22
27
|
private setupUpdateValidation;
|
|
23
28
|
private takeSnapshot;
|
|
24
29
|
private deepCloneProps;
|
|
@@ -26,10 +31,6 @@ export declare abstract class BaseEntity<T extends BaseProps> {
|
|
|
26
31
|
isNew(): boolean;
|
|
27
32
|
/**
|
|
28
33
|
* Check equality with another entity by comparing IDs
|
|
29
|
-
* Entities are equal if they have the same ID, regardless of other properties
|
|
30
|
-
*
|
|
31
|
-
* @param other - Another entity or an ID to compare with
|
|
32
|
-
* @returns true if entities have the same ID
|
|
33
34
|
*/
|
|
34
35
|
equals(other: BaseEntity<T> | Id | string): boolean;
|
|
35
36
|
get props(): T;
|
|
@@ -41,13 +42,36 @@ export declare abstract class BaseEntity<T extends BaseProps> {
|
|
|
41
42
|
* Get validation errors (when throwOnError is false)
|
|
42
43
|
*/
|
|
43
44
|
get validationErrors(): ValidationError | undefined;
|
|
44
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Returns all detected changes as AggregateChanges.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const changes = user.getChanges();
|
|
51
|
+
* const batch = changes.toBatchOperations();
|
|
52
|
+
*
|
|
53
|
+
* for (const del of batch.deletes) { ... }
|
|
54
|
+
* for (const create of batch.creates) { ... }
|
|
55
|
+
* for (const upd of batch.updates) { ... }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
getChanges<TEntityMap = Record<string, any>>(): AggregateChanges<TEntityMap>;
|
|
59
|
+
/**
|
|
60
|
+
* Returns the change history (for debugging).
|
|
61
|
+
*/
|
|
45
62
|
getHistory(): HistoryEntry[];
|
|
46
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Clears history and marks entity as "clean".
|
|
65
|
+
* Call this after successfully persisting to the database.
|
|
66
|
+
*/
|
|
67
|
+
markAsClean(): void;
|
|
47
68
|
/**
|
|
48
69
|
* Add a domain event to this entity
|
|
49
70
|
*/
|
|
50
71
|
protected addDomainEvent(event: IDomainEvent): void;
|
|
72
|
+
/**
|
|
73
|
+
* Dispatch all events through the event bus
|
|
74
|
+
*/
|
|
51
75
|
dispatchAll(bus: DomainEventBus): Promise<void>;
|
|
52
76
|
/**
|
|
53
77
|
* Get all uncommitted domain events
|