A comprehensive Domain-Driven Design library for NestJS - Build scalable, maintainable enterprise applications
npm install @nestjslatam/ddd-libDddAggregateRoot with built-in validation and state tracking
StringValueObject, NumberValueObject with immutability
AbstractRuleValidator for custom business rules
bash
npm install @nestjslatam/ddd-lib
`
$3
`bash
npm install @nestjs/common @nestjs/core rxjs uuid
`
š Quick Start
$3
`typescript
import { StringValueObject, AbstractRuleValidator } from '@nestjslatam/ddd-lib';
// Custom validator
class EmailValidator extends AbstractRuleValidator {
constructor(subject: Email) {
super(subject);
}
public addRules(): void {
const value = this.subject.getValue();
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(value)) {
this.addBrokenRule('value', 'Invalid email format');
}
}
}
// Value Object
export class Email extends StringValueObject {
private constructor(value: string) {
super(value);
}
static create(value: string): Email {
const email = new Email(value);
if (!email.isValid) {
const errors = email.brokenRules.getBrokenRules();
throw new Error(
Invalid email: ${errors.map((e) => e.message).join(', ')},
);
}
return email;
}
protected override addValidators(): void {
super.addValidators();
this.validatorRules.add(new EmailValidator(this));
}
}
`
$3
`typescript
import { DddAggregateRoot, IdValueObject } from '@nestjslatam/ddd-lib';
import { Email } from './value-objects/email';
interface UserProps {
email: Email;
name: string;
isActive: boolean;
}
export class User extends DddAggregateRoot {
private constructor(
id: IdValueObject,
props: UserProps,
createdAt?: Date,
updatedAt?: Date,
) {
super(id, props, createdAt, updatedAt);
}
static create(email: Email, name: string): User {
const id = IdValueObject.create();
const user = new User(id, {
email,
name,
isActive: false,
});
user.validate();
return user;
}
// Business methods
activate(): void {
if (this.props.isActive) {
throw new Error('User is already active');
}
this.props.isActive = true;
this.trackingState.markAsDirty();
}
deactivate(): void {
if (!this.props.isActive) {
throw new Error('User is already inactive');
}
this.props.isActive = false;
this.trackingState.markAsDirty();
}
// Getters
get email(): Email {
return this.props.email;
}
get name(): string {
return this.props.name;
}
get isActive(): boolean {
return this.props.isActive;
}
}
`
$3
`typescript
import { Injectable } from '@nestjs/common';
import { User } from './domain/user';
import { Email } from './domain/value-objects/email';
@Injectable()
export class UserService {
async createUser(emailStr: string, name: string): Promise {
const email = Email.create(emailStr);
const user = User.create(email, name);
// Check state
console.log(user.trackingState.isNew); // true
console.log(user.trackingState.isDirty); // false
console.log(user.isValid()); // true
// Business logic
user.activate();
console.log(user.trackingState.isDirty); // true
return user;
}
}
`
š Core Concepts
$3
Aggregate roots are the entry points to your domain model. They enforce consistency boundaries and business rules.
`typescript
import { DddAggregateRoot } from '@nestjslatam/ddd-lib';
export class Order extends DddAggregateRoot {
// Your domain logic
}
`
Features:
- ā
Automatic state tracking (new, dirty, deleted)
- ā
Built-in validation orchestration
- ā
Domain event support
- ā
Broken rules management
$3
Value objects are immutable and represent domain concepts without identity.
`typescript
import { StringValueObject, NumberValueObject } from '@nestjslatam/ddd-lib';
export class Money extends NumberValueObject {
// Your value object logic
}
`
Built-in Validators:
- StringNotNullOrEmptyValidator - Ensures string is not null or empty
- NumberNotNullValidator - Ensures number is not null
- NumberPositiveValidator - Ensures number is positive
$3
Create business rule validators by extending AbstractRuleValidator.
`typescript
import { AbstractRuleValidator } from '@nestjslatam/ddd-lib';
export class PriceRangeValidator extends AbstractRuleValidator {
public addRules(): void {
const value = this.subject.getValue();
if (value < 0) {
this.addBrokenRule('value', 'Price cannot be negative');
}
if (value > 999999.99) {
this.addBrokenRule('value', 'Price exceeds maximum');
}
}
}
`
$3
Every aggregate automatically tracks its state:
`typescript
const product = Product.create(name, price);
product.trackingState.isNew; // true
product.trackingState.isDirty; // false
product.trackingState.isDeleted; // false
product.changePrice(newPrice);
product.trackingState.isDirty; // true
product.trackingState.markAsDeleted();
product.trackingState.isDeleted; // true
`
šļø Architecture Example
`
src/
āāā domain/
ā āāā aggregates/
ā ā āāā product.ts # Extends DddAggregateRoot
ā āāā value-objects/
ā ā āāā price.ts # Extends NumberValueObject
ā ā āāā product-name.ts # Extends StringValueObject
ā āāā validators/
ā āāā price-range.validator.ts # Extends AbstractRuleValidator
āāā application/
ā āāā commands/
ā āāā queries/
āāā infrastructure/
āāā repositories/
`
š Version 2.0.0 Changes
$3
NPM Package Distribution
- Library is now published as a standalone NPM package
- No need for monorepo or path mappings
- Standard Node.js module resolution
Eliminated Circular Dependencies
- Refactored internal imports to eliminate circular references
- Direct imports from specific modules
- Reliable runtime behavior
Pre-compiled Distribution
- Published as compiled JavaScript with TypeScript declarations
- Faster application startup
- Better tree-shaking support
Improved Type Definitions
- Complete .d.ts files for all exports
- Better IDE support and autocomplete
- Source maps for debugging
$3
1. Installation Method
`bash
# Before (1.x.x) - Local library
# Used path mappings in tsconfig.json
# After (2.0.0) - NPM package
npm install @nestjslatam/ddd-lib
`
2. Import Paths
`typescript
// Before (1.x.x)
import { DddAggregateRoot } from '@nestjslatam/ddd-lib/aggregate-root';
// After (2.0.0)
import { DddAggregateRoot } from '@nestjslatam/ddd-lib';
`
3. No Path Mappings Required
`json
// tsconfig.json - NO LONGER NEEDED
{
"paths": {
"@nestjslatam/ddd-lib": ["libs/ddd/src"]
}
}
`
š API Reference
$3
Base Classes:
- DddAggregateRoot - Base class for aggregate roots
- StringValueObject - Base class for string value objects
- NumberValueObject - Base class for number value objects
- IdValueObject - UUID-based identity value object
Validators:
- AbstractRuleValidator - Base class for custom validators
- StringNotNullOrEmptyValidator - Built-in string validator
- NumberNotNullValidator - Built-in number validator
- NumberPositiveValidator - Built-in positive number validator
Managers:
- BrokenRulesManager - Manages validation errors
- ValidatorRuleManager - Manages validator rules
- TrackingStateManager - Manages entity state
Interfaces:
- IDomainReadRepository - Read repository interface
- IDomainWriteRepository