@hexaijs/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/LICENSE +21 -0
- package/README.md +273 -0
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +5 -0
- package/dist/config.js.map +1 -0
- package/dist/domain/aggregate-root.d.ts +11 -0
- package/dist/domain/aggregate-root.d.ts.map +1 -0
- package/dist/domain/aggregate-root.js +21 -0
- package/dist/domain/aggregate-root.js.map +1 -0
- package/dist/domain/domain-error.d.ts +11 -0
- package/dist/domain/domain-error.d.ts.map +1 -0
- package/dist/domain/domain-error.js +25 -0
- package/dist/domain/domain-error.js.map +1 -0
- package/dist/domain/domain-event.d.ts +5 -0
- package/dist/domain/domain-event.d.ts.map +1 -0
- package/dist/domain/domain-event.js +11 -0
- package/dist/domain/domain-event.js.map +1 -0
- package/dist/domain/identifiable.d.ts +11 -0
- package/dist/domain/identifiable.d.ts.map +1 -0
- package/dist/domain/identifiable.js +18 -0
- package/dist/domain/identifiable.js.map +1 -0
- package/dist/domain/index.d.ts +6 -0
- package/dist/domain/index.d.ts.map +1 -0
- package/dist/domain/index.js +22 -0
- package/dist/domain/index.js.map +1 -0
- package/dist/domain/repository.d.ts +16 -0
- package/dist/domain/repository.d.ts.map +1 -0
- package/dist/domain/repository.js +25 -0
- package/dist/domain/repository.js.map +1 -0
- package/dist/event-store.d.ts +13 -0
- package/dist/event-store.d.ts.map +1 -0
- package/dist/event-store.js +3 -0
- package/dist/event-store.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/message.d.ts +54 -0
- package/dist/message.d.ts.map +1 -0
- package/dist/message.js +120 -0
- package/dist/message.js.map +1 -0
- package/dist/test/dummy-message.d.ts +8 -0
- package/dist/test/dummy-message.d.ts.map +1 -0
- package/dist/test/dummy-message.js +22 -0
- package/dist/test/dummy-message.js.map +1 -0
- package/dist/test/expect.d.ts +3 -0
- package/dist/test/expect.d.ts.map +1 -0
- package/dist/test/expect.js +13 -0
- package/dist/test/expect.js.map +1 -0
- package/dist/test/in-memory-event-store.d.ts +11 -0
- package/dist/test/in-memory-event-store.d.ts.map +1 -0
- package/dist/test/in-memory-event-store.js +38 -0
- package/dist/test/in-memory-event-store.js.map +1 -0
- package/dist/test/index.d.ts +7 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +47 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test/matchers.d.ts +5 -0
- package/dist/test/matchers.d.ts.map +1 -0
- package/dist/test/matchers.js +77 -0
- package/dist/test/matchers.js.map +1 -0
- package/dist/test/partial-match.d.ts +4 -0
- package/dist/test/partial-match.d.ts.map +1 -0
- package/dist/test/partial-match.js +33 -0
- package/dist/test/partial-match.js.map +1 -0
- package/dist/test/utils.d.ts +5 -0
- package/dist/test/utils.d.ts.map +1 -0
- package/dist/test/utils.js +25 -0
- package/dist/test/utils.js.map +1 -0
- package/dist/unit-of-work.d.ts +13 -0
- package/dist/unit-of-work.d.ts.map +1 -0
- package/dist/unit-of-work.js +10 -0
- package/dist/unit-of-work.js.map +1 -0
- package/package.json +60 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Sangwoo Hyun
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# @hexaijs/core
|
|
2
|
+
|
|
3
|
+
> Core domain primitives for building hexagonal architecture applications
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`@hexaijs/core` provides the foundational building blocks for domain-driven design in TypeScript applications. It establishes the core abstractions that all other @hexai packages build upon.
|
|
8
|
+
|
|
9
|
+
The package focuses on three key areas:
|
|
10
|
+
|
|
11
|
+
1. **Messaging** - A unified `Message` abstraction for commands, queries, and events with built-in headers (id, type, timestamp, schema version)
|
|
12
|
+
2. **Domain Modeling** - Base classes for aggregates, entities, and domain events following DDD tactical patterns
|
|
13
|
+
3. **Infrastructure Interfaces** - Abstract contracts for repositories, unit of work, and event stores that infrastructure packages implement
|
|
14
|
+
|
|
15
|
+
These primitives are intentionally minimal. They define contracts and patterns without prescribing implementation details, allowing you to integrate with any database, message broker, or framework.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @hexaijs/core
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Core Concepts
|
|
24
|
+
|
|
25
|
+
### Message
|
|
26
|
+
|
|
27
|
+
`Message` is the base abstraction for all messages in the system - commands, queries, and events share this foundation.
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { Message } from "@hexaijs/core";
|
|
31
|
+
|
|
32
|
+
class CreateOrderCommand extends Message<{
|
|
33
|
+
customerId: string;
|
|
34
|
+
items: { productId: string; quantity: number }[];
|
|
35
|
+
}> {
|
|
36
|
+
static readonly type = "order.create-order";
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Create a message
|
|
40
|
+
const command = new CreateOrderCommand({
|
|
41
|
+
customerId: "customer-123",
|
|
42
|
+
items: [{ productId: "product-456", quantity: 2 }]
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// Access message data
|
|
46
|
+
command.getMessageId(); // unique UUID
|
|
47
|
+
command.getMessageType(); // "order.create-order"
|
|
48
|
+
command.getTimestamp(); // Date when created
|
|
49
|
+
command.getPayload(); // the typed payload object
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Every message automatically receives headers including a unique ID and timestamp. The `type` static property follows the convention `"bounded-context.message-name"`.
|
|
53
|
+
|
|
54
|
+
### DomainEvent
|
|
55
|
+
|
|
56
|
+
`DomainEvent` extends `Message` for events that represent something that happened in your domain.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
import { DomainEvent } from "@hexaijs/core";
|
|
60
|
+
|
|
61
|
+
export class OrderPlaced extends DomainEvent<{
|
|
62
|
+
orderId: string;
|
|
63
|
+
customerId: string;
|
|
64
|
+
totalAmount: number;
|
|
65
|
+
}> {
|
|
66
|
+
static readonly type = "order.order-placed";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Create and use domain events
|
|
70
|
+
const event = new OrderPlaced({
|
|
71
|
+
orderId: "order-789",
|
|
72
|
+
customerId: "customer-123",
|
|
73
|
+
totalAmount: 150.00
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Check event type
|
|
77
|
+
if (message.getMessageType() === OrderPlaced.getType()) {
|
|
78
|
+
const payload = message.getPayload();
|
|
79
|
+
// Handle the event...
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Id and Identifiable
|
|
84
|
+
|
|
85
|
+
Value objects for identity, ensuring type safety for entity IDs.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { Id, Identifiable } from "@hexaijs/core";
|
|
89
|
+
|
|
90
|
+
// Create a typed ID class
|
|
91
|
+
class OrderId extends Id<string> {}
|
|
92
|
+
|
|
93
|
+
// Use it in your domain
|
|
94
|
+
const orderId = new OrderId("order-123");
|
|
95
|
+
orderId.getValue(); // "order-123"
|
|
96
|
+
|
|
97
|
+
// Compare IDs
|
|
98
|
+
const sameId = new OrderId("order-123");
|
|
99
|
+
orderId.equals(sameId); // true
|
|
100
|
+
|
|
101
|
+
// Different ID types are not comparable
|
|
102
|
+
class CustomerId extends Id<string> {}
|
|
103
|
+
const customerId = new CustomerId("order-123");
|
|
104
|
+
// orderId.equals(customerId) - TypeScript prevents this
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### AggregateRoot
|
|
108
|
+
|
|
109
|
+
Base class for aggregate roots that collect domain events for later dispatch.
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { AggregateRoot, Id } from "@hexaijs/core";
|
|
113
|
+
|
|
114
|
+
class OrderId extends Id<string> {}
|
|
115
|
+
|
|
116
|
+
class Order extends AggregateRoot<OrderId> {
|
|
117
|
+
private status: "pending" | "confirmed" | "shipped" = "pending";
|
|
118
|
+
|
|
119
|
+
static create(orderId: OrderId, customerId: string): Order {
|
|
120
|
+
const order = new Order(orderId);
|
|
121
|
+
order.raise(new OrderPlaced({
|
|
122
|
+
orderId: orderId.getValue(),
|
|
123
|
+
customerId,
|
|
124
|
+
totalAmount: 0
|
|
125
|
+
}));
|
|
126
|
+
return order;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
confirm(): void {
|
|
130
|
+
if (this.status !== "pending") {
|
|
131
|
+
throw new Error("Can only confirm pending orders");
|
|
132
|
+
}
|
|
133
|
+
this.status = "confirmed";
|
|
134
|
+
this.raise(new OrderConfirmed({
|
|
135
|
+
orderId: this.getId().getValue()
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Usage
|
|
141
|
+
const order = Order.create(new OrderId("order-123"), "customer-456");
|
|
142
|
+
order.confirm();
|
|
143
|
+
|
|
144
|
+
// Events are collected, not immediately published
|
|
145
|
+
const events = order.getEventsOccurred();
|
|
146
|
+
// [OrderPlaced, OrderConfirmed]
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Repository
|
|
150
|
+
|
|
151
|
+
Interface for aggregate persistence. Implementations live in infrastructure packages.
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { Repository, ObjectNotFoundError } from "@hexaijs/core";
|
|
155
|
+
|
|
156
|
+
// Define your repository interface
|
|
157
|
+
interface OrderRepository extends Repository<Order> {
|
|
158
|
+
get(id: OrderId): Promise<Order>;
|
|
159
|
+
add(order: Order): Promise<void>;
|
|
160
|
+
update(order: Order): Promise<void>;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Use in your domain/application layer
|
|
164
|
+
async function confirmOrder(
|
|
165
|
+
orderId: OrderId,
|
|
166
|
+
repository: OrderRepository
|
|
167
|
+
): Promise<void> {
|
|
168
|
+
const order = await repository.get(orderId);
|
|
169
|
+
order.confirm();
|
|
170
|
+
await repository.update(order);
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### UnitOfWork
|
|
175
|
+
|
|
176
|
+
Interface for transaction management. Controls transaction propagation and provides access to the underlying database client.
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
import { UnitOfWork, Propagation } from "@hexaijs/core";
|
|
180
|
+
|
|
181
|
+
// UnitOfWork is typically accessed through application context
|
|
182
|
+
interface OrderApplicationContext {
|
|
183
|
+
getUnitOfWork(): UnitOfWork;
|
|
184
|
+
getOrderRepository(): OrderRepository;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Transaction propagation options
|
|
188
|
+
Propagation.NEW // Start new transaction
|
|
189
|
+
Propagation.EXISTING // Use existing transaction (error if none)
|
|
190
|
+
Propagation.NESTED // Nested transaction (savepoint)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### EventStore
|
|
194
|
+
|
|
195
|
+
Interface for event sourcing scenarios. Stores and retrieves events by position.
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
import { EventStore, StoredEvent } from "@hexaijs/core";
|
|
199
|
+
|
|
200
|
+
// EventStore interface for reading events
|
|
201
|
+
interface MyEventStore extends EventStore {
|
|
202
|
+
fetch(afterPosition: number, limit?: number): Promise<{
|
|
203
|
+
events: StoredEvent[];
|
|
204
|
+
lastPosition: number;
|
|
205
|
+
}>;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// StoredEvent wraps event with its position
|
|
209
|
+
interface StoredEvent {
|
|
210
|
+
position: number;
|
|
211
|
+
event: Message;
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
## Error Types
|
|
216
|
+
|
|
217
|
+
The package provides standard domain error types:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import {
|
|
221
|
+
DomainError,
|
|
222
|
+
InvariantNotSatisfiedError,
|
|
223
|
+
ValidationError,
|
|
224
|
+
RepositoryError,
|
|
225
|
+
ObjectNotFoundError,
|
|
226
|
+
DuplicateObjectError
|
|
227
|
+
} from "@hexaijs/core";
|
|
228
|
+
|
|
229
|
+
// Domain invariant violations
|
|
230
|
+
throw new InvariantNotSatisfiedError(
|
|
231
|
+
"ORDER_ALREADY_SHIPPED",
|
|
232
|
+
"Cannot modify a shipped order"
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
// Field-level validation errors
|
|
236
|
+
throw new ValidationError(
|
|
237
|
+
"email",
|
|
238
|
+
"INVALID_FORMAT",
|
|
239
|
+
"Email must be a valid email address"
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
// Repository errors
|
|
243
|
+
throw new ObjectNotFoundError("Order not found");
|
|
244
|
+
throw new DuplicateObjectError("Order with this ID already exists");
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Error hierarchy:**
|
|
248
|
+
- `DomainError` - Base for all domain errors
|
|
249
|
+
- `InvariantNotSatisfiedError` - Business rule violations
|
|
250
|
+
- `ValidationError` - Field-specific validation failures
|
|
251
|
+
- `RepositoryError` - Base for persistence errors
|
|
252
|
+
- `ObjectNotFoundError` - Entity not found
|
|
253
|
+
- `DuplicateObjectError` - Duplicate key/entity
|
|
254
|
+
|
|
255
|
+
## API Highlights
|
|
256
|
+
|
|
257
|
+
| Export | Description |
|
|
258
|
+
|--------|-------------|
|
|
259
|
+
| `Message<P>` | Base message class with headers and typed payload |
|
|
260
|
+
| `DomainEvent<P>` | Message subclass for domain events |
|
|
261
|
+
| `AggregateRoot<T>` | Base class for aggregates with event collection |
|
|
262
|
+
| `Id<T>` | Value object for typed identities |
|
|
263
|
+
| `Identifiable<T>` | Interface for entities with identity |
|
|
264
|
+
| `Repository<T>` | Interface for aggregate persistence |
|
|
265
|
+
| `UnitOfWork` | Interface for transaction management |
|
|
266
|
+
| `Propagation` | Enum for transaction propagation modes |
|
|
267
|
+
| `EventStore` | Interface for event store implementations |
|
|
268
|
+
|
|
269
|
+
## See Also
|
|
270
|
+
|
|
271
|
+
- [@hexaijs/application](../application/README.md) - Application layer with command handlers and context
|
|
272
|
+
- [@hexaijs/postgres](../postgres/README.md) - PostgreSQL implementation of UnitOfWork and EventStore
|
|
273
|
+
- [@hexaijs/sqlite](../sqlite/README.md) - SQLite implementation for testing
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,kBAAkB,SAAoC,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;;AAAa,QAAA,kBAAkB,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DomainEvent } from "./domain-event";
|
|
2
|
+
import { Id, Identifiable } from "./identifiable";
|
|
3
|
+
export declare class AggregateRoot<T extends Id<string | number>> implements Identifiable<T> {
|
|
4
|
+
protected readonly id: T;
|
|
5
|
+
protected events: DomainEvent[];
|
|
6
|
+
constructor(id: T);
|
|
7
|
+
getId(): T;
|
|
8
|
+
protected raise(event: DomainEvent): void;
|
|
9
|
+
getEventsOccurred(): DomainEvent[];
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=aggregate-root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregate-root.d.ts","sourceRoot":"","sources":["../../src/domain/aggregate-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAElD,qBAAa,aAAa,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,CACpD,YAAW,YAAY,CAAC,CAAC,CAAC;IAId,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;IAFpC,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,CAAM;gBAEN,EAAE,EAAE,CAAC;IAE7B,KAAK,IAAI,CAAC;IAIjB,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI;IAIlC,iBAAiB,IAAI,WAAW,EAAE;CAG5C"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AggregateRoot = void 0;
|
|
4
|
+
class AggregateRoot {
|
|
5
|
+
id;
|
|
6
|
+
events = [];
|
|
7
|
+
constructor(id) {
|
|
8
|
+
this.id = id;
|
|
9
|
+
}
|
|
10
|
+
getId() {
|
|
11
|
+
return this.id;
|
|
12
|
+
}
|
|
13
|
+
raise(event) {
|
|
14
|
+
this.events.push(event);
|
|
15
|
+
}
|
|
16
|
+
getEventsOccurred() {
|
|
17
|
+
return [...this.events];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.AggregateRoot = AggregateRoot;
|
|
21
|
+
//# sourceMappingURL=aggregate-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aggregate-root.js","sourceRoot":"","sources":["../../src/domain/aggregate-root.ts"],"names":[],"mappings":";;;AAGA,MAAa,aAAa;IAKS;IAFrB,MAAM,GAAkB,EAAE,CAAC;IAErC,YAA+B,EAAK;QAAL,OAAE,GAAF,EAAE,CAAG;IAAG,CAAC;IAEjC,KAAK;QACR,OAAO,IAAI,CAAC,EAAE,CAAC;IACnB,CAAC;IAES,KAAK,CAAC,KAAkB;QAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;IAEM,iBAAiB;QACpB,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;CACJ;AAlBD,sCAkBC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class DomainError extends Error {
|
|
2
|
+
}
|
|
3
|
+
export declare class InvariantNotSatisfiedError extends DomainError {
|
|
4
|
+
readonly code: string;
|
|
5
|
+
constructor(code: string, message?: string);
|
|
6
|
+
}
|
|
7
|
+
export declare class ValidationError extends InvariantNotSatisfiedError {
|
|
8
|
+
readonly field: string;
|
|
9
|
+
constructor(field: string, code: string, message?: string);
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=domain-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-error.d.ts","sourceRoot":"","sources":["../../src/domain/domain-error.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAY,SAAQ,KAAK;CAAG;AAEzC,qBAAa,0BAA2B,SAAQ,WAAW;aAEnC,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAC5B,OAAO,GAAE,MAAW;CAK3B;AAED,qBAAa,eAAgB,SAAQ,0BAA0B;aAEvC,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM,EAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,MAAW;CAM3B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidationError = exports.InvariantNotSatisfiedError = exports.DomainError = void 0;
|
|
4
|
+
class DomainError extends Error {
|
|
5
|
+
}
|
|
6
|
+
exports.DomainError = DomainError;
|
|
7
|
+
class InvariantNotSatisfiedError extends DomainError {
|
|
8
|
+
code;
|
|
9
|
+
constructor(code, message = "") {
|
|
10
|
+
super(message);
|
|
11
|
+
this.code = code;
|
|
12
|
+
this.name = "InvariantNotSatisfiedError";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.InvariantNotSatisfiedError = InvariantNotSatisfiedError;
|
|
16
|
+
class ValidationError extends InvariantNotSatisfiedError {
|
|
17
|
+
field;
|
|
18
|
+
constructor(field, code, message = "") {
|
|
19
|
+
super(code, message);
|
|
20
|
+
this.field = field;
|
|
21
|
+
this.name = "ValidationError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ValidationError = ValidationError;
|
|
25
|
+
//# sourceMappingURL=domain-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-error.js","sourceRoot":"","sources":["../../src/domain/domain-error.ts"],"names":[],"mappings":";;;AAAA,MAAa,WAAY,SAAQ,KAAK;CAAG;AAAzC,kCAAyC;AAEzC,MAAa,0BAA2B,SAAQ,WAAW;IAEnC;IADpB,YACoB,IAAY,EAC5B,UAAkB,EAAE;QAEpB,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAQ;QAI5B,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC7C,CAAC;CACJ;AARD,gEAQC;AAED,MAAa,eAAgB,SAAQ,0BAA0B;IAEvC;IADpB,YACoB,KAAa,EAC7B,IAAY,EACZ,UAAkB,EAAE;QAEpB,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QAJL,UAAK,GAAL,KAAK,CAAQ;QAM7B,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAClC,CAAC;CACJ;AAVD,0CAUC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-event.d.ts","sourceRoot":"","sources":["../../src/domain/domain-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,qBAAa,WAAW,CACpB,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACzD,SAAQ,OAAO,CAAC,CAAC,CAAC;WACA,SAAS;CAG5B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DomainEvent = void 0;
|
|
4
|
+
const message_1 = require("../message");
|
|
5
|
+
class DomainEvent extends message_1.Message {
|
|
6
|
+
static getIntent() {
|
|
7
|
+
return "event";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.DomainEvent = DomainEvent;
|
|
11
|
+
//# sourceMappingURL=domain-event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-event.js","sourceRoot":"","sources":["../../src/domain/domain-event.ts"],"names":[],"mappings":";;;AAAA,uCAAoC;AAEpC,MAAa,WAEX,SAAQ,iBAAU;IAChB,MAAM,CAAU,SAAS;QACrB,OAAO,OAAO,CAAC;IACnB,CAAC;CACJ;AAND,kCAMC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class Id<T extends string | number> {
|
|
2
|
+
private readonly value;
|
|
3
|
+
constructor(value: T);
|
|
4
|
+
getValue(): T;
|
|
5
|
+
equals(other: Id<T>): boolean;
|
|
6
|
+
}
|
|
7
|
+
export type IdOf<T> = T extends Identifiable<infer Id> ? Id : never;
|
|
8
|
+
export interface Identifiable<T extends Id<string | number> = Id<string>> {
|
|
9
|
+
getId(): T;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=identifiable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identifiable.d.ts","sourceRoot":"","sources":["../../src/domain/identifiable.ts"],"names":[],"mappings":"AAAA,qBAAa,EAAE,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IAClB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,CAAC;IAErC,QAAQ,IAAI,CAAC;IAIb,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO;CAMvC;AAED,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,YAAY,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;AAEpE,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC;IACpE,KAAK,IAAI,CAAC,CAAC;CACd"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Id = void 0;
|
|
4
|
+
class Id {
|
|
5
|
+
value;
|
|
6
|
+
constructor(value) {
|
|
7
|
+
this.value = value;
|
|
8
|
+
}
|
|
9
|
+
getValue() {
|
|
10
|
+
return this.value;
|
|
11
|
+
}
|
|
12
|
+
equals(other) {
|
|
13
|
+
return (this.constructor === other.constructor &&
|
|
14
|
+
this.getValue() === other.getValue());
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.Id = Id;
|
|
18
|
+
//# sourceMappingURL=identifiable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identifiable.js","sourceRoot":"","sources":["../../src/domain/identifiable.ts"],"names":[],"mappings":";;;AAAA,MAAa,EAAE;IACyB;IAApC,YAAoC,KAAQ;QAAR,UAAK,GAAL,KAAK,CAAG;IAAG,CAAC;IAEzC,QAAQ;QACX,OAAO,IAAI,CAAC,KAAK,CAAC;IACtB,CAAC;IAEM,MAAM,CAAC,KAAY;QACtB,OAAO,CACH,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW;YACtC,IAAI,CAAC,QAAQ,EAAE,KAAK,KAAK,CAAC,QAAQ,EAAE,CACvC,CAAC;IACN,CAAC;CACJ;AAbD,gBAaC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./aggregate-root"), exports);
|
|
18
|
+
__exportStar(require("./domain-error"), exports);
|
|
19
|
+
__exportStar(require("./domain-event"), exports);
|
|
20
|
+
__exportStar(require("./identifiable"), exports);
|
|
21
|
+
__exportStar(require("./repository"), exports);
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/domain/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,iDAA+B;AAC/B,iDAA+B;AAC/B,iDAA+B;AAC/B,+CAA6B"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Identifiable, IdOf } from "./identifiable";
|
|
2
|
+
export interface Repository<T extends Identifiable<any>> {
|
|
3
|
+
get(id: IdOf<T>): Promise<T>;
|
|
4
|
+
add(entity: T): Promise<void>;
|
|
5
|
+
update(entity: T): Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export declare class RepositoryError extends Error {
|
|
8
|
+
constructor(message: string);
|
|
9
|
+
}
|
|
10
|
+
export declare class DuplicateObjectError extends RepositoryError {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
export declare class ObjectNotFoundError extends RepositoryError {
|
|
14
|
+
constructor(message: string);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../src/domain/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,UAAU,CAAC,CAAC,SAAS,YAAY,CAAC,GAAG,CAAC;IACnD,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7B,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpC;AAED,qBAAa,eAAgB,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI9B;AAED,qBAAa,oBAAqB,SAAQ,eAAe;gBACzC,OAAO,EAAE,MAAM;CAI9B;AAED,qBAAa,mBAAoB,SAAQ,eAAe;gBACxC,OAAO,EAAE,MAAM;CAI9B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ObjectNotFoundError = exports.DuplicateObjectError = exports.RepositoryError = void 0;
|
|
4
|
+
class RepositoryError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "RepositoryError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.RepositoryError = RepositoryError;
|
|
11
|
+
class DuplicateObjectError extends RepositoryError {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = "DuplicateObjectError";
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.DuplicateObjectError = DuplicateObjectError;
|
|
18
|
+
class ObjectNotFoundError extends RepositoryError {
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "ObjectNotFoundError";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ObjectNotFoundError = ObjectNotFoundError;
|
|
25
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../src/domain/repository.ts"],"names":[],"mappings":";;;AAQA,MAAa,eAAgB,SAAQ,KAAK;IACtC,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAClC,CAAC;CACJ;AALD,0CAKC;AAED,MAAa,oBAAqB,SAAQ,eAAe;IACrD,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;IACvC,CAAC;CACJ;AALD,oDAKC;AAED,MAAa,mBAAoB,SAAQ,eAAe;IACpD,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACtC,CAAC;CACJ;AALD,kDAKC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Message } from "./message";
|
|
2
|
+
export interface StoredEvent {
|
|
3
|
+
position: number;
|
|
4
|
+
event: Message;
|
|
5
|
+
}
|
|
6
|
+
export interface EventStoreFetchResult {
|
|
7
|
+
events: StoredEvent[];
|
|
8
|
+
lastPosition: number;
|
|
9
|
+
}
|
|
10
|
+
export interface EventStore {
|
|
11
|
+
fetch(afterPosition: number, limit?: number): Promise<EventStoreFetchResult>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=event-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-store.d.ts","sourceRoot":"","sources":["../src/event-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,WAAW,WAAW;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IAClC,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACvB,KAAK,CACD,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,qBAAqB,CAAC,CAAC;CACrC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-store.js","sourceRoot":"","sources":["../src/event-store.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./domain"), exports);
|
|
18
|
+
__exportStar(require("./unit-of-work"), exports);
|
|
19
|
+
__exportStar(require("./message"), exports);
|
|
20
|
+
__exportStar(require("./event-store"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAyB;AACzB,iDAA+B;AAC/B,4CAA0B;AAC1B,gDAA8B"}
|