@testsmith/api-spector 0.2.2 → 0.2.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/bin/cli.js +42 -33
- package/out/main/chunks/auth-builder-B7-LgcGr.js +373 -0
- package/out/main/chunks/import-C9qdkBCH.js +154 -0
- package/out/main/chunks/ipc-validate-CscN4HfG.js +94 -0
- package/out/main/chunks/{mock-server-Cx-xG4pJ.js → mock-server-DmdvwCgj.js} +4 -0
- package/out/main/chunks/{request-collection-Dx0ZqB54.js → request-collection-DIsjTggj.js} +25 -349
- package/out/main/chunks/snapshots-C7YbGHM7.js +588 -0
- package/out/main/chunks/soap-handler-Cpj-JwyA.js +326 -0
- package/out/main/contract.js +210 -0
- package/out/main/index.js +398 -592
- package/out/main/mock.js +1 -1
- package/out/main/runner.js +20 -18
- package/out/main/wsdl.js +174 -0
- package/out/preload/index.js +12 -0
- package/out/renderer/assets/{index-C_vjoxxA.js → index-BC1srylp.js} +1374 -647
- package/out/renderer/assets/index-DfkLUeA1.css +2 -0
- package/out/renderer/index.html +2 -2
- package/package.json +6 -1
- package/out/renderer/assets/index-DVaubmCJ.css +0 -2
|
@@ -13317,6 +13317,112 @@ function envRelPath(name2, id2) {
|
|
|
13317
13317
|
function safeName(name2) {
|
|
13318
13318
|
return name2.trim().toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-_]/g, "").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
13319
13319
|
}
|
|
13320
|
+
const WS_MESSAGE_CAP = 1e3;
|
|
13321
|
+
const createWsSlice = (set2) => ({
|
|
13322
|
+
wsConnections: {},
|
|
13323
|
+
setWsStatus: (requestId, status, error2) => set2((s) => {
|
|
13324
|
+
if (!s.wsConnections[requestId]) {
|
|
13325
|
+
s.wsConnections[requestId] = { status, messages: [], error: error2 };
|
|
13326
|
+
} else {
|
|
13327
|
+
s.wsConnections[requestId].status = status;
|
|
13328
|
+
s.wsConnections[requestId].error = error2;
|
|
13329
|
+
}
|
|
13330
|
+
}),
|
|
13331
|
+
addWsMessage: (requestId, message) => set2((s) => {
|
|
13332
|
+
const conn = s.wsConnections[requestId];
|
|
13333
|
+
if (!conn) {
|
|
13334
|
+
s.wsConnections[requestId] = { status: "connected", messages: [message] };
|
|
13335
|
+
return;
|
|
13336
|
+
}
|
|
13337
|
+
conn.messages.push(message);
|
|
13338
|
+
if (conn.messages.length > WS_MESSAGE_CAP) {
|
|
13339
|
+
conn.messages.splice(0, conn.messages.length - WS_MESSAGE_CAP);
|
|
13340
|
+
}
|
|
13341
|
+
}),
|
|
13342
|
+
clearWsMessages: (requestId) => set2((s) => {
|
|
13343
|
+
if (s.wsConnections[requestId]) s.wsConnections[requestId].messages = [];
|
|
13344
|
+
})
|
|
13345
|
+
});
|
|
13346
|
+
const HISTORY_CAP = 200;
|
|
13347
|
+
const createHistorySlice = (set2) => ({
|
|
13348
|
+
history: [],
|
|
13349
|
+
addHistoryEntry: (entry) => set2((s) => {
|
|
13350
|
+
s.history.unshift(entry);
|
|
13351
|
+
if (s.history.length > HISTORY_CAP) s.history.length = HISTORY_CAP;
|
|
13352
|
+
}),
|
|
13353
|
+
clearHistory: () => set2((s) => {
|
|
13354
|
+
s.history = [];
|
|
13355
|
+
})
|
|
13356
|
+
});
|
|
13357
|
+
const createRunnerSlice = (set2) => ({
|
|
13358
|
+
runnerModal: { open: false, collectionId: null, folderId: null, filterTags: [] },
|
|
13359
|
+
runnerResults: [],
|
|
13360
|
+
runnerRunning: false,
|
|
13361
|
+
openRunner: (collectionId, folderId = null, filterTags = []) => set2((s) => {
|
|
13362
|
+
s.runnerModal = { open: true, collectionId, folderId, filterTags };
|
|
13363
|
+
s.runnerResults = [];
|
|
13364
|
+
}),
|
|
13365
|
+
closeRunner: () => set2((s) => {
|
|
13366
|
+
s.runnerModal.open = false;
|
|
13367
|
+
s.runnerRunning = false;
|
|
13368
|
+
}),
|
|
13369
|
+
setRunnerResults: (results) => set2((s) => {
|
|
13370
|
+
s.runnerResults = results;
|
|
13371
|
+
}),
|
|
13372
|
+
patchRunnerResult: (idx, patch) => set2((s) => {
|
|
13373
|
+
if (s.runnerResults[idx]) Object.assign(s.runnerResults[idx], patch);
|
|
13374
|
+
}),
|
|
13375
|
+
setRunnerRunning: (v) => set2((s) => {
|
|
13376
|
+
s.runnerRunning = v;
|
|
13377
|
+
})
|
|
13378
|
+
});
|
|
13379
|
+
const createRecorderSlice = (set2) => ({
|
|
13380
|
+
recorderOpen: false,
|
|
13381
|
+
recorderRunning: false,
|
|
13382
|
+
recorderUpstream: "",
|
|
13383
|
+
recorderPort: 4001,
|
|
13384
|
+
recorderTargetMockId: "",
|
|
13385
|
+
setRecorderOpen: (open) => set2((s) => {
|
|
13386
|
+
s.recorderOpen = open;
|
|
13387
|
+
}),
|
|
13388
|
+
setRecorderRunning: (running) => set2((s) => {
|
|
13389
|
+
s.recorderRunning = running;
|
|
13390
|
+
}),
|
|
13391
|
+
setRecorderUpstream: (url) => set2((s) => {
|
|
13392
|
+
s.recorderUpstream = url;
|
|
13393
|
+
}),
|
|
13394
|
+
setRecorderPort: (port) => set2((s) => {
|
|
13395
|
+
s.recorderPort = port;
|
|
13396
|
+
}),
|
|
13397
|
+
setRecorderTargetMockId: (id2) => set2((s) => {
|
|
13398
|
+
s.recorderTargetMockId = id2;
|
|
13399
|
+
})
|
|
13400
|
+
});
|
|
13401
|
+
const createContractSlice = (set2) => ({
|
|
13402
|
+
lastContractReport: null,
|
|
13403
|
+
contractSnapshots: {},
|
|
13404
|
+
activeContractSnapshotRelPath: null,
|
|
13405
|
+
setLastContractReport: (r) => set2((s) => {
|
|
13406
|
+
s.lastContractReport = r;
|
|
13407
|
+
}),
|
|
13408
|
+
loadContractSnapshot: (relPath, snapshot) => set2((s) => {
|
|
13409
|
+
s.contractSnapshots[relPath] = snapshot;
|
|
13410
|
+
if (s.workspace) {
|
|
13411
|
+
if (!s.workspace.contracts) s.workspace.contracts = [];
|
|
13412
|
+
if (!s.workspace.contracts.includes(relPath)) s.workspace.contracts.push(relPath);
|
|
13413
|
+
}
|
|
13414
|
+
}),
|
|
13415
|
+
removeContractSnapshot: (relPath) => set2((s) => {
|
|
13416
|
+
delete s.contractSnapshots[relPath];
|
|
13417
|
+
if (s.activeContractSnapshotRelPath === relPath) s.activeContractSnapshotRelPath = null;
|
|
13418
|
+
if (s.workspace?.contracts) {
|
|
13419
|
+
s.workspace.contracts = s.workspace.contracts.filter((p2) => p2 !== relPath);
|
|
13420
|
+
}
|
|
13421
|
+
}),
|
|
13422
|
+
setActiveContractSnapshot: (relPath) => set2((s) => {
|
|
13423
|
+
s.activeContractSnapshotRelPath = relPath;
|
|
13424
|
+
})
|
|
13425
|
+
});
|
|
13320
13426
|
function makeRequest(override = {}) {
|
|
13321
13427
|
return {
|
|
13322
13428
|
id: v4(),
|
|
@@ -13387,7 +13493,7 @@ function findFolderPath(root2, requestId) {
|
|
|
13387
13493
|
}
|
|
13388
13494
|
return [];
|
|
13389
13495
|
}
|
|
13390
|
-
function makeTab(requestId, collectionId) {
|
|
13496
|
+
function makeTab(requestId, collectionId, opts = {}) {
|
|
13391
13497
|
return {
|
|
13392
13498
|
id: v4(),
|
|
13393
13499
|
requestId,
|
|
@@ -13397,12 +13503,31 @@ function makeTab(requestId, collectionId) {
|
|
|
13397
13503
|
lastSentRequest: null,
|
|
13398
13504
|
lastHookResults: null,
|
|
13399
13505
|
isSending: false,
|
|
13400
|
-
|
|
13401
|
-
|
|
13506
|
+
// SOAP requests: 'params' isn't even shown for SOAP and 'body' renders the
|
|
13507
|
+
// WSDL-driven SoapEditor — that's the primary surface, so jump there.
|
|
13508
|
+
// HTTP/WebSocket: keep the existing 'params' default.
|
|
13509
|
+
requestTab: opts.protocol === "soap" ? "body" : "params",
|
|
13510
|
+
// Default to the post-response tab — that's where the typical workflow
|
|
13511
|
+
// (assertions, extracting tokens, saving variables) lives.
|
|
13512
|
+
scriptTab: "post"
|
|
13402
13513
|
};
|
|
13403
13514
|
}
|
|
13515
|
+
function protocolFor(state, requestId) {
|
|
13516
|
+
for (const c of Object.values(state.collections)) {
|
|
13517
|
+
const r = c.data.requests[requestId];
|
|
13518
|
+
if (r) return r.protocol;
|
|
13519
|
+
}
|
|
13520
|
+
return void 0;
|
|
13521
|
+
}
|
|
13404
13522
|
const useStore = create()(
|
|
13405
|
-
immer((set2) => ({
|
|
13523
|
+
immer((set2, get2, api) => ({
|
|
13524
|
+
// ── Slice composition ─────────────────────────────────────────────────────
|
|
13525
|
+
...createWsSlice(set2),
|
|
13526
|
+
...createHistorySlice(set2),
|
|
13527
|
+
...createRunnerSlice(set2),
|
|
13528
|
+
...createRecorderSlice(set2),
|
|
13529
|
+
...createContractSlice(set2),
|
|
13530
|
+
// ── Initial state for the parts that haven't been sliced yet ──────────────
|
|
13406
13531
|
workspace: null,
|
|
13407
13532
|
workspacePath: null,
|
|
13408
13533
|
collections: {},
|
|
@@ -13416,24 +13541,15 @@ const useStore = create()(
|
|
|
13416
13541
|
showGeneratorPanel: false,
|
|
13417
13542
|
theme: localStorage.getItem("theme") ?? "dark",
|
|
13418
13543
|
zoom: Number(localStorage.getItem("zoom") ?? "1.1"),
|
|
13419
|
-
history: [],
|
|
13420
13544
|
sidebarTab: "collections",
|
|
13421
13545
|
workspaceSettingsOpen: false,
|
|
13422
13546
|
mocks: {},
|
|
13423
13547
|
activeMockId: null,
|
|
13424
13548
|
mockLogs: {},
|
|
13425
|
-
recorderOpen: false,
|
|
13426
|
-
recorderRunning: false,
|
|
13427
|
-
recorderUpstream: "",
|
|
13428
|
-
recorderPort: 4001,
|
|
13429
|
-
recorderTargetMockId: "",
|
|
13430
|
-
runnerModal: { open: false, collectionId: null, folderId: null, filterTags: [] },
|
|
13431
|
-
runnerResults: [],
|
|
13432
|
-
runnerRunning: false,
|
|
13433
13549
|
commandPaletteOpen: false,
|
|
13434
13550
|
pinnedResponse: null,
|
|
13435
|
-
|
|
13436
|
-
|
|
13551
|
+
activeGitDiff: null,
|
|
13552
|
+
quickInsertsOpen: true,
|
|
13437
13553
|
// ── Workspace ─────────────────────────────────────────────────────────────
|
|
13438
13554
|
setWorkspace: (ws2, path) => set2((s) => {
|
|
13439
13555
|
s.workspace = ws2;
|
|
@@ -13458,6 +13574,8 @@ const useStore = create()(
|
|
|
13458
13574
|
s.wsConnections = {};
|
|
13459
13575
|
s.pinnedResponse = null;
|
|
13460
13576
|
s.lastContractReport = null;
|
|
13577
|
+
s.contractSnapshots = {};
|
|
13578
|
+
s.activeContractSnapshotRelPath = null;
|
|
13461
13579
|
}),
|
|
13462
13580
|
updateWorkspaceSettings: (settings) => set2((s) => {
|
|
13463
13581
|
if (s.workspace) s.workspace.settings = settings;
|
|
@@ -13471,6 +13589,7 @@ const useStore = create()(
|
|
|
13471
13589
|
if (!req.params) req.params = [];
|
|
13472
13590
|
if (!req.body) req.body = { mode: "none" };
|
|
13473
13591
|
if (!req.auth) req.auth = { type: "none" };
|
|
13592
|
+
if (!req.protocol && req.body.mode === "soap") req.protocol = "soap";
|
|
13474
13593
|
}
|
|
13475
13594
|
function sanitizeFolder(f) {
|
|
13476
13595
|
if (!f.folders) f.folders = [];
|
|
@@ -13493,7 +13612,7 @@ const useStore = create()(
|
|
|
13493
13612
|
s.activeTabId = existing.id;
|
|
13494
13613
|
s.activeCollectionId = collectionId;
|
|
13495
13614
|
} else {
|
|
13496
|
-
const tab = makeTab(requestId, collectionId);
|
|
13615
|
+
const tab = makeTab(requestId, collectionId, { protocol: protocolFor(s, requestId) });
|
|
13497
13616
|
s.tabs.push(tab);
|
|
13498
13617
|
s.activeTabId = tab.id;
|
|
13499
13618
|
s.activeCollectionId = collectionId;
|
|
@@ -13566,7 +13685,7 @@ const useStore = create()(
|
|
|
13566
13685
|
s.activeTabId = existing.id;
|
|
13567
13686
|
s.activeCollectionId = existing.collectionId;
|
|
13568
13687
|
} else {
|
|
13569
|
-
const tab = makeTab(id2, collectionId);
|
|
13688
|
+
const tab = makeTab(id2, collectionId, { protocol: protocolFor(s, id2) });
|
|
13570
13689
|
s.tabs.push(tab);
|
|
13571
13690
|
s.activeTabId = tab.id;
|
|
13572
13691
|
s.activeCollectionId = collectionId;
|
|
@@ -13682,19 +13801,26 @@ const useStore = create()(
|
|
|
13682
13801
|
entry.dirty = true;
|
|
13683
13802
|
s.activeCollectionId = collectionId;
|
|
13684
13803
|
}),
|
|
13685
|
-
deleteCollection: (id2) =>
|
|
13686
|
-
const relPath =
|
|
13687
|
-
|
|
13688
|
-
|
|
13689
|
-
|
|
13690
|
-
|
|
13691
|
-
s.tabs = s.tabs.filter((t2) => t2.collectionId !== id2);
|
|
13692
|
-
if (s.activeCollectionId === id2) {
|
|
13693
|
-
s.activeCollectionId = Object.keys(s.collections)[0] ?? null;
|
|
13694
|
-
const activeTab = s.tabs.find((t2) => t2.id === s.activeTabId);
|
|
13695
|
-
if (!activeTab) s.activeTabId = s.tabs[0]?.id ?? null;
|
|
13804
|
+
deleteCollection: (id2) => {
|
|
13805
|
+
const relPath = useStore.getState().collections[id2]?.relPath;
|
|
13806
|
+
if (relPath) {
|
|
13807
|
+
window.electron.deleteWorkspaceFile(relPath).catch((err) => {
|
|
13808
|
+
console.warn("deleteCollection: could not remove file", relPath, err);
|
|
13809
|
+
});
|
|
13696
13810
|
}
|
|
13697
|
-
|
|
13811
|
+
set2((s) => {
|
|
13812
|
+
delete s.collections[id2];
|
|
13813
|
+
if (s.workspace && relPath) {
|
|
13814
|
+
s.workspace.collections = s.workspace.collections.filter((p2) => p2 !== relPath);
|
|
13815
|
+
}
|
|
13816
|
+
s.tabs = s.tabs.filter((t2) => t2.collectionId !== id2);
|
|
13817
|
+
if (s.activeCollectionId === id2) {
|
|
13818
|
+
s.activeCollectionId = Object.keys(s.collections)[0] ?? null;
|
|
13819
|
+
const activeTab = s.tabs.find((t2) => t2.id === s.activeTabId);
|
|
13820
|
+
if (!activeTab) s.activeTabId = s.tabs[0]?.id ?? null;
|
|
13821
|
+
}
|
|
13822
|
+
});
|
|
13823
|
+
},
|
|
13698
13824
|
updateCollectionDataSet: (id2, ds) => set2((s) => {
|
|
13699
13825
|
if (!s.collections[id2]) return;
|
|
13700
13826
|
s.collections[id2].data.dataSet = ds;
|
|
@@ -13826,7 +13952,7 @@ const useStore = create()(
|
|
|
13826
13952
|
folder.requestIds.splice(idx + 1, 0, copy.id);
|
|
13827
13953
|
}
|
|
13828
13954
|
s.collections[collectionId].dirty = true;
|
|
13829
|
-
const tab = makeTab(copy.id, collectionId);
|
|
13955
|
+
const tab = makeTab(copy.id, collectionId, { protocol: copy.protocol });
|
|
13830
13956
|
s.tabs.push(tab);
|
|
13831
13957
|
s.activeTabId = tab.id;
|
|
13832
13958
|
}),
|
|
@@ -13918,10 +14044,13 @@ const useStore = create()(
|
|
|
13918
14044
|
setPinnedResponse: (r) => set2((s) => {
|
|
13919
14045
|
s.pinnedResponse = r;
|
|
13920
14046
|
}),
|
|
13921
|
-
|
|
13922
|
-
|
|
13923
|
-
s.lastContractReport = r;
|
|
14047
|
+
setActiveGitDiff: (d) => set2((s) => {
|
|
14048
|
+
s.activeGitDiff = d;
|
|
13924
14049
|
}),
|
|
14050
|
+
setQuickInsertsOpen: (open) => set2((s) => {
|
|
14051
|
+
s.quickInsertsOpen = open;
|
|
14052
|
+
}),
|
|
14053
|
+
// Contract testing + contract snapshots are now in slices/contract-slice.ts.
|
|
13925
14054
|
// ── Inherited auth/headers ────────────────────────────────────────────────
|
|
13926
14055
|
getInheritedAuthAndHeaders: (requestId) => {
|
|
13927
14056
|
const state = useStore.getState();
|
|
@@ -13954,14 +14083,37 @@ const useStore = create()(
|
|
|
13954
14083
|
s.activeEnvironmentId = env.id;
|
|
13955
14084
|
if (s.workspace) s.workspace.environments.push(relPath);
|
|
13956
14085
|
}),
|
|
13957
|
-
|
|
13958
|
-
const
|
|
13959
|
-
|
|
13960
|
-
|
|
13961
|
-
|
|
13962
|
-
|
|
13963
|
-
|
|
14086
|
+
duplicateEnvironment: (id2) => set2((s) => {
|
|
14087
|
+
const src = s.environments[id2];
|
|
14088
|
+
if (!src) return;
|
|
14089
|
+
const existingNames = Object.values(s.environments).map((e) => e.data.name);
|
|
14090
|
+
const newName = uniqueName(src.data.name + " (copy)", existingNames);
|
|
14091
|
+
const newId = v4();
|
|
14092
|
+
const env = {
|
|
14093
|
+
...JSON.parse(JSON.stringify(src.data)),
|
|
14094
|
+
id: newId,
|
|
14095
|
+
name: newName
|
|
14096
|
+
};
|
|
14097
|
+
const relPath = `environments/${newName.toLowerCase().replace(/[^a-z0-9]+/g, "-")}.env.json`;
|
|
14098
|
+
s.environments[env.id] = { relPath, data: env };
|
|
14099
|
+
s.activeEnvironmentId = env.id;
|
|
14100
|
+
if (s.workspace) s.workspace.environments.push(relPath);
|
|
13964
14101
|
}),
|
|
14102
|
+
deleteEnvironment: (id2) => {
|
|
14103
|
+
const relPath = useStore.getState().environments[id2]?.relPath;
|
|
14104
|
+
if (relPath) {
|
|
14105
|
+
window.electron.deleteWorkspaceFile(relPath).catch((err) => {
|
|
14106
|
+
console.warn("deleteEnvironment: could not remove file", relPath, err);
|
|
14107
|
+
});
|
|
14108
|
+
}
|
|
14109
|
+
set2((s) => {
|
|
14110
|
+
delete s.environments[id2];
|
|
14111
|
+
if (s.activeEnvironmentId === id2) s.activeEnvironmentId = null;
|
|
14112
|
+
if (relPath && s.workspace) {
|
|
14113
|
+
s.workspace.environments = s.workspace.environments.filter((p2) => p2 !== relPath);
|
|
14114
|
+
}
|
|
14115
|
+
});
|
|
14116
|
+
},
|
|
13965
14117
|
// ── Globals ───────────────────────────────────────────────────────────────
|
|
13966
14118
|
setGlobals: (globals) => set2((s) => {
|
|
13967
14119
|
s.globals = globals;
|
|
@@ -14022,32 +14174,8 @@ const useStore = create()(
|
|
|
14022
14174
|
}
|
|
14023
14175
|
window.electron.setZoomFactor(z);
|
|
14024
14176
|
}),
|
|
14025
|
-
//
|
|
14026
|
-
|
|
14027
|
-
s.runnerModal = { open: true, collectionId, folderId, filterTags };
|
|
14028
|
-
s.runnerResults = [];
|
|
14029
|
-
}),
|
|
14030
|
-
closeRunner: () => set2((s) => {
|
|
14031
|
-
s.runnerModal.open = false;
|
|
14032
|
-
s.runnerRunning = false;
|
|
14033
|
-
}),
|
|
14034
|
-
setRunnerResults: (results) => set2((s) => {
|
|
14035
|
-
s.runnerResults = results;
|
|
14036
|
-
}),
|
|
14037
|
-
patchRunnerResult: (idx, patch) => set2((s) => {
|
|
14038
|
-
if (s.runnerResults[idx]) Object.assign(s.runnerResults[idx], patch);
|
|
14039
|
-
}),
|
|
14040
|
-
setRunnerRunning: (v) => set2((s) => {
|
|
14041
|
-
s.runnerRunning = v;
|
|
14042
|
-
}),
|
|
14043
|
-
// ── History ───────────────────────────────────────────────────────────────
|
|
14044
|
-
addHistoryEntry: (entry) => set2((s) => {
|
|
14045
|
-
s.history.unshift(entry);
|
|
14046
|
-
if (s.history.length > 200) s.history.length = 200;
|
|
14047
|
-
}),
|
|
14048
|
-
clearHistory: () => set2((s) => {
|
|
14049
|
-
s.history = [];
|
|
14050
|
-
}),
|
|
14177
|
+
// Runner modal lives in slices/runner-slice.ts.
|
|
14178
|
+
// History lives in slices/history-slice.ts.
|
|
14051
14179
|
setSidebarTab: (tab) => set2((s) => {
|
|
14052
14180
|
s.sidebarTab = tab;
|
|
14053
14181
|
}),
|
|
@@ -14074,14 +14202,21 @@ const useStore = create()(
|
|
|
14074
14202
|
updateMock: (id2, data) => set2((s) => {
|
|
14075
14203
|
if (s.mocks[id2]) s.mocks[id2].data = data;
|
|
14076
14204
|
}),
|
|
14077
|
-
deleteMock: (id2) =>
|
|
14078
|
-
const relPath =
|
|
14079
|
-
|
|
14080
|
-
|
|
14081
|
-
|
|
14205
|
+
deleteMock: (id2) => {
|
|
14206
|
+
const relPath = useStore.getState().mocks[id2]?.relPath;
|
|
14207
|
+
if (relPath) {
|
|
14208
|
+
window.electron.deleteWorkspaceFile(relPath).catch((err) => {
|
|
14209
|
+
console.warn("deleteMock: could not remove file", relPath, err);
|
|
14210
|
+
});
|
|
14082
14211
|
}
|
|
14083
|
-
|
|
14084
|
-
|
|
14212
|
+
set2((s) => {
|
|
14213
|
+
delete s.mocks[id2];
|
|
14214
|
+
if (s.workspace?.mocks && relPath) {
|
|
14215
|
+
s.workspace.mocks = s.workspace.mocks.filter((p2) => p2 !== relPath);
|
|
14216
|
+
}
|
|
14217
|
+
if (s.activeMockId === id2) s.activeMockId = null;
|
|
14218
|
+
});
|
|
14219
|
+
},
|
|
14085
14220
|
setMockRunning: (id2, running) => set2((s) => {
|
|
14086
14221
|
if (s.mocks[id2]) s.mocks[id2].running = running;
|
|
14087
14222
|
}),
|
|
@@ -14095,47 +14230,12 @@ const useStore = create()(
|
|
|
14095
14230
|
}),
|
|
14096
14231
|
clearMockLogs: (serverId) => set2((s) => {
|
|
14097
14232
|
s.mockLogs[serverId] = [];
|
|
14098
|
-
}),
|
|
14099
|
-
// ── Recorder ──────────────────────────────────────────────────────────────
|
|
14100
|
-
setRecorderOpen: (open) => set2((s) => {
|
|
14101
|
-
s.recorderOpen = open;
|
|
14102
|
-
}),
|
|
14103
|
-
setRecorderRunning: (running) => set2((s) => {
|
|
14104
|
-
s.recorderRunning = running;
|
|
14105
|
-
}),
|
|
14106
|
-
setRecorderUpstream: (url) => set2((s) => {
|
|
14107
|
-
s.recorderUpstream = url;
|
|
14108
|
-
}),
|
|
14109
|
-
setRecorderPort: (port) => set2((s) => {
|
|
14110
|
-
s.recorderPort = port;
|
|
14111
|
-
}),
|
|
14112
|
-
setRecorderTargetMockId: (id2) => set2((s) => {
|
|
14113
|
-
s.recorderTargetMockId = id2;
|
|
14114
|
-
}),
|
|
14115
|
-
// ── WebSocket ─────────────────────────────────────────────────────────────
|
|
14116
|
-
setWsStatus: (requestId, status, error2) => set2((s) => {
|
|
14117
|
-
if (!s.wsConnections[requestId]) {
|
|
14118
|
-
s.wsConnections[requestId] = { status, messages: [], error: error2 };
|
|
14119
|
-
} else {
|
|
14120
|
-
s.wsConnections[requestId].status = status;
|
|
14121
|
-
s.wsConnections[requestId].error = error2;
|
|
14122
|
-
}
|
|
14123
|
-
}),
|
|
14124
|
-
addWsMessage: (requestId, message) => set2((s) => {
|
|
14125
|
-
if (!s.wsConnections[requestId]) {
|
|
14126
|
-
s.wsConnections[requestId] = { status: "connected", messages: [message] };
|
|
14127
|
-
} else {
|
|
14128
|
-
s.wsConnections[requestId].messages.push(message);
|
|
14129
|
-
}
|
|
14130
|
-
}),
|
|
14131
|
-
clearWsMessages: (requestId) => set2((s) => {
|
|
14132
|
-
if (s.wsConnections[requestId]) {
|
|
14133
|
-
s.wsConnections[requestId].messages = [];
|
|
14134
|
-
}
|
|
14135
14233
|
})
|
|
14234
|
+
// Recorder lives in slices/recorder-slice.ts.
|
|
14235
|
+
// WebSocket actions live in slices/ws-slice.ts.
|
|
14136
14236
|
}))
|
|
14137
14237
|
);
|
|
14138
|
-
const { electron: electron$
|
|
14238
|
+
const { electron: electron$q } = window;
|
|
14139
14239
|
function useAutoSave() {
|
|
14140
14240
|
const collections = useStore((s) => s.collections);
|
|
14141
14241
|
useStore((s) => s.environments);
|
|
@@ -14151,7 +14251,7 @@ function useAutoSave() {
|
|
|
14151
14251
|
for (const { relPath, data, dirty } of dirtyCollections) {
|
|
14152
14252
|
if (!dirty) continue;
|
|
14153
14253
|
try {
|
|
14154
|
-
await electron$
|
|
14254
|
+
await electron$q.saveCollection(relPath, data);
|
|
14155
14255
|
markCollectionClean(data.id);
|
|
14156
14256
|
} catch (e) {
|
|
14157
14257
|
console.error("Auto-save failed for", relPath, e);
|
|
@@ -14167,7 +14267,7 @@ function useAutoSave() {
|
|
|
14167
14267
|
if (wsTimerRef.current) clearTimeout(wsTimerRef.current);
|
|
14168
14268
|
wsTimerRef.current = setTimeout(async () => {
|
|
14169
14269
|
try {
|
|
14170
|
-
await electron$
|
|
14270
|
+
await electron$q.saveWorkspace(workspace);
|
|
14171
14271
|
} catch {
|
|
14172
14272
|
}
|
|
14173
14273
|
}, 300);
|
|
@@ -14176,12 +14276,13 @@ function useAutoSave() {
|
|
|
14176
14276
|
};
|
|
14177
14277
|
}, [workspace]);
|
|
14178
14278
|
}
|
|
14179
|
-
const { electron: electron$
|
|
14279
|
+
const { electron: electron$p } = window;
|
|
14180
14280
|
function useWorkspaceLoader() {
|
|
14181
14281
|
const loadCollection = useStore((s) => s.loadCollection);
|
|
14182
14282
|
const loadEnvironment = useStore((s) => s.loadEnvironment);
|
|
14183
14283
|
const loadMock = useStore((s) => s.loadMock);
|
|
14184
14284
|
const setActiveCollection = useStore((s) => s.setActiveCollection);
|
|
14285
|
+
const loadContractSnapshot = useStore((s) => s.loadContractSnapshot);
|
|
14185
14286
|
const setTheme = useStore((s) => s.setTheme);
|
|
14186
14287
|
const setZoom = useStore((s) => s.setZoom);
|
|
14187
14288
|
const applyWorkspace = reactExports.useCallback(async (ws2, path) => {
|
|
@@ -14199,62 +14300,40 @@ function useWorkspaceLoader() {
|
|
|
14199
14300
|
if (typeof ws2.settings?.zoom === "number") setZoom(ws2.settings.zoom);
|
|
14200
14301
|
for (const colPath of ws2.collections) {
|
|
14201
14302
|
try {
|
|
14202
|
-
const col = await electron$
|
|
14303
|
+
const col = await electron$p.loadCollection(colPath);
|
|
14203
14304
|
loadCollection(colPath, col);
|
|
14204
14305
|
} catch {
|
|
14205
14306
|
}
|
|
14206
14307
|
}
|
|
14207
14308
|
for (const envPath of ws2.environments) {
|
|
14208
14309
|
try {
|
|
14209
|
-
const env = await electron$
|
|
14310
|
+
const env = await electron$p.loadEnvironment(envPath);
|
|
14210
14311
|
loadEnvironment(envPath, env);
|
|
14211
14312
|
} catch {
|
|
14212
14313
|
}
|
|
14213
14314
|
}
|
|
14214
14315
|
for (const relPath of ws2.mocks ?? []) {
|
|
14215
14316
|
try {
|
|
14216
|
-
const mockData = await electron$
|
|
14317
|
+
const mockData = await electron$p.loadMock(relPath);
|
|
14217
14318
|
loadMock(relPath, mockData);
|
|
14218
14319
|
} catch {
|
|
14219
14320
|
}
|
|
14220
14321
|
}
|
|
14322
|
+
try {
|
|
14323
|
+
const snapshots = await electron$p.listContractSnapshots(ws2.contracts ?? []);
|
|
14324
|
+
for (const { relPath, snapshot } of snapshots) loadContractSnapshot(relPath, snapshot);
|
|
14325
|
+
} catch {
|
|
14326
|
+
}
|
|
14221
14327
|
if (ws2.collections.length > 0) {
|
|
14222
14328
|
try {
|
|
14223
|
-
const firstCol = await electron$
|
|
14329
|
+
const firstCol = await electron$p.loadCollection(ws2.collections[0]);
|
|
14224
14330
|
setActiveCollection(firstCol.id);
|
|
14225
14331
|
} catch {
|
|
14226
14332
|
}
|
|
14227
14333
|
}
|
|
14228
|
-
}, [loadCollection, loadEnvironment, loadMock, setActiveCollection, setTheme, setZoom]);
|
|
14334
|
+
}, [loadCollection, loadEnvironment, loadMock, loadContractSnapshot, setActiveCollection, setTheme, setZoom]);
|
|
14229
14335
|
return { applyWorkspace };
|
|
14230
14336
|
}
|
|
14231
|
-
const METHOD_COLORS$1 = {
|
|
14232
|
-
GET: "text-emerald-400",
|
|
14233
|
-
POST: "text-blue-400",
|
|
14234
|
-
PUT: "text-amber-400",
|
|
14235
|
-
PATCH: "text-orange-400",
|
|
14236
|
-
DELETE: "text-red-400",
|
|
14237
|
-
HEAD: "text-purple-400",
|
|
14238
|
-
OPTIONS: "text-surface-400",
|
|
14239
|
-
ANY: "text-surface-400"
|
|
14240
|
-
};
|
|
14241
|
-
function getMethodColor(method) {
|
|
14242
|
-
return METHOD_COLORS$1[method] ?? "text-surface-400";
|
|
14243
|
-
}
|
|
14244
|
-
const STATUS_COLORS = {
|
|
14245
|
-
"2": "text-emerald-400",
|
|
14246
|
-
"3": "text-amber-400",
|
|
14247
|
-
"4": "text-orange-400",
|
|
14248
|
-
"5": "text-red-400"
|
|
14249
|
-
};
|
|
14250
|
-
function getStatusColor(status) {
|
|
14251
|
-
return STATUS_COLORS[String(status)[0]] ?? "text-gray-400";
|
|
14252
|
-
}
|
|
14253
|
-
function MethodBadge({ method, size = "sm" }) {
|
|
14254
|
-
const color = getMethodColor(method);
|
|
14255
|
-
const cls = size === "xs" ? "text-[10px] font-bold w-10" : "text-xs font-bold w-12";
|
|
14256
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `${cls} ${color} shrink-0`, children: method });
|
|
14257
|
-
}
|
|
14258
14337
|
let rangeFrom = [], rangeTo = [];
|
|
14259
14338
|
(() => {
|
|
14260
14339
|
let numbers = "lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map((s) => s ? parseInt(s, 36) : 1);
|
|
@@ -34272,7 +34351,12 @@ const FAKER_NAMESPACES = [
|
|
|
34272
34351
|
{ label: "lorem", type: "property", info: "Lorem ipsum text" },
|
|
34273
34352
|
{ label: "location", type: "property", info: "Addresses, cities, countries" },
|
|
34274
34353
|
{ label: "finance", type: "property", info: "Credit cards, currency, etc." },
|
|
34275
|
-
{ label: "color", type: "property", info: "Color values" }
|
|
34354
|
+
{ label: "color", type: "property", info: "Color values" },
|
|
34355
|
+
{ label: "company", type: "property", info: "Company names, catch phrases" },
|
|
34356
|
+
{ label: "commerce", type: "property", info: "Products, prices, departments" },
|
|
34357
|
+
{ label: "image", type: "property", info: "Image URLs / placeholders" },
|
|
34358
|
+
{ label: "system", type: "property", info: "File names, MIME types, semver" },
|
|
34359
|
+
{ label: "helpers", type: "property", info: "Utility helpers (slugify, arrayElement, …)" }
|
|
34276
34360
|
];
|
|
34277
34361
|
const FAKER_SUB = {
|
|
34278
34362
|
string: [
|
|
@@ -34307,9 +34391,14 @@ const FAKER_SUB = {
|
|
|
34307
34391
|
],
|
|
34308
34392
|
lorem: [
|
|
34309
34393
|
{ label: "word", type: "function", detail: "()", info: "Single lorem word" },
|
|
34310
|
-
{ label: "words", type: "function", detail: "(count)", info: "Multiple lorem words" },
|
|
34394
|
+
{ label: "words", type: "function", detail: "(count?)", info: "Multiple lorem words" },
|
|
34311
34395
|
{ label: "sentence", type: "function", detail: "()", info: "Lorem sentence" },
|
|
34312
|
-
{ label: "
|
|
34396
|
+
{ label: "sentences", type: "function", detail: "(count?)", info: "Multiple lorem sentences" },
|
|
34397
|
+
{ label: "paragraph", type: "function", detail: "()", info: "Lorem paragraph" },
|
|
34398
|
+
{ label: "paragraphs", type: "function", detail: "(count?)", info: "Multiple lorem paragraphs" },
|
|
34399
|
+
{ label: "slug", type: "function", detail: "(words?)", info: 'Kebab-case slug from random words (e.g. "magnam-officia-laborum")' },
|
|
34400
|
+
{ label: "lines", type: "function", detail: "(count?)", info: "Random lines of text" },
|
|
34401
|
+
{ label: "text", type: "function", detail: "()", info: "Random lorem ipsum text" }
|
|
34313
34402
|
],
|
|
34314
34403
|
location: [
|
|
34315
34404
|
{ label: "city", type: "function", detail: "()", info: "Random city name" },
|
|
@@ -34337,6 +34426,39 @@ const FAKER_SUB = {
|
|
|
34337
34426
|
{ label: "hex", type: "function", detail: "()", info: "Hex color string (e.g. #a3f1c2)" },
|
|
34338
34427
|
{ label: "rgb", type: "function", detail: "()", info: "CSS rgb() string" },
|
|
34339
34428
|
{ label: "hsl", type: "function", detail: "()", info: "CSS hsl() string" }
|
|
34429
|
+
],
|
|
34430
|
+
company: [
|
|
34431
|
+
{ label: "name", type: "function", detail: "()", info: "Random company name" },
|
|
34432
|
+
{ label: "catchPhrase", type: "function", detail: "()", info: "Random business catch phrase" },
|
|
34433
|
+
{ label: "buzzPhrase", type: "function", detail: "()", info: "Marketing-style buzz phrase" }
|
|
34434
|
+
],
|
|
34435
|
+
commerce: [
|
|
34436
|
+
{ label: "productName", type: "function", detail: "()", info: "Random product name" },
|
|
34437
|
+
{ label: "product", type: "function", detail: "()", info: "Single product noun" },
|
|
34438
|
+
{ label: "department", type: "function", detail: "()", info: "Department name" },
|
|
34439
|
+
{ label: "price", type: "function", detail: "({min, max, dec, symbol}?)", info: "Random price (string)" },
|
|
34440
|
+
{ label: "productDescription", type: "function", detail: "()", info: "Product description" },
|
|
34441
|
+
{ label: "isbn", type: "function", detail: "()", info: "ISBN-10 or ISBN-13" }
|
|
34442
|
+
],
|
|
34443
|
+
image: [
|
|
34444
|
+
{ label: "avatar", type: "function", detail: "()", info: "Avatar URL" },
|
|
34445
|
+
{ label: "url", type: "function", detail: "({width, height}?)", info: "Placeholder image URL" },
|
|
34446
|
+
{ label: "urlLoremFlickr", type: "function", detail: "({category}?)", info: "LoremFlickr URL by category" }
|
|
34447
|
+
],
|
|
34448
|
+
system: [
|
|
34449
|
+
{ label: "fileName", type: "function", detail: "()", info: "Random file name with extension" },
|
|
34450
|
+
{ label: "mimeType", type: "function", detail: "()", info: "Random MIME type" },
|
|
34451
|
+
{ label: "semver", type: "function", detail: "()", info: "Random semver string" },
|
|
34452
|
+
{ label: "directoryPath", type: "function", detail: "()", info: "Random directory path" }
|
|
34453
|
+
],
|
|
34454
|
+
helpers: [
|
|
34455
|
+
{ label: "slugify", type: "function", detail: "(text)", info: "Convert any string to a URL slug (lower-case, dashes, no diacritics)" },
|
|
34456
|
+
{ label: "arrayElement", type: "function", detail: "(arr)", info: "Random element from an array" },
|
|
34457
|
+
{ label: "arrayElements", type: "function", detail: "(arr, n?)", info: "Multiple random elements" },
|
|
34458
|
+
{ label: "shuffle", type: "function", detail: "(arr)", info: "Shuffled copy of the array" },
|
|
34459
|
+
{ label: "replaceSymbols", type: "function", detail: '("###?")', info: "Replace # / ? / * with random chars" },
|
|
34460
|
+
{ label: "fromRegExp", type: "function", detail: "(regex)", info: "Generate a string matching a regex" },
|
|
34461
|
+
{ label: "multiple", type: "function", detail: "(fn, {count}?)", info: "Call a generator multiple times" }
|
|
34340
34462
|
]
|
|
34341
34463
|
};
|
|
34342
34464
|
function makeAtCompletionSource(varNames) {
|
|
@@ -35639,7 +35761,7 @@ function CollectionAuthPanel({ auth, onChange }) {
|
|
|
35639
35761
|
] }) })
|
|
35640
35762
|
] });
|
|
35641
35763
|
}
|
|
35642
|
-
const { electron: electron$
|
|
35764
|
+
const { electron: electron$o } = window;
|
|
35643
35765
|
function normalisePath(url) {
|
|
35644
35766
|
let path = url.replace(/^\{\{[^}]+\}\}/, "").replace(/^https?:\/\/[^/]+/, "");
|
|
35645
35767
|
if (!path.startsWith("/")) path = "/" + path;
|
|
@@ -35726,7 +35848,7 @@ function SchemaSyncModal({
|
|
|
35726
35848
|
setLoading(true);
|
|
35727
35849
|
setError(null);
|
|
35728
35850
|
try {
|
|
35729
|
-
const entries = await electron$
|
|
35851
|
+
const entries = await electron$o.extractOpenApiSchemas();
|
|
35730
35852
|
if (!entries) {
|
|
35731
35853
|
setLoading(false);
|
|
35732
35854
|
return;
|
|
@@ -35745,7 +35867,7 @@ function SchemaSyncModal({
|
|
|
35745
35867
|
setLoading(true);
|
|
35746
35868
|
setError(null);
|
|
35747
35869
|
try {
|
|
35748
|
-
const entries = await electron$
|
|
35870
|
+
const entries = await electron$o.extractOpenApiSchemasFromUrl(trimmed);
|
|
35749
35871
|
setSpecEntries(entries);
|
|
35750
35872
|
autoSelectChanged(entries);
|
|
35751
35873
|
} catch (err) {
|
|
@@ -35778,7 +35900,7 @@ function SchemaSyncModal({
|
|
|
35778
35900
|
}
|
|
35779
35901
|
const entry = useStore.getState().collections[collectionId];
|
|
35780
35902
|
if (entry) {
|
|
35781
|
-
await electron$
|
|
35903
|
+
await electron$o.saveCollection(entry.relPath, entry.data);
|
|
35782
35904
|
markCollectionClean(collectionId);
|
|
35783
35905
|
}
|
|
35784
35906
|
onClose();
|
|
@@ -35982,6 +36104,197 @@ function methodColor$2(method) {
|
|
|
35982
36104
|
return "text-surface-300";
|
|
35983
36105
|
}
|
|
35984
36106
|
}
|
|
36107
|
+
const METHOD_COLORS$1 = {
|
|
36108
|
+
GET: "text-emerald-400",
|
|
36109
|
+
POST: "text-blue-400",
|
|
36110
|
+
PUT: "text-amber-400",
|
|
36111
|
+
PATCH: "text-orange-400",
|
|
36112
|
+
DELETE: "text-red-400",
|
|
36113
|
+
HEAD: "text-purple-400",
|
|
36114
|
+
OPTIONS: "text-surface-400",
|
|
36115
|
+
ANY: "text-surface-400"
|
|
36116
|
+
};
|
|
36117
|
+
function getMethodColor(method) {
|
|
36118
|
+
return METHOD_COLORS$1[method] ?? "text-surface-400";
|
|
36119
|
+
}
|
|
36120
|
+
const STATUS_COLORS = {
|
|
36121
|
+
"2": "text-emerald-400",
|
|
36122
|
+
"3": "text-amber-400",
|
|
36123
|
+
"4": "text-orange-400",
|
|
36124
|
+
"5": "text-red-400"
|
|
36125
|
+
};
|
|
36126
|
+
function getStatusColor(status) {
|
|
36127
|
+
return STATUS_COLORS[String(status)[0]] ?? "text-gray-400";
|
|
36128
|
+
}
|
|
36129
|
+
function MethodBadge({ method, size = "sm" }) {
|
|
36130
|
+
const color = getMethodColor(method);
|
|
36131
|
+
const cls = size === "xs" ? "text-[10px] font-bold w-10" : "text-xs font-bold w-12";
|
|
36132
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `${cls} ${color} shrink-0`, children: method });
|
|
36133
|
+
}
|
|
36134
|
+
const HOOK_LABELS = {
|
|
36135
|
+
beforeAll: "Before All",
|
|
36136
|
+
before: "Before",
|
|
36137
|
+
after: "After",
|
|
36138
|
+
afterAll: "After All"
|
|
36139
|
+
};
|
|
36140
|
+
const HOOK_COLORS = {
|
|
36141
|
+
beforeAll: "bg-violet-700 text-white",
|
|
36142
|
+
before: "bg-violet-600 text-white",
|
|
36143
|
+
after: "bg-cyan-700 text-white",
|
|
36144
|
+
afterAll: "bg-cyan-800 text-white"
|
|
36145
|
+
};
|
|
36146
|
+
const AUTH_BADGE_LABELS = {
|
|
36147
|
+
basic: "Basic",
|
|
36148
|
+
bearer: "Bearer",
|
|
36149
|
+
apikey: "Key",
|
|
36150
|
+
digest: "Digest",
|
|
36151
|
+
ntlm: "NTLM",
|
|
36152
|
+
oauth2: "OAuth2"
|
|
36153
|
+
};
|
|
36154
|
+
function RequestRow({
|
|
36155
|
+
reqId,
|
|
36156
|
+
collectionId,
|
|
36157
|
+
folderId,
|
|
36158
|
+
reqIndex,
|
|
36159
|
+
name: name2,
|
|
36160
|
+
method,
|
|
36161
|
+
protocol,
|
|
36162
|
+
authType,
|
|
36163
|
+
hookType,
|
|
36164
|
+
disabled,
|
|
36165
|
+
tags: tags2,
|
|
36166
|
+
isActive,
|
|
36167
|
+
indent: indent2,
|
|
36168
|
+
autoRename = false,
|
|
36169
|
+
onSelect,
|
|
36170
|
+
onRename,
|
|
36171
|
+
onDelete,
|
|
36172
|
+
onDuplicate,
|
|
36173
|
+
onUpdateTags,
|
|
36174
|
+
onSetHookType,
|
|
36175
|
+
onToggleDisabled
|
|
36176
|
+
}) {
|
|
36177
|
+
const [renaming, setRenaming] = reactExports.useState(autoRename);
|
|
36178
|
+
const [addingTag, setAddingTag] = reactExports.useState(false);
|
|
36179
|
+
const [showSchemaSync, setShowSchemaSync] = reactExports.useState(false);
|
|
36180
|
+
const [dropPos, setDropPos] = reactExports.useState(null);
|
|
36181
|
+
const dragCtx = reactExports.useContext(DragCtx);
|
|
36182
|
+
const hookMenuItems = ["beforeAll", "before", "after", "afterAll"].map((ht) => ({
|
|
36183
|
+
type: "item",
|
|
36184
|
+
label: (hookType === ht ? "✓ " : " ") + HOOK_LABELS[ht],
|
|
36185
|
+
onClick: () => onSetHookType(hookType === ht ? void 0 : ht)
|
|
36186
|
+
}));
|
|
36187
|
+
function handleDragOver(e) {
|
|
36188
|
+
if (!dragCtx.dragging || dragCtx.dragging.type !== "request" || dragCtx.dragging.requestId === reqId) return;
|
|
36189
|
+
e.preventDefault();
|
|
36190
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
36191
|
+
setDropPos(e.clientY < rect.top + rect.height / 2 ? "before" : "after");
|
|
36192
|
+
}
|
|
36193
|
+
function handleDrop(e) {
|
|
36194
|
+
e.preventDefault();
|
|
36195
|
+
e.stopPropagation();
|
|
36196
|
+
const insertIndex = dropPos === "before" ? reqIndex : reqIndex + 1;
|
|
36197
|
+
dragCtx.onDropRequest(collectionId, folderId, insertIndex);
|
|
36198
|
+
setDropPos(null);
|
|
36199
|
+
}
|
|
36200
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
|
|
36201
|
+
dropPos === "before" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-0 inset-x-0 h-0.5 bg-blue-500 z-10 pointer-events-none" }),
|
|
36202
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
36203
|
+
"div",
|
|
36204
|
+
{
|
|
36205
|
+
draggable: true,
|
|
36206
|
+
className: `group flex items-start gap-1.5 py-1 pr-1 rounded-sm cursor-pointer transition-colors ${disabled ? "opacity-40" : ""} ${isActive ? "bg-surface-800 text-[var(--text-primary)]" : "text-surface-300 hover:bg-surface-800"}`,
|
|
36207
|
+
style: { paddingLeft: indent2 },
|
|
36208
|
+
onClick: onSelect,
|
|
36209
|
+
onDoubleClick: () => setRenaming(true),
|
|
36210
|
+
onDragStart: (e) => {
|
|
36211
|
+
e.dataTransfer.effectAllowed = "move";
|
|
36212
|
+
dragCtx.setDragging({ type: "request", requestId: reqId, collectionId });
|
|
36213
|
+
},
|
|
36214
|
+
onDragEnd: () => {
|
|
36215
|
+
dragCtx.setDragging(null);
|
|
36216
|
+
setDropPos(null);
|
|
36217
|
+
},
|
|
36218
|
+
onDragOver: handleDragOver,
|
|
36219
|
+
onDragLeave: () => setDropPos(null),
|
|
36220
|
+
onDrop: handleDrop,
|
|
36221
|
+
children: [
|
|
36222
|
+
protocol === "soap" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36223
|
+
"span",
|
|
36224
|
+
{
|
|
36225
|
+
className: "shrink-0 text-[9px] font-bold px-1.5 py-0.5 rounded bg-amber-700/80 text-amber-50",
|
|
36226
|
+
title: "SOAP request",
|
|
36227
|
+
children: "SOAP"
|
|
36228
|
+
}
|
|
36229
|
+
) : protocol === "websocket" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36230
|
+
"span",
|
|
36231
|
+
{
|
|
36232
|
+
className: "shrink-0 text-[9px] font-bold px-1.5 py-0.5 rounded bg-cyan-700/80 text-cyan-50",
|
|
36233
|
+
title: "WebSocket",
|
|
36234
|
+
children: "WS"
|
|
36235
|
+
}
|
|
36236
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsx(MethodBadge, { method, size: "xs" }),
|
|
36237
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
36238
|
+
renaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36239
|
+
InlineEdit,
|
|
36240
|
+
{
|
|
36241
|
+
value: name2,
|
|
36242
|
+
onCommit: (v) => {
|
|
36243
|
+
onRename(v);
|
|
36244
|
+
setRenaming(false);
|
|
36245
|
+
},
|
|
36246
|
+
onCancel: () => setRenaming(false),
|
|
36247
|
+
className: "w-full text-xs"
|
|
36248
|
+
}
|
|
36249
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 min-w-0", children: [
|
|
36250
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs truncate", children: name2 }),
|
|
36251
|
+
hookType && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `shrink-0 text-[9px] font-bold px-1 py-px rounded ${HOOK_COLORS[hookType]}`, children: HOOK_LABELS[hookType].toUpperCase() }),
|
|
36252
|
+
authType !== "none" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36253
|
+
"span",
|
|
36254
|
+
{
|
|
36255
|
+
className: "shrink-0 text-[9px] px-1 py-px rounded bg-amber-800/40 text-amber-400",
|
|
36256
|
+
title: `Auth: ${AUTH_BADGE_LABELS[authType] ?? authType}`,
|
|
36257
|
+
children: AUTH_BADGE_LABELS[authType] ?? authType
|
|
36258
|
+
}
|
|
36259
|
+
)
|
|
36260
|
+
] }),
|
|
36261
|
+
(tags2.length > 0 || addingTag) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36262
|
+
TagChips,
|
|
36263
|
+
{
|
|
36264
|
+
tags: tags2,
|
|
36265
|
+
onRemove: (tag) => onUpdateTags(tags2.filter((t2) => t2 !== tag)),
|
|
36266
|
+
onAdd: (tag) => onUpdateTags([...tags2, tag]),
|
|
36267
|
+
forceAdding: addingTag,
|
|
36268
|
+
onDoneAdding: () => setAddingTag(false)
|
|
36269
|
+
}
|
|
36270
|
+
)
|
|
36271
|
+
] }),
|
|
36272
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(DotsBtn, { items: [
|
|
36273
|
+
{ type: "item", label: "Rename", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(PencilIcon, {}), onClick: () => setRenaming(true) },
|
|
36274
|
+
{ type: "item", label: "Duplicate", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyIcon, {}), onClick: onDuplicate },
|
|
36275
|
+
{ type: "item", label: "Add tag", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(TagIcon, {}), onClick: () => setAddingTag(true) },
|
|
36276
|
+
{ type: "item", label: "Sync schema", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(SyncIcon, {}), onClick: () => setShowSchemaSync(true) },
|
|
36277
|
+
{ type: "item", label: disabled ? "Enable" : "Disable", onClick: onToggleDisabled },
|
|
36278
|
+
{ type: "separator" },
|
|
36279
|
+
{ type: "header", label: "Hook type" },
|
|
36280
|
+
...hookMenuItems,
|
|
36281
|
+
{ type: "separator" },
|
|
36282
|
+
{ type: "item", label: "Delete", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(TrashIcon, {}), danger: true, onClick: onDelete }
|
|
36283
|
+
] }) }),
|
|
36284
|
+
dropPos === "after" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute bottom-0 inset-x-0 h-0.5 bg-blue-500 z-10 pointer-events-none" })
|
|
36285
|
+
]
|
|
36286
|
+
}
|
|
36287
|
+
),
|
|
36288
|
+
showSchemaSync && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36289
|
+
SchemaSyncModal,
|
|
36290
|
+
{
|
|
36291
|
+
collectionId,
|
|
36292
|
+
scope: { type: "request", requestId: reqId },
|
|
36293
|
+
onClose: () => setShowSchemaSync(false)
|
|
36294
|
+
}
|
|
36295
|
+
)
|
|
36296
|
+
] });
|
|
36297
|
+
}
|
|
35985
36298
|
const DragCtx = reactExports.createContext({ dragging: null, setDragging: () => {
|
|
35986
36299
|
}, onDropRequest: () => {
|
|
35987
36300
|
}, onDropFolder: () => {
|
|
@@ -36029,7 +36342,7 @@ function InlineEdit({
|
|
|
36029
36342
|
if (e.key === "Escape") onCancel();
|
|
36030
36343
|
e.stopPropagation();
|
|
36031
36344
|
},
|
|
36032
|
-
className: `bg-surface-700 rounded px-1 focus:outline-none focus:ring-1 w-full ${error2 ? "ring-1 ring-red-500 focus:ring-red-500" : "focus:ring-blue-500"} ${className}`
|
|
36345
|
+
className: `bg-surface-700 text-[var(--text-primary)] rounded px-1 focus:outline-none focus:ring-1 w-full ${error2 ? "ring-1 ring-red-500 focus:ring-red-500" : "focus:ring-blue-500"} ${className}`
|
|
36033
36346
|
}
|
|
36034
36347
|
),
|
|
36035
36348
|
error2 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-red-400 mt-0.5 px-1", children: error2 })
|
|
@@ -36657,6 +36970,7 @@ function FolderContents({
|
|
|
36657
36970
|
reqIndex,
|
|
36658
36971
|
name: req.name,
|
|
36659
36972
|
method: req.method,
|
|
36973
|
+
protocol: req.protocol,
|
|
36660
36974
|
authType: req.auth.type,
|
|
36661
36975
|
hookType: req.hookType,
|
|
36662
36976
|
disabled: req.disabled,
|
|
@@ -36677,157 +36991,6 @@ function FolderContents({
|
|
|
36677
36991
|
})
|
|
36678
36992
|
] });
|
|
36679
36993
|
}
|
|
36680
|
-
const HOOK_LABELS = {
|
|
36681
|
-
beforeAll: "Before All",
|
|
36682
|
-
before: "Before",
|
|
36683
|
-
after: "After",
|
|
36684
|
-
afterAll: "After All"
|
|
36685
|
-
};
|
|
36686
|
-
const HOOK_COLORS = {
|
|
36687
|
-
beforeAll: "bg-violet-700 text-white",
|
|
36688
|
-
before: "bg-violet-600 text-white",
|
|
36689
|
-
after: "bg-cyan-700 text-white",
|
|
36690
|
-
afterAll: "bg-cyan-800 text-white"
|
|
36691
|
-
};
|
|
36692
|
-
const AUTH_BADGE_LABELS = {
|
|
36693
|
-
basic: "Basic",
|
|
36694
|
-
bearer: "Bearer",
|
|
36695
|
-
apikey: "Key",
|
|
36696
|
-
digest: "Digest",
|
|
36697
|
-
ntlm: "NTLM",
|
|
36698
|
-
oauth2: "OAuth2"
|
|
36699
|
-
};
|
|
36700
|
-
function RequestRow({
|
|
36701
|
-
reqId,
|
|
36702
|
-
collectionId,
|
|
36703
|
-
folderId,
|
|
36704
|
-
reqIndex,
|
|
36705
|
-
name: name2,
|
|
36706
|
-
method,
|
|
36707
|
-
authType,
|
|
36708
|
-
hookType,
|
|
36709
|
-
disabled,
|
|
36710
|
-
tags: tags2,
|
|
36711
|
-
isActive,
|
|
36712
|
-
indent: indent2,
|
|
36713
|
-
autoRename = false,
|
|
36714
|
-
onSelect,
|
|
36715
|
-
onRename,
|
|
36716
|
-
onDelete,
|
|
36717
|
-
onDuplicate,
|
|
36718
|
-
onUpdateTags,
|
|
36719
|
-
onSetHookType,
|
|
36720
|
-
onToggleDisabled
|
|
36721
|
-
}) {
|
|
36722
|
-
const [renaming, setRenaming] = reactExports.useState(autoRename);
|
|
36723
|
-
const [addingTag, setAddingTag] = reactExports.useState(false);
|
|
36724
|
-
const [showSchemaSync, setShowSchemaSync] = reactExports.useState(false);
|
|
36725
|
-
const [dropPos, setDropPos] = reactExports.useState(null);
|
|
36726
|
-
const dragCtx = reactExports.useContext(DragCtx);
|
|
36727
|
-
const hookMenuItems = [
|
|
36728
|
-
...["beforeAll", "before", "after", "afterAll"].map((ht) => ({
|
|
36729
|
-
type: "item",
|
|
36730
|
-
label: (hookType === ht ? "✓ " : " ") + HOOK_LABELS[ht],
|
|
36731
|
-
onClick: () => onSetHookType(hookType === ht ? void 0 : ht)
|
|
36732
|
-
}))
|
|
36733
|
-
];
|
|
36734
|
-
function handleDragOver(e) {
|
|
36735
|
-
if (!dragCtx.dragging || dragCtx.dragging.type !== "request" || dragCtx.dragging.requestId === reqId) return;
|
|
36736
|
-
e.preventDefault();
|
|
36737
|
-
const rect = e.currentTarget.getBoundingClientRect();
|
|
36738
|
-
setDropPos(e.clientY < rect.top + rect.height / 2 ? "before" : "after");
|
|
36739
|
-
}
|
|
36740
|
-
function handleDrop(e) {
|
|
36741
|
-
e.preventDefault();
|
|
36742
|
-
e.stopPropagation();
|
|
36743
|
-
const insertIndex = dropPos === "before" ? reqIndex : reqIndex + 1;
|
|
36744
|
-
dragCtx.onDropRequest(collectionId, folderId, insertIndex);
|
|
36745
|
-
setDropPos(null);
|
|
36746
|
-
}
|
|
36747
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
|
|
36748
|
-
dropPos === "before" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-0 inset-x-0 h-0.5 bg-blue-500 z-10 pointer-events-none" }),
|
|
36749
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
36750
|
-
"div",
|
|
36751
|
-
{
|
|
36752
|
-
draggable: true,
|
|
36753
|
-
className: `group flex items-start gap-1.5 py-1 pr-1 rounded-sm cursor-pointer transition-colors ${disabled ? "opacity-40" : ""} ${isActive ? "bg-surface-800 text-[var(--text-primary)]" : "text-surface-300 hover:bg-surface-800"}`,
|
|
36754
|
-
style: { paddingLeft: indent2 },
|
|
36755
|
-
onClick: onSelect,
|
|
36756
|
-
onDoubleClick: () => setRenaming(true),
|
|
36757
|
-
onDragStart: (e) => {
|
|
36758
|
-
e.dataTransfer.effectAllowed = "move";
|
|
36759
|
-
dragCtx.setDragging({ type: "request", requestId: reqId, collectionId });
|
|
36760
|
-
},
|
|
36761
|
-
onDragEnd: () => {
|
|
36762
|
-
dragCtx.setDragging(null);
|
|
36763
|
-
setDropPos(null);
|
|
36764
|
-
},
|
|
36765
|
-
onDragOver: handleDragOver,
|
|
36766
|
-
onDragLeave: () => setDropPos(null),
|
|
36767
|
-
onDrop: handleDrop,
|
|
36768
|
-
children: [
|
|
36769
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(MethodBadge, { method, size: "xs" }),
|
|
36770
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
36771
|
-
renaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36772
|
-
InlineEdit,
|
|
36773
|
-
{
|
|
36774
|
-
value: name2,
|
|
36775
|
-
onCommit: (v) => {
|
|
36776
|
-
onRename(v);
|
|
36777
|
-
setRenaming(false);
|
|
36778
|
-
},
|
|
36779
|
-
onCancel: () => setRenaming(false),
|
|
36780
|
-
className: "w-full text-xs"
|
|
36781
|
-
}
|
|
36782
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 min-w-0", children: [
|
|
36783
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs truncate", children: name2 }),
|
|
36784
|
-
hookType && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `shrink-0 text-[9px] font-bold px-1 py-px rounded ${HOOK_COLORS[hookType]}`, children: HOOK_LABELS[hookType].toUpperCase() }),
|
|
36785
|
-
authType !== "none" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36786
|
-
"span",
|
|
36787
|
-
{
|
|
36788
|
-
className: "shrink-0 text-[9px] px-1 py-px rounded bg-amber-800/40 text-amber-400",
|
|
36789
|
-
title: `Auth: ${AUTH_BADGE_LABELS[authType] ?? authType}`,
|
|
36790
|
-
children: AUTH_BADGE_LABELS[authType] ?? authType
|
|
36791
|
-
}
|
|
36792
|
-
)
|
|
36793
|
-
] }),
|
|
36794
|
-
(tags2.length > 0 || addingTag) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36795
|
-
TagChips,
|
|
36796
|
-
{
|
|
36797
|
-
tags: tags2,
|
|
36798
|
-
onRemove: (tag) => onUpdateTags(tags2.filter((t2) => t2 !== tag)),
|
|
36799
|
-
onAdd: (tag) => onUpdateTags([...tags2, tag]),
|
|
36800
|
-
forceAdding: addingTag,
|
|
36801
|
-
onDoneAdding: () => setAddingTag(false)
|
|
36802
|
-
}
|
|
36803
|
-
)
|
|
36804
|
-
] }),
|
|
36805
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(DotsBtn, { items: [
|
|
36806
|
-
{ type: "item", label: "Rename", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(PencilIcon, {}), onClick: () => setRenaming(true) },
|
|
36807
|
-
{ type: "item", label: "Duplicate", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyIcon, {}), onClick: onDuplicate },
|
|
36808
|
-
{ type: "item", label: "Add tag", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(TagIcon, {}), onClick: () => setAddingTag(true) },
|
|
36809
|
-
{ type: "item", label: "Sync schema", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(SyncIcon, {}), onClick: () => setShowSchemaSync(true) },
|
|
36810
|
-
{ type: "item", label: disabled ? "Enable" : "Disable", onClick: onToggleDisabled },
|
|
36811
|
-
{ type: "separator" },
|
|
36812
|
-
{ type: "header", label: "Hook type" },
|
|
36813
|
-
...hookMenuItems,
|
|
36814
|
-
{ type: "separator" },
|
|
36815
|
-
{ type: "item", label: "Delete", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(TrashIcon, {}), danger: true, onClick: onDelete }
|
|
36816
|
-
] }) }),
|
|
36817
|
-
dropPos === "after" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute bottom-0 inset-x-0 h-0.5 bg-blue-500 z-10 pointer-events-none" })
|
|
36818
|
-
]
|
|
36819
|
-
}
|
|
36820
|
-
),
|
|
36821
|
-
showSchemaSync && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36822
|
-
SchemaSyncModal,
|
|
36823
|
-
{
|
|
36824
|
-
collectionId,
|
|
36825
|
-
scope: { type: "request", requestId: reqId },
|
|
36826
|
-
onClose: () => setShowSchemaSync(false)
|
|
36827
|
-
}
|
|
36828
|
-
)
|
|
36829
|
-
] });
|
|
36830
|
-
}
|
|
36831
36994
|
function DotsHorizontalIcon() {
|
|
36832
36995
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "w-3.5 h-3.5", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M6 10a2 2 0 11-4 0 2 2 0 014 0zm6 0a2 2 0 11-4 0 2 2 0 014 0zm6 0a2 2 0 11-4 0 2 2 0 014 0z" }) });
|
|
36833
36996
|
}
|
|
@@ -54093,11 +54256,59 @@ function getBaseKind(ref2) {
|
|
|
54093
54256
|
function isLeafKind(kind) {
|
|
54094
54257
|
return kind === "SCALAR" || kind === "ENUM";
|
|
54095
54258
|
}
|
|
54259
|
+
function isRequired(ref2) {
|
|
54260
|
+
return !!ref2 && ref2.kind === "NON_NULL";
|
|
54261
|
+
}
|
|
54262
|
+
function defaultArgValue(arg) {
|
|
54263
|
+
const baseTypeName = getBaseTypeName(arg.type);
|
|
54264
|
+
const baseKind = getBaseKind(arg.type);
|
|
54265
|
+
const isList2 = arg.type.kind === "LIST" || arg.type.kind === "NON_NULL" && arg.type.ofType?.kind === "LIST";
|
|
54266
|
+
const name2 = arg.name.toLowerCase();
|
|
54267
|
+
if (baseTypeName === "Int" || baseTypeName === "Long") {
|
|
54268
|
+
if (["first", "last", "limit", "take", "top", "count", "size"].includes(name2)) return "5";
|
|
54269
|
+
if (["skip", "offset", "page"].includes(name2)) return "0";
|
|
54270
|
+
return "10";
|
|
54271
|
+
}
|
|
54272
|
+
if (isList2) return "[]";
|
|
54273
|
+
switch (baseTypeName) {
|
|
54274
|
+
case "Float":
|
|
54275
|
+
case "Double":
|
|
54276
|
+
return "1.0";
|
|
54277
|
+
case "Boolean":
|
|
54278
|
+
return "true";
|
|
54279
|
+
case "ID":
|
|
54280
|
+
return '"id"';
|
|
54281
|
+
case "String":
|
|
54282
|
+
return '""';
|
|
54283
|
+
case "DateTime":
|
|
54284
|
+
case "Date":
|
|
54285
|
+
return '""';
|
|
54286
|
+
}
|
|
54287
|
+
if (baseKind === "ENUM") return `# ${baseTypeName}`;
|
|
54288
|
+
return `$${arg.name}`;
|
|
54289
|
+
}
|
|
54096
54290
|
function buildSnippet(field, typeMap) {
|
|
54097
54291
|
const baseTypeName = getBaseTypeName(field.type);
|
|
54098
54292
|
const baseKind = getBaseKind(field.type);
|
|
54099
54293
|
const type2 = typeMap.get(baseTypeName);
|
|
54100
|
-
const
|
|
54294
|
+
const PAGINATION_NAMES = /* @__PURE__ */ new Set([
|
|
54295
|
+
"first",
|
|
54296
|
+
"last",
|
|
54297
|
+
"limit",
|
|
54298
|
+
"take",
|
|
54299
|
+
"top",
|
|
54300
|
+
"count",
|
|
54301
|
+
"size",
|
|
54302
|
+
"skip",
|
|
54303
|
+
"offset",
|
|
54304
|
+
"page",
|
|
54305
|
+
"after",
|
|
54306
|
+
"before"
|
|
54307
|
+
]);
|
|
54308
|
+
const includedArgs = field.args.filter(
|
|
54309
|
+
(a) => isRequired(a.type) || PAGINATION_NAMES.has(a.name.toLowerCase())
|
|
54310
|
+
);
|
|
54311
|
+
const args = includedArgs.length > 0 ? `(${includedArgs.map((a) => `${a.name}: ${defaultArgValue(a)}`).join(", ")})` : "";
|
|
54101
54312
|
if ((baseKind === "OBJECT" || baseKind === "INTERFACE") && type2?.fields?.length) {
|
|
54102
54313
|
const leaves = type2.fields.filter((f) => isLeafKind(getBaseKind(f.type))).slice(0, 4).map((f) => ` ${f.name}`).join("\n");
|
|
54103
54314
|
return ` ${field.name}${args} {
|
|
@@ -54938,32 +55149,86 @@ const autoCloseTags$1 = /* @__PURE__ */ EditorView.inputHandler.of((view, from,
|
|
|
54938
55149
|
]);
|
|
54939
55150
|
return true;
|
|
54940
55151
|
});
|
|
54941
|
-
const
|
|
55152
|
+
const SOAP_11_CONTENT_TYPE = "text/xml; charset=utf-8";
|
|
55153
|
+
const SOAP_12_CONTENT_TYPE = "application/soap+xml; charset=utf-8";
|
|
55154
|
+
function contentTypeForSoap(version) {
|
|
55155
|
+
return version === "1.2" ? SOAP_12_CONTENT_TYPE : SOAP_11_CONTENT_TYPE;
|
|
55156
|
+
}
|
|
55157
|
+
function withContentType(headers, value) {
|
|
55158
|
+
const idx = headers.findIndex((h) => h.key.toLowerCase() === "content-type");
|
|
55159
|
+
const next = { key: "Content-Type", value, enabled: true };
|
|
55160
|
+
if (idx === -1) return [...headers, next];
|
|
55161
|
+
return headers.map((h, i) => i === idx ? { ...h, value, enabled: true } : h);
|
|
55162
|
+
}
|
|
55163
|
+
const { electron: electron$n } = window;
|
|
55164
|
+
function ParamTree({ params, depth = 0 }) {
|
|
55165
|
+
if (params.length === 0) {
|
|
55166
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-surface-600 italic", children: "No parameters declared in WSDL." });
|
|
55167
|
+
}
|
|
55168
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: depth === 0 ? "flex flex-col gap-0.5" : "flex flex-col gap-0.5 ml-4 border-l border-surface-800 pl-3 mt-1", children: params.map((p2, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { className: "text-[11px] font-mono", children: [
|
|
55169
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-200", children: p2.name }),
|
|
55170
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-600", children: ": " }),
|
|
55171
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-400", children: p2.typeHint }),
|
|
55172
|
+
p2.children && p2.children.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(ParamTree, { params: p2.children, depth: depth + 1 })
|
|
55173
|
+
] }, `${p2.name}-${i}`)) });
|
|
55174
|
+
}
|
|
54942
55175
|
function SoapEditor({ request, onChange }) {
|
|
54943
|
-
const soap = request.body.soap ?? {
|
|
54944
|
-
wsdlUrl: "",
|
|
54945
|
-
envelope: ""
|
|
54946
|
-
};
|
|
55176
|
+
const soap = request.body.soap ?? { wsdlUrl: "", envelope: "" };
|
|
54947
55177
|
const [operations, setOperations] = reactExports.useState([]);
|
|
55178
|
+
const [endpoints, setEndpoints] = reactExports.useState([]);
|
|
55179
|
+
const [targetNs, setTargetNs] = reactExports.useState("");
|
|
54948
55180
|
const [fetchError, setFetchError] = reactExports.useState(null);
|
|
54949
55181
|
const [fetching, setFetching] = reactExports.useState(false);
|
|
55182
|
+
const [showXml, setShowXml] = reactExports.useState(true);
|
|
55183
|
+
reactExports.useEffect(() => {
|
|
55184
|
+
const url = soap.wsdlUrl?.trim();
|
|
55185
|
+
if (!url) return;
|
|
55186
|
+
let cancelled = false;
|
|
55187
|
+
(async () => {
|
|
55188
|
+
try {
|
|
55189
|
+
const result = await electron$n.wsdlFetch(url);
|
|
55190
|
+
if (cancelled) return;
|
|
55191
|
+
setOperations(result.operations);
|
|
55192
|
+
setEndpoints(result.endpoints);
|
|
55193
|
+
setTargetNs(result.targetNamespace);
|
|
55194
|
+
} catch {
|
|
55195
|
+
}
|
|
55196
|
+
})();
|
|
55197
|
+
return () => {
|
|
55198
|
+
cancelled = true;
|
|
55199
|
+
};
|
|
55200
|
+
}, [request.id]);
|
|
54950
55201
|
function updateSoap(patch) {
|
|
54951
55202
|
onChange({ body: { ...request.body, soap: { ...soap, ...patch } } });
|
|
54952
55203
|
}
|
|
55204
|
+
function applyOperation(op) {
|
|
55205
|
+
const headers = withContentType(request.headers ?? [], contentTypeForSoap(op.soapVersion));
|
|
55206
|
+
onChange({
|
|
55207
|
+
method: "POST",
|
|
55208
|
+
headers,
|
|
55209
|
+
...op.endpoint ? { url: op.endpoint } : {},
|
|
55210
|
+
body: {
|
|
55211
|
+
...request.body,
|
|
55212
|
+
soap: {
|
|
55213
|
+
...soap,
|
|
55214
|
+
operationName: op.name,
|
|
55215
|
+
soapAction: op.soapAction ?? "",
|
|
55216
|
+
envelope: op.inputTemplate
|
|
55217
|
+
}
|
|
55218
|
+
}
|
|
55219
|
+
});
|
|
55220
|
+
}
|
|
54953
55221
|
async function fetchWsdl() {
|
|
54954
55222
|
if (!soap.wsdlUrl.trim()) return;
|
|
54955
55223
|
setFetching(true);
|
|
54956
55224
|
setFetchError(null);
|
|
54957
55225
|
try {
|
|
54958
|
-
const result = await electron$
|
|
55226
|
+
const result = await electron$n.wsdlFetch(soap.wsdlUrl.trim());
|
|
54959
55227
|
setOperations(result.operations);
|
|
55228
|
+
setEndpoints(result.endpoints);
|
|
55229
|
+
setTargetNs(result.targetNamespace);
|
|
54960
55230
|
if (result.operations.length > 0) {
|
|
54961
|
-
|
|
54962
|
-
updateSoap({
|
|
54963
|
-
operationName: first.name,
|
|
54964
|
-
soapAction: first.soapAction ?? "",
|
|
54965
|
-
envelope: first.inputTemplate
|
|
54966
|
-
});
|
|
55231
|
+
applyOperation(result.operations[0]);
|
|
54967
55232
|
}
|
|
54968
55233
|
} catch (err) {
|
|
54969
55234
|
setFetchError(err instanceof Error ? err.message : String(err));
|
|
@@ -54971,23 +55236,28 @@ function SoapEditor({ request, onChange }) {
|
|
|
54971
55236
|
setFetching(false);
|
|
54972
55237
|
}
|
|
54973
55238
|
}
|
|
54974
|
-
function selectOperation(
|
|
54975
|
-
|
|
54976
|
-
if (!op) return;
|
|
54977
|
-
updateSoap({
|
|
54978
|
-
operationName: op.name,
|
|
54979
|
-
soapAction: op.soapAction ?? soap.soapAction ?? "",
|
|
54980
|
-
envelope: op.inputTemplate
|
|
54981
|
-
});
|
|
55239
|
+
function selectOperation(op) {
|
|
55240
|
+
applyOperation(op);
|
|
54982
55241
|
}
|
|
54983
|
-
|
|
55242
|
+
const selected = operations.find((o) => o.name === soap.operationName) ?? operations[0];
|
|
55243
|
+
const primaryEndpoint = endpoints[0]?.address;
|
|
55244
|
+
const versions = Array.from(new Set(operations.map((o) => o.soapVersion))).sort();
|
|
55245
|
+
const hasSavedSoap = Boolean(soap.envelope?.trim() || soap.operationName || soap.wsdlUrl?.trim());
|
|
55246
|
+
const showFullUi = operations.length > 0;
|
|
55247
|
+
const showFallback = !showFullUi && hasSavedSoap;
|
|
55248
|
+
const showEmpty = !showFullUi && !showFallback;
|
|
55249
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3 h-full min-h-0", children: [
|
|
54984
55250
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 items-center", children: [
|
|
55251
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-[10px] uppercase tracking-wider text-surface-500 font-medium whitespace-nowrap", children: "WSDL" }),
|
|
54985
55252
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
54986
55253
|
"input",
|
|
54987
55254
|
{
|
|
54988
55255
|
value: soap.wsdlUrl,
|
|
54989
55256
|
onChange: (e) => updateSoap({ wsdlUrl: e.target.value }),
|
|
54990
|
-
placeholder: "https://example.com/service
|
|
55257
|
+
placeholder: "https://example.com/service?WSDL",
|
|
55258
|
+
onKeyDown: (e) => {
|
|
55259
|
+
if (e.key === "Enter" && !fetching) fetchWsdl();
|
|
55260
|
+
},
|
|
54991
55261
|
className: "flex-1 text-xs bg-surface-800 border border-surface-700 rounded px-2.5 py-1.5 focus:outline-none focus:border-blue-500 placeholder-surface-600 font-mono"
|
|
54992
55262
|
}
|
|
54993
55263
|
),
|
|
@@ -54997,54 +55267,141 @@ function SoapEditor({ request, onChange }) {
|
|
|
54997
55267
|
onClick: fetchWsdl,
|
|
54998
55268
|
disabled: fetching || !soap.wsdlUrl.trim(),
|
|
54999
55269
|
className: "px-3 py-1.5 text-xs bg-blue-700 hover:bg-blue-600 disabled:bg-surface-800 disabled:text-surface-600 rounded transition-colors whitespace-nowrap",
|
|
55000
|
-
children: fetching ? "Fetching…" : "Fetch WSDL"
|
|
55270
|
+
children: fetching ? "Fetching…" : operations.length > 0 ? "Refresh" : "Fetch WSDL"
|
|
55001
55271
|
}
|
|
55002
55272
|
)
|
|
55003
55273
|
] }),
|
|
55004
|
-
fetchError && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-400", children: fetchError }),
|
|
55005
|
-
operations.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "
|
|
55006
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
55007
|
-
|
|
55008
|
-
"
|
|
55009
|
-
|
|
55010
|
-
|
|
55011
|
-
|
|
55012
|
-
|
|
55013
|
-
|
|
55014
|
-
|
|
55015
|
-
|
|
55274
|
+
fetchError && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-400 bg-red-950/30 border border-red-900 rounded px-2.5 py-1.5", children: fetchError }),
|
|
55275
|
+
operations.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-surface-900/40 border border-surface-800 rounded-md px-3 py-2 text-[11px] flex flex-col gap-1", children: [
|
|
55276
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-surface-500", children: [
|
|
55277
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "uppercase tracking-wider text-[9px] font-semibold text-surface-600 w-20 shrink-0", children: "Endpoint" }),
|
|
55278
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "text-surface-200 font-mono truncate", children: primaryEndpoint ?? "(not declared)" })
|
|
55279
|
+
] }),
|
|
55280
|
+
targetNs && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-surface-500", children: [
|
|
55281
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "uppercase tracking-wider text-[9px] font-semibold text-surface-600 w-20 shrink-0", children: "Namespace" }),
|
|
55282
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "text-surface-200 font-mono truncate", children: targetNs })
|
|
55283
|
+
] }),
|
|
55284
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-surface-500", children: [
|
|
55285
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "uppercase tracking-wider text-[9px] font-semibold text-surface-600 w-20 shrink-0", children: "Operations" }),
|
|
55286
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-surface-300", children: [
|
|
55287
|
+
operations.length,
|
|
55288
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-surface-600", children: [
|
|
55289
|
+
" · SOAP ",
|
|
55290
|
+
versions.join(", ")
|
|
55291
|
+
] })
|
|
55292
|
+
] })
|
|
55293
|
+
] })
|
|
55016
55294
|
] }),
|
|
55017
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-
|
|
55018
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
55019
|
-
|
|
55020
|
-
"
|
|
55021
|
-
|
|
55022
|
-
|
|
55023
|
-
|
|
55024
|
-
|
|
55025
|
-
|
|
55026
|
-
|
|
55027
|
-
|
|
55295
|
+
showFullUi && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-3 min-h-0 flex-1", children: [
|
|
55296
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "w-44 shrink-0 flex flex-col bg-surface-900/40 border border-surface-800 rounded-md overflow-hidden", children: [
|
|
55297
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-2.5 py-1.5 text-[9px] uppercase tracking-wider font-semibold text-surface-600 border-b border-surface-800", children: "Operations" }),
|
|
55298
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "overflow-y-auto flex-1", children: operations.map((op) => {
|
|
55299
|
+
const active = selected && op.name === selected.name && op.soapVersion === selected.soapVersion;
|
|
55300
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
55301
|
+
"button",
|
|
55302
|
+
{
|
|
55303
|
+
onClick: () => selectOperation(op),
|
|
55304
|
+
className: `w-full text-left px-2.5 py-1.5 text-[11px] border-b border-surface-800/50 transition-colors ${active ? "bg-blue-900/30 text-blue-300" : "text-surface-300 hover:bg-surface-800/60"}`,
|
|
55305
|
+
children: [
|
|
55306
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono truncate", children: op.name }),
|
|
55307
|
+
op.soapVersion === "1.2" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[9px] text-surface-600 uppercase", children: "SOAP 1.2" })
|
|
55308
|
+
]
|
|
55309
|
+
},
|
|
55310
|
+
`${op.binding ?? ""}:${op.name}:${op.soapVersion}`
|
|
55311
|
+
);
|
|
55312
|
+
}) })
|
|
55313
|
+
] }),
|
|
55314
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0 flex flex-col gap-2", children: selected && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
55315
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline gap-2", children: [
|
|
55316
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold text-white font-mono", children: selected.name }),
|
|
55317
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] uppercase tracking-wider text-surface-500", children: [
|
|
55318
|
+
"SOAP ",
|
|
55319
|
+
selected.soapVersion
|
|
55320
|
+
] })
|
|
55321
|
+
] }),
|
|
55322
|
+
selected.soapAction && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[11px] text-surface-500 font-mono truncate", children: [
|
|
55323
|
+
"SOAPAction: ",
|
|
55324
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-300", children: selected.soapAction })
|
|
55325
|
+
] }),
|
|
55326
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-surface-900/40 border border-surface-800 rounded-md px-3 py-2", children: [
|
|
55327
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[9px] uppercase tracking-wider font-semibold text-surface-600 mb-1.5", children: "Inputs" }),
|
|
55328
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ParamTree, { params: selected.params ?? [] })
|
|
55329
|
+
] }),
|
|
55330
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
|
|
55331
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[9px] uppercase tracking-wider font-semibold text-surface-600", children: "Envelope" }),
|
|
55332
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
55333
|
+
"button",
|
|
55334
|
+
{
|
|
55335
|
+
onClick: () => setShowXml((v) => !v),
|
|
55336
|
+
className: "text-[10px] text-surface-500 hover:text-surface-300 transition-colors",
|
|
55337
|
+
children: showXml ? "▾ Hide XML" : "▸ Edit XML"
|
|
55338
|
+
}
|
|
55339
|
+
)
|
|
55340
|
+
] }),
|
|
55341
|
+
!showXml && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[10px] text-surface-600 leading-relaxed", children: [
|
|
55342
|
+
"Envelope auto-generated from the operation's input parameters. Method (POST), endpoint URL, and Content-Type are managed for you. Click ",
|
|
55343
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("em", { children: "Edit XML" }),
|
|
55344
|
+
" to tweak."
|
|
55345
|
+
] }),
|
|
55346
|
+
showXml && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded overflow-hidden border border-surface-700 flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
55347
|
+
ReactCodeMirror,
|
|
55348
|
+
{
|
|
55349
|
+
value: soap.envelope ?? "",
|
|
55350
|
+
height: "100%",
|
|
55351
|
+
theme: oneDark,
|
|
55352
|
+
extensions: [xml()],
|
|
55353
|
+
onChange: (val) => updateSoap({ envelope: val }),
|
|
55354
|
+
basicSetup: { lineNumbers: true, foldGutter: true }
|
|
55355
|
+
}
|
|
55356
|
+
) })
|
|
55357
|
+
] }) })
|
|
55028
55358
|
] }),
|
|
55029
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
55030
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
55031
|
-
|
|
55359
|
+
showFallback && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 flex-1 min-h-0", children: [
|
|
55360
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-surface-900/40 border border-surface-800 rounded-md px-3 py-2 text-[11px] flex items-center gap-3", children: [
|
|
55361
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
55362
|
+
soap.operationName && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-mono text-surface-200 truncate", children: soap.operationName }),
|
|
55363
|
+
soap.soapAction && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-[10px] text-surface-500 truncate", children: [
|
|
55364
|
+
"SOAPAction: ",
|
|
55365
|
+
soap.soapAction
|
|
55366
|
+
] }),
|
|
55367
|
+
!soap.operationName && !soap.soapAction && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] text-surface-500", children: soap.wsdlUrl?.trim() ? "WSDL not loaded — the saved envelope below is still sent on Send." : "No WSDL — hand-crafted SOAP envelope." })
|
|
55368
|
+
] }),
|
|
55369
|
+
soap.wsdlUrl?.trim() && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
55370
|
+
"button",
|
|
55371
|
+
{
|
|
55372
|
+
onClick: fetchWsdl,
|
|
55373
|
+
disabled: fetching,
|
|
55374
|
+
className: "px-2.5 py-1 text-[11px] bg-surface-800 hover:bg-surface-700 disabled:opacity-50 rounded transition-colors whitespace-nowrap",
|
|
55375
|
+
children: fetching ? "Loading…" : "Reload WSDL"
|
|
55376
|
+
}
|
|
55377
|
+
)
|
|
55378
|
+
] }),
|
|
55379
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded overflow-hidden border border-surface-700 flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
55032
55380
|
ReactCodeMirror,
|
|
55033
55381
|
{
|
|
55034
55382
|
value: soap.envelope ?? "",
|
|
55035
|
-
height: "
|
|
55383
|
+
height: "100%",
|
|
55036
55384
|
theme: oneDark,
|
|
55037
55385
|
extensions: [xml()],
|
|
55038
55386
|
onChange: (val) => updateSoap({ envelope: val }),
|
|
55039
55387
|
basicSetup: { lineNumbers: true, foldGutter: true }
|
|
55040
55388
|
}
|
|
55041
55389
|
) })
|
|
55390
|
+
] }),
|
|
55391
|
+
showEmpty && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col items-center justify-center text-center gap-2 border border-dashed border-surface-800 rounded-md py-8 px-4", children: [
|
|
55392
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-surface-400", children: [
|
|
55393
|
+
"Paste a WSDL URL above and click ",
|
|
55394
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("em", { children: "Fetch WSDL" }),
|
|
55395
|
+
"."
|
|
55396
|
+
] }),
|
|
55397
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-surface-600 max-w-sm", children: "The endpoint, SOAP version, Content-Type header, and per-operation envelope are derived from the WSDL — you only pick the operation and fill the parameters." })
|
|
55042
55398
|
] })
|
|
55043
55399
|
] });
|
|
55044
55400
|
}
|
|
55045
55401
|
function BodyTab({ request, onChange }) {
|
|
55046
55402
|
const body = request.body;
|
|
55047
55403
|
const mode = body.mode;
|
|
55404
|
+
const isSoap = request.protocol === "soap";
|
|
55048
55405
|
const varNames = useVarNames();
|
|
55049
55406
|
const varValues = useVarValues();
|
|
55050
55407
|
const varExt = reactExports.useMemo(
|
|
@@ -55054,6 +55411,9 @@ function BodyTab({ request, onChange }) {
|
|
|
55054
55411
|
function setMode(m) {
|
|
55055
55412
|
onChange({ body: { ...body, mode: m } });
|
|
55056
55413
|
}
|
|
55414
|
+
if (isSoap) {
|
|
55415
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col h-full min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SoapEditor, { request, onChange }) });
|
|
55416
|
+
}
|
|
55057
55417
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2 h-full min-h-0", children: [
|
|
55058
55418
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-3 text-xs flex-shrink-0", children: ["none", "json", "form", "raw", "graphql", "soap"].map((m) => /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-1 cursor-pointer", children: [
|
|
55059
55419
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -55133,7 +55493,7 @@ function BodyTab({ request, onChange }) {
|
|
|
55133
55493
|
mode === "soap" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SoapEditor, { request, onChange }) })
|
|
55134
55494
|
] });
|
|
55135
55495
|
}
|
|
55136
|
-
const { electron: electron$
|
|
55496
|
+
const { electron: electron$m } = window;
|
|
55137
55497
|
const AUTH_TYPES = ["none", "bearer", "basic", "digest", "ntlm", "apikey", "oauth2"];
|
|
55138
55498
|
function AuthTab({ request, onChange }) {
|
|
55139
55499
|
const auth = request.auth;
|
|
@@ -55147,7 +55507,7 @@ function AuthTab({ request, onChange }) {
|
|
|
55147
55507
|
}
|
|
55148
55508
|
async function saveSecret(ref2) {
|
|
55149
55509
|
if (!secretValue || !ref2) return;
|
|
55150
|
-
await electron$
|
|
55510
|
+
await electron$m.setSecret(ref2, secretValue);
|
|
55151
55511
|
setSaved(true);
|
|
55152
55512
|
setSecretValue("");
|
|
55153
55513
|
setTimeout(() => setSaved(false), 2e3);
|
|
@@ -55159,7 +55519,7 @@ function AuthTab({ request, onChange }) {
|
|
|
55159
55519
|
setOauth2Error("");
|
|
55160
55520
|
try {
|
|
55161
55521
|
const vars = {};
|
|
55162
|
-
const result = await electron$
|
|
55522
|
+
const result = await electron$m.oauth2StartFlow(oauth2Auth, vars);
|
|
55163
55523
|
setAuth({
|
|
55164
55524
|
oauth2CachedToken: result.accessToken,
|
|
55165
55525
|
oauth2TokenExpiry: result.expiresAt
|
|
@@ -55177,7 +55537,7 @@ function AuthTab({ request, onChange }) {
|
|
|
55177
55537
|
setOauth2Status("fetching");
|
|
55178
55538
|
setOauth2Error("");
|
|
55179
55539
|
try {
|
|
55180
|
-
const result = await electron$
|
|
55540
|
+
const result = await electron$m.oauth2RefreshToken(oauth2Auth, {}, oauth2RefreshToken);
|
|
55181
55541
|
setAuth({
|
|
55182
55542
|
oauth2CachedToken: result.accessToken,
|
|
55183
55543
|
oauth2TokenExpiry: result.expiresAt
|
|
@@ -56418,12 +56778,13 @@ function ScriptsTab({ request, onChange }) {
|
|
|
56418
56778
|
const activeTabId = useStore((s) => s.activeTabId);
|
|
56419
56779
|
const activeAppTab = useStore((s) => s.tabs.find((t2) => t2.id === s.activeTabId));
|
|
56420
56780
|
const setTabScriptTab = useStore((s) => s.setTabScriptTab);
|
|
56421
|
-
const scriptType = activeAppTab?.scriptTab ?? "
|
|
56781
|
+
const scriptType = activeAppTab?.scriptTab ?? "post";
|
|
56422
56782
|
const setScriptType = (t2) => {
|
|
56423
56783
|
if (activeTabId) setTabScriptTab(activeTabId, t2);
|
|
56424
56784
|
};
|
|
56425
56785
|
const [expandedGroup, setExpandedGroup] = reactExports.useState(SNIPPET_GROUPS[0].group);
|
|
56426
|
-
const
|
|
56786
|
+
const snippetsOpen = useStore((s) => s.quickInsertsOpen);
|
|
56787
|
+
const setSnippetsOpen = useStore((s) => s.setQuickInsertsOpen);
|
|
56427
56788
|
const varNames = useVarNames();
|
|
56428
56789
|
const varValues = useVarValues();
|
|
56429
56790
|
const extensions = reactExports.useMemo(
|
|
@@ -62791,7 +63152,7 @@ function SchemaTab({ request, onChange }) {
|
|
|
62791
63152
|
] }) })
|
|
62792
63153
|
] });
|
|
62793
63154
|
}
|
|
62794
|
-
const { electron: electron$
|
|
63155
|
+
const { electron: electron$l } = window;
|
|
62795
63156
|
const EMPTY = { statusCode: 200, headers: [], bodySchema: "" };
|
|
62796
63157
|
function ContractTab({ request, onChange }) {
|
|
62797
63158
|
const activeTab = useStore((s) => s.tabs.find((t2) => t2.id === s.activeTabId));
|
|
@@ -62805,7 +63166,7 @@ function ContractTab({ request, onChange }) {
|
|
|
62805
63166
|
if (!lastResponse?.body) return;
|
|
62806
63167
|
setInferring(true);
|
|
62807
63168
|
try {
|
|
62808
|
-
const schema = await electron$
|
|
63169
|
+
const schema = await electron$l.inferContractSchema(lastResponse.body);
|
|
62809
63170
|
if (schema) update({ bodySchema: schema });
|
|
62810
63171
|
} finally {
|
|
62811
63172
|
setInferring(false);
|
|
@@ -62931,7 +63292,7 @@ function ContractTab({ request, onChange }) {
|
|
|
62931
63292
|
] })
|
|
62932
63293
|
] });
|
|
62933
63294
|
}
|
|
62934
|
-
const { electron: electron$
|
|
63295
|
+
const { electron: electron$k } = window;
|
|
62935
63296
|
function formatTime$1(ts) {
|
|
62936
63297
|
const d = new Date(ts);
|
|
62937
63298
|
const hh = String(d.getHours()).padStart(2, "0");
|
|
@@ -62951,14 +63312,14 @@ function WebSocketPanel({ request }) {
|
|
|
62951
63312
|
const [sendText, setSendText] = reactExports.useState("");
|
|
62952
63313
|
const logEndRef = reactExports.useRef(null);
|
|
62953
63314
|
reactExports.useEffect(() => {
|
|
62954
|
-
electron$
|
|
63315
|
+
electron$k.onWsMessage(({ requestId, message }) => {
|
|
62955
63316
|
addWsMessage(requestId, message);
|
|
62956
63317
|
});
|
|
62957
|
-
electron$
|
|
63318
|
+
electron$k.onWsStatus(({ requestId, status, error: error2 }) => {
|
|
62958
63319
|
setWsStatus(requestId, status, error2);
|
|
62959
63320
|
});
|
|
62960
63321
|
return () => {
|
|
62961
|
-
electron$
|
|
63322
|
+
electron$k.offWsEvents();
|
|
62962
63323
|
};
|
|
62963
63324
|
}, [addWsMessage, setWsStatus]);
|
|
62964
63325
|
reactExports.useEffect(() => {
|
|
@@ -62971,19 +63332,19 @@ function WebSocketPanel({ request }) {
|
|
|
62971
63332
|
if (h.enabled && h.key) headers[h.key] = h.value;
|
|
62972
63333
|
}
|
|
62973
63334
|
try {
|
|
62974
|
-
await electron$
|
|
63335
|
+
await electron$k.wsConnect(request.id, request.url, headers);
|
|
62975
63336
|
} catch (err) {
|
|
62976
63337
|
setWsStatus(request.id, "error", err instanceof Error ? err.message : String(err));
|
|
62977
63338
|
}
|
|
62978
63339
|
}
|
|
62979
63340
|
async function disconnect() {
|
|
62980
|
-
await electron$
|
|
63341
|
+
await electron$k.wsDisconnect(request.id);
|
|
62981
63342
|
}
|
|
62982
63343
|
async function sendMessage() {
|
|
62983
63344
|
const text = sendText.trim();
|
|
62984
63345
|
if (!text || !isConnected) return;
|
|
62985
63346
|
try {
|
|
62986
|
-
await electron$
|
|
63347
|
+
await electron$k.wsSend(request.id, text);
|
|
62987
63348
|
const msg = {
|
|
62988
63349
|
id: crypto.randomUUID(),
|
|
62989
63350
|
direction: "sent",
|
|
@@ -63086,7 +63447,7 @@ function WebSocketPanel({ request }) {
|
|
|
63086
63447
|
] })
|
|
63087
63448
|
] });
|
|
63088
63449
|
}
|
|
63089
|
-
const { electron: electron$
|
|
63450
|
+
const { electron: electron$j } = window;
|
|
63090
63451
|
const METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
|
|
63091
63452
|
const METHOD_COLORS = {
|
|
63092
63453
|
GET: "text-emerald-400",
|
|
@@ -63173,7 +63534,7 @@ function RequestBuilder({ request }) {
|
|
|
63173
63534
|
try {
|
|
63174
63535
|
const hookEnv = activeEnvironmentId ? useStore.getState().environments[activeEnvironmentId]?.data ?? null : null;
|
|
63175
63536
|
const hookSessionVars = useStore.getState().sessionVars;
|
|
63176
|
-
const r = await electron$
|
|
63537
|
+
const r = await electron$j.sendRequest({
|
|
63177
63538
|
...basePayload,
|
|
63178
63539
|
environment: hookEnv,
|
|
63179
63540
|
request: hook,
|
|
@@ -63214,7 +63575,7 @@ function RequestBuilder({ request }) {
|
|
|
63214
63575
|
}
|
|
63215
63576
|
const freshEnv = activeEnvironmentId ? useStore.getState().environments[activeEnvironmentId]?.data ?? null : null;
|
|
63216
63577
|
const freshSessionVars = useStore.getState().sessionVars;
|
|
63217
|
-
const result = await electron$
|
|
63578
|
+
const result = await electron$j.sendRequest({
|
|
63218
63579
|
...basePayload,
|
|
63219
63580
|
environment: freshEnv,
|
|
63220
63581
|
request: mergedRequest,
|
|
@@ -63239,7 +63600,7 @@ function RequestBuilder({ request }) {
|
|
|
63239
63600
|
try {
|
|
63240
63601
|
const hookEnv = activeEnvironmentId ? useStore.getState().environments[activeEnvironmentId]?.data ?? null : null;
|
|
63241
63602
|
const hookSessionVars = useStore.getState().sessionVars;
|
|
63242
|
-
const r = await electron$
|
|
63603
|
+
const r = await electron$j.sendRequest({
|
|
63243
63604
|
...basePayload,
|
|
63244
63605
|
environment: hookEnv,
|
|
63245
63606
|
request: hook,
|
|
@@ -63288,11 +63649,13 @@ function RequestBuilder({ request }) {
|
|
|
63288
63649
|
const hasPreScript = Boolean(request.preRequestScript?.trim());
|
|
63289
63650
|
const hasPostScript = Boolean(request.postRequestScript?.trim());
|
|
63290
63651
|
const isWs = request.protocol === "websocket";
|
|
63652
|
+
const isSoap = request.protocol === "soap";
|
|
63291
63653
|
const tabs = [
|
|
63292
|
-
|
|
63654
|
+
// SOAP collapses Params + Body into a single "SOAP" tab — the WSDL drives both.
|
|
63655
|
+
...!isSoap ? [{ id: "params", label: "Params", count: request.params.filter((p2) => p2.enabled && p2.key).length }] : [],
|
|
63293
63656
|
{ id: "headers", label: "Headers", count: request.headers.filter((h) => h.enabled && h.key).length },
|
|
63294
63657
|
...!isWs ? [
|
|
63295
|
-
{ id: "body", label: "Body", count: request.body.mode !== "none" ? 1 : 0 },
|
|
63658
|
+
{ id: "body", label: isSoap ? "SOAP" : "Body", count: request.body.mode !== "none" ? 1 : 0 },
|
|
63296
63659
|
{ id: "auth", label: "Auth", count: request.auth.type !== "none" ? 1 : 0 },
|
|
63297
63660
|
{ id: "scripts", label: "Scripts", count: (hasPreScript ? 1 : 0) + (hasPostScript ? 1 : 0) },
|
|
63298
63661
|
{ id: "schema", label: "Schema", count: request.schema?.trim() ? 1 : 0 },
|
|
@@ -63324,7 +63687,7 @@ function RequestBuilder({ request }) {
|
|
|
63324
63687
|
"button",
|
|
63325
63688
|
{
|
|
63326
63689
|
onClick: () => update({ protocol: "http" }),
|
|
63327
|
-
className: `px-2 py-1.5 transition-colors ${
|
|
63690
|
+
className: `px-2 py-1.5 transition-colors ${request.protocol !== "websocket" && request.protocol !== "soap" ? "bg-blue-600 text-white" : "text-surface-500 hover:text-white"}`,
|
|
63328
63691
|
title: "HTTP request",
|
|
63329
63692
|
children: "HTTP"
|
|
63330
63693
|
}
|
|
@@ -63337,9 +63700,25 @@ function RequestBuilder({ request }) {
|
|
|
63337
63700
|
title: "WebSocket",
|
|
63338
63701
|
children: "WS"
|
|
63339
63702
|
}
|
|
63703
|
+
),
|
|
63704
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
63705
|
+
"button",
|
|
63706
|
+
{
|
|
63707
|
+
onClick: () => {
|
|
63708
|
+
update({
|
|
63709
|
+
protocol: "soap",
|
|
63710
|
+
method: "POST",
|
|
63711
|
+
body: request.body.mode === "soap" ? request.body : { ...request.body, mode: "soap", soap: request.body.soap ?? { wsdlUrl: "", envelope: "" } }
|
|
63712
|
+
});
|
|
63713
|
+
if (activeTabId) setTabRequestTab(activeTabId, "body");
|
|
63714
|
+
},
|
|
63715
|
+
className: `px-2 py-1.5 transition-colors ${isSoap ? "bg-amber-700 text-amber-100" : "text-surface-500 hover:text-white"}`,
|
|
63716
|
+
title: "SOAP — endpoint and method are derived from the WSDL",
|
|
63717
|
+
children: "SOAP"
|
|
63718
|
+
}
|
|
63340
63719
|
)
|
|
63341
63720
|
] }),
|
|
63342
|
-
!isWs && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
63721
|
+
!isWs && !isSoap && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
63343
63722
|
"select",
|
|
63344
63723
|
{
|
|
63345
63724
|
value: request.method,
|
|
@@ -63348,14 +63727,22 @@ function RequestBuilder({ request }) {
|
|
|
63348
63727
|
children: METHODS.map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: m, className: "text-white", children: m }, m))
|
|
63349
63728
|
}
|
|
63350
63729
|
),
|
|
63730
|
+
isSoap && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
63731
|
+
"span",
|
|
63732
|
+
{
|
|
63733
|
+
className: "bg-surface-900 border border-surface-700 rounded px-2 py-1.5 text-xs font-bold text-amber-400 select-none",
|
|
63734
|
+
title: "SOAP requests are always POST",
|
|
63735
|
+
children: "POST"
|
|
63736
|
+
}
|
|
63737
|
+
),
|
|
63351
63738
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
63352
63739
|
VarInput,
|
|
63353
63740
|
{
|
|
63354
63741
|
value: request.url,
|
|
63355
63742
|
onChange: (url) => update({ url }),
|
|
63356
|
-
placeholder: isWs ? "ws://example.com/socket" : "https://api.example.com/endpoint",
|
|
63743
|
+
placeholder: isWs ? "ws://example.com/socket" : isSoap ? "Endpoint (auto-filled from WSDL <soap:address>)" : "https://api.example.com/endpoint",
|
|
63357
63744
|
wrapperClassName: "flex-1",
|
|
63358
|
-
className:
|
|
63745
|
+
className: `border rounded px-3 py-1.5 text-sm focus:outline-none focus:border-blue-500 font-mono placeholder-surface-700 ${isSoap ? "bg-surface-900 border-amber-900/50 text-surface-300" : "bg-surface-800 border-surface-700"}`
|
|
63359
63746
|
}
|
|
63360
63747
|
),
|
|
63361
63748
|
!isWs && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
@@ -63976,7 +64363,7 @@ function HookResultsPanel({ results }) {
|
|
|
63976
64363
|
}) })
|
|
63977
64364
|
] });
|
|
63978
64365
|
}
|
|
63979
|
-
const { electron: electron$
|
|
64366
|
+
const { electron: electron$i } = window;
|
|
63980
64367
|
function extractPath(url) {
|
|
63981
64368
|
try {
|
|
63982
64369
|
return new URL(url).pathname || "/";
|
|
@@ -64030,14 +64417,14 @@ function SaveAsMockModal({ onClose }) {
|
|
|
64030
64417
|
const entry = state.mocks[serverId];
|
|
64031
64418
|
const updated = { ...entry.data, name: newServerName, port: Number(newServerPort), routes: [route] };
|
|
64032
64419
|
updateMock(serverId, updated);
|
|
64033
|
-
await electron$
|
|
64420
|
+
await electron$i.saveMock(entry.relPath, updated);
|
|
64034
64421
|
const ws2 = useStore.getState().workspace;
|
|
64035
|
-
if (ws2) await electron$
|
|
64422
|
+
if (ws2) await electron$i.saveWorkspace(ws2);
|
|
64036
64423
|
} else {
|
|
64037
64424
|
const entry = useStore.getState().mocks[serverId];
|
|
64038
64425
|
const updated = { ...entry.data, routes: [...entry.data.routes, route] };
|
|
64039
64426
|
updateMock(serverId, updated);
|
|
64040
|
-
await electron$
|
|
64427
|
+
await electron$i.saveMock(entry.relPath, updated);
|
|
64041
64428
|
}
|
|
64042
64429
|
onClose();
|
|
64043
64430
|
} finally {
|
|
@@ -64298,19 +64685,24 @@ function TestsPanel({ scriptResult }) {
|
|
|
64298
64685
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-400 text-xs font-bold shrink-0", children: "POST-SCRIPT ERROR" }),
|
|
64299
64686
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-300 text-xs font-mono", children: sr.postScriptError })
|
|
64300
64687
|
] }),
|
|
64301
|
-
sr.testResults.map((result, i) =>
|
|
64302
|
-
|
|
64303
|
-
|
|
64304
|
-
|
|
64305
|
-
|
|
64306
|
-
|
|
64307
|
-
|
|
64308
|
-
|
|
64309
|
-
|
|
64310
|
-
|
|
64311
|
-
|
|
64312
|
-
|
|
64313
|
-
|
|
64688
|
+
sr.testResults.map((result, i) => (
|
|
64689
|
+
// Pass uses the bright lime-400 border at 50% (was: dark olive-800
|
|
64690
|
+
// border on near-invisible 20% bg) so the green test row actually
|
|
64691
|
+
// reads as green in dark mode.
|
|
64692
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
64693
|
+
"div",
|
|
64694
|
+
{
|
|
64695
|
+
className: `flex items-start gap-2 p-2 rounded border ${result.passed ? "bg-emerald-800/30 border-emerald-400/50" : "bg-red-900/30 border-red-700"}`,
|
|
64696
|
+
children: [
|
|
64697
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `text-xs font-bold shrink-0 ${result.passed ? "text-emerald-400" : "text-red-400"}`, children: result.passed ? "✓" : "✗" }),
|
|
64698
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
64699
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-white", children: result.name }),
|
|
64700
|
+
result.error && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] text-red-300 font-mono", children: result.error })
|
|
64701
|
+
] })
|
|
64702
|
+
]
|
|
64703
|
+
},
|
|
64704
|
+
i
|
|
64705
|
+
)
|
|
64314
64706
|
))
|
|
64315
64707
|
] });
|
|
64316
64708
|
}
|
|
@@ -64367,7 +64759,7 @@ function ConsolePanel({ scriptResult }) {
|
|
|
64367
64759
|
)) })
|
|
64368
64760
|
] });
|
|
64369
64761
|
}
|
|
64370
|
-
const { electron: electron$
|
|
64762
|
+
const { electron: electron$h } = window;
|
|
64371
64763
|
function ResponseViewer() {
|
|
64372
64764
|
const activeTab = useStore((s) => s.tabs.find((t2) => t2.id === s.activeTabId));
|
|
64373
64765
|
const activeTabId = useStore((s) => s.activeTabId);
|
|
@@ -64395,7 +64787,7 @@ function ResponseViewer() {
|
|
|
64395
64787
|
const [contractToast, setContractToast] = reactExports.useState(false);
|
|
64396
64788
|
async function saveAsContract() {
|
|
64397
64789
|
if (!response || !requestId || !activeTabId) return;
|
|
64398
|
-
const schema = response.body ? await electron$
|
|
64790
|
+
const schema = response.body ? await electron$h.inferContractSchema(response.body) : null;
|
|
64399
64791
|
const contentType2 = response.headers["content-type"];
|
|
64400
64792
|
const headers = contentType2 ? [{ key: "content-type", value: contentType2, required: true }] : [];
|
|
64401
64793
|
updateRequest(requestId, {
|
|
@@ -64420,6 +64812,7 @@ function ResponseViewer() {
|
|
|
64420
64812
|
setTabRequestTab(activeTabId, "scripts");
|
|
64421
64813
|
setTabScriptTab(activeTabId, "post");
|
|
64422
64814
|
}
|
|
64815
|
+
state.setQuickInsertsOpen(false);
|
|
64423
64816
|
setAssertToast(true);
|
|
64424
64817
|
setTimeout(() => setAssertToast(false), 2500);
|
|
64425
64818
|
}
|
|
@@ -64563,7 +64956,7 @@ function ResponseViewer() {
|
|
|
64563
64956
|
] }, k)) }) }) }) : tab === "tests" ? /* @__PURE__ */ jsxRuntimeExports.jsx(TestsPanel, { scriptResult }) : tab === "console" ? /* @__PURE__ */ jsxRuntimeExports.jsx(ConsolePanel, { scriptResult }) : tab === "request" ? /* @__PURE__ */ jsxRuntimeExports.jsx(RequestPanel, { sentRequest }) : null })
|
|
64564
64957
|
] });
|
|
64565
64958
|
}
|
|
64566
|
-
const { electron: electron$
|
|
64959
|
+
const { electron: electron$g } = window;
|
|
64567
64960
|
const TARGETS = [
|
|
64568
64961
|
{ id: "robot_framework", label: "Robot Framework", description: "Python RequestsLibrary keywords + test suite" },
|
|
64569
64962
|
{ id: "playwright_ts", label: "Playwright TS", description: "TypeScript page-object API classes + spec files" },
|
|
@@ -64601,7 +64994,7 @@ function GeneratorPanel() {
|
|
|
64601
64994
|
try {
|
|
64602
64995
|
const col = collections[selectedCollectionId]?.data;
|
|
64603
64996
|
const env = activeEnvironmentId ? environments[activeEnvironmentId]?.data ?? null : null;
|
|
64604
|
-
const generated = await electron$
|
|
64997
|
+
const generated = await electron$g.generateCode({ collection: col, environment: env, target });
|
|
64605
64998
|
setFiles(generated);
|
|
64606
64999
|
setSelectedFile(generated[0]?.path ?? null);
|
|
64607
65000
|
} catch (e) {
|
|
@@ -64613,7 +65006,7 @@ function GeneratorPanel() {
|
|
|
64613
65006
|
async function saveZip() {
|
|
64614
65007
|
if (files.length === 0) return;
|
|
64615
65008
|
const col = collections[selectedCollectionId]?.data;
|
|
64616
|
-
await electron$
|
|
65009
|
+
await electron$g.saveGeneratedFilesAsZip(files, col?.name ?? "api-tests", target);
|
|
64617
65010
|
}
|
|
64618
65011
|
const selectedContent = files.find((f) => f.path === selectedFile)?.content ?? "";
|
|
64619
65012
|
const activeTarget = TARGETS.find((t2) => t2.id === target);
|
|
@@ -64837,16 +65230,16 @@ function HistoryRow({
|
|
|
64837
65230
|
}
|
|
64838
65231
|
);
|
|
64839
65232
|
}
|
|
64840
|
-
const { electron: electron$
|
|
65233
|
+
const { electron: electron$f } = window;
|
|
64841
65234
|
function WelcomeScreen() {
|
|
64842
65235
|
const { applyWorkspace } = useWorkspaceLoader();
|
|
64843
65236
|
async function openWorkspace() {
|
|
64844
|
-
const result = await electron$
|
|
65237
|
+
const result = await electron$f.openWorkspace();
|
|
64845
65238
|
if (!result) return;
|
|
64846
65239
|
await applyWorkspace(result.workspace, result.workspacePath);
|
|
64847
65240
|
}
|
|
64848
65241
|
async function newWorkspace() {
|
|
64849
|
-
const result = await electron$
|
|
65242
|
+
const result = await electron$f.newWorkspace();
|
|
64850
65243
|
if (!result) return;
|
|
64851
65244
|
await applyWorkspace(result.workspace, result.workspacePath);
|
|
64852
65245
|
}
|
|
@@ -64897,7 +65290,7 @@ function WelcomeScreen() {
|
|
|
64897
65290
|
] })
|
|
64898
65291
|
] });
|
|
64899
65292
|
}
|
|
64900
|
-
const { electron: electron$
|
|
65293
|
+
const { electron: electron$e } = window;
|
|
64901
65294
|
const EXAMPLES = [
|
|
64902
65295
|
{
|
|
64903
65296
|
label: "macOS / Linux (~/.zshrc or ~/.bashrc)",
|
|
@@ -64916,12 +65309,12 @@ function MasterKeyModal({ onSuccess, onCancel }) {
|
|
|
64916
65309
|
const [password, setPassword] = reactExports.useState("");
|
|
64917
65310
|
const [error2, setError] = reactExports.useState("");
|
|
64918
65311
|
const [copied, setCopied] = reactExports.useState(null);
|
|
64919
|
-
async function
|
|
65312
|
+
async function confirm2() {
|
|
64920
65313
|
if (!password.trim()) {
|
|
64921
65314
|
setError("Password cannot be empty.");
|
|
64922
65315
|
return;
|
|
64923
65316
|
}
|
|
64924
|
-
await electron$
|
|
65317
|
+
await electron$e.setMasterKey(password);
|
|
64925
65318
|
onSuccess(password);
|
|
64926
65319
|
}
|
|
64927
65320
|
function copy(idx, text) {
|
|
@@ -64962,7 +65355,7 @@ function MasterKeyModal({ onSuccess, onCancel }) {
|
|
|
64962
65355
|
setPassword(e.target.value);
|
|
64963
65356
|
setError("");
|
|
64964
65357
|
},
|
|
64965
|
-
onKeyDown: (e) => e.key === "Enter" &&
|
|
65358
|
+
onKeyDown: (e) => e.key === "Enter" && confirm2(),
|
|
64966
65359
|
placeholder: "Enter master password…",
|
|
64967
65360
|
className: "bg-surface-800 border border-surface-700 rounded px-3 py-1.5 text-sm font-mono focus:outline-none focus:border-blue-500"
|
|
64968
65361
|
}
|
|
@@ -64998,7 +65391,7 @@ function MasterKeyModal({ onSuccess, onCancel }) {
|
|
|
64998
65391
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
64999
65392
|
"button",
|
|
65000
65393
|
{
|
|
65001
|
-
onClick:
|
|
65394
|
+
onClick: confirm2,
|
|
65002
65395
|
disabled: !password.trim(),
|
|
65003
65396
|
className: "px-3 py-1.5 text-xs bg-blue-600 hover:bg-blue-500 disabled:opacity-40 rounded transition-colors",
|
|
65004
65397
|
children: "Set Password & Continue"
|
|
@@ -65011,7 +65404,7 @@ function MasterKeyModal({ onSuccess, onCancel }) {
|
|
|
65011
65404
|
}
|
|
65012
65405
|
);
|
|
65013
65406
|
}
|
|
65014
|
-
const { electron: electron$
|
|
65407
|
+
const { electron: electron$d } = window;
|
|
65015
65408
|
async function shortHash(value) {
|
|
65016
65409
|
const buf = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(value));
|
|
65017
65410
|
return Array.from(new Uint8Array(buf)).map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, 8);
|
|
@@ -65057,6 +65450,7 @@ function EnvironmentEditor({ onClose }) {
|
|
|
65057
65450
|
const [pendingEncryptIdx, setPendingEncryptIdx] = reactExports.useState(null);
|
|
65058
65451
|
const [nameError, setNameError] = reactExports.useState(null);
|
|
65059
65452
|
const deleteEnvironment = useStore((s) => s.deleteEnvironment);
|
|
65453
|
+
const duplicateEnvironment = useStore((s) => s.duplicateEnvironment);
|
|
65060
65454
|
const envList = Object.values(environments);
|
|
65061
65455
|
const env = selectedId ? environments[selectedId]?.data ?? null : null;
|
|
65062
65456
|
function handleDelete(id2) {
|
|
@@ -65064,6 +65458,11 @@ function EnvironmentEditor({ onClose }) {
|
|
|
65064
65458
|
const remaining = Object.keys(environments).filter((k) => k !== id2);
|
|
65065
65459
|
setSelectedId(remaining[0] ?? "");
|
|
65066
65460
|
}
|
|
65461
|
+
function handleDuplicate(id2) {
|
|
65462
|
+
duplicateEnvironment(id2);
|
|
65463
|
+
const next = Object.keys(useStore.getState().environments).at(-1);
|
|
65464
|
+
if (next) setSelectedId(next);
|
|
65465
|
+
}
|
|
65067
65466
|
function updateVar(idx, patch) {
|
|
65068
65467
|
if (!env) return;
|
|
65069
65468
|
const vars = env.variables.map((v, i) => i === idx ? { ...v, ...patch } : v);
|
|
@@ -65112,7 +65511,7 @@ function EnvironmentEditor({ onClose }) {
|
|
|
65112
65511
|
async function saveEncrypted(idx) {
|
|
65113
65512
|
const plaintext = secretInputs[idx] ?? "";
|
|
65114
65513
|
if (!plaintext) return;
|
|
65115
|
-
const { set: set2 } = await electron$
|
|
65514
|
+
const { set: set2 } = await electron$d.checkMasterKey();
|
|
65116
65515
|
if (!set2) {
|
|
65117
65516
|
setPendingEncryptIdx(idx);
|
|
65118
65517
|
return;
|
|
@@ -65149,9 +65548,9 @@ function EnvironmentEditor({ onClose }) {
|
|
|
65149
65548
|
} : state.workspace
|
|
65150
65549
|
}));
|
|
65151
65550
|
const ws2 = useStore.getState().workspace;
|
|
65152
|
-
if (ws2) await electron$
|
|
65551
|
+
if (ws2) await electron$d.saveWorkspace(ws2);
|
|
65153
65552
|
}
|
|
65154
|
-
await electron$
|
|
65553
|
+
await electron$d.saveEnvironment(newRelPath, env);
|
|
65155
65554
|
}
|
|
65156
65555
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
65157
65556
|
pendingEncryptIdx !== null && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -65190,6 +65589,15 @@ function EnvironmentEditor({ onClose }) {
|
|
|
65190
65589
|
children: e.name
|
|
65191
65590
|
}
|
|
65192
65591
|
),
|
|
65592
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65593
|
+
"button",
|
|
65594
|
+
{
|
|
65595
|
+
onClick: () => handleDuplicate(e.id),
|
|
65596
|
+
className: "opacity-0 group-hover:opacity-100 text-surface-400 hover:text-white transition-all px-1 text-xs leading-none shrink-0",
|
|
65597
|
+
title: "Duplicate environment",
|
|
65598
|
+
children: "⧉"
|
|
65599
|
+
}
|
|
65600
|
+
),
|
|
65193
65601
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65194
65602
|
"button",
|
|
65195
65603
|
{
|
|
@@ -65239,135 +65647,141 @@ function EnvironmentEditor({ onClose }) {
|
|
|
65239
65647
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("table", { className: "w-full text-xs", children: [
|
|
65240
65648
|
/* @__PURE__ */ jsxRuntimeExports.jsx("thead", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { className: "text-surface-400 text-left border-b border-surface-800", children: [
|
|
65241
65649
|
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-3 py-2 w-8", children: "On" }),
|
|
65242
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-2 py-2 w-
|
|
65650
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-2 py-2 w-56", children: "Variable" }),
|
|
65243
65651
|
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-2 py-2", children: "Value / Encrypted / Env var" }),
|
|
65244
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-2 py-2 w-44", children: "Description" }),
|
|
65245
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-2 py-2 w-20 text-center", children: "Source" }),
|
|
65246
65652
|
/* @__PURE__ */ jsxRuntimeExports.jsx("th", { className: "px-2 py-2 w-6" })
|
|
65247
65653
|
] }) }),
|
|
65248
|
-
|
|
65654
|
+
env.variables.map((v, idx) => {
|
|
65249
65655
|
const mode = getSourceMode(v);
|
|
65250
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("
|
|
65251
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
65252
|
-
"
|
|
65253
|
-
{
|
|
65254
|
-
type: "checkbox",
|
|
65255
|
-
checked: v.enabled,
|
|
65256
|
-
onChange: (e) => updateVar(idx, { enabled: e.target.checked }),
|
|
65257
|
-
className: "accent-blue-500"
|
|
65258
|
-
}
|
|
65259
|
-
) }),
|
|
65260
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65261
|
-
"input",
|
|
65262
|
-
{
|
|
65263
|
-
value: v.key,
|
|
65264
|
-
onChange: (e) => updateVar(idx, { key: e.target.value }),
|
|
65265
|
-
placeholder: "variable_name",
|
|
65266
|
-
className: "w-full bg-surface-800 rounded px-2 py-1 font-mono focus:outline-none focus:ring-1 focus:ring-blue-500"
|
|
65267
|
-
}
|
|
65268
|
-
) }),
|
|
65269
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "px-2 py-1.5", children: [
|
|
65270
|
-
mode === "plain" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65656
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("tbody", { className: "group border-b border-surface-800/50 hover:bg-surface-800/30", children: [
|
|
65657
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [
|
|
65658
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-3 py-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65271
65659
|
"input",
|
|
65272
65660
|
{
|
|
65273
|
-
|
|
65274
|
-
|
|
65275
|
-
|
|
65661
|
+
type: "checkbox",
|
|
65662
|
+
checked: v.enabled,
|
|
65663
|
+
onChange: (e) => updateVar(idx, { enabled: e.target.checked }),
|
|
65664
|
+
className: "accent-blue-500"
|
|
65665
|
+
}
|
|
65666
|
+
) }),
|
|
65667
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65668
|
+
"input",
|
|
65669
|
+
{
|
|
65670
|
+
value: v.key,
|
|
65671
|
+
onChange: (e) => updateVar(idx, { key: e.target.value }),
|
|
65672
|
+
placeholder: "variable_name",
|
|
65276
65673
|
className: "w-full bg-surface-800 rounded px-2 py-1 font-mono focus:outline-none focus:ring-1 focus:ring-blue-500"
|
|
65277
65674
|
}
|
|
65278
|
-
),
|
|
65279
|
-
|
|
65280
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65675
|
+
) }),
|
|
65676
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("td", { className: "px-2 py-1.5", children: [
|
|
65677
|
+
mode === "plain" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65281
65678
|
"input",
|
|
65282
65679
|
{
|
|
65283
|
-
|
|
65284
|
-
|
|
65285
|
-
|
|
65286
|
-
|
|
65287
|
-
className: "flex-1 bg-surface-800 rounded px-2 py-1 font-mono focus:outline-none focus:ring-1 focus:ring-blue-500"
|
|
65288
|
-
}
|
|
65289
|
-
),
|
|
65290
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65291
|
-
"button",
|
|
65292
|
-
{
|
|
65293
|
-
onClick: () => saveEncrypted(idx),
|
|
65294
|
-
disabled: !secretInputs[idx],
|
|
65295
|
-
className: "px-2 py-1 bg-blue-700 hover:bg-blue-600 disabled:opacity-40 rounded whitespace-nowrap transition-colors",
|
|
65296
|
-
children: savedIdx === idx ? "✓ Saved" : "Encrypt"
|
|
65680
|
+
value: v.value,
|
|
65681
|
+
onChange: (e) => updateVar(idx, { value: e.target.value }),
|
|
65682
|
+
placeholder: "value",
|
|
65683
|
+
className: "w-full bg-surface-800 rounded px-2 py-1 font-mono focus:outline-none focus:ring-1 focus:ring-blue-500"
|
|
65297
65684
|
}
|
|
65298
65685
|
),
|
|
65299
|
-
|
|
65300
|
-
|
|
65301
|
-
|
|
65302
|
-
|
|
65303
|
-
|
|
65304
|
-
|
|
65305
|
-
|
|
65306
|
-
v.secretHash,
|
|
65307
|
-
"
|
|
65308
|
-
|
|
65309
|
-
|
|
65310
|
-
|
|
65686
|
+
mode === "encrypted" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
65687
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65688
|
+
"input",
|
|
65689
|
+
{
|
|
65690
|
+
type: "password",
|
|
65691
|
+
value: secretInputs[idx] ?? "",
|
|
65692
|
+
onChange: (e) => setSecretInputs((s) => ({ ...s, [idx]: e.target.value })),
|
|
65693
|
+
placeholder: v.secretHash ? `Encrypted · sha256: ${v.secretHash}…` : "Enter secret value to encrypt…",
|
|
65694
|
+
className: "flex-1 bg-surface-800 rounded px-2 py-1 font-mono focus:outline-none focus:ring-1 focus:ring-blue-500"
|
|
65695
|
+
}
|
|
65696
|
+
),
|
|
65697
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65698
|
+
"button",
|
|
65699
|
+
{
|
|
65700
|
+
onClick: () => saveEncrypted(idx),
|
|
65701
|
+
disabled: !secretInputs[idx],
|
|
65702
|
+
className: "px-2 py-1 bg-blue-700 hover:bg-blue-600 disabled:opacity-40 rounded whitespace-nowrap transition-colors",
|
|
65703
|
+
children: savedIdx === idx ? "✓ Saved" : "Encrypt"
|
|
65704
|
+
}
|
|
65705
|
+
),
|
|
65706
|
+
v.secretHash && savedIdx !== idx && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
65707
|
+
"span",
|
|
65708
|
+
{
|
|
65709
|
+
className: "text-[10px] text-emerald-400 font-mono shrink-0",
|
|
65710
|
+
title: `SHA-256 fingerprint of encrypted value: ${v.secretHash}…`,
|
|
65711
|
+
children: [
|
|
65712
|
+
"● ",
|
|
65713
|
+
v.secretHash,
|
|
65714
|
+
"…"
|
|
65715
|
+
]
|
|
65716
|
+
}
|
|
65717
|
+
)
|
|
65718
|
+
] }),
|
|
65719
|
+
mode === "env" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 font-mono", children: [
|
|
65720
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-400 select-none", children: "$" }),
|
|
65721
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65722
|
+
"input",
|
|
65723
|
+
{
|
|
65724
|
+
value: v.envRef ?? "",
|
|
65725
|
+
onChange: (e) => updateVar(idx, { envRef: e.target.value }),
|
|
65726
|
+
placeholder: "OS_ENV_VAR_NAME",
|
|
65727
|
+
className: "flex-1 bg-surface-800 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500"
|
|
65728
|
+
}
|
|
65729
|
+
),
|
|
65730
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65731
|
+
"span",
|
|
65732
|
+
{
|
|
65733
|
+
className: "text-[10px] text-surface-400 shrink-0",
|
|
65734
|
+
title: "Value read from OS env at send-time. Never stored in project.",
|
|
65735
|
+
children: "process.env"
|
|
65736
|
+
}
|
|
65737
|
+
)
|
|
65738
|
+
] })
|
|
65311
65739
|
] }),
|
|
65312
|
-
|
|
65313
|
-
|
|
65740
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65741
|
+
"button",
|
|
65742
|
+
{
|
|
65743
|
+
onClick: () => removeVar(idx),
|
|
65744
|
+
className: "text-surface-400 hover:text-red-400 opacity-0 group-hover:opacity-100 transition-all",
|
|
65745
|
+
children: "×"
|
|
65746
|
+
}
|
|
65747
|
+
) })
|
|
65748
|
+
] }),
|
|
65749
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("tr", { children: [
|
|
65750
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", {}),
|
|
65751
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { colSpan: 2, className: "px-2 pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
65314
65752
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65315
65753
|
"input",
|
|
65316
65754
|
{
|
|
65317
|
-
value: v.
|
|
65318
|
-
onChange: (e) => updateVar(idx, {
|
|
65319
|
-
placeholder: "
|
|
65320
|
-
className: "flex-1 bg-surface-800 rounded px-2 py-1 focus:outline-none focus:ring-1 focus:ring-blue-500"
|
|
65755
|
+
value: v.description ?? "",
|
|
65756
|
+
onChange: (e) => updateVar(idx, { description: e.target.value }),
|
|
65757
|
+
placeholder: "Optional description…",
|
|
65758
|
+
className: "flex-1 bg-surface-800/50 rounded px-2 py-1 text-[10px] text-surface-300 placeholder-surface-600 focus:outline-none focus:ring-1 focus:ring-blue-500/50"
|
|
65321
65759
|
}
|
|
65322
65760
|
),
|
|
65323
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
65324
|
-
"
|
|
65761
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
65762
|
+
"button",
|
|
65325
65763
|
{
|
|
65326
|
-
|
|
65327
|
-
title: "
|
|
65328
|
-
|
|
65764
|
+
onClick: () => cycleSource(idx),
|
|
65765
|
+
title: mode === "plain" ? "Plain text — click to switch to encrypted secret" : mode === "encrypted" ? "Encrypted secret — click to switch to env var ref" : "OS env var reference — click to switch to plain text",
|
|
65766
|
+
className: "flex items-center justify-center gap-1 px-1.5 py-0.5 rounded border transition-colors text-[10px] font-medium w-16 shrink-0 border-surface-700 hover:border-surface-500",
|
|
65767
|
+
children: [
|
|
65768
|
+
mode === "plain" && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "abc" }),
|
|
65769
|
+
mode === "encrypted" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
65770
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-amber-400", children: "🔒" }),
|
|
65771
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-amber-400", children: "enc" })
|
|
65772
|
+
] }),
|
|
65773
|
+
mode === "env" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
65774
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-400", children: "$" }),
|
|
65775
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-400", children: "env" })
|
|
65776
|
+
] })
|
|
65777
|
+
]
|
|
65329
65778
|
}
|
|
65330
65779
|
)
|
|
65331
|
-
] })
|
|
65332
|
-
|
|
65333
|
-
|
|
65334
|
-
"input",
|
|
65335
|
-
{
|
|
65336
|
-
value: v.description ?? "",
|
|
65337
|
-
onChange: (e) => updateVar(idx, { description: e.target.value }),
|
|
65338
|
-
placeholder: "Optional description…",
|
|
65339
|
-
className: "w-full bg-surface-800/50 rounded px-2 py-1 text-[10px] text-surface-300 placeholder-surface-600 focus:outline-none focus:ring-1 focus:ring-blue-500/50"
|
|
65340
|
-
}
|
|
65341
|
-
) }),
|
|
65342
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-1.5 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
65343
|
-
"button",
|
|
65344
|
-
{
|
|
65345
|
-
onClick: () => cycleSource(idx),
|
|
65346
|
-
title: mode === "plain" ? "Plain text — click to switch to encrypted secret" : mode === "encrypted" ? "Encrypted secret — click to switch to env var ref" : "OS env var reference — click to switch to plain text",
|
|
65347
|
-
className: "flex items-center justify-center gap-1 mx-auto px-1.5 py-0.5 rounded border transition-colors text-[10px] font-medium w-16 border-surface-700 hover:border-surface-500",
|
|
65348
|
-
children: [
|
|
65349
|
-
mode === "plain" && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "abc" }),
|
|
65350
|
-
mode === "encrypted" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
65351
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-amber-400", children: "🔒" }),
|
|
65352
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-amber-400", children: "enc" })
|
|
65353
|
-
] }),
|
|
65354
|
-
mode === "env" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
65355
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-400", children: "$" }),
|
|
65356
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-400", children: "env" })
|
|
65357
|
-
] })
|
|
65358
|
-
]
|
|
65359
|
-
}
|
|
65360
|
-
) }),
|
|
65361
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("td", { className: "px-2 py-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65362
|
-
"button",
|
|
65363
|
-
{
|
|
65364
|
-
onClick: () => removeVar(idx),
|
|
65365
|
-
className: "text-surface-400 hover:text-red-400 opacity-0 group-hover:opacity-100 transition-all",
|
|
65366
|
-
children: "×"
|
|
65367
|
-
}
|
|
65368
|
-
) })
|
|
65780
|
+
] }) }),
|
|
65781
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("td", {})
|
|
65782
|
+
] })
|
|
65369
65783
|
] }, idx);
|
|
65370
|
-
})
|
|
65784
|
+
})
|
|
65371
65785
|
] }),
|
|
65372
65786
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
65373
65787
|
"button",
|
|
@@ -65435,7 +65849,7 @@ function EnvironmentEditor({ onClose }) {
|
|
|
65435
65849
|
)
|
|
65436
65850
|
] });
|
|
65437
65851
|
}
|
|
65438
|
-
const { electron: electron$
|
|
65852
|
+
const { electron: electron$c } = window;
|
|
65439
65853
|
function EnvironmentBar({ inline = false }) {
|
|
65440
65854
|
const environments = useStore((s) => s.environments);
|
|
65441
65855
|
const activeEnvironmentId = useStore((s) => s.activeEnvironmentId);
|
|
@@ -65449,7 +65863,7 @@ function EnvironmentBar({ inline = false }) {
|
|
|
65449
65863
|
if (id2) {
|
|
65450
65864
|
const hasSecrets = environments[id2]?.data.variables.some((v) => v.enabled && v.secret);
|
|
65451
65865
|
if (hasSecrets) {
|
|
65452
|
-
const { set: set2 } = await electron$
|
|
65866
|
+
const { set: set2 } = await electron$c.checkMasterKey();
|
|
65453
65867
|
if (!set2) {
|
|
65454
65868
|
setPendingEnvId(id2);
|
|
65455
65869
|
return;
|
|
@@ -65503,7 +65917,7 @@ function EnvironmentBar({ inline = false }) {
|
|
|
65503
65917
|
controls
|
|
65504
65918
|
] });
|
|
65505
65919
|
}
|
|
65506
|
-
const { electron: electron$
|
|
65920
|
+
const { electron: electron$b } = window;
|
|
65507
65921
|
const DEFAULT_PII_PATTERNS = ["authorization", "password", "token", "secret", "api-key", "x-api-key"];
|
|
65508
65922
|
const ZOOM_STEPS = [0.75, 0.9, 1, 1.1, 1.25, 1.5];
|
|
65509
65923
|
function WorkspaceSettingsModal({ onClose }) {
|
|
@@ -65558,7 +65972,7 @@ function WorkspaceSettingsModal({ onClose }) {
|
|
|
65558
65972
|
settings.piiMaskPatterns = patterns;
|
|
65559
65973
|
updateWorkspaceSettings(settings);
|
|
65560
65974
|
const updated = useStore.getState().workspace;
|
|
65561
|
-
if (updated) await electron$
|
|
65975
|
+
if (updated) await electron$b.saveWorkspace(updated);
|
|
65562
65976
|
onClose();
|
|
65563
65977
|
}
|
|
65564
65978
|
function zoomStep(dir) {
|
|
@@ -65813,7 +66227,7 @@ function WorkspaceSettingsModal({ onClose }) {
|
|
|
65813
66227
|
}
|
|
65814
66228
|
);
|
|
65815
66229
|
}
|
|
65816
|
-
const { electron: electron$
|
|
66230
|
+
const { electron: electron$a } = window;
|
|
65817
66231
|
function DocsGeneratorModal({ onClose }) {
|
|
65818
66232
|
const collections = useStore((s) => s.collections);
|
|
65819
66233
|
const collectionList = Object.values(collections);
|
|
@@ -65833,18 +66247,29 @@ function DocsGeneratorModal({ onClose }) {
|
|
|
65833
66247
|
});
|
|
65834
66248
|
}
|
|
65835
66249
|
function buildPayload() {
|
|
66250
|
+
const tabs = useStore.getState().tabs;
|
|
66251
|
+
const examples = {};
|
|
66252
|
+
for (const t2 of tabs) {
|
|
66253
|
+
if (!t2.requestId) continue;
|
|
66254
|
+
if (!t2.lastSentRequest && !t2.lastResponse) continue;
|
|
66255
|
+
examples[t2.requestId] = {
|
|
66256
|
+
sent: t2.lastSentRequest ?? void 0,
|
|
66257
|
+
response: t2.lastResponse ?? void 0
|
|
66258
|
+
};
|
|
66259
|
+
}
|
|
65836
66260
|
return {
|
|
65837
66261
|
collections: collectionList.filter((c) => selectedIds.has(c.data.id)).map((c) => ({ collection: c.data, requests: c.data.requests })),
|
|
65838
|
-
format: format2
|
|
66262
|
+
format: format2,
|
|
66263
|
+
examples
|
|
65839
66264
|
};
|
|
65840
66265
|
}
|
|
65841
66266
|
async function handleGenerateAndSave() {
|
|
65842
66267
|
setGenerating(true);
|
|
65843
66268
|
setError(null);
|
|
65844
66269
|
try {
|
|
65845
|
-
const content2 = await electron$
|
|
66270
|
+
const content2 = await electron$a.generateDocs(buildPayload());
|
|
65846
66271
|
const filename = format2 === "html" ? "api-docs.html" : "api-docs.md";
|
|
65847
|
-
await electron$
|
|
66272
|
+
await electron$a.saveResults(content2, filename);
|
|
65848
66273
|
} catch (err) {
|
|
65849
66274
|
setError(err instanceof Error ? err.message : String(err));
|
|
65850
66275
|
} finally {
|
|
@@ -65855,7 +66280,7 @@ function DocsGeneratorModal({ onClose }) {
|
|
|
65855
66280
|
setGenerating(true);
|
|
65856
66281
|
setError(null);
|
|
65857
66282
|
try {
|
|
65858
|
-
const content2 = await electron$
|
|
66283
|
+
const content2 = await electron$a.generateDocs(buildPayload());
|
|
65859
66284
|
setPreview(content2);
|
|
65860
66285
|
} catch (err) {
|
|
65861
66286
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -65971,7 +66396,7 @@ function DocsGeneratorModal({ onClose }) {
|
|
|
65971
66396
|
] })
|
|
65972
66397
|
] }) });
|
|
65973
66398
|
}
|
|
65974
|
-
const { electron: electron$
|
|
66399
|
+
const { electron: electron$9 } = window;
|
|
65975
66400
|
const OPTIONS = [
|
|
65976
66401
|
{ id: "postman", label: "Postman", description: "Collection v2.1 JSON" },
|
|
65977
66402
|
{ id: "openapi", label: "OpenAPI", description: "JSON or YAML (v3.x)", supportsUrl: true },
|
|
@@ -66042,10 +66467,10 @@ function ImportModal({ onImport, onClose }) {
|
|
|
66042
66467
|
setError(null);
|
|
66043
66468
|
try {
|
|
66044
66469
|
let col = null;
|
|
66045
|
-
if (opt2.id === "postman") col = await electron$
|
|
66046
|
-
if (opt2.id === "openapi") col = await electron$
|
|
66047
|
-
if (opt2.id === "insomnia") col = await electron$
|
|
66048
|
-
if (opt2.id === "bruno") col = await electron$
|
|
66470
|
+
if (opt2.id === "postman") col = await electron$9.importPostman();
|
|
66471
|
+
if (opt2.id === "openapi") col = await electron$9.importOpenApi();
|
|
66472
|
+
if (opt2.id === "insomnia") col = await electron$9.importInsomnia();
|
|
66473
|
+
if (opt2.id === "bruno") col = await electron$9.importBruno();
|
|
66049
66474
|
if (!col) {
|
|
66050
66475
|
setLoading(false);
|
|
66051
66476
|
return;
|
|
@@ -66068,7 +66493,7 @@ function ImportModal({ onImport, onClose }) {
|
|
|
66068
66493
|
setLoading(true);
|
|
66069
66494
|
setError(null);
|
|
66070
66495
|
try {
|
|
66071
|
-
const col = await electron$
|
|
66496
|
+
const col = await electron$9.importOpenApiFromUrl(trimmed);
|
|
66072
66497
|
if (col) enterPreview(col);
|
|
66073
66498
|
} catch (err) {
|
|
66074
66499
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -66144,7 +66569,7 @@ function ImportModal({ onImport, onClose }) {
|
|
|
66144
66569
|
mergeIntoCollection(target, prunedRoot, prunedRequests);
|
|
66145
66570
|
const entry = useStore.getState().collections[target];
|
|
66146
66571
|
if (entry) {
|
|
66147
|
-
await electron$
|
|
66572
|
+
await electron$9.saveCollection(entry.relPath, entry.data);
|
|
66148
66573
|
markCollectionClean(target);
|
|
66149
66574
|
}
|
|
66150
66575
|
setActiveCollection(target);
|
|
@@ -66171,7 +66596,7 @@ function ImportModal({ onImport, onClose }) {
|
|
|
66171
66596
|
variables: [{ key: name2, value, enabled: true }]
|
|
66172
66597
|
};
|
|
66173
66598
|
const relPath = envRelPath(finalName, envId);
|
|
66174
|
-
await electron$
|
|
66599
|
+
await electron$9.saveEnvironment(relPath, env);
|
|
66175
66600
|
useStore.setState((s) => {
|
|
66176
66601
|
s.environments[envId] = { relPath, data: env };
|
|
66177
66602
|
if (!s.activeEnvironmentId) s.activeEnvironmentId = envId;
|
|
@@ -66181,7 +66606,7 @@ function ImportModal({ onImport, onClose }) {
|
|
|
66181
66606
|
return s;
|
|
66182
66607
|
});
|
|
66183
66608
|
const ws2 = useStore.getState().workspace;
|
|
66184
|
-
if (ws2) await electron$
|
|
66609
|
+
if (ws2) await electron$9.saveWorkspace(ws2);
|
|
66185
66610
|
} else {
|
|
66186
66611
|
const entry = state.environments[envTarget];
|
|
66187
66612
|
if (!entry) throw new Error("Target environment not found");
|
|
@@ -66196,7 +66621,7 @@ function ImportModal({ onImport, onClose }) {
|
|
|
66196
66621
|
} else {
|
|
66197
66622
|
updated.variables = [...updated.variables, { key: name2, value, enabled: true }];
|
|
66198
66623
|
}
|
|
66199
|
-
await electron$
|
|
66624
|
+
await electron$9.saveEnvironment(entry.relPath, updated);
|
|
66200
66625
|
useStore.getState().updateEnvironment(envTarget, updated);
|
|
66201
66626
|
}
|
|
66202
66627
|
}
|
|
@@ -66544,7 +66969,7 @@ function collectRequestsByFolder(folder, src) {
|
|
|
66544
66969
|
walk(folder);
|
|
66545
66970
|
return out;
|
|
66546
66971
|
}
|
|
66547
|
-
const { electron: electron$
|
|
66972
|
+
const { electron: electron$8 } = window;
|
|
66548
66973
|
function Toolbar({ onOpenDocs: _onOpenDocs }) {
|
|
66549
66974
|
const { applyWorkspace } = useWorkspaceLoader();
|
|
66550
66975
|
const workspace = useStore((s) => s.workspace);
|
|
@@ -66567,13 +66992,13 @@ function Toolbar({ onOpenDocs: _onOpenDocs }) {
|
|
|
66567
66992
|
try {
|
|
66568
66993
|
for (const { relPath, data, dirty } of Object.values(collections)) {
|
|
66569
66994
|
if (!dirty) continue;
|
|
66570
|
-
await electron$
|
|
66995
|
+
await electron$8.saveCollection(relPath, data);
|
|
66571
66996
|
markCollectionClean(data.id);
|
|
66572
66997
|
}
|
|
66573
66998
|
for (const { relPath, data } of Object.values(environments)) {
|
|
66574
|
-
await electron$
|
|
66999
|
+
await electron$8.saveEnvironment(relPath, data);
|
|
66575
67000
|
}
|
|
66576
|
-
if (workspace) await electron$
|
|
67001
|
+
if (workspace) await electron$8.saveWorkspace(workspace);
|
|
66577
67002
|
} finally {
|
|
66578
67003
|
setSaving(false);
|
|
66579
67004
|
}
|
|
@@ -66581,14 +67006,14 @@ function Toolbar({ onOpenDocs: _onOpenDocs }) {
|
|
|
66581
67006
|
async function afterImport(col) {
|
|
66582
67007
|
if (!col) return;
|
|
66583
67008
|
const relPath = colRelPath(col.name, col.id);
|
|
66584
|
-
await electron$
|
|
67009
|
+
await electron$8.saveCollection(relPath, col);
|
|
66585
67010
|
loadCollection(relPath, col);
|
|
66586
67011
|
setActiveCollection(col.id);
|
|
66587
67012
|
const ws2 = useStore.getState().workspace;
|
|
66588
67013
|
if (ws2 && !ws2.collections.includes(relPath)) {
|
|
66589
67014
|
const updated = { ...ws2, collections: [...ws2.collections, relPath] };
|
|
66590
67015
|
useStore.setState({ workspace: updated });
|
|
66591
|
-
await electron$
|
|
67016
|
+
await electron$8.saveWorkspace(updated);
|
|
66592
67017
|
}
|
|
66593
67018
|
}
|
|
66594
67019
|
if (!workspace) return null;
|
|
@@ -66677,7 +67102,7 @@ function Toolbar({ onOpenDocs: _onOpenDocs }) {
|
|
|
66677
67102
|
"button",
|
|
66678
67103
|
{
|
|
66679
67104
|
onClick: async () => {
|
|
66680
|
-
const result = await electron$
|
|
67105
|
+
const result = await electron$8.openWorkspace();
|
|
66681
67106
|
if (result) await applyWorkspace(result.workspace, result.workspacePath);
|
|
66682
67107
|
},
|
|
66683
67108
|
className: "px-2.5 py-1 text-xs bg-surface-800 hover:bg-surface-700 rounded transition-colors",
|
|
@@ -66689,7 +67114,7 @@ function Toolbar({ onOpenDocs: _onOpenDocs }) {
|
|
|
66689
67114
|
"button",
|
|
66690
67115
|
{
|
|
66691
67116
|
onClick: async () => {
|
|
66692
|
-
const result = await electron$
|
|
67117
|
+
const result = await electron$8.newWorkspace();
|
|
66693
67118
|
if (result) await applyWorkspace(result.workspace, result.workspacePath);
|
|
66694
67119
|
},
|
|
66695
67120
|
className: "px-2.5 py-1 text-xs bg-surface-800 hover:bg-surface-700 rounded transition-colors",
|
|
@@ -66701,7 +67126,7 @@ function Toolbar({ onOpenDocs: _onOpenDocs }) {
|
|
|
66701
67126
|
"button",
|
|
66702
67127
|
{
|
|
66703
67128
|
onClick: async () => {
|
|
66704
|
-
await electron$
|
|
67129
|
+
await electron$8.closeWorkspace();
|
|
66705
67130
|
closeWorkspace();
|
|
66706
67131
|
},
|
|
66707
67132
|
className: "px-2.5 py-1 text-xs bg-surface-800 hover:bg-surface-700 rounded transition-colors",
|
|
@@ -67008,7 +67433,7 @@ function buildHtmlReport(results, summary, meta2 = {}) {
|
|
|
67008
67433
|
const html = document.documentElement
|
|
67009
67434
|
const isLight = html.classList.toggle('light')
|
|
67010
67435
|
document.getElementById('themeBtn').textContent = isLight ? '🌙' : '☀️'
|
|
67011
|
-
try { localStorage.setItem('theme', isLight ? 'light' : 'dark') } catch {}
|
|
67436
|
+
try { localStorage.setItem('theme', isLight ? 'light' : 'dark') } catch {} /* private mode / quota — non-fatal */
|
|
67012
67437
|
}
|
|
67013
67438
|
// Restore saved preference or respect OS preference
|
|
67014
67439
|
(function() {
|
|
@@ -67018,7 +67443,7 @@ function buildHtmlReport(results, summary, meta2 = {}) {
|
|
|
67018
67443
|
document.documentElement.classList.add('light')
|
|
67019
67444
|
document.getElementById('themeBtn').textContent = '🌙'
|
|
67020
67445
|
}
|
|
67021
|
-
} catch {}
|
|
67446
|
+
} catch {} /* private mode / quota — non-fatal */
|
|
67022
67447
|
})()
|
|
67023
67448
|
<\/script>
|
|
67024
67449
|
</body>
|
|
@@ -67152,7 +67577,7 @@ api-tests:
|
|
|
67152
67577
|
function EmptyState({ message }) {
|
|
67153
67578
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center h-24 text-surface-400 text-xs", children: message });
|
|
67154
67579
|
}
|
|
67155
|
-
const { electron: electron$
|
|
67580
|
+
const { electron: electron$7 } = window;
|
|
67156
67581
|
const HOOK_BADGE = {
|
|
67157
67582
|
beforeAll: { label: "BEFORE ALL", cls: "bg-violet-700 text-white" },
|
|
67158
67583
|
before: { label: "BEFORE", cls: "bg-violet-600 text-white" },
|
|
@@ -67272,13 +67697,13 @@ function RunnerModal() {
|
|
|
67272
67697
|
setSummary(null);
|
|
67273
67698
|
setRunnerRunning(true);
|
|
67274
67699
|
progressIdxRef.current = 0;
|
|
67275
|
-
electron$
|
|
67700
|
+
electron$7.onRunProgress((result) => {
|
|
67276
67701
|
const idx = progressIdxRef.current;
|
|
67277
67702
|
patchRunnerResult(idx, result);
|
|
67278
67703
|
if (result.status !== "running") progressIdxRef.current++;
|
|
67279
67704
|
});
|
|
67280
67705
|
try {
|
|
67281
|
-
const s = await electron$
|
|
67706
|
+
const s = await electron$7.runCollection({
|
|
67282
67707
|
items: items2,
|
|
67283
67708
|
environment: env,
|
|
67284
67709
|
globals,
|
|
@@ -67289,7 +67714,7 @@ function RunnerModal() {
|
|
|
67289
67714
|
});
|
|
67290
67715
|
setSummary(s);
|
|
67291
67716
|
} finally {
|
|
67292
|
-
electron$
|
|
67717
|
+
electron$7.offRunProgress();
|
|
67293
67718
|
setRunnerRunning(false);
|
|
67294
67719
|
}
|
|
67295
67720
|
}, [collectionId, folderId, filterTags, selectedEnvId, environments, globals, colEntry, requestDelay, workspaceSettings, setRunnerResults, patchRunnerResult, setRunnerRunning]);
|
|
@@ -67524,7 +67949,7 @@ function RunnerModal() {
|
|
|
67524
67949
|
};
|
|
67525
67950
|
const content2 = exportFormat === "junit" ? buildJUnitReport(runnerResults, summary, meta2) : exportFormat === "html" ? buildHtmlReport(runnerResults, summary, meta2) : buildJsonReport(runnerResults, summary, meta2);
|
|
67526
67951
|
const ext = exportFormat === "junit" ? "xml" : exportFormat === "html" ? "html" : "json";
|
|
67527
|
-
electron$
|
|
67952
|
+
electron$7.saveResults(content2, `spector-results.${ext}`);
|
|
67528
67953
|
},
|
|
67529
67954
|
className: "px-2.5 py-0.5 bg-surface-800 hover:bg-surface-700 rounded transition-colors text-[11px] whitespace-nowrap",
|
|
67530
67955
|
children: "Export results"
|
|
@@ -67742,7 +68167,7 @@ function CollectionPanel() {
|
|
|
67742
68167
|
] })
|
|
67743
68168
|
] });
|
|
67744
68169
|
}
|
|
67745
|
-
const { electron: electron$
|
|
68170
|
+
const { electron: electron$6 } = window;
|
|
67746
68171
|
function MockPanel() {
|
|
67747
68172
|
const mocks = useStore((s) => s.mocks);
|
|
67748
68173
|
const activeMockId = useStore((s) => s.activeMockId);
|
|
@@ -67750,6 +68175,7 @@ function MockPanel() {
|
|
|
67750
68175
|
const addMock = useStore((s) => s.addMock);
|
|
67751
68176
|
const deleteMock = useStore((s) => s.deleteMock);
|
|
67752
68177
|
const setRunning = useStore((s) => s.setMockRunning);
|
|
68178
|
+
const loadMock = useStore((s) => s.loadMock);
|
|
67753
68179
|
const recorderOpen = useStore((s) => s.recorderOpen);
|
|
67754
68180
|
const recorderRunning = useStore((s) => s.recorderRunning);
|
|
67755
68181
|
const recorderUpstream = useStore((s) => s.recorderUpstream);
|
|
@@ -67759,16 +68185,45 @@ function MockPanel() {
|
|
|
67759
68185
|
const setRecorderUpstream = useStore((s) => s.setRecorderUpstream);
|
|
67760
68186
|
const setRecorderPort = useStore((s) => s.setRecorderPort);
|
|
67761
68187
|
const [recorderError, setRecorderError] = reactExports.useState("");
|
|
68188
|
+
const [wsdlOpen, setWsdlOpen] = reactExports.useState(false);
|
|
68189
|
+
const [wsdlUrl, setWsdlUrl] = reactExports.useState("");
|
|
68190
|
+
const [wsdlImporting, setWsdlImporting] = reactExports.useState(false);
|
|
68191
|
+
const [wsdlError, setWsdlError] = reactExports.useState("");
|
|
67762
68192
|
const mockList = Object.values(mocks);
|
|
68193
|
+
async function handleImportWsdl() {
|
|
68194
|
+
setWsdlError("");
|
|
68195
|
+
if (!wsdlUrl.trim()) return;
|
|
68196
|
+
setWsdlImporting(true);
|
|
68197
|
+
try {
|
|
68198
|
+
const existingPorts = mockList.map((m) => m.data.port);
|
|
68199
|
+
const { mock } = await electron$6.wsdlImport({ url: wsdlUrl.trim(), existingMockPorts: existingPorts });
|
|
68200
|
+
const relPath = `mocks/${mock.id}.mock.json`;
|
|
68201
|
+
loadMock(relPath, mock);
|
|
68202
|
+
await electron$6.saveMock(relPath, mock);
|
|
68203
|
+
const ws2 = useStore.getState().workspace;
|
|
68204
|
+
if (ws2) {
|
|
68205
|
+
if (!ws2.mocks) ws2.mocks = [];
|
|
68206
|
+
ws2.mocks.push(relPath);
|
|
68207
|
+
await electron$6.saveWorkspace(ws2);
|
|
68208
|
+
}
|
|
68209
|
+
setActiveMock(mock.id);
|
|
68210
|
+
setWsdlOpen(false);
|
|
68211
|
+
setWsdlUrl("");
|
|
68212
|
+
} catch (err) {
|
|
68213
|
+
setWsdlError(err instanceof Error ? err.message : String(err));
|
|
68214
|
+
} finally {
|
|
68215
|
+
setWsdlImporting(false);
|
|
68216
|
+
}
|
|
68217
|
+
}
|
|
67763
68218
|
async function handleAddMock() {
|
|
67764
68219
|
addMock();
|
|
67765
68220
|
const ws2 = useStore.getState().workspace;
|
|
67766
|
-
if (ws2) await electron$
|
|
68221
|
+
if (ws2) await electron$6.saveWorkspace(ws2);
|
|
67767
68222
|
const state = useStore.getState();
|
|
67768
68223
|
const newId = state.activeMockId;
|
|
67769
68224
|
if (newId) {
|
|
67770
68225
|
const entry = state.mocks[newId];
|
|
67771
|
-
await electron$
|
|
68226
|
+
await electron$6.saveMock(entry.relPath, entry.data);
|
|
67772
68227
|
setActiveMock(newId);
|
|
67773
68228
|
}
|
|
67774
68229
|
}
|
|
@@ -67776,15 +68231,15 @@ function MockPanel() {
|
|
|
67776
68231
|
e.stopPropagation();
|
|
67777
68232
|
const entry = useStore.getState().mocks[mockId];
|
|
67778
68233
|
if (!entry) return;
|
|
67779
|
-
if (entry.running) await electron$
|
|
68234
|
+
if (entry.running) await electron$6.mockStop(mockId);
|
|
67780
68235
|
deleteMock(mockId);
|
|
67781
68236
|
const ws2 = useStore.getState().workspace;
|
|
67782
|
-
if (ws2) await electron$
|
|
68237
|
+
if (ws2) await electron$6.saveWorkspace(ws2);
|
|
67783
68238
|
}
|
|
67784
68239
|
async function handleStartRecorder() {
|
|
67785
68240
|
setRecorderError("");
|
|
67786
68241
|
try {
|
|
67787
|
-
await electron$
|
|
68242
|
+
await electron$6.recordStart({ upstream: recorderUpstream, port: recorderPort });
|
|
67788
68243
|
setRecorderRunning(true);
|
|
67789
68244
|
} catch (err) {
|
|
67790
68245
|
setRecorderError(err instanceof Error ? err.message : String(err));
|
|
@@ -67796,12 +68251,12 @@ function MockPanel() {
|
|
|
67796
68251
|
if (!entry) return;
|
|
67797
68252
|
try {
|
|
67798
68253
|
if (entry.running) {
|
|
67799
|
-
await electron$
|
|
68254
|
+
await electron$6.mockStop(mockId);
|
|
67800
68255
|
setRunning(mockId, false);
|
|
67801
68256
|
} else {
|
|
67802
68257
|
const latest2 = useStore.getState().mocks[mockId].data;
|
|
67803
|
-
await electron$
|
|
67804
|
-
await electron$
|
|
68258
|
+
await electron$6.saveMock(entry.relPath, latest2);
|
|
68259
|
+
await electron$6.mockStart(latest2);
|
|
67805
68260
|
setRunning(mockId, true);
|
|
67806
68261
|
}
|
|
67807
68262
|
} catch {
|
|
@@ -67867,14 +68322,66 @@ function MockPanel() {
|
|
|
67867
68322
|
] }),
|
|
67868
68323
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-3 py-2 flex items-center justify-between border-b border-surface-800 flex-shrink-0", children: [
|
|
67869
68324
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] font-semibold uppercase tracking-widest text-surface-600", children: "Mock Servers" }),
|
|
68325
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
68326
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
68327
|
+
"button",
|
|
68328
|
+
{
|
|
68329
|
+
onClick: () => {
|
|
68330
|
+
setWsdlOpen((o) => !o);
|
|
68331
|
+
setWsdlError("");
|
|
68332
|
+
},
|
|
68333
|
+
className: "text-[11px] text-surface-400 hover:text-blue-300 transition-colors",
|
|
68334
|
+
title: "Generate a mock server from a WSDL",
|
|
68335
|
+
children: "Import WSDL"
|
|
68336
|
+
}
|
|
68337
|
+
),
|
|
68338
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
68339
|
+
"button",
|
|
68340
|
+
{
|
|
68341
|
+
onClick: handleAddMock,
|
|
68342
|
+
className: "text-[11px] text-blue-400 hover:text-blue-300 transition-colors",
|
|
68343
|
+
children: "+ New"
|
|
68344
|
+
}
|
|
68345
|
+
)
|
|
68346
|
+
] })
|
|
68347
|
+
] }),
|
|
68348
|
+
wsdlOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-3 py-2 flex flex-col gap-2 bg-surface-900/40 border-b border-surface-800 flex-shrink-0", children: [
|
|
67870
68349
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
67871
|
-
"
|
|
68350
|
+
"input",
|
|
67872
68351
|
{
|
|
67873
|
-
|
|
67874
|
-
|
|
67875
|
-
|
|
68352
|
+
value: wsdlUrl,
|
|
68353
|
+
onChange: (e) => setWsdlUrl(e.target.value),
|
|
68354
|
+
onKeyDown: (e) => {
|
|
68355
|
+
if (e.key === "Enter" && !wsdlImporting) handleImportWsdl();
|
|
68356
|
+
},
|
|
68357
|
+
placeholder: "https://example.com/service?WSDL",
|
|
68358
|
+
className: "w-full bg-surface-900 border border-surface-700 rounded px-2 py-1 text-[11px] font-mono placeholder-surface-600 focus:outline-none focus:border-blue-500"
|
|
67876
68359
|
}
|
|
67877
|
-
)
|
|
68360
|
+
),
|
|
68361
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
|
|
68362
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
68363
|
+
"button",
|
|
68364
|
+
{
|
|
68365
|
+
onClick: handleImportWsdl,
|
|
68366
|
+
disabled: wsdlImporting || !wsdlUrl.trim(),
|
|
68367
|
+
className: "flex-1 py-1 rounded text-[11px] bg-blue-700 hover:bg-blue-600 disabled:opacity-50 disabled:hover:bg-blue-700 transition-colors",
|
|
68368
|
+
children: wsdlImporting ? "Importing…" : "Generate mock"
|
|
68369
|
+
}
|
|
68370
|
+
),
|
|
68371
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
68372
|
+
"button",
|
|
68373
|
+
{
|
|
68374
|
+
onClick: () => {
|
|
68375
|
+
setWsdlOpen(false);
|
|
68376
|
+
setWsdlError("");
|
|
68377
|
+
},
|
|
68378
|
+
className: "px-2 py-1 rounded text-[11px] bg-surface-800 hover:bg-surface-700 transition-colors",
|
|
68379
|
+
children: "Cancel"
|
|
68380
|
+
}
|
|
68381
|
+
)
|
|
68382
|
+
] }),
|
|
68383
|
+
wsdlError && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-red-400", children: wsdlError }),
|
|
68384
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-surface-600 leading-relaxed", children: "One dispatch route per service endpoint. SOAPAction (or operation element in the body) selects which response envelope is returned." })
|
|
67878
68385
|
] }),
|
|
67879
68386
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto", children: mockList.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col items-center justify-center h-full gap-3 text-center px-4", children: [
|
|
67880
68387
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-surface-400 text-xs", children: "No mock servers yet." }),
|
|
@@ -67934,7 +68441,7 @@ function MockPanel() {
|
|
|
67934
68441
|
}) })
|
|
67935
68442
|
] });
|
|
67936
68443
|
}
|
|
67937
|
-
const { electron: electron$
|
|
68444
|
+
const { electron: electron$5 } = window;
|
|
67938
68445
|
const METHODS_PLUS_ANY = ["ANY", "GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"];
|
|
67939
68446
|
function RouteRow({
|
|
67940
68447
|
route,
|
|
@@ -68336,20 +68843,20 @@ function MockDetailPanel({ mockId }) {
|
|
|
68336
68843
|
const routes = mock.routes ?? [];
|
|
68337
68844
|
async function save(updated) {
|
|
68338
68845
|
updateMock(mock.id, updated);
|
|
68339
|
-
await electron$
|
|
68340
|
-
if (running) await electron$
|
|
68341
|
-
if (workspace) await electron$
|
|
68846
|
+
await electron$5.saveMock(entry.relPath, updated);
|
|
68847
|
+
if (running) await electron$5.mockUpdateRoutes(mock.id, updated.routes ?? []);
|
|
68848
|
+
if (workspace) await electron$5.saveWorkspace(workspace);
|
|
68342
68849
|
}
|
|
68343
68850
|
async function toggleRunning() {
|
|
68344
68851
|
setError(null);
|
|
68345
68852
|
try {
|
|
68346
68853
|
if (running) {
|
|
68347
|
-
await electron$
|
|
68854
|
+
await electron$5.mockStop(mock.id);
|
|
68348
68855
|
setRunning(mock.id, false);
|
|
68349
68856
|
} else {
|
|
68350
68857
|
const latest2 = useStore.getState().mocks[mock.id].data;
|
|
68351
|
-
await electron$
|
|
68352
|
-
await electron$
|
|
68858
|
+
await electron$5.saveMock(entry.relPath, latest2);
|
|
68859
|
+
await electron$5.mockStart(latest2);
|
|
68353
68860
|
setRunning(mock.id, true);
|
|
68354
68861
|
}
|
|
68355
68862
|
} catch (e) {
|
|
@@ -68462,7 +68969,7 @@ function MockDetailPanel({ mockId }) {
|
|
|
68462
68969
|
"button",
|
|
68463
68970
|
{
|
|
68464
68971
|
onClick: () => {
|
|
68465
|
-
if (running) electron$
|
|
68972
|
+
if (running) electron$5.mockStop(mock.id);
|
|
68466
68973
|
deleteMock(mock.id);
|
|
68467
68974
|
setActive2(null);
|
|
68468
68975
|
},
|
|
@@ -68529,7 +69036,7 @@ function MockDetailPanel({ mockId }) {
|
|
|
68529
69036
|
] })
|
|
68530
69037
|
] });
|
|
68531
69038
|
}
|
|
68532
|
-
const { electron: electron$
|
|
69039
|
+
const { electron: electron$4 } = window;
|
|
68533
69040
|
function statusColor$1(status) {
|
|
68534
69041
|
if (status === 0) return "text-yellow-400";
|
|
68535
69042
|
if (status < 300) return "text-emerald-400";
|
|
@@ -68562,7 +69069,7 @@ function RecorderPanel({ onImportMock, onClose, defaultTargetMockId }) {
|
|
|
68562
69069
|
const upstream = useStore((s) => s.recorderUpstream);
|
|
68563
69070
|
const mockList = Object.values(useStore((s) => s.mocks));
|
|
68564
69071
|
reactExports.useEffect(() => {
|
|
68565
|
-
electron$
|
|
69072
|
+
electron$4.onRecordHit((entry) => {
|
|
68566
69073
|
setEntries((prev) => {
|
|
68567
69074
|
const next = [...prev, entry];
|
|
68568
69075
|
setTimeout(() => {
|
|
@@ -68572,12 +69079,12 @@ function RecorderPanel({ onImportMock, onClose, defaultTargetMockId }) {
|
|
|
68572
69079
|
});
|
|
68573
69080
|
});
|
|
68574
69081
|
return () => {
|
|
68575
|
-
electron$
|
|
69082
|
+
electron$4.offRecordHit();
|
|
68576
69083
|
};
|
|
68577
69084
|
}, []);
|
|
68578
69085
|
async function handleStop() {
|
|
68579
69086
|
try {
|
|
68580
|
-
const s = await electron$
|
|
69087
|
+
const s = await electron$4.recordStop();
|
|
68581
69088
|
setSession(s);
|
|
68582
69089
|
setStopped(true);
|
|
68583
69090
|
} catch {
|
|
@@ -68773,7 +69280,7 @@ function HeadersTable({ headers }) {
|
|
|
68773
69280
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-300 break-all", children: v })
|
|
68774
69281
|
] }, k)) });
|
|
68775
69282
|
}
|
|
68776
|
-
const { electron: electron$
|
|
69283
|
+
const { electron: electron$3 } = window;
|
|
68777
69284
|
function ContractPanel() {
|
|
68778
69285
|
const collections = useStore((s) => s.collections);
|
|
68779
69286
|
const environments = useStore((s) => s.environments);
|
|
@@ -68781,11 +69288,20 @@ function ContractPanel() {
|
|
|
68781
69288
|
const activeCollId = useStore((s) => s.activeCollectionId);
|
|
68782
69289
|
const report = useStore((s) => s.lastContractReport);
|
|
68783
69290
|
const setReport = useStore((s) => s.setLastContractReport);
|
|
69291
|
+
const snapshots = useStore((s) => s.contractSnapshots);
|
|
69292
|
+
const activeSnapshotRelPath = useStore((s) => s.activeContractSnapshotRelPath);
|
|
69293
|
+
const setActiveSnapshot = useStore((s) => s.setActiveContractSnapshot);
|
|
69294
|
+
const loadContractSnapshot = useStore((s) => s.loadContractSnapshot);
|
|
69295
|
+
const removeContractSnapshot = useStore((s) => s.removeContractSnapshot);
|
|
69296
|
+
const workspace = useStore((s) => s.workspace);
|
|
68784
69297
|
const [mode, setMode] = reactExports.useState("consumer");
|
|
68785
69298
|
const [specUrl, setSpecUrl] = reactExports.useState("");
|
|
68786
69299
|
const [requestBaseUrl, setRequestBaseUrl] = reactExports.useState("");
|
|
68787
69300
|
const [running, setRunning] = reactExports.useState(false);
|
|
69301
|
+
const [capturing, setCapturing] = reactExports.useState(false);
|
|
68788
69302
|
const [error2, setError] = reactExports.useState(null);
|
|
69303
|
+
const snapshotList = Object.entries(snapshots).map(([relPath, snapshot]) => ({ relPath, snapshot })).sort((a, b) => b.snapshot.capturedAt.localeCompare(a.snapshot.capturedAt));
|
|
69304
|
+
const activeSnapshot = activeSnapshotRelPath ? snapshots[activeSnapshotRelPath] ?? null : null;
|
|
68789
69305
|
const allRequests = Object.values(collections).flatMap((c) => Object.values(c.data.requests));
|
|
68790
69306
|
const contractRequests = allRequests.filter(
|
|
68791
69307
|
(r) => r.contract && (r.contract.statusCode !== void 0 || r.contract.bodySchema || r.contract.headers?.length)
|
|
@@ -68795,8 +69311,8 @@ function ContractPanel() {
|
|
|
68795
69311
|
(environments[activeEnvId]?.data.variables ?? []).filter((v) => v.enabled).map((v) => [v.key, v.value])
|
|
68796
69312
|
) : {};
|
|
68797
69313
|
async function runContracts() {
|
|
68798
|
-
if (mode !== "consumer" && !specUrl.trim()) {
|
|
68799
|
-
setError("Provide an OpenAPI spec URL for provider / bi-directional mode.");
|
|
69314
|
+
if (mode !== "consumer" && !specUrl.trim() && !activeSnapshotRelPath) {
|
|
69315
|
+
setError("Provide an OpenAPI spec URL or pick a pinned snapshot for provider / bi-directional mode.");
|
|
68800
69316
|
return;
|
|
68801
69317
|
}
|
|
68802
69318
|
setRunning(true);
|
|
@@ -68804,12 +69320,13 @@ function ContractPanel() {
|
|
|
68804
69320
|
setReport(null);
|
|
68805
69321
|
try {
|
|
68806
69322
|
const requests = mode === "provider" ? allRequests : contractRequests;
|
|
68807
|
-
const result = await electron$
|
|
69323
|
+
const result = await electron$3.runContracts({
|
|
68808
69324
|
mode,
|
|
68809
69325
|
requests,
|
|
68810
69326
|
envVars,
|
|
68811
69327
|
collectionVars,
|
|
68812
69328
|
specUrl: specUrl.trim() || void 0,
|
|
69329
|
+
specSnapshotRelPath: activeSnapshotRelPath ?? void 0,
|
|
68813
69330
|
requestBaseUrl: requestBaseUrl.trim() || void 0
|
|
68814
69331
|
});
|
|
68815
69332
|
setReport(result);
|
|
@@ -68819,6 +69336,37 @@ function ContractPanel() {
|
|
|
68819
69336
|
setRunning(false);
|
|
68820
69337
|
}
|
|
68821
69338
|
}
|
|
69339
|
+
async function captureSnapshot() {
|
|
69340
|
+
if (!specUrl.trim()) {
|
|
69341
|
+
setError("Enter a spec URL before pinning a snapshot.");
|
|
69342
|
+
return;
|
|
69343
|
+
}
|
|
69344
|
+
setCapturing(true);
|
|
69345
|
+
setError(null);
|
|
69346
|
+
try {
|
|
69347
|
+
const { relPath, snapshot } = await electron$3.captureContractSnapshot({ specUrl: specUrl.trim() });
|
|
69348
|
+
loadContractSnapshot(relPath, snapshot);
|
|
69349
|
+
setActiveSnapshot(relPath);
|
|
69350
|
+
const ws2 = useStore.getState().workspace;
|
|
69351
|
+
if (ws2) await electron$3.saveWorkspace(ws2);
|
|
69352
|
+
} catch (e) {
|
|
69353
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
69354
|
+
} finally {
|
|
69355
|
+
setCapturing(false);
|
|
69356
|
+
}
|
|
69357
|
+
}
|
|
69358
|
+
async function deleteActiveSnapshot() {
|
|
69359
|
+
if (!activeSnapshotRelPath) return;
|
|
69360
|
+
const relPath = activeSnapshotRelPath;
|
|
69361
|
+
try {
|
|
69362
|
+
await electron$3.deleteContractSnapshot(relPath);
|
|
69363
|
+
removeContractSnapshot(relPath);
|
|
69364
|
+
const ws2 = useStore.getState().workspace;
|
|
69365
|
+
if (ws2) await electron$3.saveWorkspace(ws2);
|
|
69366
|
+
} catch (e) {
|
|
69367
|
+
setError(e instanceof Error ? e.message : String(e));
|
|
69368
|
+
}
|
|
69369
|
+
}
|
|
68822
69370
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col flex-1 min-h-0 overflow-hidden", children: [
|
|
68823
69371
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3 px-3 py-3 border-b border-surface-800 flex-shrink-0", children: [
|
|
68824
69372
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-1 bg-surface-800 rounded-lg p-0.5", children: ["consumer", "provider", "bidirectional"].map((m) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -68836,16 +69384,65 @@ function ContractPanel() {
|
|
|
68836
69384
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-surface-500 leading-relaxed", children: mode === "consumer" ? "Sends requests to the real provider and validates each response against the contract defined in the Contract tab." : mode === "provider" ? "Static analysis — validates that your requests conform to the provider's published OpenAPI spec (no HTTP calls)." : "Checks static schema compatibility between consumer contracts and provider spec, then verifies live responses." }),
|
|
68837
69385
|
mode !== "consumer" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
68838
69386
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
69387
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-[10px] text-surface-500 uppercase tracking-wider font-medium block mb-1", children: "Spec version" }),
|
|
69388
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1", children: [
|
|
69389
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
69390
|
+
"select",
|
|
69391
|
+
{
|
|
69392
|
+
value: activeSnapshotRelPath ?? "",
|
|
69393
|
+
onChange: (e) => setActiveSnapshot(e.target.value || null),
|
|
69394
|
+
disabled: !workspace,
|
|
69395
|
+
className: "flex-1 text-xs bg-surface-800 border border-surface-700 rounded px-2 py-1.5 focus:outline-none focus:border-blue-500 disabled:opacity-50",
|
|
69396
|
+
children: [
|
|
69397
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: "Live URL (latest from provider)" }),
|
|
69398
|
+
snapshotList.map(({ relPath, snapshot }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("option", { value: relPath, children: [
|
|
69399
|
+
snapshot.name,
|
|
69400
|
+
snapshot.specVersion ? "" : ` — ${snapshot.capturedAt.slice(0, 10)}`
|
|
69401
|
+
] }, relPath))
|
|
69402
|
+
]
|
|
69403
|
+
}
|
|
69404
|
+
),
|
|
69405
|
+
activeSnapshotRelPath && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
69406
|
+
"button",
|
|
69407
|
+
{
|
|
69408
|
+
onClick: deleteActiveSnapshot,
|
|
69409
|
+
title: "Delete this snapshot",
|
|
69410
|
+
className: "px-2 text-xs text-surface-500 hover:text-red-400 bg-surface-800 hover:bg-surface-700 rounded transition-colors",
|
|
69411
|
+
children: "✕"
|
|
69412
|
+
}
|
|
69413
|
+
)
|
|
69414
|
+
] }),
|
|
69415
|
+
activeSnapshot && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[10px] text-surface-600 mt-1 font-mono truncate", children: [
|
|
69416
|
+
"Captured ",
|
|
69417
|
+
activeSnapshot.capturedAt.slice(0, 19).replace("T", " "),
|
|
69418
|
+
" — sha ",
|
|
69419
|
+
activeSnapshot.sha256.slice(0, 8)
|
|
69420
|
+
] })
|
|
69421
|
+
] }),
|
|
69422
|
+
!activeSnapshotRelPath && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
68839
69423
|
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-[10px] text-surface-500 uppercase tracking-wider font-medium block mb-1", children: "OpenAPI Spec URL" }),
|
|
68840
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
68841
|
-
|
|
68842
|
-
|
|
68843
|
-
|
|
68844
|
-
|
|
68845
|
-
|
|
68846
|
-
|
|
68847
|
-
|
|
68848
|
-
|
|
69424
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1", children: [
|
|
69425
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
69426
|
+
"input",
|
|
69427
|
+
{
|
|
69428
|
+
value: specUrl,
|
|
69429
|
+
onChange: (e) => setSpecUrl(e.target.value),
|
|
69430
|
+
placeholder: "https://api.example.com/openapi.json",
|
|
69431
|
+
className: "flex-1 text-xs bg-surface-800 border border-surface-700 rounded px-2.5 py-1.5 focus:outline-none focus:border-blue-500 font-mono placeholder-surface-600"
|
|
69432
|
+
}
|
|
69433
|
+
),
|
|
69434
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
69435
|
+
"button",
|
|
69436
|
+
{
|
|
69437
|
+
onClick: captureSnapshot,
|
|
69438
|
+
disabled: capturing || !specUrl.trim() || !workspace,
|
|
69439
|
+
title: "Fetch and pin this spec as a versioned snapshot",
|
|
69440
|
+
className: "px-2.5 text-xs bg-surface-800 hover:bg-surface-700 disabled:opacity-50 disabled:hover:bg-surface-800 rounded transition-colors",
|
|
69441
|
+
children: capturing ? "…" : "Pin"
|
|
69442
|
+
}
|
|
69443
|
+
)
|
|
69444
|
+
] }),
|
|
69445
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-surface-600 mt-1 leading-relaxed", children: "Pin a snapshot to run against a specific spec version later, even after the provider ships an update." })
|
|
68849
69446
|
] }),
|
|
68850
69447
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
68851
69448
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-[10px] text-surface-500 uppercase tracking-wider font-medium block mb-1", children: [
|
|
@@ -68870,7 +69467,7 @@ function ContractPanel() {
|
|
|
68870
69467
|
"button",
|
|
68871
69468
|
{
|
|
68872
69469
|
onClick: runContracts,
|
|
68873
|
-
disabled: running || mode !== "consumer" && !specUrl.trim(),
|
|
69470
|
+
disabled: running || mode !== "consumer" && !specUrl.trim() && !activeSnapshotRelPath,
|
|
68874
69471
|
className: "px-3 py-1 text-xs bg-blue-700 hover:bg-blue-600 disabled:bg-surface-800 disabled:text-surface-600 rounded transition-colors font-medium",
|
|
68875
69472
|
children: running ? "Running…" : "Run"
|
|
68876
69473
|
}
|
|
@@ -68884,7 +69481,7 @@ function ContractPanel() {
|
|
|
68884
69481
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-surface-500", children: "Configure a mode above and click Run." }),
|
|
68885
69482
|
mode !== "provider" && contractRequests.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-surface-600 max-w-[180px]", children: "Define a contract on a request via the Contract tab first." })
|
|
68886
69483
|
] }),
|
|
68887
|
-
report && !running && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `flex items-center gap-2 px-3 py-2 rounded-lg border text-xs ${report.failed === 0 ? "bg-emerald-
|
|
69484
|
+
report && !running && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `flex items-center gap-2 px-3 py-2 rounded-lg border text-xs ${report.failed === 0 ? "bg-emerald-800/30 border-emerald-400/50 text-emerald-400" : "bg-red-900/30 border-red-700 text-red-300"}`, children: [
|
|
68888
69485
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-semibold", children: report.failed === 0 ? "✓ All passed" : `✗ ${report.failed} failed` }),
|
|
68889
69486
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-surface-500 ml-auto", children: [
|
|
68890
69487
|
report.passed,
|
|
@@ -69002,7 +69599,7 @@ function ContractResultsPanel() {
|
|
|
69002
69599
|
})() })
|
|
69003
69600
|
] });
|
|
69004
69601
|
}
|
|
69005
|
-
const { electron: electron$
|
|
69602
|
+
const { electron: electron$2 } = window;
|
|
69006
69603
|
function useToast() {
|
|
69007
69604
|
const [toast, setToast] = reactExports.useState(null);
|
|
69008
69605
|
const timer = reactExports.useRef(null);
|
|
@@ -69047,8 +69644,9 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
69047
69644
|
async function showDiff(file, staged) {
|
|
69048
69645
|
setDiffFile(file.path);
|
|
69049
69646
|
setDiffStaged(staged);
|
|
69647
|
+
useStore.getState().setActiveGitDiff({ path: file.path, staged });
|
|
69050
69648
|
try {
|
|
69051
|
-
const d = staged ? await electron$
|
|
69649
|
+
const d = staged ? await electron$2.gitDiffStaged(file.path) : await electron$2.gitDiff(file.path);
|
|
69052
69650
|
setDiff(d);
|
|
69053
69651
|
} catch {
|
|
69054
69652
|
setDiff("");
|
|
@@ -69056,7 +69654,7 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
69056
69654
|
}
|
|
69057
69655
|
async function stage(paths) {
|
|
69058
69656
|
try {
|
|
69059
|
-
await electron$
|
|
69657
|
+
await electron$2.gitStage(paths);
|
|
69060
69658
|
onRefresh();
|
|
69061
69659
|
} catch (e) {
|
|
69062
69660
|
setError(String(e));
|
|
@@ -69064,7 +69662,7 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
69064
69662
|
}
|
|
69065
69663
|
async function unstage(paths) {
|
|
69066
69664
|
try {
|
|
69067
|
-
await electron$
|
|
69665
|
+
await electron$2.gitUnstage(paths);
|
|
69068
69666
|
onRefresh();
|
|
69069
69667
|
} catch (e) {
|
|
69070
69668
|
setError(String(e));
|
|
@@ -69072,7 +69670,7 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
69072
69670
|
}
|
|
69073
69671
|
async function stageAll() {
|
|
69074
69672
|
try {
|
|
69075
|
-
await electron$
|
|
69673
|
+
await electron$2.gitStageAll();
|
|
69076
69674
|
onRefresh();
|
|
69077
69675
|
} catch (e) {
|
|
69078
69676
|
setError(String(e));
|
|
@@ -69082,7 +69680,7 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
69082
69680
|
if (!message.trim()) return;
|
|
69083
69681
|
try {
|
|
69084
69682
|
setError(null);
|
|
69085
|
-
await electron$
|
|
69683
|
+
await electron$2.gitCommit(message.trim());
|
|
69086
69684
|
setMessage("");
|
|
69087
69685
|
onRefresh();
|
|
69088
69686
|
} catch (e) {
|
|
@@ -69092,7 +69690,7 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
69092
69690
|
async function pull() {
|
|
69093
69691
|
setPulling(true);
|
|
69094
69692
|
try {
|
|
69095
|
-
await electron$
|
|
69693
|
+
await electron$2.gitPull();
|
|
69096
69694
|
showToast("Pull successful", true);
|
|
69097
69695
|
onRefresh();
|
|
69098
69696
|
} catch (e) {
|
|
@@ -69104,7 +69702,7 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
69104
69702
|
async function push2() {
|
|
69105
69703
|
setPushing(true);
|
|
69106
69704
|
try {
|
|
69107
|
-
await electron$
|
|
69705
|
+
await electron$2.gitPush(!status.remote);
|
|
69108
69706
|
showToast("Push successful", true);
|
|
69109
69707
|
onRefresh();
|
|
69110
69708
|
} catch (e) {
|
|
@@ -69115,9 +69713,9 @@ function ChangesTab({ status, onRefresh }) {
|
|
|
69115
69713
|
}
|
|
69116
69714
|
async function resolveConflict(path, mode) {
|
|
69117
69715
|
try {
|
|
69118
|
-
if (mode === "ours") await electron$
|
|
69119
|
-
else if (mode === "theirs") await electron$
|
|
69120
|
-
else await electron$
|
|
69716
|
+
if (mode === "ours") await electron$2.gitResolveOurs(path);
|
|
69717
|
+
else if (mode === "theirs") await electron$2.gitResolveTheirs(path);
|
|
69718
|
+
else await electron$2.gitMarkResolved(path);
|
|
69121
69719
|
if (diffFile === path) setDiffFile(null);
|
|
69122
69720
|
onRefresh();
|
|
69123
69721
|
} catch (e) {
|
|
@@ -69369,7 +69967,7 @@ function LogTab() {
|
|
|
69369
69967
|
const [commits, setCommits] = reactExports.useState([]);
|
|
69370
69968
|
const [loading, setLoading] = reactExports.useState(true);
|
|
69371
69969
|
reactExports.useEffect(() => {
|
|
69372
|
-
electron$
|
|
69970
|
+
electron$2.gitLog(100).then(setCommits).catch(() => setCommits([])).finally(() => setLoading(false));
|
|
69373
69971
|
}, []);
|
|
69374
69972
|
if (loading) return /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-surface-500 px-3 py-4", children: "Loading…" });
|
|
69375
69973
|
if (commits.length === 0) return /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-surface-500 px-3 py-4", children: "No commits yet." });
|
|
@@ -69396,11 +69994,16 @@ function BranchesTab({ onRefresh }) {
|
|
|
69396
69994
|
const [remoteUrl, setRemoteUrl] = reactExports.useState("");
|
|
69397
69995
|
const [editUrl, setEditUrl] = reactExports.useState("");
|
|
69398
69996
|
const [error2, setError] = reactExports.useState(null);
|
|
69997
|
+
const [loadError, setLoadError] = reactExports.useState(null);
|
|
69998
|
+
const [filter, setFilter] = reactExports.useState("");
|
|
69399
69999
|
const load = reactExports.useCallback(() => {
|
|
69400
|
-
|
|
70000
|
+
setLoadError(null);
|
|
70001
|
+
Promise.all([electron$2.gitBranches(), electron$2.gitRemotes()]).then(([b, r]) => {
|
|
69401
70002
|
setBranches(b);
|
|
69402
70003
|
setRemotes(r);
|
|
69403
|
-
}).catch(() => {
|
|
70004
|
+
}).catch((err) => {
|
|
70005
|
+
console.warn("GitPanel: failed to load branches/remotes", err);
|
|
70006
|
+
setLoadError(err instanceof Error ? err.message : String(err));
|
|
69404
70007
|
}).finally(() => setLoading(false));
|
|
69405
70008
|
}, []);
|
|
69406
70009
|
reactExports.useEffect(() => {
|
|
@@ -69410,7 +70013,7 @@ function BranchesTab({ onRefresh }) {
|
|
|
69410
70013
|
try {
|
|
69411
70014
|
setError(null);
|
|
69412
70015
|
const localName = remote2 ? name2.replace(/^origin\//, "") : name2;
|
|
69413
|
-
await electron$
|
|
70016
|
+
await electron$2.gitCheckout(localName, false);
|
|
69414
70017
|
load();
|
|
69415
70018
|
onRefresh();
|
|
69416
70019
|
} catch (e) {
|
|
@@ -69421,7 +70024,7 @@ function BranchesTab({ onRefresh }) {
|
|
|
69421
70024
|
if (!newBranch.trim()) return;
|
|
69422
70025
|
try {
|
|
69423
70026
|
setError(null);
|
|
69424
|
-
await electron$
|
|
70027
|
+
await electron$2.gitCheckout(newBranch.trim(), true);
|
|
69425
70028
|
setNewBranch("");
|
|
69426
70029
|
setCreating(false);
|
|
69427
70030
|
load();
|
|
@@ -69434,7 +70037,7 @@ function BranchesTab({ onRefresh }) {
|
|
|
69434
70037
|
if (!remoteName.trim() || !remoteUrl.trim()) return;
|
|
69435
70038
|
try {
|
|
69436
70039
|
setError(null);
|
|
69437
|
-
await electron$
|
|
70040
|
+
await electron$2.gitAddRemote(remoteName.trim(), remoteUrl.trim());
|
|
69438
70041
|
setRemoteName("origin");
|
|
69439
70042
|
setRemoteUrl("");
|
|
69440
70043
|
setAddingRemote(false);
|
|
@@ -69451,7 +70054,7 @@ function BranchesTab({ onRefresh }) {
|
|
|
69451
70054
|
if (!editUrl.trim()) return;
|
|
69452
70055
|
try {
|
|
69453
70056
|
setError(null);
|
|
69454
|
-
await electron$
|
|
70057
|
+
await electron$2.gitSetRemoteUrl(name2, editUrl.trim());
|
|
69455
70058
|
setEditingRemote(null);
|
|
69456
70059
|
load();
|
|
69457
70060
|
} catch (e) {
|
|
@@ -69461,65 +70064,132 @@ function BranchesTab({ onRefresh }) {
|
|
|
69461
70064
|
async function removeRemote(name2) {
|
|
69462
70065
|
try {
|
|
69463
70066
|
setError(null);
|
|
69464
|
-
await electron$
|
|
70067
|
+
await electron$2.gitRemoveRemote(name2);
|
|
69465
70068
|
load();
|
|
69466
70069
|
} catch (e) {
|
|
69467
70070
|
setError(String(e));
|
|
69468
70071
|
}
|
|
69469
70072
|
}
|
|
69470
|
-
|
|
69471
|
-
|
|
70073
|
+
async function deleteBranch(name2) {
|
|
70074
|
+
if (!confirm(`Delete branch "${name2}"?`)) return;
|
|
70075
|
+
try {
|
|
70076
|
+
setError(null);
|
|
70077
|
+
try {
|
|
70078
|
+
await electron$2.gitDeleteBranch(name2, false);
|
|
70079
|
+
} catch {
|
|
70080
|
+
if (!confirm(`"${name2}" isn't fully merged. Force delete?`)) return;
|
|
70081
|
+
await electron$2.gitDeleteBranch(name2, true);
|
|
70082
|
+
}
|
|
70083
|
+
load();
|
|
70084
|
+
onRefresh();
|
|
70085
|
+
} catch (e) {
|
|
70086
|
+
setError(String(e));
|
|
70087
|
+
}
|
|
70088
|
+
}
|
|
70089
|
+
const q = filter.trim().toLowerCase();
|
|
70090
|
+
const local = branches.filter((b) => !b.remote && (!q || b.name.toLowerCase().includes(q)));
|
|
70091
|
+
const remote = branches.filter((b) => b.remote && (!q || b.name.toLowerCase().includes(q)));
|
|
69472
70092
|
if (loading) return /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-surface-500 px-3 py-4", children: "Loading…" });
|
|
69473
70093
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col flex-1 min-h-0 overflow-y-auto", children: [
|
|
69474
70094
|
error2 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] text-red-400 px-3 py-1 truncate", children: error2 }),
|
|
69475
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
70095
|
+
loadError && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[11px] text-amber-400 px-3 py-1 truncate", title: loadError, children: [
|
|
70096
|
+
"Couldn't load git state: ",
|
|
70097
|
+
loadError
|
|
70098
|
+
] }),
|
|
70099
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-3 py-2 border-b border-surface-800 flex flex-col gap-1.5", children: [
|
|
69476
70100
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
69477
70101
|
"input",
|
|
69478
70102
|
{
|
|
69479
|
-
|
|
69480
|
-
|
|
69481
|
-
|
|
69482
|
-
|
|
69483
|
-
if (e.key === "Enter") createBranch();
|
|
69484
|
-
if (e.key === "Escape") setCreating(false);
|
|
69485
|
-
},
|
|
69486
|
-
placeholder: "branch-name",
|
|
69487
|
-
className: "flex-1 bg-surface-800 border border-surface-700 rounded px-2 py-1 text-xs focus:outline-none focus:border-blue-500 placeholder-surface-600"
|
|
70103
|
+
value: filter,
|
|
70104
|
+
onChange: (e) => setFilter(e.target.value),
|
|
70105
|
+
placeholder: "Filter branches…",
|
|
70106
|
+
className: "bg-surface-800 border border-surface-700 rounded px-2 py-1 text-xs focus:outline-none focus:border-blue-500 placeholder-surface-600"
|
|
69488
70107
|
}
|
|
69489
70108
|
),
|
|
69490
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
69491
|
-
|
|
69492
|
-
|
|
70109
|
+
creating ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1.5", children: [
|
|
70110
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
70111
|
+
"input",
|
|
70112
|
+
{
|
|
70113
|
+
autoFocus: true,
|
|
70114
|
+
value: newBranch,
|
|
70115
|
+
onChange: (e) => setNewBranch(e.target.value),
|
|
70116
|
+
onKeyDown: (e) => {
|
|
70117
|
+
if (e.key === "Enter") createBranch();
|
|
70118
|
+
if (e.key === "Escape") setCreating(false);
|
|
70119
|
+
},
|
|
70120
|
+
placeholder: "branch-name",
|
|
70121
|
+
className: "flex-1 bg-surface-800 border border-surface-700 rounded px-2 py-1 text-xs focus:outline-none focus:border-blue-500 placeholder-surface-600"
|
|
70122
|
+
}
|
|
70123
|
+
),
|
|
70124
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: createBranch, className: "text-xs text-blue-400 hover:text-blue-300 px-1", children: "Create" }),
|
|
70125
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setCreating(false), className: "text-xs text-surface-500 hover:text-white px-1", children: "✕" })
|
|
70126
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { onClick: () => setCreating(true), className: "text-[11px] text-blue-400 hover:text-blue-300 transition-colors text-left", children: [
|
|
70127
|
+
"+ New branch (from ",
|
|
70128
|
+
branches.find((b) => b.current)?.name ?? "HEAD",
|
|
70129
|
+
")"
|
|
70130
|
+
] })
|
|
70131
|
+
] }),
|
|
69493
70132
|
local.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { children: [
|
|
69494
70133
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "px-3 py-1.5 text-[10px] uppercase tracking-widest text-surface-500 font-semibold", children: "Local" }),
|
|
69495
70134
|
local.map((b) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
69496
|
-
"
|
|
70135
|
+
"div",
|
|
69497
70136
|
{
|
|
69498
|
-
|
|
69499
|
-
className: `w-full flex items-center gap-2 px-3 py-1.5 text-left text-xs transition-colors ${b.current ? "text-blue-300 cursor-default" : "text-surface-300 hover:bg-surface-800/50"}`,
|
|
70137
|
+
className: `group w-full flex items-center gap-2 px-3 py-1.5 text-xs transition-colors ${b.current ? "bg-blue-900/30 text-blue-200" : "text-surface-300 hover:bg-surface-800/50"}`,
|
|
69500
70138
|
children: [
|
|
69501
70139
|
b.current ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-blue-400 text-[10px]", children: "●" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-3" }),
|
|
69502
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
70140
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
70141
|
+
"button",
|
|
70142
|
+
{
|
|
70143
|
+
onClick: () => !b.current && checkout(b.name, false),
|
|
70144
|
+
disabled: b.current,
|
|
70145
|
+
className: "flex-1 text-left font-mono truncate disabled:cursor-default",
|
|
70146
|
+
title: b.upstream ? `tracks ${b.upstream}` : "no upstream",
|
|
70147
|
+
children: b.name
|
|
70148
|
+
}
|
|
70149
|
+
),
|
|
70150
|
+
b.behind ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] px-1 rounded bg-amber-900/40 text-amber-300", title: `${b.behind} commits behind ${b.upstream}`, children: [
|
|
70151
|
+
"↓",
|
|
70152
|
+
b.behind
|
|
70153
|
+
] }) : null,
|
|
70154
|
+
b.ahead ? /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-[10px] px-1 rounded bg-emerald-900/40 text-emerald-300", title: `${b.ahead} commits ahead of ${b.upstream}`, children: [
|
|
70155
|
+
"↑",
|
|
70156
|
+
b.ahead
|
|
70157
|
+
] }) : null,
|
|
70158
|
+
!b.current && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
70159
|
+
"button",
|
|
70160
|
+
{
|
|
70161
|
+
onClick: () => deleteBranch(b.name),
|
|
70162
|
+
className: "opacity-0 group-hover:opacity-100 text-surface-500 hover:text-red-400 transition-all text-xs leading-none",
|
|
70163
|
+
title: `Delete ${b.name}`,
|
|
70164
|
+
children: "✕"
|
|
70165
|
+
}
|
|
70166
|
+
)
|
|
69503
70167
|
]
|
|
69504
70168
|
},
|
|
69505
70169
|
b.name
|
|
69506
70170
|
))
|
|
69507
70171
|
] }),
|
|
69508
70172
|
remote.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { children: [
|
|
69509
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "px-3 py-1.5 text-[10px] uppercase tracking-widest text-surface-500 font-semibold", children: "Remote
|
|
70173
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "px-3 py-1.5 text-[10px] uppercase tracking-widest text-surface-500 font-semibold", children: "Remote" }),
|
|
69510
70174
|
remote.map((b) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
69511
70175
|
"button",
|
|
69512
70176
|
{
|
|
69513
|
-
onClick: () => checkout(b.name,
|
|
70177
|
+
onClick: () => checkout(b.name, false),
|
|
69514
70178
|
className: "w-full flex items-center gap-2 px-3 py-1.5 text-left text-xs text-surface-400 hover:bg-surface-800/50 hover:text-surface-200 transition-colors",
|
|
70179
|
+
title: "Click to check out — creates a local tracking branch if needed",
|
|
69515
70180
|
children: [
|
|
69516
70181
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-3" }),
|
|
69517
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: b.name })
|
|
70182
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono truncate", children: b.name })
|
|
69518
70183
|
]
|
|
69519
70184
|
},
|
|
69520
70185
|
b.name
|
|
69521
70186
|
))
|
|
69522
70187
|
] }),
|
|
70188
|
+
q && local.length === 0 && remote.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "px-3 py-3 text-[11px] text-surface-500", children: [
|
|
70189
|
+
'No branches match "',
|
|
70190
|
+
filter,
|
|
70191
|
+
'".'
|
|
70192
|
+
] }),
|
|
69523
70193
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "border-t border-surface-800 mt-1", children: [
|
|
69524
70194
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-3 py-1.5 flex items-center justify-between", children: [
|
|
69525
70195
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] uppercase tracking-widest text-surface-500 font-semibold", children: "Remotes" }),
|
|
@@ -69709,11 +70379,12 @@ function CiTab() {
|
|
|
69709
70379
|
const [written, setWritten] = reactExports.useState(false);
|
|
69710
70380
|
const [error2, setError] = reactExports.useState(null);
|
|
69711
70381
|
reactExports.useEffect(() => {
|
|
69712
|
-
electron$
|
|
70382
|
+
electron$2.gitRemotes().then((r) => {
|
|
69713
70383
|
setRemotes(r);
|
|
69714
70384
|
const detected = detectPlatform(r);
|
|
69715
70385
|
setPlatform(detected);
|
|
69716
|
-
}).catch(() => {
|
|
70386
|
+
}).catch((err) => {
|
|
70387
|
+
console.warn("GitPanel: failed to read git remotes", err);
|
|
69717
70388
|
});
|
|
69718
70389
|
}, []);
|
|
69719
70390
|
reactExports.useEffect(() => {
|
|
@@ -69726,7 +70397,7 @@ function CiTab() {
|
|
|
69726
70397
|
async function write() {
|
|
69727
70398
|
try {
|
|
69728
70399
|
setError(null);
|
|
69729
|
-
await electron$
|
|
70400
|
+
await electron$2.gitWriteCiFile(ciFilePath(platform), preview);
|
|
69730
70401
|
setWritten(true);
|
|
69731
70402
|
} catch (e) {
|
|
69732
70403
|
setError(String(e));
|
|
@@ -69822,9 +70493,9 @@ function GitPanel() {
|
|
|
69822
70493
|
const [loading, setLoading] = reactExports.useState(true);
|
|
69823
70494
|
const refresh = reactExports.useCallback(async () => {
|
|
69824
70495
|
try {
|
|
69825
|
-
const repo = await electron$
|
|
70496
|
+
const repo = await electron$2.gitIsRepo();
|
|
69826
70497
|
setIsRepo(repo);
|
|
69827
|
-
if (repo) setStatus(await electron$
|
|
70498
|
+
if (repo) setStatus(await electron$2.gitStatus());
|
|
69828
70499
|
} catch {
|
|
69829
70500
|
setIsRepo(false);
|
|
69830
70501
|
} finally {
|
|
@@ -69844,7 +70515,7 @@ function GitPanel() {
|
|
|
69844
70515
|
"button",
|
|
69845
70516
|
{
|
|
69846
70517
|
onClick: async () => {
|
|
69847
|
-
await electron$
|
|
70518
|
+
await electron$2.gitInit();
|
|
69848
70519
|
refresh();
|
|
69849
70520
|
},
|
|
69850
70521
|
className: "px-3 py-1.5 bg-surface-800 hover:bg-surface-700 rounded text-xs transition-colors",
|
|
@@ -69884,6 +70555,62 @@ function GitPanel() {
|
|
|
69884
70555
|
tab === "ci" && /* @__PURE__ */ jsxRuntimeExports.jsx(CiTab, {})
|
|
69885
70556
|
] });
|
|
69886
70557
|
}
|
|
70558
|
+
const { electron: electron$1 } = window;
|
|
70559
|
+
function GitDiffPane() {
|
|
70560
|
+
const active = useStore((s) => s.activeGitDiff);
|
|
70561
|
+
const setActive2 = useStore((s) => s.setActiveGitDiff);
|
|
70562
|
+
const [diff, setDiff] = reactExports.useState("");
|
|
70563
|
+
const [loading, setLoading] = reactExports.useState(false);
|
|
70564
|
+
const [error2, setError] = reactExports.useState(null);
|
|
70565
|
+
reactExports.useEffect(() => {
|
|
70566
|
+
if (!active) return;
|
|
70567
|
+
let cancelled = false;
|
|
70568
|
+
setLoading(true);
|
|
70569
|
+
setError(null);
|
|
70570
|
+
(async () => {
|
|
70571
|
+
try {
|
|
70572
|
+
const d = active.staged ? await electron$1.gitDiffStaged(active.path) : await electron$1.gitDiff(active.path);
|
|
70573
|
+
if (!cancelled) setDiff(d);
|
|
70574
|
+
} catch (err) {
|
|
70575
|
+
if (!cancelled) setError(err instanceof Error ? err.message : String(err));
|
|
70576
|
+
} finally {
|
|
70577
|
+
if (!cancelled) setLoading(false);
|
|
70578
|
+
}
|
|
70579
|
+
})();
|
|
70580
|
+
return () => {
|
|
70581
|
+
cancelled = true;
|
|
70582
|
+
};
|
|
70583
|
+
}, [active?.path, active?.staged]);
|
|
70584
|
+
if (!active) {
|
|
70585
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 flex items-center justify-center text-xs text-surface-500", children: "Select a changed file in the sidebar to view its diff." });
|
|
70586
|
+
}
|
|
70587
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-h-0 flex flex-col", children: [
|
|
70588
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-2 border-b border-surface-800 flex items-center gap-3 flex-shrink-0", children: [
|
|
70589
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
70590
|
+
"span",
|
|
70591
|
+
{
|
|
70592
|
+
className: `text-[10px] uppercase tracking-wider font-semibold ${active.staged ? "text-emerald-400" : "text-amber-400"}`,
|
|
70593
|
+
children: active.staged ? "Staged" : "Working tree"
|
|
70594
|
+
}
|
|
70595
|
+
),
|
|
70596
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-mono text-surface-200 truncate flex-1", children: active.path }),
|
|
70597
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
70598
|
+
"button",
|
|
70599
|
+
{
|
|
70600
|
+
onClick: () => setActive2(null),
|
|
70601
|
+
className: "text-surface-500 hover:text-white text-xs leading-none",
|
|
70602
|
+
title: "Close diff",
|
|
70603
|
+
children: "✕"
|
|
70604
|
+
}
|
|
70605
|
+
)
|
|
70606
|
+
] }),
|
|
70607
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-auto min-h-0", children: [
|
|
70608
|
+
loading && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-surface-500 p-4", children: "Loading diff…" }),
|
|
70609
|
+
error2 && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-red-400 p-4", children: error2 }),
|
|
70610
|
+
!loading && !error2 && /* @__PURE__ */ jsxRuntimeExports.jsx(DiffViewer, { diff })
|
|
70611
|
+
] })
|
|
70612
|
+
] });
|
|
70613
|
+
}
|
|
69887
70614
|
function CommandPalette() {
|
|
69888
70615
|
const open = useStore((s) => s.commandPaletteOpen);
|
|
69889
70616
|
const setOpen = useStore((s) => s.setCommandPaletteOpen);
|
|
@@ -70241,7 +70968,7 @@ function App() {
|
|
|
70241
70968
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "#6aa3c8" }, children: "Spector" }),
|
|
70242
70969
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-[10px] font-normal opacity-50", children: [
|
|
70243
70970
|
"v",
|
|
70244
|
-
"0.2.
|
|
70971
|
+
"0.2.4"
|
|
70245
70972
|
] }),
|
|
70246
70973
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mx-2 opacity-30", children: "·" }),
|
|
70247
70974
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -70438,7 +71165,7 @@ function App() {
|
|
|
70438
71165
|
}
|
|
70439
71166
|
)
|
|
70440
71167
|
] }),
|
|
70441
|
-
sidebarTab === "contracts" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ContractResultsPanel, {}) }) : sidebarTab === "mocks" && recorderRunning ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
71168
|
+
sidebarTab === "git" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0 flex flex-col", children: /* @__PURE__ */ jsxRuntimeExports.jsx(GitDiffPane, {}) }) : sidebarTab === "contracts" ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ContractResultsPanel, {}) }) : sidebarTab === "mocks" && recorderRunning ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
70442
71169
|
RecorderPanel,
|
|
70443
71170
|
{
|
|
70444
71171
|
defaultTargetMockId: recorderTargetMockId,
|