@danceroutine/tango-testing 1.11.1 → 1.11.2

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.
Files changed (90) hide show
  1. package/dist/{aDBClient-CH-ZcOaP.js → aDBClient-fMkIdR7p.js} +16 -7
  2. package/dist/aDBClient-fMkIdR7p.js.map +1 -0
  3. package/dist/assertions/index.d.ts +2 -4
  4. package/dist/assertions/index.js +2 -3
  5. package/dist/assertions-lsAd7fhA.js +15 -0
  6. package/dist/assertions-lsAd7fhA.js.map +1 -0
  7. package/dist/chunk-D7D4PA-g.js +13 -0
  8. package/dist/express/index.d.ts +2 -3
  9. package/dist/express/index.js +2 -3
  10. package/dist/{express-Czpfz_Ay.js → express-CH6_GAyC.js} +23 -15
  11. package/dist/express-CH6_GAyC.js.map +1 -0
  12. package/dist/factories/index.d.ts +2 -4
  13. package/dist/factories/index.js +2 -3
  14. package/dist/{factories-Cl_CAzbj.js → factories-qAJouv1I.js} +10 -8
  15. package/dist/factories-qAJouv1I.js.map +1 -0
  16. package/dist/index-49XmDOxW.d.ts +40 -0
  17. package/dist/index-B4H3wYuR.d.ts +325 -0
  18. package/dist/index-BCWo7zAn.d.ts +41 -0
  19. package/dist/index-CKVKW5j_.d.ts +15 -0
  20. package/dist/index-CnUPgs3G.d.ts +208 -0
  21. package/dist/index.d.ts +7 -19
  22. package/dist/index.js +8 -9
  23. package/dist/integration/index.d.ts +2 -18
  24. package/dist/integration/index.js +2 -4
  25. package/dist/{integration-CaRF_lF_.js → integration-CLzkacon.js} +99 -84
  26. package/dist/integration-CLzkacon.js.map +1 -0
  27. package/dist/mocks/index.d.ts +2 -20
  28. package/dist/mocks/index.js +3 -4
  29. package/dist/{mocks-BL_0iuAI.js → mocks-JyZwO-W4.js} +77 -65
  30. package/dist/mocks-JyZwO-W4.js.map +1 -0
  31. package/dist/vitest/index.d.ts +60 -3
  32. package/dist/vitest/index.js +119 -4
  33. package/dist/vitest/index.js.map +1 -0
  34. package/package.json +7 -7
  35. package/dist/aDBClient-CH-ZcOaP.js.map +0 -1
  36. package/dist/assertions/assertions.d.ts +0 -7
  37. package/dist/assertions-CCFZ53Y-.js +0 -15
  38. package/dist/assertions-CCFZ53Y-.js.map +0 -1
  39. package/dist/chunk-BkvOhyD0.js +0 -12
  40. package/dist/express/anExpressRequest.d.ts +0 -24
  41. package/dist/express/anExpressResponse.d.ts +0 -9
  42. package/dist/express-Czpfz_Ay.js.map +0 -1
  43. package/dist/factories/ModelDataFactory.d.ts +0 -33
  44. package/dist/factories-Cl_CAzbj.js.map +0 -1
  45. package/dist/integration/HarnessStrategyRegistry.d.ts +0 -25
  46. package/dist/integration/TestHarness.d.ts +0 -38
  47. package/dist/integration/anIntegrationHarness.d.ts +0 -5
  48. package/dist/integration/config.d.ts +0 -11
  49. package/dist/integration/conformance/index.d.ts +0 -1
  50. package/dist/integration/conformance/runDialectConformanceSuite.d.ts +0 -11
  51. package/dist/integration/domain/Dialect.d.ts +0 -5
  52. package/dist/integration/domain/HarnessStrategy.d.ts +0 -17
  53. package/dist/integration/domain/IntegrationHarness.d.ts +0 -22
  54. package/dist/integration/domain/ResetMode.d.ts +0 -6
  55. package/dist/integration/domain/index.d.ts +0 -7
  56. package/dist/integration/migrations/ApplyAndVerifyMigrations.d.ts +0 -16
  57. package/dist/integration/migrations/AssertMigrationPlan.d.ts +0 -9
  58. package/dist/integration/migrations/IntrospectSchema.d.ts +0 -5
  59. package/dist/integration/migrations/index.d.ts +0 -6
  60. package/dist/integration/orm/createModelQuerySetFixture.d.ts +0 -10
  61. package/dist/integration/orm/createQuerySetFixture.d.ts +0 -10
  62. package/dist/integration/orm/expectQueryResult.d.ts +0 -4
  63. package/dist/integration/orm/index.d.ts +0 -7
  64. package/dist/integration/orm/seedTable.d.ts +0 -5
  65. package/dist/integration/runtime/aTangoConfig.d.ts +0 -9
  66. package/dist/integration/runtime/aTangoRuntime.d.ts +0 -6
  67. package/dist/integration/runtime/index.d.ts +0 -7
  68. package/dist/integration/runtime/setupTestTangoRuntime.d.ts +0 -6
  69. package/dist/integration/smoke/AppProcessHarness.d.ts +0 -83
  70. package/dist/integration/smoke/index.d.ts +0 -4
  71. package/dist/integration/strategies/PostgresHarnessStrategy.d.ts +0 -19
  72. package/dist/integration/strategies/SqliteHarnessStrategy.d.ts +0 -19
  73. package/dist/integration-CaRF_lF_.js.map +0 -1
  74. package/dist/mocks/DBClient.d.ts +0 -1
  75. package/dist/mocks/MockQuerySetResult.d.ts +0 -6
  76. package/dist/mocks/aDBClient.d.ts +0 -24
  77. package/dist/mocks/aManager.d.ts +0 -20
  78. package/dist/mocks/aManyToManyRelatedManager.d.ts +0 -52
  79. package/dist/mocks/aModelQuerySet.d.ts +0 -8
  80. package/dist/mocks/aQueryExecutor.d.ts +0 -16
  81. package/dist/mocks/aQueryResult.d.ts +0 -9
  82. package/dist/mocks/aQuerySet.d.ts +0 -5
  83. package/dist/mocks/aRelationMeta.d.ts +0 -20
  84. package/dist/mocks/aRequestContext.d.ts +0 -22
  85. package/dist/mocks/anAdapter.d.ts +0 -13
  86. package/dist/mocks-BL_0iuAI.js.map +0 -1
  87. package/dist/vitest/registerVitestTango.d.ts +0 -46
  88. package/dist/vitest/withGlobalTestApi.d.ts +0 -7
  89. package/dist/vitest-BqZmULOa.js +0 -111
  90. package/dist/vitest-BqZmULOa.js.map +0 -1
@@ -1,19 +1,22 @@
1
- import { __export } from "./chunk-BkvOhyD0.js";
2
- import { aDBClient, anAdapter } from "./aDBClient-CH-ZcOaP.js";
3
- import { ManyToManyRelatedManager, ModelQuerySet as QuerySetClass } from "@danceroutine/tango-orm";
4
- import { vi, vi as vi$1, vi as vi$2, vi as vi$3 } from "vitest";
5
- import { QueryResult as QueryResultClass } from "@danceroutine/tango-orm/query";
1
+ import { t as __exportAll } from "./chunk-D7D4PA-g.js";
2
+ import { n as anAdapter, t as aDBClient } from "./aDBClient-fMkIdR7p.js";
3
+ import { ManyToManyRelatedManager, ModelQuerySet } from "@danceroutine/tango-orm";
4
+ import { vi } from "vitest";
5
+ import { QueryResult } from "@danceroutine/tango-orm/query";
6
6
  import { getLogger } from "@danceroutine/tango-core";
7
7
  import { RequestContext } from "@danceroutine/tango-resources/context";
8
-
9
8
  //#region src/mocks/aQueryResult.ts
9
+ /**
10
+ * Create a query-result test value with optional overrides.
11
+ */
10
12
  function aQueryResult(overrides = {}) {
11
- const items = overrides.items ?? overrides.results ?? [];
12
- return new QueryResultClass(items);
13
+ return new QueryResult(overrides.items ?? overrides.results ?? []);
13
14
  }
14
-
15
15
  //#endregion
16
16
  //#region src/mocks/aQueryExecutor.ts
