@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":"utils.js","sourceRoot":"","sources":["../../src/types/utils.ts"],"names":[],"mappings":""}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Id } from "./id";
|
|
2
|
+
export type EntityId = string | number;
|
|
3
|
+
export interface BaseProps {
|
|
4
|
+
id: Id;
|
|
5
|
+
}
|
|
6
|
+
export interface ChangeEvent<T> {
|
|
7
|
+
previous: T | undefined;
|
|
8
|
+
current: T;
|
|
9
|
+
path: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ArrayChangeEvent<T> {
|
|
12
|
+
toCreate: T[];
|
|
13
|
+
toUpdate: T[];
|
|
14
|
+
toDelete: T[];
|
|
15
|
+
path: string;
|
|
16
|
+
}
|
|
17
|
+
export type PropertySubscriber<T> = (event: ChangeEvent<T>) => void;
|
|
18
|
+
export type ArraySubscriber<T> = (event: ArrayChangeEvent<T>) => void;
|
|
19
|
+
export interface PropertySubscription<T> {
|
|
20
|
+
onChange: PropertySubscriber<T>;
|
|
21
|
+
}
|
|
22
|
+
export interface ArraySubscription<T> {
|
|
23
|
+
onChange: ArraySubscriber<T>;
|
|
24
|
+
}
|
|
25
|
+
type UnwrapArray<T> = T extends Array<infer U> ? U : never;
|
|
26
|
+
type IsArray<T> = T extends Array<any> ? true : false;
|
|
27
|
+
type NonUndefined<T> = T extends undefined ? never : T;
|
|
28
|
+
export type SubscriptionConfig<T extends BaseProps> = {
|
|
29
|
+
[K in keyof T]?: IsArray<NonUndefined<T[K]>> extends true ? ArraySubscription<UnwrapArray<NonUndefined<T[K]>>> : PropertySubscription<NonUndefined<T[K]>>;
|
|
30
|
+
};
|
|
31
|
+
export interface ValidationConfig {
|
|
32
|
+
onCreate?: boolean;
|
|
33
|
+
onUpdate?: boolean;
|
|
34
|
+
throwOnError?: boolean;
|
|
35
|
+
}
|
|
36
|
+
export declare const DEFAULT_VALIDATION_CONFIG: Required<ValidationConfig>;
|
|
37
|
+
export interface StandardSchemaIssue {
|
|
38
|
+
message: string;
|
|
39
|
+
path?: ReadonlyArray<unknown>;
|
|
40
|
+
}
|
|
41
|
+
export interface StandardSchemaResult<T> {
|
|
42
|
+
value?: T;
|
|
43
|
+
issues?: ReadonlyArray<StandardSchemaIssue>;
|
|
44
|
+
}
|
|
45
|
+
export interface StandardSchemaProps<T> {
|
|
46
|
+
validate: (value: unknown) => StandardSchemaResult<T> | Promise<StandardSchemaResult<T>>;
|
|
47
|
+
}
|
|
48
|
+
export interface StandardSchema<T = unknown> {
|
|
49
|
+
"~standard": StandardSchemaProps<T>;
|
|
50
|
+
}
|
|
51
|
+
interface DomainValidation<T> {
|
|
52
|
+
schema: StandardSchema<T>;
|
|
53
|
+
config?: ValidationConfig;
|
|
54
|
+
}
|
|
55
|
+
export type EntityValidation<T> = DomainValidation<T>;
|
|
56
|
+
export type VOValidation<T> = DomainValidation<T>;
|
|
57
|
+
export interface VOHooks<T, E> {
|
|
58
|
+
onBeforeUpdate?: (entity: E, snapshot: T) => boolean;
|
|
59
|
+
onCreate?: (entity: E) => void;
|
|
60
|
+
rules?: (entity: E) => void;
|
|
61
|
+
defaultValues?: Partial<T>;
|
|
62
|
+
}
|
|
63
|
+
export interface EntityHooks<T extends BaseProps, E> {
|
|
64
|
+
onBeforeUpdate?: (entity: E, snapshot: T) => boolean;
|
|
65
|
+
onCreate?: (entity: E) => void;
|
|
66
|
+
rules?: (entity: E) => void;
|
|
67
|
+
defaultValues?: Partial<Omit<T, "id">>;
|
|
68
|
+
}
|
|
69
|
+
export interface HistoryEntry {
|
|
70
|
+
path: string;
|
|
71
|
+
previousValue: any;
|
|
72
|
+
currentValue: any;
|
|
73
|
+
timestamp: number;
|
|
74
|
+
}
|
|
75
|
+
export type DeepJsonResult<T> = {
|
|
76
|
+
[K in keyof T]: T[K] extends Id ? string : T[K] extends {
|
|
77
|
+
toJson(): infer U;
|
|
78
|
+
} ? U : T[K] extends Array<infer U> ? U extends {
|
|
79
|
+
toJson(): infer V;
|
|
80
|
+
} ? V[] : U extends Id ? string[] : U[] : T[K];
|
|
81
|
+
};
|
|
82
|
+
export interface EntityConstructor<T extends BaseProps, E> {
|
|
83
|
+
new (props: T): E;
|
|
84
|
+
validation?: DomainValidation<T>;
|
|
85
|
+
hooks?: EntityHooks<T, E>;
|
|
86
|
+
}
|
|
87
|
+
export {};
|
|
88
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// Types & Interfaces for Validation
|
|
4
|
+
// ============================================================================
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DEFAULT_VALIDATION_CONFIG = void 0;
|
|
7
|
+
exports.DEFAULT_VALIDATION_CONFIG = {
|
|
8
|
+
onCreate: true,
|
|
9
|
+
onUpdate: true,
|
|
10
|
+
throwOnError: true,
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,+EAA+E;AAC/E,oCAAoC;AACpC,+EAA+E;;;AAkElE,QAAA,yBAAyB,GAA+B;IACnE,QAAQ,EAAE,IAAI;IACd,QAAQ,EAAE,IAAI;IACd,YAAY,EAAE,IAAI;CACnB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface ValidationIssue {
|
|
2
|
+
path: string[];
|
|
3
|
+
message: string;
|
|
4
|
+
}
|
|
5
|
+
export declare class ValidationError extends Error {
|
|
6
|
+
readonly issues: ValidationIssue[];
|
|
7
|
+
readonly __isValidationError = true;
|
|
8
|
+
constructor(issues: ValidationIssue[], message?: string);
|
|
9
|
+
/**
|
|
10
|
+
* Check if an error is a ValidationError (works across module boundaries)
|
|
11
|
+
*/
|
|
12
|
+
static isValidationError(error: unknown): error is ValidationError;
|
|
13
|
+
/**
|
|
14
|
+
* Get all error messages as a simple array
|
|
15
|
+
*/
|
|
16
|
+
getMessages(): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Get errors for a specific field path
|
|
19
|
+
*/
|
|
20
|
+
getErrorsForPath(path: string): ValidationIssue[];
|
|
21
|
+
/**
|
|
22
|
+
* Check if a specific path has errors
|
|
23
|
+
*/
|
|
24
|
+
hasErrorsForPath(path: string): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Convert to a plain object for serialization
|
|
27
|
+
*/
|
|
28
|
+
toJSON(): {
|
|
29
|
+
name: string;
|
|
30
|
+
message: string;
|
|
31
|
+
issues: ValidationIssue[];
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Helper to create a single validation issue
|
|
36
|
+
*/
|
|
37
|
+
export declare function createValidationIssue(path: string | string[], message: string): ValidationIssue;
|
|
38
|
+
/**
|
|
39
|
+
* Helper to throw a validation error with a single issue
|
|
40
|
+
*/
|
|
41
|
+
export declare function throwValidationError(path: string | string[], message: string): never;
|
|
42
|
+
//# sourceMappingURL=validation-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-error.d.ts","sourceRoot":"","sources":["../src/validation-error.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,eAAgB,SAAQ,KAAK;IACxC,SAAgB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1C,SAAgB,mBAAmB,QAAQ;gBAE/B,MAAM,EAAE,eAAe,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM;IAavD;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe;IAalE;;OAEG;IACH,WAAW,IAAI,MAAM,EAAE;IAIvB;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,EAAE;IAIjD;;OAEG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIvC;;OAEG;IACH,MAAM,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,eAAe,EAAE,CAAA;KAAE;CAOvE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,OAAO,EAAE,MAAM,GACd,eAAe,CAKjB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,EACvB,OAAO,EAAE,MAAM,GACd,KAAK,CAEP"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Validation Error - Domain Validation Errors
|
|
3
|
+
// ============================================================================
|
|
4
|
+
export class ValidationError extends Error {
|
|
5
|
+
constructor(issues, message) {
|
|
6
|
+
const errorMessage = message || `Validation failed: ${issues.map(i => i.message).join(', ')}`;
|
|
7
|
+
super(errorMessage);
|
|
8
|
+
this.__isValidationError = true; // Brand for identification
|
|
9
|
+
this.name = 'ValidationError';
|
|
10
|
+
this.issues = issues;
|
|
11
|
+
// Maintain proper stack trace
|
|
12
|
+
if (Error.captureStackTrace) {
|
|
13
|
+
Error.captureStackTrace(this, ValidationError);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Check if an error is a ValidationError (works across module boundaries)
|
|
18
|
+
*/
|
|
19
|
+
static isValidationError(error) {
|
|
20
|
+
if (error instanceof ValidationError) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
// Check by duck typing for cross-module compatibility
|
|
24
|
+
return (error instanceof Error &&
|
|
25
|
+
error.name === 'ValidationError' &&
|
|
26
|
+
'issues' in error &&
|
|
27
|
+
Array.isArray(error.issues));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get all error messages as a simple array
|
|
31
|
+
*/
|
|
32
|
+
getMessages() {
|
|
33
|
+
return this.issues.map(i => i.message);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Get errors for a specific field path
|
|
37
|
+
*/
|
|
38
|
+
getErrorsForPath(path) {
|
|
39
|
+
return this.issues.filter(i => i.path.join('.') === path);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Check if a specific path has errors
|
|
43
|
+
*/
|
|
44
|
+
hasErrorsForPath(path) {
|
|
45
|
+
return this.getErrorsForPath(path).length > 0;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Convert to a plain object for serialization
|
|
49
|
+
*/
|
|
50
|
+
toJSON() {
|
|
51
|
+
return {
|
|
52
|
+
name: this.name,
|
|
53
|
+
message: this.message,
|
|
54
|
+
issues: this.issues,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Helper to create a single validation issue
|
|
60
|
+
*/
|
|
61
|
+
export function createValidationIssue(path, message) {
|
|
62
|
+
return {
|
|
63
|
+
path: Array.isArray(path) ? path : path.split('.'),
|
|
64
|
+
message,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Helper to throw a validation error with a single issue
|
|
69
|
+
*/
|
|
70
|
+
export function throwValidationError(path, message) {
|
|
71
|
+
throw new ValidationError([createValidationIssue(path, message)]);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=validation-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-error.js","sourceRoot":"","sources":["../src/validation-error.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,8CAA8C;AAC9C,+EAA+E;AAO/E,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAIxC,YAAY,MAAyB,EAAE,OAAgB;QACrD,MAAM,YAAY,GAChB,OAAO,IAAI,sBAAsB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3E,KAAK,CAAC,YAAY,CAAC,CAAC;QALN,wBAAmB,GAAG,IAAI,CAAC,CAAC,2BAA2B;QAMrE,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,8BAA8B;QAC9B,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,KAAc;QACrC,IAAI,KAAK,YAAY,eAAe,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,sDAAsD;QACtD,OAAO,CACL,KAAK,YAAY,KAAK;YACtB,KAAK,CAAC,IAAI,KAAK,iBAAiB;YAChC,QAAQ,IAAI,KAAK;YACjB,KAAK,CAAC,OAAO,CAAE,KAAa,CAAC,MAAM,CAAC,CACrC,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,IAAY;QAC3B,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;IAC5D,CAAC;IAED;;OAEG;IACH,gBAAgB,CAAC,IAAY;QAC3B,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACH,MAAM;QACJ,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;SACpB,CAAC;IACJ,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAuB,EACvB,OAAe;IAEf,OAAO;QACL,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;QAClD,OAAO;KACR,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAuB,EACvB,OAAe;IAEf,MAAM,IAAI,eAAe,CAAC,CAAC,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ValidationError } from "./validation-error";
|
|
2
|
+
import { IDomainEvent } from "./domain-event";
|
|
3
|
+
import { VOHooks, EntityValidation } from "./types";
|
|
4
|
+
export declare abstract class ValueObject<T> {
|
|
5
|
+
protected readonly props: T;
|
|
6
|
+
private validationConfig;
|
|
7
|
+
private domainHooks?;
|
|
8
|
+
private domainSchema?;
|
|
9
|
+
private domainEvents;
|
|
10
|
+
protected static validation?: EntityValidation<any>;
|
|
11
|
+
protected static hooks?: VOHooks<any, any>;
|
|
12
|
+
constructor(props: T);
|
|
13
|
+
private validateProps;
|
|
14
|
+
private extractPathKey;
|
|
15
|
+
/**
|
|
16
|
+
* Check if value object has validation errors (when throwOnError is false)
|
|
17
|
+
*/
|
|
18
|
+
get hasValidationErrors(): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Get validation errors (when throwOnError is false)
|
|
21
|
+
*/
|
|
22
|
+
get validationErrors(): ValidationError | undefined;
|
|
23
|
+
equals(other: ValueObject<T>): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Add a domain event to this value object
|
|
26
|
+
*/
|
|
27
|
+
protected addDomainEvent(event: IDomainEvent): void;
|
|
28
|
+
/**
|
|
29
|
+
* Get all uncommitted domain events
|
|
30
|
+
*/
|
|
31
|
+
getUncommittedEvents(): IDomainEvent[];
|
|
32
|
+
/**
|
|
33
|
+
* Clear all domain events (call after publishing)
|
|
34
|
+
*/
|
|
35
|
+
clearEvents(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Check if value object has uncommitted events
|
|
38
|
+
*/
|
|
39
|
+
hasUncommittedEvents(): boolean;
|
|
40
|
+
toJson(): T;
|
|
41
|
+
/**
|
|
42
|
+
* Create a new ValueObject with updated properties
|
|
43
|
+
* Since ValueObjects are immutable, this returns a new instance
|
|
44
|
+
*/
|
|
45
|
+
protected clone(updates: Partial<T>): this;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=value-object.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-object.d.ts","sourceRoot":"","sources":["../src/value-object.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EACL,OAAO,EAGP,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAWjB,8BAAsB,WAAW,CAAC,CAAC;IACjC,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAG,CAAC,CAAC;IAC7B,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,WAAW,CAAC,CAAkB;IACtC,OAAO,CAAC,YAAY,CAAC,CAAoB;IACzC,OAAO,CAAC,YAAY,CAAsB;IAG1C,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACpD,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAE/B,KAAK,EAAE,CAAC;IA+CpB,OAAO,CAAC,aAAa;IA4BrB,OAAO,CAAC,cAAc;IAmBtB;;OAEG;IACH,IAAI,mBAAmB,IAAI,OAAO,CAEjC;IAED;;OAEG;IACH,IAAI,gBAAgB,IAAI,eAAe,GAAG,SAAS,CAElD;IAED,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,OAAO;IAKtC;;OAEG;IACH,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI;IAInD;;OAEG;IACH,oBAAoB,IAAI,YAAY,EAAE;IAItC;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,oBAAoB,IAAI,OAAO;IAI/B,MAAM,IAAI,CAAC;IAIX;;;OAGG;IACH,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;CAI3C"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Value Object - Immutable Domain Objects
|
|
3
|
+
// ============================================================================
|
|
4
|
+
import { ValidationError } from "./validation-error";
|
|
5
|
+
import { DEFAULT_VALIDATION_CONFIG } from "./constants";
|
|
6
|
+
// Helper to get static properties from constructor
|
|
7
|
+
function getStaticProperty(instance, propertyName) {
|
|
8
|
+
return instance.constructor[propertyName];
|
|
9
|
+
}
|
|
10
|
+
export class ValueObject {
|
|
11
|
+
constructor(props) {
|
|
12
|
+
this.domainEvents = [];
|
|
13
|
+
// Get static configuration from subclass
|
|
14
|
+
const validation = getStaticProperty(this, "validation");
|
|
15
|
+
const hooks = getStaticProperty(this, "hooks");
|
|
16
|
+
this.domainHooks = hooks;
|
|
17
|
+
if (validation?.schema) {
|
|
18
|
+
this.domainSchema = validation.schema;
|
|
19
|
+
}
|
|
20
|
+
this.validationConfig = {
|
|
21
|
+
...DEFAULT_VALIDATION_CONFIG,
|
|
22
|
+
...validation?.config,
|
|
23
|
+
};
|
|
24
|
+
// Apply defaultValues
|
|
25
|
+
let finalProps = { ...props };
|
|
26
|
+
if (hooks?.defaultValues) {
|
|
27
|
+
finalProps = { ...hooks.defaultValues, ...props };
|
|
28
|
+
}
|
|
29
|
+
// Validate schema on creation
|
|
30
|
+
if (this.domainSchema && this.validationConfig.onCreate) {
|
|
31
|
+
this.validateProps(finalProps);
|
|
32
|
+
}
|
|
33
|
+
// Set props (not frozen yet) so rules can access them
|
|
34
|
+
this.props = finalProps;
|
|
35
|
+
// Execute rules (custom validations) - after props is set but before freezing
|
|
36
|
+
if (hooks?.rules) {
|
|
37
|
+
hooks.rules(this);
|
|
38
|
+
}
|
|
39
|
+
// Now freeze the props for immutability
|
|
40
|
+
Object.freeze(this.props);
|
|
41
|
+
// Hook onCreate
|
|
42
|
+
if (hooks?.onCreate) {
|
|
43
|
+
hooks.onCreate(this);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
validateProps(props) {
|
|
47
|
+
if (!this.domainSchema)
|
|
48
|
+
return;
|
|
49
|
+
const result = this.domainSchema["~standard"].validate(props);
|
|
50
|
+
if (result instanceof Promise) {
|
|
51
|
+
throw new Error("Async validation not supported in constructor. Use sync validation schema.");
|
|
52
|
+
}
|
|
53
|
+
if (result.issues && result.issues.length > 0) {
|
|
54
|
+
const validationError = new ValidationError(result.issues.map((issue) => ({
|
|
55
|
+
path: issue.path?.map((p) => this.extractPathKey(p)) || [],
|
|
56
|
+
message: issue.message,
|
|
57
|
+
})));
|
|
58
|
+
if (this.validationConfig.throwOnError) {
|
|
59
|
+
throw validationError;
|
|
60
|
+
}
|
|
61
|
+
// If not throwing, store error for later retrieval
|
|
62
|
+
this._validationError = validationError;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
extractPathKey(pathSegment) {
|
|
66
|
+
if (pathSegment === null || pathSegment === undefined) {
|
|
67
|
+
return "";
|
|
68
|
+
}
|
|
69
|
+
// Handle PropertyKey (string | number | symbol)
|
|
70
|
+
if (typeof pathSegment === "string" || typeof pathSegment === "number") {
|
|
71
|
+
return String(pathSegment);
|
|
72
|
+
}
|
|
73
|
+
if (typeof pathSegment === "symbol") {
|
|
74
|
+
return pathSegment.toString();
|
|
75
|
+
}
|
|
76
|
+
// Handle object with 'key' property (Zod's PathSegment)
|
|
77
|
+
if (typeof pathSegment === "object" && "key" in pathSegment) {
|
|
78
|
+
return String(pathSegment.key);
|
|
79
|
+
}
|
|
80
|
+
// Fallback
|
|
81
|
+
return String(pathSegment);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Check if value object has validation errors (when throwOnError is false)
|
|
85
|
+
*/
|
|
86
|
+
get hasValidationErrors() {
|
|
87
|
+
return !!this._validationError;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get validation errors (when throwOnError is false)
|
|
91
|
+
*/
|
|
92
|
+
get validationErrors() {
|
|
93
|
+
return this._validationError;
|
|
94
|
+
}
|
|
95
|
+
equals(other) {
|
|
96
|
+
if (!other || !(other instanceof ValueObject))
|
|
97
|
+
return false;
|
|
98
|
+
return JSON.stringify(this.props) === JSON.stringify(other.props);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Add a domain event to this value object
|
|
102
|
+
*/
|
|
103
|
+
addDomainEvent(event) {
|
|
104
|
+
this.domainEvents.push(event);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Get all uncommitted domain events
|
|
108
|
+
*/
|
|
109
|
+
getUncommittedEvents() {
|
|
110
|
+
return [...this.domainEvents];
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Clear all domain events (call after publishing)
|
|
114
|
+
*/
|
|
115
|
+
clearEvents() {
|
|
116
|
+
this.domainEvents = [];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Check if value object has uncommitted events
|
|
120
|
+
*/
|
|
121
|
+
hasUncommittedEvents() {
|
|
122
|
+
return this.domainEvents.length > 0;
|
|
123
|
+
}
|
|
124
|
+
toJson() {
|
|
125
|
+
return { ...this.props };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Create a new ValueObject with updated properties
|
|
129
|
+
* Since ValueObjects are immutable, this returns a new instance
|
|
130
|
+
*/
|
|
131
|
+
clone(updates) {
|
|
132
|
+
const Constructor = this.constructor;
|
|
133
|
+
return new Constructor({ ...this.props, ...updates });
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=value-object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-object.js","sourceRoot":"","sources":["../src/value-object.ts"],"names":[],"mappings":"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"}
|
package/eslint.config.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const tsParser = require("@typescript-eslint/parser");
|
|
2
|
+
const tsPlugin = require("@typescript-eslint/eslint-plugin");
|
|
3
|
+
|
|
4
|
+
module.exports = [
|
|
5
|
+
{
|
|
6
|
+
ignores: [
|
|
7
|
+
"dist/**",
|
|
8
|
+
"node_modules/**",
|
|
9
|
+
"coverage/**",
|
|
10
|
+
"**/*.test.ts",
|
|
11
|
+
"**/*.spec.ts",
|
|
12
|
+
],
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
files: ["src/**/*.ts"],
|
|
16
|
+
languageOptions: {
|
|
17
|
+
parser: tsParser,
|
|
18
|
+
parserOptions: {
|
|
19
|
+
ecmaVersion: 2020,
|
|
20
|
+
sourceType: "module",
|
|
21
|
+
project: "./tsconfig.json",
|
|
22
|
+
},
|
|
23
|
+
globals: {
|
|
24
|
+
console: "readonly",
|
|
25
|
+
process: "readonly",
|
|
26
|
+
Buffer: "readonly",
|
|
27
|
+
__dirname: "readonly",
|
|
28
|
+
__filename: "readonly",
|
|
29
|
+
module: "readonly",
|
|
30
|
+
require: "readonly",
|
|
31
|
+
exports: "readonly",
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
plugins: {
|
|
35
|
+
"@typescript-eslint": tsPlugin,
|
|
36
|
+
},
|
|
37
|
+
rules: {
|
|
38
|
+
...tsPlugin.configs.recommended.rules,
|
|
39
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
40
|
+
"@typescript-eslint/no-unused-vars": [
|
|
41
|
+
"warn",
|
|
42
|
+
{ argsIgnorePattern: "^_" },
|
|
43
|
+
],
|
|
44
|
+
"@typescript-eslint/explicit-function-return-type": "off",
|
|
45
|
+
"@typescript-eslint/explicit-module-boundary-types": "off",
|
|
46
|
+
"@typescript-eslint/no-this-alias": "off",
|
|
47
|
+
"@typescript-eslint/no-unsafe-function-type": "off",
|
|
48
|
+
"no-console": "off",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
];
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** @type {import('ts-jest').JestConfigWithTsJest} */
|
|
2
|
+
module.exports = {
|
|
3
|
+
preset: "ts-jest",
|
|
4
|
+
testEnvironment: "node",
|
|
5
|
+
roots: ["<rootDir>/tests", "<rootDir>/src"],
|
|
6
|
+
testMatch: ["**/*.test.ts", "**/*.spec.ts"],
|
|
7
|
+
transform: {
|
|
8
|
+
"^.+\\.tsx?$": "ts-jest",
|
|
9
|
+
},
|
|
10
|
+
coveragePathIgnorePatterns: [
|
|
11
|
+
"/node_modules/",
|
|
12
|
+
"/dist/",
|
|
13
|
+
"/tests/",
|
|
14
|
+
"**/examples/**",
|
|
15
|
+
],
|
|
16
|
+
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
|
|
17
|
+
collectCoverageFrom: ["src/**/*.ts", "!src/**/*.d.ts", "!src/index.ts"],
|
|
18
|
+
coverageDirectory: "coverage",
|
|
19
|
+
coverageReporters: ["text", "lcov", "clover"],
|
|
20
|
+
verbose: true,
|
|
21
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@woltz/rich-domain",
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Rich Domain Library with Standard Schema validation support",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "jest",
|
|
13
|
+
"test:watch": "jest --watch",
|
|
14
|
+
"check": "tsc --noEmit",
|
|
15
|
+
"coverage": "jest --coverage",
|
|
16
|
+
"lint": "eslint src",
|
|
17
|
+
"prepublishOnly": "npm run build",
|
|
18
|
+
"release": "standard-version",
|
|
19
|
+
"release:minor": "standard-version --release-as minor",
|
|
20
|
+
"release:major": "standard-version --release-as major",
|
|
21
|
+
"release:patch": "standard-version --release-as patch",
|
|
22
|
+
"release:first": "standard-version --first-release",
|
|
23
|
+
"prepare": "husky"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"ddd",
|
|
27
|
+
"domain-driven-design",
|
|
28
|
+
"entity",
|
|
29
|
+
"aggregate",
|
|
30
|
+
"value-object",
|
|
31
|
+
"validation",
|
|
32
|
+
"standard-schema",
|
|
33
|
+
"typescript"
|
|
34
|
+
],
|
|
35
|
+
"author": "Tarcisio Andrade",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@commitlint/cli": "^20.1.0",
|
|
39
|
+
"@commitlint/config-conventional": "^20.0.0",
|
|
40
|
+
"@types/jest": "^29.5.12",
|
|
41
|
+
"@types/node": "^20.11.30",
|
|
42
|
+
"@typescript-eslint/eslint-plugin": "^8.46.4",
|
|
43
|
+
"@typescript-eslint/parser": "^8.46.4",
|
|
44
|
+
"eslint": "^9.39.1",
|
|
45
|
+
"husky": "^9.1.7",
|
|
46
|
+
"jest": "^29.7.0",
|
|
47
|
+
"standard-version": "^9.5.0",
|
|
48
|
+
"ts-jest": "^29.1.2",
|
|
49
|
+
"typescript": "^5.4.3",
|
|
50
|
+
"zod": "^3.24.0"
|
|
51
|
+
},
|
|
52
|
+
"peerDependencies": {
|
|
53
|
+
"typescript": ">=4.7.0"
|
|
54
|
+
},
|
|
55
|
+
"engines": {
|
|
56
|
+
"node": ">=20.0.0"
|
|
57
|
+
}
|
|
58
|
+
}
|