@holokai/holo-test 1.4.5 → 1.5.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.
Files changed (148) hide show
  1. package/README.md +216 -81
  2. package/dist/conformance/audit-tests.d.ts +4 -0
  3. package/dist/conformance/audit-tests.d.ts.map +1 -0
  4. package/dist/conformance/audit-tests.js +55 -0
  5. package/dist/conformance/audit-tests.js.map +1 -0
  6. package/dist/conformance/datastore-tests.d.ts +13 -0
  7. package/dist/conformance/datastore-tests.d.ts.map +1 -0
  8. package/dist/conformance/datastore-tests.js +121 -0
  9. package/dist/conformance/datastore-tests.js.map +1 -0
  10. package/dist/conformance/holo-fixture-loader.d.ts +4 -0
  11. package/dist/conformance/holo-fixture-loader.d.ts.map +1 -0
  12. package/dist/conformance/holo-fixture-loader.js +79 -0
  13. package/dist/conformance/holo-fixture-loader.js.map +1 -0
  14. package/dist/conformance/holo-fixture-tests.d.ts +4 -0
  15. package/dist/conformance/holo-fixture-tests.d.ts.map +1 -0
  16. package/dist/conformance/holo-fixture-tests.js +273 -0
  17. package/dist/conformance/holo-fixture-tests.js.map +1 -0
  18. package/dist/conformance/holo-fixture-types.d.ts +93 -0
  19. package/dist/conformance/holo-fixture-types.d.ts.map +1 -0
  20. package/dist/conformance/holo-fixture-types.js +2 -0
  21. package/dist/conformance/holo-fixture-types.js.map +1 -0
  22. package/dist/conformance/loader.d.ts +7 -0
  23. package/dist/conformance/loader.d.ts.map +1 -0
  24. package/dist/conformance/loader.js +71 -0
  25. package/dist/conformance/loader.js.map +1 -0
  26. package/dist/conformance/pipeline-tests.d.ts +4 -0
  27. package/dist/conformance/pipeline-tests.d.ts.map +1 -0
  28. package/dist/conformance/pipeline-tests.js +73 -0
  29. package/dist/conformance/pipeline-tests.js.map +1 -0
  30. package/dist/conformance/runner.d.ts +2 -0
  31. package/dist/conformance/runner.d.ts.map +1 -0
  32. package/dist/conformance/runner.js +102 -0
  33. package/dist/conformance/runner.js.map +1 -0
  34. package/dist/conformance/sdk-tests.d.ts +12 -0
  35. package/dist/conformance/sdk-tests.d.ts.map +1 -0
  36. package/dist/{services/http-fixture-server.js → conformance/sdk-tests.js} +56 -17
  37. package/dist/conformance/sdk-tests.js.map +1 -0
  38. package/dist/conformance/translator-tests.d.ts +4 -0
  39. package/dist/conformance/translator-tests.d.ts.map +1 -0
  40. package/dist/conformance/translator-tests.js +49 -0
  41. package/dist/conformance/translator-tests.js.map +1 -0
  42. package/dist/conformance/types.d.ts +81 -0
  43. package/dist/conformance/types.d.ts.map +1 -0
  44. package/dist/conformance/types.js +2 -0
  45. package/dist/conformance/types.js.map +1 -0
  46. package/dist/conformance/wire-tests.d.ts +4 -0
  47. package/dist/conformance/wire-tests.d.ts.map +1 -0
  48. package/dist/conformance/wire-tests.js +52 -0
  49. package/dist/conformance/wire-tests.js.map +1 -0
  50. package/dist/index.d.ts +13 -15
  51. package/dist/index.d.ts.map +1 -1
  52. package/dist/index.js +10 -14
  53. package/dist/index.js.map +1 -1
  54. package/dist/live/assertions.d.ts.map +1 -1
  55. package/dist/live/assertions.js +54 -21
  56. package/dist/live/assertions.js.map +1 -1
  57. package/dist/live/error-payloads.d.ts +5 -0
  58. package/dist/live/error-payloads.d.ts.map +1 -0
  59. package/dist/live/error-payloads.js +47 -0
  60. package/dist/live/error-payloads.js.map +1 -0
  61. package/dist/live/error-tester.d.ts +3 -0
  62. package/dist/live/error-tester.d.ts.map +1 -0
  63. package/dist/live/error-tester.js +121 -0
  64. package/dist/live/error-tester.js.map +1 -0
  65. package/dist/live/index.d.ts +3 -1
  66. package/dist/live/index.d.ts.map +1 -1
  67. package/dist/live/index.js +2 -0
  68. package/dist/live/index.js.map +1 -1
  69. package/dist/live/types.d.ts +9 -0
  70. package/dist/live/types.d.ts.map +1 -1
  71. package/dist/services/plugin-loader.d.ts +2 -1
  72. package/dist/services/plugin-loader.d.ts.map +1 -1
  73. package/dist/services/plugin-loader.js +2 -1
  74. package/dist/services/plugin-loader.js.map +1 -1
  75. package/dist/types.d.ts +0 -37
  76. package/dist/types.d.ts.map +1 -1
  77. package/package.json +3 -6
  78. package/dist/cli.d.ts +0 -3
  79. package/dist/cli.d.ts.map +0 -1
  80. package/dist/cli.js +0 -83
  81. package/dist/cli.js.map +0 -1
  82. package/dist/contracts/audit-contract.d.ts +0 -3
  83. package/dist/contracts/audit-contract.d.ts.map +0 -1
  84. package/dist/contracts/audit-contract.js +0 -11
  85. package/dist/contracts/audit-contract.js.map +0 -1
  86. package/dist/contracts/datastore-contract.d.ts +0 -12
  87. package/dist/contracts/datastore-contract.d.ts.map +0 -1
  88. package/dist/contracts/datastore-contract.js +0 -20
  89. package/dist/contracts/datastore-contract.js.map +0 -1
  90. package/dist/contracts/pipeline-contract.d.ts +0 -3
  91. package/dist/contracts/pipeline-contract.d.ts.map +0 -1
  92. package/dist/contracts/pipeline-contract.js +0 -9
  93. package/dist/contracts/pipeline-contract.js.map +0 -1
  94. package/dist/contracts/roundtrip-contract.d.ts +0 -3
  95. package/dist/contracts/roundtrip-contract.d.ts.map +0 -1
  96. package/dist/contracts/roundtrip-contract.js +0 -9
  97. package/dist/contracts/roundtrip-contract.js.map +0 -1
  98. package/dist/contracts/wire-contract.d.ts +0 -3
  99. package/dist/contracts/wire-contract.d.ts.map +0 -1
  100. package/dist/contracts/wire-contract.js +0 -9
  101. package/dist/contracts/wire-contract.js.map +0 -1
  102. package/dist/dsl/assertions.d.ts +0 -6
  103. package/dist/dsl/assertions.d.ts.map +0 -1
  104. package/dist/dsl/assertions.js +0 -54
  105. package/dist/dsl/assertions.js.map +0 -1
  106. package/dist/dsl/suite-builder.d.ts +0 -25
  107. package/dist/dsl/suite-builder.d.ts.map +0 -1
  108. package/dist/dsl/suite-builder.js +0 -96
  109. package/dist/dsl/suite-builder.js.map +0 -1
  110. package/dist/factories/worker-request-factory.d.ts +0 -5
  111. package/dist/factories/worker-request-factory.d.ts.map +0 -1
  112. package/dist/factories/worker-request-factory.js +0 -19
  113. package/dist/factories/worker-request-factory.js.map +0 -1
  114. package/dist/fixtures/fixture-loader.d.ts +0 -6
  115. package/dist/fixtures/fixture-loader.d.ts.map +0 -1
  116. package/dist/fixtures/fixture-loader.js +0 -23
  117. package/dist/fixtures/fixture-loader.js.map +0 -1
  118. package/dist/runner/test-reporter.d.ts +0 -3
  119. package/dist/runner/test-reporter.d.ts.map +0 -1
  120. package/dist/runner/test-reporter.js +0 -43
  121. package/dist/runner/test-reporter.js.map +0 -1
  122. package/dist/runner/test-runner.d.ts +0 -12
  123. package/dist/runner/test-runner.d.ts.map +0 -1
  124. package/dist/runner/test-runner.js +0 -37
  125. package/dist/runner/test-runner.js.map +0 -1
  126. package/dist/services/http-fixture-server.d.ts +0 -14
  127. package/dist/services/http-fixture-server.d.ts.map +0 -1
  128. package/dist/services/http-fixture-server.js.map +0 -1
  129. package/dist/testers/audit-tester.d.ts +0 -4
  130. package/dist/testers/audit-tester.d.ts.map +0 -1
  131. package/dist/testers/audit-tester.js +0 -74
  132. package/dist/testers/audit-tester.js.map +0 -1
  133. package/dist/testers/datastore-tester.d.ts +0 -17
  134. package/dist/testers/datastore-tester.d.ts.map +0 -1
  135. package/dist/testers/datastore-tester.js +0 -306
  136. package/dist/testers/datastore-tester.js.map +0 -1
  137. package/dist/testers/pipeline-tester.d.ts +0 -4
  138. package/dist/testers/pipeline-tester.d.ts.map +0 -1
  139. package/dist/testers/pipeline-tester.js +0 -62
  140. package/dist/testers/pipeline-tester.js.map +0 -1
  141. package/dist/testers/roundtrip-tester.d.ts +0 -3
  142. package/dist/testers/roundtrip-tester.d.ts.map +0 -1
  143. package/dist/testers/roundtrip-tester.js +0 -77
  144. package/dist/testers/roundtrip-tester.js.map +0 -1
  145. package/dist/testers/wire-tester.d.ts +0 -4
  146. package/dist/testers/wire-tester.d.ts.map +0 -1
  147. package/dist/testers/wire-tester.js +0 -87
  148. package/dist/testers/wire-tester.js.map +0 -1
