@globalart/ddd 1.0.1 → 1.0.2
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/README.md +7 -183
- package/package.json +14 -12
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -2,195 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
A comprehensive Domain-Driven Design (DDD) toolkit for NestJS applications, providing essential building blocks for building robust, maintainable domain models.
|
|
4
4
|
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **Aggregate Root**: Base class for domain aggregates with domain event management
|
|
8
|
-
- **Command & Query**: CQRS pattern implementation with command and query buses
|
|
9
|
-
- **Value Objects**: Type-safe value objects with equality comparison
|
|
10
|
-
- **Specifications**: Composite specification pattern for business rules
|
|
11
|
-
- **Filtering**: Advanced filtering system with type-safe field operations
|
|
12
|
-
- **Pagination**: Built-in pagination support with validation
|
|
13
|
-
- **Repository Pattern**: Abstract repository interface
|
|
14
|
-
- **Unit of Work**: Transaction management abstraction
|
|
15
|
-
- **Domain Events**: Event-driven architecture support
|
|
16
|
-
- **Exception Handling**: Domain-specific exception base classes
|
|
17
|
-
|
|
18
5
|
## Installation
|
|
19
6
|
|
|
20
7
|
```bash
|
|
21
8
|
npm install @globalart/ddd
|
|
22
9
|
```
|
|
23
10
|
|
|
24
|
-
##
|
|
25
|
-
|
|
26
|
-
### Aggregate Root
|
|
27
|
-
|
|
28
|
-
```typescript
|
|
29
|
-
import { AggregateRoot } from '@globalart/ddd';
|
|
30
|
-
|
|
31
|
-
class UserCreatedEvent {
|
|
32
|
-
constructor(public readonly userId: string, public readonly email: string) {}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
class User extends AggregateRoot<UserCreatedEvent> {
|
|
36
|
-
constructor(
|
|
37
|
-
public readonly id: string,
|
|
38
|
-
public readonly email: string,
|
|
39
|
-
public readonly name: string
|
|
40
|
-
) {
|
|
41
|
-
super();
|
|
42
|
-
this.addDomainEvent(new UserCreatedEvent(id, email));
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
### Value Objects
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
import { ValueObject } from '@globalart/ddd';
|
|
51
|
-
|
|
52
|
-
class Email extends ValueObject<string> {
|
|
53
|
-
constructor(value: string) {
|
|
54
|
-
if (!this.isValidEmail(value)) {
|
|
55
|
-
throw new Error('Invalid email format');
|
|
56
|
-
}
|
|
57
|
-
super({ value });
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private isValidEmail(email: string): boolean {
|
|
61
|
-
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Usage
|
|
66
|
-
const email = new Email('user@example.com');
|
|
67
|
-
const emailValue = email.unpack(); // 'user@example.com'
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Commands and Queries
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
import { Command, Query } from '@globalart/ddd';
|
|
74
|
-
|
|
75
|
-
class CreateUserCommand extends Command {
|
|
76
|
-
constructor(
|
|
77
|
-
public readonly email: string,
|
|
78
|
-
public readonly name: string,
|
|
79
|
-
correlationId?: string
|
|
80
|
-
) {
|
|
81
|
-
super({ correlationId });
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
class GetUserQuery extends Query {
|
|
86
|
-
constructor(public readonly userId: string) {
|
|
87
|
-
super();
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### Specifications
|
|
93
|
-
|
|
94
|
-
```typescript
|
|
95
|
-
import { CompositeSpecification } from '@globalart/ddd';
|
|
96
|
-
|
|
97
|
-
class UserEmailSpecification extends CompositeSpecification<User> {
|
|
98
|
-
isSatisfiedBy(user: User): boolean {
|
|
99
|
-
return user.email.includes('@');
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
mutate(user: User): Result<User, string> {
|
|
103
|
-
return this.isSatisfiedBy(user)
|
|
104
|
-
? Ok(user)
|
|
105
|
-
: Err('Invalid email format');
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
accept(visitor: ISpecVisitor): Result<void, string> {
|
|
109
|
-
return Ok(undefined);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Usage
|
|
114
|
-
const emailSpec = new UserEmailSpecification();
|
|
115
|
-
const isValid = emailSpec.isSatisfiedBy(user);
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Filtering
|
|
119
|
-
|
|
120
|
-
```typescript
|
|
121
|
-
import { StringFilter, NumberFilter, DateFilter } from '@globalart/ddd';
|
|
122
|
-
|
|
123
|
-
// String filtering
|
|
124
|
-
const nameFilter = new StringFilter('name', 'contains', 'john');
|
|
125
|
-
|
|
126
|
-
// Number filtering
|
|
127
|
-
const ageFilter = new NumberFilter('age', 'gte', 18);
|
|
128
|
-
|
|
129
|
-
// Date filtering
|
|
130
|
-
const createdFilter = new DateFilter('createdAt', 'after', new Date('2023-01-01'));
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Pagination
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
import { IPagination, paginationSchema } from '@globalart/ddd';
|
|
137
|
-
|
|
138
|
-
const pagination: IPagination = {
|
|
139
|
-
limit: 10,
|
|
140
|
-
offset: 0
|
|
141
|
-
};
|
|
142
|
-
|
|
143
|
-
// Validation
|
|
144
|
-
const result = paginationSchema.parse(pagination);
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Repository Pattern
|
|
148
|
-
|
|
149
|
-
```typescript
|
|
150
|
-
import { Repository } from '@globalart/ddd';
|
|
151
|
-
|
|
152
|
-
interface UserRepository extends Repository<User> {
|
|
153
|
-
findByEmail(email: string): Promise<User | null>;
|
|
154
|
-
findActiveUsers(): Promise<User[]>;
|
|
155
|
-
}
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## API Reference
|
|
159
|
-
|
|
160
|
-
### Core Classes
|
|
161
|
-
|
|
162
|
-
- `AggregateRoot<E>` - Base class for domain aggregates
|
|
163
|
-
- `Command` - Base class for commands with correlation tracking
|
|
164
|
-
- `Query` - Base class for queries
|
|
165
|
-
- `ValueObject<T>` - Base class for value objects
|
|
166
|
-
- `CompositeSpecification<T>` - Base class for business rules
|
|
167
|
-
|
|
168
|
-
### Value Objects
|
|
169
|
-
|
|
170
|
-
- `Id` - UUID-based identifier
|
|
171
|
-
- `NanoId` - NanoID-based identifier
|
|
172
|
-
- `StringVO` - String value object
|
|
173
|
-
- `BooleanVO` - Boolean value object
|
|
174
|
-
- `DateVO` - Date value object
|
|
175
|
-
|
|
176
|
-
### Filtering
|
|
177
|
-
|
|
178
|
-
- `StringFilter` - String field filtering
|
|
179
|
-
- `NumberFilter` - Numeric field filtering
|
|
180
|
-
- `DateFilter` - Date field filtering
|
|
181
|
-
- `RootFilter` - Filter composition
|
|
182
|
-
|
|
183
|
-
### Utilities
|
|
184
|
-
|
|
185
|
-
- `IPagination` - Pagination interface
|
|
186
|
-
- `ISort` - Sorting interface
|
|
187
|
-
- `Repository<T>` - Repository interface
|
|
188
|
-
- `UnitOfWork` - Transaction management
|
|
189
|
-
|
|
190
|
-
## License
|
|
11
|
+
## Documentation
|
|
191
12
|
|
|
192
|
-
|
|
13
|
+
📖 **[Complete documentation and usage examples](https://nestjs-toolkit.js.org/packages/ddd)**
|
|
193
14
|
|
|
194
|
-
|
|
15
|
+
The documentation includes:
|
|
16
|
+
- Detailed guides for all components
|
|
17
|
+
- Real-world usage scenarios
|
|
18
|
+
- API reference
|
|
19
|
+
- DDD best practices in NestJS
|
|
195
20
|
|
|
196
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@globalart/ddd",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"description": "A advanced DDD for NestJS",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "GlobalArt, Inc"
|
|
@@ -27,7 +27,19 @@
|
|
|
27
27
|
"keywords": [
|
|
28
28
|
"ddd"
|
|
29
29
|
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"format": "prettier --write \"**/*.ts\"",
|
|
32
|
+
"test": "jest --runInBand --passWithNoTests",
|
|
33
|
+
"test:cov": "jest --coverage --passWithNoTests",
|
|
34
|
+
"coveralls": "yarn run test:cov --coverageReporters=text-lcov | coveralls",
|
|
35
|
+
"build": "tsdown",
|
|
36
|
+
"build:watch": "tsdown --watch",
|
|
37
|
+
"prepublishOnly": "npm run build",
|
|
38
|
+
"publish:dev": "npm publish --access public --tag dev",
|
|
39
|
+
"publish:npm": "release-it"
|
|
40
|
+
},
|
|
30
41
|
"devDependencies": {
|
|
42
|
+
"release-it": "19.0.4",
|
|
31
43
|
"tsdown": "0.14.2"
|
|
32
44
|
},
|
|
33
45
|
"publishConfig": {
|
|
@@ -42,15 +54,5 @@
|
|
|
42
54
|
"ts-pattern": "5.8.0",
|
|
43
55
|
"uuid": "12.0.0",
|
|
44
56
|
"zod": "4.1.5"
|
|
45
|
-
},
|
|
46
|
-
"scripts": {
|
|
47
|
-
"format": "prettier --write \"**/*.ts\"",
|
|
48
|
-
"test": "jest --runInBand --passWithNoTests",
|
|
49
|
-
"test:cov": "jest --coverage --passWithNoTests",
|
|
50
|
-
"coveralls": "yarn run test:cov --coverageReporters=text-lcov | coveralls",
|
|
51
|
-
"build": "tsdown",
|
|
52
|
-
"build:watch": "tsdown --watch",
|
|
53
|
-
"publish:dev": "npm publish --access public --tag dev",
|
|
54
|
-
"publish:npm": "release-it"
|
|
55
57
|
}
|
|
56
|
-
}
|
|
58
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2003 GlobalArt Inc
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|