@rineex/ddd 1.6.1 → 2.0.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/README.md CHANGED
@@ -844,41 +844,185 @@ export abstract class ApplicationError extends Error {
844
844
  #### `Result<T, E>`
845
845
 
846
846
  Represents the outcome of an operation that can either succeed or fail, without
847
- relying on exceptions for control flow.
847
+ relying on exceptions for control flow. This is a functional programming pattern
848
+ that makes error handling explicit in the type system and is commonly used in
849
+ Domain-Driven Design to represent domain operation outcomes.
850
+
851
+ **Key Features:**
852
+
853
+ - **Immutable**: Result instances are frozen to prevent accidental mutations
854
+ - **Type-Safe**: Full TypeScript support with generic types
855
+ - **Explicit Error Handling**: No hidden exceptions, all errors are explicit
856
+ - **DomainError Integration**: Works seamlessly with `DomainError` by default
848
857
 
849
858
  ```typescript
850
- export class Result<T, E> {
859
+ export class Result<T, E = DomainError> {
851
860
  readonly isSuccess: boolean;
852
861
  readonly isFailure: boolean;
853
862
 
854
- public static ok<T, E>(value: T): Result<T, E>;
855
- public static fail<T, E>(error: E): Result<T, E>;
856
- public getValue(): T;
857
- public getError(): E;
863
+ public static ok<T, E = never>(value: T): Result<T, E>;
864
+ public static fail<T = never, E = DomainError>(error: E): Result<T, E>;
865
+ public getValue(): T | undefined;
866
+ public getError(): E | undefined;
867
+ public isSuccessResult(): this is Result<T, never>;
868
+ public isFailureResult(): this is Result<never, E>;
858
869
  }
859
870
  ```
860
871
 
861
- **Example:**
872
+ **Basic Example:**
862
873
 
863
874
  ```typescript
864
- import { Result } from '@rineex/ddd';
875
+ import { Result, DomainError } from '@rineex/ddd';
865
876
 
866
- function parseNumber(input: string): Result<number, string> {
877
+ class InvalidValueError extends DomainError {
878
+ public get code() {
879
+ return 'DOMAIN.INVALID_VALUE' as const;
880
+ }
881
+
882
+ constructor(message: string) {
883
+ super({ message });
884
+ }
885
+ }
886
+
887
+ function parseNumber(input: string): Result<number, DomainError> {
867
888
  const value = Number(input);
868
889
  if (Number.isNaN(value)) {
869
- return Result.fail('Invalid number');
890
+ return Result.fail(new InvalidValueError('Invalid number'));
870
891
  }
871
892
  return Result.ok(value);
872
893
  }
873
894
 
874
895
  const result = parseNumber('42');
875
896
  if (result.isSuccess) {
876
- console.log(result.getValue()); // 42
897
+ const value = result.getValue(); // number | undefined
898
+ console.log(value); // 42
877
899
  } else {
878
- console.error(result.getError());
900
+ const error = result.getError(); // DomainError | undefined
901
+ console.error(error?.message);
902
+ }
903
+ ```
904
+
905
+ **Validation Pattern:**
906
+
907
+ ```typescript
908
+ function validateAge(age: number): Result<number, DomainError> {
909
+ if (age < 0) {
910
+ return Result.fail(new InvalidValueError('Age cannot be negative'));
911
+ }
912
+ if (age > 150) {
913
+ return Result.fail(new InvalidValueError('Age seems unrealistic'));
914
+ }
915
+ return Result.ok(age);
916
+ }
917
+
918
+ const result = validateAge(25);
919
+ if (result.isSuccess) {
920
+ console.log('Valid age:', result.getValue());
921
+ }
922
+ ```
923
+
924
+ **Chaining Pattern:**
925
+
926
+ ```typescript
927
+ function validateEmail(email: string): Result<string, DomainError> {
928
+ if (!email.includes('@')) {
929
+ return Result.fail(new InvalidValueError('Invalid email format'));
930
+ }
931
+ return Result.ok(email);
932
+ }
933
+
934
+ function createAccount(email: string): Result<{ email: string }, DomainError> {
935
+ const emailResult = validateEmail(email);
936
+ if (emailResult.isFailureResult()) {
937
+ return emailResult; // Forward the error
938
+ }
939
+
940
+ const validatedEmail = emailResult.getValue()!;
941
+ return Result.ok({ email: validatedEmail });
942
+ }
943
+ ```
944
+
945
+ **Using Type Guards:**
946
+
947
+ The `isSuccessResult()` and `isFailureResult()` methods provide type-safe
948
+ narrowing:
949
+
950
+ ```typescript
951
+ function processResult<T>(result: Result<T, DomainError>): void {
952
+ if (result.isSuccessResult()) {
953
+ // TypeScript narrows result to Result<T, never>
954
+ const value = result.getValue();
955
+ if (value) {
956
+ // Process the value with full type safety
957
+ console.log('Success:', value);
958
+ }
959
+ } else if (result.isFailureResult()) {
960
+ // TypeScript narrows result to Result<never, DomainError>
961
+ const error = result.getError();
962
+ if (error) {
963
+ // Access error properties with full type safety
964
+ console.error('Error code:', error.code);
965
+ console.error('Error message:', error.message);
966
+ }
967
+ }
879
968
  }
880
969
  ```
881
970
 
971
+ **Working with Domain Errors:**
972
+
973
+ ```typescript
974
+ class InvalidStateError extends DomainError {
975
+ public get code() {
976
+ return 'DOMAIN.INVALID_STATE' as const;
977
+ }
978
+
979
+ constructor(
980
+ message: string,
981
+ metadata?: Record<string, boolean | number | string>,
982
+ ) {
983
+ super({ message, metadata });
984
+ }
985
+ }
986
+
987
+ function processOrder(orderId: string): Result<Order, DomainError> {
988
+ const order = orderRepository.findById(orderId);
989
+ if (!order) {
990
+ return Result.fail(new InvalidValueError('Order not found', { orderId }));
991
+ }
992
+ if (order.status !== 'PENDING') {
993
+ return Result.fail(
994
+ new InvalidStateError('Order cannot be processed', {
995
+ orderId,
996
+ currentStatus: order.status,
997
+ }),
998
+ );
999
+ }
1000
+ return Result.ok(order);
1001
+ }
1002
+ ```
1003
+
1004
+ **Void Operations:**
1005
+
1006
+ ```typescript
1007
+ function deleteUser(id: number): Result<void, DomainError> {
1008
+ if (id <= 0) {
1009
+ return Result.fail(new InvalidValueError('Invalid user ID'));
1010
+ }
1011
+ // ... deletion logic ...
1012
+ return Result.ok(undefined);
1013
+ }
1014
+ ```
1015
+
1016
+ **Best Practices:**
1017
+
1018
+ 1. Always check `isSuccess` or `isFailure` before calling `getValue()` or
1019
+ `getError()`
1020
+ 2. Use `isSuccessResult()` and `isFailureResult()` type guards for better type
1021
+ narrowing when you need TypeScript to narrow the result type
1022
+ 3. Use `DomainError` for domain-specific errors to maintain consistency
1023
+ 4. Forward errors in chaining operations rather than creating new ones
1024
+ 5. Leverage TypeScript's type narrowing for safe value extraction
1025
+
882
1026
  ### Domain Violations
883
1027
 
884
1028
  #### `DomainViolation`
@@ -1453,8 +1597,23 @@ try {
1453
1597
  }
1454
1598
  }
1455
1599
 
