@testsmith/api-spector 0.6.1 → 0.6.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 (30) hide show
  1. package/out/main/agents.js +2 -1
  2. package/out/main/chunks/{snapshots-Y33M1SEy.js → broker-client-WEymdqAK.js} +119 -10
  3. package/out/main/chunks/{cli-common-BKYgsbGB.js → cli-common-vASoDfQH.js} +3 -2
  4. package/out/main/chunks/data-files-Br2h3Dt2.js +85 -0
  5. package/out/main/chunks/escape-BwPM4Tf6.js +9 -0
  6. package/out/main/chunks/{handle-BFaeFA0A.js → handle-CL-nWtYA.js} +11 -2
  7. package/out/main/chunks/{import-D9LH0isB.js → import-DdXhO56X.js} +2 -2
  8. package/out/main/chunks/{request-collection-BQIo1765.js → request-collection-Hqh3I3rs.js} +75 -15
  9. package/out/main/chunks/{request-exec-5_3279w1.js → request-exec-DAFA6Fap.js} +19 -1
  10. package/out/main/chunks/{soap-handler-CWn3o6Py.js → soap-handler-BAPCALkN.js} +2 -2
  11. package/out/main/compare.js +2 -1
  12. package/out/main/contract.js +50 -147
  13. package/out/main/coverage.js +2 -1
  14. package/out/main/generate-tests.js +2 -1
  15. package/out/main/index.js +131 -36
  16. package/out/main/lib.js +2 -2
  17. package/out/main/mock.js +2 -1
  18. package/out/main/record.js +2 -1
  19. package/out/main/runner.js +80 -12
  20. package/out/main/wsdl.js +5 -4
  21. package/out/preload/index.js +21 -3
  22. package/out/renderer/assets/{GraphQLEditor-8wU1UeBL.js → GraphQLEditor-DtppmZJO.js} +3 -1
  23. package/out/renderer/assets/{SoapEditor-DQwLLqCX.js → SoapEditor-BwSm12wH.js} +4 -2
  24. package/out/renderer/assets/ajv-2MAg6kGF.js +6153 -0
  25. package/out/renderer/assets/codemirror-F6m3Hm1M.js +26552 -0
  26. package/out/renderer/assets/index-B3mtLdU3.css +2 -0
  27. package/out/renderer/assets/{index-CdxTj7i6.js → index-D6-zmXen.js} +17491 -49305
  28. package/out/renderer/index.html +4 -2
  29. package/package.json +1 -1
  30. package/out/renderer/assets/index-CkHujZU3.css +0 -2
@@ -2,17 +2,18 @@
2
2
  "use strict";
3
3
  const promises = require("fs/promises");
4
4
  const path = require("path");
5
- const snapshots = require("./chunks/snapshots-Y33M1SEy.js");
5
+ const brokerClient = require("./chunks/broker-client-WEymdqAK.js");
6
+ const escape = require("./chunks/escape-BwPM4Tf6.js");
6
7
  const crypto = require("crypto");
7
8
  const undici = require("undici");
8
9
  const os = require("os");
9
- const cliCommon = require("./chunks/cli-common-BKYgsbGB.js");
10
+ const cliCommon = require("./chunks/cli-common-vASoDfQH.js");
10
11
  const child_process = require("child_process");
11
12
  const jsYaml = require("js-yaml");
12
13
  const environments = require("./chunks/environments-iM3SUM-4.js");
13
- require("./chunks/request-exec-5_3279w1.js");
14
+ require("./chunks/request-exec-DAFA6Fap.js");
14
15
  require("tls");
15
- require("./chunks/handle-BFaeFA0A.js");
16
+ require("./chunks/handle-CL-nWtYA.js");
16
17
  require("node:fs");
17
18
  require("node:os");
18
19
  require("node:path");
@@ -24,19 +25,17 @@ require("jsonpath-plus");
24
25
  require("@xmldom/xmldom");
25
26
  require("http");
26
27
  require("ajv");
