| Package | Version | Description |
|---|---|---|
@woltz/rich-domain |
Core library — Entities, Aggregates, Value Objects, Criteria, Change Tracking, Domain Events | |
@woltz/rich-domain-prisma |
Prisma adapter — Unit of Work, batch operations, @Transactional decorator |
|
@woltz/rich-domain-drizzle |
Drizzle adapter — Unit of Work, batch operations, @Transactional decorator |
|
@woltz/rich-domain-typeorm |
TypeORM adapter — repository, transactions, batch executor | |
@woltz/rich-domain-export |
Multi-format data export (CSV, JSON, JSONL) with streaming support | |
@woltz/rich-domain-criteria-zod |
Zod schemas for validating Criteria query params from HTTP requests |
npm install @woltz/rich-domain zodAdd an ORM adapter if needed:
@woltz/rich-domain-prisma,@woltz/rich-domain-drizzle, or@woltz/rich-domain-typeorm.
import { ValueObject, VOValidation } from "@woltz/rich-domain";
import { z } from "zod";
const emailSchema = z.string().email();
class Email extends ValueObject<string> {
protected static validation<VOValidation<string>> = { schema: emailSchema };
getDomain(): string {
return this.value.split("@")[1];
}
}
const email = new Email("john@example.com");
console.log(email.value); // "john@example.com"
console.log(email.getDomain()); // "example.com"import {
Aggregate,
Entity,
Id,
type EntityValidation,
type EntityHooks,
} from "@woltz/rich-domain";
import { z } from "zod";
// Child Entity
const PostSchema = z.object({
id: z.custom<Id>(),
title: z.string().min(1),
content: z.string(),
published: z.boolean(),
});
type PostProps = z.infer<typeof PostSchema>;
class Post extends Entity<PostProps> {
protected static validation: EntityValidation<PostProps> = {
schema: PostSchema,
};
publish() {
this.props.published = true;
}
get title() {
return this.props.title;
}
get content() {
return this.props.content;
}
}
// Aggregate Root
const UserSchema = z.object({
id: z.custom<Id>(),
email: z.custom<Email>(),
name: z.string().min(2),
posts: z.array(z.instanceof(Post)),
createdAt: z.date(),
});
type UserProps = z.infer<typeof UserSchema>;
class User extends Aggregate<UserProps, "createdAt"> {
protected static validation: EntityValidation<UserProps> = {
schema: UserSchema,
};
protected static hooks: EntityHooks<UserProps, User> = {
onBeforeCreate: (props) => {
if (!props.createdAt) props.createdAt = new Date();
},
};
// Recommended pattern for type-safe change tracking
getTypedChanges() {
interface Entities {
Post: Post;
}
return this.getChanges<Entities>();
}
addPost(title: string, content: string): void {
this.props.posts.push(new Post({ title, content, published: false }));
}
get email() {
return this.props.email.value;
}
get posts() {
return this.props.posts;
}
}import { Criteria } from "@woltz/rich-domain";
const criteria = Criteria.create<User>()
.where("status", "equals", "active")
.whereContains("email", "@company.com")
.orderBy("createdAt", "desc")
.paginate(1, 20);
const result = await userRepository.find(criteria);const user = await userRepository.findById(userId);
user.addPost("Hello", "World");
user.posts[0].publish();
const changes = user.getTypedChanges();
// changes.of("Post").creates → [Post]
// changes.of("Post").updates → [{ entity: Post, changed: { published: { from: false, to: true } } }]
await userRepository.save(user); // Only the diff hits the database
user.markAsClean();Rich Domain provides the IDomainEventBus interface — you bring the implementation (in-memory, BullMQ, Kafka, etc.).
import { DomainEvent, type IDomainEventBus } from "@woltz/rich-domain";
class OrderConfirmedEvent extends DomainEvent<{
orderId: string;
total: number;
}> {}
// Inside a use case
const order = Order.create(data);
await orderRepository.save(order);
await order.dispatchAll(eventBus); // Publishes and clears events automaticallyPrerequisites: Node.js ≥ 22.12.0
git clone https://github.com/tarcisioandrade/rich-domain.git
cd rich-domain
npm install
npm run build
npm testWorkspace commands:
npm run build --workspace=@woltz/rich-domain # Build a single package
npm run test --workspace=@woltz/rich-domain # Test a single package
npm run check # Type-check all packages
npm run lint # Lint all packages
npm run clean # Clean all build artifactsVisit woltz.mintlify.app for the full documentation covering core concepts, validation, criteria queries, repository patterns, ORM integrations, React components, and CLI reference.
Contributions are welcome. Please open an issue first to discuss what you'd like to change.
- Fork the repository
- Create your feature branch (
git checkout -b feature/my-feature) - Commit with conventional commits (
git commit -m 'feat: add something') - Run
npm run check && npm test && npm formatbefore pushing - Open a Pull Request
