@shirudo/ddd-kit 2.0.0 → 2.2.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.
@@ -36,7 +36,7 @@ function errorName(error) {
36
36
  }
37
37
  __name(errorName, "errorName");
38
38
  function hasPublicIssues(error) {
39
- return typeof error.publicIssues === "function";
39
+ return typeof error === "object" && error !== null && typeof error.publicIssues === "function";
40
40
  }
41
41
  __name(hasPublicIssues, "hasPublicIssues");
42
42
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/presentation/public-error-view.ts"],"names":[],"mappings":";;;;AAaA,IAAM,mBAAA,GAAwD;AAAA,EAC7D,sBAAA,EAAwB,4CAAA;AAAA,EACxB,wBAAA,EACC,4EAAA;AAAA,EACD,uBAAA,EAAyB;AAC1B,CAAA;AAGA,IAAM,kBAAA,GAAqB,gCAAA;AAE3B,IAAM,aAAA,GAAgB,gBAAA;AACtB,IAAM,gBAAA,GAAmB,+BAAA;AAEzB,IAAM,cAAA,GAAiB,IAAA;AAoDhB,SAAS,iBAAA,CACf,KAAA,EACA,OAAA,GAAkC,EAAC,EACO;AAC1C,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,cAAA;AACjC,EAAA,MAAM,IAAA,GAAO,UAAU,KAAK,CAAA;AAK5B,EAAA,IAAI,eAAA,CAAgB,KAAK,CAAA,EAAG;AAC3B,IAAA,OAAO;AAAA,MACN,MAAM,IAAA,IAAQ,mBAAA;AAAA,MACd,OAAA,EAAS,kBAAA;AAAA,MACT,MAAA;AAAA,MACA,OAAA,EAAS,EAAE,MAAA,EAAQ,KAAA,CAAM,cAAa;AAAE,KACzC;AAAA,EACD;AAEA,EAAA,MAAM,OAAA,GAAU,IAAA,GAAO,mBAAA,CAAoB,IAAI,CAAA,GAAI,MAAA;AACnD,EAAA,IAAI,YAAY,MAAA,EAAW;AAC1B,IAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,OAAA,EAAS,kBAAkB,MAAA,EAAO;AAAA,EACjE;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAgB,OAAA,EAAS,MAAA,EAAO;AAChD;AAzBgB,MAAA,CAAA,iBAAA,EAAA,mBAAA,CAAA;AA4BhB,SAAS,UAAU,KAAA,EAAoC;AACtD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,MAAM,OAAO,MAAA;AACxD,EAAA,MAAM,EAAE,MAAK,GAAI,KAAA;AACjB,EAAA,OAAO,OAAO,IAAA,KAAS,QAAA,GAAW,IAAA,GAAO,MAAA;AAC1C;AAJS,MAAA,CAAA,SAAA,EAAA,WAAA,CAAA;AAOT,SAAS,gBACR,KAAA,EAC6C;AAC7C,EAAA,OACC,OAAQ,MAAqC,YAAA,KAAiB,UAAA;AAEhE;AANS,MAAA,CAAA,eAAA,EAAA,iBAAA,CAAA","file":"presentation.js","sourcesContent":["import type { PublicIssue } from \"@shirudo/base-error\";\nimport type { PublicErrorView } from \"@shirudo/base-error/presentation\";\n\n/**\n * Safe, client-facing English messages for the kit's known errors. They carry\n * no occurrence data (no id, version, or technical detail), so they never leak\n * across the boundary. This is the transport-neutral *presentation* layer: the\n * technical error classes stay free of these strings (removed from the core in\n * 2.0); here is their opt-in home.\n *\n * Keyed by the kit's pinned `error.name` (stable across minification and\n * duplicate installs), so matching does not depend on `instanceof`.\n */\nconst KIT_PUBLIC_MESSAGES: Readonly<Record<string, string>> = {\n\tAggregateNotFoundError: \"The requested resource could not be found.\",\n\tConcurrencyConflictError:\n\t\t\"The resource was modified by another request. Please reload and try again.\",\n\tDuplicateAggregateError: \"The resource already exists.\",\n};\n\n/** Message for a `ValidationError`, which is detected by capability, not name. */\nconst VALIDATION_MESSAGE = \"The submitted data is invalid.\";\n/** Public code and message used for any unmapped or non-kit error. */\nconst FALLBACK_CODE = \"INTERNAL_ERROR\";\nconst FALLBACK_MESSAGE = \"An unexpected error occurred.\";\n/** BCP 47 locale the built-in messages are written in. */\nconst DEFAULT_LOCALE = \"en\";\n\n/** Details shape carried by the view for a {@link toPublicErrorView} result. */\nexport interface PublicErrorViewDetails {\n\t/** Whitelisted field issues, present only for a `ValidationError`. */\n\treadonly issues: readonly PublicIssue[];\n}\n\n/** Options for {@link toPublicErrorView}. */\nexport interface PublicErrorViewOptions {\n\t/**\n\t * BCP 47 locale tag stamped on the view. The built-in messages are English;\n\t * pass a locale only when you supply your own message resolution upstream.\n\t * Default `\"en\"`.\n\t */\n\tlocale?: string;\n}\n\n/**\n * Maps a kit error (or any caught value) to a base-error\n * {@link PublicErrorView}: a **transport-neutral**, client-safe representation\n * (`code`, `message`, `locale`, optional `details`). It is deliberately *not* a\n * transport adapter: it carries no HTTP status, header, or exit code, because\n * those are the consumer's concern. Feed the view into base-error's\n * `defineProblemDetailsAdapter` (HTTP / RFC 9457), a gRPC status mapper, or a\n * CLI exit-code table, whichever boundary you are at.\n *\n * Total over `unknown`: an unmapped or non-kit value degrades to a generic\n * `INTERNAL_ERROR` view rather than leaking the technical message or throwing.\n * The kit's class-based errors match by their pinned `error.name`, so it\n * survives minification and duplicate installs (no `instanceof`). A\n * `ValidationError` is detected by its `publicIssues()` whitelist (base-error\n * names it after its code), and those issues ride along in `details.issues`.\n *\n * For richer, multi-locale messages, register the kit's errors in a base-error\n * `PublicErrorRegistry` and use `PublicErrorPresenter` instead; this helper is\n * the lean, single-locale default.\n *\n * @example\n * ```ts\n * import { toPublicErrorView } from \"@shirudo/ddd-kit/presentation\";\n * import { defineProblemDetailsAdapter } from \"@shirudo/base-error/problem-details\";\n *\n * const adapter = defineProblemDetailsAdapter({\n * definitions: { AggregateNotFoundError: { type: \"about:blank\", status: 404 } },\n * fallback: { type: \"about:blank\", status: 500 },\n * });\n *\n * const { body, status } = adapter.map(toPublicErrorView(error));\n * return Response.json(body, { status });\n * ```\n */\nexport function toPublicErrorView(\n\terror: unknown,\n\toptions: PublicErrorViewOptions = {},\n): PublicErrorView<PublicErrorViewDetails> {\n\tconst locale = options.locale ?? DEFAULT_LOCALE;\n\tconst name = errorName(error);\n\n\t// ValidationError (and subclasses) are detected by the publicIssues()\n\t// whitelist, not by name: base-error names a ValidationError after its code\n\t// (\"VALIDATION_FAILED\"), so a name match would miss it.\n\tif (hasPublicIssues(error)) {\n\t\treturn {\n\t\t\tcode: name ?? \"VALIDATION_FAILED\",\n\t\t\tmessage: VALIDATION_MESSAGE,\n\t\t\tlocale,\n\t\t\tdetails: { issues: error.publicIssues() },\n\t\t};\n\t}\n\n\tconst message = name ? KIT_PUBLIC_MESSAGES[name] : undefined;\n\tif (message === undefined) {\n\t\treturn { code: FALLBACK_CODE, message: FALLBACK_MESSAGE, locale };\n\t}\n\n\treturn { code: name as string, message, locale };\n}\n\n/** Reads a string `name` off a caught value without assuming it is an Error. */\nfunction errorName(error: unknown): string | undefined {\n\tif (typeof error !== \"object\" || error === null) return undefined;\n\tconst { name } = error as { name?: unknown };\n\treturn typeof name === \"string\" ? name : undefined;\n}\n\n/** Duck-types base-error's `ValidationError.publicIssues()` accessor. */\nfunction hasPublicIssues(\n\terror: unknown,\n): error is { publicIssues(): PublicIssue[] } {\n\treturn (\n\t\ttypeof (error as { publicIssues?: unknown }).publicIssues === \"function\"\n\t);\n}\n"]}
1
+ {"version":3,"sources":["../src/presentation/public-error-view.ts"],"names":[],"mappings":";;;;AAaA,IAAM,mBAAA,GAAwD;AAAA,EAC7D,sBAAA,EAAwB,4CAAA;AAAA,EACxB,wBAAA,EACC,4EAAA;AAAA,EACD,uBAAA,EAAyB;AAC1B,CAAA;AAGA,IAAM,kBAAA,GAAqB,gCAAA;AAE3B,IAAM,aAAA,GAAgB,gBAAA;AACtB,IAAM,gBAAA,GAAmB,+BAAA;AAEzB,IAAM,cAAA,GAAiB,IAAA;AAoDhB,SAAS,iBAAA,CACf,KAAA,EACA,OAAA,GAAkC,EAAC,EACO;AAC1C,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,cAAA;AACjC,EAAA,MAAM,IAAA,GAAO,UAAU,KAAK,CAAA;AAK5B,EAAA,IAAI,eAAA,CAAgB,KAAK,CAAA,EAAG;AAC3B,IAAA,OAAO;AAAA,MACN,MAAM,IAAA,IAAQ,mBAAA;AAAA,MACd,OAAA,EAAS,kBAAA;AAAA,MACT,MAAA;AAAA,MACA,OAAA,EAAS,EAAE,MAAA,EAAQ,KAAA,CAAM,cAAa;AAAE,KACzC;AAAA,EACD;AAEA,EAAA,MAAM,OAAA,GAAU,IAAA,GAAO,mBAAA,CAAoB,IAAI,CAAA,GAAI,MAAA;AACnD,EAAA,IAAI,YAAY,MAAA,EAAW;AAC1B,IAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,OAAA,EAAS,kBAAkB,MAAA,EAAO;AAAA,EACjE;AAEA,EAAA,OAAO,EAAE,IAAA,EAAM,IAAA,EAAgB,OAAA,EAAS,MAAA,EAAO;AAChD;AAzBgB,MAAA,CAAA,iBAAA,EAAA,mBAAA,CAAA;AA4BhB,SAAS,UAAU,KAAA,EAAoC;AACtD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,MAAM,OAAO,MAAA;AACxD,EAAA,MAAM,EAAE,MAAK,GAAI,KAAA;AACjB,EAAA,OAAO,OAAO,IAAA,KAAS,QAAA,GAAW,IAAA,GAAO,MAAA;AAC1C;AAJS,MAAA,CAAA,SAAA,EAAA,WAAA,CAAA;AAWT,SAAS,gBACR,KAAA,EAC6C;AAC7C,EAAA,OACC,OAAO,KAAA,KAAU,QAAA,IACjB,UAAU,IAAA,IACV,OAAQ,MAAqC,YAAA,KAAiB,UAAA;AAEhE;AARS,MAAA,CAAA,eAAA,EAAA,iBAAA,CAAA","file":"presentation.js","sourcesContent":["import type { PublicIssue } from \"@shirudo/base-error\";\nimport type { PublicErrorView } from \"@shirudo/base-error/presentation\";\n\n/**\n * Safe, client-facing English messages for the kit's known errors. They carry\n * no occurrence data (no id, version, or technical detail), so they never leak\n * across the boundary. This is the transport-neutral *presentation* layer: the\n * technical error classes stay free of these strings (removed from the core in\n * 2.0); here is their opt-in home.\n *\n * Keyed by the kit's pinned `error.name` (stable across minification and\n * duplicate installs), so matching does not depend on `instanceof`.\n */\nconst KIT_PUBLIC_MESSAGES: Readonly<Record<string, string>> = {\n\tAggregateNotFoundError: \"The requested resource could not be found.\",\n\tConcurrencyConflictError:\n\t\t\"The resource was modified by another request. Please reload and try again.\",\n\tDuplicateAggregateError: \"The resource already exists.\",\n};\n\n/** Message for a `ValidationError`, which is detected by capability, not name. */\nconst VALIDATION_MESSAGE = \"The submitted data is invalid.\";\n/** Public code and message used for any unmapped or non-kit error. */\nconst FALLBACK_CODE = \"INTERNAL_ERROR\";\nconst FALLBACK_MESSAGE = \"An unexpected error occurred.\";\n/** BCP 47 locale the built-in messages are written in. */\nconst DEFAULT_LOCALE = \"en\";\n\n/** Details shape carried by the view for a {@link toPublicErrorView} result. */\nexport interface PublicErrorViewDetails {\n\t/** Whitelisted field issues, present only for a `ValidationError`. */\n\treadonly issues: readonly PublicIssue[];\n}\n\n/** Options for {@link toPublicErrorView}. */\nexport interface PublicErrorViewOptions {\n\t/**\n\t * BCP 47 locale tag stamped on the view. The built-in messages are English;\n\t * pass a locale only when you supply your own message resolution upstream.\n\t * Default `\"en\"`.\n\t */\n\tlocale?: string;\n}\n\n/**\n * Maps a kit error (or any caught value) to a base-error\n * {@link PublicErrorView}: a **transport-neutral**, client-safe representation\n * (`code`, `message`, `locale`, optional `details`). It is deliberately *not* a\n * transport adapter: it carries no HTTP status, header, or exit code, because\n * those are the consumer's concern. Feed the view into base-error's\n * `defineProblemDetailsAdapter` (HTTP / RFC 9457), a gRPC status mapper, or a\n * CLI exit-code table, whichever boundary you are at.\n *\n * Total over `unknown`: an unmapped or non-kit value degrades to a generic\n * `INTERNAL_ERROR` view rather than leaking the technical message or throwing.\n * The kit's class-based errors match by their pinned `error.name`, so it\n * survives minification and duplicate installs (no `instanceof`). A\n * `ValidationError` is detected by its `publicIssues()` whitelist (base-error\n * names it after its code), and those issues ride along in `details.issues`.\n *\n * For richer, multi-locale messages, register the kit's errors in a base-error\n * `PublicErrorRegistry` and use `PublicErrorPresenter` instead; this helper is\n * the lean, single-locale default.\n *\n * @example\n * ```ts\n * import { toPublicErrorView } from \"@shirudo/ddd-kit/presentation\";\n * import { defineProblemDetailsAdapter } from \"@shirudo/base-error/problem-details\";\n *\n * const adapter = defineProblemDetailsAdapter({\n * definitions: { AggregateNotFoundError: { type: \"about:blank\", status: 404 } },\n * fallback: { type: \"about:blank\", status: 500 },\n * });\n *\n * const { body, status } = adapter.map(toPublicErrorView(error));\n * return Response.json(body, { status });\n * ```\n */\nexport function toPublicErrorView(\n\terror: unknown,\n\toptions: PublicErrorViewOptions = {},\n): PublicErrorView<PublicErrorViewDetails> {\n\tconst locale = options.locale ?? DEFAULT_LOCALE;\n\tconst name = errorName(error);\n\n\t// ValidationError (and subclasses) are detected by the publicIssues()\n\t// whitelist, not by name: base-error names a ValidationError after its code\n\t// (\"VALIDATION_FAILED\"), so a name match would miss it.\n\tif (hasPublicIssues(error)) {\n\t\treturn {\n\t\t\tcode: name ?? \"VALIDATION_FAILED\",\n\t\t\tmessage: VALIDATION_MESSAGE,\n\t\t\tlocale,\n\t\t\tdetails: { issues: error.publicIssues() },\n\t\t};\n\t}\n\n\tconst message = name ? KIT_PUBLIC_MESSAGES[name] : undefined;\n\tif (message === undefined) {\n\t\treturn { code: FALLBACK_CODE, message: FALLBACK_MESSAGE, locale };\n\t}\n\n\treturn { code: name as string, message, locale };\n}\n\n/** Reads a string `name` off a caught value without assuming it is an Error. */\nfunction errorName(error: unknown): string | undefined {\n\tif (typeof error !== \"object\" || error === null) return undefined;\n\tconst { name } = error as { name?: unknown };\n\treturn typeof name === \"string\" ? name : undefined;\n}\n\n/**\n * Duck-types base-error's `ValidationError.publicIssues()` accessor. The\n * null/object guard keeps `toPublicErrorView` total: a thrown `null` or\n * `undefined` must degrade to the fallback view, not crash the presenter.\n */\nfunction hasPublicIssues(\n\terror: unknown,\n): error is { publicIssues(): PublicIssue[] } {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\ttypeof (error as { publicIssues?: unknown }).publicIssues === \"function\"\n\t);\n}\n"]}
package/dist/testing.d.ts CHANGED
@@ -1,7 +1,129 @@
1
- import { I as IAggregateRoot, a as Id, A as AnyDomainEvent } from './aggregate-CePTINEt.js';
1
+ import { I as IAggregateRoot, a as Id, A as AnyDomainEvent } from './aggregate-DFi6HlEh.js';
2
2
  import '@shirudo/result';