27
- function escapeXml(s) {
28
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
29
- }
28
+ require("./chunks/data-files-Br2h3Dt2.js");
30
29
  function caseXml(r) {
31
- const name = escapeXml(`${r.method} ${r.requestName}`);
30
+ const name = escape.escapeXml(`${r.method} ${r.requestName}`);
32
31
  const time = ((r.durationMs ?? 0) / 1e3).toFixed(3);
33
- const classnm = escapeXml(r.url);
32
+ const classnm = escape.escapeXml(r.url);
34
33
  if (r.passed) {
35
34
  return ` <testcase name="${name}" classname="${classnm}" time="${time}"/>`;
36
35
  }
37
36
  const messages = r.violations.map((v) => `${v.type}: ${v.message}${v.path ? ` (${v.path})` : ""}`);
38
- const summary = escapeXml(messages[0] ?? "contract failed");
39
- const detail = escapeXml(messages.join("\n"));
37
+ const summary = escape.escapeXml(messages[0] ?? "contract failed");
38
+ const detail = escape.escapeXml(messages.join("\n"));
40
39
  return [
41
40
  ` <testcase name="${name}" classname="${classnm}" time="${time}">`,
42
41
  ` <failure message="${summary}">${detail}</failure>`,
@@ -48,7 +47,7 @@ function toJUnitXml(report, suiteName = "contract") {
48
47
  const lines = [
49
48
  '<?xml version="1.0" encoding="UTF-8"?>',
50
49
  `<testsuites name="api-spector" tests="${report.total}" failures="${report.failed}" time="${time}">`,
51
- ` <testsuite name="${escapeXml(`${suiteName}:${report.mode}`)}" tests="${report.total}" failures="${report.failed}" time="${time}">`,
50
+ ` <testsuite name="${escape.escapeXml(`${suiteName}:${report.mode}`)}" tests="${report.total}" failures="${report.failed}" time="${time}">`,
52
51
  ...report.results.map(caseXml),
53
52
  " </testsuite>",
54
53
  "</testsuites>"
@@ -133,102 +132,6 @@ async function fireWebhooks(hooks, payload, env = process.env, log = console.log
133
132
  }
134
133
  }));
135
134
  }