@@ -0,0 +1,73 @@
1
+ import { expect, it } from 'vitest';
2
+ import { createResponseEnvelope, createWorkerRequest, processProviderEvents } from '@holokai/holo-sdk/provider';
3
+ import { toAsyncIter } from '@holokai/holo-sdk';
4
+ import { v4 as uuidv4 } from 'uuid';
5
+ export function registerPipelineTests(family, plugin, scenario) {
6
+ if (!scenario.pipeline || !scenario.providerChunks?.length)
7
+ return;
8
+ const expectedFailure = scenario.expectedFailure?.pipeline === true;
9
+ const t = expectedFailure ? it.fails : it;
10
+ t('pipeline', async () => {
11
+ const protocol = { id: uuidv4(), name: scenario.protocol, capability: 'chat' };
12
+ const workerRequest = createWorkerRequest({
13
+ provider: { id: uuidv4(), name: family },
14
+ protocol,
15
+ payload: {},
16
+ sourceId: uuidv4(),
17
+ requestId: uuidv4(),
18
+ organizationId: 'test-org',
19
+ isStreaming: scenario.streaming === true,
20
+ httpRequestDetails: { path: '/test', method: 'POST' },
21
+ });
22
+ const envelope = createResponseEnvelope(workerRequest, scenario.audit?.access_model ?? 'unknown');
23
+ const wire = await plugin.createWireAdapter({
24
+ requestId: workerRequest.requestId,
25
+ isStreaming: scenario.streaming === true,
26
+ protocol: scenario.protocol,
27
+ });
28
+ const providerEvents = scenario.providerChunks.map((chunk, i) => {
29
+ const isLast = i === scenario.providerChunks.length - 1;
30
+ if (isLast) {
31
+ return {
32
+ type: 'done',
33
+ requestId: workerRequest.requestId,
34
+ seq: i,
35
+ message: chunk,
36
+ text: scenario.expectedText ?? '',
37
+ ts: Date.now(),
38
+ };
39
+ }
40
+ return {
41
+ type: 'stream_event',
42
+ requestId: workerRequest.requestId,
43
+ seq: i,
44
+ event: chunk,
45
+ ts: Date.now(),
46
+ };
47
+ });
48
+ const collectedChunks = [];
49
+ let auditedRecord = null;
50
+ const publisher = {
51
+ publishChunk: async (_s, _r, data) => {
52
+ collectedChunks.push(data);
53
+ },
54
+ publishFinal: async (data) => {
55
+ auditedRecord = data;
56
+ },
57
+ };
58
+ const result = await processProviderEvents(toAsyncIter(providerEvents), wire, workerRequest, envelope, publisher);
59
+ expect(result.text).toBe(scenario.expectedText ?? '');
60
+ if (scenario.audit && auditedRecord) {
61
+ expect(auditedRecord.providerEvent).toBeTruthy();
62
+ }
63
+ if (scenario.expectedPipelineChunks) {
64
+ expect(collectedChunks).toEqual(scenario.expectedPipelineChunks);
65
+ }
66
+ else if (scenario.streaming) {
67
+ expect(collectedChunks.length).toBeGreaterThan(0);
68
+ const last = collectedChunks[collectedChunks.length - 1];
69
+ expect(Boolean(last?.done)).toBe(true);
70
+ }
71
+ });
72
+ }
73
+ //# sourceMappingURL=pipeline-tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-tests.js","sourceRoot":"","sources":["../../src/conformance/pipeline-tests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runConformance(): Promise<void>;
2
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/conformance/runner.ts"],"names":[],"mappings":"AAaA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CA0GpD"}
@@ -0,0 +1,102 @@
1
+ import { describe, it } from 'vitest';
2
+ import { discoverDatastorePlugins, discoverPlugins, loadDatastorePlugin, loadPlugin, } from '../services/plugin-loader';
3
+ import { loadDatastoreConfig, loadScenarios, loadSdkAdapter } from './loader';
4
+ import { loadHoloFixtures, loadPluginHoloScenarios } from './holo-fixture-loader';
5
+ import { registerHoloFixtureTests } from './holo-fixture-tests';
6
+ import { registerTranslatorTests } from './translator-tests';
7
+ import { registerWireTests } from './wire-tests';
8
+ import { registerAuditTests } from './audit-tests';
9
+ import { registerPipelineTests } from './pipeline-tests';
10
+ import { registerSdkTests } from './sdk-tests';
11
+ import { registerDatastoreTests } from './datastore-tests';
12
+ export async function runConformance() {
13
+ let registered = 0;
14
+ const providerPackages = await discoverPlugins();
15
+ for (const pkg of providerPackages) {
16
+ const family = pkg.replace('@holokai/holo-provider-', '');
17
+ const plugin = await loadPlugin(family);
18
+ const scenarios = await loadScenarios(family);
19
+ if (!scenarios.length)
20
+ continue;
21
+ const declaredProtocols = new Set(Object.values(plugin.protocols ?? {}));
22
+ const sdkAdapter = scenarios.some(s => s.sdk) ? await loadSdkAdapter(family) : undefined;
23
+ describe(family, () => {
24
+ for (const scenario of scenarios) {
25
+ if (!declaredProtocols.has(scenario.protocol)) {
26
+ throw new Error(`${family}: scenario "${scenario.name}" declares protocol "${scenario.protocol}", which is not in plugin.protocols (${[...declaredProtocols].join(', ')})`);
27
+ }
28
+ describe(`${scenario.protocol}/${scenario.name}`, () => {
29
+ registerTranslatorTests(plugin.translator, scenario);
30
+ registerWireTests(plugin, scenario);
31
+ registerAuditTests(plugin, scenario);
32
+ registerPipelineTests(family, plugin, scenario);
33
+ registerSdkTests(plugin, scenario, sdkAdapter);
34
+ });
35
+ }
36
+ });
37
+ registered += scenarios.length;
38
+ }
39
+ // Holo-fixture conformance: each fixture pins one Holo shape (request, response,
40
+ // or streaming chunk array); each plugin contributes a native counterpart at
41
+ // tests/data/holo/. The framework auto-generates per-plugin tests + N×N cross
42
+ // tests per fixture.
43
+ const holoFixtures = await loadHoloFixtures();
44
+ if (holoFixtures.length) {
45
+ const allFamilies = providerPackages.map(pkg => pkg.replace('@holokai/holo-provider-', ''));
46
+ const translators = new Map();
47
+ const scenariosByFamily = new Map();
48
+ for (const family of allFamilies) {
49
+ const plugin = await loadPlugin(family);
50
+ translators.set(family, plugin.translator);
51
+ const pluginScenarios = await loadPluginHoloScenarios(family);
52
+ if (pluginScenarios.length)
53
+ scenariosByFamily.set(family, pluginScenarios);
54
+ }
55
+ // Group plugin scenarios by Holo fixture id.
56
+ const byHoloId = new Map();
57
+ for (const [family, scenarios] of scenariosByFamily) {
58
+ for (const scenario of scenarios) {
59
+ let map = byHoloId.get(scenario.holoId);
60
+ if (!map) {
61
+ map = new Map();
62
+ byHoloId.set(scenario.holoId, map);
63
+ }
64
+ map.set(family, scenario);
65
+ }
66
+ }
67
+ // Validate every holoId on a plugin scenario maps to an existing fixture.
68
+ const fixtureIds = new Set(holoFixtures.map(f => f.id));
69
+ for (const id of byHoloId.keys()) {
70
+ if (!fixtureIds.has(id)) {
71
+ throw new Error(`Plugin scenario references holoId "${id}" but no Holo fixture with that id exists in packages/holo-test/holo/.`);
72
+ }
73
+ }
74
+ describe('holo-fixtures', () => {
75
+ for (const fixture of holoFixtures) {
76
+ const pluginScenarios = byHoloId.get(fixture.id) ?? new Map();
77
+ registerHoloFixtureTests(fixture, pluginScenarios, translators);
78
+ }
79
+ });
80
+ registered += holoFixtures.length;
81
+ }
82
+ const datastorePackages = await discoverDatastorePlugins();
83
+ for (const pkg of datastorePackages) {
84
+ const family = pkg.replace('@holokai/holo-datastore-', '');
85
+ const config = await loadDatastoreConfig(family);
86
+ if (!config)
87
+ continue;
88
+ const plugin = await loadDatastorePlugin(family);
89
+ describe(`datastore-${family}`, () => {
90
+ registerDatastoreTests(plugin, config);
91
+ });
92
+ registered += 1;
93
+ }
94
+ if (registered === 0) {
95
+ describe('conformance', () => {
96
+ it('no scenario data files or datastore configs found under any plugin', () => {
97
+ // Sentinel to keep vitest happy until something is authored.
98
+ });
99
+ });
100
+ }
101
+ }
102
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/conformance/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { IProviderPlugin } from '@holokai/holo-types/plugin';
2
+ import type { HoloScenario } from './types';
3
+ export interface ScenarioSdkAdapter {
4
+ family: string;
5
+ call(scenario: HoloScenario, port: number): Promise<unknown>;
6
+ routes(scenario: HoloScenario): {
7
+ method: string;
8
+ path: string;
9
+ } | undefined;
10
+ }
11
+ export declare function registerSdkTests(plugin: IProviderPlugin, scenario: HoloScenario, adapter: ScenarioSdkAdapter | undefined): void;
12
+ //# sourceMappingURL=sdk-tests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-tests.d.ts","sourceRoot":"","sources":["../../src/conformance/sdk-tests.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAEhE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AAE1C,MAAM,WAAW,kBAAkB;IAC/B,MAAM,EAAE,MAAM,CAAC;IAEf,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE7D,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAC;CAChF;AAED,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,eAAe,EACvB,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,kBAAkB,GAAG,SAAS,GACxC,IAAI,CAsBN"}
@@ -1,21 +1,44 @@
1
+ import { expect, it } from 'vitest';
1
2
  import express from 'express';
