@cqrs-ddd/core 0.2.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.
- package/COMMERCIAL_LICENSE.txt +34 -0
- package/LICENSE +661 -0
- package/README.md +707 -0
- package/dist/application/base.command.d.ts +44 -0
- package/dist/application/base.command.d.ts.map +1 -0
- package/dist/application/base.command.js +58 -0
- package/dist/application/base.command.js.map +1 -0
- package/dist/application/base.query.d.ts +42 -0
- package/dist/application/base.query.d.ts.map +1 -0
- package/dist/application/base.query.js +52 -0
- package/dist/application/base.query.js.map +1 -0
- package/dist/application/command-base.handler.d.ts +106 -0
- package/dist/application/command-base.handler.d.ts.map +1 -0
- package/dist/application/command-base.handler.js +119 -0
- package/dist/application/command-base.handler.js.map +1 -0
- package/dist/application/index.d.ts +16 -0
- package/dist/application/index.d.ts.map +1 -0
- package/dist/application/index.js +33 -0
- package/dist/application/index.js.map +1 -0
- package/dist/application/ports/cache.port.d.ts +104 -0
- package/dist/application/ports/cache.port.d.ts.map +1 -0
- package/dist/application/ports/cache.port.js +17 -0
- package/dist/application/ports/cache.port.js.map +1 -0
- package/dist/application/ports/command-repository.port.d.ts +28 -0
- package/dist/application/ports/command-repository.port.d.ts.map +1 -0
- package/dist/application/ports/command-repository.port.js +4 -0
- package/dist/application/ports/command-repository.port.js.map +1 -0
- package/dist/application/ports/domain-event-publisher.port.d.ts +18 -0
- package/dist/application/ports/domain-event-publisher.port.d.ts.map +1 -0
- package/dist/application/ports/domain-event-publisher.port.js +4 -0
- package/dist/application/ports/domain-event-publisher.port.js.map +1 -0
- package/dist/application/ports/query-repository.port.d.ts +26 -0
- package/dist/application/ports/query-repository.port.d.ts.map +1 -0
- package/dist/application/ports/query-repository.port.js +4 -0
- package/dist/application/ports/query-repository.port.js.map +1 -0
- package/dist/application/ports/write-side-aggregate-repository.port.d.ts +33 -0
- package/dist/application/ports/write-side-aggregate-repository.port.d.ts.map +1 -0
- package/dist/application/ports/write-side-aggregate-repository.port.js +4 -0
- package/dist/application/ports/write-side-aggregate-repository.port.js.map +1 -0
- package/dist/application/query.options.d.ts +22 -0
- package/dist/application/query.options.d.ts.map +1 -0
- package/dist/application/query.options.js +4 -0
- package/dist/application/query.options.js.map +1 -0
- package/dist/application/request-fields.helper.d.ts +5 -0
- package/dist/application/request-fields.helper.d.ts.map +1 -0
- package/dist/application/request-fields.helper.js +20 -0
- package/dist/application/request-fields.helper.js.map +1 -0
- package/dist/application/tenant-resolver.d.ts +56 -0
- package/dist/application/tenant-resolver.d.ts.map +1 -0
- package/dist/application/tenant-resolver.js +60 -0
- package/dist/application/tenant-resolver.js.map +1 -0
- package/dist/domain/decorators/apply-mutation.decorator.d.ts +64 -0
- package/dist/domain/decorators/apply-mutation.decorator.d.ts.map +1 -0
- package/dist/domain/decorators/apply-mutation.decorator.js +86 -0
- package/dist/domain/decorators/apply-mutation.decorator.js.map +1 -0
- package/dist/domain/decorators/mutable.decorator.d.ts +54 -0
- package/dist/domain/decorators/mutable.decorator.d.ts.map +1 -0
- package/dist/domain/decorators/mutable.decorator.js +76 -0
- package/dist/domain/decorators/mutable.decorator.js.map +1 -0
- package/dist/domain/events/domain.event.d.ts +13 -0
- package/dist/domain/events/domain.event.d.ts.map +1 -0
- package/dist/domain/events/domain.event.js +20 -0
- package/dist/domain/events/domain.event.js.map +1 -0
- package/dist/domain/events/event.interface.d.ts +9 -0
- package/dist/domain/events/event.interface.d.ts.map +1 -0
- package/dist/domain/events/event.interface.js +4 -0
- package/dist/domain/events/event.interface.js.map +1 -0
- package/dist/domain/events/root-domain.event.d.ts +50 -0
- package/dist/domain/events/root-domain.event.d.ts.map +1 -0
- package/dist/domain/events/root-domain.event.js +156 -0
- package/dist/domain/events/root-domain.event.js.map +1 -0
- package/dist/domain/exceptions/concurrency-conflict.error.d.ts +20 -0
- package/dist/domain/exceptions/concurrency-conflict.error.d.ts.map +1 -0
- package/dist/domain/exceptions/concurrency-conflict.error.js +32 -0
- package/dist/domain/exceptions/concurrency-conflict.error.js.map +1 -0
- package/dist/domain/exceptions/domain.exception.d.ts +30 -0
- package/dist/domain/exceptions/domain.exception.d.ts.map +1 -0
- package/dist/domain/exceptions/domain.exception.js +39 -0
- package/dist/domain/exceptions/domain.exception.js.map +1 -0
- package/dist/domain/exceptions/entity-not-found.exception.d.ts +14 -0
- package/dist/domain/exceptions/entity-not-found.exception.d.ts.map +1 -0
- package/dist/domain/exceptions/entity-not-found.exception.js +23 -0
- package/dist/domain/exceptions/entity-not-found.exception.js.map +1 -0
- package/dist/domain/exceptions/invalid-value.exception.d.ts +35 -0
- package/dist/domain/exceptions/invalid-value.exception.d.ts.map +1 -0
- package/dist/domain/exceptions/invalid-value.exception.js +67 -0
- package/dist/domain/exceptions/invalid-value.exception.js.map +1 -0
- package/dist/domain/exceptions/missing-tenant-context.exception.d.ts +24 -0
- package/dist/domain/exceptions/missing-tenant-context.exception.d.ts.map +1 -0
- package/dist/domain/exceptions/missing-tenant-context.exception.js +33 -0
- package/dist/domain/exceptions/missing-tenant-context.exception.js.map +1 -0
- package/dist/domain/exceptions/transient-operation.error.d.ts +17 -0
- package/dist/domain/exceptions/transient-operation.error.d.ts.map +1 -0
- package/dist/domain/exceptions/transient-operation.error.js +27 -0
- package/dist/domain/exceptions/transient-operation.error.js.map +1 -0
- package/dist/domain/exceptions/unknown-mutable-field.error.d.ts +14 -0
- package/dist/domain/exceptions/unknown-mutable-field.error.d.ts.map +1 -0
- package/dist/domain/exceptions/unknown-mutable-field.error.js +24 -0
- package/dist/domain/exceptions/unknown-mutable-field.error.js.map +1 -0
- package/dist/domain/index.d.ts +26 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +43 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/interfaces/root-entity-snapshot.interface.d.ts +7 -0
- package/dist/domain/interfaces/root-entity-snapshot.interface.d.ts.map +1 -0
- package/dist/domain/interfaces/root-entity-snapshot.interface.js +4 -0
- package/dist/domain/interfaces/root-entity-snapshot.interface.js.map +1 -0
- package/dist/domain/models/aggregate-root.d.ts +87 -0
- package/dist/domain/models/aggregate-root.d.ts.map +1 -0
- package/dist/domain/models/aggregate-root.js +122 -0
- package/dist/domain/models/aggregate-root.js.map +1 -0
- package/dist/domain/models/root.entity.d.ts +208 -0
- package/dist/domain/models/root.entity.d.ts.map +1 -0
- package/dist/domain/models/root.entity.js +350 -0
- package/dist/domain/models/root.entity.js.map +1 -0
- package/dist/domain/rules/number.rule.d.ts +81 -0
- package/dist/domain/rules/number.rule.d.ts.map +1 -0
- package/dist/domain/rules/number.rule.js +81 -0
- package/dist/domain/rules/number.rule.js.map +1 -0
- package/dist/domain/rules/rule-support.d.ts +6 -0
- package/dist/domain/rules/rule-support.d.ts.map +1 -0
- package/dist/domain/rules/rule-support.js +19 -0
- package/dist/domain/rules/rule-support.js.map +1 -0
- package/dist/domain/rules/text.rule.d.ts +98 -0
- package/dist/domain/rules/text.rule.d.ts.map +1 -0
- package/dist/domain/rules/text.rule.js +103 -0
- package/dist/domain/rules/text.rule.js.map +1 -0
- package/dist/domain/rules/value-violation.d.ts +44 -0
- package/dist/domain/rules/value-violation.d.ts.map +1 -0
- package/dist/domain/rules/value-violation.js +4 -0
- package/dist/domain/rules/value-violation.js.map +1 -0
- package/dist/http/domain-error-http-status.d.ts +43 -0
- package/dist/http/domain-error-http-status.d.ts.map +1 -0
- package/dist/http/domain-error-http-status.js +27 -0
- package/dist/http/domain-error-http-status.js.map +1 -0
- package/dist/http/index.d.ts +9 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +26 -0
- package/dist/http/index.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/persistence/cache/cache-logger.d.ts +29 -0
- package/dist/persistence/cache/cache-logger.d.ts.map +1 -0
- package/dist/persistence/cache/cache-logger.js +23 -0
- package/dist/persistence/cache/cache-logger.js.map +1 -0
- package/dist/persistence/cache/memory.cache.d.ts +72 -0
- package/dist/persistence/cache/memory.cache.d.ts.map +1 -0
- package/dist/persistence/cache/memory.cache.js +183 -0
- package/dist/persistence/cache/memory.cache.js.map +1 -0
- package/dist/persistence/command-repository.abstract.d.ts +39 -0
- package/dist/persistence/command-repository.abstract.d.ts.map +1 -0
- package/dist/persistence/command-repository.abstract.js +43 -0
- package/dist/persistence/command-repository.abstract.js.map +1 -0
- package/dist/persistence/decorators/acknowledge-persisted.decorator.d.ts +82 -0
- package/dist/persistence/decorators/acknowledge-persisted.decorator.d.ts.map +1 -0
- package/dist/persistence/decorators/acknowledge-persisted.decorator.js +82 -0
- package/dist/persistence/decorators/acknowledge-persisted.decorator.js.map +1 -0
- package/dist/persistence/decorators/cache.decorator.d.ts +93 -0
- package/dist/persistence/decorators/cache.decorator.d.ts.map +1 -0
- package/dist/persistence/decorators/cache.decorator.js +200 -0
- package/dist/persistence/decorators/cache.decorator.js.map +1 -0
- package/dist/persistence/decorators/from-cache.decorator.d.ts +65 -0
- package/dist/persistence/decorators/from-cache.decorator.d.ts.map +1 -0
- package/dist/persistence/decorators/from-cache.decorator.js +165 -0
- package/dist/persistence/decorators/from-cache.decorator.js.map +1 -0
- package/dist/persistence/decorators/map-persistence-errors.decorator.d.ts +88 -0
- package/dist/persistence/decorators/map-persistence-errors.decorator.d.ts.map +1 -0
- package/dist/persistence/decorators/map-persistence-errors.decorator.js +89 -0
- package/dist/persistence/decorators/map-persistence-errors.decorator.js.map +1 -0
- package/dist/persistence/decorators/persisted-write.decorator.d.ts +61 -0
- package/dist/persistence/decorators/persisted-write.decorator.d.ts.map +1 -0
- package/dist/persistence/decorators/persisted-write.decorator.js +57 -0
- package/dist/persistence/decorators/persisted-write.decorator.js.map +1 -0
- package/dist/persistence/helpers/cache-barrier.helper.d.ts +70 -0
- package/dist/persistence/helpers/cache-barrier.helper.d.ts.map +1 -0
- package/dist/persistence/helpers/cache-barrier.helper.js +57 -0
- package/dist/persistence/helpers/cache-barrier.helper.js.map +1 -0
- package/dist/persistence/helpers/cache-key.helper.d.ts +73 -0
- package/dist/persistence/helpers/cache-key.helper.d.ts.map +1 -0
- package/dist/persistence/helpers/cache-key.helper.js +132 -0
- package/dist/persistence/helpers/cache-key.helper.js.map +1 -0
- package/dist/persistence/helpers/cache-owner.helper.d.ts +9 -0
- package/dist/persistence/helpers/cache-owner.helper.d.ts.map +1 -0
- package/dist/persistence/helpers/cache-owner.helper.js +22 -0
- package/dist/persistence/helpers/cache-owner.helper.js.map +1 -0
- package/dist/persistence/helpers/cache-snapshot.helper.d.ts +28 -0
- package/dist/persistence/helpers/cache-snapshot.helper.d.ts.map +1 -0
- package/dist/persistence/helpers/cache-snapshot.helper.js +42 -0
- package/dist/persistence/helpers/cache-snapshot.helper.js.map +1 -0
- package/dist/persistence/helpers/cache-version.helper.d.ts +29 -0
- package/dist/persistence/helpers/cache-version.helper.d.ts.map +1 -0
- package/dist/persistence/helpers/cache-version.helper.js +71 -0
- package/dist/persistence/helpers/cache-version.helper.js.map +1 -0
- package/dist/persistence/index.d.ts +23 -0
- package/dist/persistence/index.d.ts.map +1 -0
- package/dist/persistence/index.js +40 -0
- package/dist/persistence/index.js.map +1 -0
- package/dist/persistence/persistence-dialect.d.ts +35 -0
- package/dist/persistence/persistence-dialect.d.ts.map +1 -0
- package/dist/persistence/persistence-dialect.js +31 -0
- package/dist/persistence/persistence-dialect.js.map +1 -0
- package/dist/persistence/query-repository.abstract.d.ts +76 -0
- package/dist/persistence/query-repository.abstract.d.ts.map +1 -0
- package/dist/persistence/query-repository.abstract.js +67 -0
- package/dist/persistence/query-repository.abstract.js.map +1 -0
- package/dist/types/Method.type.d.ts +2 -0
- package/dist/types/Method.type.d.ts.map +1 -0
- package/dist/types/Method.type.js +4 -0
- package/dist/types/Method.type.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.InvalidValueException = void 0;
|
|
5
|
+
const domain_exception_1 = require("./domain.exception");
|
|
6
|
+
function describeViolation(violation) {
|
|
7
|
+
const { field } = violation;
|
|
8
|
+
switch (violation.rule) {
|
|
9
|
+
case 'required':
|
|
10
|
+
return `${field} is required.`;
|
|
11
|
+
case 'type':
|
|
12
|
+
return `${field} must be a ${violation.expected}.`;
|
|
13
|
+
case 'characters':
|
|
14
|
+
return `${field} must not contain control characters or unpaired surrogates.`;
|
|
15
|
+
case 'minLength':
|
|
16
|
+
return `${field} must be at least ${violation.limit} characters.`;
|
|
17
|
+
case 'maxLength':
|
|
18
|
+
return `${field} must be at most ${violation.limit} characters.`;
|
|
19
|
+
case 'pattern':
|
|
20
|
+
return `${field} does not match the required format.`;
|
|
21
|
+
case 'finite':
|
|
22
|
+
return `${field} must be a finite number.`;
|
|
23
|
+
case 'integer':
|
|
24
|
+
return `${field} must be a safe integer.`;
|
|
25
|
+
case 'min':
|
|
26
|
+
return `${field} must be at least ${violation.limit}.`;
|
|
27
|
+
case 'max':
|
|
28
|
+
return `${field} must be at most ${violation.limit}.`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* A value broke a rule of a {@link textRule} or {@link numberRule}.
|
|
33
|
+
*
|
|
34
|
+
* It is the error both rules throw by default, and the base class for an
|
|
35
|
+
* application's own exceptions, which then share its message format and its
|
|
36
|
+
* `violation`. `domainErrorHttpStatus()` answers 400 for it, like any other
|
|
37
|
+
* `DomainException`.
|
|
38
|
+
*
|
|
39
|
+
* The rejected value is not kept, so logging the exception cannot leak it.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* export class InvalidUsernameException extends InvalidValueException {}
|
|
44
|
+
*
|
|
45
|
+
* const username = textRule({
|
|
46
|
+
* field: 'username',
|
|
47
|
+
* minLength: 3,
|
|
48
|
+
* error: (violation) => new InvalidUsernameException(violation),
|
|
49
|
+
* });
|
|
50
|
+
*
|
|
51
|
+
* username.normalize('ab');
|
|
52
|
+
* // throws InvalidUsernameException: "username must be at least 3 characters."
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
class InvalidValueException extends domain_exception_1.DomainException {
|
|
56
|
+
violation;
|
|
57
|
+
/**
|
|
58
|
+
* @param violation - The broken rule.
|
|
59
|
+
* @param message - Replaces the default message built from `violation`.
|
|
60
|
+
*/
|
|
61
|
+
constructor(violation, message) {
|
|
62
|
+
super(message ?? describeViolation(violation));
|
|
63
|
+
this.violation = violation;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.InvalidValueException = InvalidValueException;
|
|
67
|
+
//# sourceMappingURL=invalid-value.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invalid-value.exception.js","sourceRoot":"","sources":["../../../domain/exceptions/invalid-value.exception.ts"],"names":[],"mappings":";AAAA,sEAAsE;;;AAGtE,yDAAqD;AAErD,SAAS,iBAAiB,CAAC,SAAyB;IAClD,MAAM,EAAE,KAAK,EAAE,GAAG,SAAS,CAAC;IAC5B,QAAQ,SAAS,CAAC,IAAI,EAAE,CAAC;QACvB,KAAK,UAAU;YACb,OAAO,GAAG,KAAK,eAAe,CAAC;QACjC,KAAK,MAAM;YACT,OAAO,GAAG,KAAK,cAAc,SAAS,CAAC,QAAQ,GAAG,CAAC;QACrD,KAAK,YAAY;YACf,OAAO,GAAG,KAAK,8DAA8D,CAAC;QAChF,KAAK,WAAW;YACd,OAAO,GAAG,KAAK,qBAAqB,SAAS,CAAC,KAAK,cAAc,CAAC;QACpE,KAAK,WAAW;YACd,OAAO,GAAG,KAAK,oBAAoB,SAAS,CAAC,KAAK,cAAc,CAAC;QACnE,KAAK,SAAS;YACZ,OAAO,GAAG,KAAK,sCAAsC,CAAC;QACxD,KAAK,QAAQ;YACX,OAAO,GAAG,KAAK,2BAA2B,CAAC;QAC7C,KAAK,SAAS;YACZ,OAAO,GAAG,KAAK,0BAA0B,CAAC;QAC5C,KAAK,KAAK;YACR,OAAO,GAAG,KAAK,qBAAqB,SAAS,CAAC,KAAK,GAAG,CAAC;QACzD,KAAK,KAAK;YACR,OAAO,GAAG,KAAK,oBAAoB,SAAS,CAAC,KAAK,GAAG,CAAC;IAC1D,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAa,qBAAsB,SAAQ,kCAAe;IAC/C,SAAS,CAAiB;IAEnC;;;OAGG;IACH,YAAY,SAAyB,EAAE,OAAgB;QACrD,KAAK,CAAC,OAAO,IAAI,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;QAC/C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAXD,sDAWC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { DomainException } from './domain.exception';
|
|
2
|
+
/**
|
|
3
|
+
* Framework-neutral signal that an operation requiring tenant isolation was
|
|
4
|
+
* attempted without a resolvable tenant identity.
|
|
5
|
+
*
|
|
6
|
+
* Tenant-scoped operations fail closed here. A missing tenant must never be
|
|
7
|
+
* collapsed into a shared or default tenant: every caller whose tenant could not
|
|
8
|
+
* be resolved would then read and write the same cache entries or database,
|
|
9
|
+
* which is a cross-tenant data leak that produces no error and no log line.
|
|
10
|
+
*
|
|
11
|
+
* Deployments that are genuinely single-tenant make that explicit rather than
|
|
12
|
+
* implicit: pass a fixed tenant id to the key helper, or register
|
|
13
|
+
* `setTenantResolver(() => 'single')`, so the decision is visible in code.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* if (!tenantId) throw new MissingTenantContextError('users.create idempotency key');
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class MissingTenantContextError extends DomainException {
|
|
21
|
+
readonly operation: string;
|
|
22
|
+
constructor(operation: string);
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=missing-tenant-context.exception.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missing-tenant-context.exception.d.ts","sourceRoot":"","sources":["../../../domain/exceptions/missing-tenant-context.exception.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,yBAA0B,SAAQ,eAAe;IAChD,QAAQ,CAAC,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAMvC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.MissingTenantContextError = void 0;
|
|
5
|
+
const domain_exception_1 = require("./domain.exception");
|
|
6
|
+
/**
|
|
7
|
+
* Framework-neutral signal that an operation requiring tenant isolation was
|
|
8
|
+
* attempted without a resolvable tenant identity.
|
|
9
|
+
*
|
|
10
|
+
* Tenant-scoped operations fail closed here. A missing tenant must never be
|
|
11
|
+
* collapsed into a shared or default tenant: every caller whose tenant could not
|
|
12
|
+
* be resolved would then read and write the same cache entries or database,
|
|
13
|
+
* which is a cross-tenant data leak that produces no error and no log line.
|
|
14
|
+
*
|
|
15
|
+
* Deployments that are genuinely single-tenant make that explicit rather than
|
|
16
|
+
* implicit: pass a fixed tenant id to the key helper, or register
|
|
17
|
+
* `setTenantResolver(() => 'single')`, so the decision is visible in code.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* if (!tenantId) throw new MissingTenantContextError('users.create idempotency key');
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
class MissingTenantContextError extends domain_exception_1.DomainException {
|
|
25
|
+
operation;
|
|
26
|
+
constructor(operation) {
|
|
27
|
+
super(`Missing tenant context for ${operation}. Run it inside a tenant scope or pass ` +
|
|
28
|
+
'the tenant explicitly; it never falls back to a shared or default tenant.');
|
|
29
|
+
this.operation = operation;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.MissingTenantContextError = MissingTenantContextError;
|
|
33
|
+
//# sourceMappingURL=missing-tenant-context.exception.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"missing-tenant-context.exception.js","sourceRoot":"","sources":["../../../domain/exceptions/missing-tenant-context.exception.ts"],"names":[],"mappings":";AAAA,sEAAsE;;;AAEtE,yDAAqD;AAErD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAa,yBAA0B,SAAQ,kCAAe;IACvC;IAArB,YAAqB,SAAiB;QACpC,KAAK,CACH,8BAA8B,SAAS,yCAAyC;YAC9E,2EAA2E,CAC9E,CAAC;QAJiB,cAAS,GAAT,SAAS,CAAQ;IAKtC,CAAC;CACF;AAPD,8DAOC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework- and infrastructure-neutral signal that an application operation
|
|
3
|
+
* failed for a reason the configured resilience policy may retry.
|
|
4
|
+
*
|
|
5
|
+
* Infrastructure adapters are responsible for translating their own transient
|
|
6
|
+
* failures into this error. Application handlers do not inspect database,
|
|
7
|
+
* driver, network, or transport-specific error codes.
|
|
8
|
+
*/
|
|
9
|
+
export declare class TransientOperationError extends Error {
|
|
10
|
+
readonly cause?: unknown;
|
|
11
|
+
constructor(message: string, options?: {
|
|
12
|
+
cause?: unknown;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
/** True when `error` is a TransientOperationError. */
|
|
16
|
+
export declare function isTransientOperationError(error: unknown): error is TransientOperationError;
|
|
17
|
+
//# sourceMappingURL=transient-operation.error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transient-operation.error.d.ts","sourceRoot":"","sources":["../../../domain/exceptions/transient-operation.error.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,qBAAa,uBAAwB,SAAQ,KAAK;IAChD,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;gBAEb,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAK3D;AAED,sDAAsD;AACtD,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,uBAAuB,CAElC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.TransientOperationError = void 0;
|
|
5
|
+
exports.isTransientOperationError = isTransientOperationError;
|
|
6
|
+
/**
|
|
7
|
+
* Framework- and infrastructure-neutral signal that an application operation
|
|
8
|
+
* failed for a reason the configured resilience policy may retry.
|
|
9
|
+
*
|
|
10
|
+
* Infrastructure adapters are responsible for translating their own transient
|
|
11
|
+
* failures into this error. Application handlers do not inspect database,
|
|
12
|
+
* driver, network, or transport-specific error codes.
|
|
13
|
+
*/
|
|
14
|
+
class TransientOperationError extends Error {
|
|
15
|
+
cause;
|
|
16
|
+
constructor(message, options) {
|
|
17
|
+
super(message);
|
|
18
|
+
this.name = TransientOperationError.name;
|
|
19
|
+
this.cause = options?.cause;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.TransientOperationError = TransientOperationError;
|
|
23
|
+
/** True when `error` is a TransientOperationError. */
|
|
24
|
+
function isTransientOperationError(error) {
|
|
25
|
+
return error instanceof TransientOperationError;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=transient-operation.error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transient-operation.error.js","sourceRoot":"","sources":["../../../domain/exceptions/transient-operation.error.ts"],"names":[],"mappings":";AAAA,sEAAsE;;;AAqBtE,8DAIC;AAvBD;;;;;;;GAOG;AACH,MAAa,uBAAwB,SAAQ,KAAK;IACvC,KAAK,CAAW;IAEzB,YAAY,OAAe,EAAE,OAA6B;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC,IAAI,CAAC;QACzC,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,CAAC;IAC9B,CAAC;CACF;AARD,0DAQC;AAED,sDAAsD;AACtD,SAAgB,yBAAyB,CACvC,KAAc;IAEd,OAAO,KAAK,YAAY,uBAAuB,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raised when `applyPatch()` receives a patch key that the aggregate has
|
|
3
|
+
* not declared with `@Mutable()`.
|
|
4
|
+
*
|
|
5
|
+
* This is a wiring defect, not a domain rule violation: the mutation names a
|
|
6
|
+
* field the aggregate does not expose for mutation, so nothing is written, no
|
|
7
|
+
* version is advanced and no event is recorded.
|
|
8
|
+
*/
|
|
9
|
+
export declare class UnknownMutableFieldError extends Error {
|
|
10
|
+
readonly aggregate: string;
|
|
11
|
+
readonly field: string;
|
|
12
|
+
constructor(aggregate: string, field: string, known: readonly string[]);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=unknown-mutable-field.error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unknown-mutable-field.error.d.ts","sourceRoot":"","sources":["../../../domain/exceptions/unknown-mutable-field.error.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE;CAUvE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.UnknownMutableFieldError = void 0;
|
|
5
|
+
/**
|
|
6
|
+
* Raised when `applyPatch()` receives a patch key that the aggregate has
|
|
7
|
+
* not declared with `@Mutable()`.
|
|
8
|
+
*
|
|
9
|
+
* This is a wiring defect, not a domain rule violation: the mutation names a
|
|
10
|
+
* field the aggregate does not expose for mutation, so nothing is written, no
|
|
11
|
+
* version is advanced and no event is recorded.
|
|
12
|
+
*/
|
|
13
|
+
class UnknownMutableFieldError extends Error {
|
|
14
|
+
aggregate;
|
|
15
|
+
field;
|
|
16
|
+
constructor(aggregate, field, known) {
|
|
17
|
+
super(`${aggregate} does not declare '${field}' as a mutable field. Declare it with @Mutable() or remove it from the mutation patch. Known mutable fields: ${known.length > 0 ? known.join(', ') : '(none)'}.`);
|
|
18
|
+
this.name = UnknownMutableFieldError.name;
|
|
19
|
+
this.aggregate = aggregate;
|
|
20
|
+
this.field = field;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.UnknownMutableFieldError = UnknownMutableFieldError;
|
|
24
|
+
//# sourceMappingURL=unknown-mutable-field.error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unknown-mutable-field.error.js","sourceRoot":"","sources":["../../../domain/exceptions/unknown-mutable-field.error.ts"],"names":[],"mappings":";AAAA,sEAAsE;;;AAEtE;;;;;;;GAOG;AACH,MAAa,wBAAyB,SAAQ,KAAK;IACxC,SAAS,CAAS;IAClB,KAAK,CAAS;IAEvB,YAAY,SAAiB,EAAE,KAAa,EAAE,KAAwB;QACpE,KAAK,CACH,GAAG,SAAS,sBAAsB,KAAK,gHACrC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QACxC,GAAG,CACJ,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC,IAAI,CAAC;QAC1C,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAdD,4DAcC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain primitives. Free of ORM and persistence dependencies.
|
|
3
|
+
*
|
|
4
|
+
* Import from here — `@cqrs-ddd/core/domain` — in domain code, so a
|
|
5
|
+
* file that only needs `DomainException` does not pull the persistence layer in
|
|
6
|
+
* behind it.
|
|
7
|
+
*/
|
|
8
|
+
export * from './decorators/apply-mutation.decorator';
|
|
9
|
+
export * from './decorators/mutable.decorator';
|
|
10
|
+
export * from './events/domain.event';
|
|
11
|
+
export * from './events/event.interface';
|
|
12
|
+
export * from './events/root-domain.event';
|
|
13
|
+
export * from './exceptions/concurrency-conflict.error';
|
|
14
|
+
export * from './exceptions/domain.exception';
|
|
15
|
+
export * from './exceptions/entity-not-found.exception';
|
|
16
|
+
export * from './exceptions/invalid-value.exception';
|
|
17
|
+
export * from './exceptions/missing-tenant-context.exception';
|
|
18
|
+
export * from './exceptions/transient-operation.error';
|
|
19
|
+
export * from './exceptions/unknown-mutable-field.error';
|
|
20
|
+
export * from './interfaces/root-entity-snapshot.interface';
|
|
21
|
+
export * from './models/aggregate-root';
|
|
22
|
+
export * from './models/root.entity';
|
|
23
|
+
export * from './rules/number.rule';
|
|
24
|
+
export * from './rules/text.rule';
|
|
25
|
+
export * from './rules/value-violation';
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../domain/index.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AAEH,cAAc,uCAAuC,CAAC;AACtD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;AACxD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yCAAyC,CAAC;AACxD,cAAc,sCAAsC,CAAC;AACrD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,wCAAwC,CAAC;AACvD,cAAc,0CAA0C,CAAC;AACzD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license. */
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
15
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
16
|
+
};
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
/**
|
|
19
|
+
* Domain primitives. Free of ORM and persistence dependencies.
|
|
20
|
+
*
|
|
21
|
+
* Import from here — `@cqrs-ddd/core/domain` — in domain code, so a
|
|
22
|
+
* file that only needs `DomainException` does not pull the persistence layer in
|
|
23
|
+
* behind it.
|
|
24
|
+
*/
|
|
25
|
+
__exportStar(require("./decorators/apply-mutation.decorator"), exports);
|
|
26
|
+
__exportStar(require("./decorators/mutable.decorator"), exports);
|
|
27
|
+
__exportStar(require("./events/domain.event"), exports);
|
|
28
|
+
__exportStar(require("./events/event.interface"), exports);
|
|
29
|
+
__exportStar(require("./events/root-domain.event"), exports);
|
|
30
|
+
__exportStar(require("./exceptions/concurrency-conflict.error"), exports);
|
|
31
|
+
__exportStar(require("./exceptions/domain.exception"), exports);
|
|
32
|
+
__exportStar(require("./exceptions/entity-not-found.exception"), exports);
|
|
33
|
+
__exportStar(require("./exceptions/invalid-value.exception"), exports);
|
|
34
|
+
__exportStar(require("./exceptions/missing-tenant-context.exception"), exports);
|
|
35
|
+
__exportStar(require("./exceptions/transient-operation.error"), exports);
|
|
36
|
+
__exportStar(require("./exceptions/unknown-mutable-field.error"), exports);
|
|
37
|
+
__exportStar(require("./interfaces/root-entity-snapshot.interface"), exports);
|
|
38
|
+
__exportStar(require("./models/aggregate-root"), exports);
|
|
39
|
+
__exportStar(require("./models/root.entity"), exports);
|
|
40
|
+
__exportStar(require("./rules/number.rule"), exports);
|
|
41
|
+
__exportStar(require("./rules/text.rule"), exports);
|
|
42
|
+
__exportStar(require("./rules/value-violation"), exports);
|
|
43
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../domain/index.ts"],"names":[],"mappings":";AAAA,sEAAsE;;;;;;;;;;;;;;;;AAEtE;;;;;;GAMG;AAEH,wEAAsD;AACtD,iEAA+C;AAC/C,wDAAsC;AACtC,2DAAyC;AACzC,6DAA2C;AAC3C,0EAAwD;AACxD,gEAA8C;AAC9C,0EAAwD;AACxD,uEAAqD;AACrD,gFAA8D;AAC9D,yEAAuD;AACvD,2EAAyD;AACzD,8EAA4D;AAC5D,0DAAwC;AACxC,uDAAqC;AACrC,sDAAoC;AACpC,oDAAkC;AAClC,0DAAwC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root-entity-snapshot.interface.d.ts","sourceRoot":"","sources":["../../../domain/interfaces/root-entity-snapshot.interface.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root-entity-snapshot.interface.js","sourceRoot":"","sources":["../../../domain/interfaces/root-entity-snapshot.interface.ts"],"names":[],"mappings":";AAAA,sEAAsE"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { IEvent } from '../events/event.interface';
|
|
2
|
+
declare const INTERNAL_EVENTS: unique symbol;
|
|
3
|
+
declare const IS_AUTO_COMMIT_ENABLED: unique symbol;
|
|
4
|
+
/**
|
|
5
|
+
* Options for applying an event to an aggregate root.
|
|
6
|
+
*/
|
|
7
|
+
export interface ApplyEventOptions {
|
|
8
|
+
/**
|
|
9
|
+
* Whether the event originates from historical rehydration.
|
|
10
|
+
* If true, the event will not be buffered into uncommitted events.
|
|
11
|
+
*/
|
|
12
|
+
readonly fromHistory?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Whether to skip calling the corresponding `on<EventName>` handler.
|
|
15
|
+
*/
|
|
16
|
+
readonly skipHandler?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Abstract base class representing a Domain-Driven Design (DDD) aggregate root.
|
|
20
|
+
*
|
|
21
|
+
* Provides a framework-neutral event buffering lifecycle:
|
|
22
|
+
* - Records uncommitted domain events via {@link apply}.
|
|
23
|
+
* - Dispatches events to optional `on<EventName>` instance handlers for internal state updates.
|
|
24
|
+
* - Supports state rehydration via {@link loadFromHistory}.
|
|
25
|
+
* - Exposes buffered events via {@link getUncommittedEvents} for out-of-band application dispatch.
|
|
26
|
+
* - Clears buffered events via {@link uncommit} once reliably persisted or published.
|
|
27
|
+
*
|
|
28
|
+
* @template EventBase The base event type, defaults to {@link IEvent}.
|
|
29
|
+
*/
|
|
30
|
+
export declare abstract class AggregateRoot<EventBase extends IEvent = IEvent> {
|
|
31
|
+
private [IS_AUTO_COMMIT_ENABLED];
|
|
32
|
+
private readonly [INTERNAL_EVENTS];
|
|
33
|
+
/**
|
|
34
|
+
* Sets whether the aggregate root should automatically commit and publish events upon application.
|
|
35
|
+
*/
|
|
36
|
+
set autoCommit(value: boolean);
|
|
37
|
+
/**
|
|
38
|
+
* Gets whether the aggregate root automatically commits and publishes events upon application.
|
|
39
|
+
*/
|
|
40
|
+
get autoCommit(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Called by apply() for each event while autoCommit is enabled; a no-op unless overridden.
|
|
43
|
+
*/
|
|
44
|
+
publish<T extends EventBase = EventBase>(_event: T): void;
|
|
45
|
+
/**
|
|
46
|
+
* Called by commit() with a copy of the buffered events; a no-op unless overridden.
|
|
47
|
+
*/
|
|
48
|
+
publishAll<T extends EventBase = EventBase>(_events: T[]): void;
|
|
49
|
+
/**
|
|
50
|
+
* Commits all uncommitted events by publishing them via {@link publishAll} and clearing the buffer.
|
|
51
|
+
*/
|
|
52
|
+
commit(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Clears all uncommitted events without publishing.
|
|
55
|
+
*/
|
|
56
|
+
uncommit(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Returns all uncommitted events currently buffered on this aggregate.
|
|
59
|
+
*/
|
|
60
|
+
getUncommittedEvents(): EventBase[];
|
|
61
|
+
/**
|
|
62
|
+
* Loads domain events from history to rehydrate the aggregate's internal state.
|
|
63
|
+
* Historical events invoke event handlers without being re-buffered.
|
|
64
|
+
*/
|
|
65
|
+
loadFromHistory(history: EventBase[]): void;
|
|
66
|
+
/**
|
|
67
|
+
* Applies an event to the aggregate root.
|
|
68
|
+
*
|
|
69
|
+
* If `fromHistory` is false and `autoCommit` is disabled, the event is appended to
|
|
70
|
+
* the uncommitted events buffer. If `autoCommit` is enabled, the event is published
|
|
71
|
+
* immediately. Unless `skipHandler` is true, routes to `on<EventName>(event)` if present.
|
|
72
|
+
*
|
|
73
|
+
* @param event The domain event to apply.
|
|
74
|
+
* @param optionsOrIsFromHistory Boolean indicating historical event or options object.
|
|
75
|
+
*/
|
|
76
|
+
apply<T extends EventBase = EventBase>(event: T, optionsOrIsFromHistory?: boolean | ApplyEventOptions): void;
|
|
77
|
+
/**
|
|
78
|
+
* Resolves the method handler corresponding to the applied event name (`on<EventName>`).
|
|
79
|
+
*/
|
|
80
|
+
protected getEventHandler<T extends EventBase = EventBase>(event: T): ((event: T) => void) | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Resolves the constructor name of the event.
|
|
83
|
+
*/
|
|
84
|
+
protected getEventName(event: unknown): string;
|
|
85
|
+
}
|
|
86
|
+
export {};
|
|
87
|
+
//# sourceMappingURL=aggregate-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregate-root.d.ts","sourceRoot":"","sources":["../../../domain/models/aggregate-root.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AAEnD,QAAA,MAAM,eAAe,eAA4B,CAAC;AAClD,QAAA,MAAM,sBAAsB,eAAmC,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;GAWG;AACH,8BAAsB,aAAa,CAAC,SAAS,SAAS,MAAM,GAAG,MAAM;IACnE,OAAO,CAAC,CAAC,sBAAsB,CAAC,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAmB;IAErD;;OAEG;IACH,IAAI,UAAU,CAAC,KAAK,EAAE,OAAO,EAE5B;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;IAED;;OAEG;IACH,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAAE,MAAM,EAAE,CAAC,GAAG,IAAI;IAEzD;;OAEG;IACH,UAAU,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,GAAG,IAAI;IAE/D;;OAEG;IACH,MAAM,IAAI,IAAI;IAKd;;OAEG;IACH,QAAQ,IAAI,IAAI;IAIhB;;OAEG;IACH,oBAAoB,IAAI,SAAS,EAAE;IAInC;;;OAGG;IACH,eAAe,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI;IAM3C;;;;;;;;;OASG;IACH,KAAK,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACnC,KAAK,EAAE,CAAC,EACR,sBAAsB,GAAE,OAAO,GAAG,iBAAsB,GACvD,IAAI;IA2BP;;OAEG;IACH,SAAS,CAAC,eAAe,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACvD,KAAK,EAAE,CAAC,GACP,CAAC,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC,GAAG,SAAS;IAQnC;;OAEG;IACH,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;CAI/C"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Copyright (C) 2026-present Aristotelis — see repository license.
|
|
3
|
+
* Derived from and compatible with NestJS CQRS AggregateRoot (MIT License).
|
|
4
|
+
* Copyright (c) 2017-2026 Kamil Mysliwiec (https://kamilmysliwiec.com)
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.AggregateRoot = void 0;
|
|
8
|
+
const INTERNAL_EVENTS = Symbol('INTERNAL_EVENTS');
|
|
9
|
+
const IS_AUTO_COMMIT_ENABLED = Symbol('IS_AUTO_COMMIT_ENABLED');
|
|
10
|
+
/**
|
|
11
|
+
* Abstract base class representing a Domain-Driven Design (DDD) aggregate root.
|
|
12
|
+
*
|
|
13
|
+
* Provides a framework-neutral event buffering lifecycle:
|
|
14
|
+
* - Records uncommitted domain events via {@link apply}.
|
|
15
|
+
* - Dispatches events to optional `on<EventName>` instance handlers for internal state updates.
|
|
16
|
+
* - Supports state rehydration via {@link loadFromHistory}.
|
|
17
|
+
* - Exposes buffered events via {@link getUncommittedEvents} for out-of-band application dispatch.
|
|
18
|
+
* - Clears buffered events via {@link uncommit} once reliably persisted or published.
|
|
19
|
+
*
|
|
20
|
+
* @template EventBase The base event type, defaults to {@link IEvent}.
|
|
21
|
+
*/
|
|
22
|
+
class AggregateRoot {
|
|
23
|
+
[IS_AUTO_COMMIT_ENABLED] = false;
|
|
24
|
+
[INTERNAL_EVENTS] = [];
|
|
25
|
+
/**
|
|
26
|
+
* Sets whether the aggregate root should automatically commit and publish events upon application.
|
|
27
|
+
*/
|
|
28
|
+
set autoCommit(value) {
|
|
29
|
+
this[IS_AUTO_COMMIT_ENABLED] = value;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Gets whether the aggregate root automatically commits and publishes events upon application.
|
|
33
|
+
*/
|
|
34
|
+
get autoCommit() {
|
|
35
|
+
return this[IS_AUTO_COMMIT_ENABLED];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Called by apply() for each event while autoCommit is enabled; a no-op unless overridden.
|
|
39
|
+
*/
|
|
40
|
+
publish(_event) { }
|
|
41
|
+
/**
|
|
42
|
+
* Called by commit() with a copy of the buffered events; a no-op unless overridden.
|
|
43
|
+
*/
|
|
44
|
+
publishAll(_events) { }
|
|
45
|
+
/**
|
|
46
|
+
* Commits all uncommitted events by publishing them via {@link publishAll} and clearing the buffer.
|
|
47
|
+
*/
|
|
48
|
+
commit() {
|
|
49
|
+
this.publishAll([...this[INTERNAL_EVENTS]]);
|
|
50
|
+
this[INTERNAL_EVENTS].length = 0;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Clears all uncommitted events without publishing.
|
|
54
|
+
*/
|
|
55
|
+
uncommit() {
|
|
56
|
+
this[INTERNAL_EVENTS].length = 0;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Returns all uncommitted events currently buffered on this aggregate.
|
|
60
|
+
*/
|
|
61
|
+
getUncommittedEvents() {
|
|
62
|
+
return this[INTERNAL_EVENTS];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Loads domain events from history to rehydrate the aggregate's internal state.
|
|
66
|
+
* Historical events invoke event handlers without being re-buffered.
|
|
67
|
+
*/
|
|
68
|
+
loadFromHistory(history) {
|
|
69
|
+
for (const event of history) {
|
|
70
|
+
this.apply(event, true);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Applies an event to the aggregate root.
|
|
75
|
+
*
|
|
76
|
+
* If `fromHistory` is false and `autoCommit` is disabled, the event is appended to
|
|
77
|
+
* the uncommitted events buffer. If `autoCommit` is enabled, the event is published
|
|
78
|
+
* immediately. Unless `skipHandler` is true, routes to `on<EventName>(event)` if present.
|
|
79
|
+
*
|
|
80
|
+
* @param event The domain event to apply.
|
|
81
|
+
* @param optionsOrIsFromHistory Boolean indicating historical event or options object.
|
|
82
|
+
*/
|
|
83
|
+
apply(event, optionsOrIsFromHistory = {}) {
|
|
84
|
+
const isFromHistory = (typeof optionsOrIsFromHistory === 'boolean'
|
|
85
|
+
? optionsOrIsFromHistory
|
|
86
|
+
: optionsOrIsFromHistory.fromHistory) ?? false;
|
|
87
|
+
const skipHandler = (typeof optionsOrIsFromHistory === 'boolean'
|
|
88
|
+
? false
|
|
89
|
+
: optionsOrIsFromHistory.skipHandler) ?? false;
|
|
90
|
+
if (!isFromHistory && !this.autoCommit) {
|
|
91
|
+
this[INTERNAL_EVENTS].push(event);
|
|
92
|
+
}
|
|
93
|
+
if (this.autoCommit) {
|
|
94
|
+
this.publish(event);
|
|
95
|
+
}
|
|
96
|
+
if (!skipHandler) {
|
|
97
|
+
const handler = this.getEventHandler(event);
|
|
98
|
+
if (handler) {
|
|
99
|
+
handler.call(this, event);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Resolves the method handler corresponding to the applied event name (`on<EventName>`).
|
|
105
|
+
*/
|
|
106
|
+
getEventHandler(event) {
|
|
107
|
+
const handler = `on${this.getEventName(event)}`;
|
|
108
|
+
const method = this[handler];
|
|
109
|
+
return typeof method === 'function'
|
|
110
|
+
? method
|
|
111
|
+
: undefined;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Resolves the constructor name of the event.
|
|
115
|
+
*/
|
|
116
|
+
getEventName(event) {
|
|
117
|
+
const proto = Object.getPrototypeOf(event);
|
|
118
|
+
return proto?.constructor?.name ?? 'Event';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.AggregateRoot = AggregateRoot;
|
|
122
|
+
//# sourceMappingURL=aggregate-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregate-root.js","sourceRoot":"","sources":["../../../domain/models/aggregate-root.ts"],"names":[],"mappings":"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"}
|