1456
- // Using Result type (functional approach)
1457
- function createUser(email: string): Result<User, string> {
1600
+ // Using Result type (functional approach with DomainError)
1601
+ class InvalidEmailError extends DomainError {
1602
+ public get code() {
1603
+ return 'DOMAIN.INVALID_VALUE' as const;
1604
+ }
1605
+
1606
+ constructor(message: string) {
1607
+ super({ message });
1608
+ }
1609
+ }
1610
+
1611
+ function createUser(email: string): Result<User, DomainError> {
1612
+ // Validate email format
1613
+ if (!email.includes('@')) {
1614
+ return Result.fail(new InvalidEmailError('Invalid email format'));
1615
+ }
1616
+
1458
1617
  try {
1459
1618
  const emailVO = Email.create(email);
1460
1619
  const user = new User({
@@ -1464,19 +1623,32 @@ function createUser(email: string): Result<User, string> {
1464
1623
  });
1465
1624
  return Result.ok(user);
1466
1625
  } catch (error) {
1626
+ if (error instanceof InvalidValueObjectError) {
1627
+ return Result.fail(new InvalidEmailError(error.message));
1628
+ }
1467
1629
  return Result.fail(
1468
- error instanceof Error ? error.message : 'Unknown error',
1630
+ new InvalidEmailError(
1631
+ error instanceof Error ? error.message : 'Unknown error',
1632
+ ),
1469
1633
  );
1470
1634
  }
1471
1635
  }
1472
1636
 
1473
1637
  const result = createUser('user@example.com');
1474
- if (result.isSuccess) {
1638
+ if (result.isSuccessResult()) {
1475
1639
  const user = result.getValue();
1476
- // Use user
1477
- } else {
1640
+ if (user) {
1641
+ // Use user safely with full type safety
1642
+ console.log('User created:', user.id.toString());
1643
+ }
1644
+ } else if (result.isFailureResult()) {
1478
1645
  const error = result.getError();
1479
- // Handle error
1646
+ if (error) {
1647
+ // Handle error with full context and type safety
1648
+ console.error('Error code:', error.code);
1649
+ console.error('Error message:', error.message);
1650
+ console.error('Metadata:', error.metadata);
1651
+ }
1480
1652
  }
1481
1653
  ```
1482
1654
 
package/dist/index.d.mts CHANGED
@@ -521,141 +521,6 @@ declare const HttpStatusMessage: {
521
521
  };
522
522
  type HttpStatusMessage = (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];
523
523
 
524
- /**
525
- * Base class for Domain violations.
526
- * Purposely does NOT extend native Error to avoid stack trace overhead in the domain.
527
- */
528
- declare abstract class DomainViolation {
529
- abstract readonly code: string;
530
- abstract readonly message: string;
531
- readonly metadata: Readonly<Record<string, unknown>>;
532
- protected constructor(metadata?: Record<string, unknown>);
533
- }
534
-
535
- /**
536
- * Represents the outcome of an operation that can either succeed or fail,
537
- * without relying on exceptions for control flow.
538
- *
539
- * This pattern is commonly used in domain and application layers to make
540
- * success and failure states explicit, predictable, and type-safe.
541
- *
542
- * ## Design guarantees
543
- * - A `Result` is **immutable** once created.
544
- * - A `Result` is **exactly one of**:
545
- * - Success → contains a value
546
- * - Failure → contains an error
547
- * - Accessing the wrong side throws immediately (fail-fast).
548
- *
549
- * @typeParam T - Type of the success value
550
- * @typeParam E - Type of the failure error
551
- *
552
- * @example
553
- * ```ts
554
- * function parseNumber(input: string): Result<number, string> {
555
- * const value = Number(input);
556
- *
557
- * if (Number.isNaN(value)) {
558
- * return Result.fail('Invalid number');
559
- * }
560
- *
561
- * return Result.ok(value);
562
- * }
563
- *
564
- * const result = parseNumber('42');
565
- *
566
- * if (result.isSuccess) {
567
- * console.log(result.getValue()); // 42
568
- * } else {
569
- * console.error(result.getError());
570
- * }
571
- * ```
572
- */
573
- declare class Result<T, E> {
574
- private readonly _value?;
575
- private readonly _error?;
576
- /**
577
- * Indicates whether the result represents a failed outcome.
578
- *
579
- * This flag is mutually exclusive with {@link isSuccess}.
580
- */
581
- readonly isFailure: boolean;
582
- /**
583
- * Indicates whether the result represents a successful outcome.
584
- *
585
- * This flag is mutually exclusive with {@link isFailure}.
586
- */
587
- readonly isSuccess: boolean;
588
- /**
589
- * Creates a new {@link Result} instance.
590
- *
591
- * This constructor is private to enforce the use of
592
- * {@link Result.ok} and {@link Result.fail} factory methods,
593
- * preserving the success/failure invariants.
594
- *
595
- * @param _value - Success value (defined only for success results)
596
- * @param _error - Failure error (defined only for failure results)
597
- */
598
- private constructor();
599
- /**
600
- * Creates a failed {@link Result}.
601
- *
602
- * @param error - Error describing the failure
603
- * @returns A failure {@link Result} containing the provided error
604
- *
605
- * @example
606
- * ```ts
607
- * return Result.fail(new ValidationError('Email is invalid'));
608
- * ```
609
- */
610
- static fail<T, E>(error: E): Result<T, E>;
611
- /**
612
- * Creates a successful {@link Result}.
613
- *
614
- * @param value - Value representing a successful outcome
615
- * @returns A success {@link Result} containing the provided value
616
- *
617
- * @example
618
- * ```ts
619
- * return Result.ok(user);
620
- * ```
621
- */
622
- static ok<T, E>(value: T): Result<T, E>;
623
- /**
624
- * Returns the failure error.
625
- *
626
- * @returns The error associated with a failed result
627
- *
628
- * @throws {Error}
629
- * Thrown if this result represents a success.
630
- * This is a fail-fast guard against incorrect usage.
631
- *
632
- * @example
633
- * ```ts
634
- * if (result.isFailure) {
635
- * const error = result.getError();
636
- * }
637
- * ```
638
- */
639
- getError(): E;
640
- /**
641
- * Returns the success value.
642
- *
643
- * @returns The value associated with a successful result
644
- *
645
- * @throws {Error}
646
- * Thrown if this result represents a failure.
647
- * This is a fail-fast guard against incorrect usage.
648
- *
649
- * @example
650
- * ```ts
651
- * if (result.isSuccess) {
652
- * const value = result.getValue();
653
- * }
654
- * ```
655
- */
656
- getValue(): T;
657
- }
658
-
659
524
  /**
660
525
  * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.
661
526
  *
@@ -717,4 +582,4 @@ type UnwrapValueObject<T> = T extends ValueObject<infer V> ? UnwrapValueObject<V
717
582
  declare function unwrapValueObject<T>(input: T, seen?: WeakSet<object>): UnwrapValueObject<T>;
718
583
  declare function ensureObject<T>(input: UnwrapValueObject<T>): object;
719
584
 
720
- export { AggregateId, AggregateRoot, ApplicationError, type ApplicationServicePort, DomainError, type DomainErrorMetadata, DomainEvent, type DomainEventPayload, DomainViolation, Entity, type EntityId, type EntityProps, EntityValidationError, HttpStatus, type HttpStatusCode, HttpStatusMessage, InvalidValueObjectError, PrimitiveValueObject, type Props, Result, UUID, type UnixTimestampMillis, type UnwrapValueObject, ValueObject, deepFreeze, ensureObject, unwrapValueObject };
585
+ export { AggregateId, AggregateRoot, ApplicationError, type ApplicationServicePort, DomainError, type DomainErrorMetadata, DomainEvent, type DomainEventPayload, Entity, type EntityId, type EntityProps, EntityValidationError, HttpStatus, type HttpStatusCode, HttpStatusMessage, InvalidValueObjectError, PrimitiveValueObject, type Props, UUID, type UnixTimestampMillis, type UnwrapValueObject, ValueObject, deepFreeze, ensureObject, unwrapValueObject };
package/dist/index.d.ts CHANGED
@@ -521,141 +521,6 @@ declare const HttpStatusMessage: {
521
521
  };
522
522
  type HttpStatusMessage = (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];
523
523
 
524
- /**
525
- * Base class for Domain violations.
526
- * Purposely does NOT extend native Error to avoid stack trace overhead in the domain.
527
- */
528
- declare abstract class DomainViolation {
529
- abstract readonly code: string;
530
- abstract readonly message: string;
531
- readonly metadata: Readonly<Record<string, unknown>>;
532
- protected constructor(metadata?: Record<string, unknown>);
533
- }
534
-
535
- /**
536
- * Represents the outcome of an operation that can either succeed or fail,
537
- * without relying on exceptions for control flow.
538
- *
539
- * This pattern is commonly used in domain and application layers to make
540
- * success and failure states explicit, predictable, and type-safe.
541
- *
542
- * ## Design guarantees
543
- * - A `Result` is **immutable** once created.
544
- * - A `Result` is **exactly one of**:
545
- * - Success → contains a value
546
- * - Failure → contains an error
547
- * - Accessing the wrong side throws immediately (fail-fast).
548
- *
549
- * @typeParam T - Type of the success value
550
- * @typeParam E - Type of the failure error
551
- *
552
- * @example
553
- * ```ts
554
- * function parseNumber(input: string): Result<number, string> {
555
- * const value = Number(input);
556
- *
557
- * if (Number.isNaN(value)) {
558
- * return Result.fail('Invalid number');
559
- * }
560
- *
561
- * return Result.ok(value);
562
- * }
563
- *
564
- * const result = parseNumber('42');
565
- *
566
- * if (result.isSuccess) {
567
- * console.log(result.getValue()); // 42
568
- * } else {
569
- * console.error(result.getError());
570
- * }
571
- * ```
572
- */
573
- declare class Result<T, E> {
574
- private readonly _value?;
575
- private readonly _error?;
576
- /**
577
- * Indicates whether the result represents a failed outcome.
578
- *
579
- * This flag is mutually exclusive with {@link isSuccess}.
580
- */
581
- readonly isFailure: boolean;
582
- /**
583
- * Indicates whether the result represents a successful outcome.
584
- *
585
- * This flag is mutually exclusive with {@link isFailure}.
586
- */
587
- readonly isSuccess: boolean;
588
- /**
589
- * Creates a new {@link Result} instance.
590
- *
591
- * This constructor is private to enforce the use of
592
- * {@link Result.ok} and {@link Result.fail} factory methods,
593
- * preserving the success/failure invariants.
594
- *
595
- * @param _value - Success value (defined only for success results)
596
- * @param _error - Failure error (defined only for failure results)
597
- */
598
- private constructor();
599
- /**
600
- * Creates a failed {@link Result}.
601
- *
602
- * @param error - Error describing the failure
603
- * @returns A failure {@link Result} containing the provided error
604
- *
605
- * @example
606
- * ```ts
607
- * return Result.fail(new ValidationError('Email is invalid'));
608
- * ```
609
- */
610
- static fail<T, E>(error: E): Result<T, E>;
611
- /**
612
- * Creates a successful {@link Result}.
613
- *
614
- * @param value - Value representing a successful outcome
615
- * @returns A success {@link Result} containing the provided value
616
- *
617
- * @example
618
- * ```ts
619
- * return Result.ok(user);
620
- * ```
621
- */
622
- static ok<T, E>(value: T): Result<T, E>;
623
- /**
624
- * Returns the failure error.
625
- *
626
- * @returns The error associated with a failed result
627
- *
628
- * @throws {Error}
629
- * Thrown if this result represents a success.
630
- * This is a fail-fast guard against incorrect usage.
631
- *
632
- * @example
633
- * ```ts
634
- * if (result.isFailure) {
635
- * const error = result.getError();
636
- * }
637
- * ```
638
- */
639
- getError(): E;
640
- /**
641
- * Returns the success value.
642
- *
643
- * @returns The value associated with a successful result
644
- *
645
- * @throws {Error}
646
- * Thrown if this result represents a failure.
647
- * This is a fail-fast guard against incorrect usage.
648
- *
649
- * @example
650
- * ```ts
651
- * if (result.isSuccess) {
652
- * const value = result.getValue();
653
- * }
654
- * ```
655
- */
656
- getValue(): T;
657
- }
658
-
659
524
  /**
660
525
  * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.
661
526
  *
@@ -717,4 +582,4 @@ type UnwrapValueObject<T> = T extends ValueObject<infer V> ? UnwrapValueObject<V
717
582
  declare function unwrapValueObject<T>(input: T, seen?: WeakSet<object>): UnwrapValueObject<T>;
718
583
  declare function ensureObject<T>(input: UnwrapValueObject<T>): object;
719
584
 
720
- export { AggregateId, AggregateRoot, ApplicationError, type ApplicationServicePort, DomainError, type DomainErrorMetadata, DomainEvent, type DomainEventPayload, DomainViolation, Entity, type EntityId, type EntityProps, EntityValidationError, HttpStatus, type HttpStatusCode, HttpStatusMessage, InvalidValueObjectError, PrimitiveValueObject, type Props, Result, UUID, type UnixTimestampMillis, type UnwrapValueObject, ValueObject, deepFreeze, ensureObject, unwrapValueObject };
585
+ export { AggregateId, AggregateRoot, ApplicationError, type ApplicationServicePort, DomainError, type DomainErrorMetadata, DomainEvent, type DomainEventPayload, Entity, type EntityId, type EntityProps, EntityValidationError, HttpStatus, type HttpStatusCode, HttpStatusMessage, InvalidValueObjectError, PrimitiveValueObject, type Props, UUID, type UnixTimestampMillis, type UnwrapValueObject, ValueObject, deepFreeze, ensureObject, unwrapValueObject };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- var C=Object.create;var i=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames,D=Object.getOwnPropertySymbols,j=Object.getPrototypeOf,h=Object.prototype.hasOwnProperty,H=Object.prototype.propertyIsEnumerable;var S=(t,e,r)=>e in t?i(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,f=(t,e)=>{for(var r in e||(e={}))h.call(e,r)&&S(t,r,e[r]);if(D)for(var r of D(e))H.call(e,r)&&S(t,r,e[r]);return t};var F=(t,e)=>{for(var r in e)i(t,r,{get:e[r],enumerable:!0})},_=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of M(e))!h.call(t,n)&&n!==r&&i(t,n,{get:()=>e[n],enumerable:!(a=L(e,n))||a.enumerable});return t};var P=(t,e,r)=>(r=t!=null?C(j(t)):{},_(e||!t||!t.__esModule?i(r,"default",{value:t,enumerable:!0}):r,t)),k=t=>_(i({},"__esModule",{value:!0}),t);var z={};F(z,{AggregateId:()=>I,AggregateRoot:()=>O,ApplicationError:()=>N,DomainError:()=>o,DomainEvent:()=>g,DomainViolation:()=>R,Entity:()=>d,EntityValidationError:()=>y,HttpStatus:()=>q,HttpStatusMessage:()=>b,InvalidValueObjectError:()=>E,PrimitiveValueObject:()=>c,Result:()=>A,UUID:()=>p,ValueObject:()=>u,deepFreeze:()=>l,ensureObject:()=>Y,unwrapValueObject:()=>s});module.exports=k(z);var d=class{constructor(e){var r;this.id=e.id,this.createdAt=(r=e.createdAt)!=null?r:new Date}equals(e){return e==null?!1:this===e?!0:this.id.equals(e.id)}};var O=class extends d{constructor(){super(...arguments);this._domainEvents=[]}get domainEvents(){return[...this._domainEvents]}addEvent(r){this._domainEvents.push(r)}pullDomainEvents(){let r=[...this._domainEvents];return this._domainEvents.length=0,r}};var G=t=>t instanceof Error?{cause:{message:t.message,stack:t.stack,name:t.name}}:t?{cause:t}:{},o=class extends Error{constructor(e,r,a={}){super(e,f({},G(a.cause))),Object.setPrototypeOf(this,new.target.prototype),this.name=new.target.name,this.code=r,this.metadata=Object.freeze(f({},a))}};var c=class{constructor(e){this.validate(e),this.value=e}equals(e){return e==null||Object.getPrototypeOf(this)!==Object.getPrototypeOf(e)?!1:this.value===e.value}getValue(){return this.value}toJSON(){return this.value}toString(){return String(this.value)}};var v=P(require("fast-deep-equal/es6"));function l(t,e=new WeakSet){if(t==null||typeof t!="object"&&!Array.isArray(t)||Object.isFrozen(t)||e.has(t))return t;if(e.add(t),Array.isArray(t))t.forEach(r=>l(r,e));else for(let r in t)Object.hasOwn(t,r)&&l(t[r],e);return Object.freeze(t)}var u=class t{get value(){return this.props}constructor(e){this.validate(e),this.props=l(e)}static is(e){return e instanceof t}equals(e){return e==null||Object.getPrototypeOf(this)!==Object.getPrototypeOf(e)?!1:(0,v.default)(this.props,e.props)}toJSON(){return this.props}toString(){return JSON.stringify(this.props)}};var y=class extends o{constructor(e,r){super(e,"ENTITY_VALIDATION_ERROR",{cause:r})}};var E=class extends o{constructor(e){super(e,"INVALID_VALUE_OBJECT")}};var U=require("crypto"),g=class{constructor(e){var r;this.id=(r=e.id)!=null?r:(0,U.randomUUID)(),this.aggregateId=e.aggregateId,this.schemaVersion=e.schemaVersion,this.occurredAt=e.occurredAt,this.payload=Object.freeze(e.payload)}toPrimitives(){return{aggregateId:this.aggregateId.toString(),schemaVersion:this.schemaVersion,occurredAt:this.occurredAt,eventName:this.eventName,payload:this.payload,id:this.id}}};var x=require("uuid"),w=P(require("zod"));var T=class T extends c{constructor(e){super(e),this.validate(e)}static fromString(e){return new this(e)}static generate(){return new this((0,x.v4)())}validate(e){let r=T.schema.safeParse(e);if(!r.success)throw new E(`Invalid UUID: ${r.error.message}`)}};T.schema=w.default.uuid();var p=T;var I=class extends p{};var q=Object.freeze({REQUEST_HEADER_FIELDS_TOO_LARGE:431,NETWORK_AUTHENTICATION_REQUIRED:511,NON_AUTHORITATIVE_INFORMATION:203,PROXY_AUTHENTICATION_REQUIRED:407,UNAVAILABLE_FOR_LEGAL_REASONS:451,HTTP_VERSION_NOT_SUPPORTED:505,BANDWIDTH_LIMIT_EXCEEDED:509,VARIANT_ALSO_NEGOTIATES:506,UNSUPPORTED_MEDIA_TYPE:415,RANGE_NOT_SATISFIABLE:416,PRECONDITION_REQUIRED:428,INTERNAL_SERVER_ERROR:500,UNPROCESSABLE_ENTITY:422,INSUFFICIENT_STORAGE:507,SWITCHING_PROTOCOLS:101,PRECONDITION_FAILED:412,MISDIRECTED_REQUEST:421,SERVICE_UNAVAILABLE:503,TEMPORARY_REDIRECT:307,PERMANENT_REDIRECT:308,METHOD_NOT_ALLOWED:405,EXPECTATION_FAILED:417,MOVED_PERMANENTLY:301,PAYLOAD_TOO_LARGE:413,FAILED_DEPENDENCY:424,TOO_MANY_REQUESTS:429,ALREADY_REPORTED:208,MULTIPLE_CHOICES:300,PAYMENT_REQUIRED:402,UPGRADE_REQUIRED:426,PARTIAL_CONTENT:206,REQUEST_TIMEOUT:408,LENGTH_REQUIRED:411,NOT_IMPLEMENTED:501,GATEWAY_TIMEOUT:504,NOT_ACCEPTABLE:406,RESET_CONTENT:205,LOOP_DETECTED:508,MULTI_STATUS:207,NOT_MODIFIED:304,UNAUTHORIZED:401,URI_TOO_LONG:414,NOT_EXTENDED:510,EARLY_HINTS:103,BAD_REQUEST:400,IM_A_TEAPOT:418,BAD_GATEWAY:502,PROCESSING:102,NO_CONTENT:204,SEE_OTHER:303,USE_PROXY:305,FORBIDDEN:403,NOT_FOUND:404,TOO_EARLY:425,CONTINUE:100,ACCEPTED:202,CONFLICT:409,CREATED:201,IM_USED:226,LOCKED:423,FOUND:302,GONE:410,OK:200}),b={431:"Request Header Fields Too Large",511:"Network Authentication Required",203:"Non-Authoritative Information",407:"Proxy Authentication Required",451:"Unavailable For Legal Reasons",505:"HTTP Version Not Supported",509:"Bandwidth Limit Exceeded",506:"Variant Also Negotiates",415:"Unsupported Media Type",416:"Range Not Satisfiable",428:"Precondition Required",500:"Internal Server Error",422:"Unprocessable Entity",507:"Insufficient Storage",101:"Switching Protocols",412:"Precondition Failed",421:"Misdirected Request",503:"Service Unavailable",307:"Temporary Redirect",308:"Permanent Redirect",405:"Method Not Allowed",417:"Expectation Failed",301:"Moved Permanently",413:"Payload Too Large",424:"Failed Dependency",429:"Too Many Requests",208:"Already Reported",300:"Multiple Choices",402:"Payment Required",426:"Upgrade Required",206:"Partial Content",408:"Request Timeout",411:"Length Required",501:"Not Implemented",504:"Gateway Timeout",406:"Not Acceptable",205:"Reset Content",508:"Loop Detected",207:"Multi-Status",304:"Not Modified",401:"Unauthorized",414:"URI Too Long",418:"I'm a Teapot",510:"Not Extended",103:"Early Hints",400:"Bad Request",502:"Bad Gateway",102:"Processing",204:"No Content",303:"See Other",305:"Use Proxy",403:"Forbidden",404:"Not Found",425:"Too Early",100:"Continue",202:"Accepted",226:"I'm Used",409:"Conflict",201:"Created",423:"Locked",302:"Found",410:"Gone",200:"OK"};var R=class{constructor(e={}){this.metadata=Object.freeze(e)}};var A=class t{constructor(e,r){this._value=e;this._error=r;this.isSuccess=r===void 0,this.isFailure=!this.isSuccess,Object.freeze(this)}static fail(e){return new t(void 0,e)}static ok(e){return new t(e)}getError(){if(this.isSuccess)throw new Error("Result: Cannot get error of a success.");return this._error}getValue(){if(this.isFailure)throw new Error("Result: Cannot get value of a failure.");return this._value}};var N=class extends Error{constructor({code:e=b[500],isOperational:r=!1,status:a=500,metadata:n,message:m,cause:V}){super(m),this.name=new.target.name,this.code=e,this.status=a,this.isOperational=r,this.metadata=n,this.cause=V,Error.captureStackTrace(this,new.target)}};function s(t,e=new WeakSet){if(t==null||typeof t!="object")return t;if(e.has(t))throw new Error("Circular reference detected in ValueObject unwrap");if(e.add(t),Array.isArray(t)){let a=t.map(n=>s(n,e));return e.delete(t),a}if(t instanceof u){let a=s(t.value,e);return e.delete(t),a}if(t instanceof Date)return e.delete(t),t.toISOString();if(t instanceof Map){let a=new Map;return t.forEach((n,m)=>{a.set(m,s(n,e))}),e.delete(t),a}if(t instanceof Set){let a=new Set(Array.from(t.values()).map(n=>s(n,e)));return e.delete(t),a}let r={};for(let a in t)Object.hasOwn(t,a)&&(r[a]=s(t[a],e));return e.delete(t),r}function Y(t){return t==null?{}:typeof t=="object"?t:{value:t}}0&&(module.exports={AggregateId,AggregateRoot,ApplicationError,DomainError,DomainEvent,DomainViolation,Entity,EntityValidationError,HttpStatus,HttpStatusMessage,InvalidValueObjectError,PrimitiveValueObject,Result,UUID,ValueObject,deepFreeze,ensureObject,unwrapValueObject});
1
+ var w=Object.create;var s=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var L=Object.getOwnPropertyNames,A=Object.getOwnPropertySymbols,M=Object.getPrototypeOf,N=Object.prototype.hasOwnProperty,C=Object.prototype.propertyIsEnumerable;var D=(e,t,r)=>t in e?s(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r,O=(e,t)=>{for(var r in t||(t={}))N.call(t,r)&&D(e,r,t[r]);if(A)for(var r of A(t))C.call(t,r)&&D(e,r,t[r]);return e};var j=(e,t)=>{for(var r in t)s(e,r,{get:t[r],enumerable:!0})},_=(e,t,r,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of L(t))!N.call(e,n)&&n!==r&&s(e,n,{get:()=>t[n],enumerable:!(a=V(t,n))||a.enumerable});return e};var S=(e,t,r)=>(r=e!=null?w(M(e)):{},_(t||!e||!e.__esModule?s(r,"default",{value:e,enumerable:!0}):r,e)),H=e=>_(s({},"__esModule",{value:!0}),e);var q={};j(q,{AggregateId:()=>g,AggregateRoot:()=>f,ApplicationError:()=>b,DomainError:()=>o,DomainEvent:()=>I,Entity:()=>d,EntityValidationError:()=>y,HttpStatus:()=>k,HttpStatusMessage:()=>R,InvalidValueObjectError:()=>E,PrimitiveValueObject:()=>c,UUID:()=>p,ValueObject:()=>u,deepFreeze:()=>l,ensureObject:()=>G,unwrapValueObject:()=>i});module.exports=H(q);var d=class{constructor(t){var r;this.id=t.id,this.createdAt=(r=t.createdAt)!=null?r:new Date}equals(t){return t==null?!1:this===t?!0:this.id.equals(t.id)}};var f=class extends d{constructor(){super(...arguments);this._domainEvents=[]}get domainEvents(){return[...this._domainEvents]}addEvent(r){this._domainEvents.push(r)}pullDomainEvents(){let r=[...this._domainEvents];return this._domainEvents.length=0,r}};var F=e=>e instanceof Error?{cause:{message:e.message,stack:e.stack,name:e.name}}:e?{cause:e}:{},o=class extends Error{constructor(t,r,a={}){super(t,O({},F(a.cause))),Object.setPrototypeOf(this,new.target.prototype),this.name=new.target.name,this.code=r,this.metadata=Object.freeze(O({},a))}};var c=class{constructor(t){this.validate(t),this.value=t}equals(t){return t==null||Object.getPrototypeOf(this)!==Object.getPrototypeOf(t)?!1:this.value===t.value}getValue(){return this.value}toJSON(){return this.value}toString(){return String(this.value)}};var P=S(require("fast-deep-equal/es6"));function l(e,t=new WeakSet){if(e==null||typeof e!="object"&&!Array.isArray(e)||Object.isFrozen(e)||t.has(e))return e;if(t.add(e),Array.isArray(e))e.forEach(r=>l(r,t));else for(let r in e)Object.hasOwn(e,r)&&l(e[r],t);return Object.freeze(e)}var u=class e{get value(){return this.props}constructor(t){this.validate(t),this.props=l(t)}static is(t){return t instanceof e}equals(t){return t==null||Object.getPrototypeOf(this)!==Object.getPrototypeOf(t)?!1:(0,P.default)(this.props,t.props)}toJSON(){return this.props}toString(){return JSON.stringify(this.props)}};var y=class extends o{constructor(t,r){super(t,"ENTITY_VALIDATION_ERROR",{cause:r})}};var E=class extends o{constructor(t){super(t,"INVALID_VALUE_OBJECT")}};var U=require("crypto"),I=class{constructor(t){var r;this.id=(r=t.id)!=null?r:(0,U.randomUUID)(),this.aggregateId=t.aggregateId,this.schemaVersion=t.schemaVersion,this.occurredAt=t.occurredAt,this.payload=Object.freeze(t.payload)}toPrimitives(){return{aggregateId:this.aggregateId.toString(),schemaVersion:this.schemaVersion,occurredAt:this.occurredAt,eventName:this.eventName,payload:this.payload,id:this.id}}};var h=require("uuid"),v=S(require("zod"));var T=class T extends c{constructor(t){super(t),this.validate(t)}static fromString(t){return new this(t)}static generate(){return new this((0,h.v4)())}validate(t){let r=T.schema.safeParse(t);if(!r.success)throw new E(`Invalid UUID: ${r.error.message}`)}};T.schema=v.default.uuid();var p=T;var g=class extends p{};var k=Object.freeze({REQUEST_HEADER_FIELDS_TOO_LARGE:431,NETWORK_AUTHENTICATION_REQUIRED:511,NON_AUTHORITATIVE_INFORMATION:203,PROXY_AUTHENTICATION_REQUIRED:407,UNAVAILABLE_FOR_LEGAL_REASONS:451,HTTP_VERSION_NOT_SUPPORTED:505,BANDWIDTH_LIMIT_EXCEEDED:509,VARIANT_ALSO_NEGOTIATES:506,UNSUPPORTED_MEDIA_TYPE:415,RANGE_NOT_SATISFIABLE:416,PRECONDITION_REQUIRED:428,INTERNAL_SERVER_ERROR:500,UNPROCESSABLE_ENTITY:422,INSUFFICIENT_STORAGE:507,SWITCHING_PROTOCOLS:101,PRECONDITION_FAILED:412,MISDIRECTED_REQUEST:421,SERVICE_UNAVAILABLE:503,TEMPORARY_REDIRECT:307,PERMANENT_REDIRECT:308,METHOD_NOT_ALLOWED:405,EXPECTATION_FAILED:417,MOVED_PERMANENTLY:301,PAYLOAD_TOO_LARGE:413,FAILED_DEPENDENCY:424,TOO_MANY_REQUESTS:429,ALREADY_REPORTED:208,MULTIPLE_CHOICES:300,PAYMENT_REQUIRED:402,UPGRADE_REQUIRED:426,PARTIAL_CONTENT:206,REQUEST_TIMEOUT:408,LENGTH_REQUIRED:411,NOT_IMPLEMENTED:501,GATEWAY_TIMEOUT:504,NOT_ACCEPTABLE:406,RESET_CONTENT:205,LOOP_DETECTED:508,MULTI_STATUS:207,NOT_MODIFIED:304,UNAUTHORIZED:401,URI_TOO_LONG:414,NOT_EXTENDED:510,EARLY_HINTS:103,BAD_REQUEST:400,IM_A_TEAPOT:418,BAD_GATEWAY:502,PROCESSING:102,NO_CONTENT:204,SEE_OTHER:303,USE_PROXY:305,FORBIDDEN:403,NOT_FOUND:404,TOO_EARLY:425,CONTINUE:100,ACCEPTED:202,CONFLICT:409,CREATED:201,IM_USED:226,LOCKED:423,FOUND:302,GONE:410,OK:200}),R={431:"Request Header Fields Too Large",511:"Network Authentication Required",203:"Non-Authoritative Information",407:"Proxy Authentication Required",451:"Unavailable For Legal Reasons",505:"HTTP Version Not Supported",509:"Bandwidth Limit Exceeded",506:"Variant Also Negotiates",415:"Unsupported Media Type",416:"Range Not Satisfiable",428:"Precondition Required",500:"Internal Server Error",422:"Unprocessable Entity",507:"Insufficient Storage",101:"Switching Protocols",412:"Precondition Failed",421:"Misdirected Request",503:"Service Unavailable",307:"Temporary Redirect",308:"Permanent Redirect",405:"Method Not Allowed",417:"Expectation Failed",301:"Moved Permanently",413:"Payload Too Large",424:"Failed Dependency",429:"Too Many Requests",208:"Already Reported",300:"Multiple Choices",402:"Payment Required",426:"Upgrade Required",206:"Partial Content",408:"Request Timeout",411:"Length Required",501:"Not Implemented",504:"Gateway Timeout",406:"Not Acceptable",205:"Reset Content",508:"Loop Detected",207:"Multi-Status",304:"Not Modified",401:"Unauthorized",414:"URI Too Long",418:"I'm a Teapot",510:"Not Extended",103:"Early Hints",400:"Bad Request",502:"Bad Gateway",102:"Processing",204:"No Content",303:"See Other",305:"Use Proxy",403:"Forbidden",404:"Not Found",425:"Too Early",100:"Continue",202:"Accepted",226:"I'm Used",409:"Conflict",201:"Created",423:"Locked",302:"Found",410:"Gone",200:"OK"};var b=class extends Error{constructor({code:t=R[500],isOperational:r=!1,status:a=500,metadata:n,message:m,cause:x}){super(m),this.name=new.target.name,this.code=t,this.status=a,this.isOperational=r,this.metadata=n,this.cause=x,Error.captureStackTrace(this,new.target)}};function i(e,t=new WeakSet){if(e==null||typeof e!="object")return e;if(t.has(e))throw new Error("Circular reference detected in ValueObject unwrap");if(t.add(e),Array.isArray(e)){let a=e.map(n=>i(n,t));return t.delete(e),a}if(e instanceof u){let a=i(e.value,t);return t.delete(e),a}if(e instanceof Date)return t.delete(e),e.toISOString();if(e instanceof Map){let a=new Map;return e.forEach((n,m)=>{a.set(m,i(n,t))}),t.delete(e),a}if(e instanceof Set){let a=new Set(Array.from(e.values()).map(n=>i(n,t)));return t.delete(e),a}let r={};for(let a in e)Object.hasOwn(e,a)&&(r[a]=i(e[a],t));return t.delete(e),r}function G(e){return e==null?{}:typeof e=="object"?e:{value:e}}0&&(module.exports={AggregateId,AggregateRoot,ApplicationError,DomainError,DomainEvent,Entity,EntityValidationError,HttpStatus,HttpStatusMessage,InvalidValueObjectError,PrimitiveValueObject,UUID,ValueObject,deepFreeze,ensureObject,unwrapValueObject});
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/domain/entities/entity.ts","../src/domain/aggregates/aggregate-root.ts","../src/domain/base/domain.error.ts","../src/domain/base/primitive-vo.ts","../src/domain/base/vo.ts","../src/utils/deep-freeze.util.ts","../src/domain/errors/entity-validation.error.ts","../src/domain/errors/invalid-vo.error.ts","../src/domain/events/domain.event.ts","../src/domain/value-objects/id.vo.ts","../src/domain/value-objects/aggregate-id.vo.ts","../src/gateway/constants/http-code.ts","../src/shared/domain/domain.violation.ts","../src/shared/domain/result.ts","../src/utils/errors/application.error.ts","../src/utils/unwrap-vo.util.ts"],"sourcesContent":["export * from './application';\nexport * from './domain/aggregates';\nexport * from './domain/base/domain.error';\nexport * from './domain/base/primitive-vo';\nexport * from './domain/base/vo';\nexport * from './domain/entities';\nexport * from './domain/errors/entity-validation.error';\nexport * from './domain/errors/invalid-vo.error';\nexport * from './domain/events';\nexport * from './domain/types';\nexport * from './domain/value-objects/aggregate-id.vo';\nexport * from './domain/value-objects/id.vo';\nexport * from './gateway/constants/http-code';\nexport * from './shared/domain';\nexport * from './utils';\n","import { EntityId } from '../types';\n\n/**\n * Configuration for the base Entity constructor.\n * Forces a single-object argument pattern to avoid positional argument errors.\n * @template ID - A type satisfying the EntityId interface.\n */\nexport interface EntityProps<ID extends EntityId, Props> {\n /** The unique identity of the entity */\n readonly id: ID;\n /** Optional creation timestamp; defaults to 'now' if not provided */\n readonly createdAt?: Date;\n\n readonly props: Props;\n}\n\n/**\n * Abstract Base Entity for Domain-Driven Design (DDD).\n * This class provides the standard contract for entity equality and identity.\n * It intentionally avoids \"magic\" property bags to ensure V8 engine optimization\n * and better IDE intellisense.\n * @template ID - The specific Identity Value Object type.\n */\nexport abstract class Entity<ID extends EntityId, Props> {\n /** The timestamp when this entity was first instantiated/created */\n public readonly createdAt: Date;\n /** The immutable unique identifier for this entity */\n public readonly id: ID;\n\n /**\n * Protected constructor to be called by subclasses.\n * @param props - Initial identity and metadata.\n */\n protected constructor(props: EntityProps<ID, Props>) {\n this.id = props.id;\n this.createdAt = props.createdAt ?? new Date();\n }\n\n /**\n * Compares entities by identity.\n * In DDD, two entities are considered equal if their IDs match,\n * regardless of their other properties.\n * @param other - The entity to compare against.\n * @returns True if IDs are equal.\n */\n public equals(other?: Entity<ID, Props>): boolean {\n if (other == null) return false;\n if (this === other) return true;\n return this.id.equals(other.id);\n }\n\n /**\n * Converts the Entity into a plain Javascript object.\n * Subclasses must implement this to explicitly control serialization,\n * @returns A plain object representation of the entity.\n */\n public abstract toObject(): Record<string, unknown>;\n\n /**\n * Validates the current state of the entity against domain invariants.\n * This method should be called after construction and any mutation.\n * @throws {Error} Should throw a specific DomainError if validation fails.\n */\n public abstract validate(): void;\n}\n","import { Entity, EntityProps } from '../entities/entity';\nimport { DomainEvent } from '../events';\nimport { EntityId } from '../types';\n\n/**\n * Interface for AggregateRoot to ensure type safety and extensibility.\n */\nexport interface Props<P> extends EntityProps<EntityId, P> {\n readonly domainEvents: readonly DomainEvent[];\n /**\n * Adds a domain event to the aggregate.\n * @param event The domain event to add.\n */\n addEvent: (event: DomainEvent) => void;\n\n /**\n * Retrieves and clears all domain events recorded by this aggregate.\n *\n * Domain events represent facts that occurred as a result of state changes\n * within the aggregate. This method transfers ownership of those events\n * to the application layer for further processing (e.g. publishing).\n *\n * Calling this method has the side effect of clearing the aggregate's\n * internal event collection to prevent duplicate handling.\n *\n * This method is intended to be invoked by application services\n * after the aggregate has been successfully persisted.\n *\n * @returns A read-only list of domain events raised by this aggregate.\n */\n pullDomainEvents: () => readonly DomainEvent[];\n}\n\n/**\n * Base class for aggregate roots in DDD, encapsulating domain events and validation.\n * @template EntityProps The type of the entity's properties.\n */\nexport abstract class AggregateRoot<ID extends EntityId, P> extends Entity<\n ID,\n P\n> {\n /**\n * Gets a read-only copy of the domain events.\n */\n get domainEvents(): readonly DomainEvent[] {\n return [...this._domainEvents];\n }\n\n /**\n * Internal list of domain events.\n */\n private readonly _domainEvents: DomainEvent[] = [];\n\n /**\n * Adds a domain event to the aggregate after validating invariants.\n * @param domainEvent The domain event to add.\n * @throws {EntityValidationError} If invariants are not met.\n */\n addEvent(domainEvent: DomainEvent): void {\n this._domainEvents.push(domainEvent);\n }\n\n public pullDomainEvents(): readonly DomainEvent[] {\n const events = [...this._domainEvents];\n this._domainEvents.length = 0;\n return events;\n }\n}\n","export interface DomainErrorMetadata {\n cause?: { name: string; message: string; stack?: string };\n [key: string]: unknown;\n}\n\nconst getCauseInfo = (cause: Error | undefined) => {\n // 1. Handle Error objects specifically\n if (cause instanceof Error) {\n return {\n cause: {\n message: cause.message,\n stack: cause.stack,\n name: cause.name,\n },\n };\n }\n\n // 2. Handle other existing values\n if (cause) {\n return { cause };\n }\n\n // 3. Default to empty\n return {};\n};\n\n/**\n * Base class for all Domain Errors in the application.\n *\n * This class ensures:\n * 1. Serializable and structured for logs or API responses.\n * 2. Identifiable via stable error codes (not just class names).\n * 3. Contextual with optional structured metadata.\n * 4. Supports error chaining (cause) and stack trace preservation.\n *\n * @example\n * export class InsufficientFundsError extends DomainError {\n * constructor(accountId: string, currentBalance: number) {\n * super(\n * `Account ${accountId} has insufficient funds.`,\n * 'INSUFFICIENT_FUNDS',\n * { accountId, currentBalance }\n * );\n * }\n * }\n */\nexport abstract class DomainError extends Error {\n /** Stable, machine-readable error code */\n public readonly code: string;\n /** Structured, immutable domain metadata */\n public readonly metadata: Readonly<DomainErrorMetadata>;\n\n /**\n * @param message - Human-readable error message\n * @param code - Stable error code\n * @param metadata - Domain-specific structured data; optional `cause` can be included\n */\n protected constructor(\n message: string,\n code: string,\n metadata: DomainErrorMetadata = {},\n ) {\n super(message, { ...getCauseInfo(metadata.cause) });\n\n // Restore prototype chain for proper `instanceof` checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n this.name = new.target.name;\n this.code = code;\n this.metadata = Object.freeze({ ...metadata });\n }\n}\n","import { EntityId } from '../types';\n\ntype Primitive = boolean | number | string;\n\n/**\n * Base class for primitive-based Value Objects.\n *\n * This class is intended for Value Objects that are represented by\n * a single primitive value (string, number, or boolean).\n *\n * Characteristics:\n * - Immutable by construction\n * - Cheap equality comparison\n * - No deep cloning or freezing\n * - Safe for serialization and logging\n *\n * Examples:\n * - AggregateId\n * - EmailAddress\n * - Username\n * - Slug\n */\nexport abstract class PrimitiveValueObject<\n T extends Primitive,\n> implements EntityId {\n /**\n * The underlying primitive value.\n * Guaranteed to be valid after construction.\n */\n protected readonly value: T;\n\n /**\n * Constructs a new PrimitiveValueObject.\n *\n * @param value - The primitive value to wrap\n * @throws Error if validation fails\n */\n protected constructor(value: T) {\n this.validate(value);\n this.value = value;\n }\n\n /**\n * Compares two Value Objects for equality.\n *\n * Equality rules:\n * - Same concrete class\n * - Same primitive value (===)\n *\n * @param other - Another Value Object\n */\n public equals(other?: PrimitiveValueObject<T> | null | undefined): boolean {\n if (other === undefined || other === null) return false;\n\n if (Object.getPrototypeOf(this) !== Object.getPrototypeOf(other)) {\n return false;\n }\n\n return this.value === other.value;\n }\n\n /**\n * Returns the primitive value.\n * Prefer explicit access over implicit coercion.\n */\n public getValue(): T {\n return this.value;\n }\n\n /**\n * JSON serialization hook.\n * Produces the raw primitive value.\n */\n public toJSON(): T {\n return this.value;\n }\n\n /**\n * String representation.\n * Useful for logging and debugging.\n */\n public toString(): string {\n return String(this.value);\n }\n\n /**\n * Domain invariant validation.\n * Must throw if the value is invalid.\n *\n * @param value - The value to validate\n */\n protected abstract validate(value: T): void;\n}\n","import deepEqual from 'fast-deep-equal/es6';\n\nimport { deepFreeze } from '@/utils/deep-freeze.util';\n\nexport abstract class ValueObject<T> {\n get value(): T {\n return this.props;\n }\n\n protected readonly props: Readonly<T>;\n\n protected constructor(props: T) {\n this.validate(props);\n this.props = deepFreeze(props);\n }\n\n /**\n * Type guard to check if an unknown object is an instance of ValueObject.\n * This is useful for runtime type checking.\n *\n * @param vo The object to check.\n * @returns True if the object is a ValueObject instance, false otherwise.\n */\n public static is(vo: unknown): vo is ValueObject<unknown> {\n return vo instanceof ValueObject;\n }\n\n /**\n * Deep equality comparison of ValueObjects\n */\n public equals(other?: ValueObject<T>): boolean {\n if (other === null || other === undefined) return false;\n\n // Check if they share the same constructor (Type check)\n if (Object.getPrototypeOf(this) !== Object.getPrototypeOf(other)) {\n return false;\n }\n\n return deepEqual(this.props, other.props);\n }\n\n /**\n * Standard for clean API integration and logging.\n */\n public toJSON(): T {\n return this.props;\n }\n\n /**\n * Useful for debugging and string-based indexing.\n */\n public toString(): string {\n return JSON.stringify(this.props);\n }\n\n /**\n * Validates the value object props\n * @throws InvalidValueObjectError if validation fails\n */\n protected abstract validate(props: T): void;\n}\n","/**\n * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.\n *\n * @param obj - The object to be deeply frozen.\n * @param seen - A WeakSet to track already processed objects (for circular references).\n * @returns A deeply frozen version of the input object.\n */\nexport function deepFreeze<T>(\n obj: T,\n seen = new WeakSet<object>(),\n): Readonly<T> {\n // Handle null, undefined, or non-object types\n if (obj == null || (typeof obj !== 'object' && !Array.isArray(obj))) {\n return obj;\n }\n\n // Skip if already frozen\n if (Object.isFrozen(obj)) {\n return obj as Readonly<T>;\n }\n\n // Handle circular references\n if (seen.has(obj as object)) {\n return obj as Readonly<T>;\n }\n\n seen.add(obj as object);\n\n // Handle arrays explicitly\n if (Array.isArray(obj)) {\n obj.forEach(item => deepFreeze(item, seen));\n } else {\n // Handle plain objects\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n deepFreeze((obj as Record<string, unknown>)[key], seen);\n }\n }\n }\n\n return Object.freeze(obj) as Readonly<T>;\n}\n","import { DomainError } from '../base/domain.error';\n\n/**\n * Custom error class for entity validation failures.\n */\nexport class EntityValidationError extends DomainError {\n constructor(message: string, cause?: Error) {\n super(message, 'ENTITY_VALIDATION_ERROR', { cause });\n }\n}\n","import { DomainError } from '../base/domain.error';\n\nexport class InvalidValueObjectError extends DomainError {\n constructor(message: string) {\n super(message, 'INVALID_VALUE_OBJECT');\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { EntityId } from '../types';\n\ntype Primitive = boolean | number | string | null;\n\ntype Serializable =\n | Primitive\n | Serializable[]\n | { [key: string]: Serializable };\n\nexport type DomainEventPayload = Record<string, Serializable>;\n\nexport type UnixTimestampMillis = number;\n\ntype DomainEventProps<AggregateId extends EntityId, Payload> = {\n id?: string;\n aggregateId: AggregateId;\n schemaVersion: number;\n occurredAt: UnixTimestampMillis;\n payload: Payload;\n};\n\n// Abstract base class for domain events\nexport abstract class DomainEvent<\n AggregateId extends EntityId = EntityId,\n T extends DomainEventPayload = DomainEventPayload,\n> {\n public readonly aggregateId: AggregateId;\n\n public abstract readonly eventName: string;\n public readonly id: string;\n public readonly occurredAt: number;\n public readonly payload: Readonly<T>;\n public readonly schemaVersion: number;\n\n protected constructor(props: DomainEventProps<AggregateId, T>) {\n this.id = props.id ?? randomUUID();\n this.aggregateId = props.aggregateId;\n this.schemaVersion = props.schemaVersion;\n this.occurredAt = props.occurredAt;\n this.payload = Object.freeze(props.payload);\n }\n\n public toPrimitives(): Readonly<{\n id: string;\n eventName: string;\n aggregateId: string;\n schemaVersion: number;\n occurredAt: UnixTimestampMillis;\n payload: T;\n }> {\n return {\n aggregateId: this.aggregateId.toString(),\n schemaVersion: this.schemaVersion,\n occurredAt: this.occurredAt,\n eventName: this.eventName,\n payload: this.payload,\n id: this.id,\n };\n }\n}\n","import { v4 } from 'uuid';\nimport z from 'zod';\n\nimport { InvalidValueObjectError } from '../errors/invalid-vo.error';\nimport { PrimitiveValueObject } from '../base/primitive-vo';\n\n/**\n * Represents a UUID (Universally Unique Identifier) value object.\n *\n * This class extends PrimitiveValueObject to provide type-safe UUID handling\n * with validation using Zod schema. UUIDs are immutable and can be generated\n * randomly or created from string values.\n *\n * @example\n * // Generate a new random UUID\n * const id = UUID.generate();\n *\n * @example\n * // Create UUID from an existing string\n * const id = UUID.fromString('550e8400-e29b-41d4-a716-446655440000');\n *\n * @throws {InvalidValueObjectError} When the provided string is not a valid UUID format\n */\nexport class UUID extends PrimitiveValueObject<string> {\n private static readonly schema = z.uuid();\n\n public constructor(value: string) {\n super(value);\n this.validate(value);\n }\n\n /**\n * Creates an UUID from an external string.\n * Use only for untrusted input.\n *\n * @param value - UUID string\n */\n public static fromString(value: string): UUID {\n return new this(value);\n }\n\n /**\n * Generates a new AggregateId.\n */\n public static generate<T extends typeof UUID>(this: T): InstanceType<T> {\n return new this(v4()) as InstanceType<T>;\n }\n\n protected validate(value: string): void {\n const result = UUID.schema.safeParse(value);\n\n if (!result.success) {\n throw new InvalidValueObjectError(\n `Invalid UUID: ${result.error.message}`,\n );\n }\n }\n}\n","import { UUID } from './id.vo';\n\n/**\n * AggregateId represents a strongly-typed aggregate identifier.\n *\n * - Backed by UUID v4\n * - Immutable\n * - Comparable only to AggregateId\n */\nexport class AggregateId extends UUID {}\n","/**\n * HTTP status code catalog.\n *\n * This object provides a typed, immutable map of standard HTTP status names\n * to their numeric codes. Designed for server-side frameworks such as Fastify.\n *\n * - All identifiers use clear, canonical semantic names.\n * - Values are numeric status codes.\n * - Frozen to prevent runtime mutation.\n * - Exporting `HttpStatus` ensures type-safe usage across the codebase.\n * Usage:\n * ```ts\n * import { HttpStatus } from 'path-to-this-file';\n *\n * function handleRequest() {\n * return {\n * statusCode: HttpStatus.OK,\n * body: 'Success',\n * };\n * }\n * ```\n */\nexport const HttpStatus = Object.freeze({\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n NON_AUTHORITATIVE_INFORMATION: 203,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n BANDWIDTH_LIMIT_EXCEEDED: 509,\n VARIANT_ALSO_NEGOTIATES: 506,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n PRECONDITION_REQUIRED: 428,\n INTERNAL_SERVER_ERROR: 500,\n UNPROCESSABLE_ENTITY: 422,\n INSUFFICIENT_STORAGE: 507,\n\n SWITCHING_PROTOCOLS: 101,\n PRECONDITION_FAILED: 412,\n MISDIRECTED_REQUEST: 421,\n SERVICE_UNAVAILABLE: 503,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n METHOD_NOT_ALLOWED: 405,\n EXPECTATION_FAILED: 417,\n\n MOVED_PERMANENTLY: 301,\n PAYLOAD_TOO_LARGE: 413,\n FAILED_DEPENDENCY: 424,\n TOO_MANY_REQUESTS: 429,\n ALREADY_REPORTED: 208,\n MULTIPLE_CHOICES: 300,\n PAYMENT_REQUIRED: 402,\n UPGRADE_REQUIRED: 426,\n PARTIAL_CONTENT: 206,\n REQUEST_TIMEOUT: 408,\n LENGTH_REQUIRED: 411,\n NOT_IMPLEMENTED: 501,\n GATEWAY_TIMEOUT: 504,\n NOT_ACCEPTABLE: 406,\n RESET_CONTENT: 205,\n LOOP_DETECTED: 508,\n MULTI_STATUS: 207,\n NOT_MODIFIED: 304,\n UNAUTHORIZED: 401,\n URI_TOO_LONG: 414,\n NOT_EXTENDED: 510,\n EARLY_HINTS: 103,\n BAD_REQUEST: 400,\n IM_A_TEAPOT: 418,\n BAD_GATEWAY: 502,\n PROCESSING: 102,\n NO_CONTENT: 204,\n SEE_OTHER: 303,\n USE_PROXY: 305,\n\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n TOO_EARLY: 425,\n CONTINUE: 100,\n ACCEPTED: 202,\n CONFLICT: 409,\n CREATED: 201,\n IM_USED: 226,\n LOCKED: 423,\n FOUND: 302,\n GONE: 410,\n OK: 200,\n} as const);\n\n/**\n * HTTP status messages mapped by numeric code.\n * Use for sending descriptive text in responses or logging.\n */\nexport const HttpStatusMessage = {\n 431: 'Request Header Fields Too Large',\n 511: 'Network Authentication Required',\n 203: 'Non-Authoritative Information',\n 407: 'Proxy Authentication Required',\n 451: 'Unavailable For Legal Reasons',\n 505: 'HTTP Version Not Supported',\n 509: 'Bandwidth Limit Exceeded',\n 506: 'Variant Also Negotiates',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 428: 'Precondition Required',\n 500: 'Internal Server Error',\n 422: 'Unprocessable Entity',\n 507: 'Insufficient Storage',\n 101: 'Switching Protocols',\n 412: 'Precondition Failed',\n 421: 'Misdirected Request',\n 503: 'Service Unavailable',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 405: 'Method Not Allowed',\n 417: 'Expectation Failed',\n 301: 'Moved Permanently',\n 413: 'Payload Too Large',\n 424: 'Failed Dependency',\n 429: 'Too Many Requests',\n 208: 'Already Reported',\n 300: 'Multiple Choices',\n 402: 'Payment Required',\n 426: 'Upgrade Required',\n 206: 'Partial Content',\n 408: 'Request Timeout',\n 411: 'Length Required',\n 501: 'Not Implemented',\n 504: 'Gateway Timeout',\n 406: 'Not Acceptable',\n 205: 'Reset Content',\n 508: 'Loop Detected',\n 207: 'Multi-Status',\n 304: 'Not Modified',\n 401: 'Unauthorized',\n 414: 'URI Too Long',\n 418: \"I'm a Teapot\",\n 510: 'Not Extended',\n 103: 'Early Hints',\n 400: 'Bad Request',\n 502: 'Bad Gateway',\n 102: 'Processing',\n 204: 'No Content',\n 303: 'See Other',\n 305: 'Use Proxy',\n 403: 'Forbidden',\n 404: 'Not Found',\n 425: 'Too Early',\n 100: 'Continue',\n 202: 'Accepted',\n 226: \"I'm Used\",\n 409: 'Conflict',\n 201: 'Created',\n 423: 'Locked',\n 302: 'Found',\n 410: 'Gone',\n 200: 'OK',\n} as const;\n\nexport type HttpStatusCode = keyof typeof HttpStatusMessage;\n\nexport type HttpStatusMessage =\n (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];\n","/**\n * Base class for Domain violations.\n * Purposely does NOT extend native Error to avoid stack trace overhead in the domain.\n */\nexport abstract class DomainViolation {\n public abstract readonly code: string;\n public abstract readonly message: string;\n public readonly metadata: Readonly<Record<string, unknown>>;\n\n protected constructor(metadata: Record<string, unknown> = {}) {\n this.metadata = Object.freeze(metadata);\n }\n}\n","/**\n * Represents the outcome of an operation that can either succeed or fail,\n * without relying on exceptions for control flow.\n *\n * This pattern is commonly used in domain and application layers to make\n * success and failure states explicit, predictable, and type-safe.\n *\n * ## Design guarantees\n * - A `Result` is **immutable** once created.\n * - A `Result` is **exactly one of**:\n * - Success → contains a value\n * - Failure → contains an error\n * - Accessing the wrong side throws immediately (fail-fast).\n *\n * @typeParam T - Type of the success value\n * @typeParam E - Type of the failure error\n *\n * @example\n * ```ts\n * function parseNumber(input: string): Result<number, string> {\n * const value = Number(input);\n *\n * if (Number.isNaN(value)) {\n * return Result.fail('Invalid number');\n * }\n *\n * return Result.ok(value);\n * }\n *\n * const result = parseNumber('42');\n *\n * if (result.isSuccess) {\n * console.log(result.getValue()); // 42\n * } else {\n * console.error(result.getError());\n * }\n * ```\n */\nexport class Result<T, E> {\n /**\n * Indicates whether the result represents a failed outcome.\n *\n * This flag is mutually exclusive with {@link isSuccess}.\n */\n public readonly isFailure: boolean;\n /**\n * Indicates whether the result represents a successful outcome.\n *\n * This flag is mutually exclusive with {@link isFailure}.\n */\n public readonly isSuccess: boolean;\n\n /**\n * Creates a new {@link Result} instance.\n *\n * This constructor is private to enforce the use of\n * {@link Result.ok} and {@link Result.fail} factory methods,\n * preserving the success/failure invariants.\n *\n * @param _value - Success value (defined only for success results)\n * @param _error - Failure error (defined only for failure results)\n */\n private constructor(\n private readonly _value?: T,\n private readonly _error?: E,\n ) {\n this.isSuccess = _error === undefined;\n this.isFailure = !this.isSuccess;\n Object.freeze(this);\n }\n\n /**\n * Creates a failed {@link Result}.\n *\n * @param error - Error describing the failure\n * @returns A failure {@link Result} containing the provided error\n *\n * @example\n * ```ts\n * return Result.fail(new ValidationError('Email is invalid'));\n * ```\n */\n public static fail<T, E>(error: E): Result<T, E> {\n return new Result<T, E>(undefined, error);\n }\n\n /**\n * Creates a successful {@link Result}.\n *\n * @param value - Value representing a successful outcome\n * @returns A success {@link Result} containing the provided value\n *\n * @example\n * ```ts\n * return Result.ok(user);\n * ```\n */\n public static ok<T, E>(value: T): Result<T, E> {\n return new Result<T, E>(value);\n }\n\n /**\n * Returns the failure error.\n *\n * @returns The error associated with a failed result\n *\n * @throws {Error}\n * Thrown if this result represents a success.\n * This is a fail-fast guard against incorrect usage.\n *\n * @example\n * ```ts\n * if (result.isFailure) {\n * const error = result.getError();\n * }\n * ```\n */\n public getError(): E {\n if (this.isSuccess) {\n throw new Error('Result: Cannot get error of a success.');\n }\n\n return this._error as E;\n }\n\n /**\n * Returns the success value.\n *\n * @returns The value associated with a successful result\n *\n * @throws {Error}\n * Thrown if this result represents a failure.\n * This is a fail-fast guard against incorrect usage.\n *\n * @example\n * ```ts\n * if (result.isSuccess) {\n * const value = result.getValue();\n * }\n * ```\n */\n public getValue(): T {\n if (this.isFailure) {\n throw new Error('Result: Cannot get value of a failure.');\n }\n\n return this._value as T;\n }\n}\n","import {\n HttpStatusCode,\n HttpStatusMessage,\n} from '@/gateway/constants/http-code';\n\ninterface ErrorParams {\n message: string;\n code: HttpStatusMessage;\n status?: HttpStatusCode;\n metadata?: Record<string, unknown> | undefined;\n isOperational?: boolean;\n cause?: Error | undefined;\n}\n\n/**\n * Abstract base class for application-level errors with structured error handling.\n *\n * Extends the native Error class to provide machine-readable error codes, HTTP status codes,\n * operational error classification, and optional metadata for better error tracking and client communication.\n *\n * @abstract\n * @extends {Error}\n *\n * @example\n * ```typescript\n * class UserNotFoundError extends ApplicationError {\n * constructor(userId: string) {\n * super({\n * code: HttpStatusMessage['404'],\n * status: 404,\n * isOperational: true,\n * message: `User with id ${userId} not found`,\n * metadata: { userId }\n * });\n * }\n * }\n * ```\n */\nexport abstract class ApplicationError extends Error {\n /** Optional cause (linked error) */\n public readonly cause?: Error | undefined;\n /** Machine-readable error code (e.g. `OTP_LOCKED`, `USER_NOT_FOUND`) */\n public readonly code: HttpStatusMessage;\n /** Operational vs programmer error flag */\n public readonly isOperational: boolean;\n /** Optional structured metadata for debugging or clients */\n public readonly metadata?: Record<string, unknown> | undefined;\n /** HTTP status code intended for response layer */\n public readonly status: HttpStatusCode;\n\n constructor({\n code = HttpStatusMessage['500'],\n isOperational = false,\n status = 500,\n metadata,\n message,\n cause,\n }: ErrorParams) {\n super(message);\n\n this.name = new.target.name;\n this.code = code;\n this.status = status;\n this.isOperational = isOperational;\n this.metadata = metadata;\n this.cause = cause;\n\n Error.captureStackTrace(this, new.target);\n }\n}\n","import { ValueObject } from '@/domain/base/vo';\n\nexport type UnwrapValueObject<T> =\n T extends ValueObject<infer V>\n ? UnwrapValueObject<V>\n : T extends (infer U)[]\n ? UnwrapValueObject<U>[]\n : T extends Map<infer K, infer V>\n ? Map<K, UnwrapValueObject<V>>\n : T extends Set<infer V>\n ? Set<UnwrapValueObject<V>>\n : T extends Date\n ? string\n : T extends object\n ? { [K in keyof T]: UnwrapValueObject<T[K]> }\n : T;\n\nexport function unwrapValueObject<T>(\n input: T,\n seen = new WeakSet(),\n): UnwrapValueObject<T> {\n if (input === null || input === undefined) {\n return input as UnwrapValueObject<T>;\n }\n\n if (typeof input !== 'object') {\n return input as UnwrapValueObject<T>;\n }\n\n if (seen.has(input)) {\n // Prevent circular reference infinite recursion, just return input or throw\n throw new Error('Circular reference detected in ValueObject unwrap');\n }\n\n seen.add(input);\n\n if (Array.isArray(input)) {\n const result = input.map(item => unwrapValueObject(item, seen));\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof ValueObject) {\n const result = unwrapValueObject(input.value, seen);\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Date) {\n seen.delete(input);\n return input.toISOString() as UnwrapValueObject<T>;\n }\n\n if (input instanceof Map) {\n const result = new Map();\n input.forEach((value, key) => {\n result.set(key, unwrapValueObject(value, seen));\n });\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Set) {\n const result = new Set(\n Array.from(input.values()).map(v => unwrapValueObject(v, seen)),\n );\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n // generic object\n const result: Record<string, unknown> = {};\n\n for (const key in input) {\n if (Object.hasOwn(input, key)) {\n result[key] = unwrapValueObject((input as any)[key], seen);\n }\n }\n\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n}\n\nexport function ensureObject<T>(input: UnwrapValueObject<T>): object {\n if (input === null || input === undefined) {\n return {};\n }\n if (typeof input === 'object') {\n return input;\n }\n\n // for primitives, wrap inside object with default key (or throw)\n return { value: input };\n}\n"],"mappings":"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","names":["index_exports","__export","AggregateId","AggregateRoot","ApplicationError","DomainError","DomainEvent","DomainViolation","Entity","EntityValidationError","HttpStatus","HttpStatusMessage","InvalidValueObjectError","PrimitiveValueObject","Result","UUID","ValueObject","deepFreeze","ensureObject","unwrapValueObject","__toCommonJS","Entity","props","_a","other","AggregateRoot","Entity","domainEvent","events","getCauseInfo","cause","DomainError","message","code","metadata","__spreadValues","PrimitiveValueObject","value","other","import_es6","deepFreeze","obj","seen","item","key","ValueObject","_ValueObject","props","deepFreeze","vo","other","deepEqual","EntityValidationError","DomainError","message","cause","InvalidValueObjectError","DomainError","message","import_node_crypto","DomainEvent","props","_a","import_uuid","import_zod","_UUID","PrimitiveValueObject","value","result","InvalidValueObjectError","z","UUID","AggregateId","UUID","HttpStatus","HttpStatusMessage","DomainViolation","metadata","Result","_Result","_value","_error","error","value","ApplicationError","code","HttpStatusMessage","isOperational","status","metadata","message","cause","unwrapValueObject","input","seen","result","item","ValueObject","value","key","v","ensureObject"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/domain/entities/entity.ts","../src/domain/aggregates/aggregate-root.ts","../src/domain/base/domain.error.ts","../src/domain/base/primitive-vo.ts","../src/domain/base/vo.ts","../src/utils/deep-freeze.util.ts","../src/domain/errors/entity-validation.error.ts","../src/domain/errors/invalid-vo.error.ts","../src/domain/events/domain.event.ts","../src/domain/value-objects/id.vo.ts","../src/domain/value-objects/aggregate-id.vo.ts","../src/gateway/constants/http-code.ts","../src/utils/errors/application.error.ts","../src/utils/unwrap-vo.util.ts"],"sourcesContent":["export * from './application';\nexport * from './domain/aggregates';\nexport * from './domain/base/domain.error';\nexport * from './domain/base/primitive-vo';\nexport * from './domain/base/vo';\nexport * from './domain/entities';\nexport * from './domain/errors/entity-validation.error';\nexport * from './domain/errors/invalid-vo.error';\nexport * from './domain/events';\nexport * from './domain/types';\nexport * from './domain/value-objects/aggregate-id.vo';\nexport * from './domain/value-objects/id.vo';\nexport * from './gateway/constants/http-code';\nexport * from './utils';\n","import { EntityId } from '../types';\n\n/**\n * Configuration for the base Entity constructor.\n * Forces a single-object argument pattern to avoid positional argument errors.\n * @template ID - A type satisfying the EntityId interface.\n */\nexport interface EntityProps<ID extends EntityId, Props> {\n /** The unique identity of the entity */\n readonly id: ID;\n /** Optional creation timestamp; defaults to 'now' if not provided */\n readonly createdAt?: Date;\n\n readonly props: Props;\n}\n\n/**\n * Abstract Base Entity for Domain-Driven Design (DDD).\n * This class provides the standard contract for entity equality and identity.\n * It intentionally avoids \"magic\" property bags to ensure V8 engine optimization\n * and better IDE intellisense.\n * @template ID - The specific Identity Value Object type.\n */\nexport abstract class Entity<ID extends EntityId, Props> {\n /** The timestamp when this entity was first instantiated/created */\n public readonly createdAt: Date;\n /** The immutable unique identifier for this entity */\n public readonly id: ID;\n\n /**\n * Protected constructor to be called by subclasses.\n * @param props - Initial identity and metadata.\n */\n protected constructor(props: EntityProps<ID, Props>) {\n this.id = props.id;\n this.createdAt = props.createdAt ?? new Date();\n }\n\n /**\n * Compares entities by identity.\n * In DDD, two entities are considered equal if their IDs match,\n * regardless of their other properties.\n * @param other - The entity to compare against.\n * @returns True if IDs are equal.\n */\n public equals(other?: Entity<ID, Props>): boolean {\n if (other == null) return false;\n if (this === other) return true;\n return this.id.equals(other.id);\n }\n\n /**\n * Converts the Entity into a plain Javascript object.\n * Subclasses must implement this to explicitly control serialization,\n * @returns A plain object representation of the entity.\n */\n public abstract toObject(): Record<string, unknown>;\n\n /**\n * Validates the current state of the entity against domain invariants.\n * This method should be called after construction and any mutation.\n * @throws {Error} Should throw a specific DomainError if validation fails.\n */\n public abstract validate(): void;\n}\n","import { Entity, EntityProps } from '../entities/entity';\nimport { DomainEvent } from '../events';\nimport { EntityId } from '../types';\n\n/**\n * Interface for AggregateRoot to ensure type safety and extensibility.\n */\nexport interface Props<P> extends EntityProps<EntityId, P> {\n readonly domainEvents: readonly DomainEvent[];\n /**\n * Adds a domain event to the aggregate.\n * @param event The domain event to add.\n */\n addEvent: (event: DomainEvent) => void;\n\n /**\n * Retrieves and clears all domain events recorded by this aggregate.\n *\n * Domain events represent facts that occurred as a result of state changes\n * within the aggregate. This method transfers ownership of those events\n * to the application layer for further processing (e.g. publishing).\n *\n * Calling this method has the side effect of clearing the aggregate's\n * internal event collection to prevent duplicate handling.\n *\n * This method is intended to be invoked by application services\n * after the aggregate has been successfully persisted.\n *\n * @returns A read-only list of domain events raised by this aggregate.\n */\n pullDomainEvents: () => readonly DomainEvent[];\n}\n\n/**\n * Base class for aggregate roots in DDD, encapsulating domain events and validation.\n * @template EntityProps The type of the entity's properties.\n */\nexport abstract class AggregateRoot<ID extends EntityId, P> extends Entity<\n ID,\n P\n> {\n /**\n * Gets a read-only copy of the domain events.\n */\n get domainEvents(): readonly DomainEvent[] {\n return [...this._domainEvents];\n }\n\n /**\n * Internal list of domain events.\n */\n private readonly _domainEvents: DomainEvent[] = [];\n\n /**\n * Adds a domain event to the aggregate after validating invariants.\n * @param domainEvent The domain event to add.\n * @throws {EntityValidationError} If invariants are not met.\n */\n addEvent(domainEvent: DomainEvent): void {\n this._domainEvents.push(domainEvent);\n }\n\n public pullDomainEvents(): readonly DomainEvent[] {\n const events = [...this._domainEvents];\n this._domainEvents.length = 0;\n return events;\n }\n}\n","export interface DomainErrorMetadata {\n cause?: { name: string; message: string; stack?: string };\n [key: string]: unknown;\n}\n\nconst getCauseInfo = (cause: Error | undefined) => {\n // 1. Handle Error objects specifically\n if (cause instanceof Error) {\n return {\n cause: {\n message: cause.message,\n stack: cause.stack,\n name: cause.name,\n },\n };\n }\n\n // 2. Handle other existing values\n if (cause) {\n return { cause };\n }\n\n // 3. Default to empty\n return {};\n};\n\n/**\n * Base class for all Domain Errors in the application.\n *\n * This class ensures:\n * 1. Serializable and structured for logs or API responses.\n * 2. Identifiable via stable error codes (not just class names).\n * 3. Contextual with optional structured metadata.\n * 4. Supports error chaining (cause) and stack trace preservation.\n *\n * @example\n * export class InsufficientFundsError extends DomainError {\n * constructor(accountId: string, currentBalance: number) {\n * super(\n * `Account ${accountId} has insufficient funds.`,\n * 'INSUFFICIENT_FUNDS',\n * { accountId, currentBalance }\n * );\n * }\n * }\n */\nexport abstract class DomainError extends Error {\n /** Stable, machine-readable error code */\n public readonly code: string;\n /** Structured, immutable domain metadata */\n public readonly metadata: Readonly<DomainErrorMetadata>;\n\n /**\n * @param message - Human-readable error message\n * @param code - Stable error code\n * @param metadata - Domain-specific structured data; optional `cause` can be included\n */\n protected constructor(\n message: string,\n code: string,\n metadata: DomainErrorMetadata = {},\n ) {\n super(message, { ...getCauseInfo(metadata.cause) });\n\n // Restore prototype chain for proper `instanceof` checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n this.name = new.target.name;\n this.code = code;\n this.metadata = Object.freeze({ ...metadata });\n }\n}\n","import { EntityId } from '../types';\n\ntype Primitive = boolean | number | string;\n\n/**\n * Base class for primitive-based Value Objects.\n *\n * This class is intended for Value Objects that are represented by\n * a single primitive value (string, number, or boolean).\n *\n * Characteristics:\n * - Immutable by construction\n * - Cheap equality comparison\n * - No deep cloning or freezing\n * - Safe for serialization and logging\n *\n * Examples:\n * - AggregateId\n * - EmailAddress\n * - Username\n * - Slug\n */\nexport abstract class PrimitiveValueObject<\n T extends Primitive,\n> implements EntityId {\n /**\n * The underlying primitive value.\n * Guaranteed to be valid after construction.\n */\n protected readonly value: T;\n\n /**\n * Constructs a new PrimitiveValueObject.\n *\n * @param value - The primitive value to wrap\n * @throws Error if validation fails\n */\n protected constructor(value: T) {\n this.validate(value);\n this.value = value;\n }\n\n /**\n * Compares two Value Objects for equality.\n *\n * Equality rules:\n * - Same concrete class\n * - Same primitive value (===)\n *\n * @param other - Another Value Object\n */\n public equals(other?: PrimitiveValueObject<T> | null | undefined): boolean {\n if (other === undefined || other === null) return false;\n\n if (Object.getPrototypeOf(this) !== Object.getPrototypeOf(other)) {\n return false;\n }\n\n return this.value === other.value;\n }\n\n /**\n * Returns the primitive value.\n * Prefer explicit access over implicit coercion.\n */\n public getValue(): T {\n return this.value;\n }\n\n /**\n * JSON serialization hook.\n * Produces the raw primitive value.\n */\n public toJSON(): T {\n return this.value;\n }\n\n /**\n * String representation.\n * Useful for logging and debugging.\n */\n public toString(): string {\n return String(this.value);\n }\n\n /**\n * Domain invariant validation.\n * Must throw if the value is invalid.\n *\n * @param value - The value to validate\n */\n protected abstract validate(value: T): void;\n}\n","import deepEqual from 'fast-deep-equal/es6';\n\nimport { deepFreeze } from '@/utils/deep-freeze.util';\n\nexport abstract class ValueObject<T> {\n get value(): T {\n return this.props;\n }\n\n protected readonly props: Readonly<T>;\n\n protected constructor(props: T) {\n this.validate(props);\n this.props = deepFreeze(props);\n }\n\n /**\n * Type guard to check if an unknown object is an instance of ValueObject.\n * This is useful for runtime type checking.\n *\n * @param vo The object to check.\n * @returns True if the object is a ValueObject instance, false otherwise.\n */\n public static is(vo: unknown): vo is ValueObject<unknown> {\n return vo instanceof ValueObject;\n }\n\n /**\n * Deep equality comparison of ValueObjects\n */\n public equals(other?: ValueObject<T>): boolean {\n if (other === null || other === undefined) return false;\n\n // Check if they share the same constructor (Type check)\n if (Object.getPrototypeOf(this) !== Object.getPrototypeOf(other)) {\n return false;\n }\n\n return deepEqual(this.props, other.props);\n }\n\n /**\n * Standard for clean API integration and logging.\n */\n public toJSON(): T {\n return this.props;\n }\n\n /**\n * Useful for debugging and string-based indexing.\n */\n public toString(): string {\n return JSON.stringify(this.props);\n }\n\n /**\n * Validates the value object props\n * @throws InvalidValueObjectError if validation fails\n */\n protected abstract validate(props: T): void;\n}\n","/**\n * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.\n *\n * @param obj - The object to be deeply frozen.\n * @param seen - A WeakSet to track already processed objects (for circular references).\n * @returns A deeply frozen version of the input object.\n */\nexport function deepFreeze<T>(\n obj: T,\n seen = new WeakSet<object>(),\n): Readonly<T> {\n // Handle null, undefined, or non-object types\n if (obj == null || (typeof obj !== 'object' && !Array.isArray(obj))) {\n return obj;\n }\n\n // Skip if already frozen\n if (Object.isFrozen(obj)) {\n return obj as Readonly<T>;\n }\n\n // Handle circular references\n if (seen.has(obj as object)) {\n return obj as Readonly<T>;\n }\n\n seen.add(obj as object);\n\n // Handle arrays explicitly\n if (Array.isArray(obj)) {\n obj.forEach(item => deepFreeze(item, seen));\n } else {\n // Handle plain objects\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n deepFreeze((obj as Record<string, unknown>)[key], seen);\n }\n }\n }\n\n return Object.freeze(obj) as Readonly<T>;\n}\n","import { DomainError } from '../base/domain.error';\n\n/**\n * Custom error class for entity validation failures.\n */\nexport class EntityValidationError extends DomainError {\n constructor(message: string, cause?: Error) {\n super(message, 'ENTITY_VALIDATION_ERROR', { cause });\n }\n}\n","import { DomainError } from '../base/domain.error';\n\nexport class InvalidValueObjectError extends DomainError {\n constructor(message: string) {\n super(message, 'INVALID_VALUE_OBJECT');\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { EntityId } from '../types';\n\ntype Primitive = boolean | number | string | null;\n\ntype Serializable =\n | Primitive\n | Serializable[]\n | { [key: string]: Serializable };\n\nexport type DomainEventPayload = Record<string, Serializable>;\n\nexport type UnixTimestampMillis = number;\n\ntype DomainEventProps<AggregateId extends EntityId, Payload> = {\n id?: string;\n aggregateId: AggregateId;\n schemaVersion: number;\n occurredAt: UnixTimestampMillis;\n payload: Payload;\n};\n\n// Abstract base class for domain events\nexport abstract class DomainEvent<\n AggregateId extends EntityId = EntityId,\n T extends DomainEventPayload = DomainEventPayload,\n> {\n public readonly aggregateId: AggregateId;\n\n public abstract readonly eventName: string;\n public readonly id: string;\n public readonly occurredAt: number;\n public readonly payload: Readonly<T>;\n public readonly schemaVersion: number;\n\n protected constructor(props: DomainEventProps<AggregateId, T>) {\n this.id = props.id ?? randomUUID();\n this.aggregateId = props.aggregateId;\n this.schemaVersion = props.schemaVersion;\n this.occurredAt = props.occurredAt;\n this.payload = Object.freeze(props.payload);\n }\n\n public toPrimitives(): Readonly<{\n id: string;\n eventName: string;\n aggregateId: string;\n schemaVersion: number;\n occurredAt: UnixTimestampMillis;\n payload: T;\n }> {\n return {\n aggregateId: this.aggregateId.toString(),\n schemaVersion: this.schemaVersion,\n occurredAt: this.occurredAt,\n eventName: this.eventName,\n payload: this.payload,\n id: this.id,\n };\n }\n}\n","import { v4 } from 'uuid';\nimport z from 'zod';\n\nimport { InvalidValueObjectError } from '../errors/invalid-vo.error';\nimport { PrimitiveValueObject } from '../base/primitive-vo';\n\n/**\n * Represents a UUID (Universally Unique Identifier) value object.\n *\n * This class extends PrimitiveValueObject to provide type-safe UUID handling\n * with validation using Zod schema. UUIDs are immutable and can be generated\n * randomly or created from string values.\n *\n * @example\n * // Generate a new random UUID\n * const id = UUID.generate();\n *\n * @example\n * // Create UUID from an existing string\n * const id = UUID.fromString('550e8400-e29b-41d4-a716-446655440000');\n *\n * @throws {InvalidValueObjectError} When the provided string is not a valid UUID format\n */\nexport class UUID extends PrimitiveValueObject<string> {\n private static readonly schema = z.uuid();\n\n public constructor(value: string) {\n super(value);\n this.validate(value);\n }\n\n /**\n * Creates an UUID from an external string.\n * Use only for untrusted input.\n *\n * @param value - UUID string\n */\n public static fromString(value: string): UUID {\n return new this(value);\n }\n\n /**\n * Generates a new AggregateId.\n */\n public static generate<T extends typeof UUID>(this: T): InstanceType<T> {\n return new this(v4()) as InstanceType<T>;\n }\n\n protected validate(value: string): void {\n const result = UUID.schema.safeParse(value);\n\n if (!result.success) {\n throw new InvalidValueObjectError(\n `Invalid UUID: ${result.error.message}`,\n );\n }\n }\n}\n","import { UUID } from './id.vo';\n\n/**\n * AggregateId represents a strongly-typed aggregate identifier.\n *\n * - Backed by UUID v4\n * - Immutable\n * - Comparable only to AggregateId\n */\nexport class AggregateId extends UUID {}\n","/**\n * HTTP status code catalog.\n *\n * This object provides a typed, immutable map of standard HTTP status names\n * to their numeric codes. Designed for server-side frameworks such as Fastify.\n *\n * - All identifiers use clear, canonical semantic names.\n * - Values are numeric status codes.\n * - Frozen to prevent runtime mutation.\n * - Exporting `HttpStatus` ensures type-safe usage across the codebase.\n * Usage:\n * ```ts\n * import { HttpStatus } from 'path-to-this-file';\n *\n * function handleRequest() {\n * return {\n * statusCode: HttpStatus.OK,\n * body: 'Success',\n * };\n * }\n * ```\n */\nexport const HttpStatus = Object.freeze({\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n NON_AUTHORITATIVE_INFORMATION: 203,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n BANDWIDTH_LIMIT_EXCEEDED: 509,\n VARIANT_ALSO_NEGOTIATES: 506,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n PRECONDITION_REQUIRED: 428,\n INTERNAL_SERVER_ERROR: 500,\n UNPROCESSABLE_ENTITY: 422,\n INSUFFICIENT_STORAGE: 507,\n\n SWITCHING_PROTOCOLS: 101,\n PRECONDITION_FAILED: 412,\n MISDIRECTED_REQUEST: 421,\n SERVICE_UNAVAILABLE: 503,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n METHOD_NOT_ALLOWED: 405,\n EXPECTATION_FAILED: 417,\n\n MOVED_PERMANENTLY: 301,\n PAYLOAD_TOO_LARGE: 413,\n FAILED_DEPENDENCY: 424,\n TOO_MANY_REQUESTS: 429,\n ALREADY_REPORTED: 208,\n MULTIPLE_CHOICES: 300,\n PAYMENT_REQUIRED: 402,\n UPGRADE_REQUIRED: 426,\n PARTIAL_CONTENT: 206,\n REQUEST_TIMEOUT: 408,\n LENGTH_REQUIRED: 411,\n NOT_IMPLEMENTED: 501,\n GATEWAY_TIMEOUT: 504,\n NOT_ACCEPTABLE: 406,\n RESET_CONTENT: 205,\n LOOP_DETECTED: 508,\n MULTI_STATUS: 207,\n NOT_MODIFIED: 304,\n UNAUTHORIZED: 401,\n URI_TOO_LONG: 414,\n NOT_EXTENDED: 510,\n EARLY_HINTS: 103,\n BAD_REQUEST: 400,\n IM_A_TEAPOT: 418,\n BAD_GATEWAY: 502,\n PROCESSING: 102,\n NO_CONTENT: 204,\n SEE_OTHER: 303,\n USE_PROXY: 305,\n\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n TOO_EARLY: 425,\n CONTINUE: 100,\n ACCEPTED: 202,\n CONFLICT: 409,\n CREATED: 201,\n IM_USED: 226,\n LOCKED: 423,\n FOUND: 302,\n GONE: 410,\n OK: 200,\n} as const);\n\n/**\n * HTTP status messages mapped by numeric code.\n * Use for sending descriptive text in responses or logging.\n */\nexport const HttpStatusMessage = {\n 431: 'Request Header Fields Too Large',\n 511: 'Network Authentication Required',\n 203: 'Non-Authoritative Information',\n 407: 'Proxy Authentication Required',\n 451: 'Unavailable For Legal Reasons',\n 505: 'HTTP Version Not Supported',\n 509: 'Bandwidth Limit Exceeded',\n 506: 'Variant Also Negotiates',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 428: 'Precondition Required',\n 500: 'Internal Server Error',\n 422: 'Unprocessable Entity',\n 507: 'Insufficient Storage',\n 101: 'Switching Protocols',\n 412: 'Precondition Failed',\n 421: 'Misdirected Request',\n 503: 'Service Unavailable',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 405: 'Method Not Allowed',\n 417: 'Expectation Failed',\n 301: 'Moved Permanently',\n 413: 'Payload Too Large',\n 424: 'Failed Dependency',\n 429: 'Too Many Requests',\n 208: 'Already Reported',\n 300: 'Multiple Choices',\n 402: 'Payment Required',\n 426: 'Upgrade Required',\n 206: 'Partial Content',\n 408: 'Request Timeout',\n 411: 'Length Required',\n 501: 'Not Implemented',\n 504: 'Gateway Timeout',\n 406: 'Not Acceptable',\n 205: 'Reset Content',\n 508: 'Loop Detected',\n 207: 'Multi-Status',\n 304: 'Not Modified',\n 401: 'Unauthorized',\n 414: 'URI Too Long',\n 418: \"I'm a Teapot\",\n 510: 'Not Extended',\n 103: 'Early Hints',\n 400: 'Bad Request',\n 502: 'Bad Gateway',\n 102: 'Processing',\n 204: 'No Content',\n 303: 'See Other',\n 305: 'Use Proxy',\n 403: 'Forbidden',\n 404: 'Not Found',\n 425: 'Too Early',\n 100: 'Continue',\n 202: 'Accepted',\n 226: \"I'm Used\",\n 409: 'Conflict',\n 201: 'Created',\n 423: 'Locked',\n 302: 'Found',\n 410: 'Gone',\n 200: 'OK',\n} as const;\n\nexport type HttpStatusCode = keyof typeof HttpStatusMessage;\n\nexport type HttpStatusMessage =\n (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];\n","import {\n HttpStatusCode,\n HttpStatusMessage,\n} from '@/gateway/constants/http-code';\n\ninterface ErrorParams {\n message: string;\n code: HttpStatusMessage;\n status?: HttpStatusCode;\n metadata?: Record<string, unknown> | undefined;\n isOperational?: boolean;\n cause?: Error | undefined;\n}\n\n/**\n * Abstract base class for application-level errors with structured error handling.\n *\n * Extends the native Error class to provide machine-readable error codes, HTTP status codes,\n * operational error classification, and optional metadata for better error tracking and client communication.\n *\n * @abstract\n * @extends {Error}\n *\n * @example\n * ```typescript\n * class UserNotFoundError extends ApplicationError {\n * constructor(userId: string) {\n * super({\n * code: HttpStatusMessage['404'],\n * status: 404,\n * isOperational: true,\n * message: `User with id ${userId} not found`,\n * metadata: { userId }\n * });\n * }\n * }\n * ```\n */\nexport abstract class ApplicationError extends Error {\n /** Optional cause (linked error) */\n public readonly cause?: Error | undefined;\n /** Machine-readable error code (e.g. `OTP_LOCKED`, `USER_NOT_FOUND`) */\n public readonly code: HttpStatusMessage;\n /** Operational vs programmer error flag */\n public readonly isOperational: boolean;\n /** Optional structured metadata for debugging or clients */\n public readonly metadata?: Record<string, unknown> | undefined;\n /** HTTP status code intended for response layer */\n public readonly status: HttpStatusCode;\n\n constructor({\n code = HttpStatusMessage['500'],\n isOperational = false,\n status = 500,\n metadata,\n message,\n cause,\n }: ErrorParams) {\n super(message);\n\n this.name = new.target.name;\n this.code = code;\n this.status = status;\n this.isOperational = isOperational;\n this.metadata = metadata;\n this.cause = cause;\n\n Error.captureStackTrace(this, new.target);\n }\n}\n","import { ValueObject } from '@/domain/base/vo';\n\nexport type UnwrapValueObject<T> =\n T extends ValueObject<infer V>\n ? UnwrapValueObject<V>\n : T extends (infer U)[]\n ? UnwrapValueObject<U>[]\n : T extends Map<infer K, infer V>\n ? Map<K, UnwrapValueObject<V>>\n : T extends Set<infer V>\n ? Set<UnwrapValueObject<V>>\n : T extends Date\n ? string\n : T extends object\n ? { [K in keyof T]: UnwrapValueObject<T[K]> }\n : T;\n\nexport function unwrapValueObject<T>(\n input: T,\n seen = new WeakSet(),\n): UnwrapValueObject<T> {\n if (input === null || input === undefined) {\n return input as UnwrapValueObject<T>;\n }\n\n if (typeof input !== 'object') {\n return input as UnwrapValueObject<T>;\n }\n\n if (seen.has(input)) {\n // Prevent circular reference infinite recursion, just return input or throw\n throw new Error('Circular reference detected in ValueObject unwrap');\n }\n\n seen.add(input);\n\n if (Array.isArray(input)) {\n const result = input.map(item => unwrapValueObject(item, seen));\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof ValueObject) {\n const result = unwrapValueObject(input.value, seen);\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Date) {\n seen.delete(input);\n return input.toISOString() as UnwrapValueObject<T>;\n }\n\n if (input instanceof Map) {\n const result = new Map();\n input.forEach((value, key) => {\n result.set(key, unwrapValueObject(value, seen));\n });\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Set) {\n const result = new Set(\n Array.from(input.values()).map(v => unwrapValueObject(v, seen)),\n );\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n // generic object\n const result: Record<string, unknown> = {};\n\n for (const key in input) {\n if (Object.hasOwn(input, key)) {\n result[key] = unwrapValueObject((input as any)[key], seen);\n }\n }\n\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n}\n\nexport function ensureObject<T>(input: UnwrapValueObject<T>): object {\n if (input === null || input === undefined) {\n return {};\n }\n if (typeof input === 'object') {\n return input;\n }\n\n // for primitives, wrap inside object with default key (or throw)\n return { value: input };\n}\n"],"mappings":"4zBAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,iBAAAE,EAAA,kBAAAC,EAAA,qBAAAC,EAAA,gBAAAC,EAAA,gBAAAC,EAAA,WAAAC,EAAA,0BAAAC,EAAA,eAAAC,EAAA,sBAAAC,EAAA,4BAAAC,EAAA,yBAAAC,EAAA,SAAAC,EAAA,gBAAAC,EAAA,eAAAC,EAAA,iBAAAC,EAAA,sBAAAC,IAAA,eAAAC,EAAAlB,GCuBO,IAAemB,EAAf,KAAkD,CAU7C,YAAYC,EAA+B,CAjCvD,IAAAC,EAkCI,KAAK,GAAKD,EAAM,GAChB,KAAK,WAAYC,EAAAD,EAAM,YAAN,KAAAC,EAAmB,IAAI,IAC1C,CASO,OAAOC,EAAoC,CAChD,OAAIA,GAAS,KAAa,GACtB,OAASA,EAAc,GACpB,KAAK,GAAG,OAAOA,EAAM,EAAE,CAChC,CAeF,EC3BO,IAAeC,EAAf,cAA6DC,CAGlE,CAHK,kCAcL,KAAiB,cAA+B,CAAC,EAPjD,IAAI,cAAuC,CACzC,MAAO,CAAC,GAAG,KAAK,aAAa,CAC/B,CAYA,SAASC,EAAgC,CACvC,KAAK,cAAc,KAAKA,CAAW,CACrC,CAEO,kBAA2C,CAChD,IAAMC,EAAS,CAAC,GAAG,KAAK,aAAa,EACrC,YAAK,cAAc,OAAS,EACrBA,CACT,CACF,EC9DA,IAAMC,EAAgBC,GAEhBA,aAAiB,MACZ,CACL,MAAO,CACL,QAASA,EAAM,QACf,MAAOA,EAAM,MACb,KAAMA,EAAM,IACd,CACF,EAIEA,EACK,CAAE,MAAAA,CAAM,EAIV,CAAC,EAuBYC,EAAf,cAAmC,KAAM,CAWpC,YACRC,EACAC,EACAC,EAAgC,CAAC,EACjC,CACA,MAAMF,EAASG,EAAA,GAAKN,EAAaK,EAAS,KAAK,EAAG,EAGlD,OAAO,eAAe,KAAM,WAAW,SAAS,EAEhD,KAAK,KAAO,WAAW,KACvB,KAAK,KAAOD,EACZ,KAAK,SAAW,OAAO,OAAOE,EAAA,GAAKD,EAAU,CAC/C,CACF,ECjDO,IAAeE,EAAf,KAEe,CAaV,YAAYC,EAAU,CAC9B,KAAK,SAASA,CAAK,EACnB,KAAK,MAAQA,CACf,CAWO,OAAOC,EAA6D,CAGzE,OAF2BA,GAAU,MAEjC,OAAO,eAAe,IAAI,IAAM,OAAO,eAAeA,CAAK,EACtD,GAGF,KAAK,QAAUA,EAAM,KAC9B,CAMO,UAAc,CACnB,OAAO,KAAK,KACd,CAMO,QAAY,CACjB,OAAO,KAAK,KACd,CAMO,UAAmB,CACxB,OAAO,OAAO,KAAK,KAAK,CAC1B,CASF,EC5FA,IAAAC,EAAsB,kCCOf,SAASC,EACdC,EACAC,EAAO,IAAI,QACE,CAYb,GAVID,GAAO,MAAS,OAAOA,GAAQ,UAAY,CAAC,MAAM,QAAQA,CAAG,GAK7D,OAAO,SAASA,CAAG,GAKnBC,EAAK,IAAID,CAAa,EACxB,OAAOA,EAMT,GAHAC,EAAK,IAAID,CAAa,EAGlB,MAAM,QAAQA,CAAG,EACnBA,EAAI,QAAQE,GAAQH,EAAWG,EAAMD,CAAI,CAAC,MAG1C,SAAWE,KAAOH,EACZ,OAAO,OAAOA,EAAKG,CAAG,GACxBJ,EAAYC,EAAgCG,CAAG,EAAGF,CAAI,EAK5D,OAAO,OAAO,OAAOD,CAAG,CAC1B,CDrCO,IAAeI,EAAf,MAAeC,CAAe,CACnC,IAAI,OAAW,CACb,OAAO,KAAK,KACd,CAIU,YAAYC,EAAU,CAC9B,KAAK,SAASA,CAAK,EACnB,KAAK,MAAQC,EAAWD,CAAK,CAC/B,CASA,OAAc,GAAGE,EAAyC,CACxD,OAAOA,aAAcH,CACvB,CAKO,OAAOI,EAAiC,CAI7C,OAHIA,GAAU,MAGV,OAAO,eAAe,IAAI,IAAM,OAAO,eAAeA,CAAK,EACtD,MAGF,EAAAC,SAAU,KAAK,MAAOD,EAAM,KAAK,CAC1C,CAKO,QAAY,CACjB,OAAO,KAAK,KACd,CAKO,UAAmB,CACxB,OAAO,KAAK,UAAU,KAAK,KAAK,CAClC,CAOF,EEvDO,IAAME,EAAN,cAAoCC,CAAY,CACrD,YAAYC,EAAiBC,EAAe,CAC1C,MAAMD,EAAS,0BAA2B,CAAE,MAAAC,CAAM,CAAC,CACrD,CACF,ECPO,IAAMC,EAAN,cAAsCC,CAAY,CACvD,YAAYC,EAAiB,CAC3B,MAAMA,EAAS,sBAAsB,CACvC,CACF,ECNA,IAAAC,EAA2B,kBAwBLC,EAAf,KAGL,CASU,YAAYC,EAAyC,CApCjE,IAAAC,EAqCI,KAAK,IAAKA,EAAAD,EAAM,KAAN,KAAAC,KAAY,cAAW,EACjC,KAAK,YAAcD,EAAM,YACzB,KAAK,cAAgBA,EAAM,cAC3B,KAAK,WAAaA,EAAM,WACxB,KAAK,QAAU,OAAO,OAAOA,EAAM,OAAO,CAC5C,CAEO,cAOJ,CACD,MAAO,CACL,YAAa,KAAK,YAAY,SAAS,EACvC,cAAe,KAAK,cACpB,WAAY,KAAK,WACjB,UAAW,KAAK,UAChB,QAAS,KAAK,QACd,GAAI,KAAK,EACX,CACF,CACF,EC7DA,IAAAE,EAAmB,gBACnBC,EAAc,kBAsBP,IAAMC,EAAN,MAAMA,UAAaC,CAA6B,CAG9C,YAAYC,EAAe,CAChC,MAAMA,CAAK,EACX,KAAK,SAASA,CAAK,CACrB,CAQA,OAAc,WAAWA,EAAqB,CAC5C,OAAO,IAAI,KAAKA,CAAK,CACvB,CAKA,OAAc,UAA0D,CACtE,OAAO,IAAI,QAAK,MAAG,CAAC,CACtB,CAEU,SAASA,EAAqB,CACtC,IAAMC,EAASH,EAAK,OAAO,UAAUE,CAAK,EAE1C,GAAI,CAACC,EAAO,QACV,MAAM,IAAIC,EACR,iBAAiBD,EAAO,MAAM,OAAO,EACvC,CAEJ,CACF,EAlCaH,EACa,OAAS,EAAAK,QAAE,KAAK,EADnC,IAAMC,EAANN,ECdA,IAAMO,EAAN,cAA0BC,CAAK,CAAC,ECahC,IAAMC,EAAa,OAAO,OAAO,CACtC,gCAAiC,IACjC,gCAAiC,IACjC,8BAA+B,IAC/B,8BAA+B,IAE/B,8BAA+B,IAC/B,2BAA4B,IAC5B,yBAA0B,IAC1B,wBAAyB,IACzB,uBAAwB,IACxB,sBAAuB,IACvB,sBAAuB,IACvB,sBAAuB,IACvB,qBAAsB,IACtB,qBAAsB,IAEtB,oBAAqB,IACrB,oBAAqB,IACrB,oBAAqB,IACrB,oBAAqB,IACrB,mBAAoB,IACpB,mBAAoB,IACpB,mBAAoB,IACpB,mBAAoB,IAEpB,kBAAmB,IACnB,kBAAmB,IACnB,kBAAmB,IACnB,kBAAmB,IACnB,iBAAkB,IAClB,iBAAkB,IAClB,iBAAkB,IAClB,iBAAkB,IAClB,gBAAiB,IACjB,gBAAiB,IACjB,gBAAiB,IACjB,gBAAiB,IACjB,gBAAiB,IACjB,eAAgB,IAChB,cAAe,IACf,cAAe,IACf,aAAc,IACd,aAAc,IACd,aAAc,IACd,aAAc,IACd,aAAc,IACd,YAAa,IACb,YAAa,IACb,YAAa,IACb,YAAa,IACb,WAAY,IACZ,WAAY,IACZ,UAAW,IACX,UAAW,IAEX,UAAW,IACX,UAAW,IACX,UAAW,IACX,SAAU,IACV,SAAU,IACV,SAAU,IACV,QAAS,IACT,QAAS,IACT,OAAQ,IACR,MAAO,IACP,KAAM,IACN,GAAI,GACN,CAAU,EAMGC,EAAoB,CAC/B,IAAK,kCACL,IAAK,kCACL,IAAK,gCACL,IAAK,gCACL,IAAK,gCACL,IAAK,6BACL,IAAK,2BACL,IAAK,0BACL,IAAK,yBACL,IAAK,wBACL,IAAK,wBACL,IAAK,wBACL,IAAK,uBACL,IAAK,uBACL,IAAK,sBACL,IAAK,sBACL,IAAK,sBACL,IAAK,sBACL,IAAK,qBACL,IAAK,qBACL,IAAK,qBACL,IAAK,qBACL,IAAK,oBACL,IAAK,oBACL,IAAK,oBACL,IAAK,oBACL,IAAK,mBACL,IAAK,mBACL,IAAK,mBACL,IAAK,mBACL,IAAK,kBACL,IAAK,kBACL,IAAK,kBACL,IAAK,kBACL,IAAK,kBACL,IAAK,iBACL,IAAK,gBACL,IAAK,gBACL,IAAK,eACL,IAAK,eACL,IAAK,eACL,IAAK,eACL,IAAK,eACL,IAAK,eACL,IAAK,cACL,IAAK,cACL,IAAK,cACL,IAAK,aACL,IAAK,aACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,YACL,IAAK,WACL,IAAK,WACL,IAAK,WACL,IAAK,WACL,IAAK,UACL,IAAK,SACL,IAAK,QACL,IAAK,OACL,IAAK,IACP,EC1HO,IAAeC,EAAf,cAAwC,KAAM,CAYnD,YAAY,CACV,KAAAC,EAAOC,EAAkB,GAAK,EAC9B,cAAAC,EAAgB,GAChB,OAAAC,EAAS,IACT,SAAAC,EACA,QAAAC,EACA,MAAAC,CACF,EAAgB,CACd,MAAMD,CAAO,EAEb,KAAK,KAAO,WAAW,KACvB,KAAK,KAAOL,EACZ,KAAK,OAASG,EACd,KAAK,cAAgBD,EACrB,KAAK,SAAWE,EAChB,KAAK,MAAQE,EAEb,MAAM,kBAAkB,KAAM,UAAU,CAC1C,CACF,ECpDO,SAASC,EACdC,EACAC,EAAO,IAAI,QACW,CAKtB,GAJID,GAAU,MAIV,OAAOA,GAAU,SACnB,OAAOA,EAGT,GAAIC,EAAK,IAAID,CAAK,EAEhB,MAAM,IAAI,MAAM,mDAAmD,EAKrE,GAFAC,EAAK,IAAID,CAAK,EAEV,MAAM,QAAQA,CAAK,EAAG,CACxB,IAAME,EAASF,EAAM,IAAIG,GAAQJ,EAAkBI,EAAMF,CAAI,CAAC,EAC9D,OAAAA,EAAK,OAAOD,CAAK,EACVE,CACT,CAEA,GAAIF,aAAiBI,EAAa,CAChC,IAAMF,EAASH,EAAkBC,EAAM,MAAOC,CAAI,EAClD,OAAAA,EAAK,OAAOD,CAAK,EACVE,CACT,CAEA,GAAIF,aAAiB,KACnB,OAAAC,EAAK,OAAOD,CAAK,EACVA,EAAM,YAAY,EAG3B,GAAIA,aAAiB,IAAK,CACxB,IAAME,EAAS,IAAI,IACnB,OAAAF,EAAM,QAAQ,CAACK,EAAOC,IAAQ,CAC5BJ,EAAO,IAAII,EAAKP,EAAkBM,EAAOJ,CAAI,CAAC,CAChD,CAAC,EACDA,EAAK,OAAOD,CAAK,EACVE,CACT,CAEA,GAAIF,aAAiB,IAAK,CACxB,IAAME,EAAS,IAAI,IACjB,MAAM,KAAKF,EAAM,OAAO,CAAC,EAAE,IAAIO,GAAKR,EAAkBQ,EAAGN,CAAI,CAAC,CAChE,EACA,OAAAA,EAAK,OAAOD,CAAK,EACVE,CACT,CAGA,IAAMA,EAAkC,CAAC,EAEzC,QAAWI,KAAON,EACZ,OAAO,OAAOA,EAAOM,CAAG,IAC1BJ,EAAOI,CAAG,EAAIP,EAAmBC,EAAcM,CAAG,EAAGL,CAAI,GAI7D,OAAAA,EAAK,OAAOD,CAAK,EACVE,CACT,CAEO,SAASM,EAAgBR,EAAqC,CACnE,OAAIA,GAAU,KACL,CAAC,EAEN,OAAOA,GAAU,SACZA,EAIF,CAAE,MAAOA,CAAM,CACxB","names":["index_exports","__export","AggregateId","AggregateRoot","ApplicationError","DomainError","DomainEvent","Entity","EntityValidationError","HttpStatus","HttpStatusMessage","InvalidValueObjectError","PrimitiveValueObject","UUID","ValueObject","deepFreeze","ensureObject","unwrapValueObject","__toCommonJS","Entity","props","_a","other","AggregateRoot","Entity","domainEvent","events","getCauseInfo","cause","DomainError","message","code","metadata","__spreadValues","PrimitiveValueObject","value","other","import_es6","deepFreeze","obj","seen","item","key","ValueObject","_ValueObject","props","deepFreeze","vo","other","deepEqual","EntityValidationError","DomainError","message","cause","InvalidValueObjectError","DomainError","message","import_node_crypto","DomainEvent","props","_a","import_uuid","import_zod","_UUID","PrimitiveValueObject","value","result","InvalidValueObjectError","z","UUID","AggregateId","UUID","HttpStatus","HttpStatusMessage","ApplicationError","code","HttpStatusMessage","isOperational","status","metadata","message","cause","unwrapValueObject","input","seen","result","item","ValueObject","value","key","v","ensureObject"]}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- var h=Object.defineProperty;var f=Object.getOwnPropertySymbols;var _=Object.prototype.hasOwnProperty,P=Object.prototype.propertyIsEnumerable;var O=(t,e,r)=>e in t?h(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,m=(t,e)=>{for(var r in e||(e={}))_.call(e,r)&&O(t,r,e[r]);if(f)for(var r of f(e))P.call(e,r)&&O(t,r,e[r]);return t};var i=class{constructor(e){var r;this.id=e.id,this.createdAt=(r=e.createdAt)!=null?r:new Date}equals(e){return e==null?!1:this===e?!0:this.id.equals(e.id)}};var y=class extends i{constructor(){super(...arguments);this._domainEvents=[]}get domainEvents(){return[...this._domainEvents]}addEvent(r){this._domainEvents.push(r)}pullDomainEvents(){let r=[...this._domainEvents];return this._domainEvents.length=0,r}};var v=t=>t instanceof Error?{cause:{message:t.message,stack:t.stack,name:t.name}}:t?{cause:t}:{},o=class extends Error{constructor(e,r,a={}){super(e,m({},v(a.cause))),Object.setPrototypeOf(this,new.target.prototype),this.name=new.target.name,this.code=r,this.metadata=Object.freeze(m({},a))}};var d=class{constructor(e){this.validate(e),this.value=e}equals(e){return e==null||Object.getPrototypeOf(this)!==Object.getPrototypeOf(e)?!1:this.value===e.value}getValue(){return this.value}toJSON(){return this.value}toString(){return String(this.value)}};import U from"fast-deep-equal/es6";function c(t,e=new WeakSet){if(t==null||typeof t!="object"&&!Array.isArray(t)||Object.isFrozen(t)||e.has(t))return t;if(e.add(t),Array.isArray(t))t.forEach(r=>c(r,e));else for(let r in t)Object.hasOwn(t,r)&&c(t[r],e);return Object.freeze(t)}var l=class t{get value(){return this.props}constructor(e){this.validate(e),this.props=c(e)}static is(e){return e instanceof t}equals(e){return e==null||Object.getPrototypeOf(this)!==Object.getPrototypeOf(e)?!1:U(this.props,e.props)}toJSON(){return this.props}toString(){return JSON.stringify(this.props)}};var g=class extends o{constructor(e,r){super(e,"ENTITY_VALIDATION_ERROR",{cause:r})}};var u=class extends o{constructor(e){super(e,"INVALID_VALUE_OBJECT")}};import{randomUUID as x}from"crypto";var I=class{constructor(e){var r;this.id=(r=e.id)!=null?r:x(),this.aggregateId=e.aggregateId,this.schemaVersion=e.schemaVersion,this.occurredAt=e.occurredAt,this.payload=Object.freeze(e.payload)}toPrimitives(){return{aggregateId:this.aggregateId.toString(),schemaVersion:this.schemaVersion,occurredAt:this.occurredAt,eventName:this.eventName,payload:this.payload,id:this.id}}};import{v4 as w}from"uuid";import V from"zod";var p=class p extends d{constructor(e){super(e),this.validate(e)}static fromString(e){return new this(e)}static generate(){return new this(w())}validate(e){let r=p.schema.safeParse(e);if(!r.success)throw new u(`Invalid UUID: ${r.error.message}`)}};p.schema=V.uuid();var E=p;var b=class extends E{};var se=Object.freeze({REQUEST_HEADER_FIELDS_TOO_LARGE:431,NETWORK_AUTHENTICATION_REQUIRED:511,NON_AUTHORITATIVE_INFORMATION:203,PROXY_AUTHENTICATION_REQUIRED:407,UNAVAILABLE_FOR_LEGAL_REASONS:451,HTTP_VERSION_NOT_SUPPORTED:505,BANDWIDTH_LIMIT_EXCEEDED:509,VARIANT_ALSO_NEGOTIATES:506,UNSUPPORTED_MEDIA_TYPE:415,RANGE_NOT_SATISFIABLE:416,PRECONDITION_REQUIRED:428,INTERNAL_SERVER_ERROR:500,UNPROCESSABLE_ENTITY:422,INSUFFICIENT_STORAGE:507,SWITCHING_PROTOCOLS:101,PRECONDITION_FAILED:412,MISDIRECTED_REQUEST:421,SERVICE_UNAVAILABLE:503,TEMPORARY_REDIRECT:307,PERMANENT_REDIRECT:308,METHOD_NOT_ALLOWED:405,EXPECTATION_FAILED:417,MOVED_PERMANENTLY:301,PAYLOAD_TOO_LARGE:413,FAILED_DEPENDENCY:424,TOO_MANY_REQUESTS:429,ALREADY_REPORTED:208,MULTIPLE_CHOICES:300,PAYMENT_REQUIRED:402,UPGRADE_REQUIRED:426,PARTIAL_CONTENT:206,REQUEST_TIMEOUT:408,LENGTH_REQUIRED:411,NOT_IMPLEMENTED:501,GATEWAY_TIMEOUT:504,NOT_ACCEPTABLE:406,RESET_CONTENT:205,LOOP_DETECTED:508,MULTI_STATUS:207,NOT_MODIFIED:304,UNAUTHORIZED:401,URI_TOO_LONG:414,NOT_EXTENDED:510,EARLY_HINTS:103,BAD_REQUEST:400,IM_A_TEAPOT:418,BAD_GATEWAY:502,PROCESSING:102,NO_CONTENT:204,SEE_OTHER:303,USE_PROXY:305,FORBIDDEN:403,NOT_FOUND:404,TOO_EARLY:425,CONTINUE:100,ACCEPTED:202,CONFLICT:409,CREATED:201,IM_USED:226,LOCKED:423,FOUND:302,GONE:410,OK:200}),R={431:"Request Header Fields Too Large",511:"Network Authentication Required",203:"Non-Authoritative Information",407:"Proxy Authentication Required",451:"Unavailable For Legal Reasons",505:"HTTP Version Not Supported",509:"Bandwidth Limit Exceeded",506:"Variant Also Negotiates",415:"Unsupported Media Type",416:"Range Not Satisfiable",428:"Precondition Required",500:"Internal Server Error",422:"Unprocessable Entity",507:"Insufficient Storage",101:"Switching Protocols",412:"Precondition Failed",421:"Misdirected Request",503:"Service Unavailable",307:"Temporary Redirect",308:"Permanent Redirect",405:"Method Not Allowed",417:"Expectation Failed",301:"Moved Permanently",413:"Payload Too Large",424:"Failed Dependency",429:"Too Many Requests",208:"Already Reported",300:"Multiple Choices",402:"Payment Required",426:"Upgrade Required",206:"Partial Content",408:"Request Timeout",411:"Length Required",501:"Not Implemented",504:"Gateway Timeout",406:"Not Acceptable",205:"Reset Content",508:"Loop Detected",207:"Multi-Status",304:"Not Modified",401:"Unauthorized",414:"URI Too Long",418:"I'm a Teapot",510:"Not Extended",103:"Early Hints",400:"Bad Request",502:"Bad Gateway",102:"Processing",204:"No Content",303:"See Other",305:"Use Proxy",403:"Forbidden",404:"Not Found",425:"Too Early",100:"Continue",202:"Accepted",226:"I'm Used",409:"Conflict",201:"Created",423:"Locked",302:"Found",410:"Gone",200:"OK"};var A=class{constructor(e={}){this.metadata=Object.freeze(e)}};var N=class t{constructor(e,r){this._value=e;this._error=r;this.isSuccess=r===void 0,this.isFailure=!this.isSuccess,Object.freeze(this)}static fail(e){return new t(void 0,e)}static ok(e){return new t(e)}getError(){if(this.isSuccess)throw new Error("Result: Cannot get error of a success.");return this._error}getValue(){if(this.isFailure)throw new Error("Result: Cannot get value of a failure.");return this._value}};var D=class extends Error{constructor({code:e=R[500],isOperational:r=!1,status:a=500,metadata:n,message:T,cause:S}){super(T),this.name=new.target.name,this.code=e,this.status=a,this.isOperational=r,this.metadata=n,this.cause=S,Error.captureStackTrace(this,new.target)}};function s(t,e=new WeakSet){if(t==null||typeof t!="object")return t;if(e.has(t))throw new Error("Circular reference detected in ValueObject unwrap");if(e.add(t),Array.isArray(t)){let a=t.map(n=>s(n,e));return e.delete(t),a}if(t instanceof l){let a=s(t.value,e);return e.delete(t),a}if(t instanceof Date)return e.delete(t),t.toISOString();if(t instanceof Map){let a=new Map;return t.forEach((n,T)=>{a.set(T,s(n,e))}),e.delete(t),a}if(t instanceof Set){let a=new Set(Array.from(t.values()).map(n=>s(n,e)));return e.delete(t),a}let r={};for(let a in t)Object.hasOwn(t,a)&&(r[a]=s(t[a],e));return e.delete(t),r}function Te(t){return t==null?{}:typeof t=="object"?t:{value:t}}export{b as AggregateId,y as AggregateRoot,D as ApplicationError,o as DomainError,I as DomainEvent,A as DomainViolation,i as Entity,g as EntityValidationError,se as HttpStatus,R as HttpStatusMessage,u as InvalidValueObjectError,d as PrimitiveValueObject,N as Result,E as UUID,l as ValueObject,c as deepFreeze,Te as ensureObject,s as unwrapValueObject};
1
+ var N=Object.defineProperty;var O=Object.getOwnPropertySymbols;var _=Object.prototype.hasOwnProperty,S=Object.prototype.propertyIsEnumerable;var f=(t,e,r)=>e in t?N(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,m=(t,e)=>{for(var r in e||(e={}))_.call(e,r)&&f(t,r,e[r]);if(O)for(var r of O(e))S.call(e,r)&&f(t,r,e[r]);return t};var s=class{constructor(e){var r;this.id=e.id,this.createdAt=(r=e.createdAt)!=null?r:new Date}equals(e){return e==null?!1:this===e?!0:this.id.equals(e.id)}};var y=class extends s{constructor(){super(...arguments);this._domainEvents=[]}get domainEvents(){return[...this._domainEvents]}addEvent(r){this._domainEvents.push(r)}pullDomainEvents(){let r=[...this._domainEvents];return this._domainEvents.length=0,r}};var P=t=>t instanceof Error?{cause:{message:t.message,stack:t.stack,name:t.name}}:t?{cause:t}:{},o=class extends Error{constructor(e,r,a={}){super(e,m({},P(a.cause))),Object.setPrototypeOf(this,new.target.prototype),this.name=new.target.name,this.code=r,this.metadata=Object.freeze(m({},a))}};var d=class{constructor(e){this.validate(e),this.value=e}equals(e){return e==null||Object.getPrototypeOf(this)!==Object.getPrototypeOf(e)?!1:this.value===e.value}getValue(){return this.value}toJSON(){return this.value}toString(){return String(this.value)}};import U from"fast-deep-equal/es6";function c(t,e=new WeakSet){if(t==null||typeof t!="object"&&!Array.isArray(t)||Object.isFrozen(t)||e.has(t))return t;if(e.add(t),Array.isArray(t))t.forEach(r=>c(r,e));else for(let r in t)Object.hasOwn(t,r)&&c(t[r],e);return Object.freeze(t)}var l=class t{get value(){return this.props}constructor(e){this.validate(e),this.props=c(e)}static is(e){return e instanceof t}equals(e){return e==null||Object.getPrototypeOf(this)!==Object.getPrototypeOf(e)?!1:U(this.props,e.props)}toJSON(){return this.props}toString(){return JSON.stringify(this.props)}};var I=class extends o{constructor(e,r){super(e,"ENTITY_VALIDATION_ERROR",{cause:r})}};var u=class extends o{constructor(e){super(e,"INVALID_VALUE_OBJECT")}};import{randomUUID as h}from"crypto";var g=class{constructor(e){var r;this.id=(r=e.id)!=null?r:h(),this.aggregateId=e.aggregateId,this.schemaVersion=e.schemaVersion,this.occurredAt=e.occurredAt,this.payload=Object.freeze(e.payload)}toPrimitives(){return{aggregateId:this.aggregateId.toString(),schemaVersion:this.schemaVersion,occurredAt:this.occurredAt,eventName:this.eventName,payload:this.payload,id:this.id}}};import{v4 as v}from"uuid";import x from"zod";var p=class p extends d{constructor(e){super(e),this.validate(e)}static fromString(e){return new this(e)}static generate(){return new this(v())}validate(e){let r=p.schema.safeParse(e);if(!r.success)throw new u(`Invalid UUID: ${r.error.message}`)}};p.schema=x.uuid();var E=p;var R=class extends E{};var ne=Object.freeze({REQUEST_HEADER_FIELDS_TOO_LARGE:431,NETWORK_AUTHENTICATION_REQUIRED:511,NON_AUTHORITATIVE_INFORMATION:203,PROXY_AUTHENTICATION_REQUIRED:407,UNAVAILABLE_FOR_LEGAL_REASONS:451,HTTP_VERSION_NOT_SUPPORTED:505,BANDWIDTH_LIMIT_EXCEEDED:509,VARIANT_ALSO_NEGOTIATES:506,UNSUPPORTED_MEDIA_TYPE:415,RANGE_NOT_SATISFIABLE:416,PRECONDITION_REQUIRED:428,INTERNAL_SERVER_ERROR:500,UNPROCESSABLE_ENTITY:422,INSUFFICIENT_STORAGE:507,SWITCHING_PROTOCOLS:101,PRECONDITION_FAILED:412,MISDIRECTED_REQUEST:421,SERVICE_UNAVAILABLE:503,TEMPORARY_REDIRECT:307,PERMANENT_REDIRECT:308,METHOD_NOT_ALLOWED:405,EXPECTATION_FAILED:417,MOVED_PERMANENTLY:301,PAYLOAD_TOO_LARGE:413,FAILED_DEPENDENCY:424,TOO_MANY_REQUESTS:429,ALREADY_REPORTED:208,MULTIPLE_CHOICES:300,PAYMENT_REQUIRED:402,UPGRADE_REQUIRED:426,PARTIAL_CONTENT:206,REQUEST_TIMEOUT:408,LENGTH_REQUIRED:411,NOT_IMPLEMENTED:501,GATEWAY_TIMEOUT:504,NOT_ACCEPTABLE:406,RESET_CONTENT:205,LOOP_DETECTED:508,MULTI_STATUS:207,NOT_MODIFIED:304,UNAUTHORIZED:401,URI_TOO_LONG:414,NOT_EXTENDED:510,EARLY_HINTS:103,BAD_REQUEST:400,IM_A_TEAPOT:418,BAD_GATEWAY:502,PROCESSING:102,NO_CONTENT:204,SEE_OTHER:303,USE_PROXY:305,FORBIDDEN:403,NOT_FOUND:404,TOO_EARLY:425,CONTINUE:100,ACCEPTED:202,CONFLICT:409,CREATED:201,IM_USED:226,LOCKED:423,FOUND:302,GONE:410,OK:200}),b={431:"Request Header Fields Too Large",511:"Network Authentication Required",203:"Non-Authoritative Information",407:"Proxy Authentication Required",451:"Unavailable For Legal Reasons",505:"HTTP Version Not Supported",509:"Bandwidth Limit Exceeded",506:"Variant Also Negotiates",415:"Unsupported Media Type",416:"Range Not Satisfiable",428:"Precondition Required",500:"Internal Server Error",422:"Unprocessable Entity",507:"Insufficient Storage",101:"Switching Protocols",412:"Precondition Failed",421:"Misdirected Request",503:"Service Unavailable",307:"Temporary Redirect",308:"Permanent Redirect",405:"Method Not Allowed",417:"Expectation Failed",301:"Moved Permanently",413:"Payload Too Large",424:"Failed Dependency",429:"Too Many Requests",208:"Already Reported",300:"Multiple Choices",402:"Payment Required",426:"Upgrade Required",206:"Partial Content",408:"Request Timeout",411:"Length Required",501:"Not Implemented",504:"Gateway Timeout",406:"Not Acceptable",205:"Reset Content",508:"Loop Detected",207:"Multi-Status",304:"Not Modified",401:"Unauthorized",414:"URI Too Long",418:"I'm a Teapot",510:"Not Extended",103:"Early Hints",400:"Bad Request",502:"Bad Gateway",102:"Processing",204:"No Content",303:"See Other",305:"Use Proxy",403:"Forbidden",404:"Not Found",425:"Too Early",100:"Continue",202:"Accepted",226:"I'm Used",409:"Conflict",201:"Created",423:"Locked",302:"Found",410:"Gone",200:"OK"};var A=class extends Error{constructor({code:e=b[500],isOperational:r=!1,status:a=500,metadata:n,message:T,cause:D}){super(T),this.name=new.target.name,this.code=e,this.status=a,this.isOperational=r,this.metadata=n,this.cause=D,Error.captureStackTrace(this,new.target)}};function i(t,e=new WeakSet){if(t==null||typeof t!="object")return t;if(e.has(t))throw new Error("Circular reference detected in ValueObject unwrap");if(e.add(t),Array.isArray(t)){let a=t.map(n=>i(n,e));return e.delete(t),a}if(t instanceof l){let a=i(t.value,e);return e.delete(t),a}if(t instanceof Date)return e.delete(t),t.toISOString();if(t instanceof Map){let a=new Map;return t.forEach((n,T)=>{a.set(T,i(n,e))}),e.delete(t),a}if(t instanceof Set){let a=new Set(Array.from(t.values()).map(n=>i(n,e)));return e.delete(t),a}let r={};for(let a in t)Object.hasOwn(t,a)&&(r[a]=i(t[a],e));return e.delete(t),r}function le(t){return t==null?{}:typeof t=="object"?t:{value:t}}export{R as AggregateId,y as AggregateRoot,A as ApplicationError,o as DomainError,g as DomainEvent,s as Entity,I as EntityValidationError,ne as HttpStatus,b as HttpStatusMessage,u as InvalidValueObjectError,d as PrimitiveValueObject,E as UUID,l as ValueObject,c as deepFreeze,le as ensureObject,i as unwrapValueObject};
2
2
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/domain/entities/entity.ts","../src/domain/aggregates/aggregate-root.ts","../src/domain/base/domain.error.ts","../src/domain/base/primitive-vo.ts","../src/domain/base/vo.ts","../src/utils/deep-freeze.util.ts","../src/domain/errors/entity-validation.error.ts","../src/domain/errors/invalid-vo.error.ts","../src/domain/events/domain.event.ts","../src/domain/value-objects/id.vo.ts","../src/domain/value-objects/aggregate-id.vo.ts","../src/gateway/constants/http-code.ts","../src/shared/domain/domain.violation.ts","../src/shared/domain/result.ts","../src/utils/errors/application.error.ts","../src/utils/unwrap-vo.util.ts"],"sourcesContent":["import { EntityId } from '../types';\n\n/**\n * Configuration for the base Entity constructor.\n * Forces a single-object argument pattern to avoid positional argument errors.\n * @template ID - A type satisfying the EntityId interface.\n */\nexport interface EntityProps<ID extends EntityId, Props> {\n /** The unique identity of the entity */\n readonly id: ID;\n /** Optional creation timestamp; defaults to 'now' if not provided */\n readonly createdAt?: Date;\n\n readonly props: Props;\n}\n\n/**\n * Abstract Base Entity for Domain-Driven Design (DDD).\n * This class provides the standard contract for entity equality and identity.\n * It intentionally avoids \"magic\" property bags to ensure V8 engine optimization\n * and better IDE intellisense.\n * @template ID - The specific Identity Value Object type.\n */\nexport abstract class Entity<ID extends EntityId, Props> {\n /** The timestamp when this entity was first instantiated/created */\n public readonly createdAt: Date;\n /** The immutable unique identifier for this entity */\n public readonly id: ID;\n\n /**\n * Protected constructor to be called by subclasses.\n * @param props - Initial identity and metadata.\n */\n protected constructor(props: EntityProps<ID, Props>) {\n this.id = props.id;\n this.createdAt = props.createdAt ?? new Date();\n }\n\n /**\n * Compares entities by identity.\n * In DDD, two entities are considered equal if their IDs match,\n * regardless of their other properties.\n * @param other - The entity to compare against.\n * @returns True if IDs are equal.\n */\n public equals(other?: Entity<ID, Props>): boolean {\n if (other == null) return false;\n if (this === other) return true;\n return this.id.equals(other.id);\n }\n\n /**\n * Converts the Entity into a plain Javascript object.\n * Subclasses must implement this to explicitly control serialization,\n * @returns A plain object representation of the entity.\n */\n public abstract toObject(): Record<string, unknown>;\n\n /**\n * Validates the current state of the entity against domain invariants.\n * This method should be called after construction and any mutation.\n * @throws {Error} Should throw a specific DomainError if validation fails.\n */\n public abstract validate(): void;\n}\n","import { Entity, EntityProps } from '../entities/entity';\nimport { DomainEvent } from '../events';\nimport { EntityId } from '../types';\n\n/**\n * Interface for AggregateRoot to ensure type safety and extensibility.\n */\nexport interface Props<P> extends EntityProps<EntityId, P> {\n readonly domainEvents: readonly DomainEvent[];\n /**\n * Adds a domain event to the aggregate.\n * @param event The domain event to add.\n */\n addEvent: (event: DomainEvent) => void;\n\n /**\n * Retrieves and clears all domain events recorded by this aggregate.\n *\n * Domain events represent facts that occurred as a result of state changes\n * within the aggregate. This method transfers ownership of those events\n * to the application layer for further processing (e.g. publishing).\n *\n * Calling this method has the side effect of clearing the aggregate's\n * internal event collection to prevent duplicate handling.\n *\n * This method is intended to be invoked by application services\n * after the aggregate has been successfully persisted.\n *\n * @returns A read-only list of domain events raised by this aggregate.\n */\n pullDomainEvents: () => readonly DomainEvent[];\n}\n\n/**\n * Base class for aggregate roots in DDD, encapsulating domain events and validation.\n * @template EntityProps The type of the entity's properties.\n */\nexport abstract class AggregateRoot<ID extends EntityId, P> extends Entity<\n ID,\n P\n> {\n /**\n * Gets a read-only copy of the domain events.\n */\n get domainEvents(): readonly DomainEvent[] {\n return [...this._domainEvents];\n }\n\n /**\n * Internal list of domain events.\n */\n private readonly _domainEvents: DomainEvent[] = [];\n\n /**\n * Adds a domain event to the aggregate after validating invariants.\n * @param domainEvent The domain event to add.\n * @throws {EntityValidationError} If invariants are not met.\n */\n addEvent(domainEvent: DomainEvent): void {\n this._domainEvents.push(domainEvent);\n }\n\n public pullDomainEvents(): readonly DomainEvent[] {\n const events = [...this._domainEvents];\n this._domainEvents.length = 0;\n return events;\n }\n}\n","export interface DomainErrorMetadata {\n cause?: { name: string; message: string; stack?: string };\n [key: string]: unknown;\n}\n\nconst getCauseInfo = (cause: Error | undefined) => {\n // 1. Handle Error objects specifically\n if (cause instanceof Error) {\n return {\n cause: {\n message: cause.message,\n stack: cause.stack,\n name: cause.name,\n },\n };\n }\n\n // 2. Handle other existing values\n if (cause) {\n return { cause };\n }\n\n // 3. Default to empty\n return {};\n};\n\n/**\n * Base class for all Domain Errors in the application.\n *\n * This class ensures:\n * 1. Serializable and structured for logs or API responses.\n * 2. Identifiable via stable error codes (not just class names).\n * 3. Contextual with optional structured metadata.\n * 4. Supports error chaining (cause) and stack trace preservation.\n *\n * @example\n * export class InsufficientFundsError extends DomainError {\n * constructor(accountId: string, currentBalance: number) {\n * super(\n * `Account ${accountId} has insufficient funds.`,\n * 'INSUFFICIENT_FUNDS',\n * { accountId, currentBalance }\n * );\n * }\n * }\n */\nexport abstract class DomainError extends Error {\n /** Stable, machine-readable error code */\n public readonly code: string;\n /** Structured, immutable domain metadata */\n public readonly metadata: Readonly<DomainErrorMetadata>;\n\n /**\n * @param message - Human-readable error message\n * @param code - Stable error code\n * @param metadata - Domain-specific structured data; optional `cause` can be included\n */\n protected constructor(\n message: string,\n code: string,\n metadata: DomainErrorMetadata = {},\n ) {\n super(message, { ...getCauseInfo(metadata.cause) });\n\n // Restore prototype chain for proper `instanceof` checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n this.name = new.target.name;\n this.code = code;\n this.metadata = Object.freeze({ ...metadata });\n }\n}\n","import { EntityId } from '../types';\n\ntype Primitive = boolean | number | string;\n\n/**\n * Base class for primitive-based Value Objects.\n *\n * This class is intended for Value Objects that are represented by\n * a single primitive value (string, number, or boolean).\n *\n * Characteristics:\n * - Immutable by construction\n * - Cheap equality comparison\n * - No deep cloning or freezing\n * - Safe for serialization and logging\n *\n * Examples:\n * - AggregateId\n * - EmailAddress\n * - Username\n * - Slug\n */\nexport abstract class PrimitiveValueObject<\n T extends Primitive,\n> implements EntityId {\n /**\n * The underlying primitive value.\n * Guaranteed to be valid after construction.\n */\n protected readonly value: T;\n\n /**\n * Constructs a new PrimitiveValueObject.\n *\n * @param value - The primitive value to wrap\n * @throws Error if validation fails\n */\n protected constructor(value: T) {\n this.validate(value);\n this.value = value;\n }\n\n /**\n * Compares two Value Objects for equality.\n *\n * Equality rules:\n * - Same concrete class\n * - Same primitive value (===)\n *\n * @param other - Another Value Object\n */\n public equals(other?: PrimitiveValueObject<T> | null | undefined): boolean {\n if (other === undefined || other === null) return false;\n\n if (Object.getPrototypeOf(this) !== Object.getPrototypeOf(other)) {\n return false;\n }\n\n return this.value === other.value;\n }\n\n /**\n * Returns the primitive value.\n * Prefer explicit access over implicit coercion.\n */\n public getValue(): T {\n return this.value;\n }\n\n /**\n * JSON serialization hook.\n * Produces the raw primitive value.\n */\n public toJSON(): T {\n return this.value;\n }\n\n /**\n * String representation.\n * Useful for logging and debugging.\n */\n public toString(): string {\n return String(this.value);\n }\n\n /**\n * Domain invariant validation.\n * Must throw if the value is invalid.\n *\n * @param value - The value to validate\n */\n protected abstract validate(value: T): void;\n}\n","import deepEqual from 'fast-deep-equal/es6';\n\nimport { deepFreeze } from '@/utils/deep-freeze.util';\n\nexport abstract class ValueObject<T> {\n get value(): T {\n return this.props;\n }\n\n protected readonly props: Readonly<T>;\n\n protected constructor(props: T) {\n this.validate(props);\n this.props = deepFreeze(props);\n }\n\n /**\n * Type guard to check if an unknown object is an instance of ValueObject.\n * This is useful for runtime type checking.\n *\n * @param vo The object to check.\n * @returns True if the object is a ValueObject instance, false otherwise.\n */\n public static is(vo: unknown): vo is ValueObject<unknown> {\n return vo instanceof ValueObject;\n }\n\n /**\n * Deep equality comparison of ValueObjects\n */\n public equals(other?: ValueObject<T>): boolean {\n if (other === null || other === undefined) return false;\n\n // Check if they share the same constructor (Type check)\n if (Object.getPrototypeOf(this) !== Object.getPrototypeOf(other)) {\n return false;\n }\n\n return deepEqual(this.props, other.props);\n }\n\n /**\n * Standard for clean API integration and logging.\n */\n public toJSON(): T {\n return this.props;\n }\n\n /**\n * Useful for debugging and string-based indexing.\n */\n public toString(): string {\n return JSON.stringify(this.props);\n }\n\n /**\n * Validates the value object props\n * @throws InvalidValueObjectError if validation fails\n */\n protected abstract validate(props: T): void;\n}\n","/**\n * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.\n *\n * @param obj - The object to be deeply frozen.\n * @param seen - A WeakSet to track already processed objects (for circular references).\n * @returns A deeply frozen version of the input object.\n */\nexport function deepFreeze<T>(\n obj: T,\n seen = new WeakSet<object>(),\n): Readonly<T> {\n // Handle null, undefined, or non-object types\n if (obj == null || (typeof obj !== 'object' && !Array.isArray(obj))) {\n return obj;\n }\n\n // Skip if already frozen\n if (Object.isFrozen(obj)) {\n return obj as Readonly<T>;\n }\n\n // Handle circular references\n if (seen.has(obj as object)) {\n return obj as Readonly<T>;\n }\n\n seen.add(obj as object);\n\n // Handle arrays explicitly\n if (Array.isArray(obj)) {\n obj.forEach(item => deepFreeze(item, seen));\n } else {\n // Handle plain objects\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n deepFreeze((obj as Record<string, unknown>)[key], seen);\n }\n }\n }\n\n return Object.freeze(obj) as Readonly<T>;\n}\n","import { DomainError } from '../base/domain.error';\n\n/**\n * Custom error class for entity validation failures.\n */\nexport class EntityValidationError extends DomainError {\n constructor(message: string, cause?: Error) {\n super(message, 'ENTITY_VALIDATION_ERROR', { cause });\n }\n}\n","import { DomainError } from '../base/domain.error';\n\nexport class InvalidValueObjectError extends DomainError {\n constructor(message: string) {\n super(message, 'INVALID_VALUE_OBJECT');\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { EntityId } from '../types';\n\ntype Primitive = boolean | number | string | null;\n\ntype Serializable =\n | Primitive\n | Serializable[]\n | { [key: string]: Serializable };\n\nexport type DomainEventPayload = Record<string, Serializable>;\n\nexport type UnixTimestampMillis = number;\n\ntype DomainEventProps<AggregateId extends EntityId, Payload> = {\n id?: string;\n aggregateId: AggregateId;\n schemaVersion: number;\n occurredAt: UnixTimestampMillis;\n payload: Payload;\n};\n\n// Abstract base class for domain events\nexport abstract class DomainEvent<\n AggregateId extends EntityId = EntityId,\n T extends DomainEventPayload = DomainEventPayload,\n> {\n public readonly aggregateId: AggregateId;\n\n public abstract readonly eventName: string;\n public readonly id: string;\n public readonly occurredAt: number;\n public readonly payload: Readonly<T>;\n public readonly schemaVersion: number;\n\n protected constructor(props: DomainEventProps<AggregateId, T>) {\n this.id = props.id ?? randomUUID();\n this.aggregateId = props.aggregateId;\n this.schemaVersion = props.schemaVersion;\n this.occurredAt = props.occurredAt;\n this.payload = Object.freeze(props.payload);\n }\n\n public toPrimitives(): Readonly<{\n id: string;\n eventName: string;\n aggregateId: string;\n schemaVersion: number;\n occurredAt: UnixTimestampMillis;\n payload: T;\n }> {\n return {\n aggregateId: this.aggregateId.toString(),\n schemaVersion: this.schemaVersion,\n occurredAt: this.occurredAt,\n eventName: this.eventName,\n payload: this.payload,\n id: this.id,\n };\n }\n}\n","import { v4 } from 'uuid';\nimport z from 'zod';\n\nimport { InvalidValueObjectError } from '../errors/invalid-vo.error';\nimport { PrimitiveValueObject } from '../base/primitive-vo';\n\n/**\n * Represents a UUID (Universally Unique Identifier) value object.\n *\n * This class extends PrimitiveValueObject to provide type-safe UUID handling\n * with validation using Zod schema. UUIDs are immutable and can be generated\n * randomly or created from string values.\n *\n * @example\n * // Generate a new random UUID\n * const id = UUID.generate();\n *\n * @example\n * // Create UUID from an existing string\n * const id = UUID.fromString('550e8400-e29b-41d4-a716-446655440000');\n *\n * @throws {InvalidValueObjectError} When the provided string is not a valid UUID format\n */\nexport class UUID extends PrimitiveValueObject<string> {\n private static readonly schema = z.uuid();\n\n public constructor(value: string) {\n super(value);\n this.validate(value);\n }\n\n /**\n * Creates an UUID from an external string.\n * Use only for untrusted input.\n *\n * @param value - UUID string\n */\n public static fromString(value: string): UUID {\n return new this(value);\n }\n\n /**\n * Generates a new AggregateId.\n */\n public static generate<T extends typeof UUID>(this: T): InstanceType<T> {\n return new this(v4()) as InstanceType<T>;\n }\n\n protected validate(value: string): void {\n const result = UUID.schema.safeParse(value);\n\n if (!result.success) {\n throw new InvalidValueObjectError(\n `Invalid UUID: ${result.error.message}`,\n );\n }\n }\n}\n","import { UUID } from './id.vo';\n\n/**\n * AggregateId represents a strongly-typed aggregate identifier.\n *\n * - Backed by UUID v4\n * - Immutable\n * - Comparable only to AggregateId\n */\nexport class AggregateId extends UUID {}\n","/**\n * HTTP status code catalog.\n *\n * This object provides a typed, immutable map of standard HTTP status names\n * to their numeric codes. Designed for server-side frameworks such as Fastify.\n *\n * - All identifiers use clear, canonical semantic names.\n * - Values are numeric status codes.\n * - Frozen to prevent runtime mutation.\n * - Exporting `HttpStatus` ensures type-safe usage across the codebase.\n * Usage:\n * ```ts\n * import { HttpStatus } from 'path-to-this-file';\n *\n * function handleRequest() {\n * return {\n * statusCode: HttpStatus.OK,\n * body: 'Success',\n * };\n * }\n * ```\n */\nexport const HttpStatus = Object.freeze({\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n NON_AUTHORITATIVE_INFORMATION: 203,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n BANDWIDTH_LIMIT_EXCEEDED: 509,\n VARIANT_ALSO_NEGOTIATES: 506,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n PRECONDITION_REQUIRED: 428,\n INTERNAL_SERVER_ERROR: 500,\n UNPROCESSABLE_ENTITY: 422,\n INSUFFICIENT_STORAGE: 507,\n\n SWITCHING_PROTOCOLS: 101,\n PRECONDITION_FAILED: 412,\n MISDIRECTED_REQUEST: 421,\n SERVICE_UNAVAILABLE: 503,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n METHOD_NOT_ALLOWED: 405,\n EXPECTATION_FAILED: 417,\n\n MOVED_PERMANENTLY: 301,\n PAYLOAD_TOO_LARGE: 413,\n FAILED_DEPENDENCY: 424,\n TOO_MANY_REQUESTS: 429,\n ALREADY_REPORTED: 208,\n MULTIPLE_CHOICES: 300,\n PAYMENT_REQUIRED: 402,\n UPGRADE_REQUIRED: 426,\n PARTIAL_CONTENT: 206,\n REQUEST_TIMEOUT: 408,\n LENGTH_REQUIRED: 411,\n NOT_IMPLEMENTED: 501,\n GATEWAY_TIMEOUT: 504,\n NOT_ACCEPTABLE: 406,\n RESET_CONTENT: 205,\n LOOP_DETECTED: 508,\n MULTI_STATUS: 207,\n NOT_MODIFIED: 304,\n UNAUTHORIZED: 401,\n URI_TOO_LONG: 414,\n NOT_EXTENDED: 510,\n EARLY_HINTS: 103,\n BAD_REQUEST: 400,\n IM_A_TEAPOT: 418,\n BAD_GATEWAY: 502,\n PROCESSING: 102,\n NO_CONTENT: 204,\n SEE_OTHER: 303,\n USE_PROXY: 305,\n\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n TOO_EARLY: 425,\n CONTINUE: 100,\n ACCEPTED: 202,\n CONFLICT: 409,\n CREATED: 201,\n IM_USED: 226,\n LOCKED: 423,\n FOUND: 302,\n GONE: 410,\n OK: 200,\n} as const);\n\n/**\n * HTTP status messages mapped by numeric code.\n * Use for sending descriptive text in responses or logging.\n */\nexport const HttpStatusMessage = {\n 431: 'Request Header Fields Too Large',\n 511: 'Network Authentication Required',\n 203: 'Non-Authoritative Information',\n 407: 'Proxy Authentication Required',\n 451: 'Unavailable For Legal Reasons',\n 505: 'HTTP Version Not Supported',\n 509: 'Bandwidth Limit Exceeded',\n 506: 'Variant Also Negotiates',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 428: 'Precondition Required',\n 500: 'Internal Server Error',\n 422: 'Unprocessable Entity',\n 507: 'Insufficient Storage',\n 101: 'Switching Protocols',\n 412: 'Precondition Failed',\n 421: 'Misdirected Request',\n 503: 'Service Unavailable',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 405: 'Method Not Allowed',\n 417: 'Expectation Failed',\n 301: 'Moved Permanently',\n 413: 'Payload Too Large',\n 424: 'Failed Dependency',\n 429: 'Too Many Requests',\n 208: 'Already Reported',\n 300: 'Multiple Choices',\n 402: 'Payment Required',\n 426: 'Upgrade Required',\n 206: 'Partial Content',\n 408: 'Request Timeout',\n 411: 'Length Required',\n 501: 'Not Implemented',\n 504: 'Gateway Timeout',\n 406: 'Not Acceptable',\n 205: 'Reset Content',\n 508: 'Loop Detected',\n 207: 'Multi-Status',\n 304: 'Not Modified',\n 401: 'Unauthorized',\n 414: 'URI Too Long',\n 418: \"I'm a Teapot\",\n 510: 'Not Extended',\n 103: 'Early Hints',\n 400: 'Bad Request',\n 502: 'Bad Gateway',\n 102: 'Processing',\n 204: 'No Content',\n 303: 'See Other',\n 305: 'Use Proxy',\n 403: 'Forbidden',\n 404: 'Not Found',\n 425: 'Too Early',\n 100: 'Continue',\n 202: 'Accepted',\n 226: \"I'm Used\",\n 409: 'Conflict',\n 201: 'Created',\n 423: 'Locked',\n 302: 'Found',\n 410: 'Gone',\n 200: 'OK',\n} as const;\n\nexport type HttpStatusCode = keyof typeof HttpStatusMessage;\n\nexport type HttpStatusMessage =\n (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];\n","/**\n * Base class for Domain violations.\n * Purposely does NOT extend native Error to avoid stack trace overhead in the domain.\n */\nexport abstract class DomainViolation {\n public abstract readonly code: string;\n public abstract readonly message: string;\n public readonly metadata: Readonly<Record<string, unknown>>;\n\n protected constructor(metadata: Record<string, unknown> = {}) {\n this.metadata = Object.freeze(metadata);\n }\n}\n","/**\n * Represents the outcome of an operation that can either succeed or fail,\n * without relying on exceptions for control flow.\n *\n * This pattern is commonly used in domain and application layers to make\n * success and failure states explicit, predictable, and type-safe.\n *\n * ## Design guarantees\n * - A `Result` is **immutable** once created.\n * - A `Result` is **exactly one of**:\n * - Success → contains a value\n * - Failure → contains an error\n * - Accessing the wrong side throws immediately (fail-fast).\n *\n * @typeParam T - Type of the success value\n * @typeParam E - Type of the failure error\n *\n * @example\n * ```ts\n * function parseNumber(input: string): Result<number, string> {\n * const value = Number(input);\n *\n * if (Number.isNaN(value)) {\n * return Result.fail('Invalid number');\n * }\n *\n * return Result.ok(value);\n * }\n *\n * const result = parseNumber('42');\n *\n * if (result.isSuccess) {\n * console.log(result.getValue()); // 42\n * } else {\n * console.error(result.getError());\n * }\n * ```\n */\nexport class Result<T, E> {\n /**\n * Indicates whether the result represents a failed outcome.\n *\n * This flag is mutually exclusive with {@link isSuccess}.\n */\n public readonly isFailure: boolean;\n /**\n * Indicates whether the result represents a successful outcome.\n *\n * This flag is mutually exclusive with {@link isFailure}.\n */\n public readonly isSuccess: boolean;\n\n /**\n * Creates a new {@link Result} instance.\n *\n * This constructor is private to enforce the use of\n * {@link Result.ok} and {@link Result.fail} factory methods,\n * preserving the success/failure invariants.\n *\n * @param _value - Success value (defined only for success results)\n * @param _error - Failure error (defined only for failure results)\n */\n private constructor(\n private readonly _value?: T,\n private readonly _error?: E,\n ) {\n this.isSuccess = _error === undefined;\n this.isFailure = !this.isSuccess;\n Object.freeze(this);\n }\n\n /**\n * Creates a failed {@link Result}.\n *\n * @param error - Error describing the failure\n * @returns A failure {@link Result} containing the provided error\n *\n * @example\n * ```ts\n * return Result.fail(new ValidationError('Email is invalid'));\n * ```\n */\n public static fail<T, E>(error: E): Result<T, E> {\n return new Result<T, E>(undefined, error);\n }\n\n /**\n * Creates a successful {@link Result}.\n *\n * @param value - Value representing a successful outcome\n * @returns A success {@link Result} containing the provided value\n *\n * @example\n * ```ts\n * return Result.ok(user);\n * ```\n */\n public static ok<T, E>(value: T): Result<T, E> {\n return new Result<T, E>(value);\n }\n\n /**\n * Returns the failure error.\n *\n * @returns The error associated with a failed result\n *\n * @throws {Error}\n * Thrown if this result represents a success.\n * This is a fail-fast guard against incorrect usage.\n *\n * @example\n * ```ts\n * if (result.isFailure) {\n * const error = result.getError();\n * }\n * ```\n */\n public getError(): E {\n if (this.isSuccess) {\n throw new Error('Result: Cannot get error of a success.');\n }\n\n return this._error as E;\n }\n\n /**\n * Returns the success value.\n *\n * @returns The value associated with a successful result\n *\n * @throws {Error}\n * Thrown if this result represents a failure.\n * This is a fail-fast guard against incorrect usage.\n *\n * @example\n * ```ts\n * if (result.isSuccess) {\n * const value = result.getValue();\n * }\n * ```\n */\n public getValue(): T {\n if (this.isFailure) {\n throw new Error('Result: Cannot get value of a failure.');\n }\n\n return this._value as T;\n }\n}\n","import {\n HttpStatusCode,\n HttpStatusMessage,\n} from '@/gateway/constants/http-code';\n\ninterface ErrorParams {\n message: string;\n code: HttpStatusMessage;\n status?: HttpStatusCode;\n metadata?: Record<string, unknown> | undefined;\n isOperational?: boolean;\n cause?: Error | undefined;\n}\n\n/**\n * Abstract base class for application-level errors with structured error handling.\n *\n * Extends the native Error class to provide machine-readable error codes, HTTP status codes,\n * operational error classification, and optional metadata for better error tracking and client communication.\n *\n * @abstract\n * @extends {Error}\n *\n * @example\n * ```typescript\n * class UserNotFoundError extends ApplicationError {\n * constructor(userId: string) {\n * super({\n * code: HttpStatusMessage['404'],\n * status: 404,\n * isOperational: true,\n * message: `User with id ${userId} not found`,\n * metadata: { userId }\n * });\n * }\n * }\n * ```\n */\nexport abstract class ApplicationError extends Error {\n /** Optional cause (linked error) */\n public readonly cause?: Error | undefined;\n /** Machine-readable error code (e.g. `OTP_LOCKED`, `USER_NOT_FOUND`) */\n public readonly code: HttpStatusMessage;\n /** Operational vs programmer error flag */\n public readonly isOperational: boolean;\n /** Optional structured metadata for debugging or clients */\n public readonly metadata?: Record<string, unknown> | undefined;\n /** HTTP status code intended for response layer */\n public readonly status: HttpStatusCode;\n\n constructor({\n code = HttpStatusMessage['500'],\n isOperational = false,\n status = 500,\n metadata,\n message,\n cause,\n }: ErrorParams) {\n super(message);\n\n this.name = new.target.name;\n this.code = code;\n this.status = status;\n this.isOperational = isOperational;\n this.metadata = metadata;\n this.cause = cause;\n\n Error.captureStackTrace(this, new.target);\n }\n}\n","import { ValueObject } from '@/domain/base/vo';\n\nexport type UnwrapValueObject<T> =\n T extends ValueObject<infer V>\n ? UnwrapValueObject<V>\n : T extends (infer U)[]\n ? UnwrapValueObject<U>[]\n : T extends Map<infer K, infer V>\n ? Map<K, UnwrapValueObject<V>>\n : T extends Set<infer V>\n ? Set<UnwrapValueObject<V>>\n : T extends Date\n ? string\n : T extends object\n ? { [K in keyof T]: UnwrapValueObject<T[K]> }\n : T;\n\nexport function unwrapValueObject<T>(\n input: T,\n seen = new WeakSet(),\n): UnwrapValueObject<T> {\n if (input === null || input === undefined) {\n return input as UnwrapValueObject<T>;\n }\n\n if (typeof input !== 'object') {\n return input as UnwrapValueObject<T>;\n }\n\n if (seen.has(input)) {\n // Prevent circular reference infinite recursion, just return input or throw\n throw new Error('Circular reference detected in ValueObject unwrap');\n }\n\n seen.add(input);\n\n if (Array.isArray(input)) {\n const result = input.map(item => unwrapValueObject(item, seen));\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof ValueObject) {\n const result = unwrapValueObject(input.value, seen);\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Date) {\n seen.delete(input);\n return input.toISOString() as UnwrapValueObject<T>;\n }\n\n if (input instanceof Map) {\n const result = new Map();\n input.forEach((value, key) => {\n result.set(key, unwrapValueObject(value, seen));\n });\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Set) {\n const result = new Set(\n Array.from(input.values()).map(v => unwrapValueObject(v, seen)),\n );\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n // generic object\n const result: Record<string, unknown> = {};\n\n for (const key in input) {\n if (Object.hasOwn(input, key)) {\n result[key] = unwrapValueObject((input as any)[key], seen);\n }\n }\n\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n}\n\nexport function ensureObject<T>(input: UnwrapValueObject<T>): object {\n if (input === null || input === undefined) {\n return {};\n }\n if (typeof input === 'object') {\n return input;\n }\n\n // for primitives, wrap inside object with default key (or throw)\n return { value: input };\n}\n"],"mappings":"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","names":["Entity","props","_a","other","AggregateRoot","Entity","domainEvent","events","getCauseInfo","cause","DomainError","message","code","metadata","__spreadValues","PrimitiveValueObject","value","other","deepEqual","deepFreeze","obj","seen","item","key","ValueObject","_ValueObject","props","deepFreeze","vo","other","deepEqual","EntityValidationError","DomainError","message","cause","InvalidValueObjectError","DomainError","message","randomUUID","DomainEvent","props","_a","v4","z","_UUID","PrimitiveValueObject","value","v4","result","InvalidValueObjectError","z","UUID","AggregateId","UUID","HttpStatus","HttpStatusMessage","DomainViolation","metadata","Result","_Result","_value","_error","error","value","ApplicationError","code","HttpStatusMessage","isOperational","status","metadata","message","cause","unwrapValueObject","input","seen","result","item","ValueObject","value","key","v","ensureObject"]}
1
+ {"version":3,"sources":["../src/domain/entities/entity.ts","../src/domain/aggregates/aggregate-root.ts","../src/domain/base/domain.error.ts","../src/domain/base/primitive-vo.ts","../src/domain/base/vo.ts","../src/utils/deep-freeze.util.ts","../src/domain/errors/entity-validation.error.ts","../src/domain/errors/invalid-vo.error.ts","../src/domain/events/domain.event.ts","../src/domain/value-objects/id.vo.ts","../src/domain/value-objects/aggregate-id.vo.ts","../src/gateway/constants/http-code.ts","../src/utils/errors/application.error.ts","../src/utils/unwrap-vo.util.ts"],"sourcesContent":["import { EntityId } from '../types';\n\n/**\n * Configuration for the base Entity constructor.\n * Forces a single-object argument pattern to avoid positional argument errors.\n * @template ID - A type satisfying the EntityId interface.\n */\nexport interface EntityProps<ID extends EntityId, Props> {\n /** The unique identity of the entity */\n readonly id: ID;\n /** Optional creation timestamp; defaults to 'now' if not provided */\n readonly createdAt?: Date;\n\n readonly props: Props;\n}\n\n/**\n * Abstract Base Entity for Domain-Driven Design (DDD).\n * This class provides the standard contract for entity equality and identity.\n * It intentionally avoids \"magic\" property bags to ensure V8 engine optimization\n * and better IDE intellisense.\n * @template ID - The specific Identity Value Object type.\n */\nexport abstract class Entity<ID extends EntityId, Props> {\n /** The timestamp when this entity was first instantiated/created */\n public readonly createdAt: Date;\n /** The immutable unique identifier for this entity */\n public readonly id: ID;\n\n /**\n * Protected constructor to be called by subclasses.\n * @param props - Initial identity and metadata.\n */\n protected constructor(props: EntityProps<ID, Props>) {\n this.id = props.id;\n this.createdAt = props.createdAt ?? new Date();\n }\n\n /**\n * Compares entities by identity.\n * In DDD, two entities are considered equal if their IDs match,\n * regardless of their other properties.\n * @param other - The entity to compare against.\n * @returns True if IDs are equal.\n */\n public equals(other?: Entity<ID, Props>): boolean {\n if (other == null) return false;\n if (this === other) return true;\n return this.id.equals(other.id);\n }\n\n /**\n * Converts the Entity into a plain Javascript object.\n * Subclasses must implement this to explicitly control serialization,\n * @returns A plain object representation of the entity.\n */\n public abstract toObject(): Record<string, unknown>;\n\n /**\n * Validates the current state of the entity against domain invariants.\n * This method should be called after construction and any mutation.\n * @throws {Error} Should throw a specific DomainError if validation fails.\n */\n public abstract validate(): void;\n}\n","import { Entity, EntityProps } from '../entities/entity';\nimport { DomainEvent } from '../events';\nimport { EntityId } from '../types';\n\n/**\n * Interface for AggregateRoot to ensure type safety and extensibility.\n */\nexport interface Props<P> extends EntityProps<EntityId, P> {\n readonly domainEvents: readonly DomainEvent[];\n /**\n * Adds a domain event to the aggregate.\n * @param event The domain event to add.\n */\n addEvent: (event: DomainEvent) => void;\n\n /**\n * Retrieves and clears all domain events recorded by this aggregate.\n *\n * Domain events represent facts that occurred as a result of state changes\n * within the aggregate. This method transfers ownership of those events\n * to the application layer for further processing (e.g. publishing).\n *\n * Calling this method has the side effect of clearing the aggregate's\n * internal event collection to prevent duplicate handling.\n *\n * This method is intended to be invoked by application services\n * after the aggregate has been successfully persisted.\n *\n * @returns A read-only list of domain events raised by this aggregate.\n */\n pullDomainEvents: () => readonly DomainEvent[];\n}\n\n/**\n * Base class for aggregate roots in DDD, encapsulating domain events and validation.\n * @template EntityProps The type of the entity's properties.\n */\nexport abstract class AggregateRoot<ID extends EntityId, P> extends Entity<\n ID,\n P\n> {\n /**\n * Gets a read-only copy of the domain events.\n */\n get domainEvents(): readonly DomainEvent[] {\n return [...this._domainEvents];\n }\n\n /**\n * Internal list of domain events.\n */\n private readonly _domainEvents: DomainEvent[] = [];\n\n /**\n * Adds a domain event to the aggregate after validating invariants.\n * @param domainEvent The domain event to add.\n * @throws {EntityValidationError} If invariants are not met.\n */\n addEvent(domainEvent: DomainEvent): void {\n this._domainEvents.push(domainEvent);\n }\n\n public pullDomainEvents(): readonly DomainEvent[] {\n const events = [...this._domainEvents];\n this._domainEvents.length = 0;\n return events;\n }\n}\n","export interface DomainErrorMetadata {\n cause?: { name: string; message: string; stack?: string };\n [key: string]: unknown;\n}\n\nconst getCauseInfo = (cause: Error | undefined) => {\n // 1. Handle Error objects specifically\n if (cause instanceof Error) {\n return {\n cause: {\n message: cause.message,\n stack: cause.stack,\n name: cause.name,\n },\n };\n }\n\n // 2. Handle other existing values\n if (cause) {\n return { cause };\n }\n\n // 3. Default to empty\n return {};\n};\n\n/**\n * Base class for all Domain Errors in the application.\n *\n * This class ensures:\n * 1. Serializable and structured for logs or API responses.\n * 2. Identifiable via stable error codes (not just class names).\n * 3. Contextual with optional structured metadata.\n * 4. Supports error chaining (cause) and stack trace preservation.\n *\n * @example\n * export class InsufficientFundsError extends DomainError {\n * constructor(accountId: string, currentBalance: number) {\n * super(\n * `Account ${accountId} has insufficient funds.`,\n * 'INSUFFICIENT_FUNDS',\n * { accountId, currentBalance }\n * );\n * }\n * }\n */\nexport abstract class DomainError extends Error {\n /** Stable, machine-readable error code */\n public readonly code: string;\n /** Structured, immutable domain metadata */\n public readonly metadata: Readonly<DomainErrorMetadata>;\n\n /**\n * @param message - Human-readable error message\n * @param code - Stable error code\n * @param metadata - Domain-specific structured data; optional `cause` can be included\n */\n protected constructor(\n message: string,\n code: string,\n metadata: DomainErrorMetadata = {},\n ) {\n super(message, { ...getCauseInfo(metadata.cause) });\n\n // Restore prototype chain for proper `instanceof` checks\n Object.setPrototypeOf(this, new.target.prototype);\n\n this.name = new.target.name;\n this.code = code;\n this.metadata = Object.freeze({ ...metadata });\n }\n}\n","import { EntityId } from '../types';\n\ntype Primitive = boolean | number | string;\n\n/**\n * Base class for primitive-based Value Objects.\n *\n * This class is intended for Value Objects that are represented by\n * a single primitive value (string, number, or boolean).\n *\n * Characteristics:\n * - Immutable by construction\n * - Cheap equality comparison\n * - No deep cloning or freezing\n * - Safe for serialization and logging\n *\n * Examples:\n * - AggregateId\n * - EmailAddress\n * - Username\n * - Slug\n */\nexport abstract class PrimitiveValueObject<\n T extends Primitive,\n> implements EntityId {\n /**\n * The underlying primitive value.\n * Guaranteed to be valid after construction.\n */\n protected readonly value: T;\n\n /**\n * Constructs a new PrimitiveValueObject.\n *\n * @param value - The primitive value to wrap\n * @throws Error if validation fails\n */\n protected constructor(value: T) {\n this.validate(value);\n this.value = value;\n }\n\n /**\n * Compares two Value Objects for equality.\n *\n * Equality rules:\n * - Same concrete class\n * - Same primitive value (===)\n *\n * @param other - Another Value Object\n */\n public equals(other?: PrimitiveValueObject<T> | null | undefined): boolean {\n if (other === undefined || other === null) return false;\n\n if (Object.getPrototypeOf(this) !== Object.getPrototypeOf(other)) {\n return false;\n }\n\n return this.value === other.value;\n }\n\n /**\n * Returns the primitive value.\n * Prefer explicit access over implicit coercion.\n */\n public getValue(): T {\n return this.value;\n }\n\n /**\n * JSON serialization hook.\n * Produces the raw primitive value.\n */\n public toJSON(): T {\n return this.value;\n }\n\n /**\n * String representation.\n * Useful for logging and debugging.\n */\n public toString(): string {\n return String(this.value);\n }\n\n /**\n * Domain invariant validation.\n * Must throw if the value is invalid.\n *\n * @param value - The value to validate\n */\n protected abstract validate(value: T): void;\n}\n","import deepEqual from 'fast-deep-equal/es6';\n\nimport { deepFreeze } from '@/utils/deep-freeze.util';\n\nexport abstract class ValueObject<T> {\n get value(): T {\n return this.props;\n }\n\n protected readonly props: Readonly<T>;\n\n protected constructor(props: T) {\n this.validate(props);\n this.props = deepFreeze(props);\n }\n\n /**\n * Type guard to check if an unknown object is an instance of ValueObject.\n * This is useful for runtime type checking.\n *\n * @param vo The object to check.\n * @returns True if the object is a ValueObject instance, false otherwise.\n */\n public static is(vo: unknown): vo is ValueObject<unknown> {\n return vo instanceof ValueObject;\n }\n\n /**\n * Deep equality comparison of ValueObjects\n */\n public equals(other?: ValueObject<T>): boolean {\n if (other === null || other === undefined) return false;\n\n // Check if they share the same constructor (Type check)\n if (Object.getPrototypeOf(this) !== Object.getPrototypeOf(other)) {\n return false;\n }\n\n return deepEqual(this.props, other.props);\n }\n\n /**\n * Standard for clean API integration and logging.\n */\n public toJSON(): T {\n return this.props;\n }\n\n /**\n * Useful for debugging and string-based indexing.\n */\n public toString(): string {\n return JSON.stringify(this.props);\n }\n\n /**\n * Validates the value object props\n * @throws InvalidValueObjectError if validation fails\n */\n protected abstract validate(props: T): void;\n}\n","/**\n * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.\n *\n * @param obj - The object to be deeply frozen.\n * @param seen - A WeakSet to track already processed objects (for circular references).\n * @returns A deeply frozen version of the input object.\n */\nexport function deepFreeze<T>(\n obj: T,\n seen = new WeakSet<object>(),\n): Readonly<T> {\n // Handle null, undefined, or non-object types\n if (obj == null || (typeof obj !== 'object' && !Array.isArray(obj))) {\n return obj;\n }\n\n // Skip if already frozen\n if (Object.isFrozen(obj)) {\n return obj as Readonly<T>;\n }\n\n // Handle circular references\n if (seen.has(obj as object)) {\n return obj as Readonly<T>;\n }\n\n seen.add(obj as object);\n\n // Handle arrays explicitly\n if (Array.isArray(obj)) {\n obj.forEach(item => deepFreeze(item, seen));\n } else {\n // Handle plain objects\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n deepFreeze((obj as Record<string, unknown>)[key], seen);\n }\n }\n }\n\n return Object.freeze(obj) as Readonly<T>;\n}\n","import { DomainError } from '../base/domain.error';\n\n/**\n * Custom error class for entity validation failures.\n */\nexport class EntityValidationError extends DomainError {\n constructor(message: string, cause?: Error) {\n super(message, 'ENTITY_VALIDATION_ERROR', { cause });\n }\n}\n","import { DomainError } from '../base/domain.error';\n\nexport class InvalidValueObjectError extends DomainError {\n constructor(message: string) {\n super(message, 'INVALID_VALUE_OBJECT');\n }\n}\n","import { randomUUID } from 'node:crypto';\n\nimport { EntityId } from '../types';\n\ntype Primitive = boolean | number | string | null;\n\ntype Serializable =\n | Primitive\n | Serializable[]\n | { [key: string]: Serializable };\n\nexport type DomainEventPayload = Record<string, Serializable>;\n\nexport type UnixTimestampMillis = number;\n\ntype DomainEventProps<AggregateId extends EntityId, Payload> = {\n id?: string;\n aggregateId: AggregateId;\n schemaVersion: number;\n occurredAt: UnixTimestampMillis;\n payload: Payload;\n};\n\n// Abstract base class for domain events\nexport abstract class DomainEvent<\n AggregateId extends EntityId = EntityId,\n T extends DomainEventPayload = DomainEventPayload,\n> {\n public readonly aggregateId: AggregateId;\n\n public abstract readonly eventName: string;\n public readonly id: string;\n public readonly occurredAt: number;\n public readonly payload: Readonly<T>;\n public readonly schemaVersion: number;\n\n protected constructor(props: DomainEventProps<AggregateId, T>) {\n this.id = props.id ?? randomUUID();\n this.aggregateId = props.aggregateId;\n this.schemaVersion = props.schemaVersion;\n this.occurredAt = props.occurredAt;\n this.payload = Object.freeze(props.payload);\n }\n\n public toPrimitives(): Readonly<{\n id: string;\n eventName: string;\n aggregateId: string;\n schemaVersion: number;\n occurredAt: UnixTimestampMillis;\n payload: T;\n }> {\n return {\n aggregateId: this.aggregateId.toString(),\n schemaVersion: this.schemaVersion,\n occurredAt: this.occurredAt,\n eventName: this.eventName,\n payload: this.payload,\n id: this.id,\n };\n }\n}\n","import { v4 } from 'uuid';\nimport z from 'zod';\n\nimport { InvalidValueObjectError } from '../errors/invalid-vo.error';\nimport { PrimitiveValueObject } from '../base/primitive-vo';\n\n/**\n * Represents a UUID (Universally Unique Identifier) value object.\n *\n * This class extends PrimitiveValueObject to provide type-safe UUID handling\n * with validation using Zod schema. UUIDs are immutable and can be generated\n * randomly or created from string values.\n *\n * @example\n * // Generate a new random UUID\n * const id = UUID.generate();\n *\n * @example\n * // Create UUID from an existing string\n * const id = UUID.fromString('550e8400-e29b-41d4-a716-446655440000');\n *\n * @throws {InvalidValueObjectError} When the provided string is not a valid UUID format\n */\nexport class UUID extends PrimitiveValueObject<string> {\n private static readonly schema = z.uuid();\n\n public constructor(value: string) {\n super(value);\n this.validate(value);\n }\n\n /**\n * Creates an UUID from an external string.\n * Use only for untrusted input.\n *\n * @param value - UUID string\n */\n public static fromString(value: string): UUID {\n return new this(value);\n }\n\n /**\n * Generates a new AggregateId.\n */\n public static generate<T extends typeof UUID>(this: T): InstanceType<T> {\n return new this(v4()) as InstanceType<T>;\n }\n\n protected validate(value: string): void {\n const result = UUID.schema.safeParse(value);\n\n if (!result.success) {\n throw new InvalidValueObjectError(\n `Invalid UUID: ${result.error.message}`,\n );\n }\n }\n}\n","import { UUID } from './id.vo';\n\n/**\n * AggregateId represents a strongly-typed aggregate identifier.\n *\n * - Backed by UUID v4\n * - Immutable\n * - Comparable only to AggregateId\n */\nexport class AggregateId extends UUID {}\n","/**\n * HTTP status code catalog.\n *\n * This object provides a typed, immutable map of standard HTTP status names\n * to their numeric codes. Designed for server-side frameworks such as Fastify.\n *\n * - All identifiers use clear, canonical semantic names.\n * - Values are numeric status codes.\n * - Frozen to prevent runtime mutation.\n * - Exporting `HttpStatus` ensures type-safe usage across the codebase.\n * Usage:\n * ```ts\n * import { HttpStatus } from 'path-to-this-file';\n *\n * function handleRequest() {\n * return {\n * statusCode: HttpStatus.OK,\n * body: 'Success',\n * };\n * }\n * ```\n */\nexport const HttpStatus = Object.freeze({\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\n NETWORK_AUTHENTICATION_REQUIRED: 511,\n NON_AUTHORITATIVE_INFORMATION: 203,\n PROXY_AUTHENTICATION_REQUIRED: 407,\n\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\n HTTP_VERSION_NOT_SUPPORTED: 505,\n BANDWIDTH_LIMIT_EXCEEDED: 509,\n VARIANT_ALSO_NEGOTIATES: 506,\n UNSUPPORTED_MEDIA_TYPE: 415,\n RANGE_NOT_SATISFIABLE: 416,\n PRECONDITION_REQUIRED: 428,\n INTERNAL_SERVER_ERROR: 500,\n UNPROCESSABLE_ENTITY: 422,\n INSUFFICIENT_STORAGE: 507,\n\n SWITCHING_PROTOCOLS: 101,\n PRECONDITION_FAILED: 412,\n MISDIRECTED_REQUEST: 421,\n SERVICE_UNAVAILABLE: 503,\n TEMPORARY_REDIRECT: 307,\n PERMANENT_REDIRECT: 308,\n METHOD_NOT_ALLOWED: 405,\n EXPECTATION_FAILED: 417,\n\n MOVED_PERMANENTLY: 301,\n PAYLOAD_TOO_LARGE: 413,\n FAILED_DEPENDENCY: 424,\n TOO_MANY_REQUESTS: 429,\n ALREADY_REPORTED: 208,\n MULTIPLE_CHOICES: 300,\n PAYMENT_REQUIRED: 402,\n UPGRADE_REQUIRED: 426,\n PARTIAL_CONTENT: 206,\n REQUEST_TIMEOUT: 408,\n LENGTH_REQUIRED: 411,\n NOT_IMPLEMENTED: 501,\n GATEWAY_TIMEOUT: 504,\n NOT_ACCEPTABLE: 406,\n RESET_CONTENT: 205,\n LOOP_DETECTED: 508,\n MULTI_STATUS: 207,\n NOT_MODIFIED: 304,\n UNAUTHORIZED: 401,\n URI_TOO_LONG: 414,\n NOT_EXTENDED: 510,\n EARLY_HINTS: 103,\n BAD_REQUEST: 400,\n IM_A_TEAPOT: 418,\n BAD_GATEWAY: 502,\n PROCESSING: 102,\n NO_CONTENT: 204,\n SEE_OTHER: 303,\n USE_PROXY: 305,\n\n FORBIDDEN: 403,\n NOT_FOUND: 404,\n TOO_EARLY: 425,\n CONTINUE: 100,\n ACCEPTED: 202,\n CONFLICT: 409,\n CREATED: 201,\n IM_USED: 226,\n LOCKED: 423,\n FOUND: 302,\n GONE: 410,\n OK: 200,\n} as const);\n\n/**\n * HTTP status messages mapped by numeric code.\n * Use for sending descriptive text in responses or logging.\n */\nexport const HttpStatusMessage = {\n 431: 'Request Header Fields Too Large',\n 511: 'Network Authentication Required',\n 203: 'Non-Authoritative Information',\n 407: 'Proxy Authentication Required',\n 451: 'Unavailable For Legal Reasons',\n 505: 'HTTP Version Not Supported',\n 509: 'Bandwidth Limit Exceeded',\n 506: 'Variant Also Negotiates',\n 415: 'Unsupported Media Type',\n 416: 'Range Not Satisfiable',\n 428: 'Precondition Required',\n 500: 'Internal Server Error',\n 422: 'Unprocessable Entity',\n 507: 'Insufficient Storage',\n 101: 'Switching Protocols',\n 412: 'Precondition Failed',\n 421: 'Misdirected Request',\n 503: 'Service Unavailable',\n 307: 'Temporary Redirect',\n 308: 'Permanent Redirect',\n 405: 'Method Not Allowed',\n 417: 'Expectation Failed',\n 301: 'Moved Permanently',\n 413: 'Payload Too Large',\n 424: 'Failed Dependency',\n 429: 'Too Many Requests',\n 208: 'Already Reported',\n 300: 'Multiple Choices',\n 402: 'Payment Required',\n 426: 'Upgrade Required',\n 206: 'Partial Content',\n 408: 'Request Timeout',\n 411: 'Length Required',\n 501: 'Not Implemented',\n 504: 'Gateway Timeout',\n 406: 'Not Acceptable',\n 205: 'Reset Content',\n 508: 'Loop Detected',\n 207: 'Multi-Status',\n 304: 'Not Modified',\n 401: 'Unauthorized',\n 414: 'URI Too Long',\n 418: \"I'm a Teapot\",\n 510: 'Not Extended',\n 103: 'Early Hints',\n 400: 'Bad Request',\n 502: 'Bad Gateway',\n 102: 'Processing',\n 204: 'No Content',\n 303: 'See Other',\n 305: 'Use Proxy',\n 403: 'Forbidden',\n 404: 'Not Found',\n 425: 'Too Early',\n 100: 'Continue',\n 202: 'Accepted',\n 226: \"I'm Used\",\n 409: 'Conflict',\n 201: 'Created',\n 423: 'Locked',\n 302: 'Found',\n 410: 'Gone',\n 200: 'OK',\n} as const;\n\nexport type HttpStatusCode = keyof typeof HttpStatusMessage;\n\nexport type HttpStatusMessage =\n (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];\n","import {\n HttpStatusCode,\n HttpStatusMessage,\n} from '@/gateway/constants/http-code';\n\ninterface ErrorParams {\n message: string;\n code: HttpStatusMessage;\n status?: HttpStatusCode;\n metadata?: Record<string, unknown> | undefined;\n isOperational?: boolean;\n cause?: Error | undefined;\n}\n\n/**\n * Abstract base class for application-level errors with structured error handling.\n *\n * Extends the native Error class to provide machine-readable error codes, HTTP status codes,\n * operational error classification, and optional metadata for better error tracking and client communication.\n *\n * @abstract\n * @extends {Error}\n *\n * @example\n * ```typescript\n * class UserNotFoundError extends ApplicationError {\n * constructor(userId: string) {\n * super({\n * code: HttpStatusMessage['404'],\n * status: 404,\n * isOperational: true,\n * message: `User with id ${userId} not found`,\n * metadata: { userId }\n * });\n * }\n * }\n * ```\n */\nexport abstract class ApplicationError extends Error {\n /** Optional cause (linked error) */\n public readonly cause?: Error | undefined;\n /** Machine-readable error code (e.g. `OTP_LOCKED`, `USER_NOT_FOUND`) */\n public readonly code: HttpStatusMessage;\n /** Operational vs programmer error flag */\n public readonly isOperational: boolean;\n /** Optional structured metadata for debugging or clients */\n public readonly metadata?: Record<string, unknown> | undefined;\n /** HTTP status code intended for response layer */\n public readonly status: HttpStatusCode;\n\n constructor({\n code = HttpStatusMessage['500'],\n isOperational = false,\n status = 500,\n metadata,\n message,\n cause,\n }: ErrorParams) {\n super(message);\n\n this.name = new.target.name;\n this.code = code;\n this.status = status;\n this.isOperational = isOperational;\n this.metadata = metadata;\n this.cause = cause;\n\n Error.captureStackTrace(this, new.target);\n }\n}\n","import { ValueObject } from '@/domain/base/vo';\n\nexport type UnwrapValueObject<T> =\n T extends ValueObject<infer V>\n ? UnwrapValueObject<V>\n : T extends (infer U)[]\n ? UnwrapValueObject<U>[]\n : T extends Map<infer K, infer V>\n ? Map<K, UnwrapValueObject<V>>\n : T extends Set<infer V>\n ? Set<UnwrapValueObject<V>>\n : T extends Date\n ? string\n : T extends object\n ? { [K in keyof T]: UnwrapValueObject<T[K]> }\n : T;\n\nexport function unwrapValueObject<T>(\n input: T,\n seen = new WeakSet(),\n): UnwrapValueObject<T> {\n if (input === null || input === undefined) {\n return input as UnwrapValueObject<T>;\n }\n\n if (typeof input !== 'object') {\n return input as UnwrapValueObject<T>;\n }\n\n if (seen.has(input)) {\n // Prevent circular reference infinite recursion, just return input or throw\n throw new Error('Circular reference detected in ValueObject unwrap');\n }\n\n seen.add(input);\n\n if (Array.isArray(input)) {\n const result = input.map(item => unwrapValueObject(item, seen));\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof ValueObject) {\n const result = unwrapValueObject(input.value, seen);\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Date) {\n seen.delete(input);\n return input.toISOString() as UnwrapValueObject<T>;\n }\n\n if (input instanceof Map) {\n const result = new Map();\n input.forEach((value, key) => {\n result.set(key, unwrapValueObject(value, seen));\n });\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n if (input instanceof Set) {\n const result = new Set(\n Array.from(input.values()).map(v => unwrapValueObject(v, seen)),\n );\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n }\n\n // generic object\n const result: Record<string, unknown> = {};\n\n for (const key in input) {\n if (Object.hasOwn(input, key)) {\n result[key] = unwrapValueObject((input as any)[key], seen);\n }\n }\n\n seen.delete(input);\n return result as UnwrapValueObject<T>;\n}\n\nexport function ensureObject<T>(input: UnwrapValueObject<T>): object {\n if (input === null || input === undefined) {\n return {};\n }\n if (typeof input === 'object') {\n return input;\n }\n\n // for primitives, wrap inside object with default key (or throw)\n return { value: input };\n}\n"],"mappings":"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","names":["Entity","props","_a","other","AggregateRoot","Entity","domainEvent","events","getCauseInfo","cause","DomainError","message","code","metadata","__spreadValues","PrimitiveValueObject","value","other","deepEqual","deepFreeze","obj","seen","item","key","ValueObject","_ValueObject","props","deepFreeze","vo","other","deepEqual","EntityValidationError","DomainError","message","cause","InvalidValueObjectError","DomainError","message","randomUUID","DomainEvent","props","_a","v4","z","_UUID","PrimitiveValueObject","value","v4","result","InvalidValueObjectError","z","UUID","AggregateId","UUID","HttpStatus","HttpStatusMessage","ApplicationError","code","HttpStatusMessage","isOperational","status","metadata","message","cause","unwrapValueObject","input","seen","result","item","ValueObject","value","key","v","ensureObject"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rineex/ddd",
3
- "version": "1.6.1",
3
+ "version": "2.0.0",
4
4
  "description": "Domain Driven Design package for Rineex core modules",
5
5
  "author": "Rineex Team",
6
6
  "main": "./dist/index.js",