2
- export class HttpFixtureServer {
3
+ export function registerSdkTests(plugin, scenario, adapter) {
4
+ if (!scenario.sdk || !scenario.providerChunks?.length)
5
+ return;
6
+ if (!adapter) {
7
+ it.todo(`sdk (no sdk-adapter found for plugin)`);
8
+ return;
9
+ }
10
+ const expectedFailure = scenario.expectedFailure?.sdk === true;
11
+ const t = expectedFailure ? it.fails : it;
12
+ t('sdk', async () => {
13
+ const server = new HoloFixtureServer();
14
+ server.mount(scenario, plugin, adapter);
15
+ const port = await server.start();
16
+ try {
17
+ const result = await adapter.call(scenario, port);
18
+ assertPartialMatch(result, scenario.sdk.expectedResult);
19
+ }
20
+ finally {
21
+ await server.stop();
22
+ }
23
+ });
24
+ }
25
+ class HoloFixtureServer {
3
26
  server = null;
4
27
  app = express();
5
28
  constructor() {
6
29
  this.app.use(express.json());
7
30
  }
8
- mount(fixture, plugin, adapter) {
9
- const route = adapter.routes(fixture);
31
+ mount(scenario, plugin, adapter) {
32
+ const route = adapter.routes(scenario);
10
33
  if (!route)
11
34
  return;
12
35
  const handler = async (_req, res) => {
13
36
  const wire = await plugin.createWireAdapter({
14
- requestId: 'roundtrip-req',
15
- isStreaming: fixture.streaming,
16
- protocol: fixture.protocol,
37
+ requestId: 'sdk-test',
38
+ isStreaming: scenario.streaming === true,
39
+ protocol: scenario.protocol,
17
40
  });
18
- const events = buildProviderEvents(fixture);
41
+ const events = buildProviderEvents(scenario);
19
42
  let headersSent = false;
20
43
  for (const evt of events) {
21
44
  const chunks = await wire.fromProviderEvent(evt);
@@ -45,10 +68,9 @@ export class HttpFixtureServer {
45
68
  this.app.get(route.path, handler);
46
69
  }
47
70
  }
48
- async start(options) {
49
- const port = options?.port ?? 0;
71
+ async start() {
50
72
  return new Promise((resolve, reject) => {
51
- this.server = this.app.listen(port, () => {
73
+ this.server = this.app.listen(0, () => {
52
74
  const addr = this.server.address();
53
75
  if (typeof addr === 'object' && addr) {
54
76
  resolve(addr.port);
@@ -68,26 +90,43 @@ export class HttpFixtureServer {
68
90
  });
69
91
  }
70
92
  }
71
- function buildProviderEvents(fixture) {
72
- return fixture.providerChunks.map((chunk, i) => {
73
- const isLast = i === fixture.providerChunks.length - 1;
93
+ function buildProviderEvents(scenario) {
94
+ return scenario.providerChunks.map((chunk, i) => {
95
+ const isLast = i === scenario.providerChunks.length - 1;
74
96
  if (isLast) {
75
97
  return {
76
98
  type: 'done',
77
- requestId: 'roundtrip-req',
99
+ requestId: 'sdk-test',
78
100
  seq: i,
79
101
  message: chunk,
80
- text: fixture.expectedText,
102
+ text: scenario.expectedText ?? '',
81
103
  ts: Date.now(),
82
104
  };
83
105
  }
84
106
  return {
85
107
  type: 'stream_event',
86
- requestId: 'roundtrip-req',
108
+ requestId: 'sdk-test',
87
109
  seq: i,
88
110
  event: chunk,
89
111
  ts: Date.now(),
90
112
  };
91
113
  });
92
114
  }
93
- //# sourceMappingURL=http-fixture-server.js.map
115
+ function assertPartialMatch(actual, expected, path = 'sdk.result') {
116
+ if (Array.isArray(expected)) {
117
+ expect(Array.isArray(actual), `${path} should be array`).toBe(true);
118
+ const arr = actual;
119
+ expect(arr.length, `${path}.length`).toBe(expected.length);
120
+ expected.forEach((item, i) => assertPartialMatch(arr[i], item, `${path}[${i}]`));
121
+ return;
122
+ }
123
+ if (expected && typeof expected === 'object') {
124
+ expect(actual, path).toBeTypeOf('object');
125
+ for (const [k, v] of Object.entries(expected)) {
126
+ assertPartialMatch(actual?.[k], v, `${path}.${k}`);
127
+ }
128
+ return;
129
+ }
130
+ expect(actual, path).toEqual(expected);
131
+ }
132
+ //# sourceMappingURL=sdk-tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-tests.js","sourceRoot":"","sources":["../../src/conformance/sdk-tests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { IProviderTranslator } from '@holokai/holo-types/provider';
2
+ import type { HoloScenario } from './types';
3
+ export declare function registerTranslatorTests(translator: IProviderTranslator, scenario: HoloScenario): void;
4
+ //# sourceMappingURL=translator-tests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translator-tests.d.ts","sourceRoot":"","sources":["../../src/conformance/translator-tests.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,8BAA8B,CAAC;AAEtE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AAmB1C,wBAAgB,uBAAuB,CACnC,UAAU,EAAE,mBAAmB,EAC/B,QAAQ,EAAE,YAAY,GACvB,IAAI,CA6DN"}
@@ -0,0 +1,49 @@
1
+ import { expect, it } from 'vitest';
2
+ function isExpectedFailure(scenario, side, direction) {
3
+ const flag = scenario.expectedFailure?.[side];
4
+ if (flag === undefined)
5
+ return false;
6
+ if (typeof flag === 'boolean')
7
+ return flag;
8
+ return flag[direction] === true;
9
+ }
10
+ function maybeFailing(expectedFailure) {
11
+ return expectedFailure ? it.fails : it;
12
+ }
13
+ export function registerTranslatorTests(translator, scenario) {
14
+ if (scenario.request) {
15
+ const { native, holo } = scenario.request;
16
+ maybeFailing(isExpectedFailure(scenario, 'request', 'toHolo'))('request: toHolo', async () => {
17
+ const result = await translator.toHoloRequest(native);
18
+ expect(result).toEqual(holo);
19
+ });
20
+ maybeFailing(isExpectedFailure(scenario, 'request', 'fromHolo'))('request: fromHolo', async () => {
21
+ const result = await translator.fromHoloRequest(holo);
22
+ expect(result).toEqual(native);
23
+ });
24
+ maybeFailing(isExpectedFailure(scenario, 'request', 'roundTrip'))('request: round-trip (native → Holo → native)', async () => {
25
+ const intermediate = await translator.toHoloRequest(native);
26
+ const back = await translator.fromHoloRequest(intermediate);
27
+ expect(back).toEqual(native);
28
+ });
29
+ }
30
+ if (scenario.response) {
31
+ const { native, holo } = scenario.response;
32
+ maybeFailing(isExpectedFailure(scenario, 'response', 'toHolo'))('response: toHolo', async () => {
33
+ const result = await translator.toHoloResponse(native);
34
+ expect(result).toEqual(holo);
35
+ });
36
+ maybeFailing(isExpectedFailure(scenario, 'response', 'fromHolo'))('response: fromHolo', async () => {
37
+ const result = await translator.fromHoloResponse(holo);
38
+ expect(result).toEqual(native);
39
+ });
40
+ maybeFailing(isExpectedFailure(scenario, 'response', 'roundTrip'))('response: round-trip (native → Holo → native)', async () => {
41
+ const intermediate = await translator.toHoloResponse(native);
42
+ const back = await translator.fromHoloResponse(intermediate);
43
+ expect(back).toEqual(native);
44
+ });
45
+ }
46
+ // Streaming-translator round-trip is exercised via the holo-fixture
47
+ // `fromHoloStream` / `toHoloStream` tests in holo-fixture-tests.ts.
48
+ }
49
+ //# sourceMappingURL=translator-tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translator-tests.js","sourceRoot":"","sources":["../../src/conformance/translator-tests.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { HoloRequest, HoloResponse } from '@holokai/holo-types/holo';
2
+ import type { ProviderResponseStatus } from '@holokai/holo-types/entities';
3
+ export interface HoloScenarioRequest<TNative = unknown> {
4
+ native: TNative;
5
+ holo: Partial<HoloRequest>;
6
+ }
7
+ export interface HoloScenarioResponse<TNative = unknown> {
8
+ native: TNative;
9
+ holo: Partial<HoloResponse>;
10
+ }
11
+ export interface HoloScenarioWire {
12
+ expectedStatus: number;
13
+ expectedHeaders: Record<string, string>;
14
+ expectedWire: string[];
15
+ }
16
+ export interface HoloScenarioAudit {
17
+ access_model?: string;
18
+ input_tokens?: number;
19
+ output_tokens?: number;
20
+ status: ProviderResponseStatus;
21
+ metadata?: Record<string, unknown>;
22
+ }
23
+ export interface HoloScenarioSdk<TRequest = unknown, TResult = unknown> {
24
+ request: TRequest;
25
+ expectedResult: TResult;
26
+ }
27
+ type ExpectedFailureFlag<TDirection extends string = string> = boolean | (Partial<Record<TDirection, boolean>>);
28
+ export interface HoloScenario<TNativeRequest = unknown, TNativeResponse = unknown, TNativeChunk = unknown, TSdkRequest = unknown, TSdkResult = unknown> {
29
+ name: string;
30
+ protocol: string;
31
+ /** Request-side translator data. */
32
+ request?: HoloScenarioRequest<TNativeRequest>;
33
+ /** Response-side translator data. */
34
+ response?: HoloScenarioResponse<TNativeResponse>;
35
+ /**
36
+ * Streaming mode flag. Used by wire/audit/pipeline/sdk tests to set up the
37
+ * provider event sequence and the wire adapter's `isStreaming`.
38
+ */
39
+ streaming?: boolean;
40
+ /**
41
+ * Provider response chunks consumed by wire/audit/pipeline/sdk tests.
42
+ * For non-streaming, a single-element array. For streaming, the chunk sequence.
43
+ */
44
+ providerChunks?: TNativeChunk[];
45
+ /**
46
+ * Concatenated text result expected after consuming all chunks.
47
+ * Used by wire (final `done` event), audit (token accounting), and pipeline (text assertion).
48
+ */
49
+ expectedText?: string;
50
+ /** Wire-conformance assertions (chunk bodies, status, headers). */
51
+ wire?: HoloScenarioWire;
52
+ /** Audit-conformance assertions on the produced ProviderResponse. */
53
+ audit?: HoloScenarioAudit;
54
+ /** SDK pipeline (real client → fixture HTTP server → assertion). */
55
+ sdk?: HoloScenarioSdk<TSdkRequest, TSdkResult>;
56
+ /** Enable the pipeline test path. Reuses providerChunks/expectedText. */
57
+ pipeline?: boolean;
58
+ /**
59
+ * Optional chunk-level shape assertion for pipeline-tests. When provided, the
60
+ * collected `WireChunk[]` (what `publishChunk` receives during the run) must
61
+ * match this expected sequence. Inputs are compared after `stripProviderMetadata`
62
+ * to ignore translator pass-through fields.
63
+ *
64
+ * When omitted, pipeline-tests still verifies structural invariants (count > 0,
65
+ * last chunk carries `done`) and — when the protocol declares one — runs
66
+ * `assertEventSequence` against the input ProviderEvents.
67
+ */
68
+ expectedPipelineChunks?: unknown[];
69
+ /** Pin known translator/wire/audit losses without polluting CI red. */
70
+ expectedFailure?: {
71
+ request?: ExpectedFailureFlag<'toHolo' | 'fromHolo' | 'roundTrip'>;
72
+ response?: ExpectedFailureFlag<'toHolo' | 'fromHolo' | 'roundTrip'>;
73
+ wire?: boolean;
74
+ audit?: boolean;
75
+ sdk?: boolean;
76
+ pipeline?: boolean;
77
+ reason?: string;
78
+ };
79
+ }
80
+ export {};
81
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/conformance/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,WAAW,EAAE,YAAY,EAAC,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAC,sBAAsB,EAAC,MAAM,8BAA8B,CAAC;AAEzE,MAAM,WAAW,mBAAmB,CAAC,OAAO,GAAG,OAAO;IAClD,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,oBAAoB,CAAC,OAAO,GAAG,OAAO;IACnD,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,eAAe,CAAC,QAAQ,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO;IAClE,OAAO,EAAE,QAAQ,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;CAC3B;AAED,KAAK,mBAAmB,CAAC,UAAU,SAAS,MAAM,GAAG,MAAM,IACrD,OAAO,GACP,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;AAE7C,MAAM,WAAW,YAAY,CACzB,cAAc,GAAG,OAAO,EACxB,eAAe,GAAG,OAAO,EACzB,YAAY,GAAG,OAAO,EACtB,WAAW,GAAG,OAAO,EACrB,UAAU,GAAG,OAAO;IAEpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IAEjB,oCAAoC;IACpC,OAAO,CAAC,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAC;IAC9C,qCAAqC;IACrC,QAAQ,CAAC,EAAE,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAEjD;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,cAAc,CAAC,EAAE,YAAY,EAAE,CAAC;IAEhC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,mEAAmE;IACnE,IAAI,CAAC,EAAE,gBAAgB,CAAC;IAExB,qEAAqE;IACrE,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAE1B,oEAAoE;IACpE,GAAG,CAAC,EAAE,eAAe,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAE/C,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;;;OASG;IACH,sBAAsB,CAAC,EAAE,OAAO,EAAE,CAAC;IAEnC,uEAAuE;IACvE,eAAe,CAAC,EAAE;QACd,OAAO,CAAC,EAAE,mBAAmB,CAAC,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC,CAAC;QACnE,QAAQ,CAAC,EAAE,mBAAmB,CAAC,QAAQ,GAAG,UAAU,GAAG,WAAW,CAAC,CAAC;QACpE,IAAI,CAAC,EAAE,OAAO,CAAC;QACf,KAAK,CAAC,EAAE,OAAO,CAAC;QAChB,GAAG,CAAC,EAAE,OAAO,CAAC;QACd,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACL"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/conformance/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { IProviderPlugin } from '@holokai/holo-types/plugin';
2
+ import type { HoloScenario } from './types';
3
+ export declare function registerWireTests(plugin: IProviderPlugin, scenario: HoloScenario): void;
4
+ //# sourceMappingURL=wire-tests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-tests.d.ts","sourceRoot":"","sources":["../../src/conformance/wire-tests.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,4BAA4B,CAAC;AAEhE,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,SAAS,CAAC;AAE1C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI,CAmCvF"}
@@ -0,0 +1,52 @@
1
+ import { expect, it } from 'vitest';
2
+ export function registerWireTests(plugin, scenario) {
3
+ if (!scenario.wire || !scenario.providerChunks?.length)
4
+ return;
5
+ const expectedFailure = scenario.expectedFailure?.wire === true;
6
+ const t = expectedFailure ? it.fails : it;
7
+ t('wire', async () => {
8
+ const wire = await plugin.createWireAdapter({
9
+ requestId: 'test-req',
10
+ isStreaming: scenario.streaming === true,
11
+ protocol: scenario.protocol,
12
+ });
13
+ const allChunks = [];
14
+ for (let i = 0; i < scenario.providerChunks.length; i++) {
15
+ const isLast = i === scenario.providerChunks.length - 1;
16
+ const event = toProviderEvent(scenario, i, isLast);
17
+ const chunks = await wire.fromProviderEvent(event);
18
+ allChunks.push(...chunks);
19
+ }
20
+ const firstChunk = allChunks[0];
21
+ expect(firstChunk, 'wire emitted no chunks').toBeDefined();
22
+ expect(firstChunk.status).toBe(scenario.wire.expectedStatus);
23
+ for (const [k, v] of Object.entries(scenario.wire.expectedHeaders)) {
24
+ expect(firstChunk.headers?.[k], `header ${k}`).toBe(v);
25
+ }
26
+ const lastChunk = allChunks[allChunks.length - 1];
27
+ expect(lastChunk.done, 'last chunk must mark done').toBe(true);
28
+ const wireBodies = allChunks.map(c => c.body);
29
+ expect(wireBodies).toEqual(scenario.wire.expectedWire);
30
+ });
31
+ }
32
+ function toProviderEvent(scenario, index, isLast) {
33
+ const chunk = scenario.providerChunks[index];
34
+ if (isLast) {
35
+ return {
36
+ type: 'done',
37
+ requestId: 'test-req',
38
+ seq: index,
39
+ message: chunk,
40
+ text: scenario.expectedText ?? '',
41
+ ts: Date.now(),
42
+ };
43
+ }
44
+ return {
45
+ type: 'stream_event',
46
+ requestId: 'test-req',
47
+ seq: index,
48
+ event: chunk,
49
+ ts: Date.now(),
50
+ };
51
+ }
52
+ //# sourceMappingURL=wire-tests.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wire-tests.js","sourceRoot":"","sources":["../../src/conformance/wire-tests.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,21 +1,19 @@
1
- export { testWire } from './testers/wire-tester';
2
- export { testAudit } from './testers/audit-tester';
3
- export { testPipeline } from './testers/pipeline-tester';
4
- export { testRoundTrip } from './testers/roundtrip-tester';
5
- export type { FixtureScenario, SdkAdapter, TestResult, AssertionError } from './types';
6
- export { createTestWorkerRequest, createTestEnvelope } from './factories/worker-request-factory';
7
- export { suite } from './dsl/suite-builder';
8
- export { runTests, type RunOptions } from './runner/test-runner';
9
- export { loadFixtures } from './fixtures/fixture-loader';
1
+ export type { TestResult, AssertionError } from './types';
10
2
  export { loadPlugin, loadAllPlugins, loadDatastorePlugin, discoverPlugins, getLoadedPlugins } from './services/plugin-loader';
11
- export { HttpFixtureServer } from './services/http-fixture-server';
12
3
  export { parseSseBody, type SseFrame } from './services/sse-parser';
13
4
  export { parseNdjsonBody } from './services/ndjson-parser';
14
- export { runWireContract } from './contracts/wire-contract';
15
- export { runAuditContract } from './contracts/audit-contract';
16
- export { runPipelineContract } from './contracts/pipeline-contract';
17
- export { runRoundTripContract } from './contracts/roundtrip-contract';
18
- export { runDatastoreContract, type DatastoreTestConfig } from './contracts/datastore-contract';
5
+ export { registerDatastoreTests, type DatastoreConfig } from './conformance/datastore-tests';
6
+ export { type HoloScenario, type HoloScenarioRequest, type HoloScenarioResponse, type HoloScenarioWire, type HoloScenarioAudit, type HoloScenarioSdk, } from './conformance/types';
7
+ export { runConformance } from './conformance/runner';
8
+ export { loadScenarios, loadSdkAdapter, loadDatastoreConfig } from './conformance/loader';
9
+ export { loadHoloFixtures, loadPluginHoloScenarios } from './conformance/holo-fixture-loader';
10
+ export { registerHoloFixtureTests } from './conformance/holo-fixture-tests';
11
+ export type { HoloFixture, HoloFixtureKind, HoloRequestFixture, HoloResponseFixture, HoloStreamingFixture, PluginHoloScenario, PluginHoloScenarioExpectedFailure, PluginHoloScenarioThrows, } from './conformance/holo-fixture-types';
12
+ export { registerTranslatorTests } from './conformance/translator-tests';
13
+ export { registerWireTests } from './conformance/wire-tests';
14
+ export { registerAuditTests } from './conformance/audit-tests';
15
+ export { registerPipelineTests } from './conformance/pipeline-tests';
16
+ export { registerSdkTests, type ScenarioSdkAdapter } from './conformance/sdk-tests';
19
17
  export { hasGateway, gatewayUrl, getTestConfig, createTestClient } from './helpers/env';
20
18
  export { collectStreamText, collectStreamEvents } from './helpers/stream-helpers';
21
19
  export { createMockFetch, createSseMockFetch } from './helpers/mock-fetch';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,QAAQ,EAAC,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAC,SAAS,EAAC,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAC,YAAY,EAAC,MAAM,2BAA2B,CAAC;AACvD,OAAO,EAAC,aAAa,EAAC,MAAM,4BAA4B,CAAC;AACzD,YAAY,EAAC,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAC,MAAM,SAAS,CAAC;AACrF,OAAO,EAAC,uBAAuB,EAAE,kBAAkB,EAAC,MAAM,oCAAoC,CAAC;AAC/F,OAAO,EAAC,KAAK,EAAC,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAC,QAAQ,EAAE,KAAK,UAAU,EAAC,MAAM,sBAAsB,CAAC;AAC/D,OAAO,EAAC,YAAY,EAAC,MAAM,2BAA2B,CAAC;AACvD,OAAO,EACH,UAAU,EAAE,cAAc,EAAE,mBAAmB,EAAE,eAAe,EAAE,gBAAgB,EACrF,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAC,iBAAiB,EAAC,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAC,YAAY,EAAE,KAAK,QAAQ,EAAC,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAC,gBAAgB,EAAC,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAC,mBAAmB,EAAC,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAC,oBAAoB,EAAC,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAC,oBAAoB,EAAE,KAAK,mBAAmB,EAAC,MAAM,gCAAgC,CAAC;AAC9F,OAAO,EAAC,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACtF,OAAO,EAAC,iBAAiB,EAAE,mBAAmB,EAAC,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAC,eAAe,EAAE,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAC,iBAAiB,EAAE,cAAc,EAAC,MAAM,kBAAkB,CAAC;AACnE,YAAY,EAAC,kBAAkB,EAAE,eAAe,EAAE,uBAAuB,EAAC,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAC,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAC,WAAW,EAAE,mBAAmB,EAAE,YAAY,EAAE,sBAAsB,EAAC,MAAM,QAAQ,CAAC;AAC9F,YAAY,EAAC,cAAc,EAAE,cAAc,EAAC,MAAM,QAAQ,CAAC;AAC3D,OAAO,EACH,gBAAgB,EAAE,uBAAuB,EAAE,iBAAiB,EAC5D,aAAa,EAAE,cAAc,EAC7B,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EACrD,KAAK,cAAc,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,QAAQ,EAAE,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAC,MAAM,EAAC,MAAM,eAAe,CAAC;AACrC,OAAO,EAAC,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAC,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAC,UAAU,EAAE,cAAc,EAAC,MAAM,SAAS,CAAC;AACxD,OAAO,EACH,UAAU,EAAE,cAAc,EAAE,mBAAmB,EAAE,eAAe,EAAE,gBAAgB,EACrF,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAC,YAAY,EAAE,KAAK,QAAQ,EAAC,MAAM,uBAAuB,CAAC;AAClE,OAAO,EAAC,eAAe,EAAC,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAC,sBAAsB,EAAE,KAAK,eAAe,EAAC,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EACH,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAC,cAAc,EAAC,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAC,aAAa,EAAE,cAAc,EAAE,mBAAmB,EAAC,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAC,gBAAgB,EAAE,uBAAuB,EAAC,MAAM,mCAAmC,CAAC;AAC5F,OAAO,EAAC,wBAAwB,EAAC,MAAM,kCAAkC,CAAC;AAC1E,YAAY,EACR,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,oBAAoB,EACpB,kBAAkB,EAClB,iCAAiC,EACjC,wBAAwB,GAC3B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAC,uBAAuB,EAAC,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAC,iBAAiB,EAAC,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAC,kBAAkB,EAAC,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAC,qBAAqB,EAAC,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAC,gBAAgB,EAAE,KAAK,kBAAkB,EAAC,MAAM,yBAAyB,CAAC;AAClF,OAAO,EAAC,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAC,MAAM,eAAe,CAAC;AACtF,OAAO,EAAC,iBAAiB,EAAE,mBAAmB,EAAC,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAC,eAAe,EAAE,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAC,iBAAiB,EAAE,cAAc,EAAC,MAAM,kBAAkB,CAAC;AACnE,YAAY,EAAC,kBAAkB,EAAE,eAAe,EAAE,uBAAuB,EAAC,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAC,gBAAgB,EAAC,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAC,WAAW,EAAE,mBAAmB,EAAE,YAAY,EAAE,sBAAsB,EAAC,MAAM,QAAQ,CAAC;AAC9F,YAAY,EAAC,cAAc,EAAE,cAAc,EAAC,MAAM,QAAQ,CAAC;AAC3D,OAAO,EACH,gBAAgB,EAAE,uBAAuB,EAAE,iBAAiB,EAC5D,aAAa,EAAE,cAAc,EAC7B,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,eAAe,EACrD,KAAK,cAAc,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAC,QAAQ,EAAE,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAC1D,OAAO,EAAC,MAAM,EAAC,MAAM,eAAe,CAAC;AACrC,OAAO,EAAC,eAAe,EAAE,kBAAkB,EAAE,mBAAmB,EAAC,MAAM,iBAAiB,CAAC"}