domaindrivenjs
Version:
Composition-based Domain-Driven Design toolkit for JavaScript/TypeScript
1,505 lines (1,272 loc) • 34.4 kB
TypeScript
import { z } from 'zod';
/**
* A value object with standard methods
*/
type ValueObject<T> = T & {
/**
* Compares this value object with another for equality
*/
equals: (other: unknown) => boolean;
/**
* Returns a string representation of the value object
*/
toString: () => string;
/**
* Returns the primitive value for primitive wrappers
*/
valueOf: () => unknown;
[key: string]: unknown;
}
/**
* A factory for creating value objects
*/
type ValueObjectFactory<T, SchemaType extends z.ZodType = z.ZodType> = {
/**
* Creates a new instance of the value object
*/
create: (data: unknown) => ValueObject<T>;
/**
* The Zod schema used for validation
*/
schema: SchemaType;
/**
* Creates an extended version of this value object
*/
extend: <R = unknown>(options: {
name: string;
schema?: (schema: SchemaType) => z.ZodType;
methodsFactory: (factory: ValueObjectFactory<T, SchemaType>) => Record<string, Function>;
}) => ValueObjectFactory<R>;
}
/**
* Defines the structure of methods that will be bound to a value object instance
*/
type ValueObjectMethods<T> = Record<string, (this: T, ...args: any[]) => any>;
/**
* Creates a value object factory
*
* Value objects in Domain-Driven Design are:
* 1. Defined by their attributes, not an identity
* 2. Immutable - any modification creates a new instance
* 3. Comparable by value - two instances with the same attributes are equal
*/
declare function valueObject<T, SchemaType extends z.ZodType = z.ZodType>(options: {
/**
* Name of the value object
*/
name: string;
/**
* Zod schema for validation
*/
schema: SchemaType;
/**
* Factory function that creates methods that will be bound to the value object instance
* The `this` context inside these methods will be the value object instance
*/
methodsFactory: (factory: ValueObjectFactory<T, SchemaType>) => ValueObjectMethods<T & ValueObject<T>>;
/**
* Override primitive detection
*/
overrideIsPrimitive?: boolean;
}): ValueObjectFactory<T, SchemaType>;
/**
* StringValue represents a string with validation and common operations
*/
type StringValueType = ValueObject<string>;
/**
* String value object factory for creating string values with built-in methods
*/
declare const String: ValueObjectFactory<string> & {
create: (data: string | unknown) => StringValueType & {
/**
* Checks if string contains a substring
*/
contains: (substring: string) => boolean;
/**
* Truncates the string if it exceeds max length
*/
truncate: (maxLength: number, suffix?: string) => StringValueType;
/**
* Converts string to lowercase
*/
toLower: () => StringValueType;
/**
* Converts string to uppercase
*/
toUpper: () => StringValueType;
/**
* Capitalizes the first letter of the string
*/
capitalize: () => StringValueType;
/**
* Trims whitespace from both ends of the string
*/
trim: () => StringValueType;
/**
* Replaces occurrences of a substring with a replacement
*/
replace: (searchValue: string | RegExp, replaceValue: string) => StringValueType;
/**
* Splits the string by a separator
*/
split: (separator: string | RegExp) => string[];
/**
* Checks if string starts with a substring
*/
startsWith: (substring: string) => boolean;
/**
* Checks if string ends with a substring
*/
endsWith: (substring: string) => boolean;
/**
* Pads the string to a target length
*/
pad: (length: number, padString?: string) => StringValueType;
/**
* Pads the string from the start to a target length
*/
padStart: (length: number, padString?: string) => StringValueType;
/**
* Pads the string from the end to a target length
*/
padEnd: (length: number, padString?: string) => StringValueType;
/**
* Checks if string matches a regular expression
*/
matches: (pattern: RegExp) => boolean;
/**
* Checks if string is empty
*/
isEmpty: () => boolean;
/**
* Returns a substring of this string
*/
substring: (start: number, end?: number) => StringValueType;
};
};
/**
* NumberValue represents a numeric value with validation and operations
*/
type NumberValueType = ValueObject<number>;
/**
* Number value object factory for creating number values with built-in methods
*/
declare const NumberValue: ValueObjectFactory<number> & {
create: (data: number | unknown) => NumberValueType & {
/**
* Adds a value to this number
*/
add: (value: number) => NumberValueType;
/**
* Subtracts a value from this number
*/
subtract: (value: number) => NumberValueType;
/**
* Multiplies this number by a factor
*/
multiply: (factor: number) => NumberValueType;
/**
* Divides this number by a divisor
*/
divide: (divisor: number) => NumberValueType;
/**
* Increments the value by the specified amount (defaults to 1)
*/
increment: (amount?: number) => NumberValueType;
/**
* Decrements the value by the specified amount (defaults to 1)
*/
decrement: (amount?: number) => NumberValueType;
/**
* Rounds this value to specified decimal places
*/
round: (decimals?: number) => NumberValueType;
/**
* Floors this value to the nearest integer or specified decimal place
*/
floor: (decimals?: number) => NumberValueType;
/**
* Ceils this value to the nearest integer or specified decimal place
*/
ceil: (decimals?: number) => NumberValueType;
/**
* Checks if this number is zero
*/
isZero: () => boolean;
/**
* Checks if this number is positive (greater than zero)
*/
isPositive: () => boolean;
/**
* Checks if this number is negative (less than zero)
*/
isNegative: () => boolean;
/**
* Checks if this number is an integer
*/
isInteger: () => boolean;
/**
* Returns the absolute value of this number
*/
abs: () => NumberValueType;
/**
* Calculates the power of this number
*/
pow: (exponent: number) => NumberValueType;
/**
* Calculates the square root of this number
*/
sqrt: () => NumberValueType;
/**
* Converts the number to a formatted string
*/
format: (locale?: string, options?: Intl.NumberFormatOptions) => string;
/**
* Formats the number as a percentage
*/
toPercentage: (locale?: string, decimals?: number) => string;
/**
* Formats the number as currency
*/
toCurrency: (currency: string, locale?: string) => string;
};
};
/**
* Identifier represents a unique identifier value object
*/
type IdentifierType = ValueObject<string>;
/**
* UUID-specific identifier type
*/
type UUIDIdentifierType = ValueObject<string> & {
/**
* Gets the version of this UUID
*/
getVersion(): number;
/**
* Converts UUID to a hyphen-free format
*/
toCompact(): string;
/**
* Gets specific segments of the UUID
*/
getSegment(index: number): string;
};
/**
* Numeric identifier type
*/
type NumericIdentifierType = ValueObject<number> & {
/**
* Returns the next sequential identifier
*/
next(): NumericIdentifierType;
/**
* Converts to string with optional padding
*/
toString(padLength?: number): string;
};
/**
* Identifier factory for creating unique identifiers
*/
declare const Identifier: ValueObjectFactory<string> & {
create: (data: string | unknown) => IdentifierType & {
/**
* Checks if this identifier matches a specific pattern
*/
matches: (pattern: RegExp) => boolean;
/**
* Formats the identifier according to a pattern
*/
format: (format: string) => string;
/**
* Returns a prefixed version of this identifier
*/
withPrefix: (prefix: string) => IdentifierType;
/**
* Returns a suffixed version of this identifier
*/
withSuffix: (suffix: string) => IdentifierType;
};
/**
* Creates a UUID-specific identifier value object
*/
uuid: () => ValueObjectFactory<string> & {
create: (data: string | unknown) => UUIDIdentifierType;
};
/**
* Creates a numeric identifier value object
*/
numeric: (options?: { min?: number }) => ValueObjectFactory<number> & {
create: (data: number | unknown) => NumericIdentifierType;
};
/**
* Creates an identifier that must match a specific pattern
*/
pattern: (pattern: RegExp, name?: string) => ValueObjectFactory<string>;
/**
* Generates a new UUID v4 identifier
*/
generateUUID: () => string;
};
/**
* Creates a Zod schema for validating value objects
*/
declare function valueObjectSchema<VOType>(options?: {
/**
* Name of the expected value object type
*/
typeName?: string;
/**
* Custom function to validate the type
*/
typeCheck?: (val: unknown) => boolean;
}): z.ZodType<VOType>;
/**
* Creates a Zod schema for validating specific value object types
*/
declare function specificValueObjectSchema<VOFactory>(
/**
* The value object factory
*/
valueObjectFactory: VOFactory
): z.ZodType;
/**
* An entity with standard methods
*/
type Entity<T> = T & {
/**
* Compares this entity with another for equality
*/
equals: (other: unknown) => boolean;
/**
* Returns a string representation of the entity
*/
toString: () => string;
[key: string]: unknown;
}
/**
* Represents all properties in T as optional
*/
type PartialOf<T> = {
[P in keyof T]?: T[P];
};
/**
* A factory for creating and managing entities
*/
type EntityFactory<SchemaType extends z.ZodType, T> = {
/**
* Creates a new instance of the entity
*/
create: (data: T) => Entity<T>;
/**
* Updates an entity with new values while preserving its identity
*/
update: (entity: Entity<T>, updates: PartialOf<T>) => Entity<T>;
/**
* The schema used for validation
*/
schema: SchemaType;
/**
* The field used as identity
*/
identity: string;
/**
* Creates an extended version of this entity with additional functionality
*/
extend: <NewSchemaType extends z.ZodType = SchemaType, NewT = T>(options: {
name: string;
schema?: (schema: SchemaType) => NewSchemaType;
methodsFactory: (factory: EntityFactory<SchemaType, T>) => Record<string, Function>;
identity?: string;
historize?: boolean;
}) => EntityFactory<NewSchemaType, NewT>;
}
/**
* Defines the structure of methods that will be bound to an entity instance
*/
type EntityMethods<T> = Record<string, (this: T, ...args: any[]) => any>;
/**
* Creates an entity factory
*
* Entities in Domain-Driven Design are:
* 1. Defined by their identity, not their attributes
* 2. Mutable - their state can change over time
* 3. Have a lifecycle - they can be created, updated, and deleted
* 4. Encapsulate domain logic and business rules
*/
declare function entity<SchemaType extends z.ZodType, T = z.infer<SchemaType>>(options: {
/**
* Name of the entity
*/
name: string;
/**
* Zod schema for validation
*/
schema: SchemaType;
/**
* Field name that serves as the identity
*/
identity: string;
/**
* Factory function that creates methods that will be bound to the entity instance
* The `this` context inside these methods will be the entity instance
*/
methodsFactory: (factory: EntityFactory<SchemaType, T>) => EntityMethods<T & Entity<T>>;
/**
* Whether to track state changes
*/
historize?: boolean;
}): EntityFactory<SchemaType, T>;
/**
* Defines a business rule invariant for an aggregate
*/
type InvariantDefinition = {
/**
* The name of the invariant
*/
name: string;
/**
* Function that returns true if the invariant is satisfied
*/
check: (data: unknown) => boolean;
/**
* Optional custom error message
*/
message?: string;
}
/**
* An aggregate with standard methods
*/
type Aggregate<T> = Entity<T> & {
[key: string]: unknown;
}
/**
* A factory for creating and managing aggregates
*/
type AggregateFactory<SchemaType extends z.ZodType, T> = {
/**
* Creates a new instance of the aggregate
*/
create: (data: T) => Aggregate<T>;
/**
* Updates an aggregate with new values while preserving its identity
*/
update: (aggregate: Aggregate<T>, updates: PartialOf<T>) => Aggregate<T>;
/**
* The schema used for validation
*/
schema: SchemaType;
/**
* The field used as identity
*/
identity: string;
/**
* The invariants for this aggregate
*/
invariants: InvariantDefinition[];
/**
* Creates an extended version of this aggregate with additional functionality
*/
extend: <NewSchemaType extends z.ZodType = SchemaType, NewT = T>(options: {
name: string;
schema?: (schema: SchemaType) => NewSchemaType;
methodsFactory: (factory: AggregateFactory<SchemaType, T>) => Record<string, Function>;
identity?: string;
invariants?: InvariantDefinition[];
historize?: boolean;
}) => AggregateFactory<NewSchemaType, NewT>;
}
/**
* Defines the structure of methods that will be bound to an aggregate instance
*/
type AggregateMethods<T> = Record<string, (this: T, ...args: any[]) => any>;
/**
* Creates an aggregate factory
*
* Aggregates in Domain-Driven Design are:
* 1. Clusters of entities and value objects treated as a single unit
* 2. Have a root entity that serves as the entry point
* 3. Maintain invariants (business rules) across the cluster
* 4. Define transactional boundaries
*/
declare function aggregate<SchemaType extends z.ZodType, T = z.infer<SchemaType>>(options: {
/**
* Name of the aggregate
*/
name: string;
/**
* Zod schema for validation
*/
schema: SchemaType;
/**
* Field name that serves as the identity
*/
identity: string;
/**
* Factory function that creates methods that will be bound to the aggregate instance
* The `this` context inside these methods will be the aggregate instance
*/
methodsFactory: (factory: AggregateFactory<SchemaType, T>) => AggregateMethods<T & Aggregate<T>>;
/**
* Business rules that must be satisfied
*/
invariants?: InvariantDefinition[];
/**
* Whether to track state changes
*/
historize?: boolean;
}): AggregateFactory<SchemaType, T>;
/**
* Aggregate with event sourcing capabilities
*/
type AggregateWithEvents = {
/**
* The domain events emitted by this aggregate
*/
_domainEvents: Array<Record<string, unknown>>;
/**
* Emits a new domain event
*/
emitEvent: (eventTypeOrFactory: string | { create: Function }, eventData: Record<string, unknown>) => AggregateWithEvents;
/**
* Gets all domain events
*/
getDomainEvents: () => Array<Record<string, unknown>>;
/**
* Clears all domain events
*/
clearDomainEvents: () => AggregateWithEvents;
}
/**
* Enhances an aggregate instance with event sourcing capabilities
*/
declare function withEvents<T>(
/**
* The aggregate instance to enhance
*/
aggregate: T
): T & AggregateWithEvents;
/**
* Updates an aggregate with event sourcing capabilities, preserving any existing events
*/
declare function updateWithEvents<T>(
/**
* The original aggregate with events
*/
originalAggregate: T & AggregateWithEvents,
/**
* The updated aggregate instance
*/
updatedAggregate: T
): T & AggregateWithEvents;
/**
* Base error class for domain-specific errors
*/
declare class DomainError extends Error {
constructor(
message: string,
cause?: Error
);
/**
* The cause of this error
*/
cause?: Error;
}
/**
* Error thrown when validation fails
*/
declare class ValidationError extends DomainError {
constructor(
message: string,
cause?: Error,
context?: Record<string, unknown>
);
/**
* Additional context about the validation error
*/
context: Record<string, unknown>;
}
/**
* Error thrown when an aggregate invariant is violated
*/
declare class InvariantViolationError extends DomainError {
constructor(
message: string,
invariantName: string,
context?: Record<string, unknown>
);
/**
* Name of the violated invariant
*/
invariantName: string;
/**
* Additional context about the violation
*/
context: Record<string, unknown>;
}
/**
* Error thrown when repository operations fail
*/
declare class RepositoryError extends DomainError {
constructor(
message: string,
cause?: Error,
context?: Record<string, unknown>
);
/**
* Additional context about the repository error
*/
context: Record<string, unknown>;
}
/**
* Error thrown when domain service operations fail
*/
declare class DomainServiceError extends DomainError {
constructor(
message: string,
cause?: Error,
context?: Record<string, unknown>
);
/**
* Additional context about the domain service error
*/
context: Record<string, unknown>;
}
/**
* A domain event with standard methods
*/
type DomainEvent<T> = T & {
/**
* The type of the event
*/
type: string;
/**
* The timestamp when the event occurred
*/
timestamp: Date;
/**
* Compares this event with another for equality
*/
equals: (other: unknown) => boolean;
/**
* Returns a string representation of the event
*/
toString: () => string;
[key: string]: unknown;
}
/**
* A factory for creating and managing domain events
*/
type DomainEventFactory<SchemaType extends z.ZodType, T> = {
/**
* The event type name
*/
type: string;
/**
* Creates a new instance of the domain event
*/
create: (data: T) => DomainEvent<T>;
/**
* The schema used for validation
*/
schema: SchemaType;
/**
* Metadata about the event
*/
metadata: Record<string, any>;
/**
* Creates an extended version of this event with additional functionality
*/
extend: <NewSchemaType extends z.ZodType = SchemaType, NewT = T>(options: {
name: string;
schema?: (schema: SchemaType) => NewSchemaType;
methodsFactory?: (factory: DomainEventFactory<SchemaType, T>) => Record<string, Function>;
metadata?: Record<string, any>;
}) => DomainEventFactory<NewSchemaType, NewT>;
}
/**
* Defines the structure of methods that will be bound to a domain event instance
*/
type DomainEventMethods<T> = Record<string, (this: T, ...args: any[]) => any>;
/**
* Creates a domain event factory
*
* Domain Events in Domain-Driven Design are:
* 1. Something that happened in the domain that domain experts care about
* 2. Immutable records of facts that occurred
* 3. Named using past-tense verbs (e.g., OrderPlaced, PaymentReceived)
* 4. Carriers of data relevant to the event
*/
declare function domainEvent<SchemaType extends z.ZodType, T = z.infer<SchemaType>>(options: {
/**
* Name of the event (should be past tense)
*/
name: string;
/**
* Zod schema for validation
*/
schema: SchemaType;
/**
* Factory function that creates methods that will be bound to the event instance
* The `this` context inside these methods will be the event instance
*/
methodsFactory?: (factory: DomainEventFactory<SchemaType, T>) => DomainEventMethods<T & DomainEvent<T>>;
/**
* Additional metadata about the event
*/
metadata?: Record<string, any>;
}): DomainEventFactory<SchemaType, T>;
/**
* Error thrown when event bus operations fail
*/
declare class EventBusError extends DomainError {
constructor(
message: string,
cause?: Error,
context?: Record<string, unknown>
);
context: Record<string, unknown>;
}
/**
* Subscription to an event
*/
type EventSubscription = {
/**
* Function to call to unsubscribe
*/
unsubscribe: () => void;
}
/**
* Adapter for event bus operations
*/
type EventBusAdapter = {
/**
* Function to publish an event
*/
publish: (event: unknown) => Promise<void>;
/**
* Function to subscribe to an event
*/
subscribe: (eventType: string, handler: Function) => Function;
}
/**
* Creates an event bus for publishing and subscribing to domain events
*/
declare function createEventBus(options?: {
/**
* Custom adapter for event bus operations
*/
adapter?: EventBusAdapter;
}): {
/**
* Publishes an event to all subscribers
*/
publish: (event: Record<string, unknown>) => Promise<void>;
/**
* Publishes multiple events in sequence
*/
publishAll: (events: Array<Record<string, unknown>>) => Promise<void>;
/**
* Subscribes to an event type
*/
on: (
eventTypeOrFactory: string | { type: string },
handler: Function,
options?: { once?: boolean }
) => EventSubscription;
/**
* Subscribes to an event type for a single invocation
*/
once: (
eventTypeOrFactory: string | { type: string },
handler: Function
) => EventSubscription;
/**
* Adds an event to the pending queue
*/
addPendingEvent: (event: Record<string, unknown>) => void;
/**
* Clears the pending events queue
*/
clearPendingEvents: () => Array<Record<string, unknown>>;
/**
* Publishes all pending events and clears the queue
*/
publishPendingEvents: () => Promise<void>;
/**
* Replaces the default implementation with a custom one
*/
setAdapter: (customAdapter: EventBusAdapter) => void;
/**
* Removes all event handlers
*/
reset: () => void;
};
/**
* Default event bus instance
*/
declare const eventBus: ReturnType<typeof createEventBus>;
/**
* Adapter for repository operations
*/
type RepositoryAdapter<T> = {
/**
* Find aggregate by ID
*/
findById: (id: string) => Promise<T | null>;
/**
* Find all aggregates matching filter
*/
findAll: (filter?: unknown) => Promise<T[]>;
/**
* Save aggregate
*/
save: (aggregate: T) => Promise<void>;
/**
* Delete aggregate by ID
*/
delete: (id: string) => Promise<void>;
/**
* Find aggregates by multiple IDs
*/
findByIds?: (ids: string[]) => Promise<Map<string, T>>;
/**
* Save multiple aggregates
*/
saveAll?: (aggregates: T[]) => Promise<void>;
/**
* Count aggregates matching filter
*/
count?: (filter?: unknown) => Promise<number>;
/**
* Find using specification
*/
findBySpecification?: (specification: unknown) => Promise<T[]>;
}
/**
* Creates a repository for an aggregate
*/
declare function repository<T>(options: {
/**
* The aggregate factory
*/
aggregate: {
name: string;
identity: string;
create: (data: unknown) => T;
};
/**
* Storage adapter
*/
adapter: RepositoryAdapter<T>;
/**
* Event handling options
*/
events?: {
/**
* Auto-publish events on save
*/
publishOnSave?: boolean;
/**
* Clear events after publishing
*/
clearAfterPublish?: boolean;
};
}): {
/**
* Finds an aggregate by its ID
*/
findById: (id: string) => Promise<T | null>;
/**
* Finds multiple aggregates by their IDs
*/
findByIds: (ids: string[]) => Promise<Map<string, T>>;
/**
* Finds all aggregates matching the optional filter
*/
findAll: (filter?: unknown) => Promise<T[]>;
/**
* Finds a single aggregate matching the filter
*/
findOne: (filter: unknown) => Promise<T | null>;
/**
* Finds aggregates using a specification
*/
findBySpecification: (specification: unknown) => Promise<T[]>;
/**
* Saves an aggregate and optionally publishes its events
*/
save: (aggregate: T) => Promise<void>;
/**
* Saves multiple aggregates in a batch
*/
saveAll: (aggregates: T[]) => Promise<void>;
/**
* Deletes an aggregate by its ID
*/
delete: (id: string) => Promise<void>;
/**
* Checks if an aggregate with the given ID exists
*/
exists: (id: string) => Promise<boolean>;
/**
* Counts aggregates matching the optional filter
*/
count: (filter?: unknown) => Promise<number>;
};
/**
* Creates an in-memory repository adapter
*/
declare function createInMemoryAdapter<T>(options: {
/**
* Identity field of the aggregate
*/
identity: string;
/**
* Initial data to populate the repository
*/
initialData?: T[];
}): RepositoryAdapter<T> & {
/**
* Find aggregate by ID
*/
findById: (id: string) => Promise<T | null>;
/**
* Find multiple aggregates by their IDs
*/
findByIds: (ids: string[]) => Promise<Map<string, T>>;
/**
* Find all aggregates matching filter
*/
findAll: (filter?: Record<string, unknown>) => Promise<T[]>;
/**
* Find aggregates using a specification
*/
findBySpecification: (specification: unknown) => Promise<T[]>;
/**
* Count aggregates matching filter
*/
count: (filter?: Record<string, unknown>) => Promise<number>;
/**
* Save aggregate
*/
save: (aggregate: T) => Promise<void>;
/**
* Save multiple aggregates
*/
saveAll: (aggregates: T[]) => Promise<void>;
/**
* Delete aggregate by ID
*/
delete: (id: string) => Promise<void>;
/**
* Clears all data from the store
*/
clear: () => void;
/**
* Gets the count of aggregates in the store
*/
size: () => number;
};
/**
* Configuration options for creating a specification
*/
type SpecificationOptions = {
/**
* The name of the specification
*/
name: string;
/**
* Function that tests if an object satisfies the specification
*/
isSatisfiedBy: (candidate: unknown) => boolean;
/**
* Optional function to convert specification to a query object
*/
toQuery?: () => Record<string, unknown>;
}
/**
* A specification that encapsulates a business rule
*/
type Specification<T> = {
/**
* The name of the specification
*/
name: string;
/**
* Tests if an object satisfies the specification
*/
isSatisfiedBy: (candidate: T) => boolean;
/**
* Returns a new specification that is the logical AND of this and another
*/
and: (other: Specification<T>) => Specification<T>;
/**
* Returns a new specification that is the logical OR of this and another
*/
or: (other: Specification<T>) => Specification<T>;
/**
* Returns a new specification that is the logical NOT of this one
*/
not: () => Specification<T>;
/**
* Converts specification to a query object for repositories
*/
toQuery?: () => Record<string, unknown>;
}
/**
* Creates a specification that encapsulates a business rule
*/
declare function specification<T>(
/**
* Specification configuration
*/
options: SpecificationOptions
): Specification<T>;
/**
* Creates a specification that checks if an object's property equals a specific value
*/
declare function propertyEquals<T>(
/**
* The name of the property to check
*/
propertyName: string,
/**
* The expected value of the property
*/
expectedValue: unknown,
/**
* Optional custom name for the specification
*/
specName?: string
): Specification<T>;
/**
* Creates a specification that checks if an object's property contains a specific value
*/
declare function propertyContains<T>(
/**
* The name of the property to check
*/
propertyName: string,
/**
* The value to check for
*/
value: unknown,
/**
* Optional custom name for the specification
*/
specName?: string
): Specification<T>;
/**
* Creates a specification that checks if an object's property matches a regular expression
*/
declare function propertyMatches<T>(
/**
* The name of the property to check
*/
propertyName: string,
/**
* The regular expression to match against
*/
pattern: RegExp,
/**
* Optional custom name for the specification
*/
specName?: string
): Specification<T>;
/**
* Creates a specification that checks if an object's property is greater than a specific value
*/
declare function propertyGreaterThan<T>(
/**
* The name of the property to check
*/
propertyName: string,
/**
* The value to compare against
*/
value: number,
/**
* Optional custom name for the specification
*/
specName?: string
): Specification<T>;
/**
* Creates a specification that checks if an object's property is less than a specific value
*/
declare function propertyLessThan<T>(
/**
* The name of the property to check
*/
propertyName: string,
/**
* The value to compare against
*/
value: number,
/**
* Optional custom name for the specification
*/
specName?: string
): Specification<T>;
/**
* Creates a specification that checks if an object's property is between min and max values
*/
declare function propertyBetween<T>(
/**
* The name of the property to check
*/
propertyName: string,
/**
* The minimum value (inclusive)
*/
min: number,
/**
* The maximum value (inclusive)
*/
max: number,
/**
* Optional custom name for the specification
*/
specName?: string
): Specification<T>;
/**
* Creates a specification that checks if an object's property is in a set of values
*/
declare function propertyIn<T>(
/**
* The name of the property to check
*/
propertyName: string,
/**
* The array of possible values
*/
values: unknown[],
/**
* Optional custom name for the specification
*/
specName?: string
): Specification<T>;
/**
* Creates a specification that checks if an object's property is null or undefined
*/
declare function propertyIsNull<T>(
/**
* The name of the property to check
*/
propertyName: string,
/**
* Optional custom name for the specification
*/
specName?: string
): Specification<T>;
/**
* Creates a specification that checks if an object's property is not null or undefined
*/
declare function propertyIsNotNull<T>(
/**
* The name of the property to check
*/
propertyName: string,
/**
* Optional custom name for the specification
*/
specName?: string
): Specification<T>;
/**
* Creates a specification that always returns true
*/
declare function alwaysTrue<T>(): Specification<T>;
/**
* Creates a specification that always returns false
*/
declare function alwaysFalse<T>(): Specification<T>;
/**
* Creates a parameterized specification for reuse with different values
*/
declare function parameterizedSpecification<T, P>(options: {
/**
* Base name of the specification
*/
name: string | ((params: P) => string);
/**
* Function that creates a predicate based on parameters
*/
createPredicate: (params: P) => (candidate: T) => boolean;
/**
* Function that creates a query based on parameters
*/
createQuery?: (params: P) => () => Record<string, unknown>;
}): (params: P) => Specification<T>;
/**
* Defines the structure of operations that will be bound to a domain service instance
*/
type DomainServiceOperations<D> = Record<string, (this: { serviceName: string, dependencies: D }, ...args: any[]) => any>;
/**
* Creates a domain service for encapsulating domain logic that doesn't belong to entities or value objects
*/
declare function domainService<D = Record<string, unknown>, O = Record<string, Function>>(options: {
/**
* Name of the service
*/
name: string;
/**
* Dependencies required by this service
*/
dependencies?: D;
/**
* Method factory function that creates operations
* @deprecated Use operationsFactory instead
*/
methodsFactory?: (factory: any) => Record<string, Function>;
/**
* Factory function that creates operations that will be bound to the service instance
* The `this` context inside these operations will be the service instance
*/
operationsFactory: (factory: any) => DomainServiceOperations<D>;
}): {
/**
* Creates a new domain service instance with the provided dependencies
*/
create: (injectedDependencies?: D) => {
/**
* Name of the service
*/
serviceName: string;
/**
* Dependencies injected into the service
*/
dependencies: D;
} & O;
/**
* Name of the service
*/
name: string;
/**
* Dependencies required by this service
*/
dependencies: D;
/**
* Extends this domain service with additional operations
*/
extend: <NewD = D, NewO = O>(options: {
/**
* The name of the extended service
*/
name: string;
/**
* Additional dependencies
*/
dependencies?: Partial<NewD>;
/**
* Method factory function that creates operations
* @deprecated Use operationsFactory instead
*/
methodsFactory?: (factory: any) => Record<string, Function>;
/**
* Factory function that creates operations that will be bound to the service instance
* The `this` context inside these operations will be the service instance
*/
operationsFactory: (factory: any) => DomainServiceOperations<D & NewD>;
}) => ReturnType<typeof domainService<D & NewD, O & NewO>>;
};
export { type Aggregate, type AggregateFactory, type AggregateWithEvents, DomainError, type DomainEvent, type DomainEventFactory, DomainServiceError, type Entity, type EntityFactory, type EventBusAdapter, EventBusError, type EventSubscription, Identifier, type IdentifierType, type InvariantDefinition, InvariantViolationError, NumberValue, type NumberValueType, type NumericIdentifierType, type PartialOf, type RepositoryAdapter, RepositoryError, type Specification, type SpecificationOptions, String, type StringValueType, type UUIDIdentifierType, ValidationError, type ValueObject, type ValueObjectFactory, aggregate, alwaysFalse, alwaysTrue, createEventBus, createInMemoryAdapter, domainEvent, domainService, entity, eventBus, parameterizedSpecification, propertyBetween, propertyContains, propertyEquals, propertyGreaterThan, propertyIn, propertyIsNotNull, propertyIsNull, propertyLessThan, propertyMatches, repository, specificValueObjectSchema, specification, updateWithEvents, valueObject, valueObjectSchema, withEvents };