@testsmith/api-spector 0.6.3 → 0.6.5
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-u5atf7vH.js} +6 -6
- package/out/renderer/assets/{SoapEditor-rxb3heue.js → SoapEditor-D8MpL0vd.js} +3 -3
- package/out/renderer/assets/{index-ByGIqJ2H.js → index-C0kKFo3R.js} +380 -269
- package/out/renderer/index.html +1 -1
- package/package.json +1 -1
- package/out/main/chunks/escape-BwPM4Tf6.js +0 -9
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./GraphQLEditor-
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./GraphQLEditor-u5atf7vH.js","./codemirror-F6m3Hm1M.js","./ajv-2MAg6kGF.js","./SoapEditor-D8MpL0vd.js"])))=>i.map(i=>d[i]);
|
|
2
2
|
import { r as reactExports, g as getDefaultExportFromCjs, R as React$2, a as autocompletion, h as hoverTooltip, j as jsxRuntimeExports, k as keymap, t as toggleComment, x as xml, b as json, c as ReactCodeMirror, o as oneDark, d as javascript } from "./codemirror-F6m3Hm1M.js";
|
|
3
3
|
import { A as Ajv } from "./ajv-2MAg6kGF.js";
|
|
4
4
|
var client = { exports: {} };
|
|
@@ -12797,132 +12797,6 @@ const immerImpl = (initializer) => (set2, get2, store) => {
|
|
|
12797
12797
|
return initializer(store.setState, get2, store);
|
|
12798
12798
|
};
|
|
12799
12799
|
const immer = immerImpl;
|
|
12800
|
-
function uniqueName(base, existing) {
|
|
12801
|
-
if (!existing.includes(base)) return base;
|
|
12802
|
-
let i = 2;
|
|
12803
|
-
while (existing.includes(`${base} (${i})`)) i++;
|
|
12804
|
-
return `${base} (${i})`;
|
|
12805
|
-
}
|
|
12806
|
-
function colRelPath(name, id) {
|
|
12807
|
-
const safe = safeName(name) || id.slice(0, 8);
|
|
12808
|
-
return `collections/${safe}.spector`;
|
|
12809
|
-
}
|
|
12810
|
-
function envRelPath(name, id) {
|
|
12811
|
-
const safe = safeName(name) || id;
|
|
12812
|
-
return `environments/${safe}.env.json`;
|
|
12813
|
-
}
|
|
12814
|
-
function safeName(name) {
|
|
12815
|
-
return name.trim().toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-_]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
12816
|
-
}
|
|
12817
|
-
let getRandomValues;
|
|
12818
|
-
const rnds8 = new Uint8Array(16);
|
|
12819
|
-
function rng() {
|
|
12820
|
-
if (!getRandomValues) {
|
|
12821
|
-
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
|
|
12822
|
-
if (!getRandomValues) {
|
|
12823
|
-
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
12824
|
-
}
|
|
12825
|
-
}
|
|
12826
|
-
return getRandomValues(rnds8);
|
|
12827
|
-
}
|
|
12828
|
-
const byteToHex = [];
|
|
12829
|
-
for (let i = 0; i < 256; ++i) {
|
|
12830
|
-
byteToHex.push((i + 256).toString(16).slice(1));
|
|
12831
|
-
}
|
|
12832
|
-
function unsafeStringify(arr, offset = 0) {
|
|
12833
|
-
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
12834
|
-
}
|
|
12835
|
-
const randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
|
|
12836
|
-
const native = {
|
|
12837
|
-
randomUUID
|
|
12838
|
-
};
|
|
12839
|
-
function v4(options, buf, offset) {
|
|
12840
|
-
if (native.randomUUID && true && !options) {
|
|
12841
|
-
return native.randomUUID();
|
|
12842
|
-
}
|
|
12843
|
-
options = options || {};
|
|
12844
|
-
const rnds = options.random || (options.rng || rng)();
|
|
12845
|
-
rnds[6] = rnds[6] & 15 | 64;
|
|
12846
|
-
rnds[8] = rnds[8] & 63 | 128;
|
|
12847
|
-
return unsafeStringify(rnds);
|
|
12848
|
-
}
|
|
12849
|
-
function orderedChildren(folder2) {
|
|
12850
|
-
const reqSet = new Set(folder2.requestIds);
|
|
12851
|
-
const folderSet = new Set(folder2.folders.map((f) => f.id));
|
|
12852
|
-
const seen2 = /* @__PURE__ */ new Set();
|
|
12853
|
-
const out = [];
|
|
12854
|
-
for (const ref of folder2.childOrder ?? []) {
|
|
12855
|
-
const key = `${ref.type}:${ref.id}`;
|
|
12856
|
-
if (seen2.has(key)) continue;
|
|
12857
|
-
if (ref.type === "request" && reqSet.has(ref.id) || ref.type === "folder" && folderSet.has(ref.id)) {
|
|
12858
|
-
out.push({ type: ref.type, id: ref.id });
|
|
12859
|
-
seen2.add(key);
|
|
12860
|
-
}
|
|
12861
|
-
}
|
|
12862
|
-
for (const id of folder2.requestIds) if (!seen2.has(`request:${id}`)) out.push({ type: "request", id });
|
|
12863
|
-
for (const f of folder2.folders) if (!seen2.has(`folder:${f.id}`)) out.push({ type: "folder", id: f.id });
|
|
12864
|
-
return out;
|
|
12865
|
-
}
|
|
12866
|
-
function findFolder$1(root2, id) {
|
|
12867
|
-
if (root2.id === id) return root2;
|
|
12868
|
-
for (const sub of root2.folders) {
|
|
12869
|
-
const found = findFolder$1(sub, id);
|
|
12870
|
-
if (found) return found;
|
|
12871
|
-
}
|
|
12872
|
-
return null;
|
|
12873
|
-
}
|
|
12874
|
-
function findFolderContaining(root2, reqId) {
|
|
12875
|
-
if (root2.requestIds.includes(reqId)) return root2;
|
|
12876
|
-
for (const sub of root2.folders) {
|
|
12877
|
-
const found = findFolderContaining(sub, reqId);
|
|
12878
|
-
if (found) return found;
|
|
12879
|
-
}
|
|
12880
|
-
return null;
|
|
12881
|
-
}
|
|
12882
|
-
function removeFromFolder(root2, reqId) {
|
|
12883
|
-
root2.requestIds = root2.requestIds.filter((id) => id !== reqId);
|
|
12884
|
-
root2.folders.forEach((sub) => removeFromFolder(sub, reqId));
|
|
12885
|
-
}
|
|
12886
|
-
function removeFolderById(parent, folderId) {
|
|
12887
|
-
const idx = parent.folders.findIndex((f) => f.id === folderId);
|
|
12888
|
-
if (idx !== -1) {
|
|
12889
|
-
parent.folders.splice(idx, 1);
|
|
12890
|
-
return true;
|
|
12891
|
-
}
|
|
12892
|
-
for (const sub of parent.folders) {
|
|
12893
|
-
if (removeFolderById(sub, folderId)) return true;
|
|
12894
|
-
}
|
|
12895
|
-
return false;
|
|
12896
|
-
}
|
|
12897
|
-
function findFolderParent(root2, folderId) {
|
|
12898
|
-
for (const sub of root2.folders) {
|
|
12899
|
-
if (sub.id === folderId) return root2;
|
|
12900
|
-
const found = findFolderParent(sub, folderId);
|
|
12901
|
-
if (found) return found;
|
|
12902
|
-
}
|
|
12903
|
-
return null;
|
|
12904
|
-
}
|
|
12905
|
-
function findFolderPath(root2, requestId) {
|
|
12906
|
-
if (root2.requestIds.includes(requestId)) return [root2];
|
|
12907
|
-
for (const sub of root2.folders) {
|
|
12908
|
-
const path = findFolderPath(sub, requestId);
|
|
12909
|
-
if (path.length > 0) return [root2, ...path];
|
|
12910
|
-
}
|
|
12911
|
-
return [];
|
|
12912
|
-
}
|
|
12913
|
-
function collectRequestIds$1(f) {
|
|
12914
|
-
return [...f.requestIds, ...f.folders.flatMap(collectRequestIds$1)];
|
|
12915
|
-
}
|
|
12916
|
-
function reIdFolderTree(root2, mapRequestId) {
|
|
12917
|
-
root2.id = v4();
|
|
12918
|
-
root2.requestIds = root2.requestIds.map(mapRequestId);
|
|
12919
|
-
root2.folders.forEach((sub) => reIdFolderTree(sub, mapRequestId));
|
|
12920
|
-
}
|
|
12921
|
-
function cloneAndReId(folder2, mapRequestId) {
|
|
12922
|
-
const cloned = JSON.parse(JSON.stringify(folder2));
|
|
12923
|
-
reIdFolderTree(cloned, mapRequestId);
|
|
12924
|
-
return cloned;
|
|
12925
|
-
}
|
|
12926
12800
|
const WS_MESSAGE_CAP = 1e3;
|
|
12927
12801
|
const createWsSlice = (set2) => ({
|
|
12928
12802
|
wsConnections: {},
|
|
@@ -12988,7 +12862,7 @@ const createStreamSlice = (set2) => ({
|
|
|
12988
12862
|
s.liveStream = { streamId, tabId, events: [], streaming: true };
|
|
12989
12863
|
}),
|
|
12990
12864
|
pushLiveStreamEvents: (streamId, events) => set2((s) => {
|
|
12991
|
-
if (
|
|
12865
|
+
if (s.liveStream?.streamId !== streamId) return;
|
|
12992
12866
|
s.liveStream.events.push(...events);
|
|
12993
12867
|
const overflow = s.liveStream.events.length - LIVE_EVENT_CAP;
|
|
12994
12868
|
if (overflow > 0) s.liveStream.events.splice(0, overflow);
|
|
@@ -13088,7 +12962,7 @@ const createContractSlice = (set2) => ({
|
|
|
13088
12962
|
loadContractSnapshot: (relPath, snapshot) => set2((s) => {
|
|
13089
12963
|
s.contractSnapshots[relPath] = snapshot;
|
|
13090
12964
|
if (s.workspace) {
|
|
13091
|
-
|
|
12965
|
+
s.workspace.contracts ??= [];
|
|
13092
12966
|
if (!s.workspace.contracts.includes(relPath)) s.workspace.contracts.push(relPath);
|
|
13093
12967
|
}
|
|
13094
12968
|
}),
|
|
@@ -13111,6 +12985,38 @@ const createContractSlice = (set2) => ({
|
|
|
13111
12985
|
s.contractDesignerSeed = null;
|
|
13112
12986
|
})
|
|
13113
12987
|
});
|
|
12988
|
+
let getRandomValues;
|
|
12989
|
+
const rnds8 = new Uint8Array(16);
|
|
12990
|
+
function rng() {
|
|
12991
|
+
if (!getRandomValues) {
|
|
12992
|
+
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
|
|
12993
|
+
if (!getRandomValues) {
|
|
12994
|
+
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
12995
|
+
}
|
|
12996
|
+
}
|
|
12997
|
+
return getRandomValues(rnds8);
|
|
12998
|
+
}
|
|
12999
|
+
const byteToHex = [];
|
|
13000
|
+
for (let i = 0; i < 256; ++i) {
|
|
13001
|
+
byteToHex.push((i + 256).toString(16).slice(1));
|
|
13002
|
+
}
|
|
13003
|
+
function unsafeStringify(arr, offset = 0) {
|
|
13004
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
13005
|
+
}
|
|
13006
|
+
const randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
|
|
13007
|
+
const native = {
|
|
13008
|
+
randomUUID
|
|
13009
|
+
};
|
|
13010
|
+
function v4(options, buf, offset) {
|
|
13011
|
+
if (native.randomUUID && true && !options) {
|
|
13012
|
+
return native.randomUUID();
|
|
13013
|
+
}
|
|
13014
|
+
options = options || {};
|
|
13015
|
+
const rnds = options.random || (options.rng || rng)();
|
|
13016
|
+
rnds[6] = rnds[6] & 15 | 64;
|
|
13017
|
+
rnds[8] = rnds[8] & 63 | 128;
|
|
13018
|
+
return unsafeStringify(rnds);
|
|
13019
|
+
}
|
|
13114
13020
|
function makeTab(requestId, collectionId, opts = {}) {
|
|
13115
13021
|
return {
|
|
13116
13022
|
id: v4(),
|
|
@@ -13241,6 +13147,100 @@ const createTabsSlice = (set2, get2) => ({
|
|
|
13241
13147
|
if (tab) tab.requestTab = t;
|
|
13242
13148
|
})
|
|
13243
13149
|
});
|
|
13150
|
+
function uniqueName(base, existing) {
|
|
13151
|
+
if (!existing.includes(base)) return base;
|
|
13152
|
+
let i = 2;
|
|
13153
|
+
while (existing.includes(`${base} (${i})`)) i++;
|
|
13154
|
+
return `${base} (${i})`;
|
|
13155
|
+
}
|
|
13156
|
+
function colRelPath(name, id) {
|
|
13157
|
+
const safe = safeName(name) || id.slice(0, 8);
|
|
13158
|
+
return `collections/${safe}.spector`;
|
|
13159
|
+
}
|
|
13160
|
+
function envRelPath(name, id) {
|
|
13161
|
+
const safe = safeName(name) || id;
|
|
13162
|
+
return `environments/${safe}.env.json`;
|
|
13163
|
+
}
|
|
13164
|
+
function safeName(name) {
|
|
13165
|
+
return name.trim().toLowerCase().replaceAll(/\s+/g, "-").replaceAll(/[^a-z0-9-_]/g, "").replaceAll(/-+/g, "-").replaceAll(/^-|-$/g, "");
|
|
13166
|
+
}
|
|
13167
|
+
function orderedChildren(folder2) {
|
|
13168
|
+
const reqSet = new Set(folder2.requestIds);
|
|
13169
|
+
const folderSet = new Set(folder2.folders.map((f) => f.id));
|
|
13170
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
13171
|
+
const out = [];
|
|
13172
|
+
for (const ref of folder2.childOrder ?? []) {
|
|
13173
|
+
const key = `${ref.type}:${ref.id}`;
|
|
13174
|
+
if (seen2.has(key)) continue;
|
|
13175
|
+
if (ref.type === "request" && reqSet.has(ref.id) || ref.type === "folder" && folderSet.has(ref.id)) {
|
|
13176
|
+
out.push({ type: ref.type, id: ref.id });
|
|
13177
|
+
seen2.add(key);
|
|
13178
|
+
}
|
|
13179
|
+
}
|
|
13180
|
+
for (const id of folder2.requestIds) if (!seen2.has(`request:${id}`)) out.push({ type: "request", id });
|
|
13181
|
+
for (const f of folder2.folders) if (!seen2.has(`folder:${f.id}`)) out.push({ type: "folder", id: f.id });
|
|
13182
|
+
return out;
|
|
13183
|
+
}
|
|
13184
|
+
function findFolder$1(root2, id) {
|
|
13185
|
+
if (root2.id === id) return root2;
|
|
13186
|
+
for (const sub of root2.folders) {
|
|
13187
|
+
const found = findFolder$1(sub, id);
|
|
13188
|
+
if (found) return found;
|
|
13189
|
+
}
|
|
13190
|
+
return null;
|
|
13191
|
+
}
|
|
13192
|
+
function findFolderContaining(root2, reqId) {
|
|
13193
|
+
if (root2.requestIds.includes(reqId)) return root2;
|
|
13194
|
+
for (const sub of root2.folders) {
|
|
13195
|
+
const found = findFolderContaining(sub, reqId);
|
|
13196
|
+
if (found) return found;
|
|
13197
|
+
}
|
|
13198
|
+
return null;
|
|
13199
|
+
}
|
|
13200
|
+
function removeFromFolder(root2, reqId) {
|
|
13201
|
+
root2.requestIds = root2.requestIds.filter((id) => id !== reqId);
|
|
13202
|
+
root2.folders.forEach((sub) => removeFromFolder(sub, reqId));
|
|
13203
|
+
}
|
|
13204
|
+
function removeFolderById(parent, folderId) {
|
|
13205
|
+
const idx = parent.folders.findIndex((f) => f.id === folderId);
|
|
13206
|
+
if (idx !== -1) {
|
|
13207
|
+
parent.folders.splice(idx, 1);
|
|
13208
|
+
return true;
|
|
13209
|
+
}
|
|
13210
|
+
for (const sub of parent.folders) {
|
|
13211
|
+
if (removeFolderById(sub, folderId)) return true;
|
|
13212
|
+
}
|
|
13213
|
+
return false;
|
|
13214
|
+
}
|
|
13215
|
+
function findFolderParent(root2, folderId) {
|
|
13216
|
+
for (const sub of root2.folders) {
|
|
13217
|
+
if (sub.id === folderId) return root2;
|
|
13218
|
+
const found = findFolderParent(sub, folderId);
|
|
13219
|
+
if (found) return found;
|
|
13220
|
+
}
|
|
13221
|
+
return null;
|
|
13222
|
+
}
|
|
13223
|
+
function findFolderPath(root2, requestId) {
|
|
13224
|
+
if (root2.requestIds.includes(requestId)) return [root2];
|
|
13225
|
+
for (const sub of root2.folders) {
|
|
13226
|
+
const path = findFolderPath(sub, requestId);
|
|
13227
|
+
if (path.length > 0) return [root2, ...path];
|
|
13228
|
+
}
|
|
13229
|
+
return [];
|
|
13230
|
+
}
|
|
13231
|
+
function collectRequestIds$1(f) {
|
|
13232
|
+
return [...f.requestIds, ...f.folders.flatMap(collectRequestIds$1)];
|
|
13233
|
+
}
|
|
13234
|
+
function reIdFolderTree(root2, mapRequestId) {
|
|
13235
|
+
root2.id = v4();
|
|
13236
|
+
root2.requestIds = root2.requestIds.map(mapRequestId);
|
|
13237
|
+
root2.folders.forEach((sub) => reIdFolderTree(sub, mapRequestId));
|
|
13238
|
+
}
|
|
13239
|
+
function cloneAndReId(folder2, mapRequestId) {
|
|
13240
|
+
const cloned = structuredClone(folder2);
|
|
13241
|
+
reIdFolderTree(cloned, mapRequestId);
|
|
13242
|
+
return cloned;
|
|
13243
|
+
}
|
|
13244
13244
|
const WRITE_METHODS$1 = /* @__PURE__ */ new Set(["POST", "PUT", "PATCH"]);
|
|
13245
13245
|
function newId() {
|
|
13246
13246
|
try {
|
|
@@ -13250,7 +13250,7 @@ function newId() {
|
|
|
13250
13250
|
}
|
|
13251
13251
|
}
|
|
13252
13252
|
function clone(base, patch) {
|
|
13253
|
-
const copy2 =
|
|
13253
|
+
const copy2 = structuredClone(base);
|
|
13254
13254
|
copy2.id = newId();
|
|
13255
13255
|
delete copy2.examples;
|
|
13256
13256
|
delete copy2.contract;
|
|
@@ -13482,8 +13482,8 @@ const createCollectionsSlice = (set2, get2) => ({
|
|
|
13482
13482
|
s.tabs = s.tabs.filter((t) => t.collectionId !== id);
|
|
13483
13483
|
if (s.activeCollectionId === id) {
|
|
13484
13484
|
s.activeCollectionId = Object.keys(s.collections)[0] ?? null;
|
|
13485
|
-
const
|
|
13486
|
-
if (!
|
|
13485
|
+
const hasActiveTab = s.tabs.some((t) => t.id === s.activeTabId);
|
|
13486
|
+
if (!hasActiveTab) s.activeTabId = s.tabs[0]?.id ?? null;
|
|
13487
13487
|
}
|
|
13488
13488
|
});
|
|
13489
13489
|
},
|
|
@@ -13629,7 +13629,7 @@ const createCollectionsSlice = (set2, get2) => ({
|
|
|
13629
13629
|
const entry = Object.values(s.collections).find((c) => c.data.requests[requestId]);
|
|
13630
13630
|
const ex = entry?.data.requests[requestId].examples?.find((e) => e.id === exampleId);
|
|
13631
13631
|
if (!entry || !ex) return;
|
|
13632
|
-
ex.request = { ...ex.request
|
|
13632
|
+
ex.request = { ...ex.request, ...patch };
|
|
13633
13633
|
entry.dirty = true;
|
|
13634
13634
|
}),
|
|
13635
13635
|
updateExampleResponse: (requestId, exampleId, response) => set2((s) => {
|
|
@@ -13711,7 +13711,7 @@ const createCollectionsSlice = (set2, get2) => ({
|
|
|
13711
13711
|
}),
|
|
13712
13712
|
duplicateRequest: (collectionId, id) => set2((s) => {
|
|
13713
13713
|
const col = s.collections[collectionId]?.data;
|
|
13714
|
-
if (!col
|
|
13714
|
+
if (!col?.requests[id]) return;
|
|
13715
13715
|
const orig = col.requests[id];
|
|
13716
13716
|
const copy2 = { ...JSON.parse(JSON.stringify(orig)), id: v4(), name: orig.name + " (copy)" };
|
|
13717
13717
|
col.requests[copy2.id] = copy2;
|
|
@@ -13834,7 +13834,7 @@ const createCollectionsSlice = (set2, get2) => ({
|
|
|
13834
13834
|
const entry = Object.values(s.collections).find((c) => c.data.requests[requestId]);
|
|
13835
13835
|
if (!entry) return;
|
|
13836
13836
|
const req = entry.data.requests[requestId];
|
|
13837
|
-
req.meta = { ...req.meta
|
|
13837
|
+
req.meta = { ...req.meta, tags };
|
|
13838
13838
|
entry.dirty = true;
|
|
13839
13839
|
}),
|
|
13840
13840
|
// ── Folder settings ─────────────────────────────────────────────────────────
|
|
@@ -13882,7 +13882,7 @@ const STORAGE_KEYS = {
|
|
|
13882
13882
|
updateSkipped: "apiSpectorUpdateSkipped"
|
|
13883
13883
|
};
|
|
13884
13884
|
function envSlugRelPath(name) {
|
|
13885
|
-
return `environments/${name.toLowerCase().
|
|
13885
|
+
return `environments/${name.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-")}.env.json`;
|
|
13886
13886
|
}
|
|
13887
13887
|
const createEnvironmentsSlice = (set2, get2) => ({
|
|
13888
13888
|
environments: {},
|
|
@@ -13982,7 +13982,7 @@ const createMocksSlice = (set2, get2) => ({
|
|
|
13982
13982
|
s.mocks[mock.id] = { relPath, data: mock, running: false };
|
|
13983
13983
|
s.activeMockId = mock.id;
|
|
13984
13984
|
if (s.workspace) {
|
|
13985
|
-
|
|
13985
|
+
s.workspace.mocks ??= [];
|
|
13986
13986
|
s.workspace.mocks.push(relPath);
|
|
13987
13987
|
}
|
|
13988
13988
|
}),
|
|
@@ -14045,7 +14045,7 @@ const createUiSlice = (set2) => ({
|
|
|
14045
14045
|
s.theme = t;
|
|
14046
14046
|
localStorage.setItem(STORAGE_KEYS.theme, t);
|
|
14047
14047
|
if (s.workspace) {
|
|
14048
|
-
|
|
14048
|
+
s.workspace.settings ??= {};
|
|
14049
14049
|
s.workspace.settings.theme = t;
|
|
14050
14050
|
}
|
|
14051
14051
|
if (t === "system") {
|
|
@@ -14184,7 +14184,7 @@ const useStore = create()(
|
|
|
14184
14184
|
if (activeColId && s.collections[activeColId]) {
|
|
14185
14185
|
const col = s.collections[activeColId].data;
|
|
14186
14186
|
col.collectionVariables = {
|
|
14187
|
-
...col.collectionVariables
|
|
14187
|
+
...col.collectionVariables,
|
|
14188
14188
|
...safeColVars
|
|
14189
14189
|
};
|
|
14190
14190
|
s.collections[activeColId].dirty = true;
|
|
@@ -14972,7 +14972,7 @@ function useVarNames() {
|
|
|
14972
14972
|
}
|
|
14973
14973
|
const envVars = activeEnv?.variables ?? [];
|
|
14974
14974
|
envVars.filter((v) => v.enabled && v.key).forEach((v) => names.add(v.key));
|
|
14975
|
-
return [...DYNAMIC_VAR_NAMES, ...Array.from(names).sort()];
|
|
14975
|
+
return [...DYNAMIC_VAR_NAMES, ...Array.from(names).sort((a, b) => a.localeCompare(b))];
|
|
14976
14976
|
}, [
|
|
14977
14977
|
activeEnv,
|
|
14978
14978
|
activeCollectionId,
|
|
@@ -23837,7 +23837,7 @@ function detectLocale() {
|
|
|
23837
23837
|
}
|
|
23838
23838
|
function interpolate(str, vars) {
|
|
23839
23839
|
if (!vars) return str;
|
|
23840
|
-
return str.
|
|
23840
|
+
return str.replaceAll(/:([a-zA-Z][a-zA-Z0-9]*)/g, (m, k) => k in vars ? String(vars[k]) : m);
|
|
23841
23841
|
}
|
|
23842
23842
|
function translate(locale, key, vars) {
|
|
23843
23843
|
let msg = CATALOGS[locale]?.[key] ?? key;
|
|
@@ -23872,7 +23872,8 @@ function I18nProvider({ children }) {
|
|
|
23872
23872
|
setLocaleState(l);
|
|
23873
23873
|
}, []);
|
|
23874
23874
|
const t = reactExports.useCallback((key, vars) => translate(locale, key, vars), [locale]);
|
|
23875
|
-
|
|
23875
|
+
const ctx = reactExports.useMemo(() => ({ locale, setLocale, t }), [locale, setLocale, t]);
|
|
23876
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(I18nContext.Provider, { value: ctx, children });
|
|
23876
23877
|
}
|
|
23877
23878
|
function useT() {
|
|
23878
23879
|
return reactExports.useContext(I18nContext).t;
|
|
@@ -24359,18 +24360,34 @@ function Modal({
|
|
|
24359
24360
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
24360
24361
|
"div",
|
|
24361
24362
|
{
|
|
24363
|
+
role: closeOnBackdrop ? "button" : void 0,
|
|
24364
|
+
tabIndex: closeOnBackdrop ? -1 : void 0,
|
|
24365
|
+
"aria-label": closeOnBackdrop ? "Close dialog" : void 0,
|
|
24362
24366
|
className: `fixed inset-0 ${overlayClassName}`,
|
|
24363
|
-
onClick: closeOnBackdrop ?
|
|
24364
|
-
|
|
24365
|
-
|
|
24366
|
-
|
|
24367
|
-
|
|
24368
|
-
|
|
24369
|
-
|
|
24370
|
-
|
|
24371
|
-
|
|
24372
|
-
|
|
24373
|
-
|
|
24367
|
+
onClick: closeOnBackdrop ? (e) => {
|
|
24368
|
+
if (e.target === e.currentTarget) onClose();
|
|
24369
|
+
} : void 0,
|
|
24370
|
+
onKeyDown: closeOnBackdrop ? (e) => {
|
|
24371
|
+
if (e.key === "Escape") onClose();
|
|
24372
|
+
} : void 0,
|
|
24373
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
24374
|
+
"div",
|
|
24375
|
+
{
|
|
24376
|
+
role: "dialog",
|
|
24377
|
+
"aria-modal": "true",
|
|
24378
|
+
className: panelClassName,
|
|
24379
|
+
children: [
|
|
24380
|
+
title !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-4 py-2.5 border-b border-surface-800 flex-shrink-0", children: [
|
|
24381
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
24382
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-sm font-semibold", children: title }),
|
|
24383
|
+
subtitle !== void 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-surface-400 mt-0.5", children: subtitle })
|
|
24384
|
+
] }),
|
|
24385
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: onClose, className: "text-surface-400 hover:text-[var(--text-primary)] text-lg leading-none", children: "×" })
|
|
24386
|
+
] }),
|
|
24387
|
+
children
|
|
24388
|
+
]
|
|
24389
|
+
}
|
|
24390
|
+
)
|
|
24374
24391
|
}
|
|
24375
24392
|
);
|
|
24376
24393
|
}
|
|
@@ -25053,7 +25070,7 @@ function normalisePath(url) {
|
|
|
25053
25070
|
let path = url.replace(/^\{\{[^}]+\}\}/, "").replace(/^https?:\/\/[^/]+/, "");
|
|
25054
25071
|
if (!path.startsWith("/")) path = "/" + path;
|
|
25055
25072
|
path = path.split("?")[0];
|
|
25056
|
-
path = path.
|
|
25073
|
+
path = path.replaceAll(/\{\{([^}]+)\}\}/g, "{$1}");
|
|
25057
25074
|
return path;
|
|
25058
25075
|
}
|
|
25059
25076
|
function collectRequestIds(folder2) {
|
|
@@ -25499,7 +25516,7 @@ function collectAllTags(folder2, requests) {
|
|
|
25499
25516
|
f.folders.forEach(walk2);
|
|
25500
25517
|
}
|
|
25501
25518
|
walk2(folder2);
|
|
25502
|
-
return Array.from(tags).sort();
|
|
25519
|
+
return Array.from(tags).sort((a, b) => a.localeCompare(b));
|
|
25503
25520
|
}
|
|
25504
25521
|
function folderPathTo(root2, requestId) {
|
|
25505
25522
|
if (root2.requestIds.includes(requestId)) return [root2];
|
|
@@ -25522,11 +25539,12 @@ function getHooksForRequest(requestId, collection2) {
|
|
|
25522
25539
|
before.push(...bAll, ...bEach);
|
|
25523
25540
|
afterReversed.push(...aEach, ...aAll);
|
|
25524
25541
|
}
|
|
25525
|
-
|
|
25542
|
+
afterReversed.reverse();
|
|
25543
|
+
return { before, after: afterReversed };
|
|
25526
25544
|
}
|
|
25527
25545
|
function authIsConfigured(auth) {
|
|
25528
25546
|
if (!auth || auth.type === "none") return false;
|
|
25529
|
-
const set2 = (s) => !!
|
|
25547
|
+
const set2 = (s) => !!s?.trim();
|
|
25530
25548
|
switch (auth.type) {
|
|
25531
25549
|
case "bearer":
|
|
25532
25550
|
return set2(auth.token) || set2(auth.tokenSecretRef);
|
|
@@ -25642,7 +25660,7 @@ function parseDataRow(columns, row) {
|
|
|
25642
25660
|
const key = col.toLowerCase();
|
|
25643
25661
|
const val = row[ci] ?? "";
|
|
25644
25662
|
if (RESERVED_STATUS.has(key)) {
|
|
25645
|
-
const nums = val.split(/[\s,|]+/).map((x) => parseInt(x, 10)).filter((n) => Number.isFinite(n));
|
|
25663
|
+
const nums = val.split(/[\s,|]+/).map((x) => Number.parseInt(x, 10)).filter((n) => Number.isFinite(n));
|
|
25646
25664
|
if (nums.length) expectStatus = nums;
|
|
25647
25665
|
} else if (RESERVED_OWASP.has(key)) {
|
|
25648
25666
|
if (val.trim()) owaspTag = val.trim().toUpperCase();
|
|
@@ -25727,7 +25745,7 @@ async function pushRequestAsMonitor(request2, opts) {
|
|
|
25727
25745
|
const s = useStore.getState();
|
|
25728
25746
|
const colEntry = Object.values(s.collections).find((c) => c.data.requests[request2.id]);
|
|
25729
25747
|
const collectionVars = {
|
|
25730
|
-
...colEntry?.data.collectionVariables
|
|
25748
|
+
...colEntry?.data.collectionVariables,
|
|
25731
25749
|
...s.getInheritedVariables(request2.id),
|
|
25732
25750
|
...s.sessionVars
|
|
25733
25751
|
};
|
|
@@ -25949,12 +25967,13 @@ function InlineEdit({
|
|
|
25949
25967
|
}
|
|
25950
25968
|
onCommit(trimmed);
|
|
25951
25969
|
}
|
|
25952
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
25970
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
25953
25971
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
25954
25972
|
"input",
|
|
25955
25973
|
{
|
|
25956
25974
|
ref,
|
|
25957
25975
|
value: draft,
|
|
25976
|
+
onClick: (e) => e.stopPropagation(),
|
|
25958
25977
|
onChange: (e) => {
|
|
25959
25978
|
setDraft(e.target.value);
|
|
25960
25979
|
setError(null);
|
|
@@ -26046,6 +26065,8 @@ function ContextMenu({ items, x, y, onClose }) {
|
|
|
26046
26065
|
"div",
|
|
26047
26066
|
{
|
|
26048
26067
|
ref,
|
|
26068
|
+
role: "menu",
|
|
26069
|
+
tabIndex: -1,
|
|
26049
26070
|
style: { position: "fixed", top: pos.top, left: pos.left, zIndex: 9999 },
|
|
26050
26071
|
className: "bg-surface-900 border border-surface-700 rounded-lg shadow-2xl py-1 min-w-[170px]",
|
|
26051
26072
|
onMouseDown: (e) => e.stopPropagation(),
|
|
@@ -26096,6 +26117,14 @@ function DotsBtn({ items }) {
|
|
|
26096
26117
|
menu && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenu, { items, x: menu.x, y: menu.y, onClose: () => setMenu(null) })
|
|
26097
26118
|
] });
|
|
26098
26119
|
}
|
|
26120
|
+
function onActivateKey(handler) {
|
|
26121
|
+
return (e) => {
|
|
26122
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
26123
|
+
e.preventDefault();
|
|
26124
|
+
handler();
|
|
26125
|
+
}
|
|
26126
|
+
};
|
|
26127
|
+
}
|
|
26099
26128
|
function useToast(durationMs = 3e3) {
|
|
26100
26129
|
const [toast, setToast] = reactExports.useState(null);
|
|
26101
26130
|
const timer = reactExports.useRef(null);
|
|
@@ -26202,6 +26231,14 @@ function RequestRow({
|
|
|
26202
26231
|
"div",
|
|
26203
26232
|
{
|
|
26204
26233
|
draggable: true,
|
|
26234
|
+
role: "button",
|
|
26235
|
+
tabIndex: 0,
|
|
26236
|
+
onKeyDown: (e) => {
|
|
26237
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
26238
|
+
e.preventDefault();
|
|
26239
|
+
handleRowClick(e);
|
|
26240
|
+
}
|
|
26241
|
+
},
|
|
26205
26242
|
className: `group flex items-start gap-1.5 py-1 pr-1 rounded-sm cursor-pointer transition-colors ${disabled ? "opacity-40" : ""} ${selected ? "bg-blue-950/40 ring-1 ring-inset ring-blue-500" : isActive ? "bg-surface-800 text-[var(--text-primary)]" : "text-surface-300 hover:bg-surface-800"}`,
|
|
26206
26243
|
style: { paddingLeft: indent },
|
|
26207
26244
|
onClick: handleRowClick,
|
|
@@ -26351,7 +26388,10 @@ function ExampleRow({ name, indent, isActive, onOpen, onRename, onDelete, onDupl
|
|
|
26351
26388
|
{
|
|
26352
26389
|
className: `group flex items-center gap-1.5 py-1 pr-1 rounded-sm cursor-pointer transition-colors ${isActive ? "bg-surface-800 text-[var(--text-primary)]" : "text-surface-400 hover:bg-surface-800"}`,
|
|
26353
26390
|
style: { paddingLeft: indent },
|
|
26391
|
+
role: "button",
|
|
26392
|
+
tabIndex: 0,
|
|
26354
26393
|
onClick: onOpen,
|
|
26394
|
+
onKeyDown: onActivateKey(onOpen),
|
|
26355
26395
|
onDoubleClick: () => setRenaming(true),
|
|
26356
26396
|
children: [
|
|
26357
26397
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "shrink-0 text-[8px] font-bold px-1 py-px rounded bg-surface-700 text-surface-300", title: t("Example"), children: "EX" }),
|
|
@@ -26467,46 +26507,56 @@ function TagChips({
|
|
|
26467
26507
|
setAdding(false);
|
|
26468
26508
|
onDoneAdding?.();
|
|
26469
26509
|
}
|
|
26470
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
26471
|
-
|
|
26472
|
-
|
|
26473
|
-
|
|
26474
|
-
|
|
26475
|
-
|
|
26476
|
-
|
|
26477
|
-
|
|
26478
|
-
|
|
26479
|
-
|
|
26480
|
-
|
|
26481
|
-
|
|
26482
|
-
|
|
26483
|
-
|
|
26484
|
-
|
|
26485
|
-
|
|
26486
|
-
|
|
26487
|
-
|
|
26488
|
-
|
|
26489
|
-
|
|
26490
|
-
|
|
26491
|
-
|
|
26492
|
-
|
|
26493
|
-
|
|
26494
|
-
|
|
26495
|
-
|
|
26496
|
-
|
|
26497
|
-
|
|
26498
|
-
|
|
26499
|
-
|
|
26500
|
-
|
|
26510
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
26511
|
+
"div",
|
|
26512
|
+
{
|
|
26513
|
+
role: "group",
|
|
26514
|
+
"aria-label": "Tags",
|
|
26515
|
+
className: "flex flex-wrap items-center gap-0.5 mt-0.5",
|
|
26516
|
+
onClick: (e) => e.stopPropagation(),
|
|
26517
|
+
onKeyDown: (e) => e.stopPropagation(),
|
|
26518
|
+
children: [
|
|
26519
|
+
tags.map((tag) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
26520
|
+
"span",
|
|
26521
|
+
{
|
|
26522
|
+
className: "flex items-center gap-0.5 px-1 py-px rounded text-[9px] bg-blue-900/50 text-blue-300 border border-blue-800/50",
|
|
26523
|
+
children: [
|
|
26524
|
+
tag,
|
|
26525
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
26526
|
+
"button",
|
|
26527
|
+
{
|
|
26528
|
+
onClick: () => onRemove(tag),
|
|
26529
|
+
className: "hover:text-red-400 leading-none ml-0.5",
|
|
26530
|
+
children: "×"
|
|
26531
|
+
}
|
|
26532
|
+
)
|
|
26533
|
+
]
|
|
26534
|
+
},
|
|
26535
|
+
tag
|
|
26536
|
+
)),
|
|
26537
|
+
adding ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
26538
|
+
"input",
|
|
26539
|
+
{
|
|
26540
|
+
ref: inputRef,
|
|
26541
|
+
value: draft,
|
|
26542
|
+
onChange: (e) => setDraft(e.target.value),
|
|
26543
|
+
onKeyDown: (e) => {
|
|
26544
|
+
if (e.key === "Enter") commit();
|
|
26545
|
+
if (e.key === "Escape") {
|
|
26546
|
+
setAdding(false);
|
|
26547
|
+
setDraft("");
|
|
26548
|
+
onDoneAdding?.();
|
|
26549
|
+
}
|
|
26550
|
+
e.stopPropagation();
|
|
26551
|
+
},
|
|
26552
|
+
onBlur: commit,
|
|
26553
|
+
className: "w-16 text-[9px] bg-surface-700 rounded px-1 py-px focus:outline-none focus:ring-1 focus:ring-blue-500",
|
|
26554
|
+
placeholder: t("tag…")
|
|
26501
26555
|
}
|
|
26502
|
-
|
|
26503
|
-
|
|
26504
|
-
|
|
26505
|
-
|
|
26506
|
-
placeholder: t("tag…")
|
|
26507
|
-
}
|
|
26508
|
-
) : null
|
|
26509
|
-
] });
|
|
26556
|
+
) : null
|
|
26557
|
+
]
|
|
26558
|
+
}
|
|
26559
|
+
);
|
|
26510
26560
|
}
|
|
26511
26561
|
function methodColor$2(method) {
|
|
26512
26562
|
switch (method) {
|
|
@@ -26603,12 +26653,12 @@ function CollectionTree() {
|
|
|
26603
26653
|
} });
|
|
26604
26654
|
}
|
|
26605
26655
|
function onDropRequest(destCollectionId, destFolderId, destIndex) {
|
|
26606
|
-
if (
|
|
26656
|
+
if (dragging?.type !== "request") return;
|
|
26607
26657
|
moveRequest(dragging.collectionId, dragging.requestId, destCollectionId, destFolderId, destIndex);
|
|
26608
26658
|
setDragging(null);
|
|
26609
26659
|
}
|
|
26610
26660
|
function onDropFolder(destCollectionId, destParentFolderId, destIndex) {
|
|
26611
|
-
if (
|
|
26661
|
+
if (dragging?.type !== "folder") return;
|
|
26612
26662
|
if (dragging.collectionId !== destCollectionId) return;
|
|
26613
26663
|
moveFolder(dragging.collectionId, dragging.folderId, destParentFolderId, destIndex);
|
|
26614
26664
|
setDragging(null);
|
|
@@ -26831,10 +26881,16 @@ function CollectionNode({
|
|
|
26831
26881
|
"div",
|
|
26832
26882
|
{
|
|
26833
26883
|
className: `group flex items-center gap-1 px-2 py-1.5 cursor-pointer hover:bg-surface-800 transition-colors ${panelActive ? "bg-surface-800 text-[var(--text-primary)]" : isActive ? "text-[var(--text-primary)]" : "text-surface-400"} ${col.disabled ? "opacity-50" : ""} ${dropOver ? "outline outline-1 outline-blue-500 rounded" : ""}`,
|
|
26884
|
+
role: "button",
|
|
26885
|
+
tabIndex: 0,
|
|
26834
26886
|
onClick: () => {
|
|
26835
26887
|
onSelectCollection();
|
|
26836
26888
|
setExpanded((e) => !e);
|
|
26837
26889
|
},
|
|
26890
|
+
onKeyDown: onActivateKey(() => {
|
|
26891
|
+
onSelectCollection();
|
|
26892
|
+
setExpanded((e) => !e);
|
|
26893
|
+
}),
|
|
26838
26894
|
onDragOver: dragCtx.dragging ? (e) => {
|
|
26839
26895
|
e.preventDefault();
|
|
26840
26896
|
setDropOver(true);
|
|
@@ -26990,10 +27046,16 @@ function FolderRow({
|
|
|
26990
27046
|
draggable: true,
|
|
26991
27047
|
className: `group flex items-center gap-1 py-1 transition-colors cursor-pointer ${isActive ? "bg-surface-800 text-[var(--text-primary)]" : "text-surface-400 hover:bg-surface-800"} ${folder2.disabled ? "opacity-40" : ""} ${dropInside ? "outline outline-1 outline-blue-500 rounded" : ""}`,
|
|
26992
27048
|
style: { paddingLeft: indent },
|
|
27049
|
+
role: "button",
|
|
27050
|
+
tabIndex: 0,
|
|
26993
27051
|
onClick: () => {
|
|
26994
27052
|
openFolderPanel(collectionId, folder2.id);
|
|
26995
27053
|
setExpanded((e) => !e);
|
|
26996
27054
|
},
|
|
27055
|
+
onKeyDown: onActivateKey(() => {
|
|
27056
|
+
openFolderPanel(collectionId, folder2.id);
|
|
27057
|
+
setExpanded((e) => !e);
|
|
27058
|
+
}),
|
|
26997
27059
|
onDragStart: (e) => {
|
|
26998
27060
|
e.dataTransfer.effectAllowed = "move";
|
|
26999
27061
|
e.stopPropagation();
|
|
@@ -27376,8 +27438,8 @@ function jsonWithComments() {
|
|
|
27376
27438
|
function xmlWithComments() {
|
|
27377
27439
|
return [xml(), commentKeymap];
|
|
27378
27440
|
}
|
|
27379
|
-
const GraphQLEditor = reactExports.lazy(() => __vitePreload(() => import("./GraphQLEditor-
|
|
27380
|
-
const SoapEditor = reactExports.lazy(() => __vitePreload(() => import("./SoapEditor-
|
|
27441
|
+
const GraphQLEditor = reactExports.lazy(() => __vitePreload(() => import("./GraphQLEditor-u5atf7vH.js"), true ? __vite__mapDeps([0,1,2]) : void 0, import.meta.url).then((m) => ({ default: m.GraphQLEditor })));
|
|
27442
|
+
const SoapEditor = reactExports.lazy(() => __vitePreload(() => import("./SoapEditor-D8MpL0vd.js"), true ? __vite__mapDeps([3,1,2]) : void 0, import.meta.url).then((m) => ({ default: m.SoapEditor })));
|
|
27381
27443
|
function BodyTab({ request: request2, onChange }) {
|
|
27382
27444
|
const t = useT();
|
|
27383
27445
|
const editorFallback = /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 text-xs text-surface-500", children: t("Loading editor…") });
|
|
@@ -27609,7 +27671,7 @@ function AuthTab({ request: request2, onChange }) {
|
|
|
27609
27671
|
{
|
|
27610
27672
|
type: "number",
|
|
27611
27673
|
value: auth.oauth2RedirectPort ?? 9876,
|
|
27612
|
-
onChange: (e) => setAuth({ oauth2RedirectPort: parseInt(e.target.value, 10) || 9876 }),
|
|
27674
|
+
onChange: (e) => setAuth({ oauth2RedirectPort: Number.parseInt(e.target.value, 10) || 9876 }),
|
|
27613
27675
|
className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
|
|
27614
27676
|
}
|
|
27615
27677
|
)
|
|
@@ -28232,17 +28294,17 @@ function renderInline(text, keyBase) {
|
|
|
28232
28294
|
});
|
|
28233
28295
|
}
|
|
28234
28296
|
function renderMarkdown(md) {
|
|
28235
|
-
const lines = md.
|
|
28297
|
+
const lines = md.replaceAll("\r\n", "\n").split("\n");
|
|
28236
28298
|
const blocks = [];
|
|
28237
28299
|
let i = 0;
|
|
28238
28300
|
let key = 0;
|
|
28239
28301
|
const k = () => `md-${key++}`;
|
|
28240
28302
|
while (i < lines.length) {
|
|
28241
28303
|
const line = lines[i];
|
|
28242
|
-
if (
|
|
28304
|
+
if (line.trim().startsWith("```")) {
|
|
28243
28305
|
const buf2 = [];
|
|
28244
28306
|
i++;
|
|
28245
|
-
while (i < lines.length &&
|
|
28307
|
+
while (i < lines.length && !lines[i].trim().startsWith("```")) {
|
|
28246
28308
|
buf2.push(lines[i]);
|
|
28247
28309
|
i++;
|
|
28248
28310
|
}
|
|
@@ -28301,7 +28363,7 @@ function renderMarkdown(md) {
|
|
|
28301
28363
|
continue;
|
|
28302
28364
|
}
|
|
28303
28365
|
const buf = [];
|
|
28304
|
-
while (i < lines.length && lines[i].trim() !== "" &&
|
|
28366
|
+
while (i < lines.length && lines[i].trim() !== "" && !lines[i].trim().startsWith("```") && !/^(#{1,6})\s+/.test(lines[i]) && !/^\s*>\s?/.test(lines[i]) && !/^\s*[-*+]\s+/.test(lines[i]) && !/^\s*\d+\.\s+/.test(lines[i]) && !/^\s*([-*_])\1{2,}\s*$/.test(lines[i])) {
|
|
28305
28367
|
buf.push(lines[i]);
|
|
28306
28368
|
i++;
|
|
28307
28369
|
}
|
|
@@ -28453,7 +28515,7 @@ function useAiAvailable() {
|
|
|
28453
28515
|
return available;
|
|
28454
28516
|
}
|
|
28455
28517
|
async function generateDocs(input) {
|
|
28456
|
-
return electron$u.
|
|
28518
|
+
return electron$u.generateAiDocs({ ...input, model: getAiConfig().model });
|
|
28457
28519
|
}
|
|
28458
28520
|
function kvLines(label, rows) {
|
|
28459
28521
|
const on = (rows ?? []).filter((r) => r.enabled !== false && r.key);
|
|
@@ -28466,8 +28528,7 @@ function requestDocsContext(req, example) {
|
|
|
28466
28528
|
`Method: ${req.method}`,
|
|
28467
28529
|
`URL: ${req.url}`
|
|
28468
28530
|
];
|
|
28469
|
-
lines.push(...kvLines("Query params", req.params));
|
|
28470
|
-
lines.push(...kvLines("Headers", req.headers));
|
|
28531
|
+
lines.push(...kvLines("Query params", req.params), ...kvLines("Headers", req.headers));
|
|
28471
28532
|
if (req.auth && req.auth.type !== "none") lines.push(`Auth: ${req.auth.type}`);
|
|
28472
28533
|
if (req.body && req.body.mode !== "none") {
|
|
28473
28534
|
lines.push(`Request body (${req.body.mode}):`);
|
|
@@ -28475,8 +28536,7 @@ function requestDocsContext(req, example) {
|
|
|
28475
28536
|
if (raw) lines.push(raw.slice(0, 2e3));
|
|
28476
28537
|
}
|
|
28477
28538
|
if (example?.response) {
|
|
28478
|
-
lines.push(`Example response (status ${example.response.status})
|
|
28479
|
-
lines.push((example.response.body || "").slice(0, 2e3));
|
|
28539
|
+
lines.push(`Example response (status ${example.response.status}):`, (example.response.body || "").slice(0, 2e3));
|
|
28480
28540
|
}
|
|
28481
28541
|
return lines.join("\n");
|
|
28482
28542
|
}
|
|
@@ -28497,8 +28557,7 @@ function collectionDocsContext(col) {
|
|
|
28497
28557
|
const lines = [`API collection with ${reqs.length} request(s).`];
|
|
28498
28558
|
const byMethod = {};
|
|
28499
28559
|
for (const r of reqs) byMethod[r.method] = (byMethod[r.method] ?? 0) + 1;
|
|
28500
|
-
lines.push("Methods: " + Object.entries(byMethod).map(([m, n]) => `${m}×${n}`).join(", "));
|
|
28501
|
-
lines.push("Endpoints:");
|
|
28560
|
+
lines.push("Methods: " + Object.entries(byMethod).map(([m, n]) => `${m}×${n}`).join(", "), "Endpoints:");
|
|
28502
28561
|
for (const r of reqs.slice(0, 60)) lines.push(` - ${r.method} ${r.url}`);
|
|
28503
28562
|
if (reqs.length > 60) lines.push(` … and ${reqs.length - 60} more`);
|
|
28504
28563
|
return lines.join("\n");
|
|
@@ -28765,7 +28824,7 @@ function textToMeta(text) {
|
|
|
28765
28824
|
}
|
|
28766
28825
|
function GrpcPanel({ request: request2, onChange }) {
|
|
28767
28826
|
const t = useT();
|
|
28768
|
-
const grpc = { ...DEFAULT_GRPC, ...request2.body.grpc
|
|
28827
|
+
const grpc = { ...DEFAULT_GRPC, ...request2.body.grpc };
|
|
28769
28828
|
const grpcCalls = useStore((s) => s.grpcCalls);
|
|
28770
28829
|
const setGrpcStatus = useStore((s) => s.setGrpcStatus);
|
|
28771
28830
|
const addGrpcMessage = useStore((s) => s.addGrpcMessage);
|
|
@@ -29925,7 +29984,7 @@ function XmlNode({ element, depth, onLeaf }) {
|
|
|
29925
29984
|
] });
|
|
29926
29985
|
}
|
|
29927
29986
|
function esc(s) {
|
|
29928
|
-
return s.
|
|
29987
|
+
return s.replaceAll("\\", "\\\\").replaceAll('"', '\\"').replaceAll("\n", "\\n").replaceAll(/\r/g, "");
|
|
29929
29988
|
}
|
|
29930
29989
|
function toLit(v) {
|
|
29931
29990
|
if (v === null) return "null";
|
|
@@ -29962,7 +30021,7 @@ function toJsonPathExpr(path, filterKey, filterValue) {
|
|
|
29962
30021
|
const prefix2 = path.slice(0, arrayIdx).join(".");
|
|
29963
30022
|
const arrayPart = prefix2 ? "$." + prefix2 : "$";
|
|
29964
30023
|
const leafPart = path.slice(arrayIdx + 1).join(".");
|
|
29965
|
-
const filterVal = isNaN(Number(filterValue)) ? `"${filterValue.
|
|
30024
|
+
const filterVal = Number.isNaN(Number(filterValue)) ? `"${filterValue.replaceAll('"', '\\"')}"` : filterValue;
|
|
29966
30025
|
return leafPart ? `${arrayPart}[?(@.${filterKey}==${filterVal})].${leafPart}` : `${arrayPart}[?(@.${filterKey}==${filterVal})]`;
|
|
29967
30026
|
}
|
|
29968
30027
|
function varNameFromPath(path) {
|
|
@@ -30004,7 +30063,7 @@ function makeJsonPathSnippet(path, value2, filterKey, filterValue) {
|
|
|
30004
30063
|
});`;
|
|
30005
30064
|
}
|
|
30006
30065
|
function makeXmlSnippet(selector, value2, mode) {
|
|
30007
|
-
const sel = selector.
|
|
30066
|
+
const sel = selector.replaceAll('"', '\\"');
|
|
30008
30067
|
switch (mode) {
|
|
30009
30068
|
case "equals":
|
|
30010
30069
|
return `sp.test('${selector} equals "${esc(value2)}"', function() {
|
|
@@ -30032,7 +30091,7 @@ function makeJsonPathExtractSnippet(path, filterKey, filterValue, target) {
|
|
|
30032
30091
|
sp.${target}.set("${varName}", String(matches[0] ?? ''));`;
|
|
30033
30092
|
}
|
|
30034
30093
|
function makeXmlExtractSnippet(selector, target) {
|
|
30035
|
-
return `sp.${target}.set("extracted_value", sp.response.xmlText("${selector.
|
|
30094
|
+
return `sp.${target}.set("extracted_value", sp.response.xmlText("${selector.replaceAll('"', '\\"')}") ?? '');`;
|
|
30036
30095
|
}
|
|
30037
30096
|
function AssertMenu({ state, onClose, onConfirm }) {
|
|
30038
30097
|
const t = useT();
|
|
@@ -30331,7 +30390,7 @@ function findPrimaryArray(data) {
|
|
|
30331
30390
|
const { node, path, depth } = queue.shift();
|
|
30332
30391
|
if (depth > 6 || node === null || typeof node !== "object") continue;
|
|
30333
30392
|
if (Array.isArray(node)) {
|
|
30334
|
-
const key = (path.split(".").pop() ?? "").
|
|
30393
|
+
const key = (path.split(".").pop() ?? "").replaceAll(/\[\d+\]/g, "");
|
|
30335
30394
|
const objs = node.filter((x) => x && typeof x === "object" && !Array.isArray(x)).length;
|
|
30336
30395
|
found.push({ path, array: node, pref: PREFERRED.test(key) ? 1 : 0, objs, depth });
|
|
30337
30396
|
} else {
|
|
@@ -30715,7 +30774,7 @@ function HookResultsPanel({ results }) {
|
|
|
30715
30774
|
"div",
|
|
30716
30775
|
{
|
|
30717
30776
|
className: `flex items-center gap-2 py-0.5 ${hasDetail2 ? "cursor-pointer hover:bg-surface-800/20 rounded px-1 -mx-1" : ""}`,
|
|
30718
|
-
onClick: () =>
|
|
30777
|
+
...hasDetail2 ? { role: "button", tabIndex: 0, onClick: () => toggle(r.requestId + i), onKeyDown: onActivateKey(() => toggle(r.requestId + i)) } : {},
|
|
30719
30778
|
children: [
|
|
30720
30779
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `w-1.5 h-1.5 rounded-full shrink-0 ${r.status === "passed" ? "bg-emerald-500" : r.status === "failed" ? "bg-red-500" : "bg-orange-500"}` }),
|
|
30721
30780
|
badge && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `text-[9px] font-bold px-1 py-0.5 rounded uppercase tracking-wide shrink-0 ${badge.cls}`, children: t(badge.label) }),
|
|
@@ -30751,7 +30810,7 @@ function extractPath(url) {
|
|
|
30751
30810
|
try {
|
|
30752
30811
|
return new URL(url).pathname || "/";
|
|
30753
30812
|
} catch {
|
|
30754
|
-
const match =
|
|
30813
|
+
const match = /(?:https?:\/\/[^/]+)?(\/[^?]*)/.exec(url);
|
|
30755
30814
|
return match?.[1] ?? "/";
|
|
30756
30815
|
}
|
|
30757
30816
|
}
|
|
@@ -31221,6 +31280,7 @@ function OverflowMenu({ button, ariaLabel, title, wrapperClassName = "", buttonC
|
|
|
31221
31280
|
ref: menuRef,
|
|
31222
31281
|
id: menuId,
|
|
31223
31282
|
role: "menu",
|
|
31283
|
+
tabIndex: -1,
|
|
31224
31284
|
"aria-label": ariaLabel,
|
|
31225
31285
|
onKeyDown: onMenuKeyDown,
|
|
31226
31286
|
onClick: () => setOpen(false),
|
|
@@ -31254,7 +31314,7 @@ function validateHttpSemantics(res, opts = {}) {
|
|
|
31254
31314
|
const body = hasBody(res);
|
|
31255
31315
|
const contentType = header(res.headers, "content-type");
|
|
31256
31316
|
const contentEncoding = header(res.headers, "content-encoding");
|
|
31257
|
-
const clNum = Number(header(res.headers, "content-length") ?? NaN);
|
|
31317
|
+
const clNum = Number(header(res.headers, "content-length") ?? Number.NaN);
|
|
31258
31318
|
const isBodiless = status in BODILESS || status >= 100 && status < 200;
|
|
31259
31319
|
if (isBodiless) {
|
|
31260
31320
|
const declaresBody = body || Number.isFinite(clNum) && clNum > 0;
|
|
@@ -31443,7 +31503,7 @@ function ResponseViewer() {
|
|
|
31443
31503
|
const setTabScriptTab = useStore((s) => s.setTabScriptTab);
|
|
31444
31504
|
const isSending = activeTab?.isSending ?? false;
|
|
31445
31505
|
const liveStream = useStore((s) => s.liveStream);
|
|
31446
|
-
const streamForTab = liveStream
|
|
31506
|
+
const streamForTab = liveStream?.tabId === activeTabId ? liveStream : null;
|
|
31447
31507
|
const response = activeTab?.lastResponse ?? null;
|
|
31448
31508
|
const scriptResult = activeTab?.lastScriptResult ?? null;
|
|
31449
31509
|
const sentRequest = activeTab?.lastSentRequest ?? null;
|
|
@@ -31670,7 +31730,7 @@ function ResponseViewer() {
|
|
|
31670
31730
|
" KB"
|
|
31671
31731
|
] })
|
|
31672
31732
|
] }),
|
|
31673
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { role: "tablist", "aria-label": t("Response sections"), onKeyDown: onTablistKey, className: "flex items-center gap-0 min-w-0 ml-1", children: [
|
|
31733
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { role: "tablist", tabIndex: -1, "aria-label": t("Response sections"), onKeyDown: onTablistKey, className: "flex items-center gap-0 min-w-0 ml-1", children: [
|
|
31674
31734
|
tabList.map((def) => renderTabButton(def, "inline")),
|
|
31675
31735
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
31676
31736
|
OverflowMenu,
|
|
@@ -31924,7 +31984,7 @@ function ResponseViewer() {
|
|
|
31924
31984
|
type: "item",
|
|
31925
31985
|
label: t('Create variable in ":env"', { env: activeEnvName ?? "" }),
|
|
31926
31986
|
onClick: () => {
|
|
31927
|
-
setVarDialog({ name: headerMenu.key.
|
|
31987
|
+
setVarDialog({ name: headerMenu.key.replaceAll(/[^a-zA-Z0-9]+/g, "_").replaceAll(/^_+|_+$/g, ""), value: headerMenu.value });
|
|
31928
31988
|
setHeaderMenu(null);
|
|
31929
31989
|
}
|
|
31930
31990
|
} : { type: "header", label: t("Select an environment first") }
|
|
@@ -32333,7 +32393,7 @@ function HistoryPanel() {
|
|
|
32333
32393
|
return out;
|
|
32334
32394
|
}, [history, search]);
|
|
32335
32395
|
async function downloadHar() {
|
|
32336
|
-
const stamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 19).
|
|
32396
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().slice(0, 19).replaceAll(/[:T]/g, "-");
|
|
32337
32397
|
await electron$l.saveResults(historyToHar(history), `api-spector-history-${stamp}.har`);
|
|
32338
32398
|
}
|
|
32339
32399
|
function open2(entry) {
|
|
@@ -32537,7 +32597,7 @@ function WelcomeScreen() {
|
|
|
32537
32597
|
)
|
|
32538
32598
|
] }),
|
|
32539
32599
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-surface-400 text-sm max-w-sm", children: t("Local-first API testing with Robot Framework & Playwright code generation. Secrets stay on your machine.") }),
|
|
32540
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] mt-3", style: { color: "var(--text-muted)" }, children: t("version :version", { version: "0.6.
|
|
32600
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] mt-3", style: { color: "var(--text-muted)" }, children: t("version :version", { version: "0.6.5" }) })
|
|
32541
32601
|
] }),
|
|
32542
32602
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3 w-64", children: [
|
|
32543
32603
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -32807,8 +32867,7 @@ function EnvironmentEditor({ onClose }) {
|
|
|
32807
32867
|
}
|
|
32808
32868
|
function handleDelete(id) {
|
|
32809
32869
|
deleteEnvironment(id);
|
|
32810
|
-
|
|
32811
|
-
setSelectedId(remaining[0] ?? "");
|
|
32870
|
+
setSelectedId(Object.keys(environments).find((k) => k !== id) ?? "");
|
|
32812
32871
|
}
|
|
32813
32872
|
function handleDuplicate(id) {
|
|
32814
32873
|
duplicateEnvironment(id);
|
|
@@ -33260,7 +33319,7 @@ function EnvironmentBar({ inline = false }) {
|
|
|
33260
33319
|
style: { color: "var(--text-primary)" },
|
|
33261
33320
|
children: [
|
|
33262
33321
|
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: t("No env") }),
|
|
33263
|
-
envList.map(({ data: env2 }) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: env2.id, children:
|
|
33322
|
+
envList.map(({ data: env2 }) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: env2.id, children: env2.name.toLowerCase() === defaultEnvName?.toLowerCase() ? t(":name (default)", { name: env2.name }) : env2.name }, env2.id))
|
|
33264
33323
|
]
|
|
33265
33324
|
}
|
|
33266
33325
|
),
|
|
@@ -33542,7 +33601,7 @@ function WorkspaceSettingsModal({ onClose }) {
|
|
|
33542
33601
|
}
|
|
33543
33602
|
async function save() {
|
|
33544
33603
|
const settings = {
|
|
33545
|
-
...workspace?.settings
|
|
33604
|
+
...workspace?.settings
|
|
33546
33605
|
};
|
|
33547
33606
|
if (proxyUrl.trim()) {
|
|
33548
33607
|
settings.proxy = { url: proxyUrl.trim() };
|
|
@@ -33661,6 +33720,7 @@ function WorkspaceSettingsModal({ onClose }) {
|
|
|
33661
33720
|
"input",
|
|
33662
33721
|
{
|
|
33663
33722
|
type: "checkbox",
|
|
33723
|
+
"aria-label": t("Persist request history"),
|
|
33664
33724
|
checked: persistHistory,
|
|
33665
33725
|
onChange: (e) => setPersistHistory(e.target.checked),
|
|
33666
33726
|
className: "mt-0.5"
|
|
@@ -33796,6 +33856,7 @@ function WorkspaceSettingsModal({ onClose }) {
|
|
|
33796
33856
|
"input",
|
|
33797
33857
|
{
|
|
33798
33858
|
type: "checkbox",
|
|
33859
|
+
"aria-label": t("Enable API Spector Cloud"),
|
|
33799
33860
|
checked: cloudEnabled2,
|
|
33800
33861
|
onChange: (e) => setCloudEnabled(e.target.checked),
|
|
33801
33862
|
className: "mt-0.5 accent-blue-500"
|
|
@@ -34573,12 +34634,12 @@ function parseCurl(command) {
|
|
|
34573
34634
|
} else if (hasData) {
|
|
34574
34635
|
const data = dataParts.join("&");
|
|
34575
34636
|
const ct = headers.find((h) => h.key.toLowerCase() === "content-type")?.value;
|
|
34576
|
-
if (ct
|
|
34637
|
+
if (ct?.includes("json") || looksJson(data)) body = { mode: "json", json: data };
|
|
34577
34638
|
else body = { mode: "raw", raw: data, rawContentType: ct ?? "application/x-www-form-urlencoded" };
|
|
34578
34639
|
}
|
|
34579
34640
|
let name;
|
|
34580
34641
|
try {
|
|
34581
|
-
const u = new URL(url.
|
|
34642
|
+
const u = new URL(url.replaceAll(/\{\{[^}]+\}\}/g, "x"));
|
|
34582
34643
|
name = `${resolvedMethod} ${u.pathname === "/" ? u.hostname : u.pathname}`;
|
|
34583
34644
|
} catch {
|
|
34584
34645
|
const cleaned = url.replace(/^[a-z]+:\/\//i, "").replace(/\?.*$/, "");
|
|
@@ -35427,7 +35488,7 @@ function Toolbar({ onOpenDocs: _onOpenDocs }) {
|
|
|
35427
35488
|
] });
|
|
35428
35489
|
}
|
|
35429
35490
|
function escapeHtml(s) {
|
|
35430
|
-
return String(s ?? "").
|
|
35491
|
+
return String(s ?? "").replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
35431
35492
|
}
|
|
35432
35493
|
function buildJsonReport(results, summary, meta = {}) {
|
|
35433
35494
|
return JSON.stringify({
|
|
@@ -35743,7 +35804,7 @@ function buildJUnitReport(results, summary, meta = {}) {
|
|
|
35743
35804
|
const label = r.iterationLabel ? ` #${r.iterationLabel}` : "";
|
|
35744
35805
|
const hookPrefix = r.isHook && r.hookType ? `[${HOOK_JUNIT_LABELS[r.hookType] ?? "Hook"}] ` : "";
|
|
35745
35806
|
const name = esc2(hookPrefix + r.name + label);
|
|
35746
|
-
const classname = esc2([r.collection ?? meta.collection, ...r.scopePath ?? []].filter(Boolean).map((s) => String(s).
|
|
35807
|
+
const classname = esc2([r.collection ?? meta.collection, ...r.scopePath ?? []].filter(Boolean).map((s) => String(s).replaceAll(".", "_")).join(".") || "API Tests");
|
|
35747
35808
|
const timeSec = ((r.durationMs ?? 0) / 1e3).toFixed(3);
|
|
35748
35809
|
const failures = [];
|
|
35749
35810
|
if (r.status === "error") {
|
|
@@ -36328,13 +36389,13 @@ function RunnerModal() {
|
|
|
36328
36389
|
}
|
|
36329
36390
|
);
|
|
36330
36391
|
}
|
|
36331
|
-
const HTTP_METHODS$2 = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
|
|
36392
|
+
const HTTP_METHODS$2 = /* @__PURE__ */ new Set(["get", "put", "post", "delete", "options", "head", "patch", "trace"]);
|
|
36332
36393
|
function normalizePath(url) {
|
|
36333
36394
|
let u = (url || "").trim();
|
|
36334
36395
|
u = u.split("#")[0].split("?")[0];
|
|
36335
|
-
u = u.
|
|
36396
|
+
u = u.replaceAll(/\{\{[^}]*\}\}/g, "");
|
|
36336
36397
|
u = u.replace(/^[a-z0-9+.-]+:\/\/[^/]*/i, "");
|
|
36337
|
-
u = u.
|
|
36398
|
+
u = u.replaceAll(/\/{2,}/g, "/");
|
|
36338
36399
|
if (!u.startsWith("/")) u = "/" + u;
|
|
36339
36400
|
u = u.replace(/\/+$/, "");
|
|
36340
36401
|
return u === "" ? "/" : u;
|
|
@@ -36354,7 +36415,7 @@ function pathMatches(requestUrl, template) {
|
|
|
36354
36415
|
}
|
|
36355
36416
|
function resolveRef$2(spec2, ref) {
|
|
36356
36417
|
const parts = ref.replace(/^#\//, "").split("/");
|
|
36357
|
-
return parts.reduce((o, k) => o?.[decodeURIComponent(k.
|
|
36418
|
+
return parts.reduce((o, k) => o?.[decodeURIComponent(k.replaceAll("~1", "/").replaceAll("~0", "~"))], spec2);
|
|
36358
36419
|
}
|
|
36359
36420
|
function deref$2(spec2, node, depth = 0, seen2 = /* @__PURE__ */ new Set()) {
|
|
36360
36421
|
if (!node || typeof node !== "object" || depth > 8) return node;
|
|
@@ -36375,8 +36436,7 @@ function flattenSchemaPaths(schema, prefix2 = "", depth = 0) {
|
|
|
36375
36436
|
if (type === "object" || schema.properties) {
|
|
36376
36437
|
for (const [name, sub] of Object.entries(schema.properties ?? {})) {
|
|
36377
36438
|
const path = prefix2 ? `${prefix2}.${name}` : name;
|
|
36378
|
-
out.push(path);
|
|
36379
|
-
out.push(...flattenSchemaPaths(sub, path, depth + 1));
|
|
36439
|
+
out.push(path, ...flattenSchemaPaths(sub, path, depth + 1));
|
|
36380
36440
|
}
|
|
36381
36441
|
} else if (type === "array" && schema.items) {
|
|
36382
36442
|
out.push(...flattenSchemaPaths(schema.items, `${prefix2}[]`, depth + 1));
|
|
@@ -36391,14 +36451,13 @@ function flattenValuePaths(value2, prefix2 = "", depth = 0) {
|
|
|
36391
36451
|
} else {
|
|
36392
36452
|
for (const [k, v] of Object.entries(value2)) {
|
|
36393
36453
|
const path = prefix2 ? `${prefix2}.${k}` : k;
|
|
36394
|
-
out.push(path);
|
|
36395
|
-
out.push(...flattenValuePaths(v, path, depth + 1));
|
|
36454
|
+
out.push(path, ...flattenValuePaths(v, path, depth + 1));
|
|
36396
36455
|
}
|
|
36397
36456
|
}
|
|
36398
36457
|
return [...new Set(out)];
|
|
36399
36458
|
}
|
|
36400
36459
|
function successResponseSchema$1(spec2, responses) {
|
|
36401
|
-
const code = Object.keys(responses ?? {}).filter((c) => /^2\d\d$/.test(c)).sort()[0];
|
|
36460
|
+
const code = Object.keys(responses ?? {}).filter((c) => /^2\d\d$/.test(c)).sort((a, b) => a.localeCompare(b))[0];
|
|
36402
36461
|
if (!code) return void 0;
|
|
36403
36462
|
const schema = responses[code]?.content?.["application/json"]?.schema ?? responses[code]?.content?.["application/json;charset=utf-8"]?.schema;
|
|
36404
36463
|
return schema ? deref$2(spec2, schema) : void 0;
|
|
@@ -36409,7 +36468,7 @@ function enumerateOperations(spec2) {
|
|
|
36409
36468
|
for (const [path, item] of Object.entries(doc.paths ?? {})) {
|
|
36410
36469
|
if (!item || typeof item !== "object") continue;
|
|
36411
36470
|
for (const [method, op] of Object.entries(item)) {
|
|
36412
|
-
if (!HTTP_METHODS$2.
|
|
36471
|
+
if (!HTTP_METHODS$2.has(method.toLowerCase())) continue;
|
|
36413
36472
|
if (!op || typeof op !== "object") continue;
|
|
36414
36473
|
const declaredStatuses = Object.keys(op.responses ?? {}).filter((c) => /^\d{3}$/.test(c));
|
|
36415
36474
|
ops.push({ method: method.toUpperCase(), path, operationId: op.operationId, declaredStatuses, responses: op.responses });
|
|
@@ -36470,10 +36529,10 @@ function computeCoverage(spec2, requests, observations = []) {
|
|
|
36470
36529
|
operations: operations2
|
|
36471
36530
|
};
|
|
36472
36531
|
}
|
|
36473
|
-
const HTTP_METHODS$1 = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
|
|
36532
|
+
const HTTP_METHODS$1 = /* @__PURE__ */ new Set(["get", "put", "post", "delete", "options", "head", "patch", "trace"]);
|
|
36474
36533
|
function resolveRef$1(spec2, ref) {
|
|
36475
36534
|
const parts = ref.replace(/^#\//, "").split("/");
|
|
36476
|
-
return parts.reduce((o, k) => o?.[decodeURIComponent(k.
|
|
36535
|
+
return parts.reduce((o, k) => o?.[decodeURIComponent(k.replaceAll("~1", "/").replaceAll("~0", "~"))], spec2);
|
|
36477
36536
|
}
|
|
36478
36537
|
function deref$1(spec2, node, depth = 0, seen2 = /* @__PURE__ */ new Set()) {
|
|
36479
36538
|
if (!node || typeof node !== "object" || depth > 8) return node;
|
|
@@ -36646,7 +36705,7 @@ function generateTests(spec2, options = {}) {
|
|
|
36646
36705
|
for (const [path, item] of Object.entries(doc.paths ?? {})) {
|
|
36647
36706
|
if (!item || typeof item !== "object") continue;
|
|
36648
36707
|
for (const [method, op] of Object.entries(item)) {
|
|
36649
|
-
if (!HTTP_METHODS$1.
|
|
36708
|
+
if (!HTTP_METHODS$1.has(method.toLowerCase())) continue;
|
|
36650
36709
|
if (!op || typeof op !== "object") continue;
|
|
36651
36710
|
if (opts.only.size && !opts.only.has(`${method.toUpperCase()} ${path}`)) continue;
|
|
36652
36711
|
out.push(...generateForOperation(doc, method.toUpperCase(), path, item, op, opts));
|
|
@@ -36882,10 +36941,10 @@ function CoverageModal() {
|
|
|
36882
36941
|
}
|
|
36883
36942
|
);
|
|
36884
36943
|
}
|
|
36885
|
-
const HTTP_METHODS = ["get", "put", "post", "delete", "options", "head", "patch", "trace"];
|
|
36944
|
+
const HTTP_METHODS = /* @__PURE__ */ new Set(["get", "put", "post", "delete", "options", "head", "patch", "trace"]);
|
|
36886
36945
|
function resolveRef(spec2, ref) {
|
|
36887
36946
|
const parts = ref.replace(/^#\//, "").split("/");
|
|
36888
|
-
return parts.reduce((o, k) => o?.[decodeURIComponent(k.
|
|
36947
|
+
return parts.reduce((o, k) => o?.[decodeURIComponent(k.replaceAll("~1", "/").replaceAll("~0", "~"))], spec2);
|
|
36889
36948
|
}
|
|
36890
36949
|
function deref(spec2, node, depth = 0, seen2 = /* @__PURE__ */ new Set()) {
|
|
36891
36950
|
if (!node || typeof node !== "object" || depth > 8) return node;
|
|
@@ -36926,7 +36985,7 @@ function requestSchema(spec2, op) {
|
|
|
36926
36985
|
}
|
|
36927
36986
|
function successResponseSchema(spec2, op) {
|
|
36928
36987
|
const responses = op?.responses ?? {};
|
|
36929
|
-
const code = Object.keys(responses).filter((c) => /^2\d\d$/.test(c)).sort()[0];
|
|
36988
|
+
const code = Object.keys(responses).filter((c) => /^2\d\d$/.test(c)).sort((a, b) => a.localeCompare(b))[0];
|
|
36930
36989
|
return code ? deref(spec2, responses[code])?.content?.["application/json"]?.schema : void 0;
|
|
36931
36990
|
}
|
|
36932
36991
|
function paramRequired(spec2, pathItem, op) {
|
|
@@ -36940,7 +36999,7 @@ function operations(spec2) {
|
|
|
36940
36999
|
for (const [path, item] of Object.entries(spec2?.paths ?? {})) {
|
|
36941
37000
|
if (!item || typeof item !== "object") continue;
|
|
36942
37001
|
for (const [method, op] of Object.entries(item)) {
|
|
36943
|
-
if (!HTTP_METHODS.
|
|
37002
|
+
if (!HTTP_METHODS.has(method.toLowerCase())) continue;
|
|
36944
37003
|
map.set(`${method.toUpperCase()} ${path}`, { method: method.toUpperCase(), path, pathItem: item, op });
|
|
36945
37004
|
}
|
|
36946
37005
|
}
|
|
@@ -37144,7 +37203,7 @@ function CompareModal() {
|
|
|
37144
37203
|
);
|
|
37145
37204
|
}
|
|
37146
37205
|
function toCSV(ds) {
|
|
37147
|
-
const escape = (s) => s.includes(",") || s.includes('"') || s.includes("\n") ? `"${s.
|
|
37206
|
+
const escape = (s) => s.includes(",") || s.includes('"') || s.includes("\n") ? `"${s.replaceAll('"', '""')}"` : s;
|
|
37148
37207
|
return [ds.columns, ...ds.rows].map((row) => row.map(escape).join(",")).join("\n");
|
|
37149
37208
|
}
|
|
37150
37209
|
function parseCSV(text) {
|
|
@@ -37210,7 +37269,7 @@ function DataSetEditor({ ds, onChange, exportName, scopeLabel = "collection" })
|
|
|
37210
37269
|
const url = URL.createObjectURL(blob);
|
|
37211
37270
|
const a = document.createElement("a");
|
|
37212
37271
|
a.href = url;
|
|
37213
|
-
a.download = `${exportName.
|
|
37272
|
+
a.download = `${exportName.replaceAll(/\s+/g, "_")}_data.csv`;
|
|
37214
37273
|
a.click();
|
|
37215
37274
|
URL.revokeObjectURL(url);
|
|
37216
37275
|
}
|
|
@@ -37368,7 +37427,7 @@ function CollectionPanel() {
|
|
|
37368
37427
|
] }),
|
|
37369
37428
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex border-b border-surface-800 px-6 flex-shrink-0", children: [
|
|
37370
37429
|
{ id: "documentation", label: "Documentation", badge: col.description?.trim() ? 1 : 0 },
|
|
37371
|
-
{ id: "data", label: "Data", badge: iterCount
|
|
37430
|
+
{ id: "data", label: "Data", badge: Math.max(iterCount, 0) },
|
|
37372
37431
|
{ id: "variables", label: "Variables", badge: Object.keys(col.collectionVariables ?? {}).length }
|
|
37373
37432
|
].map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
37374
37433
|
"button",
|
|
@@ -37454,7 +37513,7 @@ function FolderPanel() {
|
|
|
37454
37513
|
] }),
|
|
37455
37514
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex border-b border-surface-800 px-6 flex-shrink-0", children: [
|
|
37456
37515
|
{ id: "documentation", label: "Documentation", badge: folder2.description?.trim() ? 1 : 0 },
|
|
37457
|
-
{ id: "data", label: "Data", badge: iterCount
|
|
37516
|
+
{ id: "data", label: "Data", badge: Math.max(iterCount, 0) },
|
|
37458
37517
|
{ id: "variables", label: "Variables", badge: varRows.length }
|
|
37459
37518
|
].map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
37460
37519
|
"button",
|
|
@@ -37622,7 +37681,7 @@ function MockPanel() {
|
|
|
37622
37681
|
await electron$9.saveMock(relPath, mock);
|
|
37623
37682
|
const ws = useStore.getState().workspace;
|
|
37624
37683
|
if (ws) {
|
|
37625
|
-
|
|
37684
|
+
ws.mocks ??= [];
|
|
37626
37685
|
ws.mocks.push(relPath);
|
|
37627
37686
|
await electron$9.saveWorkspace(ws);
|
|
37628
37687
|
}
|
|
@@ -39117,7 +39176,7 @@ function ViolationRow({ v }) {
|
|
|
39117
39176
|
const t = useT();
|
|
39118
39177
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-1 px-4 py-2.5 border-l-2 border-red-600 bg-red-950/20 rounded-r", children: [
|
|
39119
39178
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
39120
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] font-mono font-bold text-red-400 uppercase tracking-wide", children: v.type.
|
|
39179
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] font-mono font-bold text-red-400 uppercase tracking-wide", children: v.type.replaceAll("_", " ") }),
|
|
39121
39180
|
v.path && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] font-mono text-surface-500 bg-surface-800 px-1.5 py-0.5 rounded", children: v.path })
|
|
39122
39181
|
] }),
|
|
39123
39182
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-200", children: v.message }),
|
|
@@ -39306,7 +39365,7 @@ function designContractToMock(cc, port = 4100) {
|
|
|
39306
39365
|
id: it2.id || `route-${i}`,
|
|
39307
39366
|
// Pact path templates use {id}; the mock router uses :id.
|
|
39308
39367
|
method: (it2.request.method || "GET").toUpperCase(),
|
|
39309
|
-
path: (it2.request.path || "/").
|
|
39368
|
+
path: (it2.request.path || "/").replaceAll(/\{([^}]+)\}/g, ":$1"),
|
|
39310
39369
|
statusCode: it2.response.status,
|
|
39311
39370
|
headers: { "Content-Type": "application/json", ...kvToHeaders(it2.response.headers) },
|
|
39312
39371
|
body: it2.response.body?.trim() ? it2.response.body : "",
|
|
@@ -39394,8 +39453,8 @@ function ContractDesignerModal({ seed, onClose }) {
|
|
|
39394
39453
|
...base,
|
|
39395
39454
|
...seed,
|
|
39396
39455
|
id: uid(),
|
|
39397
|
-
request: { ...base.request, ...seed.request
|
|
39398
|
-
response: { ...base.response, ...seed.response
|
|
39456
|
+
request: { ...base.request, ...seed.request },
|
|
39457
|
+
response: { ...base.response, ...seed.response }
|
|
39399
39458
|
};
|
|
39400
39459
|
const contract = { ...newContract(), interactions: [interaction] };
|
|
39401
39460
|
setSelectedId(contract.id);
|
|
@@ -39995,7 +40054,7 @@ function ConflictEditor({ path, onClose, onResolved }) {
|
|
|
39995
40054
|
}, [path]);
|
|
39996
40055
|
const conflictCount = reactExports.useMemo(() => parts?.filter((p) => p.type === "conflict").length ?? 0, [parts]);
|
|
39997
40056
|
const unresolved = reactExports.useMemo(() => parts?.filter((p) => p.type === "conflict" && !p.choice).length ?? 0, [parts]);
|
|
39998
|
-
const content = manual
|
|
40057
|
+
const content = manual ?? (parts ? assemble(parts) : "");
|
|
39999
40058
|
const stillHasMarkers = /^(<{7}|={7}|>{7})/m.test(content);
|
|
40000
40059
|
function choose(idx, choice) {
|
|
40001
40060
|
setParts((prev) => prev?.map((p, i) => i === idx && p.type === "conflict" ? { ...p, choice } : p) ?? prev);
|
|
@@ -40353,7 +40412,10 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
40353
40412
|
"div",
|
|
40354
40413
|
{
|
|
40355
40414
|
className: `flex items-center gap-2 px-3 py-1 hover:bg-surface-800/50 cursor-pointer group text-xs ${diffFile === f.path && diffStaged ? "bg-surface-800" : ""}`,
|
|
40415
|
+
role: "button",
|
|
40416
|
+
tabIndex: 0,
|
|
40356
40417
|
onClick: () => showDiff(f, true),
|
|
40418
|
+
onKeyDown: onActivateKey(() => showDiff(f, true)),
|
|
40357
40419
|
children: [
|
|
40358
40420
|
/* @__PURE__ */ jsxRuntimeExports.jsx(StatusBadge, { status: f.status }),
|
|
40359
40421
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 truncate text-surface-200", children: f.path }),
|
|
@@ -40390,7 +40452,10 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
40390
40452
|
"div",
|
|
40391
40453
|
{
|
|
40392
40454
|
className: `flex items-center gap-2 px-3 py-1 hover:bg-surface-800/50 cursor-pointer group text-xs ${diffFile === f.path && !diffStaged ? "bg-surface-800" : ""}`,
|
|
40455
|
+
role: "button",
|
|
40456
|
+
tabIndex: 0,
|
|
40393
40457
|
onClick: () => showDiff(f, false),
|
|
40458
|
+
onKeyDown: onActivateKey(() => showDiff(f, false)),
|
|
40394
40459
|
children: [
|
|
40395
40460
|
/* @__PURE__ */ jsxRuntimeExports.jsx(StatusBadge, { status: f.status }),
|
|
40396
40461
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 truncate text-surface-200", children: f.path }),
|
|
@@ -40417,7 +40482,10 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
40417
40482
|
"div",
|
|
40418
40483
|
{
|
|
40419
40484
|
className: `flex items-center gap-2 px-3 py-1 hover:bg-surface-800/50 cursor-pointer group text-xs ${diffFile === path && !diffStaged ? "bg-surface-800" : ""}`,
|
|
40485
|
+
role: "button",
|
|
40486
|
+
tabIndex: 0,
|
|
40420
40487
|
onClick: () => showDiff({ path, status: "modified" }, false),
|
|
40488
|
+
onKeyDown: onActivateKey(() => showDiff({ path, status: "modified" }, false)),
|
|
40421
40489
|
children: [
|
|
40422
40490
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-[11px] font-bold w-4 shrink-0 text-red-400", children: "!" }),
|
|
40423
40491
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 truncate text-red-300", children: path }),
|
|
@@ -41145,10 +41213,16 @@ function CommandPalette() {
|
|
|
41145
41213
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-h-80 overflow-y-auto", children: filtered2.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-4 py-6 text-center text-sm text-surface-600", children: t('No requests match ":query"', { query }) }) : filtered2.map((item, idx) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
41146
41214
|
"div",
|
|
41147
41215
|
{
|
|
41216
|
+
role: "button",
|
|
41217
|
+
tabIndex: 0,
|
|
41148
41218
|
onClick: () => {
|
|
41149
41219
|
openInTab(item.requestId, item.collectionId);
|
|
41150
41220
|
setOpen(false);
|
|
41151
41221
|
},
|
|
41222
|
+
onKeyDown: onActivateKey(() => {
|
|
41223
|
+
openInTab(item.requestId, item.collectionId);
|
|
41224
|
+
setOpen(false);
|
|
41225
|
+
}),
|
|
41152
41226
|
onMouseEnter: () => setActiveIdx(idx),
|
|
41153
41227
|
className: `flex items-center gap-3 px-4 py-2.5 cursor-pointer transition-colors ${idx === activeIdx ? "bg-surface-800" : "hover:bg-surface-800/50"}`,
|
|
41154
41228
|
children: [
|
|
@@ -41307,7 +41381,10 @@ const TabRow = React$2.memo(function TabRow2({
|
|
|
41307
41381
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
41308
41382
|
"div",
|
|
41309
41383
|
{
|
|
41384
|
+
role: "button",
|
|
41385
|
+
tabIndex: 0,
|
|
41310
41386
|
onClick: () => onActivate(tabId),
|
|
41387
|
+
onKeyDown: onActivateKey(() => onActivate(tabId)),
|
|
41311
41388
|
onContextMenu: (e) => {
|
|
41312
41389
|
e.preventDefault();
|
|
41313
41390
|
onContextMenu(tabId, e.clientX, e.clientY);
|
|
@@ -41513,7 +41590,7 @@ function App() {
|
|
|
41513
41590
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "#6aa3c8" }, children: "Spector" }),
|
|
41514
41591
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-[10px] font-normal opacity-50", children: [
|
|
41515
41592
|
"v",
|
|
41516
|
-
"0.6.
|
|
41593
|
+
"0.6.5"
|
|
41517
41594
|
] }),
|
|
41518
41595
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mx-2 opacity-30", children: "·" }),
|
|
41519
41596
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -41612,13 +41689,27 @@ function App() {
|
|
|
41612
41689
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41613
41690
|
"div",
|
|
41614
41691
|
{
|
|
41615
|
-
|
|
41692
|
+
role: "separator",
|
|
41693
|
+
"aria-orientation": "vertical",
|
|
41694
|
+
"aria-label": "Resize sidebar",
|
|
41695
|
+
"aria-valuemin": 160,
|
|
41696
|
+
"aria-valuemax": 520,
|
|
41697
|
+
"aria-valuenow": sidebarWidth,
|
|
41698
|
+
tabIndex: 0,
|
|
41699
|
+
className: "flex-shrink-0 w-1 cursor-col-resize border-r border-surface-800 hover:border-blue-500 focus:border-blue-500 focus:outline-none transition-colors",
|
|
41616
41700
|
onMouseDown: (e) => {
|
|
41617
41701
|
dragging.current = "sidebar";
|
|
41618
41702
|
dragStart.current = { x: e.clientX, w: sidebarWidth };
|
|
41619
41703
|
document.body.style.cursor = "col-resize";
|
|
41620
41704
|
document.body.style.userSelect = "none";
|
|
41621
41705
|
e.preventDefault();
|
|
41706
|
+
},
|
|
41707
|
+
onKeyDown: (e) => {
|
|
41708
|
+
if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
|
|
41709
|
+
e.preventDefault();
|
|
41710
|
+
const step = e.key === "ArrowLeft" ? -16 : 16;
|
|
41711
|
+
setSidebarWidth((w) => Math.max(160, Math.min(520, w + step)));
|
|
41712
|
+
}
|
|
41622
41713
|
}
|
|
41623
41714
|
}
|
|
41624
41715
|
)
|
|
@@ -41664,8 +41755,14 @@ function App() {
|
|
|
41664
41755
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41665
41756
|
"div",
|
|
41666
41757
|
{
|
|
41758
|
+
role: "button",
|
|
41759
|
+
tabIndex: -1,
|
|
41760
|
+
"aria-label": t("Close menu"),
|
|
41667
41761
|
className: "fixed inset-0 z-40",
|
|
41668
41762
|
onClick: () => setTabContextMenu(null),
|
|
41763
|
+
onKeyDown: (e) => {
|
|
41764
|
+
if (e.key === "Escape") setTabContextMenu(null);
|
|
41765
|
+
},
|
|
41669
41766
|
onContextMenu: (e) => {
|
|
41670
41767
|
e.preventDefault();
|
|
41671
41768
|
setTabContextMenu(null);
|
|
@@ -41741,7 +41838,7 @@ function App() {
|
|
|
41741
41838
|
await electron.saveMock(relPath, newRoutes);
|
|
41742
41839
|
const ws = useStore.getState().workspace;
|
|
41743
41840
|
if (ws) {
|
|
41744
|
-
|
|
41841
|
+
ws.mocks ??= [];
|
|
41745
41842
|
ws.mocks.push(relPath);
|
|
41746
41843
|
await electron.saveWorkspace(ws);
|
|
41747
41844
|
}
|
|
@@ -41763,7 +41860,13 @@ function App() {
|
|
|
41763
41860
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41764
41861
|
"div",
|
|
41765
41862
|
{
|
|
41766
|
-
|
|
41863
|
+
role: "separator",
|
|
41864
|
+
"aria-orientation": "vertical",
|
|
41865
|
+
"aria-label": "Resize request pane",
|
|
41866
|
+
"aria-valuemin": 200,
|
|
41867
|
+
"aria-valuenow": requestPaneWidth ?? leftPaneRef.current?.offsetWidth ?? 400,
|
|
41868
|
+
tabIndex: 0,
|
|
41869
|
+
className: "flex-shrink-0 w-1 relative cursor-col-resize border-x border-surface-800 hover:border-blue-500 focus:border-blue-500 focus:outline-none transition-colors group",
|
|
41767
41870
|
onMouseDown: (e) => {
|
|
41768
41871
|
dragging.current = "request";
|
|
41769
41872
|
dragStart.current = { x: e.clientX, w: leftPaneRef.current?.offsetWidth ?? requestPaneWidth ?? 400 };
|
|
@@ -41771,6 +41874,14 @@ function App() {
|
|
|
41771
41874
|
document.body.style.userSelect = "none";
|
|
41772
41875
|
e.preventDefault();
|
|
41773
41876
|
},
|
|
41877
|
+
onKeyDown: (e) => {
|
|
41878
|
+
if (e.key === "ArrowLeft" || e.key === "ArrowRight") {
|
|
41879
|
+
e.preventDefault();
|
|
41880
|
+
const step = e.key === "ArrowLeft" ? -16 : 16;
|
|
41881
|
+
const cur = leftPaneRef.current?.offsetWidth ?? requestPaneWidth ?? 400;
|
|
41882
|
+
setRequestPaneWidth(Math.max(200, Math.min(window.innerWidth - 300, cur + step)));
|
|
41883
|
+
}
|
|
41884
|
+
},
|
|
41774
41885
|
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
41775
41886
|
"button",
|
|
41776
41887
|
{
|
|
@@ -41810,7 +41921,7 @@ if (savedTheme === "light") {
|
|
|
41810
41921
|
}
|
|
41811
41922
|
}
|
|
41812
41923
|
const savedZoom = localStorage.getItem(STORAGE_KEYS.zoom);
|
|
41813
|
-
if (savedZoom) window.electron.setZoomFactor(parseFloat(savedZoom));
|
|
41924
|
+
if (savedZoom) window.electron.setZoomFactor(Number.parseFloat(savedZoom));
|
|
41814
41925
|
ReactDOM.createRoot(document.getElementById("root")).render(
|
|
41815
41926
|
/* @__PURE__ */ jsxRuntimeExports.jsx(React$2.StrictMode, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(I18nProvider, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBoundary, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(App, {}) }) }) })
|
|
41816
41927
|
);
|