@rineex/ddd 2.0.0 → 2.1.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/dist/index.d.mts CHANGED
@@ -197,7 +197,7 @@ interface DomainErrorMetadata {
197
197
  * }
198
198
  * }
199
199
  */
200
- declare abstract class DomainError extends Error {
200
+ declare abstract class DomainError$1 extends Error {
201
201
  /** Stable, machine-readable error code */
202
202
  readonly code: string;
203
203
  /** Structured, immutable domain metadata */
@@ -310,11 +310,11 @@ declare abstract class ValueObject<T> {
310
310
  /**
311
311
  * Custom error class for entity validation failures.
312
312
  */
313
- declare class EntityValidationError extends DomainError {
313
+ declare class EntityValidationError extends DomainError$1 {
314
314
  constructor(message: string, cause?: Error);
315
315
  }
316
316
 
317
- declare class InvalidValueObjectError extends DomainError {
317
+ declare class InvalidValueObjectError extends DomainError$1 {
318
318
  constructor(message: string);
319
319
  }
320
320
 
@@ -521,6 +521,362 @@ declare const HttpStatusMessage: {
521
521
  };
522
522
  type HttpStatusMessage = (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];
523
523
 
524
+ /**
525
+ * Strongly-typed domain error used in Result failures.
526
+ * Does NOT extend native Error on purpose — infrastructure maps to transport later.
527
+ */
528
+ declare abstract class DomainError {
529
+ abstract readonly code: DomainErrorCode;
530
+ readonly message: string;
531
+ readonly metadata: Readonly<Record<string, boolean | number | string>>;
532
+ protected constructor(params: {
533
+ message: string;
534
+ metadata?: Record<string, boolean | number | string>;
535
+ });
536
+ }
537
+ type DomainErrorCode = 'DOMAIN.INVALID_STATE' | 'DOMAIN.INVALID_VALUE';
538
+
539
+ /**
540
+ * Represents the result of an operation, which can be either a success or a failure.
541
+ *
542
+ * This is a functional programming pattern that helps avoid throwing exceptions
543
+ * and makes error handling explicit in the type system. It's commonly used in
544
+ * Domain-Driven Design (DDD) to represent domain operation outcomes.
545
+ *
546
+ * @template T The type of a successful result.
547
+ * @template E The type of the error in case of failure (defaults to DomainError).
548
+ *
549
+ * @example
550
+ * ```typescript
551
+ * // Creating a successful result
552
+ * const success = Result.ok({ id: 1, name: 'John' });
553
+ * if (success.isSuccess) {
554
+ * const user = success.getValue(); // { id: 1, name: 'John' }
555
+ * }
556
+ *
557
+ * // Creating a failed result
558
+ * const failure = Result.fail(new InvalidUserError('User not found'));
559
+ * if (failure.isFailure) {
560
+ * const error = failure.getError(); // InvalidUserError instance
561
+ * }
562
+ * ```
563
+ *
564
+ * @example
565
+ * ```typescript
566
+ * // Using in a domain service
567
+ * function createUser(name: string): Result<User, DomainError> {
568
+ * if (!name || name.trim().length === 0) {
569
+ * return Result.fail(new InvalidValueError('Name cannot be empty'));
570
+ * }
571
+ *
572
+ * const user = new User(name);
573
+ * return Result.ok(user);
574
+ * }
575
+ *
576
+ * const result = createUser('John Doe');
577
+ * if (result.isSuccess) {
578
+ * console.log('User created:', result.getValue());
579
+ * } else {
580
+ * console.error('Failed:', result.getError()?.message);
581
+ * }
582
+ * ```
583
+ *
584
+ * @example
585
+ * ```typescript
586
+ * // Chaining operations
587
+ * function validateEmail(email: string): Result<string, DomainError> {
588
+ * if (!email.includes('@')) {
589
+ * return Result.fail(new InvalidValueError('Invalid email format'));
590
+ * }
591
+ * return Result.ok(email);
592
+ * }
593
+ *
594
+ * function createAccount(email: string): Result<Account, DomainError> {
595
+ * const emailResult = validateEmail(email);
596
+ * if (emailResult.isFailure) {
597
+ * return emailResult; // Forward the error
598
+ * }
599
+ *
600
+ * const account = new Account(emailResult.getValue()!);
601
+ * return Result.ok(account);
602
+ * }
603
+ * ```
604
+ *
605
+ * @example
606
+ * ```typescript
607
+ * // Working with async operations
608
+ * async function fetchUser(id: number): Promise<Result<User, DomainError>> {
609
+ * try {
610
+ * const user = await userRepository.findById(id);
611
+ * if (!user) {
612
+ * return Result.fail(new NotFoundError(`User ${id} not found`));
613
+ * }
614
+ * return Result.ok(user);
615
+ * } catch (error) {
616
+ * return Result.fail(new SystemError('Database connection failed'));
617
+ * }
618
+ * }
619
+ *
620
+ * const result = await fetchUser(123);
621
+ * if (result.isSuccess) {
622
+ * // Handle success
623
+ * } else {
624
+ * // Handle failure
625
+ * }
626
+ * ```
627
+ */
628
+ declare class Result<T, E> {
629
+ /**
630
+ * Indicates if the result is a failure.
631
+ *
632
+ * @example
633
+ * ```typescript
634
+ * const result = Result.fail(new Error('Something went wrong'));
635
+ * if (result.isFailure) {
636
+ * // Handle error case
637
+ * console.error(result.getError());
638
+ * }
639
+ * ```
640
+ */
641
+ readonly isFailure: boolean;
642
+ /**
643
+ * Indicates if the result is a success.
644
+ *
645
+ * @example
646
+ * ```typescript
647
+ * const result = Result.ok(42);
648
+ * if (result.isSuccess) {
649
+ * // Handle success case
650
+ * const value = result.getValue(); // 42
651
+ * }
652
+ * ```
653
+ */
654
+ readonly isSuccess: boolean;
655
+ /**
656
+ * The error, if any.
657
+ * @private
658
+ */
659
+ private readonly _error?;
660
+ /**
661
+ * The value, if any.
662
+ * @private
663
+ */
664
+ private readonly _value?;
665
+ /**
666
+ * Private constructor to enforce the use of static methods.
667
+ * @param params.value The value on success.
668
+ * @param params.error The error on failure.
669
+ * @private
670
+ */
671
+ private constructor();
672
+ /**
673
+ * Creates a failed result.
674
+ *
675
+ * @template T The type of a successful result (never for failure).
676
+ * @template E The type of the error (defaults to DomainError).
677
+ * @param error The error object.
678
+ * @returns {Result<T, E>} A failed Result instance.
679
+ *
680
+ * @example
681
+ * ```typescript
682
+ * // With DomainError
683
+ * class InvalidValueError extends DomainError {
684
+ * public readonly code = 'DOMAIN.INVALID_VALUE' as const;
685
+ * constructor(message: string) {
686
+ * super({ message });
687
+ * }
688
+ * }
689
+ *
690
+ * const result = Result.fail(new InvalidValueError('Value must be positive'));
691
+ * // result.isFailure === true
692
+ * // result.getError() === InvalidValueError instance
693
+ * ```
694
+ *
695
+ * @example
696
+ * ```typescript
697
+ * // With custom error type
698
+ * interface ValidationError {
699
+ * field: string;
700
+ * message: string;
701
+ * }
702
+ *
703
+ * const result = Result.fail<never, ValidationError>({
704
+ * field: 'email',
705
+ * message: 'Invalid email format'
706
+ * });
707
+ * ```
708
+ *
709
+ * @example
710
+ * ```typescript
711
+ * // In a validation function
712
+ * function validateAge(age: number): Result<number, DomainError> {
713
+ * if (age < 0) {
714
+ * return Result.fail(new InvalidValueError('Age cannot be negative'));
715
+ * }
716
+ * if (age > 150) {
717
+ * return Result.fail(new InvalidValueError('Age seems unrealistic'));
718
+ * }
719
+ * return Result.ok(age);
720
+ * }
721
+ * ```
722
+ */
723
+ static fail<T = never, E = DomainError>(error: E): Result<T, E>;
724
+ /**
725
+ * Creates a successful result.
726
+ *
727
+ * @template T The type of the successful result.
728
+ * @template E The type of the error (never for success).
729
+ * @param value The success value.
730
+ * @returns {Result<T, E>} A successful Result instance.
731
+ *
732
+ * @example
733
+ * ```typescript
734
+ * // With primitive value
735
+ * const result = Result.ok(42);
736
+ * // result.isSuccess === true
737
+ * // result.getValue() === 42
738
+ * ```
739
+ *
740
+ * @example
741
+ * ```typescript
742
+ * // With object
743
+ * const user = { id: 1, name: 'John', email: 'john@example.com' };
744
+ * const result = Result.ok(user);
745
+ * if (result.isSuccess) {
746
+ * const savedUser = result.getValue(); // { id: 1, name: 'John', ... }
747
+ * }
748
+ * ```
749
+ *
750
+ * @example
751
+ * ```typescript
752
+ * // With domain entity
753
+ * class User {
754
+ * constructor(public readonly id: number, public readonly name: string) {}
755
+ * }
756
+ *
757
+ * function createUser(name: string): Result<User, DomainError> {
758
+ * const user = new User(Date.now(), name);
759
+ * return Result.ok(user);
760
+ * }
761
+ *
762
+ * const result = createUser('Alice');
763
+ * if (result.isSuccess) {
764
+ * console.log(`Created user: ${result.getValue()?.name}`);
765
+ * }
766
+ * ```
767
+ *
768
+ * @example
769
+ * ```typescript
770
+ * // With void/undefined (for operations that don't return a value)
771
+ * function deleteUser(id: number): Result<void, DomainError> {
772
+ * // ... deletion logic ...
773
+ * return Result.ok(undefined);
774
+ * }
775
+ *
776
+ * const result = deleteUser(123);
777
+ * if (result.isSuccess) {
778
+ * console.log('User deleted successfully');
779
+ * }
780
+ * ```
781
+ */
782
+ static ok<T, E = never>(value: T): Result<T, E>;
783
+ /**
784
+ * Returns the error if present, otherwise undefined.
785
+ *
786
+ * **Note:** Always check `isFailure` before calling this method to ensure
787
+ * the result is actually a failure. This method will return `undefined` for
788
+ * successful results.
789
+ *
790
+ * @returns {E | undefined} The error or undefined if successful.
791
+ *
792
+ * @example
793
+ * ```typescript
794
+ * const result = Result.fail(new InvalidValueError('Invalid input'));
795
+ *
796
+ * if (result.isFailure) {
797
+ * const error = result.getError();
798
+ * if (error) {
799
+ * console.error(`Error code: ${error.code}, Message: ${error.message}`);
800
+ * }
801
+ * }
802
+ * ```
803
+ *
804
+ * @example
805
+ * ```typescript
806
+ * // Safe error handling pattern
807
+ * function handleResult<T>(result: Result<T, DomainError>): void {
808
+ * if (result.isFailure) {
809
+ * const error = result.getError();
810
+ * if (error) {
811
+ * // Log error with metadata
812
+ * console.error({
813
+ * code: error.code,
814
+ * message: error.message,
815
+ * metadata: error.metadata
816
+ * });
817
+ * }
818
+ * }
819
+ * }
820
+ * ```
821
+ */
822
+ getError(): E | undefined;
823
+ /**
824
+ * Returns the value if present, otherwise undefined.
825
+ *
826
+ * **Note:** Always check `isSuccess` before calling this method to ensure
827
+ * the result is actually a success. This method will return `undefined` for
828
+ * failed results.
829
+ *
830
+ * @returns {T | undefined} The value or undefined if failed.
831
+ *
832
+ * @example
833
+ * ```typescript
834
+ * const result = Result.ok({ id: 1, name: 'John' });
835
+ *
836
+ * if (result.isSuccess) {
837
+ * const user = result.getValue();
838
+ * if (user) {
839
+ * console.log(`User: ${user.name} (ID: ${user.id})`);
840
+ * }
841
+ * }
842
+ * ```
843
+ *
844
+ * @example
845
+ * ```typescript
846
+ * // Type-safe value extraction
847
+ * function processUser(result: Result<User, DomainError>): void {
848
+ * if (result.isSuccess) {
849
+ * const user = result.getValue();
850
+ * // TypeScript knows user is User | undefined here
851
+ * if (user) {
852
+ * // Process the user
853
+ * userRepository.save(user);
854
+ * }
855
+ * }
856
+ * }
857
+ * ```
858
+ *
859
+ * @example
860
+ * ```typescript
861
+ * // Using non-null assertion (use with caution)
862
+ * const result = Result.ok(42);
863
+ * if (result.isSuccess) {
864
+ * const value = result.getValue()!; // Safe because we checked isSuccess
865
+ * console.log(value * 2); // 84
866
+ * }
867
+ * ```
868
+ */
869
+ getValue(): T | undefined;
870
+ /**
871
+ * Type guard for failure.
872
+ */
873
+ isFailureResult(): this is Result<never, E>;
874
+ /**
875
+ * Type guard for success.
876
+ */
877
+ isSuccessResult(): this is Result<T, never>;
878
+ }
879
+
524
880
  /**
525
881
  * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.
526
882
  *
@@ -582,4 +938,4 @@ type UnwrapValueObject<T> = T extends ValueObject<infer V> ? UnwrapValueObject<V
582
938
  declare function unwrapValueObject<T>(input: T, seen?: WeakSet<object>): UnwrapValueObject<T>;
583
939
  declare function ensureObject<T>(input: UnwrapValueObject<T>): object;
584
940
 
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 };
941
+ export { AggregateId, AggregateRoot, ApplicationError, type ApplicationServicePort, DomainError$1 as DomainError, type DomainErrorMetadata, DomainEvent, type DomainEventPayload, Entity, type EntityId, type EntityProps, EntityValidationError, HttpStatus, type HttpStatusCode, HttpStatusMessage, InvalidValueObjectError, PrimitiveValueObject, type Props, Result, UUID, type UnixTimestampMillis, type UnwrapValueObject, ValueObject, deepFreeze, ensureObject, unwrapValueObject };
package/dist/index.d.ts CHANGED
@@ -197,7 +197,7 @@ interface DomainErrorMetadata {
197
197
  * }
198
198
  * }
199
199
  */
200
- declare abstract class DomainError extends Error {
200
+ declare abstract class DomainError$1 extends Error {
201
201
  /** Stable, machine-readable error code */
202
202
  readonly code: string;
203
203
  /** Structured, immutable domain metadata */
@@ -310,11 +310,11 @@ declare abstract class ValueObject<T> {
310
310
  /**
311
311
  * Custom error class for entity validation failures.
312
312
  */
313
- declare class EntityValidationError extends DomainError {
313
+ declare class EntityValidationError extends DomainError$1 {
314
314
  constructor(message: string, cause?: Error);
315
315
  }
316
316
 
317
- declare class InvalidValueObjectError extends DomainError {
317
+ declare class InvalidValueObjectError extends DomainError$1 {
318
318
  constructor(message: string);
319
319
  }
320
320
 
@@ -521,6 +521,362 @@ declare const HttpStatusMessage: {
521
521
  };
522
522
  type HttpStatusMessage = (typeof HttpStatusMessage)[keyof typeof HttpStatusMessage];
523
523
 
524
+ /**
525
+ * Strongly-typed domain error used in Result failures.
526
+ * Does NOT extend native Error on purpose — infrastructure maps to transport later.
527
+ */
528
+ declare abstract class DomainError {
529
+ abstract readonly code: DomainErrorCode;
530
+ readonly message: string;
531
+ readonly metadata: Readonly<Record<string, boolean | number | string>>;
532
+ protected constructor(params: {
533
+ message: string;
534
+ metadata?: Record<string, boolean | number | string>;
535
+ });
536
+ }
537
+ type DomainErrorCode = 'DOMAIN.INVALID_STATE' | 'DOMAIN.INVALID_VALUE';
538
+
539
+ /**
540
+ * Represents the result of an operation, which can be either a success or a failure.
541
+ *
542
+ * This is a functional programming pattern that helps avoid throwing exceptions
543
+ * and makes error handling explicit in the type system. It's commonly used in
544
+ * Domain-Driven Design (DDD) to represent domain operation outcomes.
545
+ *
546
+ * @template T The type of a successful result.
547
+ * @template E The type of the error in case of failure (defaults to DomainError).
548
+ *
549
+ * @example
550
+ * ```typescript
551
+ * // Creating a successful result
552
+ * const success = Result.ok({ id: 1, name: 'John' });
553
+ * if (success.isSuccess) {
554
+ * const user = success.getValue(); // { id: 1, name: 'John' }
555
+ * }
556
+ *
557
+ * // Creating a failed result
558
+ * const failure = Result.fail(new InvalidUserError('User not found'));
559
+ * if (failure.isFailure) {
560
+ * const error = failure.getError(); // InvalidUserError instance
561
+ * }
562
+ * ```
563
+ *
564
+ * @example
565
+ * ```typescript
566
+ * // Using in a domain service
567
+ * function createUser(name: string): Result<User, DomainError> {
568
+ * if (!name || name.trim().length === 0) {
569
+ * return Result.fail(new InvalidValueError('Name cannot be empty'));
570
+ * }
571
+ *
572
+ * const user = new User(name);
573
+ * return Result.ok(user);
574
+ * }
575
+ *
576
+ * const result = createUser('John Doe');
577
+ * if (result.isSuccess) {
578
+ * console.log('User created:', result.getValue());
579
+ * } else {
580
+ * console.error('Failed:', result.getError()?.message);
581
+ * }
582
+ * ```
583
+ *
584
+ * @example
585
+ * ```typescript
586
+ * // Chaining operations
587
+ * function validateEmail(email: string): Result<string, DomainError> {
588
+ * if (!email.includes('@')) {
589
+ * return Result.fail(new InvalidValueError('Invalid email format'));
590
+ * }
591
+ * return Result.ok(email);
592
+ * }
593
+ *
594
+ * function createAccount(email: string): Result<Account, DomainError> {
595
+ * const emailResult = validateEmail(email);
596
+ * if (emailResult.isFailure) {
597
+ * return emailResult; // Forward the error
598
+ * }
599
+ *
600
+ * const account = new Account(emailResult.getValue()!);
601
+ * return Result.ok(account);
602
+ * }
603
+ * ```
604
+ *
605
+ * @example
606
+ * ```typescript
607
+ * // Working with async operations
608
+ * async function fetchUser(id: number): Promise<Result<User, DomainError>> {
609
+ * try {
610
+ * const user = await userRepository.findById(id);
611
+ * if (!user) {
612
+ * return Result.fail(new NotFoundError(`User ${id} not found`));
613
+ * }
614
+ * return Result.ok(user);
615
+ * } catch (error) {
616
+ * return Result.fail(new SystemError('Database connection failed'));
617
+ * }
618
+ * }
619
+ *
620
+ * const result = await fetchUser(123);
621
+ * if (result.isSuccess) {
622
+ * // Handle success
623
+ * } else {
624
+ * // Handle failure
625
+ * }
626
+ * ```
627
+ */
628
+ declare class Result<T, E> {
629
+ /**
630
+ * Indicates if the result is a failure.
631
+ *
632
+ * @example
633
+ * ```typescript
634
+ * const result = Result.fail(new Error('Something went wrong'));
635
+ * if (result.isFailure) {
636
+ * // Handle error case
637
+ * console.error(result.getError());
638
+ * }
639
+ * ```
640
+ */
641
+ readonly isFailure: boolean;
642
+ /**
643
+ * Indicates if the result is a success.
644
+ *
645
+ * @example
646
+ * ```typescript
647
+ * const result = Result.ok(42);
648
+ * if (result.isSuccess) {
649
+ * // Handle success case
650
+ * const value = result.getValue(); // 42
651
+ * }
652
+ * ```
653
+ */
654
+ readonly isSuccess: boolean;
655
+ /**
656
+ * The error, if any.
657
+ * @private
658
+ */
659
+ private readonly _error?;
660
+ /**
661
+ * The value, if any.
662
+ * @private
663
+ */
664
+ private readonly _value?;
665
+ /**
666
+ * Private constructor to enforce the use of static methods.
667
+ * @param params.value The value on success.
668
+ * @param params.error The error on failure.
669
+ * @private
670
+ */
671
+ private constructor();
672
+ /**
673
+ * Creates a failed result.
674
+ *
675
+ * @template T The type of a successful result (never for failure).
676
+ * @template E The type of the error (defaults to DomainError).
677
+ * @param error The error object.
678
+ * @returns {Result<T, E>} A failed Result instance.
679
+ *
680
+ * @example
681
+ * ```typescript
682
+ * // With DomainError
683
+ * class InvalidValueError extends DomainError {
684
+ * public readonly code = 'DOMAIN.INVALID_VALUE' as const;
685
+ * constructor(message: string) {
686
+ * super({ message });
687
+ * }
688
+ * }
689
+ *
690
+ * const result = Result.fail(new InvalidValueError('Value must be positive'));
691
+ * // result.isFailure === true
692
+ * // result.getError() === InvalidValueError instance
693
+ * ```
694
+ *
695
+ * @example
696
+ * ```typescript
697
+ * // With custom error type
698
+ * interface ValidationError {
699
+ * field: string;
700
+ * message: string;
701
+ * }
702
+ *
703
+ * const result = Result.fail<never, ValidationError>({
704
+ * field: 'email',
705
+ * message: 'Invalid email format'
706
+ * });
707
+ * ```
708
+ *
709
+ * @example
710
+ * ```typescript
711
+ * // In a validation function
712
+ * function validateAge(age: number): Result<number, DomainError> {
713
+ * if (age < 0) {
714
+ * return Result.fail(new InvalidValueError('Age cannot be negative'));
715
+ * }
716
+ * if (age > 150) {
717
+ * return Result.fail(new InvalidValueError('Age seems unrealistic'));
718
+ * }
719
+ * return Result.ok(age);
720
+ * }
721
+ * ```
722
+ */
723
+ static fail<T = never, E = DomainError>(error: E): Result<T, E>;
724
+ /**
725
+ * Creates a successful result.
726
+ *
727
+ * @template T The type of the successful result.
728
+ * @template E The type of the error (never for success).
729
+ * @param value The success value.
730
+ * @returns {Result<T, E>} A successful Result instance.
731
+ *
732
+ * @example
733
+ * ```typescript
734
+ * // With primitive value
735
+ * const result = Result.ok(42);
736
+ * // result.isSuccess === true
737
+ * // result.getValue() === 42
738
+ * ```
739
+ *
740
+ * @example
741
+ * ```typescript
742
+ * // With object
743
+ * const user = { id: 1, name: 'John', email: 'john@example.com' };
744
+ * const result = Result.ok(user);
745
+ * if (result.isSuccess) {
746
+ * const savedUser = result.getValue(); // { id: 1, name: 'John', ... }
747
+ * }
748
+ * ```
749
+ *
750
+ * @example
751
+ * ```typescript
752
+ * // With domain entity
753
+ * class User {
754
+ * constructor(public readonly id: number, public readonly name: string) {}
755
+ * }
756
+ *
757
+ * function createUser(name: string): Result<User, DomainError> {
758
+ * const user = new User(Date.now(), name);
759
+ * return Result.ok(user);
760
+ * }
761
+ *
762
+ * const result = createUser('Alice');
763
+ * if (result.isSuccess) {
764
+ * console.log(`Created user: ${result.getValue()?.name}`);
765
+ * }
766
+ * ```
767
+ *
768
+ * @example
769
+ * ```typescript
770
+ * // With void/undefined (for operations that don't return a value)
771
+ * function deleteUser(id: number): Result<void, DomainError> {
772
+ * // ... deletion logic ...
773
+ * return Result.ok(undefined);
774
+ * }
775
+ *
776
+ * const result = deleteUser(123);
777
+ * if (result.isSuccess) {
778
+ * console.log('User deleted successfully');
779
+ * }
780
+ * ```
781
+ */
782
+ static ok<T, E = never>(value: T): Result<T, E>;
783
+ /**
784
+ * Returns the error if present, otherwise undefined.
785
+ *
786
+ * **Note:** Always check `isFailure` before calling this method to ensure
787
+ * the result is actually a failure. This method will return `undefined` for
788
+ * successful results.
789
+ *
790
+ * @returns {E | undefined} The error or undefined if successful.
791
+ *
792
+ * @example
793
+ * ```typescript
794
+ * const result = Result.fail(new InvalidValueError('Invalid input'));
795
+ *
796
+ * if (result.isFailure) {
797
+ * const error = result.getError();
798
+ * if (error) {
799
+ * console.error(`Error code: ${error.code}, Message: ${error.message}`);
800
+ * }
801
+ * }
802
+ * ```
803
+ *
804
+ * @example
805
+ * ```typescript
806
+ * // Safe error handling pattern
807
+ * function handleResult<T>(result: Result<T, DomainError>): void {
808
+ * if (result.isFailure) {
809
+ * const error = result.getError();
810
+ * if (error) {
811
+ * // Log error with metadata
812
+ * console.error({
813
+ * code: error.code,
814
+ * message: error.message,
815
+ * metadata: error.metadata
816
+ * });
817
+ * }
818
+ * }
819
+ * }
820
+ * ```
821
+ */
822
+ getError(): E | undefined;
823
+ /**
824
+ * Returns the value if present, otherwise undefined.
825
+ *
826
+ * **Note:** Always check `isSuccess` before calling this method to ensure
827
+ * the result is actually a success. This method will return `undefined` for
828
+ * failed results.
829
+ *
830
+ * @returns {T | undefined} The value or undefined if failed.
831
+ *
832
+ * @example
833
+ * ```typescript
834
+ * const result = Result.ok({ id: 1, name: 'John' });
835
+ *
836
+ * if (result.isSuccess) {
837
+ * const user = result.getValue();
838
+ * if (user) {
839
+ * console.log(`User: ${user.name} (ID: ${user.id})`);
840
+ * }
841
+ * }
842
+ * ```
843
+ *
844
+ * @example
845
+ * ```typescript
846
+ * // Type-safe value extraction
847
+ * function processUser(result: Result<User, DomainError>): void {
848
+ * if (result.isSuccess) {
849
+ * const user = result.getValue();
850
+ * // TypeScript knows user is User | undefined here
851
+ * if (user) {
852
+ * // Process the user
853
+ * userRepository.save(user);
854
+ * }
855
+ * }
856
+ * }
857
+ * ```
858
+ *
859
+ * @example
860
+ * ```typescript
861
+ * // Using non-null assertion (use with caution)
862
+ * const result = Result.ok(42);
863
+ * if (result.isSuccess) {
864
+ * const value = result.getValue()!; // Safe because we checked isSuccess
865
+ * console.log(value * 2); // 84
866
+ * }
867
+ * ```
868
+ */
869
+ getValue(): T | undefined;
870
+ /**
871
+ * Type guard for failure.
872
+ */
873
+ isFailureResult(): this is Result<never, E>;
874
+ /**
875
+ * Type guard for success.
876
+ */
877
+ isSuccessResult(): this is Result<T, never>;
878
+ }
879
+
524
880
  /**
525
881
  * Utility to deeply freeze objects to ensure immutability - handles nested objects and arrays.
526
882
  *
@@ -582,4 +938,4 @@ type UnwrapValueObject<T> = T extends ValueObject<infer V> ? UnwrapValueObject<V
582
938
  declare function unwrapValueObject<T>(input: T, seen?: WeakSet<object>): UnwrapValueObject<T>;
583
939
  declare function ensureObject<T>(input: UnwrapValueObject<T>): object;
584
940
 
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 };
941
+ export { AggregateId, AggregateRoot, ApplicationError, type ApplicationServicePort, DomainError$1 as DomainError, type DomainErrorMetadata, DomainEvent, type DomainEventPayload, Entity, type EntityId, type EntityProps, EntityValidationError, HttpStatus, type HttpStatusCode, HttpStatusMessage, InvalidValueObjectError, PrimitiveValueObject, type Props, Result, UUID, type UnixTimestampMillis, type UnwrapValueObject, ValueObject, deepFreeze, ensureObject, unwrapValueObject };
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
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});
1
+ var V=Object.create;var s=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames,D=Object.getOwnPropertySymbols,C=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty,j=Object.prototype.propertyIsEnumerable;var N=(t,e,r)=>e in t?s(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,O=(t,e)=>{for(var r in e||(e={}))_.call(e,r)&&N(t,r,e[r]);if(D)for(var r of D(e))j.call(e,r)&&N(t,r,e[r]);return t};var F=(t,e)=>{for(var r in e)s(t,r,{get:e[r],enumerable:!0})},h=(t,e,r,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of M(e))!_.call(t,n)&&n!==r&&s(t,n,{get:()=>e[n],enumerable:!(a=L(e,n))||a.enumerable});return t};var v=(t,e,r)=>(r=t!=null?V(C(t)):{},h(e||!t||!t.__esModule?s(r,"default",{value:t,enumerable:!0}):r,t)),H=t=>h(s({},"__esModule",{value:!0}),t);var Y={};F(Y,{AggregateId:()=>b,AggregateRoot:()=>y,ApplicationError:()=>A,DomainError:()=>o,DomainEvent:()=>g,Entity:()=>d,EntityValidationError:()=>I,HttpStatus:()=>G,HttpStatusMessage:()=>R,InvalidValueObjectError:()=>E,PrimitiveValueObject:()=>l,Result:()=>m,UUID:()=>p,ValueObject:()=>u,deepFreeze:()=>c,ensureObject:()=>q,unwrapValueObject:()=>i});module.exports=H(Y);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 y=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 k=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,O({},k(a.cause))),Object.setPrototypeOf(this,new.target.prototype),this.name=new.target.name,this.code=r,this.metadata=Object.freeze(O({},a))}};var l=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 S=v(require("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 u=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:(0,S.default)(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 E=class extends o{constructor(e){super(e,"INVALID_VALUE_OBJECT")}};var P=require("crypto"),g=class{constructor(e){var r;this.id=(r=e.id)!=null?r:(0,P.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 U=require("uuid"),x=v(require("zod"));var T=class T extends l{constructor(e){super(e),this.validate(e)}static fromString(e){return new this(e)}static generate(){return new this((0,U.v4)())}validate(e){let r=T.schema.safeParse(e);if(!r.success)throw new E(`Invalid UUID: ${r.error.message}`)}};T.schema=x.default.uuid();var p=T;var b=class extends p{};var G=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 m=class t{constructor(e){let r=e.error!==void 0;this.isFailure=r,this.isSuccess=!r,this._value=e.value,this._error=e.error,Object.freeze(this)}static fail(e){return new t({error:e})}static ok(e){return new t({value:e})}getError(){return this._error}getValue(){return this._value}isFailureResult(){return this.isFailure}isSuccessResult(){return this.isSuccess}};var A=class extends Error{constructor({code:e=R[500],isOperational:r=!1,status:a=500,metadata:n,message:f,cause:w}){super(f),this.name=new.target.name,this.code=e,this.status=a,this.isOperational=r,this.metadata=n,this.cause=w,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 u){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,f)=>{a.set(f,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 q(t){return t==null?{}:typeof t=="object"?t:{value:t}}0&&(module.exports={AggregateId,AggregateRoot,ApplicationError,DomainError,DomainEvent,Entity,EntityValidationError,HttpStatus,HttpStatusMessage,InvalidValueObjectError,PrimitiveValueObject,Result,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/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":"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","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"]}
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/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 { Result } from './shared/domain/result';\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 { DomainError } from './domain.error';\n\n/**\n * Represents the result of an operation, which can be either a success or a failure.\n *\n * This is a functional programming pattern that helps avoid throwing exceptions\n * and makes error handling explicit in the type system. It's commonly used in\n * Domain-Driven Design (DDD) to represent domain operation outcomes.\n *\n * @template T The type of a successful result.\n * @template E The type of the error in case of failure (defaults to DomainError).\n *\n * @example\n * ```typescript\n * // Creating a successful result\n * const success = Result.ok({ id: 1, name: 'John' });\n * if (success.isSuccess) {\n * const user = success.getValue(); // { id: 1, name: 'John' }\n * }\n *\n * // Creating a failed result\n * const failure = Result.fail(new InvalidUserError('User not found'));\n * if (failure.isFailure) {\n * const error = failure.getError(); // InvalidUserError instance\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Using in a domain service\n * function createUser(name: string): Result<User, DomainError> {\n * if (!name || name.trim().length === 0) {\n * return Result.fail(new InvalidValueError('Name cannot be empty'));\n * }\n *\n * const user = new User(name);\n * return Result.ok(user);\n * }\n *\n * const result = createUser('John Doe');\n * if (result.isSuccess) {\n * console.log('User created:', result.getValue());\n * } else {\n * console.error('Failed:', result.getError()?.message);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Chaining operations\n * function validateEmail(email: string): Result<string, DomainError> {\n * if (!email.includes('@')) {\n * return Result.fail(new InvalidValueError('Invalid email format'));\n * }\n * return Result.ok(email);\n * }\n *\n * function createAccount(email: string): Result<Account, DomainError> {\n * const emailResult = validateEmail(email);\n * if (emailResult.isFailure) {\n * return emailResult; // Forward the error\n * }\n *\n * const account = new Account(emailResult.getValue()!);\n * return Result.ok(account);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Working with async operations\n * async function fetchUser(id: number): Promise<Result<User, DomainError>> {\n * try {\n * const user = await userRepository.findById(id);\n * if (!user) {\n * return Result.fail(new NotFoundError(`User ${id} not found`));\n * }\n * return Result.ok(user);\n * } catch (error) {\n * return Result.fail(new SystemError('Database connection failed'));\n * }\n * }\n *\n * const result = await fetchUser(123);\n * if (result.isSuccess) {\n * // Handle success\n * } else {\n * // Handle failure\n * }\n * ```\n */\nexport class Result<T, E> {\n /**\n * Indicates if the result is a failure.\n *\n * @example\n * ```typescript\n * const result = Result.fail(new Error('Something went wrong'));\n * if (result.isFailure) {\n * // Handle error case\n * console.error(result.getError());\n * }\n * ```\n */\n public readonly isFailure: boolean;\n\n /**\n * Indicates if the result is a success.\n *\n * @example\n * ```typescript\n * const result = Result.ok(42);\n * if (result.isSuccess) {\n * // Handle success case\n * const value = result.getValue(); // 42\n * }\n * ```\n */\n public readonly isSuccess: boolean;\n\n /**\n * The error, if any.\n * @private\n */\n private readonly _error?: E;\n\n /**\n * The value, if any.\n * @private\n */\n private readonly _value?: T;\n\n /**\n * Private constructor to enforce the use of static methods.\n * @param params.value The value on success.\n * @param params.error The error on failure.\n * @private\n */\n private constructor(params: { value?: T; error?: E }) {\n const hasError = params.error !== undefined;\n this.isFailure = hasError;\n this.isSuccess = !hasError;\n\n this._value = params.value;\n this._error = params.error;\n Object.freeze(this);\n }\n\n /**\n * Creates a failed result.\n *\n * @template T The type of a successful result (never for failure).\n * @template E The type of the error (defaults to DomainError).\n * @param error The error object.\n * @returns {Result<T, E>} A failed Result instance.\n *\n * @example\n * ```typescript\n * // With DomainError\n * class InvalidValueError extends DomainError {\n * public readonly code = 'DOMAIN.INVALID_VALUE' as const;\n * constructor(message: string) {\n * super({ message });\n * }\n * }\n *\n * const result = Result.fail(new InvalidValueError('Value must be positive'));\n * // result.isFailure === true\n * // result.getError() === InvalidValueError instance\n * ```\n *\n * @example\n * ```typescript\n * // With custom error type\n * interface ValidationError {\n * field: string;\n * message: string;\n * }\n *\n * const result = Result.fail<never, ValidationError>({\n * field: 'email',\n * message: 'Invalid email format'\n * });\n * ```\n *\n * @example\n * ```typescript\n * // In a validation function\n * function validateAge(age: number): Result<number, DomainError> {\n * if (age < 0) {\n * return Result.fail(new InvalidValueError('Age cannot be negative'));\n * }\n * if (age > 150) {\n * return Result.fail(new InvalidValueError('Age seems unrealistic'));\n * }\n * return Result.ok(age);\n * }\n * ```\n */\n public static fail<T = never, E = DomainError>(error: E): Result<T, E> {\n return new Result({ error });\n }\n\n /**\n * Creates a successful result.\n *\n * @template T The type of the successful result.\n * @template E The type of the error (never for success).\n * @param value The success value.\n * @returns {Result<T, E>} A successful Result instance.\n *\n * @example\n * ```typescript\n * // With primitive value\n * const result = Result.ok(42);\n * // result.isSuccess === true\n * // result.getValue() === 42\n * ```\n *\n * @example\n * ```typescript\n * // With object\n * const user = { id: 1, name: 'John', email: 'john@example.com' };\n * const result = Result.ok(user);\n * if (result.isSuccess) {\n * const savedUser = result.getValue(); // { id: 1, name: 'John', ... }\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With domain entity\n * class User {\n * constructor(public readonly id: number, public readonly name: string) {}\n * }\n *\n * function createUser(name: string): Result<User, DomainError> {\n * const user = new User(Date.now(), name);\n * return Result.ok(user);\n * }\n *\n * const result = createUser('Alice');\n * if (result.isSuccess) {\n * console.log(`Created user: ${result.getValue()?.name}`);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With void/undefined (for operations that don't return a value)\n * function deleteUser(id: number): Result<void, DomainError> {\n * // ... deletion logic ...\n * return Result.ok(undefined);\n * }\n *\n * const result = deleteUser(123);\n * if (result.isSuccess) {\n * console.log('User deleted successfully');\n * }\n * ```\n */\n public static ok<T, E = never>(value: T): Result<T, E> {\n return new Result({ value });\n }\n\n /**\n * Returns the error if present, otherwise undefined.\n *\n * **Note:** Always check `isFailure` before calling this method to ensure\n * the result is actually a failure. This method will return `undefined` for\n * successful results.\n *\n * @returns {E | undefined} The error or undefined if successful.\n *\n * @example\n * ```typescript\n * const result = Result.fail(new InvalidValueError('Invalid input'));\n *\n * if (result.isFailure) {\n * const error = result.getError();\n * if (error) {\n * console.error(`Error code: ${error.code}, Message: ${error.message}`);\n * }\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Safe error handling pattern\n * function handleResult<T>(result: Result<T, DomainError>): void {\n * if (result.isFailure) {\n * const error = result.getError();\n * if (error) {\n * // Log error with metadata\n * console.error({\n * code: error.code,\n * message: error.message,\n * metadata: error.metadata\n * });\n * }\n * }\n * }\n * ```\n */\n public getError(): E | undefined {\n return this._error;\n }\n\n /**\n * Returns the value if present, otherwise undefined.\n *\n * **Note:** Always check `isSuccess` before calling this method to ensure\n * the result is actually a success. This method will return `undefined` for\n * failed results.\n *\n * @returns {T | undefined} The value or undefined if failed.\n *\n * @example\n * ```typescript\n * const result = Result.ok({ id: 1, name: 'John' });\n *\n * if (result.isSuccess) {\n * const user = result.getValue();\n * if (user) {\n * console.log(`User: ${user.name} (ID: ${user.id})`);\n * }\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Type-safe value extraction\n * function processUser(result: Result<User, DomainError>): void {\n * if (result.isSuccess) {\n * const user = result.getValue();\n * // TypeScript knows user is User | undefined here\n * if (user) {\n * // Process the user\n * userRepository.save(user);\n * }\n * }\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Using non-null assertion (use with caution)\n * const result = Result.ok(42);\n * if (result.isSuccess) {\n * const value = result.getValue()!; // Safe because we checked isSuccess\n * console.log(value * 2); // 84\n * }\n * ```\n */\n public getValue(): T | undefined {\n return this._value;\n }\n\n /**\n * Type guard for failure.\n */\n public isFailureResult(): this is Result<never, E> {\n return this.isFailure;\n }\n\n /**\n * Type guard for success.\n */\n public isSuccessResult(): this is Result<T, never> {\n return this.isSuccess;\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","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","Result","_Result","params","hasError","error","value","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 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};
1
+ var _=Object.defineProperty;var O=Object.getOwnPropertySymbols;var h=Object.prototype.hasOwnProperty,v=Object.prototype.propertyIsEnumerable;var y=(t,e,r)=>e in t?_(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,m=(t,e)=>{for(var r in e||(e={}))h.call(e,r)&&y(t,r,e[r]);if(O)for(var r of O(e))v.call(e,r)&&y(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 I=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 S=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({},S(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 P from"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 c=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:P(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 U}from"crypto";var b=class{constructor(e){var r;this.id=(r=e.id)!=null?r:U(),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 x}from"uuid";import w 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(x())}validate(e){let r=p.schema.safeParse(e);if(!r.success)throw new u(`Invalid UUID: ${r.error.message}`)}};p.schema=w.uuid();var E=p;var R=class extends E{};var oe=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}),A={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 f=class t{constructor(e){let r=e.error!==void 0;this.isFailure=r,this.isSuccess=!r,this._value=e.value,this._error=e.error,Object.freeze(this)}static fail(e){return new t({error:e})}static ok(e){return new t({value:e})}getError(){return this._error}getValue(){return this._value}isFailureResult(){return this.isFailure}isSuccessResult(){return this.isSuccess}};var D=class extends Error{constructor({code:e=A[500],isOperational:r=!1,status:a=500,metadata:n,message:T,cause:N}){super(T),this.name=new.target.name,this.code=e,this.status=a,this.isOperational=r,this.metadata=n,this.cause=N,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 c){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 Ee(t){return t==null?{}:typeof t=="object"?t:{value:t}}export{R as AggregateId,I as AggregateRoot,D as ApplicationError,o as DomainError,b as DomainEvent,s as Entity,g as EntityValidationError,oe as HttpStatus,A as HttpStatusMessage,u as InvalidValueObjectError,d as PrimitiveValueObject,f as Result,E as UUID,c as ValueObject,l as deepFreeze,Ee 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/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"]}
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/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","import { DomainError } from './domain.error';\n\n/**\n * Represents the result of an operation, which can be either a success or a failure.\n *\n * This is a functional programming pattern that helps avoid throwing exceptions\n * and makes error handling explicit in the type system. It's commonly used in\n * Domain-Driven Design (DDD) to represent domain operation outcomes.\n *\n * @template T The type of a successful result.\n * @template E The type of the error in case of failure (defaults to DomainError).\n *\n * @example\n * ```typescript\n * // Creating a successful result\n * const success = Result.ok({ id: 1, name: 'John' });\n * if (success.isSuccess) {\n * const user = success.getValue(); // { id: 1, name: 'John' }\n * }\n *\n * // Creating a failed result\n * const failure = Result.fail(new InvalidUserError('User not found'));\n * if (failure.isFailure) {\n * const error = failure.getError(); // InvalidUserError instance\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Using in a domain service\n * function createUser(name: string): Result<User, DomainError> {\n * if (!name || name.trim().length === 0) {\n * return Result.fail(new InvalidValueError('Name cannot be empty'));\n * }\n *\n * const user = new User(name);\n * return Result.ok(user);\n * }\n *\n * const result = createUser('John Doe');\n * if (result.isSuccess) {\n * console.log('User created:', result.getValue());\n * } else {\n * console.error('Failed:', result.getError()?.message);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Chaining operations\n * function validateEmail(email: string): Result<string, DomainError> {\n * if (!email.includes('@')) {\n * return Result.fail(new InvalidValueError('Invalid email format'));\n * }\n * return Result.ok(email);\n * }\n *\n * function createAccount(email: string): Result<Account, DomainError> {\n * const emailResult = validateEmail(email);\n * if (emailResult.isFailure) {\n * return emailResult; // Forward the error\n * }\n *\n * const account = new Account(emailResult.getValue()!);\n * return Result.ok(account);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Working with async operations\n * async function fetchUser(id: number): Promise<Result<User, DomainError>> {\n * try {\n * const user = await userRepository.findById(id);\n * if (!user) {\n * return Result.fail(new NotFoundError(`User ${id} not found`));\n * }\n * return Result.ok(user);\n * } catch (error) {\n * return Result.fail(new SystemError('Database connection failed'));\n * }\n * }\n *\n * const result = await fetchUser(123);\n * if (result.isSuccess) {\n * // Handle success\n * } else {\n * // Handle failure\n * }\n * ```\n */\nexport class Result<T, E> {\n /**\n * Indicates if the result is a failure.\n *\n * @example\n * ```typescript\n * const result = Result.fail(new Error('Something went wrong'));\n * if (result.isFailure) {\n * // Handle error case\n * console.error(result.getError());\n * }\n * ```\n */\n public readonly isFailure: boolean;\n\n /**\n * Indicates if the result is a success.\n *\n * @example\n * ```typescript\n * const result = Result.ok(42);\n * if (result.isSuccess) {\n * // Handle success case\n * const value = result.getValue(); // 42\n * }\n * ```\n */\n public readonly isSuccess: boolean;\n\n /**\n * The error, if any.\n * @private\n */\n private readonly _error?: E;\n\n /**\n * The value, if any.\n * @private\n */\n private readonly _value?: T;\n\n /**\n * Private constructor to enforce the use of static methods.\n * @param params.value The value on success.\n * @param params.error The error on failure.\n * @private\n */\n private constructor(params: { value?: T; error?: E }) {\n const hasError = params.error !== undefined;\n this.isFailure = hasError;\n this.isSuccess = !hasError;\n\n this._value = params.value;\n this._error = params.error;\n Object.freeze(this);\n }\n\n /**\n * Creates a failed result.\n *\n * @template T The type of a successful result (never for failure).\n * @template E The type of the error (defaults to DomainError).\n * @param error The error object.\n * @returns {Result<T, E>} A failed Result instance.\n *\n * @example\n * ```typescript\n * // With DomainError\n * class InvalidValueError extends DomainError {\n * public readonly code = 'DOMAIN.INVALID_VALUE' as const;\n * constructor(message: string) {\n * super({ message });\n * }\n * }\n *\n * const result = Result.fail(new InvalidValueError('Value must be positive'));\n * // result.isFailure === true\n * // result.getError() === InvalidValueError instance\n * ```\n *\n * @example\n * ```typescript\n * // With custom error type\n * interface ValidationError {\n * field: string;\n * message: string;\n * }\n *\n * const result = Result.fail<never, ValidationError>({\n * field: 'email',\n * message: 'Invalid email format'\n * });\n * ```\n *\n * @example\n * ```typescript\n * // In a validation function\n * function validateAge(age: number): Result<number, DomainError> {\n * if (age < 0) {\n * return Result.fail(new InvalidValueError('Age cannot be negative'));\n * }\n * if (age > 150) {\n * return Result.fail(new InvalidValueError('Age seems unrealistic'));\n * }\n * return Result.ok(age);\n * }\n * ```\n */\n public static fail<T = never, E = DomainError>(error: E): Result<T, E> {\n return new Result({ error });\n }\n\n /**\n * Creates a successful result.\n *\n * @template T The type of the successful result.\n * @template E The type of the error (never for success).\n * @param value The success value.\n * @returns {Result<T, E>} A successful Result instance.\n *\n * @example\n * ```typescript\n * // With primitive value\n * const result = Result.ok(42);\n * // result.isSuccess === true\n * // result.getValue() === 42\n * ```\n *\n * @example\n * ```typescript\n * // With object\n * const user = { id: 1, name: 'John', email: 'john@example.com' };\n * const result = Result.ok(user);\n * if (result.isSuccess) {\n * const savedUser = result.getValue(); // { id: 1, name: 'John', ... }\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With domain entity\n * class User {\n * constructor(public readonly id: number, public readonly name: string) {}\n * }\n *\n * function createUser(name: string): Result<User, DomainError> {\n * const user = new User(Date.now(), name);\n * return Result.ok(user);\n * }\n *\n * const result = createUser('Alice');\n * if (result.isSuccess) {\n * console.log(`Created user: ${result.getValue()?.name}`);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // With void/undefined (for operations that don't return a value)\n * function deleteUser(id: number): Result<void, DomainError> {\n * // ... deletion logic ...\n * return Result.ok(undefined);\n * }\n *\n * const result = deleteUser(123);\n * if (result.isSuccess) {\n * console.log('User deleted successfully');\n * }\n * ```\n */\n public static ok<T, E = never>(value: T): Result<T, E> {\n return new Result({ value });\n }\n\n /**\n * Returns the error if present, otherwise undefined.\n *\n * **Note:** Always check `isFailure` before calling this method to ensure\n * the result is actually a failure. This method will return `undefined` for\n * successful results.\n *\n * @returns {E | undefined} The error or undefined if successful.\n *\n * @example\n * ```typescript\n * const result = Result.fail(new InvalidValueError('Invalid input'));\n *\n * if (result.isFailure) {\n * const error = result.getError();\n * if (error) {\n * console.error(`Error code: ${error.code}, Message: ${error.message}`);\n * }\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Safe error handling pattern\n * function handleResult<T>(result: Result<T, DomainError>): void {\n * if (result.isFailure) {\n * const error = result.getError();\n * if (error) {\n * // Log error with metadata\n * console.error({\n * code: error.code,\n * message: error.message,\n * metadata: error.metadata\n * });\n * }\n * }\n * }\n * ```\n */\n public getError(): E | undefined {\n return this._error;\n }\n\n /**\n * Returns the value if present, otherwise undefined.\n *\n * **Note:** Always check `isSuccess` before calling this method to ensure\n * the result is actually a success. This method will return `undefined` for\n * failed results.\n *\n * @returns {T | undefined} The value or undefined if failed.\n *\n * @example\n * ```typescript\n * const result = Result.ok({ id: 1, name: 'John' });\n *\n * if (result.isSuccess) {\n * const user = result.getValue();\n * if (user) {\n * console.log(`User: ${user.name} (ID: ${user.id})`);\n * }\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Type-safe value extraction\n * function processUser(result: Result<User, DomainError>): void {\n * if (result.isSuccess) {\n * const user = result.getValue();\n * // TypeScript knows user is User | undefined here\n * if (user) {\n * // Process the user\n * userRepository.save(user);\n * }\n * }\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Using non-null assertion (use with caution)\n * const result = Result.ok(42);\n * if (result.isSuccess) {\n * const value = result.getValue()!; // Safe because we checked isSuccess\n * console.log(value * 2); // 84\n * }\n * ```\n */\n public getValue(): T | undefined {\n return this._value;\n }\n\n /**\n * Type guard for failure.\n */\n public isFailureResult(): this is Result<never, E> {\n return this.isFailure;\n }\n\n /**\n * Type guard for success.\n */\n public isSuccessResult(): this is Result<T, never> {\n return this.isSuccess;\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","Result","_Result","params","hasError","error","value","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": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Domain Driven Design package for Rineex core modules",
5
5
  "author": "Rineex Team",
6
6
  "main": "./dist/index.js",
@@ -43,6 +43,7 @@
43
43
  "url": "https://github.com/rineex/core.git",
44
44
  "directory": "packages/ddd"
45
45
  },
46
+ "homepage": "https://github.com/rineex/core/tree/main/packages/ddd",
46
47
  "dependencies": {
47
48
  "fast-deep-equal": "3.1.3",
48
49
  "isbot": "5.1.32",