3
3
  import '@shirudo/base-error';
4
4
 
5
+ /**
6
+ * The repository surface the event-sourced contract suite exercises.
7
+ * Deliberately smaller than the state-stored `ContractRepository`: pure
8
+ * event-sourced aggregates rarely have a meaningful `delete` (the
9
+ * lifecycle ends with a `Closed` / `Terminated` event in the stream),
10
+ * so the suite does not require one.
11
+ */
12
+ interface EsContractRepository<TAgg extends IAggregateRoot<Id<string>, AnyDomainEvent>> {
13
+ getById(id: TAgg["id"]): Promise<TAgg | null>;
14
+ save(aggregate: TAgg): Promise<void>;
15
+ }
16
+ /**
17
+ * One isolated test environment: fresh event store, fresh outbox. The
18
+ * suite creates one per test and tears it down afterwards.
19
+ */
20
+ interface EsRepositoryContractEnvironment<TAgg extends IAggregateRoot<Id<string>, Evt>, Evt extends AnyDomainEvent = AnyDomainEvent> {
21
+ /**
22
+ * Execute one unit of work against the adapter under test. Wire this
23
+ * through your real `UnitOfWork` / `withCommit` setup: the commit
24
+ * boundary IS part of what the suite proves (outbox harvest,
25
+ * `markPersisted`, rollback purity).
26
+ */
27
+ run<R>(work: (ctx: {
28
+ repository: EsContractRepository<TAgg>;
29
+ }) => Promise<R>): Promise<R>;
30
+ /**
31
+ * All events currently persisted in the outbox (committed writes
32
+ * only; a rolled-back transaction's events must not appear here).
33
+ */
34
+ committedOutboxEvents(): Promise<ReadonlyArray<Evt>>;
35
+ /**
36
+ * The COMMITTED stream for the given aggregate id, in stream order,
37
+ * optionally only the events after `fromVersion` (the snapshot
38
+ * catch-up read). Implement this through your adapter's
39
+ * `EventStore.readStream` so the suite's ordering and slicing
40
+ * assertions exercise your real read path. A rolled-back
41
+ * transaction's events must not appear here.
42
+ */
43
+ committedStreamEvents(id: TAgg["id"], fromVersion?: number): Promise<ReadonlyArray<Evt>>;
44
+ /** Release connections, drop schemas, etc. Called in a finally. */
45
+ teardown?(): Promise<void>;
46
+ }
47
+ /**
48
+ * What an adapter supplies to run the event-sourced contract suite.
49
+ *
50
+ * The harness MUST provide isolation per environment. **For SQL-backed
51
+ * event stores this must run against a real database** (testcontainers
52
+ * or equivalent): the mandatory two-writer test proves YOUR
53
+ * expectedVersion guard, and an in-memory stand-in proves only itself.
54
+ *
55
+ * Aggregate arithmetic the suite relies on:
56
+ * - `createAggregate()` returns a fresh aggregate with exactly ONE
57
+ * applied creation event (version 1, `persistedVersion === undefined`).
58
+ * - `mutate()` applies exactly ONE event (+1 version).
59
+ */
60
+ interface EsRepositoryContractHarness<TAgg extends IAggregateRoot<Id<string>, Evt>, Evt extends AnyDomainEvent = AnyDomainEvent> {
61
+ createEnvironment(): Promise<EsRepositoryContractEnvironment<TAgg, Evt>>;
62
+ /**
63
+ * A brand-new aggregate: exactly one applied creation event, unique
64
+ * id, version 1, `persistedVersion === undefined`.
65
+ */
66
+ createAggregate(): TAgg;
67
+ /** Apply exactly ONE domain event via `apply()` (+1 version). */
68
+ mutate(aggregate: TAgg): void;
69
+ /**
70
+ * Optional: construct a NEW (never-persisted) aggregate carrying a
71
+ * SPECIFIC id, with its creation event applied. Enables the
72
+ * duplicate-create conflict test (two creators racing on one stream).
73
+ */
74
+ createAggregateWithId?(id: TAgg["id"]): TAgg;
75
+ /**
76
+ * Optional: a plain-data projection of the aggregate's state,
77
+ * compared with deep equality. Enables the state assertions in the
78
+ * mandatory and replay-equality tests. Must be roundtrip-stable
79
+ * across your store (see the state-stored harness JSDoc for the
80
+ * normalization checklist).
81
+ */
82
+ snapshotState?(aggregate: TAgg): unknown;
83
+ }
84
+ /** One named contract test; see the state-stored suite for the binding pattern. */
85
+ interface EsRepositoryContractTest {
86
+ name: string;
87
+ run: () => Promise<void>;
88
+ /** Present when the harness lacks the capability this test needs. */
89
+ skipped?: {
90
+ capability: string;
91
+ };
92
+ }
93
+ /**
94
+ * The event-sourced repository contract test suite: the proof that an
95
+ * adapter delivers what the kit's `EventStore` port and Unit of Work
96
+ * document. The kit is store-agnostic: the expectedVersion guard lives
97
+ * in YOUR adapter's append. That makes stream OCC a **repository
98
+ * contract, not a kit guarantee**; an adapter that has not passed this
99
+ * suite (against a real store, for SQL-backed adapters) has not
100
+ * demonstrated it.
101
+ *
102
+ * What each test proves:
103
+ * - The MANDATORY two-writer test proves your append's expectedVersion
104
+ * guard and its atomicity.
105
+ * - The replay/lifecycle tests prove your read path (fold order,
106
+ * identity map wiring) and the commit lifecycle (outbox harvest,
107
+ * `markPersisted`, rollback purity).
108
+ * - The duplicate-create and fromVersion tests prove the create race
109
+ * and the snapshot catch-up read.
110
+ *
111
+ * Error matching is by NAME along the `cause` chain, not `instanceof`
112
+ * (same rationale as the state-stored suite). Binding:
113
+ *
114
+ * ```ts
115
+ * for (const test of createEsRepositoryContractTests(harness)) {
116
+ * (test.skipped ? it.skip : it)(test.name, test.run);
117
+ * }
118
+ * ```
119
+ *
120
+ * **Known limitation:** like the state-stored suite, the two-writer
121
+ * test is sequential-deterministic; lock interaction and raw
122
+ * serialization failures (Postgres 40001) need adapter-specific tests
123
+ * on top.
124
+ */
125
+ declare function createEsRepositoryContractTests<TAgg extends IAggregateRoot<Id<string>, Evt>, Evt extends AnyDomainEvent = AnyDomainEvent>(harness: EsRepositoryContractHarness<TAgg, Evt>): EsRepositoryContractTest[];
126
+
5
127
  /**
6
128
  * The repository surface the contract suite exercises: the minimal
7
129
  * structural subset of the canonical `IUnitOfWorkRepository` (exported
@@ -249,4 +371,4 @@ interface RepositoryContractTest {
249
371
  */
250
372
  declare function createRepositoryContractTests<TAgg extends IAggregateRoot<Id<string>, Evt>, Evt extends AnyDomainEvent = AnyDomainEvent>(harness: RepositoryContractHarness<TAgg, Evt>): RepositoryContractTest[];
251
373
 
252
- export { type ContractRepository, type RepositoryContractEnvironment, type RepositoryContractHarness, type RepositoryContractTest, createRepositoryContractTests };
374
+ export { type ContractRepository, type EsContractRepository, type EsRepositoryContractEnvironment, type EsRepositoryContractHarness, type EsRepositoryContractTest, type RepositoryContractEnvironment, type RepositoryContractHarness, type RepositoryContractTest, createEsRepositoryContractTests, createRepositoryContractTests };