136
- function brokerConfigFromEnv() {
137
- return {
138
- endpoint: (process.env["API_SPECTOR_CLOUD_ENDPOINT"] || "https://api-spector.dev").replace(/\/+$/, ""),
139
- token: process.env["API_SPECTOR_TOKEN"] || ""
140
- };
141
- }
142
- async function brokerFetch(cfg, path2, method, body) {
143
- if (!cfg.token) throw new Error("No API token. Set API_SPECTOR_TOKEN (create one in the cloud dashboard under Tokens).");
144
- const url = cfg.endpoint + path2;
145
- let res;
146
- try {
147
- res = await undici.fetch(url, {
148
- method,
149
- headers: {
150
- "Content-Type": "application/json",
151
- Accept: "application/json",
152
- Authorization: `Bearer ${cfg.token}`
153
- },
154
- body: body === void 0 ? void 0 : JSON.stringify(body)
155
- });
156
- } catch (err) {
157
- throw new Error(`Could not reach ${url}: ${err.message}`);
158
- }
159
- const text = await res.text();
160
- let json;
161
- try {
162
- json = text ? JSON.parse(text) : {};
163
- } catch {
164
- json = { raw: text };
165
- }
166
- return { status: res.status, ok: res.ok, json };
167
- }
168
- function fail(r, what) {
169
- const detail = r.json?.error || r.json?.message || (r.status === 401 ? "Unauthorized (check API_SPECTOR_TOKEN)" : `HTTP ${r.status}`);
170
- throw new Error(`${what}: ${detail}`);
171
- }
172
- async function publishPact(cfg, input) {
173
- const r = await brokerFetch(cfg, "/api/contracts", "PUT", {
174
- consumer: input.consumer,
175
- consumerVersion: input.consumerVersion,
176
- provider: input.provider,
177
- content: input.pact
178
- });
179
- if (!r.ok) fail(r, "Publish pact failed");
180
- }
181
- async function publishSpec(cfg, input) {
182
- const r = await brokerFetch(cfg, "/api/provider-contracts", "PUT", {
183
- pacticipant: input.pacticipant,
184
- version: input.version,
185
- spec: input.spec,
186
- // Optional provider self-verification (its own tests run against this spec).
187
- ...input.results ? { results: input.results } : {}
188
- });
189
- if (!r.ok) fail(r, "Publish spec failed");
190
- }
191
- async function canIDeploy(cfg, input) {
192
- const q = new URLSearchParams({ pacticipant: input.pacticipant, version: input.version, environment: input.environment }).toString();
193
- const r = await brokerFetch(cfg, "/can-i-deploy?" + q, "GET");
194
- if (r.status !== 200 && r.status !== 409) fail(r, "can-i-deploy failed");
195
- return { deployable: r.status === 200, reason: r.json?.summary?.reason || "" };
196
- }
197
- async function deployPreview(cfg, input) {
198
- const q = new URLSearchParams({ pacticipant: input.pacticipant, version: input.version, environment: input.environment }).toString();
199
- const r = await brokerFetch(cfg, "/api/deploy-preview?" + q, "GET");
200
- if (!r.ok) fail(r, "deploy-preview failed");
201
- return r.json;
202
- }
203
- async function recordDeployment(cfg, input) {
204
- const path2 = `/pacticipants/${encodeURIComponent(input.pacticipant)}/versions/${encodeURIComponent(input.version)}/deployed-versions/environment/${encodeURIComponent(input.environment)}`;
205
- const r = await brokerFetch(cfg, path2, "POST", {});
206
- if (!r.ok) fail(r, "record-deployment failed");
207
- }
208
- async function checkCompatibility(cfg, input) {
209
- const q = new URLSearchParams({ consumer: input.consumer, consumerVersion: input.consumerVersion, provider: input.provider, providerVersion: input.providerVersion }).toString();
210
- const r = await brokerFetch(cfg, "/api/compatibility?" + q, "GET");
211
- if (r.status !== 200 && r.status !== 409) fail(r, "Compatibility check failed");
212
- return { compatible: r.json?.compatible === true, checks: r.json?.checks ?? [] };
213
- }
214
- async function fetchContracts(cfg, input = {}) {
215
- const q = new URLSearchParams();
216
- if (input.consumer) q.set("consumer", input.consumer);
217
- if (input.provider) q.set("provider", input.provider);
218
- const suffix = q.toString() ? "?" + q.toString() : "";
219
- const r = await brokerFetch(cfg, "/api/contracts" + suffix, "GET");
220
- if (!r.ok) fail(r, "Fetch contracts failed");
221
- return r.json?.contracts ?? [];
222
- }
223
- async function publishVerification(cfg, input) {
224
- const r = await brokerFetch(cfg, "/api/verifications", "POST", {
225
- contractId: input.contractId,
226
- providerVersion: input.providerVersion,
227
- success: input.success,
228
- ...input.buildUrl ? { buildUrl: input.buildUrl } : {}
229
- });
230
- if (!r.ok) fail(r, "Publish verification failed");
231
- }
232
135
  function resolveVersion(override) {
233
136
  if (override) return override;
234
137
  const env = process.env["GITHUB_SHA"] || process.env["CI_COMMIT_SHA"] || process.env["GIT_COMMIT"] || process.env["CIRCLE_SHA1"] || process.env["BUILD_SOURCEVERSION"] || process.env["BITBUCKET_COMMIT"];
@@ -285,8 +188,8 @@ async function cmdList(args) {
285
188
  process.exit(2);
286
189
  }
287
190
  const { workspace, dir } = await cliCommon.loadWorkspace(wsArg);
288
- const snapshots$1 = await snapshots.listSnapshots(dir, workspace.contracts ?? []);
289
- if (snapshots$1.length === 0) {
191
+ const snapshots = await brokerClient.listSnapshots(dir, workspace.contracts ?? []);
192
+ if (snapshots.length === 0) {
290
193
  console.log(" No contract snapshots. Capture one from the app or via:");
291
194
  console.log(" api-spector contract pin --workspace <path> --spec-url <url>");
292
195
  return;
@@ -294,7 +197,7 @@ async function cmdList(args) {
294
197
  console.log("");
295
198
  console.log(" ID Name Version Captured");
296
199
  console.log(" ──────── ─────────────────────────────────── ─────────── ──────────────────");
297
- for (const { snapshot } of snapshots$1) {
200
+ for (const { snapshot } of snapshots) {
298
201
  const id = snapshot.id.slice(0, 8);
299
202
  const name = snapshot.name.slice(0, 35).padEnd(35);
300
203
  const version = (snapshot.specVersion ?? "-").slice(0, 11).padEnd(11);
@@ -319,8 +222,8 @@ async function cmdPin(args) {
319
222
  }
320
223
  const name = typeof args["name"] === "string" ? args["name"] : void 0;
321
224
  const { workspace, dir, file } = await cliCommon.loadWorkspace(wsArg);
322
- const snapshot = await snapshots.captureSnapshot(dir, { specUrl, specPath, name });
323
- const relPath = snapshots.relPathOf(snapshot);
225
+ const snapshot = await brokerClient.captureSnapshot(dir, { specUrl, specPath, name });
226
+ const relPath = brokerClient.relPathOf(snapshot);
324
227
  if (relPath && !(workspace.contracts ?? []).includes(relPath)) {
325
228
  workspace.contracts = [...workspace.contracts ?? [], relPath];
326
229
  await promises.writeFile(file, JSON.stringify(workspace, null, 2), "utf8");
@@ -333,7 +236,7 @@ async function cmdPin(args) {
333
236
  console.log(` api-spector contract run --workspace ${wsArg} --mode provider --snapshot ${snapshot.id.slice(0, 8)}`);
334
237
  }
335
238
  async function resolveSnapshot(ws, dir, needle) {
336
- const all = await snapshots.listSnapshots(dir, ws.contracts ?? []);
239
+ const all = await brokerClient.listSnapshots(dir, ws.contracts ?? []);
337
240
  const matches = all.filter(
338
241
  ({ snapshot }) => snapshot.id === needle || snapshot.id.startsWith(needle) || snapshot.name === needle
339
242
  );
@@ -366,10 +269,10 @@ async function cmdRun(args) {
366
269
  const collectionVars = {};
367
270
  for (const c of collections) Object.assign(collectionVars, c.collectionVariables ?? {});
368
271
  const allRequests = collections.flatMap((c) => Object.values(c.requests));
369
- const collectionContracts = allRequests.filter((r) => snapshots.hasContract(r.contract));
272
+ const collectionContracts = allRequests.filter((r) => brokerClient.hasContract(r.contract));
370
273
  const keyOf = (r) => `${r.method} ${r.url} ${r.name}`;
371
274
  const collectionKeys = new Set(collectionContracts.map(keyOf));
372
- const designContracts = (await snapshots.loadDesignContractRequests(workspace, dir)).filter((r) => !collectionKeys.has(keyOf(r)));
275
+ const designContracts = (await brokerClient.loadDesignContractRequests(workspace, dir)).filter((r) => !collectionKeys.has(keyOf(r)));
373
276
  const contractRequests = [...collectionContracts, ...designContracts];
374
277
  if (designContracts.length) {
375
278
  console.log(` + ${designContracts.length} design-first interaction(s) from the Contract Designer / pacts/`);
@@ -408,16 +311,16 @@ async function cmdRun(args) {
408
311
  const modeValue = mode;
409
312
  switch (modeValue) {
410
313
  case "consumer":
411
- report = await snapshots.runConsumerContracts(contractRequests, envVars, collectionVars, providerBaseUrl);
314
+ report = await brokerClient.runConsumerContracts(contractRequests, envVars, collectionVars, providerBaseUrl);
412
315
  break;
413
316
  case "provider":
414
- report = await snapshots.runProviderVerification(allRequests, envVars, collectionVars, specUrl, specPath, requestBaseUrl);
317
+ report = await brokerClient.runProviderVerification(allRequests, envVars, collectionVars, specUrl, specPath, requestBaseUrl);
415
318
  break;
416
319
  case "provider-live":
417
- report = await snapshots.runLiveProviderVerification(contractRequests, envVars, collectionVars, providerBaseUrl, stateHandlerUrl);
320
+ report = await brokerClient.runLiveProviderVerification(contractRequests, envVars, collectionVars, providerBaseUrl, stateHandlerUrl);
418
321
  break;
419
322
  case "bidirectional":
420
- report = await snapshots.runBidirectional(contractRequests, envVars, collectionVars, specUrl, specPath, requestBaseUrl);
323
+ report = await brokerClient.runBidirectional(contractRequests, envVars, collectionVars, specUrl, specPath, requestBaseUrl);
421
324
  break;
422
325
  }
423
326
  if (args["allow-pending"]) {
@@ -459,7 +362,7 @@ async function cmdRun(args) {
459
362
  console.log(` JUnit report written to ${args["junit"]}`);
460
363
  }
461
364
  if (typeof args["html"] === "string") {
462
- const html = snapshots.reportToHtml(report, {
365
+ const html = brokerClient.reportToHtml(report, {
463
366
  consumer: collections[0]?.name,
464
367
  provider: providerBaseUrl,
465
368
  spec: snapshotLabel ?? specUrl ?? specPath,
@@ -475,7 +378,7 @@ async function cmdRun(args) {
475
378
  process.exit(2);
476
379
  }
477
380
  const pacticipant = typeof args["pacticipant"] === "string" ? args["pacticipant"] : collections[0]?.name ?? "app";
478
- const file = await snapshots.recordResult(dir, pacticipant, appVersion, report, (/* @__PURE__ */ new Date()).toISOString());
381
+ const file = await brokerClient.recordResult(dir, pacticipant, appVersion, report, (/* @__PURE__ */ new Date()).toISOString());
479
382
  console.log(` Recorded result for ${pacticipant}@${appVersion} → ${file}`);
480
383
  }
481
384
  process.exit(report.failed === 0 ? 0 : 1);
@@ -498,7 +401,7 @@ async function cmdCanIDeploy(args) {
498
401
  }
499
402
  const toEnv = typeof args["to"] === "string" ? args["to"] : void 0;
500
403
  const { dir } = await cliCommon.loadWorkspace(wsArg);
501
- const verdict = await snapshots.canIDeploy(dir, pacticipant, appVersion, toEnv);
404
+ const verdict = await brokerClient.canIDeploy$1(dir, pacticipant, appVersion, toEnv);
502
405
  console.log("");
503
406
  console.log(verdict.deployable ? ` ✓ Computer says yes - safe to deploy.` : ` ✗ Computer says no.`);
504
407
  console.log(` ${verdict.reason}`);
@@ -537,8 +440,8 @@ async function cmdRecordDeployment(args) {
537
440
  process.exit(2);
538
441
  }
539
442
  const { dir } = await cliCommon.loadWorkspace(wsArg);
540
- const verdict = await snapshots.canIDeploy(dir, pacticipant, appVersion);
541
- const { file, previous } = await snapshots.recordDeployment(dir, env, pacticipant, appVersion, (/* @__PURE__ */ new Date()).toISOString());
443
+ const verdict = await brokerClient.canIDeploy$1(dir, pacticipant, appVersion);
444
+ const { file, previous } = await brokerClient.recordDeployment$1(dir, env, pacticipant, appVersion, (/* @__PURE__ */ new Date()).toISOString());
542
445
  console.log(` Recorded: ${pacticipant}@${appVersion} deployed to ${env}`);
543
446
  if (previous) console.log(` Replaces: ${pacticipant}@${previous.version} (deployed ${previous.recordedAt})`);
544
447
  console.log(` File: ${file}`);
@@ -555,7 +458,7 @@ async function cmdEnvironments(args) {
555
458
  process.exit(2);
556
459
  }
557
460
  const { dir } = await cliCommon.loadWorkspace(wsArg);
558
- const envs = await snapshots.listEnvironments(dir);
461
+ const envs = await brokerClient.listEnvironments(dir);
559
462
  if (envs.length === 0) {
560
463
  console.log(" No deployments recorded. After a deploy, run:");
561
464
  console.log(" api-spector contract record-deployment --workspace <path> --pacticipant <name> --app-version <ver> --env <name>");
@@ -607,7 +510,7 @@ async function cmdFuzz(args) {
607
510
  console.log(` Fuzzing ${allRequests.length} request(s)${specUrl || specPath ? " against the spec" : " from request bodies"} at the ${level} level...`);
608
511
  if (level === "aggressive") console.log(" Aggressive: includes injection probes (SQL/NoSQL/…) and header tampering. Only run against systems you own.");
609
512
  if (!includeWrites) console.log(" Write methods (POST/PUT/PATCH/DELETE) are skipped. Add --include-writes to fuzz them (sends malformed writes; target staging or a mock).");
610
- const report = await snapshots.runFuzz({
513
+ const report = await brokerClient.runFuzz({
611
514
  level,
612
515
  requests: allRequests,
613
516
  envVars,
@@ -658,7 +561,7 @@ async function cmdFuzz(args) {
658
561
  Report written to ${args["output"]}`);
659
562
  }
660
563
  if (typeof args["html"] === "string") {
661
- await promises.writeFile(args["html"], snapshots.fuzzReportToHtml(report, (/* @__PURE__ */ new Date()).toISOString()), "utf8");
564
+ await promises.writeFile(args["html"], brokerClient.fuzzReportToHtml(report, (/* @__PURE__ */ new Date()).toISOString()), "utf8");
662
565
  console.log(` HTML report written to ${args["html"]}`);
663
566
  }
664
567
  process.exit(report.totalFindings === 0 ? 0 : 1);
@@ -715,9 +618,9 @@ async function cmdReport(args) {
715
618
  }
716
619
  const { dir } = await cliCommon.loadWorkspace(wsArg);
717
620
  const out = typeof args["html"] === "string" ? args["html"] : "contract-dashboard.html";
718
- const records = await snapshots.listResults(dir);
719
- const environments2 = await snapshots.listEnvironments(dir);
720
- await promises.writeFile(out, snapshots.dashboardToHtml(records, (/* @__PURE__ */ new Date()).toISOString(), { environments: environments2 }), "utf8");
621
+ const records = await brokerClient.listResults(dir);
622
+ const environments2 = await brokerClient.listEnvironments(dir);
623
+ await promises.writeFile(out, brokerClient.dashboardToHtml(records, (/* @__PURE__ */ new Date()).toISOString(), { environments: environments2 }), "utf8");
721
624
  console.log(` Dashboard with ${records.length} recorded result(s) written to ${out}`);
722
625
  }
723
626
  async function cmdPactImport(args) {
@@ -726,10 +629,10 @@ async function cmdPactImport(args) {
726
629
  console.error(" [error] --file <pact.json> is required");
727
630
  process.exit(2);
728
631
  }
729
- const result = snapshots.importPact(await promises.readFile(file, "utf8"));
632
+ const result = brokerClient.importPact(await promises.readFile(file, "utf8"));
730
633
  console.log(` Imported ${result.requests.length} interaction(s): ${result.consumer} → ${result.provider} (spec ${result.specVersion})`);
731
634
  if (typeof args["out"] === "string") {
732
- const collection = snapshots.pactToCollection(result);
635
+ const collection = brokerClient.pactToCollection(result);
733
636
  await promises.writeFile(args["out"], JSON.stringify(collection, null, 2), "utf8");
734
637
  console.log(` Collection written to ${args["out"]}`);
735
638
  console.log(` Set the "baseUrl" collection variable, then verify with:`);
@@ -750,14 +653,14 @@ async function cmdPactExport(args) {
750
653
  const { workspace, dir } = await cliCommon.loadWorkspace(wsArg);
751
654
  const collectionName = typeof args["collection"] === "string" ? args["collection"] : void 0;
752
655
  const collections = await cliCommon.loadCollections(workspace, dir, { filterName: collectionName });
753
- const requests = collections.flatMap((c) => Object.values(c.requests)).filter((r) => snapshots.hasContract(r.contract));
656
+ const requests = collections.flatMap((c) => Object.values(c.requests)).filter((r) => brokerClient.hasContract(r.contract));
754
657
  if (requests.length === 0) {
755
658
  console.error(" [error] No requests with contracts found to export.");
756
659
  process.exit(2);
757
660
  }
758
661
  const consumer = typeof args["consumer"] === "string" ? args["consumer"] : collections[0]?.name ?? "consumer";
759
662
  const provider = typeof args["provider"] === "string" ? args["provider"] : "provider";
760
- const pact = snapshots.exportPact(consumer, provider, requests);
663
+ const pact = brokerClient.exportPact(consumer, provider, requests);
761
664
  await promises.writeFile(out, JSON.stringify(pact, null, 2), "utf8");
762
665
  console.log(` Exported ${requests.length} interaction(s) to ${out} (${consumer} → ${provider})`);
763
666
  }
@@ -797,14 +700,14 @@ async function cmdPublish(args) {
797
700
  let all = collections.flatMap((c) => Object.values(c.requests));
798
701
  const tag = str(args["tag"]);
799
702
  if (tag) all = all.filter((r) => (r.meta?.tags ?? []).includes(tag));
800
- let requests = all.filter((r) => snapshots.hasContract(r.contract));
703
+ let requests = all.filter((r) => brokerClient.hasContract(r.contract));
801
704
  if (args["derive"]) {
802
- const derived = all.filter((r) => !snapshots.hasContract(r.contract)).map((r) => ({ ...r, contract: deriveContract(r) })).filter((r) => snapshots.hasContract(r.contract));
705
+ const derived = all.filter((r) => !brokerClient.hasContract(r.contract)).map((r) => ({ ...r, contract: deriveContract(r) })).filter((r) => brokerClient.hasContract(r.contract));
803
706
  requests = [...requests, ...derived];
804
707
  }
805
708
  if (requests.length === 0) die("No requests with contract expectations found to publish (set them on the Contract tab, or pass --derive to use saved example responses).");
806
- const pact = snapshots.exportPact(consumer, provider, requests);
807
- await publishPact(brokerConfigFromEnv(), { consumer, provider, consumerVersion: version, pact });
709
+ const pact = brokerClient.exportPact(consumer, provider, requests);
710
+ await brokerClient.publishPact(brokerClient.brokerConfigFromEnv(), { consumer, provider, consumerVersion: version, pact });
808
711
  console.log(` Published ${requests.length} interaction(s): ${consumer}@${version.slice(0, 7)} → ${provider}`);
809
712
  }
810
713
  async function cmdPublishSpecLocal(args) {
@@ -838,7 +741,7 @@ async function cmdPublishSpec(args) {
838
741
  let results;
839
742
  const resultsPath = str(args["results"]);
840
743
  if (resultsPath) results = parseSelfVerification(await promises.readFile(resultsPath, "utf8"), resultsPath);
841
- await publishSpec(brokerConfigFromEnv(), { pacticipant, version, spec, results });
744
+ await brokerClient.publishSpec(brokerClient.brokerConfigFromEnv(), { pacticipant, version, spec, results });
842
745
  const selfNote = results ? ` (self-verification: ${results.success ? "passed" : "FAILED"})` : "";
843
746
  console.log(` Published spec: ${pacticipant}@${version.slice(0, 7)}${selfNote}`);
844
747
  }
@@ -846,7 +749,7 @@ async function cmdCloudCanIDeploy(args) {
846
749
  const pacticipant = str(args["pacticipant"]) ?? die("--pacticipant <name> is required");
847
750
  const version = resolveVersion(str(args["version"]));
848
751
  const environment = str(args["environment"]) ?? str(args["to"]) ?? die("--environment <name> is required");
849
- const { deployable, reason } = await canIDeploy(brokerConfigFromEnv(), { pacticipant, version, environment });
752
+ const { deployable, reason } = await brokerClient.canIDeploy(brokerClient.brokerConfigFromEnv(), { pacticipant, version, environment });
850
753
  if (deployable) {
851
754
  console.log(` ✓ ${pacticipant}@${version.slice(0, 7)} can deploy to ${environment}`);
852
755
  } else {
@@ -859,7 +762,7 @@ async function cmdPreview(args) {
859
762
  const pacticipant = str(args["pacticipant"]) ?? die("--pacticipant <name> is required");
860
763
  const version = resolveVersion(str(args["version"]));
861
764
  const environment = str(args["environment"]) ?? str(args["to"]) ?? die("--environment <name> is required");
862
- const preview = await deployPreview(brokerConfigFromEnv(), { pacticipant, version, environment });
765
+ const preview = await brokerClient.deployPreview(brokerClient.brokerConfigFromEnv(), { pacticipant, version, environment });
863
766
  console.log(`### ${preview.check.title}
864
767
 
865
768
  ${preview.check.summary}`);
@@ -869,7 +772,7 @@ async function cmdCloudRecordDeployment(args) {
869
772
  const pacticipant = str(args["pacticipant"]) ?? die("--pacticipant <name> is required");
870
773
  const version = resolveVersion(str(args["version"]));
871
774
  const environment = str(args["environment"]) ?? str(args["env"]) ?? die("--environment <name> is required");
872
- await recordDeployment(brokerConfigFromEnv(), { pacticipant, version, environment });
775
+ await brokerClient.recordDeployment(brokerClient.brokerConfigFromEnv(), { pacticipant, version, environment });
873
776
  console.log(` Recorded ${pacticipant}@${version.slice(0, 7)} deployed to ${environment}`);
874
777
  }
875
778
  async function cmdCheck(args) {
@@ -877,7 +780,7 @@ async function cmdCheck(args) {
877
780
  const consumerVersion = str(args["consumer-version"]) ?? die("--consumer-version <ver> is required");
878
781
  const provider = str(args["provider"]) ?? die("--provider <name> is required");
879
782
  const providerVersion = str(args["provider-version"]) ?? die("--provider-version <ver> is required");
880
- const { compatible, checks } = await checkCompatibility(brokerConfigFromEnv(), { consumer, consumerVersion, provider, providerVersion });
783
+ const { compatible, checks } = await brokerClient.checkCompatibility(brokerClient.brokerConfigFromEnv(), { consumer, consumerVersion, provider, providerVersion });
881
784
  if (compatible) {
882
785
  console.log(` ✓ ${consumer}@${consumerVersion} is compatible with ${provider}@${providerVersion}`);
883
786
  return;
@@ -899,11 +802,11 @@ async function cmdPublishVerification(args) {
899
802
  const success = successArg === "true" || successArg === "1";
900
803
  const buildUrl = str(args["build-url"]);
901
804
  const consumerVersion = str(args["consumer-version"]);
902
- const cfg = brokerConfigFromEnv();
903
- const contracts = await fetchContracts(cfg, { consumer, provider });
805
+ const cfg = brokerClient.brokerConfigFromEnv();
806
+ const contracts = await brokerClient.fetchContracts(cfg, { consumer, provider });
904
807
  const match = consumerVersion ? contracts.find((c) => c.consumerVersion === consumerVersion) : contracts[contracts.length - 1];
905
808
  if (!match) die(`No published contract for ${consumer} -> ${provider}${consumerVersion ? "@" + consumerVersion : ""}.`);
906
- await publishVerification(cfg, { contractId: match.id, providerVersion, success, buildUrl });
809
+ await brokerClient.publishVerification(cfg, { contractId: match.id, providerVersion, success, buildUrl });
907
810
  console.log(` Published verification: ${provider}@${providerVersion.slice(0, 7)} -> ${consumer}@${match.consumerVersion} = ${success ? "passed" : "FAILED"}`);
908
811
  }
909
812
  async function main() {
@@ -4,8 +4,9 @@ const promises = require("fs/promises");
4
4
  const jsYaml = require("js-yaml");
5
5
  const undici = require("undici");
6
6
  const coverage = require("./chunks/coverage-C54mZEh_.js");
7
- const cliCommon = require("./chunks/cli-common-BKYgsbGB.js");
7
+ const cliCommon = require("./chunks/cli-common-vASoDfQH.js");
8
8
  require("path");
9
+ require("./chunks/data-files-Br2h3Dt2.js");
9
10
  require("crypto");
10
11
  async function loadObservations(path) {
11
12
  const report = JSON.parse(await promises.readFile(path, "utf8"));
@@ -5,8 +5,9 @@ const jsYaml = require("js-yaml");
5
5
  const undici = require("undici");
6
6
  const uuid = require("uuid");
7
7
  const coverage = require("./chunks/coverage-C54mZEh_.js");
8
- const cliCommon = require("./chunks/cli-common-BKYgsbGB.js");
8
+ const cliCommon = require("./chunks/cli-common-vASoDfQH.js");
9
9
  require("path");
10
+ require("./chunks/data-files-Br2h3Dt2.js");
10
11
  require("crypto");
11
12
  const HTTP_METHODS = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
12
13
  function resolveRef(spec, ref) {