@testsmith/api-spector 0.4.6 → 0.4.7

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.
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
- const undici = require("undici");
3
- const requestExec = require("./request-exec-CBi2kL6s.js");
4
2
  const promises = require("fs/promises");
5
3
  const path = require("path");
4
+ const crypto = require("crypto");
5
+ const undici = require("undici");
6
+ const requestExec = require("./request-exec-BH-M3KqZ.js");
6
7
  const Ajv = require("ajv");
7
8
  const jsYaml = require("js-yaml");
8
- const crypto = require("crypto");
9
9
  const MATCH_KEY = "__match";
10
- function isMatcher(node) {
10
+ function isMatcher$1(node) {
11
11
  return typeof node === "object" && node !== null && !Array.isArray(node) && typeof node[MATCH_KEY] === "string";
12
12
  }
13
13
  function compileMatcher(m) {
@@ -44,7 +44,7 @@ function compileMatcher(m) {
44
44
  }
45
45
  }
46
46
  function compileMatcherExample(node, exact = true) {
47
- if (isMatcher(node)) return compileMatcher(node);
47
+ if (isMatcher$1(node)) return compileMatcher(node);
48
48
  if (node === null) return { type: "null" };
49
49
  const t = typeof node;
50
50
  if (t === "boolean") return exact ? { const: node } : { type: "boolean" };
@@ -68,6 +68,552 @@ function compileMatcherExample(node, exact = true) {
68
68
  }
69
69
  return {};
70
70
  }
71
+ function parsePath(path2) {
72
+ const tokens = [];
73
+ const re = /\.([^.[\]]+)|\['([^']*)'\]|\[(\d+|\*)\]/g;
74
+ let m;
75
+ while ((m = re.exec(path2)) !== null) {
76
+ if (m[1] !== void 0) tokens.push({ key: m[1] });
77
+ else if (m[2] !== void 0) tokens.push({ key: m[2] });
78
+ else if (m[3] !== void 0) tokens.push({ index: m[3] === "*" ? "*" : Number(m[3]) });
79
+ }
80
+ return tokens;
81
+ }
82
+ function ruleToMatcher(value, rule) {
83
+ switch (rule.match) {
84
+ case "type":
85
+ if (Array.isArray(value)) {
86
+ return { [MATCH_KEY]: "eachLike", value: value[0] ?? {}, min: rule.min ?? 1 };
87
+ }
88
+ return { [MATCH_KEY]: "type", value };
89
+ case "regex":
90
+ return { [MATCH_KEY]: "regex", regex: rule.regex ?? ".*", value };
91
+ case "integer":
92
+ return { [MATCH_KEY]: "integer", value };
93
+ case "number":
94
+ case "decimal":
95
+ return { [MATCH_KEY]: "decimal", value };
96
+ case "boolean":
97
+ return { [MATCH_KEY]: "boolean", value };
98
+ case "null":
99
+ return { [MATCH_KEY]: "null", value: null };
100
+ case "datetime":
101
+ case "timestamp":
102
+ return { [MATCH_KEY]: "datetime", value, format: rule.format };
103
+ case "date":
104
+ return { [MATCH_KEY]: "date", value };
105
+ case "time":
106
+ return { [MATCH_KEY]: "time", value };
107
+ default:
108
+ return value;
109
+ }
110
+ }
111
+ function applyAtPath(root, tokens, transform) {
112
+ if (tokens.length === 0) return transform(root);
113
+ const [head, ...rest] = tokens;
114
+ if ("index" in head) {
115
+ if (!Array.isArray(root)) return root;
116
+ if (head.index === "*") {
117
+ return root.map((el) => applyAtPath(el, rest, transform));
118
+ }
119
+ const arr = [...root];
120
+ if (head.index < arr.length) arr[head.index] = applyAtPath(arr[head.index], rest, transform);
121
+ return arr;
122
+ }
123
+ if (typeof root !== "object" || root === null || Array.isArray(root)) return root;
124
+ const obj = { ...root };
125
+ if (head.key in obj) obj[head.key] = applyAtPath(obj[head.key], rest, transform);
126
+ return obj;
127
+ }
128
+ function bodyWithMatchers(body, matchingRules) {
129
+ const bodyRules = matchingRules?.["body"] ?? matchingRules?.["content"];
130
+ if (!bodyRules || body === void 0) return body;
131
+ const entries = Object.entries(bodyRules).sort((a, b) => parsePath(b[0]).length - parsePath(a[0]).length);
132
+ let result = body;
133
+ for (const [path2, def] of entries) {
134
+ const rule = def?.matchers?.[0];
135
+ if (!rule) continue;
136
+ const tokens = parsePath(path2);
137
+ result = applyAtPath(result, tokens, (v) => ruleToMatcher(v, rule));
138
+ }
139
+ return result;
140
+ }
141
+ function providerStatesOf(interaction) {
142
+ const v3 = interaction["providerStates"];
143
+ if (Array.isArray(v3)) return v3.map((s) => s?.name ?? "").filter(Boolean);
144
+ const v2 = interaction["providerState"] ?? interaction["provider_state"];
145
+ return typeof v2 === "string" && v2 ? [v2] : [];
146
+ }
147
+ function queryToParams(query) {
148
+ const params = [];
149
+ if (!query) return params;
150
+ if (typeof query === "string") {
151
+ for (const pair of query.split("&")) {
152
+ const [k, v = ""] = pair.split("=");
153
+ if (k) params.push({ key: decodeURIComponent(k), value: decodeURIComponent(v), enabled: true });
154
+ }
155
+ } else if (typeof query === "object") {
156
+ for (const [k, vals] of Object.entries(query)) {
157
+ const list = Array.isArray(vals) ? vals : [vals];
158
+ for (const v of list) params.push({ key: k, value: String(v ?? ""), enabled: true });
159
+ }
160
+ }
161
+ return params;
162
+ }
163
+ function headerEntries(headers) {
164
+ if (!headers || typeof headers !== "object") return [];
165
+ return Object.entries(headers).map(([key, value]) => ({
166
+ key,
167
+ value: Array.isArray(value) ? value.join(", ") : String(value ?? "")
168
+ }));
169
+ }
170
+ function headersToKv(headers) {
171
+ return headerEntries(headers).map((h) => ({ ...h, enabled: true }));
172
+ }
173
+ function headersToContract(headers) {
174
+ return headerEntries(headers).map((h) => ({ ...h, required: true }));
175
+ }
176
+ function importInteraction(interaction) {
177
+ const request = interaction["request"] ?? {};
178
+ const response = interaction["response"] ?? {};
179
+ const method = String(request["method"] ?? "GET").toUpperCase();
180
+ const path2 = String(request["path"] ?? "/");
181
+ const reqBody = request["body"];
182
+ const body = reqBody === void 0 ? { mode: "none" } : typeof reqBody === "string" ? { mode: "raw", raw: reqBody } : { mode: "json", json: JSON.stringify(reqBody, null, 2) };
183
+ const contract = {};
184
+ if (typeof response["status"] === "number") contract.statusCode = response["status"];
185
+ const respHeaders = headersToContract(response["headers"]);
186
+ if (respHeaders?.length) contract.headers = respHeaders;
187
+ if (response["body"] !== void 0) {
188
+ const example = bodyWithMatchers(response["body"], response["matchingRules"]);
189
+ contract.bodyMatcher = JSON.stringify(example, null, 2);
190
+ }
191
+ const states = providerStatesOf(interaction);
192
+ if (states.length) contract.providerStates = states;
193
+ return {
194
+ id: crypto.randomUUID(),
195
+ name: String(interaction["description"] ?? `${method} ${path2}`),
196
+ method,
197
+ url: `{{baseUrl}}${path2}`,
198
+ headers: headersToKv(request["headers"]),
199
+ params: queryToParams(request["query"]),
200
+ auth: { type: "none" },
201
+ body,
202
+ contract,
203
+ meta: { tags: ["pact"] }
204
+ };
205
+ }
206
+ function importPact(json) {
207
+ const pact = typeof json === "string" ? JSON.parse(json) : json;
208
+ const consumer = pact["consumer"]?.name ?? "consumer";
209
+ const provider = pact["provider"]?.name ?? "provider";
210
+ const metadata = pact["metadata"];
211
+ const specVersion = String(
212
+ metadata?.["pactSpecification"]?.version ?? metadata?.["pact-specification"]?.version ?? "3.0.0"
213
+ );
214
+ const interactions = pact["interactions"] ?? [];
215
+ const httpInteractions = interactions.filter((i) => {
216
+ const type = i["type"];
217
+ return type === void 0 || type === "Synchronous/HTTP" || type === "HTTP";
218
+ });
219
+ return {
220
+ consumer,
221
+ provider,
222
+ specVersion,
223
+ requests: httpInteractions.map(importInteraction)
224
+ };
225
+ }
226
+ function pactToCollection(result) {
227
+ const requests = {};
228
+ for (const r of result.requests) requests[r.id] = r;
229
+ return {
230
+ version: "1.0",
231
+ id: crypto.randomUUID(),
232
+ name: `${result.consumer} → ${result.provider}`,
233
+ description: `Imported from Pact (spec ${result.specVersion})`,
234
+ rootFolder: {
235
+ id: crypto.randomUUID(),
236
+ name: "root",
237
+ folders: [],
238
+ requestIds: result.requests.map((r) => r.id)
239
+ },
240
+ requests,
241
+ collectionVariables: { baseUrl: "" }
242
+ };
243
+ }
244
+ function isMatcher(node) {
245
+ return typeof node === "object" && node !== null && !Array.isArray(node) && typeof node[MATCH_KEY] === "string";
246
+ }
247
+ function exampleToPactBody(node) {
248
+ const rules = {};
249
+ function walk(n, path2) {
250
+ if (isMatcher(n)) {
251
+ const kind = n[MATCH_KEY];
252
+ switch (kind) {
253
+ case "type":
254
+ rules[path2] = { matchers: [{ match: "type" }] };
255
+ return walk(n.value, path2);
256
+ case "eachLike": {
257
+ rules[path2] = { matchers: [{ match: "type", min: n.min ?? 1 }] };
258
+ return [walk(n.value, `${path2}[*]`)];
259
+ }
260
+ case "regex":
261
+ rules[path2] = { matchers: [{ match: "regex", regex: n.regex ?? ".*" }] };
262
+ return n.value ?? "";
263
+ case "integer":
264
+ rules[path2] = { matchers: [{ match: "integer" }] };
265
+ return n.value ?? 0;
266
+ case "decimal":
267
+ case "number":
268
+ rules[path2] = { matchers: [{ match: "decimal" }] };
269
+ return n.value ?? 0;
270
+ case "boolean":
271
+ rules[path2] = { matchers: [{ match: "boolean" }] };
272
+ return n.value ?? false;
273
+ case "string":
274
+ rules[path2] = { matchers: [{ match: "type" }] };
275
+ return n.value ?? "";
276
+ case "null":
277
+ rules[path2] = { matchers: [{ match: "null" }] };
278
+ return null;
279
+ case "datetime":
280
+ case "timestamp":
281
+ rules[path2] = { matchers: [{ match: "datetime", format: n.format }] };
282
+ return n.value ?? "";
283
+ case "date":
284
+ rules[path2] = { matchers: [{ match: "date" }] };
285
+ return n.value ?? "";
286
+ case "time":
287
+ rules[path2] = { matchers: [{ match: "time" }] };
288
+ return n.value ?? "";
289
+ default:
290
+ return n.value;
291
+ }
292
+ }
293
+ if (Array.isArray(n)) return n.map((el, i) => walk(el, `${path2}[${i}]`));
294
+ if (typeof n === "object" && n !== null) {
295
+ const out = {};
296
+ for (const [k, v] of Object.entries(n)) out[k] = walk(v, `${path2}.${k}`);
297
+ return out;
298
+ }
299
+ return n;
300
+ }
301
+ const body = walk(node, "$");
302
+ return { body, rules };
303
+ }
304
+ function kvToHeaders$1(kv) {
305
+ if (!kv?.length) return void 0;
306
+ const out = {};
307
+ for (const h of kv) if (h.enabled !== false && h.key) out[h.key] = h.value;
308
+ return Object.keys(out).length ? out : void 0;
309
+ }
310
+ const V4_SYNC_HTTP = "Synchronous/HTTP";
311
+ function interactionKey(identity) {
312
+ let h = 2166136261;
313
+ for (let i = 0; i < identity.length; i++) {
314
+ h ^= identity.charCodeAt(i);
315
+ h = Math.imul(h, 16777619);
316
+ }
317
+ return (h >>> 0).toString(16).padStart(8, "0");
318
+ }
319
+ function exportPact(consumer, provider, requests) {
320
+ const interactions = requests.filter((r) => r.contract).map((r) => {
321
+ const c = r.contract;
322
+ const path2 = r.url.replace(/^\{\{baseUrl\}\}/, "").replace(/^https?:\/\/[^/]+/, "") || "/";
323
+ const query = {};
324
+ for (const p of r.params ?? []) {
325
+ if (p.enabled === false || !p.key) continue;
326
+ (query[p.key] ??= []).push(p.value);
327
+ }
328
+ const response = {};
329
+ if (c.statusCode !== void 0) response["status"] = c.statusCode;
330
+ const respHeaders = kvToHeaders$1(c.headers);
331
+ if (respHeaders) response["headers"] = respHeaders;
332
+ if (c.bodyMatcher?.trim()) {
333
+ try {
334
+ const { body, rules } = exampleToPactBody(JSON.parse(c.bodyMatcher));
335
+ response["body"] = body;
336
+ if (Object.keys(rules).length) response["matchingRules"] = { body: rules };
337
+ } catch {
338
+ }
339
+ }
340
+ const request = { method: r.method, path: path2 };
341
+ if (Object.keys(query).length) request["query"] = query;
342
+ const reqHeaders = kvToHeaders$1(r.headers);
343
+ if (reqHeaders) request["headers"] = reqHeaders;
344
+ if (r.body?.mode === "json" && r.body.json) {
345
+ try {
346
+ request["body"] = JSON.parse(r.body.json);
347
+ } catch {
348
+ }
349
+ } else if (r.body?.mode === "raw" && r.body.raw) request["body"] = r.body.raw;
350
+ const interaction = {
351
+ type: V4_SYNC_HTTP,
352
+ key: interactionKey(`${r.method}|${path2}|${c.statusCode ?? ""}|${r.name}`),
353
+ description: r.name,
354
+ request,
355
+ response
356
+ };
357
+ if (c.providerStates?.length) interaction["providerStates"] = c.providerStates.map((name) => ({ name }));
358
+ return interaction;
359
+ });
360
+ return {
361
+ consumer: { name: consumer },
362
+ provider: { name: provider },
363
+ interactions,
364
+ metadata: {
365
+ pactSpecification: { version: "4.0" },
366
+ client: { name: "api-spector" }
367
+ }
368
+ };
369
+ }
370
+ function kvToHeaders(kv) {
371
+ const out = {};
372
+ for (const p of kv ?? []) {
373
+ if (p.enabled === false || !p.key) continue;
374
+ out[p.key] = p.value;
375
+ }
376
+ return Object.keys(out).length ? out : void 0;
377
+ }
378
+ function kvToQuery(kv) {
379
+ const out = {};
380
+ for (const p of kv ?? []) {
381
+ if (p.enabled === false || !p.key) continue;
382
+ (out[p.key] ??= []).push(p.value);
383
+ }
384
+ return Object.keys(out).length ? out : void 0;
385
+ }
386
+ function parseJson(s) {
387
+ if (!s || !s.trim()) return void 0;
388
+ try {
389
+ return JSON.parse(s);
390
+ } catch {
391
+ return void 0;
392
+ }
393
+ }
394
+ function typeMatchingRules(body) {
395
+ const rules = {};
396
+ const walk = (node, path2) => {
397
+ if (Array.isArray(node)) {
398
+ rules[path2] = { matchers: [{ match: "type", min: node.length > 0 ? 1 : 0 }] };
399
+ if (node.length > 0) walk(node[0], `${path2}[*]`);
400
+ } else if (node !== null && typeof node === "object") {
401
+ for (const [k, v] of Object.entries(node)) walk(v, `${path2}.${k}`);
402
+ } else {
403
+ rules[path2] = { matchers: [{ match: "type" }] };
404
+ }
405
+ };
406
+ walk(body, "$");
407
+ return rules;
408
+ }
409
+ function scalarFromName(name) {
410
+ switch (name.toLowerCase()) {
411
+ case "integer":
412
+ case "int":
413
+ return { kind: "scalar", type: "integer" };
414
+ case "number":
415
+ case "float":
416
+ case "double":
417
+ case "decimal":
418
+ return { kind: "scalar", type: "number" };
419
+ case "boolean":
420
+ case "bool":
421
+ return { kind: "scalar", type: "boolean" };
422
+ case "null":
423
+ return { kind: "scalar", type: "null" };
424
+ default:
425
+ return { kind: "scalar", type: "string" };
426
+ }
427
+ }
428
+ function tokenizeShape(src) {
429
+ const tokens = [];
430
+ const re = /\s*([{}[\]:,]|[A-Za-z0-9_$-]+|"[^"]*")\s*/y;
431
+ let i = 0;
432
+ while (i < src.length) {
433
+ re.lastIndex = i;
434
+ const m = re.exec(src);
435
+ if (!m || m.index !== i) return void 0;
436
+ tokens.push(m[1].startsWith('"') ? m[1].slice(1, -1) : m[1]);
437
+ i = re.lastIndex;
438
+ }
439
+ return tokens;
440
+ }
441
+ function parseShape(src) {
442
+ if (!src || !src.trim()) return void 0;
443
+ const tokens = tokenizeShape(src);
444
+ if (!tokens || tokens.length === 0) return void 0;
445
+ let pos = 0;
446
+ const peek = () => tokens[pos];
447
+ const structural = /* @__PURE__ */ new Set(["{", "}", "[", "]", ":", ","]);
448
+ const parseValue = () => {
449
+ const tok = peek();
450
+ if (tok === "{") return parseObject();
451
+ if (tok === "[") return parseArray();
452
+ if (tok === void 0 || structural.has(tok)) return void 0;
453
+ pos++;
454
+ return scalarFromName(tok);
455
+ };
456
+ const parseObject = () => {
457
+ pos++;
458
+ const fields = [];
459
+ while (peek() !== void 0 && peek() !== "}") {
460
+ const name = peek();
461
+ if (structural.has(name)) return void 0;
462
+ pos++;
463
+ let shape2;
464
+ if (peek() === ":") {
465
+ pos++;
466
+ const s = parseValue();
467
+ if (!s) return void 0;
468
+ shape2 = s;
469
+ } else {
470
+ shape2 = { kind: "scalar", type: "string" };
471
+ }
472
+ fields.push({ name, shape: shape2 });
473
+ if (peek() === ",") pos++;
474
+ }
475
+ if (peek() !== "}") return void 0;
476
+ pos++;
477
+ return { kind: "object", fields };
478
+ };
479
+ const parseArray = () => {
480
+ pos++;
481
+ let item;
482
+ if (peek() === "]") {
483
+ item = { kind: "scalar", type: "string" };
484
+ } else {
485
+ const s = parseValue();
486
+ if (!s) return void 0;
487
+ item = s;
488
+ }
489
+ if (peek() !== "]") return void 0;
490
+ pos++;
491
+ return { kind: "array", item };
492
+ };
493
+ const shape = parseValue();
494
+ if (!shape || pos !== tokens.length) return void 0;
495
+ return shape;
496
+ }
497
+ function compileShape(shape) {
498
+ const rules = {};
499
+ const build = (s, path2) => {
500
+ if (s.kind === "array") {
501
+ rules[path2] = { matchers: [{ match: "type", min: 1 }] };
502
+ return [build(s.item, `${path2}[*]`)];
503
+ }
504
+ if (s.kind === "object") {
505
+ const obj = {};
506
+ for (const f of s.fields) obj[f.name] = build(f.shape, `${path2}.${f.name}`);
507
+ return obj;
508
+ }
509
+ switch (s.type) {
510
+ case "integer":
511
+ rules[path2] = { matchers: [{ match: "integer" }] };
512
+ return 0;
513
+ case "number":
514
+ rules[path2] = { matchers: [{ match: "number" }] };
515
+ return 0;
516
+ case "boolean":
517
+ rules[path2] = { matchers: [{ match: "boolean" }] };
518
+ return false;
519
+ case "null":
520
+ rules[path2] = { matchers: [{ match: "null" }] };
521
+ return null;
522
+ default:
523
+ rules[path2] = { matchers: [{ match: "type" }] };
524
+ return "string";
525
+ }
526
+ };
527
+ const body = build(shape, "$");
528
+ return { body, rules };
529
+ }
530
+ function compileResponseBody(text, loose = true) {
531
+ if (!text || !text.trim()) return void 0;
532
+ try {
533
+ const json = JSON.parse(text);
534
+ const rules = loose ? typeMatchingRules(json) : {};
535
+ return { body: json, rules: Object.keys(rules).length ? rules : void 0 };
536
+ } catch {
537
+ }
538
+ const shape = parseShape(text);
539
+ if (shape) {
540
+ const { body, rules } = compileShape(shape);
541
+ return { body, rules: Object.keys(rules).length ? rules : void 0 };
542
+ }
543
+ return void 0;
544
+ }
545
+ function interactionToPact(it) {
546
+ const request = {
547
+ method: (it.request.method || "GET").toUpperCase(),
548
+ path: it.request.path || "/"
549
+ };
550
+ const query = kvToQuery(it.request.query);
551
+ if (query) request["query"] = query;
552
+ const reqHeaders = kvToHeaders(it.request.headers);
553
+ if (reqHeaders) request["headers"] = reqHeaders;
554
+ const reqBody = parseJson(it.request.body);
555
+ if (reqBody !== void 0) request["body"] = reqBody;
556
+ const response = { status: it.response.status };
557
+ const respHeaders = kvToHeaders(it.response.headers);
558
+ if (respHeaders) response["headers"] = respHeaders;
559
+ const respBody = compileResponseBody(it.response.body, it.looseMatch !== false);
560
+ if (respBody) {
561
+ response["body"] = respBody.body;
562
+ if (respBody.rules) response["matchingRules"] = { body: respBody.rules };
563
+ }
564
+ const interaction = {
565
+ type: V4_SYNC_HTTP,
566
+ key: interactionKey(`${(it.request.method || "GET").toUpperCase()}|${it.request.path || "/"}|${it.response.status}|${it.description ?? ""}`),
567
+ description: it.description || `${it.request.method} ${it.request.path}`,
568
+ request,
569
+ response
570
+ };
571
+ if (it.providerState?.trim()) interaction["providerStates"] = [{ name: it.providerState.trim() }];
572
+ return interaction;
573
+ }
574
+ function designContractToPact(cc) {
575
+ return {
576
+ consumer: { name: cc.consumer },
577
+ provider: { name: cc.provider },
578
+ interactions: cc.interactions.map(interactionToPact),
579
+ metadata: {
580
+ pactSpecification: { version: "4.0" },
581
+ client: { name: "api-spector", designFirst: true }
582
+ }
583
+ };
584
+ }
585
+ async function loadDesignContractRequests(workspace, dir) {
586
+ const out = [];
587
+ const seen = /* @__PURE__ */ new Set();
588
+ const add = (requests) => {
589
+ for (const r of requests) {
590
+ const key = `${r.method} ${r.url} ${r.name}`;
591
+ if (seen.has(key)) continue;
592
+ seen.add(key);
593
+ out.push(r);
594
+ }
595
+ };
596
+ for (const cc of workspace.designContracts ?? []) {
597
+ try {
598
+ add(importPact(designContractToPact(cc)).requests);
599
+ } catch {
600
+ }
601
+ }
602
+ if (dir) {
603
+ let files = [];
604
+ try {
605
+ files = (await promises.readdir(path.join(dir, "pacts"))).filter((f) => f.endsWith(".json"));
606
+ } catch {
607
+ }
608
+ for (const f of files.sort()) {
609
+ try {
610
+ add(importPact(await promises.readFile(path.join(dir, "pacts", f), "utf8")).requests);
611
+ } catch {
612
+ }
613
+ }
614
+ }
615
+ return out;
616
+ }
71
617
  const ajv$2 = new Ajv({ allErrors: true, strict: false });
