@testsmith/api-spector 0.6.3 → 0.6.4
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.
- package/out/main/agents.js +5 -5
- package/out/main/chunks/{broker-client-WEymdqAK.js → broker-client-CvRuiX3o.js} +26 -23
- package/out/main/chunks/{cli-common-vASoDfQH.js → cli-common-Cq_cphpZ.js} +4 -4
- package/out/main/chunks/{coverage-C54mZEh_.js → coverage-C0U4QM83.js} +8 -10
- package/out/main/chunks/{data-files-Br2h3Dt2.js → data-files-BYqhsoPe.js} +4 -4
- package/out/main/chunks/escape-DDVAlOvZ.js +9 -0
- package/out/main/chunks/{import-DdXhO56X.js → import-DYssQzex.js} +4 -4
- package/out/main/chunks/{mock-server-BxiXhP1m.js → mock-server-C4kTFkod.js} +9 -11
- package/out/main/chunks/{recorder-0Ij921El.js → recorder-BkO8G_mB.js} +2 -2
- package/out/main/chunks/{request-collection-GzK4QgvT.js → request-collection-KGPuvN7o.js} +2 -2
- package/out/main/chunks/{request-exec-DAFA6Fap.js → request-exec-BRmVweue.js} +41 -41
- package/out/main/chunks/{soap-handler-BAPCALkN.js → soap-handler-BznuMFIP.js} +7 -9
- package/out/main/compare.js +10 -10
- package/out/main/contract.js +18 -20
- package/out/main/coverage.js +7 -7
- package/out/main/generate-tests.js +9 -9
- package/out/main/index.js +163 -263
- package/out/main/lib.js +6 -7
- package/out/main/mock.js +8 -8
- package/out/main/record.js +9 -9
- package/out/main/runner.js +14 -15
- package/out/main/wsdl.js +9 -9
- package/out/preload/index.js +1 -1
- package/out/renderer/assets/{GraphQLEditor-MImdgXb4.js → GraphQLEditor-Bih8eb_r.js} +6 -6
- package/out/renderer/assets/{SoapEditor-rxb3heue.js → SoapEditor-D1sQKu7l.js} +3 -3
- package/out/renderer/assets/{index-ByGIqJ2H.js → index-vEDOfWlE.js} +380 -269
- package/out/renderer/index.html +1 -1
- package/package.json +1 -1
- package/out/main/chunks/escape-BwPM4Tf6.js +0 -9
package/out/main/agents.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
const promises = require("fs/promises");
|
|
4
|
-
const path = require("path");
|
|
5
|
-
const cliCommon = require("./chunks/cli-common-
|
|
6
|
-
require("./chunks/data-files-
|
|
7
|
-
require("crypto");
|
|
3
|
+
const promises = require("node:fs/promises");
|
|
4
|
+
const path = require("node:path");
|
|
5
|
+
const cliCommon = require("./chunks/cli-common-Cq_cphpZ.js");
|
|
6
|
+
require("./chunks/data-files-BYqhsoPe.js");
|
|
7
|
+
require("node:crypto");
|
|
8
8
|
const AGENTS = {
|
|
9
9
|
claude: {
|
|
10
10
|
name: "Claude Code",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const promises = require("fs/promises");
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const crypto = require("crypto");
|
|
2
|
+
const promises = require("node:fs/promises");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const crypto = require("node:crypto");
|
|
5
5
|
const undici = require("undici");
|
|
6
|
-
const requestExec = require("./request-exec-
|
|
6
|
+
const requestExec = require("./request-exec-BRmVweue.js");
|
|
7
7
|
const Ajv = require("ajv");
|
|
8
8
|
const jsYaml = require("js-yaml");
|
|
9
|
-
require("http");
|
|
10
|
-
const escape = require("./escape-
|
|
9
|
+
require("node:http");
|
|
10
|
+
const escape = require("./escape-DDVAlOvZ.js");
|
|
11
11
|
const MATCH_KEY = "__match";
|
|
12
12
|
function isMatcher$1(node) {
|
|
13
13
|
return typeof node === "object" && node !== null && !Array.isArray(node) && typeof node[MATCH_KEY] === "string";
|
|
@@ -325,7 +325,8 @@ function exportPact(consumer, provider, requests) {
|
|
|
325
325
|
const query = {};
|
|
326
326
|
for (const p of r.params ?? []) {
|
|
327
327
|
if (p.enabled === false || !p.key) continue;
|
|
328
|
-
|
|
328
|
+
query[p.key] ??= [];
|
|
329
|
+
query[p.key].push(p.value);
|
|
329
330
|
}
|
|
330
331
|
const response = {};
|
|
331
332
|
if (c.statusCode !== void 0) response["status"] = c.statusCode;
|
|
@@ -381,12 +382,13 @@ function kvToQuery(kv) {
|
|
|
381
382
|
const out = {};
|
|
382
383
|
for (const p of kv ?? []) {
|
|
383
384
|
if (p.enabled === false || !p.key) continue;
|
|
384
|
-
|
|
385
|
+
out[p.key] ??= [];
|
|
386
|
+
out[p.key].push(p.value);
|
|
385
387
|
}
|
|
386
388
|
return Object.keys(out).length ? out : void 0;
|
|
387
389
|
}
|
|
388
390
|
function parseJson(s) {
|
|
389
|
-
if (!s
|
|
391
|
+
if (!s?.trim()) return void 0;
|
|
390
392
|
try {
|
|
391
393
|
return JSON.parse(s);
|
|
392
394
|
} catch {
|
|
@@ -434,14 +436,14 @@ function tokenizeShape(src) {
|
|
|
434
436
|
while (i < src.length) {
|
|
435
437
|
re.lastIndex = i;
|
|
436
438
|
const m = re.exec(src);
|
|
437
|
-
if (
|
|
439
|
+
if (m?.index !== i) return void 0;
|
|
438
440
|
tokens.push(m[1].startsWith('"') ? m[1].slice(1, -1) : m[1]);
|
|
439
441
|
i = re.lastIndex;
|
|
440
442
|
}
|
|
441
443
|
return tokens;
|
|
442
444
|
}
|
|
443
445
|
function parseShape(src) {
|
|
444
|
-
if (!src
|
|
446
|
+
if (!src?.trim()) return void 0;
|
|
445
447
|
const tokens = tokenizeShape(src);
|
|
446
448
|
if (!tokens || tokens.length === 0) return void 0;
|
|
447
449
|
let pos = 0;
|
|
@@ -530,7 +532,7 @@ function compileShape(shape) {
|
|
|
530
532
|
return { body, rules };
|
|
531
533
|
}
|
|
532
534
|
function compileResponseBody(text, loose = true) {
|
|
533
|
-
if (!text
|
|
535
|
+
if (!text?.trim()) return void 0;
|
|
534
536
|
try {
|
|
535
537
|
const json = JSON.parse(text);
|
|
536
538
|
const rules = loose ? typeMatchingRules(json) : {};
|
|
@@ -607,7 +609,8 @@ async function loadDesignContractRequests(workspace, dir) {
|
|
|
607
609
|
files = (await promises.readdir(path.join(dir, "pacts"))).filter((f) => f.endsWith(".json"));
|
|
608
610
|
} catch {
|
|
609
611
|
}
|
|
610
|
-
|
|
612
|
+
files.sort((a, b) => a.localeCompare(b));
|
|
613
|
+
for (const f of files) {
|
|
611
614
|
try {
|
|
612
615
|
add(importPact(await promises.readFile(path.join(dir, "pacts", f), "utf8")).requests);
|
|
613
616
|
} catch {
|
|
@@ -852,8 +855,8 @@ function urlPathname(raw, baseUrl) {
|
|
|
852
855
|
}
|
|
853
856
|
}
|
|
854
857
|
function pathTemplateToRegex(base, template) {
|
|
855
|
-
const combined = (base + template).
|
|
856
|
-
const pattern = combined.
|
|
858
|
+
const combined = (base + template).replaceAll(/\/+/g, "/");
|
|
859
|
+
const pattern = combined.replaceAll(/\{[^}]+\}/g, "[^/]+");
|
|
857
860
|
return new RegExp("^" + pattern + "/?$");
|
|
858
861
|
}
|
|
859
862
|
function findOperation(spec, method, reqUrl, requestBaseUrl) {
|
|
@@ -1237,7 +1240,7 @@ async function runBidirectional(requests, envVars, collectionVars = {}, specUrl,
|
|
|
1237
1240
|
}
|
|
1238
1241
|
const RESULTS_DIR = "contracts/results";
|
|
1239
1242
|
function safe(part) {
|
|
1240
|
-
return part.trim().
|
|
1243
|
+
return part.trim().replaceAll(/[^a-zA-Z0-9._-]+/g, "-").replaceAll(/^-+|-+$/g, "") || "unknown";
|
|
1241
1244
|
}
|
|
1242
1245
|
function resultPath(dir, pacticipant, version) {
|
|
1243
1246
|
return path.join(dir, RESULTS_DIR, safe(pacticipant), `${safe(version)}.json`);
|
|
@@ -1465,7 +1468,7 @@ const NAUGHTY_STRINGS = [
|
|
|
1465
1468
|
["huge", "A".repeat(5e4)]
|
|
1466
1469
|
];
|
|
1467
1470
|
function clone(v) {
|
|
1468
|
-
return
|
|
1471
|
+
return structuredClone(v);
|
|
1469
1472
|
}
|
|
1470
1473
|
function setAtPath(root, path2, value) {
|
|
1471
1474
|
if (path2.length === 0) return value;
|
|
@@ -1518,7 +1521,7 @@ function mutate(baseline, schema, label, level = "standard") {
|
|
|
1518
1521
|
if (type === "array" && schemaNode) {
|
|
1519
1522
|
const items = schemaNode["items"];
|
|
1520
1523
|
const arr = getAtPath(baseline, path2);
|
|
1521
|
-
if (arr
|
|
1524
|
+
if (arr?.length) walk(items, [...path2, "0"]);
|
|
1522
1525
|
cases.push({
|
|
1523
1526
|
mutation: { target, kind: "type:array→string", description: "send a string where an array is expected" },
|
|
1524
1527
|
value: setAtPath(baseline, path2, "not-an-array")
|
|
@@ -1822,7 +1825,7 @@ async function runFuzz(opts) {
|
|
|
1822
1825
|
const casesPerOp = opts.casesPerOperation ?? 40;
|
|
1823
1826
|
const level = opts.level ?? "standard";
|
|
1824
1827
|
const vars = requestExec.mergeVars(opts.envVars, opts.collectionVars ?? {}, {}, {}, await requestExec.buildDynamicVars());
|
|
1825
|
-
const dispatcher = await requestExec.buildDispatcher(
|
|
1828
|
+
const dispatcher = await requestExec.buildDispatcher();
|
|
1826
1829
|
const start = Date.now();
|
|
1827
1830
|
const results = [];
|
|
1828
1831
|
let totalCases = 0;
|
|
@@ -2065,7 +2068,7 @@ function violationHtml(r) {
|
|
|
2065
2068
|
const items = r.violations.map((v) => {
|
|
2066
2069
|
const path2 = v.path ? `<span class="path">${esc(v.path)}</span>` : "";
|
|
2067
2070
|
const ea = v.expected || v.actual ? `<div class="ea">${v.expected ? `<span><span class="lab">expected </span><span class="exp">${esc(v.expected)}</span></span>` : ""}${v.actual ? `<span><span class="lab">actual </span><span class="act">${esc(v.actual)}</span></span>` : ""}</div>` : "";
|
|
2068
|
-
return `<div class="v"><div><span class="t">${esc(v.type.
|
|
2071
|
+
return `<div class="v"><div><span class="t">${esc(v.type.replaceAll("_", " "))}</span>${path2}</div><p class="m">${esc(v.message)}</p>${ea}</div>`;
|
|
2069
2072
|
}).join("");
|
|
2070
2073
|
return `<div class="viol">${items}</div>`;
|
|
2071
2074
|
}
|
|
@@ -2103,8 +2106,8 @@ function reportToHtml(report, meta = {}) {
|
|
|
2103
2106
|
return page(meta.title ?? "Contract Verification Report", body);
|
|
2104
2107
|
}
|
|
2105
2108
|
function dashboardToHtml(records, generatedAt, opts = {}) {
|
|
2106
|
-
const pacticipants = [...new Set(records.map((r) => r.pacticipant))].sort();
|
|
2107
|
-
const versions = [...new Set(records.map((r) => r.version))].sort();
|
|
2109
|
+
const pacticipants = [...new Set(records.map((r) => r.pacticipant))].sort((a, b) => a.localeCompare(b));
|
|
2110
|
+
const versions = [...new Set(records.map((r) => r.version))].sort((a, b) => a.localeCompare(b));
|
|
2108
2111
|
const byKey = new Map(records.map((r) => [`${r.pacticipant}@@${r.version}`, r]));
|
|
2109
2112
|
const header = `<tr><th>Pacticipant \\ Version</th>${versions.map((v) => `<th>${esc(v)}</th>`).join("")}</tr>`;
|
|
2110
2113
|
const rows = pacticipants.map((p) => {
|
|
@@ -2197,7 +2200,7 @@ ${cleanOps ? `<p class="foot">${cleanOps} operation${cleanOps === 1 ? "" : "s"}
|
|
|
2197
2200
|
}
|
|
2198
2201
|
const SNAPSHOT_DIR = "contracts";
|
|
2199
2202
|
function safeName(raw) {
|
|
2200
|
-
return raw.trim().toLowerCase().
|
|
2203
|
+
return raw.trim().toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replaceAll(/^-+|-+$/g, "").slice(0, 40) || "spec";
|
|
2201
2204
|
}
|
|
2202
2205
|
function sha256(text) {
|
|
2203
2206
|
return crypto.createHash("sha256").update(text).digest("hex");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const promises = require("fs/promises");
|
|
3
|
-
const path = require("path");
|
|
4
|
-
const dataFiles = require("./data-files-
|
|
5
|
-
require("crypto");
|
|
2
|
+
const promises = require("node:fs/promises");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const dataFiles = require("./data-files-BYqhsoPe.js");
|
|
5
|
+
require("node:crypto");
|
|
6
6
|
const C = {
|
|
7
7
|
reset: "\x1B[0m",
|
|
8
8
|
bold: "\x1B[1m",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const HTTP_METHODS = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
|
|
2
|
+
const HTTP_METHODS = /* @__PURE__ */ new Set(["get", "put", "post", "delete", "options", "head", "patch", "trace"]);
|
|
3
3
|
function normalizePath(url) {
|
|
4
4
|
let u = (url || "").trim();
|
|
5
5
|
u = u.split("#")[0].split("?")[0];
|
|
6
|
-
u = u.
|
|
6
|
+
u = u.replaceAll(/\{\{[^}]*\}\}/g, "");
|
|
7
7
|
u = u.replace(/^[a-z0-9+.-]+:\/\/[^/]*/i, "");
|
|
8
|
-
u = u.
|
|
8
|
+
u = u.replaceAll(/\/{2,}/g, "/");
|
|
9
9
|
if (!u.startsWith("/")) u = "/" + u;
|
|
10
10
|
u = u.replace(/\/+$/, "");
|
|
11
11
|
return u === "" ? "/" : u;
|
|
@@ -25,7 +25,7 @@ function pathMatches(requestUrl, template) {
|
|
|
25
25
|
}
|
|
26
26
|
function resolveRef(spec, ref) {
|
|
27
27
|
const parts = ref.replace(/^#\//, "").split("/");
|
|
28
|
-
return parts.reduce((o, k) => o?.[decodeURIComponent(k.
|
|
28
|
+
return parts.reduce((o, k) => o?.[decodeURIComponent(k.replaceAll("~1", "/").replaceAll("~0", "~"))], spec);
|
|
29
29
|
}
|
|
30
30
|
function deref(spec, node, depth = 0, seen = /* @__PURE__ */ new Set()) {
|
|
31
31
|
if (!node || typeof node !== "object" || depth > 8) return node;
|
|
@@ -46,8 +46,7 @@ function flattenSchemaPaths(schema, prefix = "", depth = 0) {
|
|
|
46
46
|
if (type === "object" || schema.properties) {
|
|
47
47
|
for (const [name, sub] of Object.entries(schema.properties ?? {})) {
|
|
48
48
|
const path = prefix ? `${prefix}.${name}` : name;
|
|
49
|
-
out.push(path);
|
|
50
|
-
out.push(...flattenSchemaPaths(sub, path, depth + 1));
|
|
49
|
+
out.push(path, ...flattenSchemaPaths(sub, path, depth + 1));
|
|
51
50
|
}
|
|
52
51
|
} else if (type === "array" && schema.items) {
|
|
53
52
|
out.push(...flattenSchemaPaths(schema.items, `${prefix}[]`, depth + 1));
|
|
@@ -62,14 +61,13 @@ function flattenValuePaths(value, prefix = "", depth = 0) {
|
|
|
62
61
|
} else {
|
|
63
62
|
for (const [k, v] of Object.entries(value)) {
|
|
64
63
|
const path = prefix ? `${prefix}.${k}` : k;
|
|
65
|
-
out.push(path);
|
|
66
|
-
out.push(...flattenValuePaths(v, path, depth + 1));
|
|
64
|
+
out.push(path, ...flattenValuePaths(v, path, depth + 1));
|
|
67
65
|
}
|
|
68
66
|
}
|
|
69
67
|
return [...new Set(out)];
|
|
70
68
|
}
|
|
71
69
|
function successResponseSchema(spec, responses) {
|
|
72
|
-
const code = Object.keys(responses ?? {}).filter((c) => /^2\d\d$/.test(c)).sort()[0];
|
|
70
|
+
const code = Object.keys(responses ?? {}).filter((c) => /^2\d\d$/.test(c)).sort((a, b) => a.localeCompare(b))[0];
|
|
73
71
|
if (!code) return void 0;
|
|
74
72
|
const schema = responses[code]?.content?.["application/json"]?.schema ?? responses[code]?.content?.["application/json;charset=utf-8"]?.schema;
|
|
75
73
|
return schema ? deref(spec, schema) : void 0;
|
|
@@ -80,7 +78,7 @@ function enumerateOperations(spec) {
|
|
|
80
78
|
for (const [path, item] of Object.entries(doc.paths ?? {})) {
|
|
81
79
|
if (!item || typeof item !== "object") continue;
|
|
82
80
|
for (const [method, op] of Object.entries(item)) {
|
|
83
|
-
if (!HTTP_METHODS.
|
|
81
|
+
if (!HTTP_METHODS.has(method.toLowerCase())) continue;
|
|
84
82
|
if (!op || typeof op !== "object") continue;
|
|
85
83
|
const declaredStatuses = Object.keys(op.responses ?? {}).filter((c) => /^\d{3}$/.test(c));
|
|
86
84
|
ops.push({ method: method.toUpperCase(), path, operationId: op.operationId, declaredStatuses, responses: op.responses });
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const path = require("path");
|
|
3
|
-
const promises = require("fs/promises");
|
|
2
|
+
const path = require("node:path");
|
|
3
|
+
const promises = require("node:fs/promises");
|
|
4
4
|
function toCSV(ds) {
|
|
5
|
-
const escape = (s) => s.includes(",") || s.includes('"') || s.includes("\n") ? `"${s.
|
|
5
|
+
const escape = (s) => s.includes(",") || s.includes('"') || s.includes("\n") ? `"${s.replaceAll('"', '""')}"` : s;
|
|
6
6
|
return [ds.columns, ...ds.rows].map((row) => row.map(escape).join(",")).join("\n");
|
|
7
7
|
}
|
|
8
8
|
function parseCSV(text) {
|
|
@@ -37,7 +37,7 @@ const DATA_DIR = "data";
|
|
|
37
37
|
const hasRows = (ds) => !!ds && ds.columns.length > 0;
|
|
38
38
|
const refFor = (id) => `${DATA_DIR}/${id}.csv`;
|
|
39
39
|
async function externalizeDataSets(col, colDir) {
|
|
40
|
-
const clone =
|
|
40
|
+
const clone = structuredClone(col);
|
|
41
41
|
const writes = [];
|
|
42
42
|
const removals = [];
|
|
43
43
|
const handle = (h) => {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
function escapeHtml(s) {
|
|
3
|
+
return String(s ?? "").replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
4
|
+
}
|
|
5
|
+
function escapeXml(s) {
|
|
6
|
+
return escapeHtml(s).replaceAll("'", "'");
|
|
7
|
+
}
|
|
8
|
+
exports.escapeHtml = escapeHtml;
|
|
9
|
+
exports.escapeXml = escapeXml;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const uuid = require("uuid");
|
|
4
|
-
const soapHandler = require("./soap-handler-
|
|
4
|
+
const soapHandler = require("./soap-handler-BznuMFIP.js");
|
|
5
5
|
require("./handle-CL-nWtYA.js");
|
|
6
|
-
require("https");
|
|
7
|
-
require("http");
|
|
6
|
+
require("node:https");
|
|
7
|
+
require("node:http");
|
|
8
8
|
require("@xmldom/xmldom");
|
|
9
9
|
const SOAP_11_CONTENT_TYPE = "text/xml; charset=utf-8";
|
|
10
10
|
const SOAP_12_CONTENT_TYPE = "application/soap+xml; charset=utf-8";
|
|
@@ -134,7 +134,7 @@ function importWsdl(wsdlText, opts = {}) {
|
|
|
134
134
|
return { parsed, collection, mock };
|
|
135
135
|
}
|
|
136
136
|
function defaultCollectionRelPath(ws, collection) {
|
|
137
|
-
const safe = collection.name.toLowerCase().
|
|
137
|
+
const safe = collection.name.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replaceAll(/^-+|-+$/g, "") || "wsdl";
|
|
138
138
|
let i = 0;
|
|
139
139
|
let candidate = `collections/${safe}.json`;
|
|
140
140
|
const existing = new Set(ws.collections);
|
|
@@ -21,9 +21,9 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
21
21
|
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
22
|
mod
|
|
23
23
|
));
|
|
24
|
-
const http = require("http");
|
|
25
|
-
const crypto = require("crypto");
|
|
26
|
-
const vm = require("vm");
|
|
24
|
+
const http = require("node:http");
|
|
25
|
+
const crypto = require("node:crypto");
|
|
26
|
+
const vm = require("node:vm");
|
|
27
27
|
const dayjs = require("dayjs");
|
|
28
28
|
const xmldom = require("@xmldom/xmldom");
|
|
29
29
|
function _interopNamespaceDefault(e) {
|
|
@@ -45,7 +45,7 @@ function _interopNamespaceDefault(e) {
|
|
|
45
45
|
const vm__namespace = /* @__PURE__ */ _interopNamespaceDefault(vm);
|
|
46
46
|
let _fakerCache = null;
|
|
47
47
|
async function getFaker() {
|
|
48
|
-
|
|
48
|
+
_fakerCache ??= await import("@faker-js/faker");
|
|
49
49
|
return _fakerCache.faker;
|
|
50
50
|
}
|
|
51
51
|
const running = /* @__PURE__ */ new Map();
|
|
@@ -58,7 +58,7 @@ function updateMockRoutes(id, routes) {
|
|
|
58
58
|
liveRoutes.set(id, routes);
|
|
59
59
|
}
|
|
60
60
|
function matchPath(pattern, urlPath) {
|
|
61
|
-
const regexStr = pattern.
|
|
61
|
+
const regexStr = pattern.replaceAll(/[.+?^${}()|[\]\\]/g, "\\$&").replaceAll(/:[^/]+/g, "[^/]+");
|
|
62
62
|
try {
|
|
63
63
|
const regex = new RegExp("^" + regexStr + "/?$");
|
|
64
64
|
return regex.test(urlPath.split("?")[0]);
|
|
@@ -103,15 +103,13 @@ const ELEMENT_NODE = 1, TEXT_NODE = 3, CDATA_NODE = 4;
|
|
|
103
103
|
function elementToValue(el) {
|
|
104
104
|
const obj = {};
|
|
105
105
|
if (el.attributes) {
|
|
106
|
-
for (
|
|
107
|
-
const a = el.attributes[i];
|
|
106
|
+
for (const a of Array.from(el.attributes)) {
|
|
108
107
|
obj["@" + a.nodeName] = a.nodeValue ?? "";
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
110
|
let text = "";
|
|
112
111
|
const childEls = [];
|
|
113
|
-
for (
|
|
114
|
-
const c = el.childNodes[i];
|
|
112
|
+
for (const c of Array.from(el.childNodes)) {
|
|
115
113
|
if (c.nodeType === ELEMENT_NODE) childEls.push(c);
|
|
116
114
|
else if (c.nodeType === TEXT_NODE || c.nodeType === CDATA_NODE) text += c.nodeValue ?? "";
|
|
117
115
|
}
|
|
@@ -136,7 +134,7 @@ function parseXmlToObject(xml) {
|
|
|
136
134
|
} };
|
|
137
135
|
const doc = new xmldom.DOMParser({ errorHandler: silent }).parseFromString(xml, "text/xml");
|
|
138
136
|
const root = doc.documentElement;
|
|
139
|
-
if (
|
|
137
|
+
if (root?.nodeType !== ELEMENT_NODE) return null;
|
|
140
138
|
return { [root.nodeName]: elementToValue(root) };
|
|
141
139
|
} catch {
|
|
142
140
|
return null;
|
|
@@ -155,7 +153,7 @@ function parseRequestBody(bodyRaw, contentType) {
|
|
|
155
153
|
return {};
|
|
156
154
|
}
|
|
157
155
|
function interpolateMockBody(body, context) {
|
|
158
|
-
return body.
|
|
156
|
+
return body.replaceAll(/\{\{([^}]+)\}\}/g, (match, key) => {
|
|
159
157
|
const expr = key.trim();
|
|
160
158
|
if (expr.includes(".") || expr.includes("(")) {
|
|
161
159
|
try {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const http = require("http");
|
|
3
|
-
const crypto = require("crypto");
|
|
2
|
+
const http = require("node:http");
|
|
3
|
+
const crypto = require("node:crypto");
|
|
4
4
|
const undici = require("undici");
|
|
5
5
|
const DEFAULT_MASK_HEADERS = /* @__PURE__ */ new Set([
|
|
6
6
|
"authorization",
|
|
@@ -153,7 +153,7 @@ function getAllApplicableHooks(folderId, collection) {
|
|
|
153
153
|
}
|
|
154
154
|
function authIsConfigured(auth) {
|
|
155
155
|
if (!auth || auth.type === "none") return false;
|
|
156
|
-
const set = (s) => !!
|
|
156
|
+
const set = (s) => !!s?.trim();
|
|
157
157
|
switch (auth.type) {
|
|
158
158
|
case "bearer":
|
|
159
159
|
return set(auth.token) || set(auth.tokenSecretRef);
|
|
@@ -223,7 +223,7 @@ function parseDataRow(columns, row) {
|
|
|
223
223
|
const key = col.toLowerCase();
|
|
224
224
|
const val = row[ci] ?? "";
|
|
225
225
|
if (RESERVED_STATUS.has(key)) {
|
|
226
|
-
const nums = val.split(/[\s,|]+/).map((x) => parseInt(x, 10)).filter((n) => Number.isFinite(n));
|
|
226
|
+
const nums = val.split(/[\s,|]+/).map((x) => Number.parseInt(x, 10)).filter((n) => Number.isFinite(n));
|
|
227
227
|
if (nums.length) expectStatus = nums;
|
|
228
228
|
} else if (RESERVED_OWASP.has(key)) {
|
|
229
229
|
if (val.trim()) owaspTag = val.trim().toUpperCase();
|