@woltz/rich-domain 0.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/.github/workflows/ci.yml +40 -0
- package/.husky/commit-msg +1 -0
- package/.husky/pre-commit +1 -0
- package/.versionrc.json +21 -0
- package/.vscode/settings.json +3 -0
- package/CHANGELOG.md +81 -0
- package/LICENSE +21 -0
- package/README.md +712 -0
- package/commitlint.config.js +23 -0
- package/dist/base-entity.d.ts +67 -0
- package/dist/base-entity.d.ts.map +1 -0
- package/dist/base-entity.js +309 -0
- package/dist/base-entity.js.map +1 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +6 -0
- package/dist/constants.js.map +1 -0
- package/dist/criteria.d.ts +60 -0
- package/dist/criteria.d.ts.map +1 -0
- package/dist/criteria.js +214 -0
- package/dist/criteria.js.map +1 -0
- package/dist/deep-proxy.d.ts +34 -0
- package/dist/deep-proxy.d.ts.map +1 -0
- package/dist/deep-proxy.js +297 -0
- package/dist/deep-proxy.js.map +1 -0
- package/dist/domain-event-bus.d.ts +57 -0
- package/dist/domain-event-bus.d.ts.map +1 -0
- package/dist/domain-event-bus.js +112 -0
- package/dist/domain-event-bus.js.map +1 -0
- package/dist/domain-event.d.ts +55 -0
- package/dist/domain-event.d.ts.map +1 -0
- package/dist/domain-event.js +42 -0
- package/dist/domain-event.js.map +1 -0
- package/dist/entity.d.ts +13 -0
- package/dist/entity.d.ts.map +1 -0
- package/dist/entity.js +15 -0
- package/dist/entity.js.map +1 -0
- package/dist/filtering.d.ts +107 -0
- package/dist/filtering.d.ts.map +1 -0
- package/dist/filtering.js +202 -0
- package/dist/filtering.js.map +1 -0
- package/dist/id.d.ts +51 -0
- package/dist/id.d.ts.map +1 -0
- package/dist/id.js +84 -0
- package/dist/id.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -0
- package/dist/ordering.d.ts +93 -0
- package/dist/ordering.d.ts.map +1 -0
- package/dist/ordering.js +154 -0
- package/dist/ordering.js.map +1 -0
- package/dist/paginated-result.d.ts +62 -0
- package/dist/paginated-result.d.ts.map +1 -0
- package/dist/paginated-result.js +201 -0
- package/dist/paginated-result.js.map +1 -0
- package/dist/pagination.d.ts +218 -0
- package/dist/pagination.d.ts.map +1 -0
- package/dist/pagination.js +281 -0
- package/dist/pagination.js.map +1 -0
- package/dist/repository/base-repository.d.ts +77 -0
- package/dist/repository/base-repository.d.ts.map +1 -0
- package/dist/repository/base-repository.js +80 -0
- package/dist/repository/base-repository.js.map +1 -0
- package/dist/repository/in-memory-repository.d.ts +46 -0
- package/dist/repository/in-memory-repository.d.ts.map +1 -0
- package/dist/repository/in-memory-repository.js +85 -0
- package/dist/repository/in-memory-repository.js.map +1 -0
- package/dist/repository/index.d.ts +42 -0
- package/dist/repository/index.d.ts.map +1 -0
- package/dist/repository/index.js +47 -0
- package/dist/repository/index.js.map +1 -0
- package/dist/repository/mapper.d.ts +56 -0
- package/dist/repository/mapper.d.ts.map +1 -0
- package/dist/repository/mapper.js +15 -0
- package/dist/repository/mapper.js.map +1 -0
- package/dist/repository/types.d.ts +87 -0
- package/dist/repository/types.d.ts.map +1 -0
- package/dist/repository/types.js +6 -0
- package/dist/repository/types.js.map +1 -0
- package/dist/repository/unit-of-work.d.ts +70 -0
- package/dist/repository/unit-of-work.d.ts.map +1 -0
- package/dist/repository/unit-of-work.js +122 -0
- package/dist/repository/unit-of-work.js.map +1 -0
- package/dist/repository.d.ts +2 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +21 -0
- package/dist/repository.js.map +1 -0
- package/dist/specification.d.ts +102 -0
- package/dist/specification.d.ts.map +1 -0
- package/dist/specification.js +187 -0
- package/dist/specification.js.map +1 -0
- package/dist/types/criteria.d.ts +35 -0
- package/dist/types/criteria.d.ts.map +1 -0
- package/dist/types/criteria.js +17 -0
- package/dist/types/criteria.js.map +1 -0
- package/dist/types/domain.d.ts +30 -0
- package/dist/types/domain.d.ts.map +1 -0
- package/dist/types/domain.js +2 -0
- package/dist/types/domain.js.map +1 -0
- package/dist/types/history-tracker.d.ts +36 -0
- package/dist/types/history-tracker.d.ts.map +1 -0
- package/dist/types/history-tracker.js +2 -0
- package/dist/types/history-tracker.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/repository.d.ts +43 -0
- package/dist/types/repository.d.ts.map +1 -0
- package/dist/types/repository.js +2 -0
- package/dist/types/repository.js.map +1 -0
- package/dist/types/standard-schema.d.ts +15 -0
- package/dist/types/standard-schema.d.ts.map +1 -0
- package/dist/types/standard-schema.js +2 -0
- package/dist/types/standard-schema.js.map +1 -0
- package/dist/types/unit-of-work.d.ts +39 -0
- package/dist/types/unit-of-work.d.ts.map +1 -0
- package/dist/types/unit-of-work.js +2 -0
- package/dist/types/unit-of-work.js.map +1 -0
- package/dist/types/utils.d.ts +14 -0
- package/dist/types/utils.d.ts.map +1 -0
- package/dist/types/utils.js +2 -0
- package/dist/types/utils.js.map +1 -0
- package/dist/types.d.ts +88 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/dist/validation-error.d.ts +42 -0
- package/dist/validation-error.d.ts.map +1 -0
- package/dist/validation-error.js +73 -0
- package/dist/validation-error.js.map +1 -0
- package/dist/value-object.d.ts +47 -0
- package/dist/value-object.d.ts.map +1 -0
- package/dist/value-object.js +136 -0
- package/dist/value-object.js.map +1 -0
- package/eslint.config.js +51 -0
- package/jest.config.js +21 -0
- package/package.json +58 -0
- package/src/base-entity.ts +401 -0
- package/src/constants.ts +7 -0
- package/src/criteria.ts +291 -0
- package/src/deep-proxy.ts +339 -0
- package/src/domain-event-bus.ts +166 -0
- package/src/domain-event.ts +90 -0
- package/src/entity.ts +16 -0
- package/src/id.ts +94 -0
- package/src/index.ts +33 -0
- package/src/paginated-result.ts +274 -0
- package/src/repository/base-repository.ts +152 -0
- package/src/repository/in-memory-repository.ts +104 -0
- package/src/repository/index.ts +55 -0
- package/src/repository/mapper.ts +74 -0
- package/src/repository/unit-of-work.ts +148 -0
- package/src/types/criteria.ts +79 -0
- package/src/types/domain.ts +37 -0
- package/src/types/history-tracker.ts +45 -0
- package/src/types/index.ts +7 -0
- package/src/types/repository.ts +51 -0
- package/src/types/standard-schema.ts +19 -0
- package/src/types/unit-of-work.ts +46 -0
- package/src/types/utils.ts +29 -0
- package/src/validation-error.ts +97 -0
- package/src/value-object.ts +187 -0
- package/tests/criteria.test.ts +432 -0
- package/tests/domain-events.test.ts +445 -0
- package/tests/entity-equality.test.ts +487 -0
- package/tests/entity-validation.test.ts +339 -0
- package/tests/entity.test.ts +33 -0
- package/tests/history-tracker.spec.ts +667 -0
- package/tests/id.test.ts +341 -0
- package/tests/repository.test.ts +641 -0
- package/tests/to-json.test.ts +91 -0
- package/tests/utils.ts +151 -0
- package/tests/value-object-validation.test.ts +228 -0
- package/tests/value-objects.test.ts +52 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,187 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"specification.js","sourceRoot":"","sources":["../src/specification.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Primitive } from "./utils";
|
|
2
|
+
export declare const FilterOperator: readonly ["equals", "notEquals", "greaterThan", "greaterThanOrEqual", "lessThan", "lessThanOrEqual", "contains", "startsWith", "endsWith", "in", "notIn", "between", "isNull", "isNotNull"];
|
|
3
|
+
export type FilterValueFor<T> = T | (T extends number | Date ? [T, T] : never) | T[] | null;
|
|
4
|
+
export type PathValue<T, P extends string> = P extends `${infer K}.${infer Rest}` ? K extends keyof T ? PathValue<T[K], Rest> : never : P extends keyof T ? T[P] : never;
|
|
5
|
+
export type FilterOperator = (typeof FilterOperator)[number];
|
|
6
|
+
export interface Filter<TField = string, TValue = unknown> {
|
|
7
|
+
field: TField;
|
|
8
|
+
operator: FilterOperator;
|
|
9
|
+
value: TValue;
|
|
10
|
+
}
|
|
11
|
+
export type TypedFilter<T> = {
|
|
12
|
+
[K in FieldPath<T>]: Filter<K, FilterValueFor<PathValue<T, K>>>;
|
|
13
|
+
}[FieldPath<T>];
|
|
14
|
+
export type OrderDirection = "asc" | "desc";
|
|
15
|
+
export interface Order {
|
|
16
|
+
field: string;
|
|
17
|
+
direction: OrderDirection;
|
|
18
|
+
}
|
|
19
|
+
export interface Pagination {
|
|
20
|
+
page: number;
|
|
21
|
+
limit: number;
|
|
22
|
+
offset: number;
|
|
23
|
+
}
|
|
24
|
+
export interface PaginationMeta {
|
|
25
|
+
page: number;
|
|
26
|
+
limit: number;
|
|
27
|
+
total: number;
|
|
28
|
+
totalPages: number;
|
|
29
|
+
hasNext: boolean;
|
|
30
|
+
hasPrevious: boolean;
|
|
31
|
+
}
|
|
32
|
+
export type FieldPath<T> = {
|
|
33
|
+
[K in keyof T & string]: T[K] extends Primitive ? K : T[K] extends Array<infer U> ? K | `${K}.${FieldPath<U>}` : K | `${K}.${FieldPath<T[K]>}`;
|
|
34
|
+
}[keyof T & string];
|
|
35
|
+
//# sourceMappingURL=criteria.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"criteria.d.ts","sourceRoot":"","sources":["../../src/types/criteria.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpC,eAAO,MAAM,cAAc,6LAejB,CAAC;AAEX,MAAM,MAAM,cAAc,CAAC,CAAC,IACxB,CAAC,GACD,CAAC,CAAC,SAAS,MAAM,GAAG,IAAI,GACpB,CAAC,CAAC,EAAE,CAAC,CAAC,GACN,KAAK,CAAC,GACV,CAAC,EAAE,GACH,IAAI,CAAC;AAET,MAAM,MAAM,SAAS,CACnB,CAAC,EACD,CAAC,SAAS,MAAM,IACd,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,MAAM,IAAI,EAAE,GACpC,CAAC,SAAS,MAAM,CAAC,GACf,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GACrB,KAAK,GACP,CAAC,SAAS,MAAM,CAAC,GACjB,CAAC,CAAC,CAAC,CAAC,GACJ,KAAK,CAAC;AAEV,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,GAAG,OAAO;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI;KAC1B,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;CAChE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhB,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5C,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI;KACxB,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,SAAS,GAC3C,CAAC,GACD,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GAC3B,CAAC,GAAG,GAAG,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,GAC1B,CAAC,GAAG,GAAG,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;CAClC,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const FilterOperator = [
|
|
2
|
+
"equals",
|
|
3
|
+
"notEquals",
|
|
4
|
+
"greaterThan",
|
|
5
|
+
"greaterThanOrEqual",
|
|
6
|
+
"lessThan",
|
|
7
|
+
"lessThanOrEqual",
|
|
8
|
+
"contains",
|
|
9
|
+
"startsWith",
|
|
10
|
+
"endsWith",
|
|
11
|
+
"in",
|
|
12
|
+
"notIn",
|
|
13
|
+
"between",
|
|
14
|
+
"isNull",
|
|
15
|
+
"isNotNull",
|
|
16
|
+
];
|
|
17
|
+
//# sourceMappingURL=criteria.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"criteria.js","sourceRoot":"","sources":["../../src/types/criteria.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,QAAQ;IACR,WAAW;IACX,aAAa;IACb,oBAAoB;IACpB,UAAU;IACV,iBAAiB;IACjB,UAAU;IACV,YAAY;IACZ,UAAU;IACV,IAAI;IACJ,OAAO;IACP,SAAS;IACT,QAAQ;IACR,WAAW;CACH,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { StandardSchema, ValidationConfig } from "..";
|
|
2
|
+
import { Id } from "../id";
|
|
3
|
+
export type EntityId = string | number;
|
|
4
|
+
export interface BaseProps {
|
|
5
|
+
id: Id;
|
|
6
|
+
}
|
|
7
|
+
interface DomainValidation<T> {
|
|
8
|
+
schema: StandardSchema<T>;
|
|
9
|
+
config?: ValidationConfig;
|
|
10
|
+
}
|
|
11
|
+
export type EntityValidation<T> = DomainValidation<T>;
|
|
12
|
+
export type VOValidation<T> = DomainValidation<T>;
|
|
13
|
+
export interface VOHooks<T, E> {
|
|
14
|
+
onBeforeUpdate?: (entity: E, snapshot: T) => boolean;
|
|
15
|
+
onCreate?: (entity: E) => void;
|
|
16
|
+
rules?: (entity: E) => void;
|
|
17
|
+
defaultValues?: Partial<T>;
|
|
18
|
+
}
|
|
19
|
+
export interface EntityHooks<T extends BaseProps, E> {
|
|
20
|
+
onBeforeUpdate?: (entity: E, snapshot: T) => boolean;
|
|
21
|
+
onCreate?: (entity: E) => void;
|
|
22
|
+
rules?: (entity: E) => void;
|
|
23
|
+
}
|
|
24
|
+
export interface EntityConstructor<T extends BaseProps, E> {
|
|
25
|
+
new (props: T): E;
|
|
26
|
+
validation?: DomainValidation<T>;
|
|
27
|
+
hooks?: EntityHooks<T, E>;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=domain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.d.ts","sourceRoot":"","sources":["../../src/types/domain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,IAAI,CAAC;AACtD,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAE3B,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;AAEvC,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,EAAE,CAAC;CACR;AAED,UAAU,gBAAgB,CAAC,CAAC;IAC1B,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC;IAC1B,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;AACtD,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAGlD,MAAM,WAAW,OAAO,CAAC,CAAC,EAAE,CAAC;IAC3B,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,OAAO,CAAC;IACrD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAC5B;AAGD,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC;IACjD,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,KAAK,OAAO,CAAC;IACrD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;IAC/B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,SAAS,EAAE,CAAC;IACvD,KAAK,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC;IAClB,UAAU,CAAC,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain.js","sourceRoot":"","sources":["../../src/types/domain.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { BaseProps } from "..";
|
|
2
|
+
import { IsArray, NonUndefined, UnwrapArray } from "./utils";
|
|
3
|
+
export interface ChangeEvent<T> {
|
|
4
|
+
previous: T | undefined;
|
|
5
|
+
current: T;
|
|
6
|
+
path: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ArrayChangeEvent<T> {
|
|
9
|
+
toCreate: T[];
|
|
10
|
+
toUpdate: T[];
|
|
11
|
+
toDelete: T[];
|
|
12
|
+
path: string;
|
|
13
|
+
}
|
|
14
|
+
export type PropertySubscriber<T> = (event: ChangeEvent<T>) => void;
|
|
15
|
+
export type ArraySubscriber<T> = (event: ArrayChangeEvent<T>) => void;
|
|
16
|
+
export interface PropertySubscription<T> {
|
|
17
|
+
onChange: PropertySubscriber<T>;
|
|
18
|
+
}
|
|
19
|
+
export interface ArraySubscription<T> {
|
|
20
|
+
onChange: ArraySubscriber<T>;
|
|
21
|
+
}
|
|
22
|
+
export type SubscriptionConfig<T extends BaseProps> = {
|
|
23
|
+
[K in keyof T]?: IsArray<NonUndefined<T[K]>> extends true ? ArraySubscription<UnwrapArray<NonUndefined<T[K]>>> : PropertySubscription<NonUndefined<T[K]>>;
|
|
24
|
+
};
|
|
25
|
+
export interface ValidationConfig {
|
|
26
|
+
onCreate?: boolean;
|
|
27
|
+
onUpdate?: boolean;
|
|
28
|
+
throwOnError?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface HistoryEntry {
|
|
31
|
+
path: string;
|
|
32
|
+
previousValue: any;
|
|
33
|
+
currentValue: any;
|
|
34
|
+
timestamp: number;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=history-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-tracker.d.ts","sourceRoot":"","sources":["../../src/types/history-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE7D,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,QAAQ,EAAE,CAAC,GAAG,SAAS,CAAC;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AACpE,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;AAEtE,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,QAAQ,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC;CAC9B;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,SAAS,IAAI;KACnD,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,GACrD,iBAAiB,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAClD,oBAAoB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC7C,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,GAAG,CAAC;IACnB,YAAY,EAAE,GAAG,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history-tracker.js","sourceRoot":"","sources":["../../src/types/history-tracker.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,SAAS,CAAC;AACxB,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Criteria } from "../criteria";
|
|
2
|
+
import { Aggregate } from "../entity";
|
|
3
|
+
import { Id } from "../id";
|
|
4
|
+
import { PaginatedResult } from "../paginated-result";
|
|
5
|
+
export interface IRepository<TDomain extends Aggregate<any>> {
|
|
6
|
+
/**
|
|
7
|
+
* Find by ID
|
|
8
|
+
*/
|
|
9
|
+
findById(id: Id): Promise<TDomain | null>;
|
|
10
|
+
/**
|
|
11
|
+
* Find using criteria (filtering, ordering, pagination)
|
|
12
|
+
*/
|
|
13
|
+
find(criteria: Criteria<TDomain>): Promise<PaginatedResult<TDomain>>;
|
|
14
|
+
/**
|
|
15
|
+
* Find all (with optional criteria)
|
|
16
|
+
*/
|
|
17
|
+
findAll(criteria?: Criteria<TDomain>): Promise<TDomain[]>;
|
|
18
|
+
/**
|
|
19
|
+
* Find one (first matching criteria)
|
|
20
|
+
*/
|
|
21
|
+
findOne(criteria: Criteria<TDomain>): Promise<TDomain | null>;
|
|
22
|
+
/**
|
|
23
|
+
* Save (insert or update based on aggregate.isNew)
|
|
24
|
+
*/
|
|
25
|
+
save(aggregate: TDomain): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Delete aggregate
|
|
28
|
+
*/
|
|
29
|
+
delete(aggregate: TDomain): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Delete by ID
|
|
32
|
+
*/
|
|
33
|
+
deleteById(id: Id): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Check if exists
|
|
36
|
+
*/
|
|
37
|
+
exists(id: Id): Promise<boolean>;
|
|
38
|
+
/**
|
|
39
|
+
* Count matching criteria
|
|
40
|
+
*/
|
|
41
|
+
count(criteria?: Criteria<TDomain>): Promise<number>;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/types/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,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,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/types/repository.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface StandardSchemaIssue {
|
|
2
|
+
message: string;
|
|
3
|
+
path?: ReadonlyArray<unknown>;
|
|
4
|
+
}
|
|
5
|
+
export interface StandardSchemaResult<T> {
|
|
6
|
+
value?: T;
|
|
7
|
+
issues?: ReadonlyArray<StandardSchemaIssue>;
|
|
8
|
+
}
|
|
9
|
+
export interface StandardSchemaProps<T> {
|
|
10
|
+
validate: (value: unknown) => StandardSchemaResult<T> | Promise<StandardSchemaResult<T>>;
|
|
11
|
+
}
|
|
12
|
+
export interface StandardSchema<T = unknown> {
|
|
13
|
+
"~standard": StandardSchemaProps<T>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=standard-schema.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard-schema.d.ts","sourceRoot":"","sources":["../../src/types/standard-schema.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,CAAC,CAAC;IACV,MAAM,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,mBAAmB,CAAC,CAAC;IACpC,QAAQ,EAAE,CACR,KAAK,EAAE,OAAO,KACX,oBAAoB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;CACjE;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,OAAO;IACzC,WAAW,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC;CACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standard-schema.js","sourceRoot":"","sources":["../../src/types/standard-schema.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { Aggregate } from "../entity";
|
|
2
|
+
import { IRepository } from "./repository";
|
|
3
|
+
/**
|
|
4
|
+
* Transaction context for Unit of Work
|
|
5
|
+
*/
|
|
6
|
+
export interface TransactionContext {
|
|
7
|
+
/**
|
|
8
|
+
* Commit all changes
|
|
9
|
+
*/
|
|
10
|
+
commit(): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Rollback all changes
|
|
13
|
+
*/
|
|
14
|
+
rollback(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Check if transaction is active
|
|
17
|
+
*/
|
|
18
|
+
isActive(): boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Unit of Work interface
|
|
22
|
+
* Manages transactions across multiple repositories
|
|
23
|
+
*/
|
|
24
|
+
export interface IUnitOfWork {
|
|
25
|
+
/**
|
|
26
|
+
* Start a new transaction
|
|
27
|
+
*/
|
|
28
|
+
begin(): Promise<TransactionContext>;
|
|
29
|
+
/**
|
|
30
|
+
* Execute work within a transaction
|
|
31
|
+
* Auto-commits on success, rolls back on error
|
|
32
|
+
*/
|
|
33
|
+
transaction<T>(work: (ctx: TransactionContext) => Promise<T>): Promise<T>;
|
|
34
|
+
/**
|
|
35
|
+
* Get repository within transaction context
|
|
36
|
+
*/
|
|
37
|
+
getRepository<TDomain extends Aggregate<any>>(repository: new (...args: any[]) => IRepository<TDomain>): IRepository<TDomain>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=unit-of-work.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unit-of-work.d.ts","sourceRoot":"","sources":["../../src/types/unit-of-work.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C;;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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unit-of-work.js","sourceRoot":"","sources":["../../src/types/unit-of-work.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Id } from "../id";
|
|
2
|
+
export type DeepJsonResult<T> = {
|
|
3
|
+
[K in keyof T]: T[K] extends Id ? string : T[K] extends {
|
|
4
|
+
toJson(): infer U;
|
|
5
|
+
} ? U : T[K] extends Array<infer U> ? U extends {
|
|
6
|
+
toJson(): infer V;
|
|
7
|
+
} ? V[] : U extends Id ? string[] : U[] : T[K];
|
|
8
|
+
};
|
|
9
|
+
export type DeepKeyOf<T, K extends keyof T = keyof T> = K extends string ? T[K] extends Primitive ? K : T[K] extends object ? `${K}` | `${K}.${DeepKeyOf<T[K]>}` : never : never;
|
|
10
|
+
export type Primitive = string | number | boolean | Date | null | undefined;
|
|
11
|
+
export type UnwrapArray<T> = T extends Array<infer U> ? U : never;
|
|
12
|
+
export type IsArray<T> = T extends Array<any> ? true : false;
|
|
13
|
+
export type NonUndefined<T> = T extends undefined ? never : T;
|
|
14
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/types/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAE3B,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI;KAC7B,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,GAC3B,MAAM,GACN,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,MAAM,IAAI,MAAM,CAAC,CAAA;KAAE,GAClC,CAAC,GACD,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GAC3B,CAAC,SAAS;QAAE,MAAM,IAAI,MAAM,CAAC,CAAA;KAAE,GAC7B,CAAC,EAAE,GACH,CAAC,SAAS,EAAE,GACZ,MAAM,EAAE,GACR,CAAC,EAAE,GACL,CAAC,CAAC,CAAC,CAAC;CACT,CAAC;AAEF,MAAM,MAAM,SAAS,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,MAAM,GACpE,CAAC,CAAC,CAAC,CAAC,SAAS,SAAS,GACpB,CAAC,GACD,CAAC,CAAC,CAAC,CAAC,SAAS,MAAM,GACnB,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAClC,KAAK,GACP,KAAK,CAAC;AAEV,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;AAE5E,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAClE,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,KAAK,CAAC;AAC7D,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,SAAS,SAAS,GAAG,KAAK,GAAG,CAAC,CAAC"}
|