17
+ /**
18
+ * Create a minimal `QueryExecutor` test double for `QuerySet` tests.
19
+ */
17
20
  function aQueryExecutor(overrides = {}) {
18
21
  const adapter = overrides.adapter ?? anAdapter({ dialect: overrides.dialect ?? "postgres" });
19
22
  const meta = overrides.meta ?? {
@@ -21,27 +24,31 @@ function aQueryExecutor(overrides = {}) {
21
24
  pk: "id",
22
25
  columns: {}
23
26
  };
24
- const run = overrides.run ?? vi$3.fn(async () => []);
25
- const client = aDBClient(overrides.query ? { query: overrides.query } : {});
27
+ const run = overrides.run ?? vi.fn(async () => []);
26
28
  return {
27
29
  meta,
28
- client,
30
+ client: aDBClient(overrides.query ? { query: overrides.query } : {}),
29
31
  adapter,
30
32
  run,
31
33
  ...overrides.attachPersistedRecordAccessors ? { attachPersistedRecordAccessors: overrides.attachPersistedRecordAccessors } : {}
32
34
  };
33
35
  }
34
-
35
36
  //#endregion
36
37
  //#region src/mocks/aModelQuerySet.ts
38
+ /**
39
+ * Create a chainable model-queryset test double with optional behavior overrides.
40
+ *
41
+ * All methods are wrapped in `vi.fn()` so they can be asserted on directly
42
+ * without an additional `vi.mocked()` call.
43
+ */
37
44
  function aModelQuerySet(overrides = {}) {
38
- const queryset = new QuerySetClass(aQueryExecutor());
45
+ const queryset = new ModelQuerySet(aQueryExecutor());
39
46
  const filterImpl = overrides.filter ?? ((_input) => queryset);
40
47
  const excludeImpl = overrides.exclude ?? ((_input) => queryset);
41
48
  const orderByImpl = overrides.orderBy ?? ((..._tokens) => queryset);
42
49
  const limitImpl = overrides.limit ?? ((_n) => queryset);
43
50
  const offsetImpl = overrides.offset ?? ((_n) => queryset);
44
- const defaultSelect = (_cols) => queryset;
51
+ const defaultSelect = ((_cols) => queryset);
45
52
  const selectImpl = overrides.select ?? defaultSelect;
46
53
  const selectRelatedImpl = overrides.selectRelated ?? ((..._rels) => queryset);
47
54
  const prefetchRelatedImpl = overrides.prefetchRelated ?? ((..._rels) => queryset);
@@ -49,23 +56,25 @@ function aModelQuerySet(overrides = {}) {
49
56
  const fetchOneImpl = overrides.fetchOne ?? (async (_shape) => null);
50
57
  const countImpl = overrides.count ?? (async () => 0);
51
58
  const existsImpl = overrides.exists ?? (async () => false);
52
- queryset.filter = vi$2.fn((input) => filterImpl(input));
53
- queryset.exclude = vi$2.fn((input) => excludeImpl(input));
54
- queryset.orderBy = vi$2.fn((...tokens) => orderByImpl(...tokens));
55
- queryset.limit = vi$2.fn((n) => limitImpl(n));
56
- queryset.offset = vi$2.fn((n) => offsetImpl(n));
57
- queryset.select = vi$2.fn((cols) => selectImpl(cols));
58
- queryset.selectRelated = vi$2.fn((...rels) => selectRelatedImpl(...rels));
59
- queryset.prefetchRelated = vi$2.fn((...rels) => prefetchRelatedImpl(...rels));
60
- queryset.fetch = vi$2.fn(fetchImpl);
61
- queryset.fetchOne = vi$2.fn(fetchOneImpl);
62
- queryset.count = vi$2.fn(() => countImpl());
63
- queryset.exists = vi$2.fn(() => existsImpl());
59
+ queryset.filter = vi.fn((input) => filterImpl(input));
60
+ queryset.exclude = vi.fn((input) => excludeImpl(input));
61
+ queryset.orderBy = vi.fn((...tokens) => orderByImpl(...tokens));
62
+ queryset.limit = vi.fn((n) => limitImpl(n));
63
+ queryset.offset = vi.fn((n) => offsetImpl(n));
64
+ queryset.select = vi.fn((cols) => selectImpl(cols));
65
+ queryset.selectRelated = vi.fn((...rels) => selectRelatedImpl(...rels));
66
+ queryset.prefetchRelated = vi.fn((...rels) => prefetchRelatedImpl(...rels));
67
+ queryset.fetch = vi.fn(fetchImpl);
68
+ queryset.fetchOne = vi.fn(fetchOneImpl);
69
+ queryset.count = vi.fn(() => countImpl());
70
+ queryset.exists = vi.fn(() => existsImpl());
64
71
  return queryset;
65
72
  }
66
-
67
73
  //#endregion
68
74
  //#region src/mocks/aManager.ts
75
+ /**
76
+ * Create a manager-shaped test double for resource and service tests.
77
+ */
69
78
  function aManager(overrides = {}) {
70
79
  const meta = overrides.meta ?? {
71
80
  table: "mock_table",
@@ -96,21 +105,26 @@ function aManager(overrides = {}) {
96
105
  }));
97
106
  return {
98
107
  meta,
99
- query: vi$1.fn(() => queryImpl()),
100
- all: vi$1.fn(() => allImpl()),
101
- getOrCreate: vi$1.fn((args) => getOrCreateImpl(args)),
102
- updateOrCreate: vi$1.fn((args) => updateOrCreateImpl(args)),
103
- findById: vi$1.fn((id) => findByIdImpl(id)),
104
- getOrThrow: vi$1.fn((id) => getOrThrowImpl(id)),
105
- create: vi$1.fn((input) => createImpl(input)),
106
- update: vi$1.fn((id, patch) => updateImpl(id, patch)),
107
- delete: vi$1.fn((id) => deleteImpl(id)),
108
- bulkCreate: vi$1.fn((inputs) => bulkCreateImpl(inputs))
108
+ query: vi.fn(() => queryImpl()),
109
+ all: vi.fn(() => allImpl()),
110
+ getOrCreate: vi.fn((args) => getOrCreateImpl(args)),
111
+ updateOrCreate: vi.fn((args) => updateOrCreateImpl(args)),
112
+ findById: vi.fn((id) => findByIdImpl(id)),
113
+ getOrThrow: vi.fn((id) => getOrThrowImpl(id)),
114
+ create: vi.fn((input) => createImpl(input)),
115
+ update: vi.fn((id, patch) => updateImpl(id, patch)),
116
+ delete: vi.fn((id) => deleteImpl(id)),
117
+ bulkCreate: vi.fn((inputs) => bulkCreateImpl(inputs))
109
118
  };
110
119
  }
111
-
112
120
  //#endregion
113
121
  //#region src/mocks/aManyToManyRelatedManager.ts
122
+ /**
123
+ * Build a {@link ManyToManyRelatedManager} instance wired to lightweight spies
124
+ * for its underlying join-table operations. The fixture skips the
125
+ * relation-metadata and registry plumbing exercised by `ModelManager`, so
126
+ * tests can focus on manager behavior in isolation.
127
+ */
114
128
  function aManyToManyRelatedManager(overrides = {}) {
115
129
  const insertLink = vi.fn(overrides.insertLink ?? (async () => {}));
116
130
  const insertLinks = vi.fn(overrides.insertLinks ?? (async () => {}));
@@ -131,18 +145,17 @@ function aManyToManyRelatedManager(overrides = {}) {
131
145
  deleteAllLinksForOwner,
132
146
  selectTargetIdsForOwner
133
147
  };
134
- const manager = new ManyToManyRelatedManager({
135
- ownerPrimaryKey: overrides.ownerPrimaryKey ?? 7,
136
- relationName: overrides.relationName ?? "tags",
137
- ownerModelLabel: overrides.ownerModelLabel ?? "Post",
138
- targetPrimaryKeyField: overrides.targetPrimaryKeyField ?? "id",
139
- throughTableManager,
140
- targetExecutorProvider: () => overrides.targetExecutor === undefined ? {} : overrides.targetExecutor,
141
- createTarget,
142
- runAtomic: runAtomicSpy
143
- });
144
148
  return {
145
- manager,
149
+ manager: new ManyToManyRelatedManager({
150
+ ownerPrimaryKey: overrides.ownerPrimaryKey ?? 7,
151
+ relationName: overrides.relationName ?? "tags",
152
+ ownerModelLabel: overrides.ownerModelLabel ?? "Post",
153
+ targetPrimaryKeyField: overrides.targetPrimaryKeyField ?? "id",
154
+ throughTableManager,
155
+ targetExecutorProvider: () => overrides.targetExecutor === void 0 ? {} : overrides.targetExecutor,
156
+ createTarget,
157
+ runAtomic: runAtomicSpy
158
+ }),
146
159
  insertLink,
147
160
  insertLinks,
148
161
  deleteLink,
@@ -153,11 +166,13 @@ function aManyToManyRelatedManager(overrides = {}) {
153
166
  runAtomic: runAtomicSpy
154
167
  };
155
168
  }
156
-
157
169
  //#endregion
158
170
  //#region src/mocks/aQuerySet.ts
159
171
  const logger = getLogger("tango.testing.mocks");
160
172
  let hasWarned = false;
173
+ /**
174
+ * @deprecated Use `aModelQuerySet(...)` instead.
175
+ */
161
176
  function aQuerySet(overrides = {}) {
162
177
  if (!hasWarned) {
163
178
  hasWarned = true;
@@ -165,33 +180,32 @@ function aQuerySet(overrides = {}) {
165
180
  }
166
181
  return aModelQuerySet(overrides);
167
182
  }
168
-
169
183
  //#endregion
170
184
  //#region src/mocks/aRequestContext.ts
171
185
  function aRequestContext(optionsOrMethod = {}, urlArg, bodyArg) {
172
- const resolvedOptions = typeof optionsOrMethod === "string" ? {
186
+ const { method = "GET", url = "https://example.test", body, user = null, params = {}, headers, contextFactory } = typeof optionsOrMethod === "string" ? {
173
187
  method: optionsOrMethod,
174
188
  url: urlArg,
175
189
  body: bodyArg
176
190
  } : optionsOrMethod;
177
- const { method = "GET", url = "https://example.test", body, user = null, params = {}, headers, contextFactory } = resolvedOptions;
178
- const resolvedHeaders = body === undefined ? headers : {
191
+ const resolvedHeaders = body === void 0 ? headers : {
179
192
  "content-type": "application/json",
180
193
  ...headers
181
194
  };
182
195
  const request = new Request(url, {
183
196
  method,
184
197
  headers: resolvedHeaders,
185
- body: body === undefined ? undefined : JSON.stringify(body)
198
+ body: body === void 0 ? void 0 : JSON.stringify(body)
186
199
  });
187
- const createContext = contextFactory ?? ((req, currentUser) => RequestContext.create(req, currentUser));
188
- const context = createContext(request, user);
200
+ const context = (contextFactory ?? ((req, currentUser) => RequestContext.create(req, currentUser)))(request, user);
189
201
  context.params = params;
190
202
  return context;
191
203
  }
192
-
193
204
  //#endregion
194
205
  //#region src/mocks/aRelationMeta.ts
206
+ /**
207
+ * Build recursive relation metadata fixtures for planner/compiler/query tests.
208
+ */
195
209
  function aRelationMeta(input) {
196
210
  const cardinality = input.kind === "belongsTo" || input.kind === "hasOne" ? "single" : "many";
197
211
  const defaultHydratable = input.kind !== "manyToMany";
@@ -223,11 +237,9 @@ function aRelationMeta(input) {
223
237
  targetMeta
224
238
  };
225
239
  }
226
-
227
240
  //#endregion
228
241
  //#region src/mocks/index.ts
229
- var mocks_exports = {};
230
- __export(mocks_exports, {
242
+ var mocks_exports = /* @__PURE__ */ __exportAll({
231
243
  aDBClient: () => aDBClient,
232
244
  aManager: () => aManager,
233
245
  aManyToManyRelatedManager: () => aManyToManyRelatedManager,
@@ -239,7 +251,7 @@ __export(mocks_exports, {
239
251
  aRequestContext: () => aRequestContext,
240
252
  anAdapter: () => anAdapter
241
253
  });
242
-
243
254
  //#endregion
244
- export { aManager, aManyToManyRelatedManager, aModelQuerySet, aQueryExecutor, aQueryResult, aQuerySet, aRelationMeta, aRequestContext, mocks_exports };
245
- //# sourceMappingURL=mocks-BL_0iuAI.js.map
255
+ export { aManyToManyRelatedManager as a, aQueryExecutor as c, aQuerySet as i, aQueryResult as l, aRelationMeta as n, aManager as o, aRequestContext as r, aModelQuerySet as s, mocks_exports as t };
256
+
257
+ //# sourceMappingURL=mocks-JyZwO-W4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mocks-JyZwO-W4.js","names":["QueryResultClass","QuerySetClass"],"sources":["../src/mocks/aQueryResult.ts","../src/mocks/aQueryExecutor.ts","../src/mocks/aModelQuerySet.ts","../src/mocks/aManager.ts","../src/mocks/aManyToManyRelatedManager.ts","../src/mocks/aQuerySet.ts","../src/mocks/aRequestContext.ts","../src/mocks/aRelationMeta.ts","../src/mocks/index.ts"],"sourcesContent":["import type { QueryResult } from '@danceroutine/tango-orm/query';\nimport { QueryResult as QueryResultClass } from '@danceroutine/tango-orm/query';\n\nexport type AQueryResultOverrides<TModel> = {\n items?: readonly TModel[];\n results?: readonly TModel[];\n};\n\n/**\n * Create a query-result test value with optional overrides.\n */\nexport function aQueryResult<TModel>(overrides: AQueryResultOverrides<TModel> = {}): QueryResult<TModel> {\n const items = overrides.items ?? overrides.results ?? ([] as TModel[]);\n return new QueryResultClass(items);\n}\n","import { vi } from 'vitest';\nimport type { Adapter, QueryExecutor } from '@danceroutine/tango-orm';\nimport type { Dialect, TableMeta } from '@danceroutine/tango-orm/query';\nimport { anAdapter } from './anAdapter';\nimport { aDBClient } from './aDBClient';\n\nexport type QueryExecutorOverrides<TModel extends Record<string, unknown>> = {\n dialect?: Dialect;\n adapter?: Adapter;\n meta?: TableMeta;\n query?: (sql: string, params?: readonly unknown[]) => Promise<{ rows: unknown[] }>;\n run?: QueryExecutor<TModel>['run'];\n attachPersistedRecordAccessors?: QueryExecutor<TModel>['attachPersistedRecordAccessors'];\n};\n\n/**\n * Create a minimal `QueryExecutor` test double for `QuerySet` tests.\n */\nexport function aQueryExecutor<TModel extends Record<string, unknown>>(\n overrides: QueryExecutorOverrides<TModel> = {}\n): QueryExecutor<TModel> {\n const adapter = overrides.adapter ?? anAdapter({ dialect: overrides.dialect ?? 'postgres' });\n const meta: TableMeta = overrides.meta ?? { table: 'mock_table', pk: 'id', columns: {} };\n const run = overrides.run ?? vi.fn(async () => [] as TModel[]);\n const client = aDBClient(overrides.query ? { query: overrides.query } : {});\n\n return {\n meta,\n client,\n adapter,\n run,\n ...(overrides.attachPersistedRecordAccessors\n ? { attachPersistedRecordAccessors: overrides.attachPersistedRecordAccessors }\n : {}),\n };\n}\n","import { vi } from 'vitest';\nimport type { QuerySet } from '@danceroutine/tango-orm';\nimport { ModelQuerySet as QuerySetClass } from '@danceroutine/tango-orm';\nimport { aQueryResult } from './aQueryResult';\nimport { aQueryExecutor } from './aQueryExecutor';\n\n/**\n * Create a chainable model-queryset test double with optional behavior overrides.\n *\n * All methods are wrapped in `vi.fn()` so they can be asserted on directly\n * without an additional `vi.mocked()` call.\n */\nexport function aModelQuerySet<\n TModel extends Record<string, unknown>,\n TResult extends Record<string, unknown> = TModel,\n>(overrides: Partial<QuerySet<TModel, TResult>> = {}): QuerySet<TModel, TResult> {\n const queryset = new QuerySetClass<TModel, TResult>(aQueryExecutor<TModel>());\n const filterImpl: QuerySet<TModel, TResult>['filter'] = overrides.filter ?? ((_input) => queryset);\n const excludeImpl: QuerySet<TModel, TResult>['exclude'] = overrides.exclude ?? ((_input) => queryset);\n const orderByImpl: QuerySet<TModel, TResult>['orderBy'] = overrides.orderBy ?? ((..._tokens) => queryset);\n const limitImpl: QuerySet<TModel, TResult>['limit'] = overrides.limit ?? ((_n) => queryset);\n const offsetImpl: QuerySet<TModel, TResult>['offset'] = overrides.offset ?? ((_n) => queryset);\n const defaultSelect = ((_cols: readonly (keyof TModel)[]) => queryset) as unknown as QuerySet<\n TModel,\n TResult\n >['select'];\n const selectImpl = overrides.select ?? defaultSelect;\n const selectRelatedImpl =\n (overrides.selectRelated as ((...rels: readonly string[]) => QuerySet<TModel, TResult>) | undefined) ??\n ((..._rels: readonly string[]) => queryset);\n const prefetchRelatedImpl =\n (overrides.prefetchRelated as ((...rels: readonly string[]) => QuerySet<TModel, TResult>) | undefined) ??\n ((..._rels: readonly string[]) => queryset);\n const fetchImpl: QuerySet<TModel, TResult>['fetch'] =\n overrides.fetch ??\n (async <Out = TResult>(_shape?: ((r: TResult) => Out) | { parse: (r: TResult) => Out }) => aQueryResult<Out>());\n const fetchOneImpl: QuerySet<TModel, TResult>['fetchOne'] =\n overrides.fetchOne ??\n (async <Out = TResult>(_shape?: ((r: TResult) => Out) | { parse: (r: TResult) => Out }) => null as Out | null);\n const countImpl: QuerySet<TModel, TResult>['count'] = overrides.count ?? (async () => 0);\n const existsImpl: QuerySet<TModel, TResult>['exists'] = overrides.exists ?? (async () => false);\n\n queryset.filter = vi.fn((input: Parameters<QuerySet<TModel, TResult>['filter']>[0]) =>\n filterImpl(input)\n ) as QuerySet<TModel, TResult>['filter'];\n queryset.exclude = vi.fn((input: Parameters<QuerySet<TModel, TResult>['exclude']>[0]) =>\n excludeImpl(input)\n ) as QuerySet<TModel, TResult>['exclude'];\n queryset.orderBy = vi.fn((...tokens: Parameters<QuerySet<TModel, TResult>['orderBy']>) =>\n orderByImpl(...tokens)\n ) as QuerySet<TModel, TResult>['orderBy'];\n queryset.limit = vi.fn((n: number) => limitImpl(n)) as QuerySet<TModel, TResult>['limit'];\n queryset.offset = vi.fn((n: number) => offsetImpl(n)) as QuerySet<TModel, TResult>['offset'];\n queryset.select = vi.fn((cols: Parameters<QuerySet<TModel, TResult>['select']>[0]) =>\n selectImpl(cols)\n ) as unknown as QuerySet<TModel, TResult>['select'];\n queryset.selectRelated = vi.fn((...rels: readonly string[]) => selectRelatedImpl(...rels)) as unknown as QuerySet<\n TModel,\n TResult\n >['selectRelated'];\n queryset.prefetchRelated = vi.fn((...rels: readonly string[]) =>\n prefetchRelatedImpl(...rels)\n ) as unknown as QuerySet<TModel, TResult>['prefetchRelated'];\n queryset.fetch = vi.fn(fetchImpl) as unknown as QuerySet<TModel, TResult>['fetch'];\n queryset.fetchOne = vi.fn(fetchOneImpl) as unknown as QuerySet<TModel, TResult>['fetchOne'];\n queryset.count = vi.fn(() => countImpl()) as QuerySet<TModel, TResult>['count'];\n queryset.exists = vi.fn(() => existsImpl()) as QuerySet<TModel, TResult>['exists'];\n\n return queryset;\n}\n","import { vi } from 'vitest';\nimport type { ManagerLike, QuerySet } from '@danceroutine/tango-orm';\nimport type { TableMeta } from '@danceroutine/tango-orm/query';\nimport { aModelQuerySet } from './aModelQuerySet';\n\nexport type ManagerOverrides<TModel extends Record<string, unknown>> = {\n meta?: TableMeta;\n querySet?: QuerySet<TModel>;\n query?: ManagerLike<TModel>['query'];\n all?: ManagerLike<TModel>['all'];\n getOrCreate?: ManagerLike<TModel>['getOrCreate'];\n updateOrCreate?: ManagerLike<TModel>['updateOrCreate'];\n findById?: ManagerLike<TModel>['findById'];\n getOrThrow?: ManagerLike<TModel>['getOrThrow'];\n create?: ManagerLike<TModel>['create'];\n update?: ManagerLike<TModel>['update'];\n delete?: ManagerLike<TModel>['delete'];\n bulkCreate?: ManagerLike<TModel>['bulkCreate'];\n};\n\n/**\n * Create a manager-shaped test double for resource and service tests.\n */\nexport function aManager<TModel extends Record<string, unknown>>(\n overrides: ManagerOverrides<TModel> = {}\n): ManagerLike<TModel> {\n const meta = overrides.meta ?? { table: 'mock_table', pk: 'id', columns: {} };\n const querySet = overrides.querySet ?? aModelQuerySet<TModel>();\n type ModelId = TModel[keyof TModel];\n\n const queryImpl = overrides.query ?? (() => querySet);\n const allImpl = overrides.all ?? (() => queryImpl());\n const findByIdImpl = overrides.findById ?? (async () => null as TModel | null);\n const getOrThrowImpl =\n overrides.getOrThrow ??\n (async (id: ModelId) => {\n const record = await findByIdImpl(id);\n if (!record) {\n throw new Error(`No ${meta.table} record found for ${String(meta.pk)}=${String(id)}.`);\n }\n return record;\n });\n const createImpl = overrides.create ?? (async (input: Partial<TModel>) => input as TModel);\n const updateImpl = overrides.update ?? (async (_id: ModelId, patch: Partial<TModel>) => patch as TModel);\n const deleteImpl = overrides.delete ?? (async (_id: ModelId) => {});\n const bulkCreateImpl = overrides.bulkCreate ?? (async (inputs: Partial<TModel>[]) => inputs as TModel[]);\n const getOrCreateImpl =\n overrides.getOrCreate ??\n (async ({ defaults }: Parameters<ManagerLike<TModel>['getOrCreate']>[0]) => ({\n record: { ...defaults } as TModel,\n created: true,\n }));\n const updateOrCreateImpl =\n overrides.updateOrCreate ??\n (async ({ defaults }: Parameters<ManagerLike<TModel>['updateOrCreate']>[0]) => ({\n record: { ...defaults } as TModel,\n created: true,\n updated: false,\n }));\n\n return {\n meta,\n query: vi.fn(() => queryImpl()),\n all: vi.fn(() => allImpl()),\n getOrCreate: vi.fn((args: Parameters<ManagerLike<TModel>['getOrCreate']>[0]) => getOrCreateImpl(args)),\n updateOrCreate: vi.fn((args: Parameters<ManagerLike<TModel>['updateOrCreate']>[0]) => updateOrCreateImpl(args)),\n findById: vi.fn((id: ModelId) => findByIdImpl(id)),\n getOrThrow: vi.fn((id: ModelId) => getOrThrowImpl(id)),\n create: vi.fn((input: Partial<TModel>) => createImpl(input)),\n update: vi.fn((id: ModelId, patch: Partial<TModel>) => updateImpl(id, patch)),\n delete: vi.fn((id: ModelId) => deleteImpl(id)),\n bulkCreate: vi.fn((inputs: Partial<TModel>[]) => bulkCreateImpl(inputs)),\n };\n}\n","import { vi } from 'vitest';\nimport type { QueryExecutor } from '@danceroutine/tango-orm';\nimport { ManyToManyRelatedManager } from '@danceroutine/tango-orm';\n\ntype ManagerConstructorInputs = ConstructorParameters<typeof ManyToManyRelatedManager>[0];\n\n/**\n * Overrides accepted by the {@link aManyToManyRelatedManager} fixture. All\n * fields are optional; defaults produce a manager bound to owner primary key\n * `7`, relation name `'tags'`, owner label `'Post'`, and target primary-key\n * field `'id'`.\n */\nexport interface ManyToManyRelatedManagerFixtureOverrides<TTarget extends Record<string, unknown>> {\n ownerPrimaryKey?: unknown;\n relationName?: string;\n ownerModelLabel?: string;\n targetPrimaryKeyField?: string;\n /**\n * Resolver returned by the manager's `targetExecutorProvider`. Pass `null`\n * to simulate the registry not yet knowing about the target model; omit to\n * return a minimal executor stub.\n */\n targetExecutor?: QueryExecutor<TTarget> | null;\n insertLink?: (ownerPrimaryKey: unknown, targetPrimaryKey: unknown) => Promise<void>;\n insertLinks?: (ownerPrimaryKey: unknown, targetPrimaryKeys: readonly unknown[]) => Promise<void>;\n deleteLink?: (ownerPrimaryKey: unknown, targetPrimaryKey: unknown) => Promise<void>;\n deleteLinks?: (ownerPrimaryKey: unknown, targetPrimaryKeys: readonly unknown[]) => Promise<void>;\n deleteAllLinksForOwner?: (ownerPrimaryKey: unknown) => Promise<void>;\n selectTargetIdsForOwner?: (ownerPrimaryKey: unknown) => Promise<readonly (string | number)[]>;\n createTarget?: (input: Partial<TTarget>) => Promise<TTarget>;\n runAtomic?: <T>(work: () => Promise<T>) => Promise<T>;\n}\n\n/**\n * Return shape of the {@link aManyToManyRelatedManager} fixture. The spy\n * references are returned alongside the manager so tests can assert against\n * the join-table calls without reaching into private fields.\n */\nexport interface ManyToManyRelatedManagerFixture<TTarget extends Record<string, unknown>> {\n manager: ManyToManyRelatedManager<TTarget>;\n insertLink: ReturnType<typeof vi.fn>;\n insertLinks: ReturnType<typeof vi.fn>;\n deleteLink: ReturnType<typeof vi.fn>;\n deleteLinks: ReturnType<typeof vi.fn>;\n deleteAllLinksForOwner: ReturnType<typeof vi.fn>;\n selectTargetIdsForOwner: ReturnType<typeof vi.fn>;\n createTarget: ReturnType<typeof vi.fn>;\n runAtomic: ReturnType<typeof vi.fn>;\n}\n\n/**\n * Build a {@link ManyToManyRelatedManager} instance wired to lightweight spies\n * for its underlying join-table operations. The fixture skips the\n * relation-metadata and registry plumbing exercised by `ModelManager`, so\n * tests can focus on manager behavior in isolation.\n */\nexport function aManyToManyRelatedManager<TTarget extends Record<string, unknown>>(\n overrides: ManyToManyRelatedManagerFixtureOverrides<TTarget> = {}\n): ManyToManyRelatedManagerFixture<TTarget> {\n const insertLink = vi.fn(overrides.insertLink ?? (async () => {}));\n const insertLinks = vi.fn(overrides.insertLinks ?? (async () => {}));\n const deleteLink = vi.fn(overrides.deleteLink ?? (async () => {}));\n const deleteLinks = vi.fn(overrides.deleteLinks ?? (async () => {}));\n const deleteAllLinksForOwner = vi.fn(overrides.deleteAllLinksForOwner ?? (async () => {}));\n const selectTargetIdsForOwner = vi.fn(\n overrides.selectTargetIdsForOwner ?? (async (): Promise<readonly (string | number)[]> => [])\n );\n const createTarget = vi.fn(\n overrides.createTarget ??\n (async (input: Partial<TTarget>) => {\n return input as TTarget;\n })\n );\n const runAtomicImpl: ManagerConstructorInputs['runAtomic'] =\n overrides.runAtomic ?? (async <T>(work: () => Promise<T>) => work());\n const runAtomicSpy = vi.fn(async <T>(work: () => Promise<T>) => runAtomicImpl(work));\n\n const throughTableManager = {\n insertLink,\n insertLinks,\n deleteLink,\n deleteLinks,\n deleteAllLinksForOwner,\n selectTargetIdsForOwner,\n } as unknown as ManagerConstructorInputs['throughTableManager'];\n\n const manager = new ManyToManyRelatedManager<TTarget>({\n ownerPrimaryKey: overrides.ownerPrimaryKey ?? 7,\n relationName: overrides.relationName ?? 'tags',\n ownerModelLabel: overrides.ownerModelLabel ?? 'Post',\n targetPrimaryKeyField: overrides.targetPrimaryKeyField ?? 'id',\n throughTableManager,\n targetExecutorProvider: () =>\n overrides.targetExecutor === undefined ? ({} as QueryExecutor<TTarget>) : overrides.targetExecutor,\n createTarget,\n runAtomic: runAtomicSpy as ManagerConstructorInputs['runAtomic'],\n });\n\n return {\n manager,\n insertLink,\n insertLinks,\n deleteLink,\n deleteLinks,\n deleteAllLinksForOwner,\n selectTargetIdsForOwner,\n createTarget,\n runAtomic: runAtomicSpy,\n };\n}\n","import { getLogger } from '@danceroutine/tango-core';\nimport type { QuerySet } from '@danceroutine/tango-orm';\nimport { aModelQuerySet } from './aModelQuerySet';\n\nconst logger = getLogger('tango.testing.mocks');\n// TODO this pattern keeps showing up, perhaps we should implement logger.warnOnce\nlet hasWarned = false;\n\n/**\n * @deprecated Use `aModelQuerySet(...)` instead.\n */\nexport function aQuerySet<TModel extends Record<string, unknown>, TResult extends Record<string, unknown> = TModel>(\n overrides: Partial<QuerySet<TModel, TResult>> = {}\n): QuerySet<TModel, TResult> {\n if (!hasWarned) {\n hasWarned = true;\n logger.warn('`aQuerySet(...)` is deprecated. Use `aModelQuerySet(...)` instead.');\n }\n\n return aModelQuerySet(overrides);\n}\n","// Import through the package subpath so fixtures stay aligned with the public nominal type.\nimport { RequestContext, type BaseUser } from '@danceroutine/tango-resources/context';\n\ntype RequestContextFactory<TUser, TContext extends RequestContextLike<TUser>> = (\n request: Request,\n user: TUser | null\n) => TContext;\n\ntype RequestContextLike<TUser> = {\n request: Request;\n user: TUser | null;\n params: Record<string, string>;\n};\n\nexport type RequestContextFixtureOptions<\n TUser = BaseUser,\n TContext extends RequestContextLike<TUser> = RequestContext<TUser>,\n> = {\n method?: string;\n url?: string;\n body?: unknown;\n user?: TUser | null;\n params?: Record<string, string>;\n headers?: HeadersInit;\n contextFactory?: RequestContextFactory<TUser, TContext>;\n};\n\n/**\n * Create a RequestContext fixture with optional method/url/body/user/params.\n */\nexport function aRequestContext<TUser = BaseUser, TContext extends RequestContextLike<TUser> = RequestContext<TUser>>(\n method: string,\n url: string,\n body?: unknown\n): TContext;\nexport function aRequestContext<TUser = BaseUser, TContext extends RequestContextLike<TUser> = RequestContext<TUser>>(\n options?: RequestContextFixtureOptions<TUser, TContext>\n): TContext;\nexport function aRequestContext<TUser = BaseUser, TContext extends RequestContextLike<TUser> = RequestContext<TUser>>(\n optionsOrMethod: RequestContextFixtureOptions<TUser, TContext> | string = {},\n urlArg?: string,\n bodyArg?: unknown\n): TContext {\n const resolvedOptions: RequestContextFixtureOptions<TUser, TContext> =\n typeof optionsOrMethod === 'string'\n ? {\n method: optionsOrMethod,\n url: urlArg,\n body: bodyArg,\n }\n : optionsOrMethod;\n const {\n method = 'GET',\n url = 'https://example.test',\n body,\n user = null,\n params = {},\n headers,\n contextFactory,\n } = resolvedOptions;\n\n const resolvedHeaders: HeadersInit | undefined =\n body === undefined ? headers : { 'content-type': 'application/json', ...headers };\n\n const request = new Request(url, {\n method,\n headers: resolvedHeaders,\n body: body === undefined ? undefined : JSON.stringify(body),\n });\n const createContext =\n contextFactory ?? ((req: Request, currentUser: TUser | null) => RequestContext.create<TUser>(req, currentUser));\n const context = createContext(request, user) as TContext;\n context.params = params;\n return context;\n}\n","import type { RelationMeta, TableMeta } from '@danceroutine/tango-orm/query';\n\ntype RelationMetaInput = {\n kind: RelationMeta['kind'];\n table: string;\n sourceKey: string;\n targetKey: string;\n targetColumns: Record<string, string>;\n alias: string;\n edgeId?: string;\n sourceModelKey?: string;\n targetModelKey?: string;\n targetPrimaryKey?: string;\n targetMeta?: TableMeta;\n capabilities?: Partial<RelationMeta['capabilities']>;\n};\n\n/**\n * Build recursive relation metadata fixtures for planner/compiler/query tests.\n */\nexport function aRelationMeta(input: RelationMetaInput): RelationMeta {\n const cardinality = input.kind === 'belongsTo' || input.kind === 'hasOne' ? 'single' : 'many';\n const defaultHydratable = input.kind !== ('manyToMany' as RelationMeta['kind']);\n\n const targetMeta =\n input.targetMeta ??\n ({\n modelKey: input.targetModelKey ?? `${input.alias}:target`,\n table: input.table,\n pk: input.targetPrimaryKey ?? 'id',\n columns: input.targetColumns,\n } satisfies TableMeta);\n\n return {\n edgeId: input.edgeId ?? `${input.alias}:${input.sourceKey}:${input.targetKey}`,\n sourceModelKey: input.sourceModelKey ?? `${input.alias}:source`,\n targetModelKey: input.targetModelKey ?? `${input.alias}:target`,\n kind: input.kind,\n cardinality,\n capabilities: {\n queryable: true,\n hydratable: defaultHydratable,\n joinable: cardinality === 'single' && defaultHydratable,\n prefetchable: defaultHydratable,\n ...input.capabilities,\n },\n table: input.table,\n sourceKey: input.sourceKey,\n targetKey: input.targetKey,\n targetPrimaryKey: input.targetPrimaryKey ?? 'id',\n targetColumns: input.targetColumns,\n alias: input.alias,\n targetMeta,\n };\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { anAdapter } from './anAdapter';\nexport { aDBClient } from './aDBClient';\nexport { aManager } from './aManager';\nexport { aManyToManyRelatedManager } from './aManyToManyRelatedManager';\nexport { aModelQuerySet } from './aModelQuerySet';\nexport { aQueryResult } from './aQueryResult';\nexport { aQuerySet } from './aQuerySet';\nexport { aRequestContext } from './aRequestContext';\nexport { aQueryExecutor } from './aQueryExecutor';\nexport { aRelationMeta } from './aRelationMeta';\nexport type { AdapterOverrides } from './anAdapter';\nexport type { QueryExecutorOverrides } from './aQueryExecutor';\nexport type { ManagerOverrides } from './aManager';\nexport type {\n ManyToManyRelatedManagerFixture,\n ManyToManyRelatedManagerFixtureOverrides,\n} from './aManyToManyRelatedManager';\nexport type { DBClient } from './DBClient';\nexport type { MockQuerySetResult } from './MockQuerySetResult';\nexport type { RequestContextFixtureOptions } from './aRequestContext';\n"],"mappings":"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"}
@@ -1,5 +1,62 @@
1
+ import { A as IntegrationHarness, s as HarnessStrategyRegistry, w as AssertMigrationPlanOptions, x as ApplyAndVerifyMigrationsOptions } from "../index-B4H3wYuR.js";
2
+
3
+ //#region src/vitest/registerVitestTango.d.ts
4
+ interface Parseable {
5
+ parse(data: unknown): unknown;
6
+ }
7
+ interface TangoVitestHelpers {
8
+ useHarness(input: IntegrationHarness | (() => IntegrationHarness | Promise<IntegrationHarness>)): Promise<IntegrationHarness>;
9
+ getTestHarness(): IntegrationHarness;
10
+ getRegistry(): HarnessStrategyRegistry;
11
+ assertMigrationPlan(options: AssertMigrationPlanOptions & {
12
+ harness?: IntegrationHarness;
13
+ }): Promise<string>;
14
+ applyAndVerifyMigrations(options: ApplyAndVerifyMigrationsOptions & {
15
+ harness?: IntegrationHarness;
16
+ }): Promise<{
17
+ statuses: {
18
+ id: string;
19
+ applied: boolean;
20
+ }[];
21
+ }>;
22
+ introspectSchema(harness?: IntegrationHarness): Promise<unknown>;
23
+ seedTable<T extends Record<string, unknown>>(table: string, rows: T[], harness?: IntegrationHarness): Promise<void>;
24
+ createModelQuerySetFixture<TModel extends Record<string, unknown>>(options: {
25
+ meta: import('@danceroutine/tango-orm/query').TableMeta;
26
+ harness?: IntegrationHarness;
27
+ }): import('@danceroutine/tango-orm').QuerySet<TModel>;
28
+ /**
29
+ * @deprecated Use `vi.tango.createModelQuerySetFixture(...)` instead.
30
+ */
31
+ createQuerySetFixture<TModel extends Record<string, unknown>>(options: {
32
+ meta: import('@danceroutine/tango-orm/query').TableMeta;
33
+ harness?: IntegrationHarness;
34
+ }): import('@danceroutine/tango-orm').QuerySet<TModel>;
35
+ expectQueryResult<T>(actual: Promise<T> | T, expected: T): Promise<void>;
36
+ }
37
+ declare module 'vitest' {
38
+ interface Assertion<T> {
39
+ toMatchSchema(schema: Parseable): void;
40
+ }
41
+ interface AsymmetricMatchersContaining {
42
+ toMatchSchema(schema: Parseable): void;
43
+ }
44
+ interface VitestUtils {
45
+ tango: TangoVitestHelpers;
46
+ }
47
+ }
48
+ //#endregion
49
+ //#region src/vitest/withGlobalTestApi.d.ts
1
50
  /**
2
- * Domain boundary barrel: centralizes this subdomain's public contract.
51
+ * Install a temporary global test API for the duration of one callback.
52
+ *
53
+ * This is useful for module-loading tests that need a stable escape hatch into
54
+ * already-imported symbols without introducing a second copy of the same package.
3
55
  */
4
- export * from './registerVitestTango';
5
- export * from './withGlobalTestApi';
56
+ declare function withGlobalTestApi<TValue, TResult>(key: string, value: TValue, work: () => TResult | Promise<TResult>): Promise<TResult>;
57
+ declare namespace index_d_exports {
58
+ export { TangoVitestHelpers, withGlobalTestApi };
59
+ }
60
+ //#endregion
61
+ export { TangoVitestHelpers, index_d_exports as t, withGlobalTestApi };
62
+ //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,120 @@
1
- import "../aDBClient-CH-ZcOaP.js";
2
- import "../integration-CaRF_lF_.js";
3
- import { withGlobalTestApi } from "../vitest-BqZmULOa.js";
1
+ import { t as __exportAll } from "../chunk-D7D4PA-g.js";
2
+ import { a as seedTable, b as assertMigrationPlan, i as createModelQuerySetFixture, n as expectQueryResult, o as TestHarness, v as introspectSchema, y as applyAndVerifyMigrations } from "../integration-CLzkacon.js";
3
+ import { expect, vi } from "vitest";
4
+ import { getLogger } from "@danceroutine/tango-core";
5
+ //#region src/vitest/registerVitestTango.ts
6
+ /**
7
+ * Vitest custom matchers and helpers for Tango.
8
+ *
9
+ * Import this module in your Vitest setup file:
10
+ *
11
+ * ```typescript
12
+ * import '@danceroutine/tango-testing/vitest';
13
+ * ```
14
+ */
15
+ function isError(value) {
16
+ return typeof value === "object" && value !== null && typeof value.name === "string" && typeof value.message === "string";
17
+ }
18
+ let activeHarness = null;
19
+ const logger = getLogger("tango.testing.vitest");
20
+ let hasWarnedForCreateQuerySetFixture = false;
21
+ async function resolveHarness(input) {
22
+ if (typeof input === "function") return input();
23
+ return input;
24
+ }
25
+ const tangoHelpers = {
26
+ async useHarness(input) {
27
+ const harness = await resolveHarness(input);
28
+ await harness.setup();
29
+ activeHarness = harness;
30
+ return harness;
31
+ },
32
+ getTestHarness() {
33
+ if (!activeHarness) throw new Error("No active test harness. Call vi.tango.useHarness(...) in beforeAll first.");
34
+ return activeHarness;
35
+ },
36
+ getRegistry() {
37
+ return TestHarness.getRegistry();
38
+ },
39
+ async assertMigrationPlan(options) {
40
+ return assertMigrationPlan(options.harness ?? tangoHelpers.getTestHarness(), {
41
+ migrationsDir: options.migrationsDir,
42
+ expectSqlContains: options.expectSqlContains
43
+ });
44
+ },
45
+ async applyAndVerifyMigrations(options) {
46
+ return applyAndVerifyMigrations(options.harness ?? tangoHelpers.getTestHarness(), {
47
+ migrationsDir: options.migrationsDir,
48
+ toId: options.toId,
49
+ expectedAppliedIds: options.expectedAppliedIds
50
+ });
51
+ },
52
+ async introspectSchema(harness) {
53
+ return introspectSchema(harness ?? tangoHelpers.getTestHarness());
54
+ },
55
+ async seedTable(table, rows, harness) {
56
+ await seedTable(harness ?? tangoHelpers.getTestHarness(), table, rows);
57
+ },
58
+ createModelQuerySetFixture(options) {
59
+ return createModelQuerySetFixture({
60
+ harness: options.harness ?? tangoHelpers.getTestHarness(),
61
+ meta: options.meta
62
+ });
63
+ },
64
+ createQuerySetFixture(options) {
65
+ if (!hasWarnedForCreateQuerySetFixture) {
66
+ hasWarnedForCreateQuerySetFixture = true;
67
+ logger.warn("`vi.tango.createQuerySetFixture(...)` is deprecated. Use `vi.tango.createModelQuerySetFixture(...)` instead.");
68
+ }
69
+ return createModelQuerySetFixture({
70
+ harness: options.harness ?? tangoHelpers.getTestHarness(),
71
+ meta: options.meta
72
+ });
73
+ },
74
+ async expectQueryResult(actual, expected) {
75
+ await expectQueryResult(actual, expected);
76
+ }
77
+ };
78
+ expect.extend({ toMatchSchema(received, schema) {
79
+ try {
80
+ schema.parse(received);
81
+ return {
82
+ pass: true,
83
+ message: () => "expected data not to match schema"
84
+ };
85
+ } catch (error) {
86
+ const detail = isError(error) ? error.message : String(error);
87
+ return {
88
+ pass: false,
89
+ message: () => `expected data to match schema\n\n${detail}`
90
+ };
91
+ }
92
+ } });
93
+ vi.tango = tangoHelpers;
94
+ //#endregion
95
+ //#region src/vitest/withGlobalTestApi.ts
96
+ /**
97
+ * Install a temporary global test API for the duration of one callback.
98
+ *
99
+ * This is useful for module-loading tests that need a stable escape hatch into
100
+ * already-imported symbols without introducing a second copy of the same package.
101
+ */
102
+ async function withGlobalTestApi(key, value, work) {
103
+ const globalRecord = globalThis;
104
+ const previousValue = globalRecord[key];
105
+ const hadPreviousValue = Object.prototype.hasOwnProperty.call(globalRecord, key);
106
+ globalRecord[key] = value;
107
+ try {
108
+ return await work();
109
+ } finally {
110
+ if (hadPreviousValue) globalRecord[key] = previousValue;
111
+ else delete globalRecord[key];
112
+ }
113
+ }
114
+ //#endregion
115
+ //#region src/vitest/index.ts
116
+ var vitest_exports = /* @__PURE__ */ __exportAll({ withGlobalTestApi: () => withGlobalTestApi });
117
+ //#endregion
118
+ export { vitest_exports as t, withGlobalTestApi };
4
119
 
5
- export { withGlobalTestApi };
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["assertMigrationPlanFn","applyAndVerifyMigrationsFn","introspectSchemaFn","seedTableFn","createModelQuerySetFixtureFn","expectQueryResultFn"],"sources":["../../src/vitest/registerVitestTango.ts","../../src/vitest/withGlobalTestApi.ts","../../src/vitest/index.ts"],"sourcesContent":["/**\n * Vitest custom matchers and helpers for Tango.\n *\n * Import this module in your Vitest setup file:\n *\n * ```typescript\n * import '@danceroutine/tango-testing/vitest';\n * ```\n */\nimport { expect, vi } from 'vitest';\nimport { getLogger } from '@danceroutine/tango-core';\nimport {\n TestHarness,\n applyAndVerifyMigrations as applyAndVerifyMigrationsFn,\n assertMigrationPlan as assertMigrationPlanFn,\n createModelQuerySetFixture as createModelQuerySetFixtureFn,\n expectQueryResult as expectQueryResultFn,\n introspectSchema as introspectSchemaFn,\n seedTable as seedTableFn,\n type ApplyAndVerifyMigrationsOptions,\n type AssertMigrationPlanOptions,\n type HarnessStrategyRegistry,\n type IntegrationHarness,\n} from '../integration';\n\ninterface Parseable {\n parse(data: unknown): unknown;\n}\n\nfunction isError(value: unknown): value is Error {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as { name?: unknown }).name === 'string' &&\n typeof (value as { message?: unknown }).message === 'string'\n );\n}\n\nlet activeHarness: IntegrationHarness | null = null;\nconst logger = getLogger('tango.testing.vitest');\nlet hasWarnedForCreateQuerySetFixture = false;\n\nasync function resolveHarness(\n input: IntegrationHarness | (() => IntegrationHarness | Promise<IntegrationHarness>)\n): Promise<IntegrationHarness> {\n if (typeof input === 'function') {\n return input();\n }\n return input;\n}\n\nexport interface TangoVitestHelpers {\n useHarness(\n input: IntegrationHarness | (() => IntegrationHarness | Promise<IntegrationHarness>)\n ): Promise<IntegrationHarness>;\n getTestHarness(): IntegrationHarness;\n getRegistry(): HarnessStrategyRegistry;\n assertMigrationPlan(options: AssertMigrationPlanOptions & { harness?: IntegrationHarness }): Promise<string>;\n applyAndVerifyMigrations(\n options: ApplyAndVerifyMigrationsOptions & { harness?: IntegrationHarness }\n ): Promise<{ statuses: { id: string; applied: boolean }[] }>;\n introspectSchema(harness?: IntegrationHarness): Promise<unknown>;\n seedTable<T extends Record<string, unknown>>(table: string, rows: T[], harness?: IntegrationHarness): Promise<void>;\n createModelQuerySetFixture<TModel extends Record<string, unknown>>(options: {\n meta: import('@danceroutine/tango-orm/query').TableMeta;\n harness?: IntegrationHarness;\n }): import('@danceroutine/tango-orm').QuerySet<TModel>;\n /**\n * @deprecated Use `vi.tango.createModelQuerySetFixture(...)` instead.\n */\n createQuerySetFixture<TModel extends Record<string, unknown>>(options: {\n meta: import('@danceroutine/tango-orm/query').TableMeta;\n harness?: IntegrationHarness;\n }): import('@danceroutine/tango-orm').QuerySet<TModel>;\n expectQueryResult<T>(actual: Promise<T> | T, expected: T): Promise<void>;\n}\n\nconst tangoHelpers: TangoVitestHelpers = {\n async useHarness(input): Promise<IntegrationHarness> {\n const harness = await resolveHarness(input);\n await harness.setup();\n activeHarness = harness;\n return harness;\n },\n getTestHarness(): IntegrationHarness {\n if (!activeHarness) {\n throw new Error('No active test harness. Call vi.tango.useHarness(...) in beforeAll first.');\n }\n return activeHarness;\n },\n getRegistry(): HarnessStrategyRegistry {\n return TestHarness.getRegistry();\n },\n async assertMigrationPlan(options): Promise<string> {\n const harness = options.harness ?? tangoHelpers.getTestHarness();\n return assertMigrationPlanFn(harness, {\n migrationsDir: options.migrationsDir,\n expectSqlContains: options.expectSqlContains,\n });\n },\n async applyAndVerifyMigrations(options): Promise<{ statuses: { id: string; applied: boolean }[] }> {\n const harness = options.harness ?? tangoHelpers.getTestHarness();\n return applyAndVerifyMigrationsFn(harness, {\n migrationsDir: options.migrationsDir,\n toId: options.toId,\n expectedAppliedIds: options.expectedAppliedIds,\n });\n },\n async introspectSchema(harness?: IntegrationHarness): Promise<unknown> {\n return introspectSchemaFn(harness ?? tangoHelpers.getTestHarness());\n },\n async seedTable<T extends Record<string, unknown>>(\n table: string,\n rows: T[],\n harness?: IntegrationHarness\n ): Promise<void> {\n await seedTableFn(harness ?? tangoHelpers.getTestHarness(), table, rows);\n },\n createModelQuerySetFixture<TModel extends Record<string, unknown>>(options: {\n meta: import('@danceroutine/tango-orm/query').TableMeta;\n harness?: IntegrationHarness;\n }): import('@danceroutine/tango-orm').QuerySet<TModel> {\n return createModelQuerySetFixtureFn<TModel>({\n harness: options.harness ?? tangoHelpers.getTestHarness(),\n meta: options.meta,\n });\n },\n createQuerySetFixture<TModel extends Record<string, unknown>>(options: {\n meta: import('@danceroutine/tango-orm/query').TableMeta;\n harness?: IntegrationHarness;\n }): import('@danceroutine/tango-orm').QuerySet<TModel> {\n if (!hasWarnedForCreateQuerySetFixture) {\n hasWarnedForCreateQuerySetFixture = true;\n logger.warn(\n '`vi.tango.createQuerySetFixture(...)` is deprecated. Use `vi.tango.createModelQuerySetFixture(...)` instead.'\n );\n }\n return createModelQuerySetFixtureFn<TModel>({\n harness: options.harness ?? tangoHelpers.getTestHarness(),\n meta: options.meta,\n });\n },\n async expectQueryResult<T>(actual: Promise<T> | T, expected: T): Promise<void> {\n await expectQueryResultFn(actual, expected);\n },\n};\n\nexpect.extend({\n toMatchSchema(received: unknown, schema: Parseable) {\n try {\n schema.parse(received);\n return {\n pass: true,\n message: () => 'expected data not to match schema',\n };\n } catch (error) {\n const detail = isError(error) ? error.message : String(error);\n return {\n pass: false,\n message: () => `expected data to match schema\\n\\n${detail}`,\n };\n }\n },\n});\n\n(vi as unknown as { tango?: TangoVitestHelpers }).tango = tangoHelpers;\n\ndeclare module 'vitest' {\n // oxlint-disable-next-line no-unused-vars\n interface Assertion<T> {\n toMatchSchema(schema: Parseable): void;\n }\n\n interface AsymmetricMatchersContaining {\n toMatchSchema(schema: Parseable): void;\n }\n\n interface VitestUtils {\n tango: TangoVitestHelpers;\n }\n}\n","/**\n * Install a temporary global test API for the duration of one callback.\n *\n * This is useful for module-loading tests that need a stable escape hatch into\n * already-imported symbols without introducing a second copy of the same package.\n */\nexport async function withGlobalTestApi<TValue, TResult>(\n key: string,\n value: TValue,\n work: () => TResult | Promise<TResult>\n): Promise<TResult> {\n const globalRecord = globalThis as Record<string, unknown>;\n const previousValue = globalRecord[key];\n const hadPreviousValue = Object.prototype.hasOwnProperty.call(globalRecord, key);\n\n globalRecord[key] = value;\n try {\n return await work();\n } finally {\n if (hadPreviousValue) {\n globalRecord[key] = previousValue;\n } else {\n delete globalRecord[key];\n }\n }\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport * from './registerVitestTango';\nexport * from './withGlobalTestApi';\n"],"mappings":";;;;;;;;;;;;;;AA6BA,SAAS,QAAQ,OAAgC;CAC7C,OACI,OAAO,UAAU,YACjB,UAAU,QACV,OAAQ,MAA6B,SAAS,YAC9C,OAAQ,MAAgC,YAAY;AAE5D;AAEA,IAAI,gBAA2C;AAC/C,MAAM,SAAS,UAAU,sBAAsB;AAC/C,IAAI,oCAAoC;AAExC,eAAe,eACX,OAC2B;CAC3B,IAAI,OAAO,UAAU,YACjB,OAAO,MAAM;CAEjB,OAAO;AACX;AA4BA,MAAM,eAAmC;CACrC,MAAM,WAAW,OAAoC;EACjD,MAAM,UAAU,MAAM,eAAe,KAAK;EAC1C,MAAM,QAAQ,MAAM;EACpB,gBAAgB;EAChB,OAAO;CACX;CACA,iBAAqC;EACjC,IAAI,CAAC,eACD,MAAM,IAAI,MAAM,2EAA2E;EAE/F,OAAO;CACX;CACA,cAAuC;EACnC,OAAO,YAAY,YAAY;CACnC;CACA,MAAM,oBAAoB,SAA0B;EAEhD,OAAOA,oBADS,QAAQ,WAAW,aAAa,eAAe,GACzB;GAClC,eAAe,QAAQ;GACvB,mBAAmB,QAAQ;EAC/B,CAAC;CACL;CACA,MAAM,yBAAyB,SAAoE;EAE/F,OAAOC,yBADS,QAAQ,WAAW,aAAa,eAAe,GACpB;GACvC,eAAe,QAAQ;GACvB,MAAM,QAAQ;GACd,oBAAoB,QAAQ;EAChC,CAAC;CACL;CACA,MAAM,iBAAiB,SAAgD;EACnE,OAAOC,iBAAmB,WAAW,aAAa,eAAe,CAAC;CACtE;CACA,MAAM,UACF,OACA,MACA,SACa;EACb,MAAMC,UAAY,WAAW,aAAa,eAAe,GAAG,OAAO,IAAI;CAC3E;CACA,2BAAmE,SAGZ;EACnD,OAAOC,2BAAqC;GACxC,SAAS,QAAQ,WAAW,aAAa,eAAe;GACxD,MAAM,QAAQ;EAClB,CAAC;CACL;CACA,sBAA8D,SAGP;EACnD,IAAI,CAAC,mCAAmC;GACpC,oCAAoC;GACpC,OAAO,KACH,8GACJ;EACJ;EACA,OAAOA,2BAAqC;GACxC,SAAS,QAAQ,WAAW,aAAa,eAAe;GACxD,MAAM,QAAQ;EAClB,CAAC;CACL;CACA,MAAM,kBAAqB,QAAwB,UAA4B;EAC3E,MAAMC,kBAAoB,QAAQ,QAAQ;CAC9C;AACJ;AAEA,OAAO,OAAO,EACV,cAAc,UAAmB,QAAmB;CAChD,IAAI;EACA,OAAO,MAAM,QAAQ;EACrB,OAAO;GACH,MAAM;GACN,eAAe;EACnB;CACJ,SAAS,OAAO;EACZ,MAAM,SAAS,QAAQ,KAAK,IAAI,MAAM,UAAU,OAAO,KAAK;EAC5D,OAAO;GACH,MAAM;GACN,eAAe,oCAAoC;EACvD;CACJ;AACJ,EACJ,CAAC;AAED,GAAkD,QAAQ;;;;;;;;;AC/J1D,eAAsB,kBAClB,KACA,OACA,MACgB;CAChB,MAAM,eAAe;CACrB,MAAM,gBAAgB,aAAa;CACnC,MAAM,mBAAmB,OAAO,UAAU,eAAe,KAAK,cAAc,GAAG;CAE/E,aAAa,OAAO;CACpB,IAAI;EACA,OAAO,MAAM,KAAK;CACtB,UAAU;EACN,IAAI,kBACA,aAAa,OAAO;OAEpB,OAAO,aAAa;CAE5B;AACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danceroutine/tango-testing",
3
- "version": "1.11.1",
3
+ "version": "1.11.2",
4
4
  "description": "Testing utilities for Tango",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -52,11 +52,11 @@
52
52
  "directory": "packages/testing"
53
53
  },
54
54
  "dependencies": {
55
- "@danceroutine/tango-config": "1.11.1",
56
- "@danceroutine/tango-core": "1.11.1",
57
- "@danceroutine/tango-migrations": "1.11.1",
58
- "@danceroutine/tango-orm": "1.11.1",
59
- "@danceroutine/tango-resources": "1.11.1"
55
+ "@danceroutine/tango-core": "1.11.2",
56
+ "@danceroutine/tango-migrations": "1.11.2",
57
+ "@danceroutine/tango-orm": "1.11.2",
58
+ "@danceroutine/tango-config": "1.11.2",
59
+ "@danceroutine/tango-resources": "1.11.2"
60
60
  },
61
61
  "peerDependencies": {
62
62
  "@types/express": "^5.0.0",
@@ -73,7 +73,7 @@
73
73
  "devDependencies": {
74
74
  "@types/express": "^5.0.0",
75
75
  "@types/node": "^22.9.0",
76
- "tsdown": "^0.4.0",
76
+ "tsdown": "^0.22.1",
77
77
  "typescript": "^5.6.3",
78
78
  "vitest": "^4.1.7",
79
79
  "zod": "^4.0.0"
@@ -1 +0,0 @@
1
- {"version":3,"file":"aDBClient-CH-ZcOaP.js","names":["overrides: AdapterOverrides","dialect: Dialect","overrides: DBClientOverrides","_sql: string","_params?: readonly unknown[]","_name: string","client: DBClient","sql: string","params?: readonly unknown[]","name: string"],"sources":["../src/mocks/anAdapter.ts","../src/mocks/aDBClient.ts"],"sourcesContent":["import { PostgresAdapter, SqliteAdapter, type Adapter } from '@danceroutine/tango-orm';\nimport type { Dialect } from '@danceroutine/tango-orm/query';\n\nexport type AdapterOverrides = {\n dialect?: Dialect;\n};\n\n/**\n * Create a real built-in `Adapter` instance for unit tests that need one.\n *\n * Defaults to a Postgres adapter; pass `{ dialect: 'sqlite' }` to obtain a\n * SQLite adapter. The returned adapter carries the matching placeholder\n * formatter so compilers exercised under test emit dialect-accurate SQL.\n */\nexport function anAdapter(overrides: AdapterOverrides = {}): Adapter {\n const dialect: Dialect = overrides.dialect ?? 'postgres';\n switch (dialect) {\n case 'postgres':\n return new PostgresAdapter();\n case 'sqlite':\n return new SqliteAdapter();\n default:\n throw new Error(`Unsupported dialect: ${dialect}`);\n }\n}\n","import { vi } from 'vitest';\nimport type { DBClient } from './DBClient';\n\n/**\n * Looser override type for `aDBClient` that accepts concrete-typed query mocks.\n * Consumers should not need to cast their mocks to satisfy `DBClient['query']`'s generic.\n */\ntype DBClientOverrides = {\n // oxlint-disable-next-line typescript/no-explicit-any\n query?: (sql: string, params?: readonly unknown[]) => Promise<{ rows: any[] }>;\n begin?: () => Promise<void>;\n commit?: () => Promise<void>;\n rollback?: () => Promise<void>;\n close?: () => Promise<void>;\n createSavepoint?: (name: string) => Promise<void>;\n releaseSavepoint?: (name: string) => Promise<void>;\n rollbackToSavepoint?: (name: string) => Promise<void>;\n};\n\n/**\n * Create a lightweight `DBClient` test double with optional behavior overrides.\n * The `query` override accepts any function returning `Promise<{ rows: any[] }>`,\n * so concrete-typed Vitest mocks do not require a cast at the call site.\n */\nexport function aDBClient(overrides: DBClientOverrides = {}): DBClient {\n const queryImpl =\n // oxlint-disable-next-line typescript/no-explicit-any\n overrides.query ?? (async (_sql: string, _params?: readonly unknown[]) => ({ rows: [] as any[] }));\n const beginImpl = overrides.begin ?? (async () => {});\n const commitImpl = overrides.commit ?? (async () => {});\n const rollbackImpl = overrides.rollback ?? (async () => {});\n const closeImpl = overrides.close ?? (async () => {});\n const createSavepointImpl = overrides.createSavepoint ?? (async (_name: string) => {});\n const releaseSavepointImpl = overrides.releaseSavepoint ?? (async (_name: string) => {});\n const rollbackToSavepointImpl = overrides.rollbackToSavepoint ?? (async (_name: string) => {});\n\n const client: DBClient = {\n query: vi.fn((sql: string, params?: readonly unknown[]) => queryImpl(sql, params)) as DBClient['query'],\n begin: vi.fn(() => beginImpl()),\n commit: vi.fn(() => commitImpl()),\n rollback: vi.fn(() => rollbackImpl()),\n close: vi.fn(() => closeImpl()),\n createSavepoint: vi.fn((name: string) => createSavepointImpl(name)),\n releaseSavepoint: vi.fn((name: string) => releaseSavepointImpl(name)),\n rollbackToSavepoint: vi.fn((name: string) => rollbackToSavepointImpl(name)),\n };\n\n return client;\n}\n"],"mappings":";;;;AAcO,SAAS,UAAUA,YAA8B,CAAE,GAAW;CACjE,MAAMC,UAAmB,UAAU,WAAW;AAC9C,SAAQ,SAAR;AACI,OAAK,WACD,QAAO,IAAI;AACf,OAAK,SACD,QAAO,IAAI;AACf,UACI,OAAM,IAAI,OAAO,uBAAuB,QAAQ;CACvD;AACJ;;;;ACAM,SAAS,UAAUC,YAA+B,CAAE,GAAY;CACnE,MAAM,YAEF,UAAU,UAAU,OAAOC,MAAcC,aAAkC,EAAE,MAAM,CAAE,EAAW;CACpG,MAAM,YAAY,UAAU,UAAU,YAAY,CAAE;CACpD,MAAM,aAAa,UAAU,WAAW,YAAY,CAAE;CACtD,MAAM,eAAe,UAAU,aAAa,YAAY,CAAE;CAC1D,MAAM,YAAY,UAAU,UAAU,YAAY,CAAE;CACpD,MAAM,sBAAsB,UAAU,oBAAoB,OAAOC,UAAkB,CAAE;CACrF,MAAM,uBAAuB,UAAU,qBAAqB,OAAOA,UAAkB,CAAE;CACvF,MAAM,0BAA0B,UAAU,wBAAwB,OAAOA,UAAkB,CAAE;CAE7F,MAAMC,SAAmB;EACrB,OAAO,GAAG,GAAG,CAACC,KAAaC,WAAgC,UAAU,KAAK,OAAO,CAAC;EAClF,OAAO,GAAG,GAAG,MAAM,WAAW,CAAC;EAC/B,QAAQ,GAAG,GAAG,MAAM,YAAY,CAAC;EACjC,UAAU,GAAG,GAAG,MAAM,cAAc,CAAC;EACrC,OAAO,GAAG,GAAG,MAAM,WAAW,CAAC;EAC/B,iBAAiB,GAAG,GAAG,CAACC,SAAiB,oBAAoB,KAAK,CAAC;EACnE,kBAAkB,GAAG,GAAG,CAACA,SAAiB,qBAAqB,KAAK,CAAC;EACrE,qBAAqB,GAAG,GAAG,CAACA,SAAiB,wBAAwB,KAAK,CAAC;CAC9E;AAED,QAAO;AACV"}
@@ -1,7 +0,0 @@
1
- import type { GenericModelFactory } from '../factories';
2
- /**
3
- * Assertion helpers for Tango models.
4
- */
5
- export declare const assertions: {
6
- matchesSchema<TModel extends GenericModelFactory<Record<string, unknown>, unknown>>(model: TModel, data: unknown): asserts data is ReturnType<TModel["parse"]>;
7
- };
@@ -1,15 +0,0 @@
1
- import { __export } from "./chunk-BkvOhyD0.js";
2
-
3
- //#region src/assertions/assertions.ts
4
- const assertions = { matchesSchema(model, data) {
5
- model.parse(data);
6
- } };
7
-
8
- //#endregion
9
- //#region src/assertions/index.ts
10
- var assertions_exports = {};
11
- __export(assertions_exports, { assertions: () => assertions });
12
-
13
- //#endregion
14
- export { assertions, assertions_exports };
15
- //# sourceMappingURL=assertions-CCFZ53Y-.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"assertions-CCFZ53Y-.js","names":["model: TModel","data: unknown"],"sources":["../src/assertions/assertions.ts","../src/assertions/index.ts"],"sourcesContent":["import type { GenericModelFactory } from '../factories';\n\n/**\n * Assertion helpers for Tango models.\n */\nexport const assertions = {\n matchesSchema<TModel extends GenericModelFactory<Record<string, unknown>, unknown>>(\n model: TModel,\n data: unknown\n ): asserts data is ReturnType<TModel['parse']> {\n model.parse(data);\n },\n};\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { assertions } from './assertions';\n"],"mappings":";;;MAKa,aAAa,EACtB,cACIA,OACAC,MAC2C;AAC3C,OAAM,MAAM,KAAK;AACpB,EACJ"}
@@ -1,12 +0,0 @@
1
-
2
- //#region rolldown:runtime
3
- var __defProp = Object.defineProperty;
4
- var __export = (target, all) => {
5
- for (var name in all) __defProp(target, name, {
6
- get: all[name],
7
- enumerable: true
8
- });
9
- };
10
-
11
- //#endregion
12
- export { __export };