72
618
  function hasContract(contract) {
73
619
  return !!contract && (contract.statusCode !== void 0 || !!contract.bodySchema || !!contract.bodyMatcher || !!contract.headers?.length);
@@ -1636,17 +2182,21 @@ async function deleteSnapshot(workspaceDir, relPath) {
1636
2182
  } catch {
1637
2183
  }
1638
2184
  }
1639
- exports.MATCH_KEY = MATCH_KEY;
1640
2185
  exports.canIDeploy = canIDeploy;
1641
2186
  exports.captureSnapshot = captureSnapshot;
1642
2187
  exports.dashboardToHtml = dashboardToHtml;
1643
2188
  exports.deleteSnapshot = deleteSnapshot;
2189
+ exports.designContractToPact = designContractToPact;
2190
+ exports.exportPact = exportPact;
1644
2191
  exports.fuzzReportToHtml = fuzzReportToHtml;
1645
2192
  exports.hasContract = hasContract;
2193
+ exports.importPact = importPact;
1646
2194
  exports.listEnvironments = listEnvironments;
1647
2195
  exports.listResults = listResults;
1648
2196
  exports.listSnapshots = listSnapshots;
2197
+ exports.loadDesignContractRequests = loadDesignContractRequests;
1649
2198
  exports.loadSnapshot = loadSnapshot;
