@shirudo/ddd-kit 3.0.0-rc.8 → 3.0.0-rc.9
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/chunks/kit-errors.d.ts +7 -1
- package/dist/chunks/kit-errors.js +6 -2
- package/dist/chunks/kit-errors.js.map +1 -1
- package/dist/index.d.ts +91 -14
- package/dist/index.js +32 -25
- package/dist/index.js.map +1 -1
- package/dist/testing.d.ts +10 -1
- package/dist/testing.js +27 -18
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1422,6 +1422,11 @@ interface PersistenceModel<TAggregate, TBaseline, TChangeSet> {
|
|
|
1422
1422
|
* `Set` members and `Map` keys by reference (JS `SameValueZero`
|
|
1423
1423
|
* semantics): a capture that re-materializes object Set members or Map
|
|
1424
1424
|
* keys on every call must supply {@link captureEquals}.
|
|
1425
|
+
*
|
|
1426
|
+
* A column that the store owns stays out of the capture, for example an
|
|
1427
|
+
* `updatedAt` that the adapter stamps; `flush` writes it. A captured store
|
|
1428
|
+
* column pushes a stale value back on the next write, or it marks every
|
|
1429
|
+
* row as changed.
|
|
1425
1430
|
*/
|
|
1426
1431
|
capture(aggregate: TAggregate): TBaseline;
|
|
1427
1432
|
/**
|
|
@@ -1505,8 +1510,10 @@ type UnitOfWorkIdentityMap = Pick<IdentityMap, "get" | "has" | "isDeleted">;
|
|
|
1505
1510
|
* `tracking.trackLoaded(aggregate)` after hydration. This captures the
|
|
1506
1511
|
* expected version before application code can mutate the instance.
|
|
1507
1512
|
* - Adapter objects do not need lifecycle methods; the facade installs the
|
|
1508
|
-
* Unit-of-Work-owned `add`, `update
|
|
1509
|
-
*
|
|
1513
|
+
* Unit-of-Work-owned `add`, `update` unless the definition is append-only,
|
|
1514
|
+
* and `remove` with `physicalRemoval`. If a concrete adapter has a method
|
|
1515
|
+
* named `add`, `update`, or `remove` anyway, the facade masks it, installed
|
|
1516
|
+
* or not.
|
|
1510
1517
|
* - Other repository methods are reads. A custom method that performs a write
|
|
1511
1518
|
* would bypass the Unit of Work and violates the adapter contract.
|
|
1512
1519
|
*/
|
|
@@ -1629,7 +1636,9 @@ declare class AggregateTrackingError extends KitWiringError<"AGGREGATE_TRACKING"
|
|
|
1629
1636
|
readonly operation: AggregateWriteIntent | "load" | "commit";
|
|
1630
1637
|
readonly reason: AggregateTrackingFailure;
|
|
1631
1638
|
readonly registeredIntent?: AggregateWriteIntent | undefined;
|
|
1632
|
-
constructor(aggregateId: string, operation: AggregateWriteIntent | "load" | "commit", reason: AggregateTrackingFailure, registeredIntent?: AggregateWriteIntent | undefined
|
|
1639
|
+
constructor(aggregateId: string, operation: AggregateWriteIntent | "load" | "commit", reason: AggregateTrackingFailure, registeredIntent?: AggregateWriteIntent | undefined, options?: {
|
|
1640
|
+
readonly appendOnly?: boolean;
|
|
1641
|
+
});
|
|
1633
1642
|
}
|
|
1634
1643
|
/**
|
|
1635
1644
|
* The unit of work failed AFTER the work callback completed
|
|
@@ -1736,7 +1745,7 @@ interface RunOptions {
|
|
|
1736
1745
|
}
|
|
1737
1746
|
declare const repositoryDefinitionBrand: unique symbol;
|
|
1738
1747
|
/** Adapter wiring accepted by {@link defineRepository}. */
|
|
1739
|
-
interface RepositoryDefinitionOptions<TCtx, TRepositoryPort extends object, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TBaseline, TChangeSet, TRemoval extends boolean = false> {
|
|
1748
|
+
interface RepositoryDefinitionOptions<TCtx, TRepositoryPort extends object, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TBaseline, TChangeSet, TRemoval extends boolean = false, TAppendOnly extends boolean = false> {
|
|
1740
1749
|
/**
|
|
1741
1750
|
* Concrete aggregate class used as the Identity Map key, and for nothing
|
|
1742
1751
|
* else. The read adapter passes the same class to `identityMap.get`, so
|
|
@@ -1748,7 +1757,8 @@ interface RepositoryDefinitionOptions<TCtx, TRepositoryPort extends object, TAgg
|
|
|
1748
1757
|
readonly persistence: PersistenceModel<TAggregate, TBaseline, TChangeSet>;
|
|
1749
1758
|
/**
|
|
1750
1759
|
* Creates the transaction-bound adapter for the port's non-lifecycle
|
|
1751
|
-
* methods. The Unit of Work supplies `add`, `update
|
|
1760
|
+
* methods. The Unit of Work supplies `add`, `update` unless the definition
|
|
1761
|
+
* is append-only, and `remove` with `physicalRemoval`.
|
|
1752
1762
|
*/
|
|
1753
1763
|
readonly create: (transaction: TCtx, tracking: RepositoryTracking<TAggregate>) => Omit<TRepositoryPort, "add" | "update" | "remove">;
|
|
1754
1764
|
/**
|
|
@@ -1767,19 +1777,83 @@ interface RepositoryDefinitionOptions<TCtx, TRepositoryPort extends object, TAgg
|
|
|
1767
1777
|
readonly mapError: (error: unknown, write: AggregatePersistenceWrite<TAggregate, TChangeSet>) => InfrastructureError;
|
|
1768
1778
|
/** Adds Unit-of-Work-owned `remove` to the application-facing repository. */
|
|
1769
1779
|
readonly physicalRemoval?: TRemoval;
|
|
1780
|
+
/**
|
|
1781
|
+
* Leaves `update` out of the application-facing repository. An append-only
|
|
1782
|
+
* aggregate is a fact that the domain never changes after `add`, for
|
|
1783
|
+
* example a ledger entry or an audit record. The port then declares no
|
|
1784
|
+
* `update`, and the Unit of Work installs none.
|
|
1785
|
+
*/
|
|
1786
|
+
readonly appendOnly?: TAppendOnly;
|
|
1770
1787
|
}
|
|
1771
1788
|
/** Complete, helper-created definition for one Unit-of-Work repository. */
|
|
1772
|
-
interface RepositoryDefinition<TCtx, TRepositoryPort extends object, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TBaseline, TChangeSet, TRemoval extends boolean = false> extends RepositoryDefinitionOptions<TCtx, TRepositoryPort, TAggregate, TBaseline, TChangeSet, TRemoval> {
|
|
1789
|
+
interface RepositoryDefinition<TCtx, TRepositoryPort extends object, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TBaseline, TChangeSet, TRemoval extends boolean = false, TAppendOnly extends boolean = false> extends RepositoryDefinitionOptions<TCtx, TRepositoryPort, TAggregate, TBaseline, TChangeSet, TRemoval, TAppendOnly> {
|
|
1773
1790
|
/** Nominal marker installed by {@link defineRepository}. */
|
|
1774
1791
|
readonly [repositoryDefinitionBrand]: true;
|
|
1775
1792
|
}
|
|
1776
1793
|
/** @inline */
|
|
1777
1794
|
type CallableValue = (...args: never[]) => unknown;
|
|
1795
|
+
/**
|
|
1796
|
+
* The compile-time report for a port that violates one constraint of
|
|
1797
|
+
* {@link defineRepository}. No definition can carry a property of type
|
|
1798
|
+
* `never`, so the compiler rejects the call. Its message names the violated
|
|
1799
|
+
* constraint instead of the bare "parameter of type never".
|
|
1800
|
+
* @inline
|
|
1801
|
+
*/
|
|
1802
|
+
type RepositoryPortViolation<TConstraint extends string> = { readonly [constraint in `defineRepository: ${TConstraint}`]: never; };
|
|
1803
|
+
/**
|
|
1804
|
+
* Continues with the next constraint when the checked one passed, and
|
|
1805
|
+
* otherwise reports the violation of the checked one.
|
|
1806
|
+
* @inline
|
|
1807
|
+
*/
|
|
1808
|
+
type Then<TChecked, TNext> = unknown extends TChecked ? TNext : TChecked;
|
|
1809
|
+
/** @inline */
|
|
1810
|
+
type IsUnion<T, TEach = T> = T extends unknown ? [TEach] extends [T] ? false : true : never;
|
|
1811
|
+
/** @inline */
|
|
1812
|
+
type PortShapeConstraint<TRepositoryPort> = [Extract<TRepositoryPort, CallableValue>] extends [never] ? true extends IsUnion<TRepositoryPort> ? RepositoryPortViolation<"the port must be one object type, not a union"> : unknown : RepositoryPortViolation<"the port must be an object type, not a function">;
|
|
1813
|
+
/**
|
|
1814
|
+
* Checks a lifecycle member that the port declares: it is required, and it
|
|
1815
|
+
* accepts the definition's aggregate. An optional member is the trap of a
|
|
1816
|
+
* port that extends a type with `update?` or `remove?`, so it gets its own
|
|
1817
|
+
* message.
|
|
1818
|
+
* @inline
|
|
1819
|
+
*/
|
|
1820
|
+
type MemberAcceptsAggregate<TRepositoryPort, TMember extends "add" | "update" | "remove", TAggregate extends Aggregate<Id<string>, AnyDomainEvent>> = undefined extends TRepositoryPort[TMember & keyof TRepositoryPort] ? RepositoryPortViolation<`the port's ${TMember} must not be optional`> : [TRepositoryPort] extends [Pick<AggregateWriteRegistration<TAggregate> & PhysicalRemovalRegistration<TAggregate>, TMember>] ? unknown : RepositoryPortViolation<`the port's ${TMember} must accept the definition's aggregate`>;
|
|
1821
|
+
/** @inline */
|
|
1822
|
+
type AddConstraint<TRepositoryPort, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>> = "add" extends keyof TRepositoryPort ? MemberAcceptsAggregate<TRepositoryPort, "add", TAggregate> : RepositoryPortViolation<"the port must declare add(aggregate): void">;
|
|
1823
|
+
/** @inline */
|
|
1824
|
+
type UpdateConstraint<TRepositoryPort, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TAppendOnly extends boolean> = "update" extends keyof TRepositoryPort ? boolean extends TAppendOnly ? RepositoryPortViolation<"the port declares update, so the definition must not set appendOnly"> : [TAppendOnly] extends [true] ? RepositoryPortViolation<"appendOnly is true, so the port must not declare update"> : MemberAcceptsAggregate<TRepositoryPort, "update", TAggregate> : [TAppendOnly] extends [true] ? unknown : RepositoryPortViolation<"the port declares no update, so the definition must set appendOnly: true">;
|
|
1825
|
+
/** @inline */
|
|
1826
|
+
type RemovalConstraint<TRepositoryPort, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TRemoval extends boolean> = "remove" extends keyof TRepositoryPort ? [TRemoval] extends [true] ? MemberAcceptsAggregate<TRepositoryPort, "remove", TAggregate> : RepositoryPortViolation<"the port declares remove, so the definition must set physicalRemoval: true"> : [TRemoval] extends [true] ? RepositoryPortViolation<"physicalRemoval is true, so the port must declare remove(aggregate): void"> : unknown;
|
|
1827
|
+
/**
|
|
1828
|
+
* Checks the port against every constraint of {@link defineRepository}, one
|
|
1829
|
+
* at a time, so the report names the first violated constraint. Resolves to
|
|
1830
|
+
* `unknown` when the port satisfies all of them. A port typed `any` opts out
|
|
1831
|
+
* of the check, as it does everywhere else. Under the `object` bound of the
|
|
1832
|
+
* builder only `any` satisfies `unknown extends TRepositoryPort`; the usual
|
|
1833
|
+
* `0 extends 1 & T` probe misses an `any` that passed through that bound.
|
|
1834
|
+
* @inline
|
|
1835
|
+
*/
|
|
1836
|
+
type RepositoryPortConstraint<TRepositoryPort, TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TRemoval extends boolean, TAppendOnly extends boolean> = unknown extends TRepositoryPort ? unknown : Then<PortShapeConstraint<TRepositoryPort>, Then<AddConstraint<TRepositoryPort, TAggregate>, Then<UpdateConstraint<TRepositoryPort, TAggregate, TAppendOnly>, RemovalConstraint<TRepositoryPort, TAggregate, TRemoval>>>>;
|
|
1778
1837
|
/** @inline */
|
|
1779
|
-
type RepositoryDefinitionBuilder<TRepositoryPort extends object> = <TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TCreate extends (transaction: never, tracking: RepositoryTracking<TAggregate>) => Omit<TRepositoryPort, "add" | "update" | "remove">, TBaseline, TChangeSet, TRemoval extends boolean = false>(definition: RepositoryDefinitionOptions<Parameters<TCreate>[0], TRepositoryPort, TAggregate, TBaseline, TChangeSet, TRemoval> & {
|
|
1838
|
+
type RepositoryDefinitionBuilder<TRepositoryPort extends object> = <TAggregate extends Aggregate<Id<string>, AnyDomainEvent>, TCreate extends (transaction: never, tracking: RepositoryTracking<TAggregate>) => Omit<TRepositoryPort, "add" | "update" | "remove">, TBaseline, TChangeSet, TRemoval extends boolean = false, TAppendOnly extends boolean = false>(definition: RepositoryDefinitionOptions<Parameters<TCreate>[0], TRepositoryPort, TAggregate, TBaseline, TChangeSet, TRemoval, TAppendOnly> & {
|
|
1780
1839
|
readonly create: TCreate;
|
|
1781
|
-
} &
|
|
1782
|
-
|
|
1840
|
+
} & RepositoryPortConstraint<TRepositoryPort, TAggregate, TRemoval, TAppendOnly>) => RepositoryDefinition<Parameters<TCreate>[0], TRepositoryPort, TAggregate, TBaseline, TChangeSet, TRemoval, TAppendOnly>;
|
|
1841
|
+
/**
|
|
1842
|
+
* Defines repository wiring for an application-owned driven port.
|
|
1843
|
+
*
|
|
1844
|
+
* The first call makes the port explicit; the second infers the transaction,
|
|
1845
|
+
* aggregate, persistence, event, and lifecycle types from the adapter wiring.
|
|
1846
|
+
* The port must declare `add` for the aggregate. It declares `update` unless
|
|
1847
|
+
* the definition sets `appendOnly: true`. If it declares `remove`, the
|
|
1848
|
+
* definition must set `physicalRemoval: true`. A violated constraint fails
|
|
1849
|
+
* the call with a compiler error that names the constraint. The adapter
|
|
1850
|
+
* created by the definition implements only the remaining methods because
|
|
1851
|
+
* lifecycle writes are installed by the Unit of Work.
|
|
1852
|
+
* The returned definition is the only form accepted by {@link UnitOfWork}; a
|
|
1853
|
+
* raw adapter-shaped object cannot silently turn its concrete surface into the
|
|
1854
|
+
* application contract.
|
|
1855
|
+
*/
|
|
1856
|
+
declare function defineRepository<TRepositoryPort extends object>(): RepositoryDefinitionBuilder<TRepositoryPort>;
|
|
1783
1857
|
/** Application-facing repositories inferred from their adapter definitions. */
|
|
1784
1858
|
type RepositoriesOf<TDefinitions> = { [K in keyof TDefinitions]: RepositoryFacadeOf<TDefinitions[K]>; };
|
|
1785
1859
|
/**
|
|
@@ -1787,12 +1861,15 @@ type RepositoriesOf<TDefinitions> = { [K in keyof TDefinitions]: RepositoryFacad
|
|
|
1787
1861
|
* entries, callable adapter results, and definitions whose transaction context
|
|
1788
1862
|
* or aggregate event family does not belong to the Unit of Work that owns them.
|
|
1789
1863
|
*/
|
|
1790
|
-
type CompatibleRepositoryDefinitions<Evt extends AnyDomainEvent, TCtx, TDefinitions> = { [K in keyof TDefinitions]: TDefinitions[K] extends RepositoryDefinition<infer TDefinitionContext, infer _TRepositoryPort, infer TAggregate, infer _TBaseline, infer _TChangeSet, infer _TRemoval> ? TAggregate extends Aggregate<Id<string>, infer TDefinitionEvent> ? [TDefinitionEvent] extends [Evt] ? TCtx extends TDefinitionContext ? TDefinitions[K] : never : never : never : never; };
|
|
1864
|
+
type CompatibleRepositoryDefinitions<Evt extends AnyDomainEvent, TCtx, TDefinitions> = { [K in keyof TDefinitions]: TDefinitions[K] extends RepositoryDefinition<infer TDefinitionContext, infer _TRepositoryPort, infer TAggregate, infer _TBaseline, infer _TChangeSet, infer _TRemoval, infer _TAppendOnly> ? TAggregate extends Aggregate<Id<string>, infer TDefinitionEvent> ? [TDefinitionEvent] extends [Evt] ? TCtx extends TDefinitionContext ? TDefinitions[K] : never : never : never : never; };
|
|
1791
1865
|
/** @inline */
|
|
1792
|
-
type RepositoryFacadeOf<TDefinition> = TDefinition extends RepositoryDefinition<infer _TCtx, infer TRepositoryPort, infer _TAggregate, infer _TBaseline, infer _TChangeSet, infer _TRemoval> ? TRepositoryPort : never;
|
|
1793
|
-
/** Unit-of-Work-owned
|
|
1794
|
-
interface
|
|
1866
|
+
type RepositoryFacadeOf<TDefinition> = TDefinition extends RepositoryDefinition<infer _TCtx, infer TRepositoryPort, infer _TAggregate, infer _TBaseline, infer _TChangeSet, infer _TRemoval, infer _TAppendOnly> ? TRepositoryPort : never;
|
|
1867
|
+
/** The one Unit-of-Work-owned write of an append-only repository facade. */
|
|
1868
|
+
interface AppendOnlyWriteRegistration<TAggregate extends Aggregate<Id<string>, AnyDomainEvent>> {
|
|
1795
1869
|
add(aggregate: TAggregate): void;
|
|
1870
|
+
}
|
|
1871
|
+
/** Unit-of-Work-owned writes of a repository facade that is not append-only. */
|
|
1872
|
+
interface AggregateWriteRegistration<TAggregate extends Aggregate<Id<string>, AnyDomainEvent>> extends AppendOnlyWriteRegistration<TAggregate> {
|
|
1796
1873
|
update(aggregate: TAggregate): void;
|
|
1797
1874
|
}
|
|
1798
1875
|
/** Optional physical removal added only by an explicit repository definition. */
|
|
@@ -4274,5 +4351,5 @@ declare function captureAggregateSnapshot<TAggregate extends SnapshotAggregate,
|
|
|
4274
4351
|
*/
|
|
4275
4352
|
declare function reconstituteAggregateFromSnapshot<TAggregate extends SnapshotAggregate, TSnapshotState>(model: SnapshotModel<TAggregate, TSnapshotState>, id: TAggregate["id"], snapshot: AggregateSnapshot<unknown>): TAggregate;
|
|
4276
4353
|
//#endregion
|
|
4277
|
-
export { type Aggregate, type AggregateAddress, type AggregateAddressMismatchOptions, type AggregateClass, type AggregateCommitToken, type AggregateConfig, AggregateDeletedError, AggregateNotFoundError, type AggregateNotFoundErrorOptions, type AggregatePersistence, type AggregatePersistenceWrite, type AggregateSnapshot, AggregateTrackingError, type AggregateTrackingFailure, type AggregateWriteIntent, type AggregateWriteRegistration, type AnyDomainEvent, type AnyUncommittedDomainEvent, CapabilityRegistryConflictError, type ClockFactory, type Command, CommandBus, type CommandBusOptions, type CommandCommitOriginCandidate, type CommandHandler, type CommandMessageContent, type CommandMessageRelationships, type CommandOutboxCommitCandidate, type CommandOutboxMapper, type CommandOutboxWriter, type CommitEnrollment, type CommitEnrollmentOptions, CommitError, type CommitPosition, type CommittedDomainEvent, type CompatibleRepositoryDefinitions, ConcurrencyConflictError, type ConcurrencyConflictErrorOptions, type CreateDomainEventFromFactsOptions, type CreateDomainEventOptions, type CreateDomainEventStampOptions, type CreateUncommittedDomainEventOptions, type DeadLetterDeadline, type DeadLetterRecord, DeadlineProcessor, type DeadlineProcessorObservers, type DeadlineProcessorOptions, type DeadlineStore, type DeepEqualExceptOptions, type DeepOmitKey, type DeepOmitOptions, type DeepOmitPathSegment, type DeliveryFailureAssessment, type DeliveryFailureClassifier, type DeliveryFailureKind, DirectStateMutationError, type DispatchTrackingOutbox, DomainError, type DomainErrorClass, type DomainEvent, type DomainEventFactory, type DomainEventFactoryOptions, type DomainEventStamp, type DomainEventStampFactory, type DomainEventStampProvider, type DomainEventValidationCode, DomainEventValidationError, type DomainEventValidationField, type DomainMachineDefinition, type DomainMachineDefinitionAnalysis, type DomainMachineDefinitionDiagnostic, type DomainMachineInput, type DomainMachineReadonly, type DomainMachineSnapshot, type DomainMachineTransitionDescription, DomainStateMachine, type DomainStateNode, type DomainTransition, DomainTransitionGuardRejectedError, type DomainTransitionGuardResult, type DomainTransitionOutcome, type DomainTransitionResult, type DueDeadline, DuplicateAggregateError, type DuplicateAggregateErrorOptions, DuplicateEventIdError, DuplicateHandlerRegistrationError, type DuplicateHandlerRegistrationErrorOptions, type DurableCommandMessage, Entity, type EntityConfig, ErrorMapperFailedError, type ErrorMapperFailedErrorOptions, type EventBus, EventBusClosedError, EventBusImpl, type EventBusObservers, type EventBusOptions, type EventCommitCandidate, type EventCommitCandidatePosition, type EventHandler, EventHarvestError, type EventIdFactory, type EventMetadata, EventSourcedAggregate, type EventStore, type EventStoreAppendOptions, type ExecutionContext, FoldReturnedNoStateError, ForeignEventError, type HandlerFailureReport, HostileStateKeyError, type ICommandBus, type IEntity, type IQueryBus, type IValueObject, type Id, type IdGenerator, type IdempotencyClaim, type IdempotencyClaimHandle, IdempotencyClaimLostError, type IdempotencyClaimLostErrorOptions, IdempotencyCompletionWithoutClaimError, IdempotencyInFlightError, type IdempotencyInFlightErrorOptions, IdempotencyKeyReuseError, type IdempotencyKeyReuseErrorOptions, type IdempotencyLease, type IdempotencyOperationErrorContext, type IdempotencyReconciliation, type IdempotencyReconciliationDecision, IdempotencyReconciliationRequiredError, type IdempotencyReconciliationRequiredErrorOptions, type IdempotencyStore, type IdempotentCommitRequest, type IdempotentCommitResult, type IdempotentExecution, type Identifiable, IdentityMap, InMemoryCapacityExceededError, type InMemoryCapacityExceededErrorOptions, InMemoryDeadlineStore, type InMemoryDeadlineStoreOptions, InMemoryEventStore, type InMemoryEventStoreOptions, InMemoryIdempotencyStore, type InMemoryIdempotencyStoreOptions, InMemoryOutbox, type InMemoryOutboxOptions, InMemoryProjectionCheckpointStore, type InMemoryProjectionCheckpointStoreOptions, InMemorySnapshotStore, type InMemorySnapshotStoreOptions, InfrastructureError, type IntegrationMessage, type IntegrationMessageContent, type IntegrationMessageMapper, type IntegrationMessageRelationships, InvalidCommandMessageError, InvalidDomainMachineContextError, InvalidDomainMachineDefinitionError, InvalidDomainMachineInputError, InvalidDomainMachineSnapshotError, InvalidDomainTransitionError, InvalidDomainTransitionGuardResultError, InvalidDomainTransitionResultError, InvalidIntegrationMessageError, InvalidRepositoryAdapterError, InvalidRepositoryDefinitionError, InvalidVersionError, type JsonObject, type JsonPrimitive, type JsonValue, type KitErrorCode, type KitErrorOptions, MisaddressedEventError, MissingEntityIdError, MissingFoldError, MissingHandlerError, NestedUnitOfWorkError, NonProgressingEventStreamPageError, type NonProgressingEventStreamPageErrorOptions, type OnceOptions, type Outbox, OutboxDispatcher, type OutboxDispatcherObservers, type OutboxDispatcherOptions, type OutboxRecord, type OutboxSink, type OutboxWriter, type PendingDomainEvent, PendingEventBatchMismatchError, PendingEventLimitExceededError, type PendingEventLimitExceededErrorOptions, type PersistenceBaseline, type PersistenceChanges, type PersistenceLifecycle, type PersistenceModel, type PhysicalRemovalRegistration, type PreparedDomainMachineDefinition, type ProjectOptions, type Projection, type ProjectionBatchResult, type ProjectionCheckpoint, type ProjectionCheckpointStore, type ProjectionEventHandler, type ProjectionFromHandlersOptions, ProjectionGapError, type ProjectionHandlers, ProjectionIdentityViolationError, ProjectionOrderViolationError, type ProjectionPosition, ProjectionReceiptViolationError, Projector, type ProjectorOptions, type PublishAbortedReport, type PublishChainState, type PublishChainStore, PublishDepthExceededError, type PublishOptions, type PublishedCommand, type Query, QueryBus, type QueryBusOptions, type QueryHandler, type ReadStreamOptions, ReentrantDomainStateMachineEvaluationError, ReentrantEventRecordingError, ReplayHeadMismatchError, type ReplayHeadMismatchErrorOptions, type ReplayableAggregate, type RepositoriesOf, type Repository, type RepositoryDefinition, type RepositoryDefinitionOptions, RepositoryErrorMappingFailedError, type RepositoryTracking, type RetryPolicy, RetryingTransactionScope, RollbackError, type RunOptions, type SharedDomainEventStampOptions, SnapshotCorruptedError, type SnapshotModel, SnapshotSchemaMismatchError, type SnapshotSchemaMismatchErrorOptions, type SnapshotStore, SnapshotTimeValidationError, SnapshotVersionNotRestoredError, type SnapshotVersionNotRestoredErrorOptions, Specification, type SpecificationComposite, StateStoredAggregate, type StateValidator, type StreamReadResult, type SubscriptionThresholdReport, TransactionClosedError, type TransactionScope, type TransactionalOptions, type UncommittedDomainEvent, type UncommittedDomainEventOf, UnenrolledChangesError, UnitOfWork, type UnitOfWorkContext, type UnitOfWorkDeps, type UnitOfWorkIdentityMap, UnmanagedInstanceError, UnmintedEventError, UnprojectableEventError, UnregisteredHandlerError, type UnregisteredHandlerErrorOptions, UnreplayableAggregateError, type VO, ValueObject, type Version, type WithCommitDeps, type WithCommitWorkResult, type WithIdempotentCommitDeps, analyzeDomainMachineDefinition, canTransitionDomainState, captureAggregateSnapshot, capturePersistenceBaseline, copyMetadata, createDomainEvent, createDomainEventFactory, createDomainEventFromFacts, createInitialDomainMachineSnapshot, createIntegrationMessage, createUncommittedDomainEvent, decodeIntegrationMessage, deepEqual, deepEqualExcept, deepFreeze, deepOmit, defaultDomainEventFactory, defineRepository, defineSnapshotModel, derivePersistenceChanges, detachState, domainErrorToResult, encodeIntegrationMessage, entityIds, eventBusSink, findEntityById, freezeShallow, hasEntityId, ignoreProjectionEvent, insertPersistenceBaseline, integrationMessageToCommittedEvent, isDomainErrorLike, isInfrastructureErrorLike, isPositionAfter, mergeMetadata, outboxWriterAcceptingEventLoss, persistenceProjectionDrifted, prepareDomainMachineDefinition, projectionFromHandlers, recapturePersistenceBaseline, reconstituteAggregateFromHistory, reconstituteAggregateFromSnapshot, recordDomainEvent, recordPendingEvents, removeEntityById, replaceEntityById, routeEventsToCommandOutbox, sameEntity, sameVersion, specification, toVersion, transitionDomainState, updateEntityById, vo, voEquals, voEqualsExcept, voValidated, voWithValidation, withCommit, withIdempotentCommit };
|
|
4354
|
+
export { type Aggregate, type AggregateAddress, type AggregateAddressMismatchOptions, type AggregateClass, type AggregateCommitToken, type AggregateConfig, AggregateDeletedError, AggregateNotFoundError, type AggregateNotFoundErrorOptions, type AggregatePersistence, type AggregatePersistenceWrite, type AggregateSnapshot, AggregateTrackingError, type AggregateTrackingFailure, type AggregateWriteIntent, type AggregateWriteRegistration, type AnyDomainEvent, type AnyUncommittedDomainEvent, type AppendOnlyWriteRegistration, CapabilityRegistryConflictError, type ClockFactory, type Command, CommandBus, type CommandBusOptions, type CommandCommitOriginCandidate, type CommandHandler, type CommandMessageContent, type CommandMessageRelationships, type CommandOutboxCommitCandidate, type CommandOutboxMapper, type CommandOutboxWriter, type CommitEnrollment, type CommitEnrollmentOptions, CommitError, type CommitPosition, type CommittedDomainEvent, type CompatibleRepositoryDefinitions, ConcurrencyConflictError, type ConcurrencyConflictErrorOptions, type CreateDomainEventFromFactsOptions, type CreateDomainEventOptions, type CreateDomainEventStampOptions, type CreateUncommittedDomainEventOptions, type DeadLetterDeadline, type DeadLetterRecord, DeadlineProcessor, type DeadlineProcessorObservers, type DeadlineProcessorOptions, type DeadlineStore, type DeepEqualExceptOptions, type DeepOmitKey, type DeepOmitOptions, type DeepOmitPathSegment, type DeliveryFailureAssessment, type DeliveryFailureClassifier, type DeliveryFailureKind, DirectStateMutationError, type DispatchTrackingOutbox, DomainError, type DomainErrorClass, type DomainEvent, type DomainEventFactory, type DomainEventFactoryOptions, type DomainEventStamp, type DomainEventStampFactory, type DomainEventStampProvider, type DomainEventValidationCode, DomainEventValidationError, type DomainEventValidationField, type DomainMachineDefinition, type DomainMachineDefinitionAnalysis, type DomainMachineDefinitionDiagnostic, type DomainMachineInput, type DomainMachineReadonly, type DomainMachineSnapshot, type DomainMachineTransitionDescription, DomainStateMachine, type DomainStateNode, type DomainTransition, DomainTransitionGuardRejectedError, type DomainTransitionGuardResult, type DomainTransitionOutcome, type DomainTransitionResult, type DueDeadline, DuplicateAggregateError, type DuplicateAggregateErrorOptions, DuplicateEventIdError, DuplicateHandlerRegistrationError, type DuplicateHandlerRegistrationErrorOptions, type DurableCommandMessage, Entity, type EntityConfig, ErrorMapperFailedError, type ErrorMapperFailedErrorOptions, type EventBus, EventBusClosedError, EventBusImpl, type EventBusObservers, type EventBusOptions, type EventCommitCandidate, type EventCommitCandidatePosition, type EventHandler, EventHarvestError, type EventIdFactory, type EventMetadata, EventSourcedAggregate, type EventStore, type EventStoreAppendOptions, type ExecutionContext, FoldReturnedNoStateError, ForeignEventError, type HandlerFailureReport, HostileStateKeyError, type ICommandBus, type IEntity, type IQueryBus, type IValueObject, type Id, type IdGenerator, type IdempotencyClaim, type IdempotencyClaimHandle, IdempotencyClaimLostError, type IdempotencyClaimLostErrorOptions, IdempotencyCompletionWithoutClaimError, IdempotencyInFlightError, type IdempotencyInFlightErrorOptions, IdempotencyKeyReuseError, type IdempotencyKeyReuseErrorOptions, type IdempotencyLease, type IdempotencyOperationErrorContext, type IdempotencyReconciliation, type IdempotencyReconciliationDecision, IdempotencyReconciliationRequiredError, type IdempotencyReconciliationRequiredErrorOptions, type IdempotencyStore, type IdempotentCommitRequest, type IdempotentCommitResult, type IdempotentExecution, type Identifiable, IdentityMap, InMemoryCapacityExceededError, type InMemoryCapacityExceededErrorOptions, InMemoryDeadlineStore, type InMemoryDeadlineStoreOptions, InMemoryEventStore, type InMemoryEventStoreOptions, InMemoryIdempotencyStore, type InMemoryIdempotencyStoreOptions, InMemoryOutbox, type InMemoryOutboxOptions, InMemoryProjectionCheckpointStore, type InMemoryProjectionCheckpointStoreOptions, InMemorySnapshotStore, type InMemorySnapshotStoreOptions, InfrastructureError, type IntegrationMessage, type IntegrationMessageContent, type IntegrationMessageMapper, type IntegrationMessageRelationships, InvalidCommandMessageError, InvalidDomainMachineContextError, InvalidDomainMachineDefinitionError, InvalidDomainMachineInputError, InvalidDomainMachineSnapshotError, InvalidDomainTransitionError, InvalidDomainTransitionGuardResultError, InvalidDomainTransitionResultError, InvalidIntegrationMessageError, InvalidRepositoryAdapterError, InvalidRepositoryDefinitionError, InvalidVersionError, type JsonObject, type JsonPrimitive, type JsonValue, type KitErrorCode, type KitErrorOptions, MisaddressedEventError, MissingEntityIdError, MissingFoldError, MissingHandlerError, NestedUnitOfWorkError, NonProgressingEventStreamPageError, type NonProgressingEventStreamPageErrorOptions, type OnceOptions, type Outbox, OutboxDispatcher, type OutboxDispatcherObservers, type OutboxDispatcherOptions, type OutboxRecord, type OutboxSink, type OutboxWriter, type PendingDomainEvent, PendingEventBatchMismatchError, PendingEventLimitExceededError, type PendingEventLimitExceededErrorOptions, type PersistenceBaseline, type PersistenceChanges, type PersistenceLifecycle, type PersistenceModel, type PhysicalRemovalRegistration, type PreparedDomainMachineDefinition, type ProjectOptions, type Projection, type ProjectionBatchResult, type ProjectionCheckpoint, type ProjectionCheckpointStore, type ProjectionEventHandler, type ProjectionFromHandlersOptions, ProjectionGapError, type ProjectionHandlers, ProjectionIdentityViolationError, ProjectionOrderViolationError, type ProjectionPosition, ProjectionReceiptViolationError, Projector, type ProjectorOptions, type PublishAbortedReport, type PublishChainState, type PublishChainStore, PublishDepthExceededError, type PublishOptions, type PublishedCommand, type Query, QueryBus, type QueryBusOptions, type QueryHandler, type ReadStreamOptions, ReentrantDomainStateMachineEvaluationError, ReentrantEventRecordingError, ReplayHeadMismatchError, type ReplayHeadMismatchErrorOptions, type ReplayableAggregate, type RepositoriesOf, type Repository, type RepositoryDefinition, type RepositoryDefinitionOptions, RepositoryErrorMappingFailedError, type RepositoryTracking, type RetryPolicy, RetryingTransactionScope, RollbackError, type RunOptions, type SharedDomainEventStampOptions, SnapshotCorruptedError, type SnapshotModel, SnapshotSchemaMismatchError, type SnapshotSchemaMismatchErrorOptions, type SnapshotStore, SnapshotTimeValidationError, SnapshotVersionNotRestoredError, type SnapshotVersionNotRestoredErrorOptions, Specification, type SpecificationComposite, StateStoredAggregate, type StateValidator, type StreamReadResult, type SubscriptionThresholdReport, TransactionClosedError, type TransactionScope, type TransactionalOptions, type UncommittedDomainEvent, type UncommittedDomainEventOf, UnenrolledChangesError, UnitOfWork, type UnitOfWorkContext, type UnitOfWorkDeps, type UnitOfWorkIdentityMap, UnmanagedInstanceError, UnmintedEventError, UnprojectableEventError, UnregisteredHandlerError, type UnregisteredHandlerErrorOptions, UnreplayableAggregateError, type VO, ValueObject, type Version, type WithCommitDeps, type WithCommitWorkResult, type WithIdempotentCommitDeps, analyzeDomainMachineDefinition, canTransitionDomainState, captureAggregateSnapshot, capturePersistenceBaseline, copyMetadata, createDomainEvent, createDomainEventFactory, createDomainEventFromFacts, createInitialDomainMachineSnapshot, createIntegrationMessage, createUncommittedDomainEvent, decodeIntegrationMessage, deepEqual, deepEqualExcept, deepFreeze, deepOmit, defaultDomainEventFactory, defineRepository, defineSnapshotModel, derivePersistenceChanges, detachState, domainErrorToResult, encodeIntegrationMessage, entityIds, eventBusSink, findEntityById, freezeShallow, hasEntityId, ignoreProjectionEvent, insertPersistenceBaseline, integrationMessageToCommittedEvent, isDomainErrorLike, isInfrastructureErrorLike, isPositionAfter, mergeMetadata, outboxWriterAcceptingEventLoss, persistenceProjectionDrifted, prepareDomainMachineDefinition, projectionFromHandlers, recapturePersistenceBaseline, reconstituteAggregateFromHistory, reconstituteAggregateFromSnapshot, recordDomainEvent, recordPendingEvents, removeEntityById, replaceEntityById, routeEventsToCommandOutbox, sameEntity, sameVersion, specification, toVersion, transitionDomainState, updateEntityById, vo, voEquals, voEqualsExcept, voValidated, voWithValidation, withCommit, withIdempotentCommit };
|
|
4278
4355
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -2212,18 +2212,18 @@ var AggregateTrackingError = class extends KitWiringError {
|
|
|
2212
2212
|
operation;
|
|
2213
2213
|
reason;
|
|
2214
2214
|
registeredIntent;
|
|
2215
|
-
constructor(aggregateId, operation, reason, registeredIntent) {
|
|
2216
|
-
super("AGGREGATE_TRACKING", trackingFailureMessage(aggregateId, operation, reason, registeredIntent));
|
|
2215
|
+
constructor(aggregateId, operation, reason, registeredIntent, options = {}) {
|
|
2216
|
+
super("AGGREGATE_TRACKING", trackingFailureMessage(aggregateId, operation, reason, registeredIntent, options));
|
|
2217
2217
|
this.aggregateId = aggregateId;
|
|
2218
2218
|
this.operation = operation;
|
|
2219
2219
|
this.reason = reason;
|
|
2220
2220
|
this.registeredIntent = registeredIntent;
|
|
2221
2221
|
}
|
|
2222
2222
|
};
|
|
2223
|
-
function trackingFailureMessage(aggregateId, operation, reason, registeredIntent) {
|
|
2223
|
+
function trackingFailureMessage(aggregateId, operation, reason, registeredIntent, options) {
|
|
2224
2224
|
switch (reason) {
|
|
2225
2225
|
case "not_loaded": return `Aggregate ${aggregateId} cannot be registered for ${operation}: it was not loaded into this unit of work. Load it through the repository before updating or removing it.`;
|
|
2226
|
-
case "loaded_as_new": return `Aggregate ${aggregateId} cannot be added as new because it was loaded by this unit of work. Use update for a loaded aggregate
|
|
2226
|
+
case "loaded_as_new": return `Aggregate ${aggregateId} cannot be added as new because it was loaded by this unit of work. ` + (options.appendOnly ? "Its repository is append-only, so a loaded aggregate is already persisted and must not change." : "Use update for a loaded aggregate.");
|
|
2227
2227
|
case "different_repository": return `Aggregate ${aggregateId} cannot be registered for ${operation} through a different repository in the same unit of work. One aggregate instance must remain owned by the repository definition that first tracked it.`;
|
|
2228
2228
|
case "conflicting_intent": return `Aggregate ${aggregateId} is already registered for ${registeredIntent ?? "another write"}; ${operation} would create conflicting persistence intent in one unit of work. Decide the final lifecycle outcome before registering it.`;
|
|
2229
2229
|
case "mutated_after_registration": return `Aggregate ${aggregateId} changed after ${registeredIntent ?? "write"} was registered. Make domain decisions first and call add, update, or remove last so persisted state and recorded events cannot diverge.`;
|
|
@@ -2386,9 +2386,14 @@ function defineForwardedRepositoryProperty(state, property, descriptor) {
|
|
|
2386
2386
|
});
|
|
2387
2387
|
state.forwardedOwnProperties.add(property);
|
|
2388
2388
|
}
|
|
2389
|
+
function installedLifecycleOperations(definition) {
|
|
2390
|
+
const operations = ["add"];
|
|
2391
|
+
if (!definition.appendOnly) operations.push("update");
|
|
2392
|
+
if (definition.physicalRemoval) operations.push("remove");
|
|
2393
|
+
return operations;
|
|
2394
|
+
}
|
|
2389
2395
|
function installRepositoryLifecycleOperations(state) {
|
|
2390
|
-
const
|
|
2391
|
-
for (const operation of operations) {
|
|
2396
|
+
for (const operation of installedLifecycleOperations(state.definition)) {
|
|
2392
2397
|
state.writes.add(operation);
|
|
2393
2398
|
Object.defineProperty(state.target, operation, {
|
|
2394
2399
|
configurable: false,
|
|
@@ -2414,13 +2419,13 @@ function createRepositoryFacadeHandler(state) {
|
|
|
2414
2419
|
if (!hasMemberBelowObjectPrototype(target, property) && !hasMemberBelowObjectPrototype(state.source, property)) return Reflect.get(target, property, receiver);
|
|
2415
2420
|
state.session.assertOpen(repositoryOperationName(property));
|
|
2416
2421
|
if (Reflect.getOwnPropertyDescriptor(target, property)) return Reflect.get(target, property, receiver);
|
|
2417
|
-
if (property
|
|
2422
|
+
if (isRepositoryLifecycleOperation(property)) return void 0;
|
|
2418
2423
|
return readRepositorySource(state, property);
|
|
2419
2424
|
},
|
|
2420
2425
|
set: (target, property, value, receiver) => setRepositoryFacadeProperty(state, target, property, value, receiver),
|
|
2421
2426
|
has: (target, property) => {
|
|
2422
2427
|
state.session.assertOpen(repositoryOperationName(property));
|
|
2423
|
-
return state.writes.has(property) || property
|
|
2428
|
+
return state.writes.has(property) || !isRepositoryLifecycleOperation(property) && (Reflect.has(target, property) || Reflect.has(state.source, property));
|
|
2424
2429
|
},
|
|
2425
2430
|
defineProperty: (target, property, descriptor) => defineRepositoryFacadeProperty(state, target, property, descriptor),
|
|
2426
2431
|
deleteProperty: (target, property) => deleteRepositoryFacadeProperty(state, target, property)
|
|
@@ -2771,7 +2776,7 @@ var Session = class {
|
|
|
2771
2776
|
this.assertNotRemoved(aggregate, definition);
|
|
2772
2777
|
const existing = this._trackingByAggregate.get(aggregate);
|
|
2773
2778
|
if (existing && existing.definition !== definition) throw new AggregateTrackingError(String(aggregate.id), "add", "different_repository", existing.registration?.intent);
|
|
2774
|
-
if (existing?.lifecycle === "loaded") throw new AggregateTrackingError(String(aggregate.id), "add", "loaded_as_new", existing.registration?.intent);
|
|
2779
|
+
if (existing?.lifecycle === "loaded") throw new AggregateTrackingError(String(aggregate.id), "add", "loaded_as_new", existing.registration?.intent, { appendOnly: definition.appendOnly === true });
|
|
2775
2780
|
let entry = existing;
|
|
2776
2781
|
const newlyTracked = !entry;
|
|
2777
2782
|
if (!entry) {
|
|
@@ -2888,12 +2893,12 @@ var Session = class {
|
|
|
2888
2893
|
this.assertUnchangedAfterRegistration(entry);
|
|
2889
2894
|
continue;
|
|
2890
2895
|
}
|
|
2891
|
-
if (entry.lifecycle === "loaded" && (entry.aggregate.version !== entry.expectedVersion || persistenceProjectionDrifted(entry.baseline, entry.aggregate))) throw new UnenrolledChangesError(String(entry.aggregate.id));
|
|
2896
|
+
if (entry.lifecycle === "loaded" && (entry.aggregate.version !== entry.expectedVersion || persistenceProjectionDrifted(entry.baseline, entry.aggregate))) throw new UnenrolledChangesError(String(entry.aggregate.id), { appendOnly: entry.definition.appendOnly === true });
|
|
2892
2897
|
}
|
|
2893
2898
|
for (const instance of this._identityMap.instancesWithNewPendingEvents()) {
|
|
2894
2899
|
if (instance !== null && typeof instance === "object" && this.registrationOf(instance) !== void 0) continue;
|
|
2895
2900
|
const id = instance.id;
|
|
2896
|
-
throw new UnenrolledChangesError(String(id));
|
|
2901
|
+
throw new UnenrolledChangesError(String(id), { appendOnly: this._trackingByAggregate.get(instance)?.definition.appendOnly === true });
|
|
2897
2902
|
}
|
|
2898
2903
|
}
|
|
2899
2904
|
/** Flushes every registered receipt in deterministic registration order. */
|
|
@@ -2954,20 +2959,7 @@ function mapRepositoryPersistenceError(definition, error, write) {
|
|
|
2954
2959
|
|
|
2955
2960
|
//#endregion
|
|
2956
2961
|
//#region src/application/unit-of-work/unit-of-work.ts
|
|
2957
|
-
const repositoryDefinitionBrand = Symbol.for("@shirudo/ddd-kit/repository-definition/
|
|
2958
|
-
/**
|
|
2959
|
-
* Defines repository wiring for an application-owned driven port.
|
|
2960
|
-
*
|
|
2961
|
-
* The first call makes the port explicit; the second infers the transaction,
|
|
2962
|
-
* aggregate, persistence, event, and removal types from the adapter wiring.
|
|
2963
|
-
* The port must declare `add` and `update`; if it declares `remove`, the
|
|
2964
|
-
* definition must set `physicalRemoval: true`. The adapter created by the
|
|
2965
|
-
* definition implements only the remaining methods because lifecycle writes
|
|
2966
|
-
* are installed by the Unit of Work.
|
|
2967
|
-
* The returned definition is the only form accepted by {@link UnitOfWork}; a
|
|
2968
|
-
* raw adapter-shaped object cannot silently turn its concrete surface into the
|
|
2969
|
-
* application contract.
|
|
2970
|
-
*/
|
|
2962
|
+
const repositoryDefinitionBrand = Symbol.for("@shirudo/ddd-kit/repository-definition/v2");
|
|
2971
2963
|
function assertRepositoryDefinitionMembers(definition) {
|
|
2972
2964
|
for (const key of [
|
|
2973
2965
|
"create",
|
|
@@ -2977,6 +2969,21 @@ function assertRepositoryDefinitionMembers(definition) {
|
|
|
2977
2969
|
if (typeof definition.aggregate !== "function") throw new TypeError("defineRepository: \"aggregate\" is missing or not a class reference on the definition. Pass a plain object literal with own enumerable properties.");
|
|
2978
2970
|
if (definition.persistence === null || typeof definition.persistence !== "object") throw new TypeError("defineRepository: \"persistence\" is missing or not a PersistenceModel on the definition. Pass a plain object literal with own enumerable properties.");
|
|
2979
2971
|
}
|
|
2972
|
+
/**
|
|
2973
|
+
* Defines repository wiring for an application-owned driven port.
|
|
2974
|
+
*
|
|
2975
|
+
* The first call makes the port explicit; the second infers the transaction,
|
|
2976
|
+
* aggregate, persistence, event, and lifecycle types from the adapter wiring.
|
|
2977
|
+
* The port must declare `add` for the aggregate. It declares `update` unless
|
|
2978
|
+
* the definition sets `appendOnly: true`. If it declares `remove`, the
|
|
2979
|
+
* definition must set `physicalRemoval: true`. A violated constraint fails
|
|
2980
|
+
* the call with a compiler error that names the constraint. The adapter
|
|
2981
|
+
* created by the definition implements only the remaining methods because
|
|
2982
|
+
* lifecycle writes are installed by the Unit of Work.
|
|
2983
|
+
* The returned definition is the only form accepted by {@link UnitOfWork}; a
|
|
2984
|
+
* raw adapter-shaped object cannot silently turn its concrete surface into the
|
|
2985
|
+
* application contract.
|
|
2986
|
+
*/
|
|
2980
2987
|
function defineRepository() {
|
|
2981
2988
|
const builder = (definition) => {
|
|
2982
2989
|
const branded = { ...definition };
|