2199
+ exports.pactToCollection = pactToCollection;
1650
2200
  exports.recordDeployment = recordDeployment;
1651
2201
  exports.recordResult = recordResult;
1652
2202
  exports.relPathOf = relPathOf;
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const handle = require("./handle-BGYDylL2.js");
2
+ const handle = require("./handle-rimXXdJH.js");
3
3
  const https = require("https");
4
4
  const http = require("http");
5
5
  const xmldom = require("@xmldom/xmldom");
@@ -315,7 +315,7 @@ function registerSoapHandlers(ipc) {
315
315
  handle.handleIpc(ipc, handle.IPC.wsdl.import, async (_event, opts) => {
316
316
  const { validateWsdlImport } = await Promise.resolve().then(() => require("./ipc-validate-k6KI8adf.js"));
317
317
  validateWsdlImport(opts);
318
- const { importWsdl } = await Promise.resolve().then(() => require("./import-CUcjlmSK.js"));
318
+ const { importWsdl } = await Promise.resolve().then(() => require("./import-DcenB5Q_.js"));
319
319
  const wsdlText = opts.xml ?? (opts.url ? await fetchUrl(opts.url) : "");
320
320
  if (!wsdlText) throw new Error("wsdl:import requires either `url` or `xml`");
321
321
  return importWsdl(wsdlText, { name: opts.name, existingMockPorts: opts.existingMockPorts });