@testsmith/api-spector 0.1.4 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/out/main/chunks/{request-handler-CvqESn11.js → request-handler-BEFvdSz6.js} +2 -0
- package/out/main/index.js +10 -5
- package/out/main/runner.js +51 -22
- package/out/renderer/assets/index-BZqTnf6_.css +2 -0
- package/out/renderer/assets/{index-D-jqC4fC.js → index-D5-etZ-W.js} +740 -193
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
- package/out/renderer/assets/index-Dhvg6Rst.css +0 -2
|
@@ -905,6 +905,7 @@ function checkDCE$1() {
|
|
|
905
905
|
reactDom.exports = reactDom_production;
|
|
906
906
|
}
|
|
907
907
|
var reactDomExports = reactDom.exports;
|
|
908
|
+
const ReactDOM$2 = /* @__PURE__ */ getDefaultExportFromCjs(reactDomExports);
|
|
908
909
|
/**
|
|
909
910
|
* @license React
|
|
910
911
|
* react-dom-client.production.js
|
|
@@ -13410,9 +13411,10 @@ const useStore = create()(
|
|
|
13410
13411
|
activeCollectionId: null,
|
|
13411
13412
|
activeEnvironmentId: localStorage.getItem("activeEnvironmentId") ?? null,
|
|
13412
13413
|
globals: {},
|
|
13414
|
+
sessionVars: {},
|
|
13413
13415
|
showGeneratorPanel: false,
|
|
13414
13416
|
theme: localStorage.getItem("theme") ?? "dark",
|
|
13415
|
-
zoom: Number(localStorage.getItem("zoom") ?? "1"),
|
|
13417
|
+
zoom: Number(localStorage.getItem("zoom") ?? "1.1"),
|
|
13416
13418
|
history: [],
|
|
13417
13419
|
sidebarTab: "collections",
|
|
13418
13420
|
workspaceSettingsOpen: false,
|
|
@@ -13446,6 +13448,7 @@ const useStore = create()(
|
|
|
13446
13448
|
s.activeTabId = null;
|
|
13447
13449
|
s.activeCollectionId = null;
|
|
13448
13450
|
s.globals = {};
|
|
13451
|
+
s.sessionVars = {};
|
|
13449
13452
|
s.runnerResults = [];
|
|
13450
13453
|
s.runnerRunning = false;
|
|
13451
13454
|
s.runnerModal = { open: false, collectionId: null, folderId: null, filterTags: [] };
|
|
@@ -13639,6 +13642,12 @@ const useStore = create()(
|
|
|
13639
13642
|
s.collections[id2].data.tls = tls;
|
|
13640
13643
|
s.collections[id2].dirty = true;
|
|
13641
13644
|
}),
|
|
13645
|
+
updateCollectionAuthAndHeaders: (id2, auth, headers) => set2((s) => {
|
|
13646
|
+
if (!s.collections[id2]) return;
|
|
13647
|
+
s.collections[id2].data.auth = auth;
|
|
13648
|
+
s.collections[id2].data.headers = headers;
|
|
13649
|
+
s.collections[id2].dirty = true;
|
|
13650
|
+
}),
|
|
13642
13651
|
// ── Folder CRUD ───────────────────────────────────────────────────────────
|
|
13643
13652
|
addFolder: (collectionId, parentFolderId, name2) => set2((s) => {
|
|
13644
13653
|
const col = s.collections[collectionId]?.data;
|
|
@@ -13758,6 +13767,37 @@ const useStore = create()(
|
|
|
13758
13767
|
s.tabs.push(tab);
|
|
13759
13768
|
s.activeTabId = tab.id;
|
|
13760
13769
|
}),
|
|
13770
|
+
moveRequest: (srcCollectionId, requestId, destCollectionId, destFolderId, destIndex) => set2((s) => {
|
|
13771
|
+
const srcCol = s.collections[srcCollectionId]?.data;
|
|
13772
|
+
const destCol = s.collections[destCollectionId]?.data;
|
|
13773
|
+
if (!srcCol || !destCol) return;
|
|
13774
|
+
const req = srcCol.requests[requestId];
|
|
13775
|
+
if (!req) return;
|
|
13776
|
+
const srcFolder = findFolderContaining(srcCol.rootFolder, requestId);
|
|
13777
|
+
const srcIdx = srcFolder ? srcFolder.requestIds.indexOf(requestId) : -1;
|
|
13778
|
+
removeFromFolder(srcCol.rootFolder, requestId);
|
|
13779
|
+
s.collections[srcCollectionId].dirty = true;
|
|
13780
|
+
if (srcCollectionId !== destCollectionId) {
|
|
13781
|
+
delete srcCol.requests[requestId];
|
|
13782
|
+
destCol.requests[requestId] = req;
|
|
13783
|
+
const tab = s.tabs.find((t2) => t2.requestId === requestId);
|
|
13784
|
+
if (tab) tab.collectionId = destCollectionId;
|
|
13785
|
+
}
|
|
13786
|
+
const destFolder = findFolder(destCol.rootFolder, destFolderId);
|
|
13787
|
+
if (destFolder) {
|
|
13788
|
+
if (destIndex !== void 0) {
|
|
13789
|
+
let adjusted = destIndex;
|
|
13790
|
+
if (srcCollectionId === destCollectionId && srcFolder?.id === destFolder.id && srcIdx < destIndex) {
|
|
13791
|
+
adjusted--;
|
|
13792
|
+
}
|
|
13793
|
+
adjusted = Math.max(0, Math.min(adjusted, destFolder.requestIds.length));
|
|
13794
|
+
destFolder.requestIds.splice(adjusted, 0, requestId);
|
|
13795
|
+
} else {
|
|
13796
|
+
destFolder.requestIds.push(requestId);
|
|
13797
|
+
}
|
|
13798
|
+
}
|
|
13799
|
+
s.collections[destCollectionId].dirty = true;
|
|
13800
|
+
}),
|
|
13761
13801
|
// ── Tags ──────────────────────────────────────────────────────────────────
|
|
13762
13802
|
updateFolderTags: (collectionId, folderId, tags2) => set2((s) => {
|
|
13763
13803
|
const col = s.collections[collectionId]?.data;
|
|
@@ -13802,16 +13842,12 @@ const useStore = create()(
|
|
|
13802
13842
|
const state = useStore.getState();
|
|
13803
13843
|
const colEntry = Object.values(state.collections).find((c) => c.data.requests[requestId]);
|
|
13804
13844
|
if (!colEntry) return { auth: null, headers: [] };
|
|
13845
|
+
let inheritedAuth = colEntry.data.auth && colEntry.data.auth.type !== "none" ? colEntry.data.auth : null;
|
|
13846
|
+
let inheritedHeaders = colEntry.data.headers?.filter((h) => h.enabled && h.key) ?? [];
|
|
13805
13847
|
const path = findFolderPath(colEntry.data.rootFolder, requestId);
|
|
13806
|
-
let inheritedAuth = null;
|
|
13807
|
-
let inheritedHeaders = [];
|
|
13808
13848
|
for (const folder of path) {
|
|
13809
|
-
if (folder.auth && folder.auth.type !== "none")
|
|
13810
|
-
|
|
13811
|
-
}
|
|
13812
|
-
if (folder.headers && folder.headers.length > 0) {
|
|
13813
|
-
inheritedHeaders = [...inheritedHeaders, ...folder.headers];
|
|
13814
|
-
}
|
|
13849
|
+
if (folder.auth && folder.auth.type !== "none") inheritedAuth = folder.auth;
|
|
13850
|
+
if (folder.headers?.length) inheritedHeaders = [...inheritedHeaders, ...folder.headers];
|
|
13815
13851
|
}
|
|
13816
13852
|
return { auth: inheritedAuth, headers: inheritedHeaders };
|
|
13817
13853
|
},
|
|
@@ -13868,6 +13904,7 @@ const useStore = create()(
|
|
|
13868
13904
|
}
|
|
13869
13905
|
}
|
|
13870
13906
|
s.globals = { ...s.globals, ...result.updatedGlobals };
|
|
13907
|
+
s.sessionVars = { ...s.sessionVars, ...result.updatedLocalVars };
|
|
13871
13908
|
}),
|
|
13872
13909
|
// ── Theme & zoom ──────────────────────────────────────────────────────────
|
|
13873
13910
|
setTheme: (t2) => set2((s) => {
|
|
@@ -34505,18 +34542,35 @@ function mockScriptCompletionExtension() {
|
|
|
34505
34542
|
]
|
|
34506
34543
|
});
|
|
34507
34544
|
}
|
|
34545
|
+
const SCRIPT_SET_RE = /\bsp\.(?:variables|collectionVariables|environment|globals)\.set\(\s*["']([^"']+)["']/g;
|
|
34546
|
+
function extractScriptVarNames(script) {
|
|
34547
|
+
if (!script) return [];
|
|
34548
|
+
const names2 = [];
|
|
34549
|
+
let m;
|
|
34550
|
+
SCRIPT_SET_RE.lastIndex = 0;
|
|
34551
|
+
while ((m = SCRIPT_SET_RE.exec(script)) !== null) names2.push(m[1]);
|
|
34552
|
+
return names2;
|
|
34553
|
+
}
|
|
34508
34554
|
function useVarNames() {
|
|
34509
34555
|
const activeEnvironmentId = useStore((s) => s.activeEnvironmentId);
|
|
34510
34556
|
const activeCollectionId = useStore((s) => s.activeCollectionId);
|
|
34511
34557
|
const environments = useStore((s) => s.environments);
|
|
34512
34558
|
const collections = useStore((s) => s.collections);
|
|
34513
34559
|
const globals = useStore((s) => s.globals);
|
|
34560
|
+
const sessionVars = useStore((s) => s.sessionVars);
|
|
34514
34561
|
return reactExports.useMemo(() => {
|
|
34515
34562
|
const names2 = /* @__PURE__ */ new Set();
|
|
34516
34563
|
Object.keys(globals).forEach((k) => names2.add(k));
|
|
34564
|
+
Object.keys(sessionVars).forEach((k) => names2.add(k));
|
|
34517
34565
|
if (activeCollectionId) {
|
|
34518
|
-
const
|
|
34519
|
-
|
|
34566
|
+
const col = collections[activeCollectionId]?.data;
|
|
34567
|
+
if (col) {
|
|
34568
|
+
Object.keys(col.collectionVariables ?? {}).forEach((k) => names2.add(k));
|
|
34569
|
+
for (const req of Object.values(col.requests)) {
|
|
34570
|
+
extractScriptVarNames(req.preRequestScript).forEach((k) => names2.add(k));
|
|
34571
|
+
extractScriptVarNames(req.postRequestScript).forEach((k) => names2.add(k));
|
|
34572
|
+
}
|
|
34573
|
+
}
|
|
34520
34574
|
}
|
|
34521
34575
|
if (activeEnvironmentId) {
|
|
34522
34576
|
const envVars = environments[activeEnvironmentId]?.data.variables ?? [];
|
|
@@ -34528,7 +34582,8 @@ function useVarNames() {
|
|
|
34528
34582
|
activeCollectionId,
|
|
34529
34583
|
environments,
|
|
34530
34584
|
collections,
|
|
34531
|
-
globals
|
|
34585
|
+
globals,
|
|
34586
|
+
sessionVars
|
|
34532
34587
|
]);
|
|
34533
34588
|
}
|
|
34534
34589
|
function useVarValues() {
|
|
@@ -34566,24 +34621,80 @@ function parseVarTokens(str) {
|
|
|
34566
34621
|
}
|
|
34567
34622
|
return found;
|
|
34568
34623
|
}
|
|
34569
|
-
function
|
|
34624
|
+
function PortalDropdown({
|
|
34625
|
+
pos,
|
|
34626
|
+
items: items2,
|
|
34627
|
+
activeIndex,
|
|
34628
|
+
mode,
|
|
34629
|
+
onPick
|
|
34630
|
+
}) {
|
|
34631
|
+
return ReactDOM$2.createPortal(
|
|
34632
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34633
|
+
"ul",
|
|
34634
|
+
{
|
|
34635
|
+
style: { position: "fixed", top: pos.top, left: pos.left, minWidth: pos.minWidth, zIndex: 9999 },
|
|
34636
|
+
className: "max-h-52 overflow-y-auto bg-surface-800 border border-surface-600 rounded shadow-xl text-xs",
|
|
34637
|
+
children: items2.map((s, i) => /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34638
|
+
"button",
|
|
34639
|
+
{
|
|
34640
|
+
onMouseDown: (e) => {
|
|
34641
|
+
e.preventDefault();
|
|
34642
|
+
onPick(s);
|
|
34643
|
+
},
|
|
34644
|
+
className: `w-full text-left px-3 py-1.5 font-mono transition-colors ${i === activeIndex ? "bg-blue-600 text-white" : "hover:bg-surface-700"}`,
|
|
34645
|
+
children: mode === "var" ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
34646
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-500", children: "{{" }),
|
|
34647
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: s }),
|
|
34648
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-500", children: "}}" })
|
|
34649
|
+
] }) : s
|
|
34650
|
+
}
|
|
34651
|
+
) }, s))
|
|
34652
|
+
}
|
|
34653
|
+
),
|
|
34654
|
+
document.body
|
|
34655
|
+
);
|
|
34656
|
+
}
|
|
34657
|
+
function VarInput({ value, onChange, className, wrapperClassName, staticSuggestions, ...rest }) {
|
|
34570
34658
|
const varNames = useVarNames();
|
|
34571
34659
|
const varValues = useVarValues();
|
|
34572
34660
|
const inputRef = reactExports.useRef(null);
|
|
34573
34661
|
const [suggestions, setSuggestions] = reactExports.useState([]);
|
|
34662
|
+
const [suggestionMode, setSuggestionMode] = reactExports.useState("var");
|
|
34574
34663
|
const [activeIndex, setActiveIndex] = reactExports.useState(-1);
|
|
34664
|
+
const [dropPos, setDropPos] = reactExports.useState(null);
|
|
34575
34665
|
const [showPreview, setShowPreview] = reactExports.useState(false);
|
|
34666
|
+
reactExports.useEffect(() => {
|
|
34667
|
+
if (suggestions.length === 0) {
|
|
34668
|
+
setDropPos(null);
|
|
34669
|
+
return;
|
|
34670
|
+
}
|
|
34671
|
+
const el = inputRef.current;
|
|
34672
|
+
if (!el) return;
|
|
34673
|
+
const r = el.getBoundingClientRect();
|
|
34674
|
+
setDropPos({ top: r.bottom + 2, left: r.left, minWidth: r.width });
|
|
34675
|
+
}, [suggestions.length]);
|
|
34576
34676
|
function detectQuery(val, cursor2) {
|
|
34577
34677
|
const before = val.slice(0, cursor2);
|
|
34578
|
-
const
|
|
34579
|
-
if (
|
|
34678
|
+
const varMatch = /\{\{(\w*)$/.exec(before);
|
|
34679
|
+
if (varMatch) {
|
|
34680
|
+
const q = varMatch[1].toLowerCase();
|
|
34681
|
+
const filtered = varNames.filter((n) => n.toLowerCase().includes(q));
|
|
34682
|
+
setSuggestions(filtered);
|
|
34683
|
+
setSuggestionMode("var");
|
|
34684
|
+
setActiveIndex(-1);
|
|
34685
|
+
} else if (staticSuggestions) {
|
|
34686
|
+
const q = val.toLowerCase();
|
|
34687
|
+
const filtered = q ? staticSuggestions.filter((s) => s.toLowerCase().includes(q)).sort((a, b) => {
|
|
34688
|
+
const aP = a.toLowerCase().startsWith(q) ? 0 : 1;
|
|
34689
|
+
const bP = b.toLowerCase().startsWith(q) ? 0 : 1;
|
|
34690
|
+
return aP - bP;
|
|
34691
|
+
}).slice(0, 20) : staticSuggestions.slice(0, 20);
|
|
34692
|
+
setSuggestions(filtered);
|
|
34693
|
+
setSuggestionMode("static");
|
|
34694
|
+
setActiveIndex(-1);
|
|
34695
|
+
} else {
|
|
34580
34696
|
setSuggestions([]);
|
|
34581
|
-
return;
|
|
34582
34697
|
}
|
|
34583
|
-
const q = match[1].toLowerCase();
|
|
34584
|
-
const filtered = varNames.filter((n) => n.toLowerCase().includes(q));
|
|
34585
|
-
setSuggestions(filtered);
|
|
34586
|
-
setActiveIndex(-1);
|
|
34587
34698
|
}
|
|
34588
34699
|
function handleChange(e) {
|
|
34589
34700
|
const newVal = e.target.value;
|
|
@@ -34591,6 +34702,10 @@ function VarInput({ value, onChange, className, wrapperClassName, ...rest }) {
|
|
|
34591
34702
|
onChange(newVal);
|
|
34592
34703
|
detectQuery(newVal, cursor2);
|
|
34593
34704
|
}
|
|
34705
|
+
function handleFocus(e) {
|
|
34706
|
+
detectQuery(value, e.target.selectionStart ?? value.length);
|
|
34707
|
+
rest.onFocus?.(e);
|
|
34708
|
+
}
|
|
34594
34709
|
function handleKeyDown(e) {
|
|
34595
34710
|
if (suggestions.length === 0) return;
|
|
34596
34711
|
if (e.key === "ArrowDown") {
|
|
@@ -34606,21 +34721,28 @@ function VarInput({ value, onChange, className, wrapperClassName, ...rest }) {
|
|
|
34606
34721
|
setSuggestions([]);
|
|
34607
34722
|
}
|
|
34608
34723
|
}
|
|
34609
|
-
const apply = reactExports.useCallback((
|
|
34724
|
+
const apply = reactExports.useCallback((suggestion) => {
|
|
34725
|
+
if (suggestionMode === "static") {
|
|
34726
|
+
onChange(suggestion);
|
|
34727
|
+
setSuggestions([]);
|
|
34728
|
+
return;
|
|
34729
|
+
}
|
|
34610
34730
|
const el = inputRef.current;
|
|
34611
34731
|
const cursor2 = el?.selectionStart ?? value.length;
|
|
34612
34732
|
const before = value.slice(0, cursor2);
|
|
34613
34733
|
const after = value.slice(cursor2);
|
|
34614
34734
|
const match = /\{\{(\w*)$/.exec(before);
|
|
34615
34735
|
if (!match) return;
|
|
34616
|
-
const newVal = before.slice(0, match.index) + `{{${
|
|
34617
|
-
const newCursor = match.index +
|
|
34736
|
+
const newVal = before.slice(0, match.index) + `{{${suggestion}}}` + after;
|
|
34737
|
+
const newCursor = match.index + suggestion.length + 4;
|
|
34618
34738
|
onChange(newVal);
|
|
34619
34739
|
setSuggestions([]);
|
|
34620
34740
|
requestAnimationFrame(() => el?.setSelectionRange(newCursor, newCursor));
|
|
34621
|
-
}, [value, onChange]);
|
|
34622
|
-
function handleBlur() {
|
|
34741
|
+
}, [suggestionMode, value, onChange]);
|
|
34742
|
+
function handleBlur(e) {
|
|
34623
34743
|
setTimeout(() => setSuggestions([]), 150);
|
|
34744
|
+
setShowPreview(false);
|
|
34745
|
+
rest.onBlur?.(e);
|
|
34624
34746
|
}
|
|
34625
34747
|
const tokens = parseVarTokens(value);
|
|
34626
34748
|
const hasVars = tokens.length > 0;
|
|
@@ -34628,6 +34750,7 @@ function VarInput({ value, onChange, className, wrapperClassName, ...rest }) {
|
|
|
34628
34750
|
name: name2,
|
|
34629
34751
|
resolved: varValues[name2] ?? null
|
|
34630
34752
|
}));
|
|
34753
|
+
const { onFocus: _f, onBlur: _b, ...inputRest } = rest;
|
|
34631
34754
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
34632
34755
|
"div",
|
|
34633
34756
|
{
|
|
@@ -34642,26 +34765,22 @@ function VarInput({ value, onChange, className, wrapperClassName, ...rest }) {
|
|
|
34642
34765
|
value,
|
|
34643
34766
|
onChange: handleChange,
|
|
34644
34767
|
onKeyDown: handleKeyDown,
|
|
34768
|
+
onFocus: handleFocus,
|
|
34645
34769
|
onBlur: handleBlur,
|
|
34646
34770
|
className: `w-full ${className ?? ""}`,
|
|
34647
|
-
...
|
|
34771
|
+
...inputRest
|
|
34648
34772
|
}
|
|
34649
34773
|
),
|
|
34650
|
-
suggestions.length > 0 &&
|
|
34651
|
-
|
|
34774
|
+
suggestions.length > 0 && dropPos && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34775
|
+
PortalDropdown,
|
|
34652
34776
|
{
|
|
34653
|
-
|
|
34654
|
-
|
|
34655
|
-
|
|
34656
|
-
|
|
34657
|
-
|
|
34658
|
-
children: [
|
|
34659
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-500", children: "{{" }),
|
|
34660
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: name2 }),
|
|
34661
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-500", children: "}}" })
|
|
34662
|
-
]
|
|
34777
|
+
pos: dropPos,
|
|
34778
|
+
items: suggestions,
|
|
34779
|
+
activeIndex,
|
|
34780
|
+
mode: suggestionMode,
|
|
34781
|
+
onPick: apply
|
|
34663
34782
|
}
|
|
34664
|
-
)
|
|
34783
|
+
),
|
|
34665
34784
|
showPreview && suggestions.length === 0 && previewItems.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute left-0 top-full mt-0.5 z-50 bg-surface-800 border border-surface-600 rounded shadow-xl text-xs min-w-[220px] max-w-[420px]", children: previewItems.map(({ name: name2, resolved }) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-baseline gap-2 px-3 py-1.5 border-b border-surface-700 last:border-0", children: [
|
|
34666
34785
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-blue-400 shrink-0", children: `{{${name2}}}` }),
|
|
34667
34786
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-500 mx-0.5", children: "→" }),
|
|
@@ -34671,7 +34790,113 @@ function VarInput({ value, onChange, className, wrapperClassName, ...rest }) {
|
|
|
34671
34790
|
}
|
|
34672
34791
|
);
|
|
34673
34792
|
}
|
|
34674
|
-
|
|
34793
|
+
const HEADER_NAMES = [
|
|
34794
|
+
"Accept",
|
|
34795
|
+
"Authorization",
|
|
34796
|
+
"Content-Type",
|
|
34797
|
+
"Cache-Control",
|
|
34798
|
+
"Accept-Language",
|
|
34799
|
+
"Accept-Encoding",
|
|
34800
|
+
"Connection",
|
|
34801
|
+
"Content-Encoding",
|
|
34802
|
+
"Content-Length",
|
|
34803
|
+
"Cookie",
|
|
34804
|
+
"Host",
|
|
34805
|
+
"Origin",
|
|
34806
|
+
"Referer",
|
|
34807
|
+
"User-Agent",
|
|
34808
|
+
"X-Api-Key",
|
|
34809
|
+
"X-Auth-Token",
|
|
34810
|
+
"X-Correlation-ID",
|
|
34811
|
+
"X-Request-ID",
|
|
34812
|
+
"X-Forwarded-For",
|
|
34813
|
+
"X-Requested-With",
|
|
34814
|
+
"X-Tenant-ID",
|
|
34815
|
+
"If-Match",
|
|
34816
|
+
"If-None-Match",
|
|
34817
|
+
"If-Modified-Since",
|
|
34818
|
+
"If-Unmodified-Since",
|
|
34819
|
+
"If-Range",
|
|
34820
|
+
"Date",
|
|
34821
|
+
"Expect",
|
|
34822
|
+
"From",
|
|
34823
|
+
"Max-Forwards",
|
|
34824
|
+
"Pragma",
|
|
34825
|
+
"Proxy-Authorization",
|
|
34826
|
+
"Range",
|
|
34827
|
+
"TE",
|
|
34828
|
+
"Upgrade",
|
|
34829
|
+
"Via",
|
|
34830
|
+
"Warning"
|
|
34831
|
+
];
|
|
34832
|
+
const HEADER_VALUE_SUGGESTIONS = {
|
|
34833
|
+
"accept": [
|
|
34834
|
+
"application/json",
|
|
34835
|
+
"application/xml",
|
|
34836
|
+
"text/html",
|
|
34837
|
+
"text/plain",
|
|
34838
|
+
"application/ld+json",
|
|
34839
|
+
"*/*"
|
|
34840
|
+
],
|
|
34841
|
+
"content-type": [
|
|
34842
|
+
"application/json",
|
|
34843
|
+
"application/xml",
|
|
34844
|
+
"application/x-www-form-urlencoded",
|
|
34845
|
+
"multipart/form-data",
|
|
34846
|
+
"text/plain",
|
|
34847
|
+
"text/html",
|
|
34848
|
+
"text/xml",
|
|
34849
|
+
"application/octet-stream",
|
|
34850
|
+
"application/graphql",
|
|
34851
|
+
"application/ld+json"
|
|
34852
|
+
],
|
|
34853
|
+
"cache-control": [
|
|
34854
|
+
"no-cache",
|
|
34855
|
+
"no-store",
|
|
34856
|
+
"max-age=0",
|
|
34857
|
+
"max-age=3600",
|
|
34858
|
+
"must-revalidate",
|
|
34859
|
+
"private",
|
|
34860
|
+
"public"
|
|
34861
|
+
],
|
|
34862
|
+
"connection": [
|
|
34863
|
+
"keep-alive",
|
|
34864
|
+
"close",
|
|
34865
|
+
"upgrade"
|
|
34866
|
+
],
|
|
34867
|
+
"accept-encoding": [
|
|
34868
|
+
"gzip",
|
|
34869
|
+
"deflate",
|
|
34870
|
+
"br",
|
|
34871
|
+
"gzip, deflate, br",
|
|
34872
|
+
"identity",
|
|
34873
|
+
"*"
|
|
34874
|
+
],
|
|
34875
|
+
"accept-language": [
|
|
34876
|
+
"en-US",
|
|
34877
|
+
"en-US,en;q=0.9",
|
|
34878
|
+
"en",
|
|
34879
|
+
"*"
|
|
34880
|
+
],
|
|
34881
|
+
"pragma": [
|
|
34882
|
+
"no-cache"
|
|
34883
|
+
],
|
|
34884
|
+
"transfer-encoding": [
|
|
34885
|
+
"chunked",
|
|
34886
|
+
"gzip",
|
|
34887
|
+
"deflate",
|
|
34888
|
+
"compress",
|
|
34889
|
+
"identity"
|
|
34890
|
+
],
|
|
34891
|
+
"upgrade": [
|
|
34892
|
+
"websocket",
|
|
34893
|
+
"HTTP/2.0"
|
|
34894
|
+
]
|
|
34895
|
+
};
|
|
34896
|
+
function getValueSuggestions(headerName) {
|
|
34897
|
+
return HEADER_VALUE_SUGGESTIONS[headerName.toLowerCase()];
|
|
34898
|
+
}
|
|
34899
|
+
function KVTable({ rows, onChange, keyPlaceholder = "Key", valuePlaceholder = "Value", headerMode }) {
|
|
34675
34900
|
const [descVisible, setDescVisible] = reactExports.useState(
|
|
34676
34901
|
() => new Set(rows.map((r, i) => r.description ? i : -1).filter((i) => i >= 0))
|
|
34677
34902
|
);
|
|
@@ -34725,7 +34950,8 @@ function KVTable({ rows, onChange, keyPlaceholder = "Key", valuePlaceholder = "V
|
|
|
34725
34950
|
onChange: (v) => update(idx, { key: v }),
|
|
34726
34951
|
placeholder: keyPlaceholder,
|
|
34727
34952
|
wrapperClassName: "flex-1",
|
|
34728
|
-
className: "bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500 font-mono"
|
|
34953
|
+
className: "bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500 font-mono",
|
|
34954
|
+
staticSuggestions: headerMode ? HEADER_NAMES : void 0
|
|
34729
34955
|
}
|
|
34730
34956
|
),
|
|
34731
34957
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -34735,7 +34961,8 @@ function KVTable({ rows, onChange, keyPlaceholder = "Key", valuePlaceholder = "V
|
|
|
34735
34961
|
onChange: (v) => update(idx, { value: v }),
|
|
34736
34962
|
placeholder: valuePlaceholder,
|
|
34737
34963
|
wrapperClassName: "flex-1",
|
|
34738
|
-
className: "bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500 font-mono"
|
|
34964
|
+
className: "bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500 font-mono",
|
|
34965
|
+
staticSuggestions: headerMode ? getValueSuggestions(row.key) ?? void 0 : void 0
|
|
34739
34966
|
}
|
|
34740
34967
|
),
|
|
34741
34968
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -34769,7 +34996,7 @@ function KVTable({ rows, onChange, keyPlaceholder = "Key", valuePlaceholder = "V
|
|
|
34769
34996
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: add2, className: "mt-1 text-surface-400 hover:text-white transition-colors", children: "+ Add" })
|
|
34770
34997
|
] });
|
|
34771
34998
|
}
|
|
34772
|
-
const AUTH_TYPES$
|
|
34999
|
+
const AUTH_TYPES$2 = ["none", "bearer", "basic", "digest", "ntlm", "apikey"];
|
|
34773
35000
|
function FolderSettingsModal({ collectionId, folder, onClose }) {
|
|
34774
35001
|
const updateFolder = useStore((s) => s.updateFolder);
|
|
34775
35002
|
const [activeTab, setActiveTab] = reactExports.useState("auth");
|
|
@@ -34820,7 +35047,8 @@ function FolderSettingsModal({ collectionId, folder, onClose }) {
|
|
|
34820
35047
|
rows: headers,
|
|
34821
35048
|
onChange: setHeaders,
|
|
34822
35049
|
keyPlaceholder: "Header-Name",
|
|
34823
|
-
valuePlaceholder: "value"
|
|
35050
|
+
valuePlaceholder: "value",
|
|
35051
|
+
headerMode: true
|
|
34824
35052
|
}
|
|
34825
35053
|
)
|
|
34826
35054
|
] }),
|
|
@@ -34853,7 +35081,7 @@ function FolderAuthPanel({ auth, onChange }) {
|
|
|
34853
35081
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-surface-600", children: "Auth configured here is inherited by all requests in this folder unless the request overrides it with its own non-none auth type." }),
|
|
34854
35082
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
34855
35083
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-400", children: "Type:" }),
|
|
34856
|
-
AUTH_TYPES$
|
|
35084
|
+
AUTH_TYPES$2.map((t2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-1 cursor-pointer", children: [
|
|
34857
35085
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
34858
35086
|
"input",
|
|
34859
35087
|
{
|
|
@@ -34999,14 +35227,23 @@ function FolderAuthPanel({ auth, onChange }) {
|
|
|
34999
35227
|
] }) })
|
|
35000
35228
|
] });
|
|
35001
35229
|
}
|
|
35230
|
+
const AUTH_TYPES$1 = ["none", "bearer", "basic", "digest", "ntlm", "apikey"];
|
|
35002
35231
|
function CollectionSettingsModal({ collection, onClose }) {
|
|
35003
35232
|
const updateCollectionTls = useStore((s) => s.updateCollectionTls);
|
|
35233
|
+
const updateCollectionAuthAndHeaders = useStore((s) => s.updateCollectionAuthAndHeaders);
|
|
35234
|
+
const [activeTab, setActiveTab] = reactExports.useState("auth");
|
|
35235
|
+
const [auth, setAuth] = reactExports.useState(collection.auth ?? { type: "none" });
|
|
35236
|
+
const [headers, setHeaders] = reactExports.useState(collection.headers ?? []);
|
|
35004
35237
|
const existing = collection.tls;
|
|
35005
35238
|
const [caCertPath, setCaCertPath] = reactExports.useState(existing?.caCertPath ?? "");
|
|
35006
35239
|
const [clientCertPath, setClientCertPath] = reactExports.useState(existing?.clientCertPath ?? "");
|
|
35007
35240
|
const [clientKeyPath, setClientKeyPath] = reactExports.useState(existing?.clientKeyPath ?? "");
|
|
35008
35241
|
const [rejectUnauthorized, setRejectUnauthorized] = reactExports.useState(existing?.rejectUnauthorized !== false);
|
|
35242
|
+
function patchAuth(patch) {
|
|
35243
|
+
setAuth((prev) => ({ ...prev, ...patch }));
|
|
35244
|
+
}
|
|
35009
35245
|
function save() {
|
|
35246
|
+
updateCollectionAuthAndHeaders(collection.id, auth, headers);
|
|
35010
35247
|
const hasAny = caCertPath.trim() || clientCertPath.trim() || clientKeyPath.trim();
|
|
35011
35248
|
updateCollectionTls(collection.id, hasAny ? {
|
|
35012
35249
|
caCertPath: caCertPath.trim() || void 0,
|
|
@@ -35024,65 +35261,90 @@ function CollectionSettingsModal({ collection, onClose }) {
|
|
|
35024
35261
|
children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
35025
35262
|
"div",
|
|
35026
35263
|
{
|
|
35027
|
-
className: "w-[
|
|
35264
|
+
className: "w-[600px] bg-surface-900 border border-surface-800 rounded-lg shadow-2xl flex flex-col max-h-[80vh]",
|
|
35028
35265
|
onClick: (e) => e.stopPropagation(),
|
|
35029
35266
|
children: [
|
|
35030
35267
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-4 py-2.5 border-b border-surface-800 shrink-0", children: [
|
|
35031
35268
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
35032
35269
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-sm font-semibold", children: "Collection settings" }),
|
|
35033
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
35270
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-[10px] text-surface-600 mt-0.5", children: [
|
|
35271
|
+
collection.name,
|
|
35272
|
+
" — auth and headers inherited by all requests in this collection"
|
|
35273
|
+
] })
|
|
35034
35274
|
] }),
|
|
35035
35275
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: onClose, className: "text-surface-400 hover:text-white text-lg leading-none", children: "×" })
|
|
35036
35276
|
] }),
|
|
35037
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
35038
|
-
|
|
35039
|
-
|
|
35040
|
-
|
|
35041
|
-
|
|
35042
|
-
|
|
35043
|
-
|
|
35044
|
-
|
|
35045
|
-
|
|
35046
|
-
|
|
35047
|
-
|
|
35048
|
-
|
|
35049
|
-
|
|
35050
|
-
|
|
35051
|
-
|
|
35052
|
-
|
|
35053
|
-
|
|
35054
|
-
"
|
|
35055
|
-
|
|
35056
|
-
|
|
35057
|
-
|
|
35058
|
-
|
|
35059
|
-
|
|
35060
|
-
|
|
35061
|
-
|
|
35062
|
-
|
|
35063
|
-
|
|
35064
|
-
|
|
35065
|
-
|
|
35066
|
-
|
|
35067
|
-
|
|
35068
|
-
|
|
35069
|
-
|
|
35070
|
-
|
|
35071
|
-
|
|
35072
|
-
|
|
35073
|
-
|
|
35074
|
-
|
|
35075
|
-
|
|
35076
|
-
|
|
35077
|
-
|
|
35078
|
-
|
|
35079
|
-
|
|
35080
|
-
|
|
35081
|
-
|
|
35082
|
-
|
|
35083
|
-
|
|
35084
|
-
|
|
35085
|
-
|
|
35277
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex border-b border-surface-800 px-4 shrink-0", children: ["auth", "headers", "tls"].map((t2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35278
|
+
"button",
|
|
35279
|
+
{
|
|
35280
|
+
onClick: () => setActiveTab(t2),
|
|
35281
|
+
className: `px-3 py-1.5 text-xs transition-colors border-b-2 -mb-px capitalize ${activeTab === t2 ? "border-blue-500 text-white" : "border-transparent text-surface-400 hover:text-white"}`,
|
|
35282
|
+
children: t2 === "tls" ? "TLS" : t2
|
|
35283
|
+
},
|
|
35284
|
+
t2
|
|
35285
|
+
)) }),
|
|
35286
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-4 py-3 flex-1 overflow-y-auto text-xs", children: [
|
|
35287
|
+
activeTab === "auth" && /* @__PURE__ */ jsxRuntimeExports.jsx(CollectionAuthPanel, { auth, onChange: patchAuth }),
|
|
35288
|
+
activeTab === "headers" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35289
|
+
KVTable,
|
|
35290
|
+
{
|
|
35291
|
+
rows: headers,
|
|
35292
|
+
onChange: setHeaders,
|
|
35293
|
+
keyPlaceholder: "Header-Name",
|
|
35294
|
+
valuePlaceholder: "value",
|
|
35295
|
+
headerMode: true
|
|
35296
|
+
}
|
|
35297
|
+
),
|
|
35298
|
+
activeTab === "tls" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
35299
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-surface-500", children: "TLS settings override the workspace-level configuration for every request in this collection. Leave all paths empty to inherit from the workspace." }),
|
|
35300
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
35301
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-[10px] uppercase tracking-wider text-surface-600 font-medium", children: "CA Certificate path" }),
|
|
35302
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35303
|
+
"input",
|
|
35304
|
+
{
|
|
35305
|
+
value: caCertPath,
|
|
35306
|
+
onChange: (e) => setCaCertPath(e.target.value),
|
|
35307
|
+
placeholder: "/path/to/ca.crt (leave empty to inherit)",
|
|
35308
|
+
className: "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"
|
|
35309
|
+
}
|
|
35310
|
+
)
|
|
35311
|
+
] }),
|
|
35312
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
35313
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-[10px] uppercase tracking-wider text-surface-600 font-medium", children: "Client certificate path" }),
|
|
35314
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35315
|
+
"input",
|
|
35316
|
+
{
|
|
35317
|
+
value: clientCertPath,
|
|
35318
|
+
onChange: (e) => setClientCertPath(e.target.value),
|
|
35319
|
+
placeholder: "/path/to/client.crt (leave empty to inherit)",
|
|
35320
|
+
className: "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"
|
|
35321
|
+
}
|
|
35322
|
+
)
|
|
35323
|
+
] }),
|
|
35324
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
35325
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-[10px] uppercase tracking-wider text-surface-600 font-medium", children: "Client key path" }),
|
|
35326
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35327
|
+
"input",
|
|
35328
|
+
{
|
|
35329
|
+
value: clientKeyPath,
|
|
35330
|
+
onChange: (e) => setClientKeyPath(e.target.value),
|
|
35331
|
+
placeholder: "/path/to/client.key (leave empty to inherit)",
|
|
35332
|
+
className: "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"
|
|
35333
|
+
}
|
|
35334
|
+
)
|
|
35335
|
+
] }),
|
|
35336
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
|
|
35337
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35338
|
+
"input",
|
|
35339
|
+
{
|
|
35340
|
+
type: "checkbox",
|
|
35341
|
+
checked: rejectUnauthorized,
|
|
35342
|
+
onChange: (e) => setRejectUnauthorized(e.target.checked),
|
|
35343
|
+
className: "accent-blue-500"
|
|
35344
|
+
}
|
|
35345
|
+
),
|
|
35346
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "Reject unauthorized / self-signed certificates" })
|
|
35347
|
+
] })
|
|
35086
35348
|
] })
|
|
35087
35349
|
] }),
|
|
35088
35350
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 px-4 py-3 border-t border-surface-800 shrink-0", children: [
|
|
@@ -35109,6 +35371,160 @@ function CollectionSettingsModal({ collection, onClose }) {
|
|
|
35109
35371
|
}
|
|
35110
35372
|
);
|
|
35111
35373
|
}
|
|
35374
|
+
function CollectionAuthPanel({ auth, onChange }) {
|
|
35375
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
35376
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[10px] text-surface-600", children: "Auth configured here is inherited by all requests in this collection unless a folder or request overrides it with its own non-none auth type." }),
|
|
35377
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
35378
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-400", children: "Type:" }),
|
|
35379
|
+
AUTH_TYPES$1.map((t2) => /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-1 cursor-pointer", children: [
|
|
35380
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35381
|
+
"input",
|
|
35382
|
+
{
|
|
35383
|
+
type: "radio",
|
|
35384
|
+
value: t2,
|
|
35385
|
+
checked: auth.type === t2,
|
|
35386
|
+
onChange: () => onChange({ type: t2 }),
|
|
35387
|
+
className: "accent-blue-500"
|
|
35388
|
+
}
|
|
35389
|
+
),
|
|
35390
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: auth.type === t2 ? "text-white" : "text-surface-400", children: t2 })
|
|
35391
|
+
] }, t2))
|
|
35392
|
+
] }),
|
|
35393
|
+
auth.type === "bearer" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
35394
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: "Token" }),
|
|
35395
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35396
|
+
"input",
|
|
35397
|
+
{
|
|
35398
|
+
value: auth.token ?? "",
|
|
35399
|
+
onChange: (e) => onChange({ token: e.target.value }),
|
|
35400
|
+
placeholder: "Bearer token",
|
|
35401
|
+
className: "bg-surface-800 border border-surface-700 rounded px-2 py-1 font-mono focus:outline-none focus:border-blue-500"
|
|
35402
|
+
}
|
|
35403
|
+
)
|
|
35404
|
+
] }),
|
|
35405
|
+
(auth.type === "basic" || auth.type === "digest") && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
|
|
35406
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
|
|
35407
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: "Username" }),
|
|
35408
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35409
|
+
"input",
|
|
35410
|
+
{
|
|
35411
|
+
value: auth.username ?? "",
|
|
35412
|
+
onChange: (e) => onChange({ username: e.target.value }),
|
|
35413
|
+
className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
|
|
35414
|
+
}
|
|
35415
|
+
)
|
|
35416
|
+
] }),
|
|
35417
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
|
|
35418
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: "Password" }),
|
|
35419
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35420
|
+
"input",
|
|
35421
|
+
{
|
|
35422
|
+
type: "password",
|
|
35423
|
+
value: auth.password ?? "",
|
|
35424
|
+
onChange: (e) => onChange({ password: e.target.value }),
|
|
35425
|
+
className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 font-mono focus:outline-none focus:border-blue-500"
|
|
35426
|
+
}
|
|
35427
|
+
)
|
|
35428
|
+
] })
|
|
35429
|
+
] }),
|
|
35430
|
+
auth.type === "ntlm" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
35431
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
|
|
35432
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
|
|
35433
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: "Username" }),
|
|
35434
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35435
|
+
"input",
|
|
35436
|
+
{
|
|
35437
|
+
value: auth.username ?? "",
|
|
35438
|
+
onChange: (e) => onChange({ username: e.target.value }),
|
|
35439
|
+
className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
|
|
35440
|
+
}
|
|
35441
|
+
)
|
|
35442
|
+
] }),
|
|
35443
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
|
|
35444
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: "Password" }),
|
|
35445
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35446
|
+
"input",
|
|
35447
|
+
{
|
|
35448
|
+
type: "password",
|
|
35449
|
+
value: auth.password ?? "",
|
|
35450
|
+
onChange: (e) => onChange({ password: e.target.value }),
|
|
35451
|
+
className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 font-mono focus:outline-none focus:border-blue-500"
|
|
35452
|
+
}
|
|
35453
|
+
)
|
|
35454
|
+
] })
|
|
35455
|
+
] }),
|
|
35456
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
|
|
35457
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
|
|
35458
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: "Domain" }),
|
|
35459
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35460
|
+
"input",
|
|
35461
|
+
{
|
|
35462
|
+
value: auth.ntlmDomain ?? "",
|
|
35463
|
+
onChange: (e) => onChange({ ntlmDomain: e.target.value }),
|
|
35464
|
+
placeholder: "WORKGROUP",
|
|
35465
|
+
className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
|
|
35466
|
+
}
|
|
35467
|
+
)
|
|
35468
|
+
] }),
|
|
35469
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
|
|
35470
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: "Workstation" }),
|
|
35471
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35472
|
+
"input",
|
|
35473
|
+
{
|
|
35474
|
+
value: auth.ntlmWorkstation ?? "",
|
|
35475
|
+
onChange: (e) => onChange({ ntlmWorkstation: e.target.value }),
|
|
35476
|
+
placeholder: "MACHINE",
|
|
35477
|
+
className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
|
|
35478
|
+
}
|
|
35479
|
+
)
|
|
35480
|
+
] })
|
|
35481
|
+
] })
|
|
35482
|
+
] }),
|
|
35483
|
+
auth.type === "apikey" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
|
|
35484
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
35485
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: "Key name" }),
|
|
35486
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35487
|
+
"input",
|
|
35488
|
+
{
|
|
35489
|
+
value: auth.apiKeyName ?? "X-API-Key",
|
|
35490
|
+
onChange: (e) => onChange({ apiKeyName: e.target.value }),
|
|
35491
|
+
className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
|
|
35492
|
+
}
|
|
35493
|
+
)
|
|
35494
|
+
] }),
|
|
35495
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
35496
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: "In" }),
|
|
35497
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
35498
|
+
"select",
|
|
35499
|
+
{
|
|
35500
|
+
value: auth.apiKeyIn ?? "header",
|
|
35501
|
+
onChange: (e) => onChange({ apiKeyIn: e.target.value }),
|
|
35502
|
+
className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500",
|
|
35503
|
+
children: [
|
|
35504
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "header", children: "Header" }),
|
|
35505
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "query", children: "Query" })
|
|
35506
|
+
]
|
|
35507
|
+
}
|
|
35508
|
+
)
|
|
35509
|
+
] }),
|
|
35510
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
|
|
35511
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: "Value" }),
|
|
35512
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35513
|
+
"input",
|
|
35514
|
+
{
|
|
35515
|
+
value: auth.apiKeyValue ?? "",
|
|
35516
|
+
onChange: (e) => onChange({ apiKeyValue: e.target.value }),
|
|
35517
|
+
placeholder: "API key value",
|
|
35518
|
+
className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 font-mono focus:outline-none focus:border-blue-500"
|
|
35519
|
+
}
|
|
35520
|
+
)
|
|
35521
|
+
] })
|
|
35522
|
+
] }) })
|
|
35523
|
+
] });
|
|
35524
|
+
}
|
|
35525
|
+
const DragCtx = reactExports.createContext({ dragging: null, setDragging: () => {
|
|
35526
|
+
}, onDrop: () => {
|
|
35527
|
+
} });
|
|
35112
35528
|
function InlineEdit({
|
|
35113
35529
|
value,
|
|
35114
35530
|
onCommit,
|
|
@@ -35356,16 +35772,23 @@ function CollectionTree() {
|
|
|
35356
35772
|
const updateRequestTags = useStore((s) => s.updateRequestTags);
|
|
35357
35773
|
const updateRequest = useStore((s) => s.updateRequest);
|
|
35358
35774
|
const openRunner = useStore((s) => s.openRunner);
|
|
35775
|
+
const moveRequest = useStore((s) => s.moveRequest);
|
|
35359
35776
|
const colList = Object.values(collections);
|
|
35360
35777
|
const [pendingConfirm, setPendingConfirm] = reactExports.useState(null);
|
|
35361
35778
|
const [newRequestId, setNewRequestId] = reactExports.useState(null);
|
|
35779
|
+
const [dragging, setDragging] = reactExports.useState(null);
|
|
35362
35780
|
function confirmThen(message, action) {
|
|
35363
35781
|
setPendingConfirm({ message, onConfirm: () => {
|
|
35364
35782
|
action();
|
|
35365
35783
|
setPendingConfirm(null);
|
|
35366
35784
|
} });
|
|
35367
35785
|
}
|
|
35368
|
-
|
|
35786
|
+
function onDrop(destCollectionId, destFolderId, destIndex) {
|
|
35787
|
+
if (!dragging) return;
|
|
35788
|
+
moveRequest(dragging.collectionId, dragging.requestId, destCollectionId, destFolderId, destIndex);
|
|
35789
|
+
setDragging(null);
|
|
35790
|
+
}
|
|
35791
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx(DragCtx.Provider, { value: { dragging, setDragging, onDrop }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col flex-1 min-h-0 select-none", children: [
|
|
35369
35792
|
pendingConfirm && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35370
35793
|
ConfirmDialog,
|
|
35371
35794
|
{
|
|
@@ -35410,7 +35833,7 @@ function CollectionTree() {
|
|
|
35410
35833
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "pt-1", children: "or import from Postman / OpenAPI above." })
|
|
35411
35834
|
] })
|
|
35412
35835
|
] })
|
|
35413
|
-
] });
|
|
35836
|
+
] }) });
|
|
35414
35837
|
}
|
|
35415
35838
|
function CollectionNode({
|
|
35416
35839
|
col,
|
|
@@ -35441,6 +35864,8 @@ function CollectionNode({
|
|
|
35441
35864
|
const [renaming, setRenaming] = reactExports.useState(false);
|
|
35442
35865
|
const [showSettings, setShowSettings] = reactExports.useState(false);
|
|
35443
35866
|
const [expandCtrl, setExpandCtrl] = reactExports.useState({ value: true, seq: 0 });
|
|
35867
|
+
const [dropOver, setDropOver] = reactExports.useState(false);
|
|
35868
|
+
const dragCtx = reactExports.useContext(DragCtx);
|
|
35444
35869
|
function expandAll() {
|
|
35445
35870
|
setExpandCtrl((c) => ({ value: true, seq: c.seq + 1 }));
|
|
35446
35871
|
}
|
|
@@ -35451,11 +35876,21 @@ function CollectionNode({
|
|
|
35451
35876
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
35452
35877
|
"div",
|
|
35453
35878
|
{
|
|
35454
|
-
className: `group flex items-start gap-1 px-2 py-1.5 cursor-pointer hover:bg-surface-800 transition-colors ${isActive ? "text-[var(--text-primary)]" : "text-surface-400"}`,
|
|
35879
|
+
className: `group flex items-start gap-1 px-2 py-1.5 cursor-pointer hover:bg-surface-800 transition-colors ${isActive ? "text-[var(--text-primary)]" : "text-surface-400"} ${dropOver ? "outline outline-1 outline-blue-500 rounded" : ""}`,
|
|
35455
35880
|
onClick: () => {
|
|
35456
35881
|
onSelectCollection();
|
|
35457
35882
|
setExpanded((e) => !e);
|
|
35458
35883
|
},
|
|
35884
|
+
onDragOver: dragCtx.dragging ? (e) => {
|
|
35885
|
+
e.preventDefault();
|
|
35886
|
+
setDropOver(true);
|
|
35887
|
+
} : void 0,
|
|
35888
|
+
onDragLeave: () => setDropOver(false),
|
|
35889
|
+
onDrop: (e) => {
|
|
35890
|
+
e.preventDefault();
|
|
35891
|
+
setDropOver(false);
|
|
35892
|
+
dragCtx.onDrop(col.id, col.rootFolder.id);
|
|
35893
|
+
},
|
|
35459
35894
|
children: [
|
|
35460
35895
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] w-3 text-center shrink-0 mt-0.5", children: expanded ? "▾" : "▸" }),
|
|
35461
35896
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0", children: renaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -35539,6 +35974,8 @@ function FolderRow({
|
|
|
35539
35974
|
const [renaming, setRenaming] = reactExports.useState(false);
|
|
35540
35975
|
const [showSettings, setShowSettings] = reactExports.useState(false);
|
|
35541
35976
|
const [addingTag, setAddingTag] = reactExports.useState(false);
|
|
35977
|
+
const [dropOver, setDropOver] = reactExports.useState(false);
|
|
35978
|
+
const dragCtx = reactExports.useContext(DragCtx);
|
|
35542
35979
|
const tags2 = folder.tags ?? [];
|
|
35543
35980
|
const indent = depth * 12 + 8;
|
|
35544
35981
|
const hasInheritedConfig = folder.auth && folder.auth.type !== "none" || folder.headers && folder.headers.length > 0;
|
|
@@ -35546,9 +35983,19 @@ function FolderRow({
|
|
|
35546
35983
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
35547
35984
|
"div",
|
|
35548
35985
|
{
|
|
35549
|
-
className:
|
|
35986
|
+
className: `group flex items-start gap-1 py-1 hover:bg-surface-800 transition-colors cursor-pointer text-surface-400 ${dropOver ? "outline outline-1 outline-blue-500 rounded" : ""}`,
|
|
35550
35987
|
style: { paddingLeft: indent },
|
|
35551
35988
|
onClick: () => setExpanded((e) => !e),
|
|
35989
|
+
onDragOver: dragCtx.dragging ? (e) => {
|
|
35990
|
+
e.preventDefault();
|
|
35991
|
+
setDropOver(true);
|
|
35992
|
+
} : void 0,
|
|
35993
|
+
onDragLeave: () => setDropOver(false),
|
|
35994
|
+
onDrop: (e) => {
|
|
35995
|
+
e.preventDefault();
|
|
35996
|
+
setDropOver(false);
|
|
35997
|
+
dragCtx.onDrop(collectionId, folder.id);
|
|
35998
|
+
},
|
|
35552
35999
|
children: [
|
|
35553
36000
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[10px] w-3 text-center shrink-0 mt-0.5", children: expanded ? "▾" : "▸" }),
|
|
35554
36001
|
/* @__PURE__ */ jsxRuntimeExports.jsx(FolderIcon, { className: `shrink-0 mt-0.5 ${hasInheritedConfig ? "text-blue-500" : "text-amber-600"}` }),
|
|
@@ -35668,13 +36115,16 @@ function FolderContents({
|
|
|
35668
36115
|
},
|
|
35669
36116
|
sub.id
|
|
35670
36117
|
)),
|
|
35671
|
-
folder.requestIds.map((reqId) => {
|
|
36118
|
+
folder.requestIds.map((reqId, reqIndex) => {
|
|
35672
36119
|
const req = requests[reqId];
|
|
35673
36120
|
if (!req) return null;
|
|
35674
36121
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
35675
36122
|
RequestRow,
|
|
35676
36123
|
{
|
|
35677
36124
|
reqId: req.id,
|
|
36125
|
+
collectionId,
|
|
36126
|
+
folderId: folder.id,
|
|
36127
|
+
reqIndex,
|
|
35678
36128
|
name: req.name,
|
|
35679
36129
|
method: req.method,
|
|
35680
36130
|
hookType: req.hookType,
|
|
@@ -35707,7 +36157,10 @@ const HOOK_COLORS = {
|
|
|
35707
36157
|
afterAll: "bg-cyan-800 text-white"
|
|
35708
36158
|
};
|
|
35709
36159
|
function RequestRow({
|
|
35710
|
-
reqId
|
|
36160
|
+
reqId,
|
|
36161
|
+
collectionId,
|
|
36162
|
+
folderId,
|
|
36163
|
+
reqIndex,
|
|
35711
36164
|
name: name2,
|
|
35712
36165
|
method,
|
|
35713
36166
|
hookType,
|
|
@@ -35724,6 +36177,8 @@ function RequestRow({
|
|
|
35724
36177
|
}) {
|
|
35725
36178
|
const [renaming, setRenaming] = reactExports.useState(autoRename);
|
|
35726
36179
|
const [addingTag, setAddingTag] = reactExports.useState(false);
|
|
36180
|
+
const [dropPos, setDropPos] = reactExports.useState(null);
|
|
36181
|
+
const dragCtx = reactExports.useContext(DragCtx);
|
|
35727
36182
|
const hookMenuItems = [
|
|
35728
36183
|
...["beforeAll", "before", "after", "afterAll"].map((ht) => ({
|
|
35729
36184
|
type: "item",
|
|
@@ -35731,55 +36186,84 @@ function RequestRow({
|
|
|
35731
36186
|
onClick: () => onSetHookType(hookType === ht ? void 0 : ht)
|
|
35732
36187
|
}))
|
|
35733
36188
|
];
|
|
35734
|
-
|
|
35735
|
-
|
|
35736
|
-
|
|
35737
|
-
|
|
35738
|
-
|
|
35739
|
-
|
|
35740
|
-
|
|
35741
|
-
|
|
35742
|
-
|
|
35743
|
-
|
|
35744
|
-
|
|
35745
|
-
|
|
35746
|
-
|
|
35747
|
-
|
|
35748
|
-
|
|
35749
|
-
|
|
35750
|
-
|
|
35751
|
-
|
|
35752
|
-
|
|
35753
|
-
|
|
35754
|
-
|
|
35755
|
-
|
|
35756
|
-
|
|
35757
|
-
|
|
36189
|
+
function handleDragOver(e) {
|
|
36190
|
+
if (!dragCtx.dragging || dragCtx.dragging.requestId === reqId) return;
|
|
36191
|
+
e.preventDefault();
|
|
36192
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
36193
|
+
setDropPos(e.clientY < rect.top + rect.height / 2 ? "before" : "after");
|
|
36194
|
+
}
|
|
36195
|
+
function handleDrop(e) {
|
|
36196
|
+
e.preventDefault();
|
|
36197
|
+
e.stopPropagation();
|
|
36198
|
+
const insertIndex = dropPos === "before" ? reqIndex : reqIndex + 1;
|
|
36199
|
+
dragCtx.onDrop(collectionId, folderId, insertIndex);
|
|
36200
|
+
setDropPos(null);
|
|
36201
|
+
}
|
|
36202
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
|
|
36203
|
+
dropPos === "before" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-0 inset-x-0 h-0.5 bg-blue-500 z-10 pointer-events-none" }),
|
|
36204
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
36205
|
+
"div",
|
|
36206
|
+
{
|
|
36207
|
+
draggable: true,
|
|
36208
|
+
className: `group flex items-start gap-1.5 py-1 pr-1 rounded-sm cursor-pointer transition-colors ${isActive ? "bg-surface-800 text-[var(--text-primary)]" : "text-surface-300 hover:bg-surface-800"}`,
|
|
36209
|
+
style: { paddingLeft: indent },
|
|
36210
|
+
onClick: onSelect,
|
|
36211
|
+
onDoubleClick: () => setRenaming(true),
|
|
36212
|
+
onDragStart: (e) => {
|
|
36213
|
+
e.dataTransfer.effectAllowed = "move";
|
|
36214
|
+
dragCtx.setDragging({ requestId: reqId, collectionId });
|
|
36215
|
+
},
|
|
36216
|
+
onDragEnd: () => {
|
|
36217
|
+
dragCtx.setDragging(null);
|
|
36218
|
+
setDropPos(null);
|
|
36219
|
+
},
|
|
36220
|
+
onDragOver: handleDragOver,
|
|
36221
|
+
onDragLeave: () => setDropPos(null),
|
|
36222
|
+
onDrop: handleDrop,
|
|
36223
|
+
children: [
|
|
36224
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(MethodBadge, { method, size: "xs" }),
|
|
36225
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
36226
|
+
renaming ? /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36227
|
+
InlineEdit,
|
|
36228
|
+
{
|
|
36229
|
+
value: name2,
|
|
36230
|
+
onCommit: (v) => {
|
|
36231
|
+
onRename(v);
|
|
36232
|
+
setRenaming(false);
|
|
36233
|
+
},
|
|
36234
|
+
onCancel: () => setRenaming(false),
|
|
36235
|
+
className: "w-full text-xs"
|
|
36236
|
+
}
|
|
36237
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 min-w-0", children: [
|
|
36238
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs truncate", children: name2 }),
|
|
36239
|
+
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() })
|
|
36240
|
+
] }),
|
|
36241
|
+
(tags2.length > 0 || addingTag) && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
36242
|
+
TagChips,
|
|
36243
|
+
{
|
|
36244
|
+
tags: tags2,
|
|
36245
|
+
onRemove: (tag) => onUpdateTags(tags2.filter((t2) => t2 !== tag)),
|
|
36246
|
+
onAdd: (tag) => onUpdateTags([...tags2, tag]),
|
|
36247
|
+
forceAdding: addingTag,
|
|
36248
|
+
onDoneAdding: () => setAddingTag(false)
|
|
36249
|
+
}
|
|
36250
|
+
)
|
|
35758
36251
|
] }),
|
|
35759
|
-
(
|
|
35760
|
-
|
|
35761
|
-
{
|
|
35762
|
-
|
|
35763
|
-
|
|
35764
|
-
|
|
35765
|
-
|
|
35766
|
-
|
|
35767
|
-
}
|
|
35768
|
-
)
|
|
35769
|
-
|
|
35770
|
-
|
|
35771
|
-
|
|
35772
|
-
|
|
35773
|
-
|
|
35774
|
-
{ type: "separator" },
|
|
35775
|
-
{ type: "header", label: "Hook type" },
|
|
35776
|
-
...hookMenuItems,
|
|
35777
|
-
{ type: "separator" },
|
|
35778
|
-
{ type: "item", label: "Delete", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(TrashIcon, {}), danger: true, onClick: onDelete }
|
|
35779
|
-
] }) })
|
|
35780
|
-
]
|
|
35781
|
-
}
|
|
35782
|
-
);
|
|
36252
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(DotsBtn, { items: [
|
|
36253
|
+
{ type: "item", label: "Rename", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(PencilIcon, {}), onClick: () => setRenaming(true) },
|
|
36254
|
+
{ type: "item", label: "Duplicate", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(CopyIcon, {}), onClick: onDuplicate },
|
|
36255
|
+
{ type: "item", label: "Add tag", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(TagIcon, {}), onClick: () => setAddingTag(true) },
|
|
36256
|
+
{ type: "separator" },
|
|
36257
|
+
{ type: "header", label: "Hook type" },
|
|
36258
|
+
...hookMenuItems,
|
|
36259
|
+
{ type: "separator" },
|
|
36260
|
+
{ type: "item", label: "Delete", icon: /* @__PURE__ */ jsxRuntimeExports.jsx(TrashIcon, {}), danger: true, onClick: onDelete }
|
|
36261
|
+
] }) }),
|
|
36262
|
+
dropPos === "after" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute bottom-0 inset-x-0 h-0.5 bg-blue-500 z-10 pointer-events-none" })
|
|
36263
|
+
]
|
|
36264
|
+
}
|
|
36265
|
+
)
|
|
36266
|
+
] });
|
|
35783
36267
|
}
|
|
35784
36268
|
function DotsHorizontalIcon() {
|
|
35785
36269
|
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" }) });
|
|
@@ -35841,7 +36325,8 @@ function HeadersTab({ request, onChange }) {
|
|
|
35841
36325
|
rows: request.headers,
|
|
35842
36326
|
onChange: (rows) => onChange({ headers: rows }),
|
|
35843
36327
|
keyPlaceholder: "Header-Name",
|
|
35844
|
-
valuePlaceholder: "value"
|
|
36328
|
+
valuePlaceholder: "value",
|
|
36329
|
+
headerMode: true
|
|
35845
36330
|
}
|
|
35846
36331
|
);
|
|
35847
36332
|
}
|
|
@@ -42007,39 +42492,17 @@ function AuthTab({ request, onChange }) {
|
|
|
42007
42492
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: auth.type === t2 ? "text-white" : "text-surface-400", children: t2 })
|
|
42008
42493
|
] }, t2))
|
|
42009
42494
|
] }),
|
|
42010
|
-
auth.type === "bearer" && /* @__PURE__ */ jsxRuntimeExports.
|
|
42011
|
-
|
|
42012
|
-
|
|
42013
|
-
|
|
42014
|
-
|
|
42015
|
-
|
|
42016
|
-
|
|
42017
|
-
|
|
42018
|
-
|
|
42019
|
-
|
|
42020
|
-
|
|
42021
|
-
}
|
|
42022
|
-
),
|
|
42023
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
42024
|
-
"input",
|
|
42025
|
-
{
|
|
42026
|
-
value: auth.tokenSecretRef ?? "API_TOKEN",
|
|
42027
|
-
onChange: (e) => setAuth({ tokenSecretRef: e.target.value }),
|
|
42028
|
-
placeholder: "Keychain key name",
|
|
42029
|
-
className: "w-36 bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
|
|
42030
|
-
}
|
|
42031
|
-
),
|
|
42032
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
42033
|
-
"button",
|
|
42034
|
-
{
|
|
42035
|
-
onClick: () => saveSecret(auth.tokenSecretRef ?? "API_TOKEN"),
|
|
42036
|
-
className: "px-2 py-1 bg-blue-700 hover:bg-blue-600 rounded transition-colors",
|
|
42037
|
-
children: saved ? "✓" : "Save"
|
|
42038
|
-
}
|
|
42039
|
-
)
|
|
42040
|
-
] }),
|
|
42041
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-surface-400 text-[10px]", children: "Token is stored in your OS keychain — never written to disk." })
|
|
42042
|
-
] }),
|
|
42495
|
+
auth.type === "bearer" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
42496
|
+
BearerPanel,
|
|
42497
|
+
{
|
|
42498
|
+
auth,
|
|
42499
|
+
secretValue,
|
|
42500
|
+
setSecretValue,
|
|
42501
|
+
saved,
|
|
42502
|
+
setAuth,
|
|
42503
|
+
saveSecret
|
|
42504
|
+
}
|
|
42505
|
+
),
|
|
42043
42506
|
auth.type === "basic" && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
42044
42507
|
BasicCredentialsFields,
|
|
42045
42508
|
{
|
|
@@ -42431,6 +42894,80 @@ function BasicCredentialsFields({
|
|
|
42431
42894
|
note && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-surface-600 text-[10px]", children: note })
|
|
42432
42895
|
] });
|
|
42433
42896
|
}
|
|
42897
|
+
function BearerPanel({
|
|
42898
|
+
auth,
|
|
42899
|
+
secretValue,
|
|
42900
|
+
setSecretValue,
|
|
42901
|
+
saved,
|
|
42902
|
+
setAuth,
|
|
42903
|
+
saveSecret
|
|
42904
|
+
}) {
|
|
42905
|
+
const [keychainOpen, setKeychainOpen] = reactExports.useState(!!auth.tokenSecretRef);
|
|
42906
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
42907
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-1", children: [
|
|
42908
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-surface-400", children: [
|
|
42909
|
+
"Token",
|
|
42910
|
+
" ",
|
|
42911
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-surface-500 text-[10px]", children: [
|
|
42912
|
+
"— supports ",
|
|
42913
|
+
"{{variables}}"
|
|
42914
|
+
] })
|
|
42915
|
+
] }),
|
|
42916
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
42917
|
+
VarInput,
|
|
42918
|
+
{
|
|
42919
|
+
value: auth.token ?? "",
|
|
42920
|
+
onChange: (v) => setAuth({ token: v }),
|
|
42921
|
+
placeholder: "{{token}} or paste a raw token",
|
|
42922
|
+
className: "bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500 font-mono text-xs"
|
|
42923
|
+
}
|
|
42924
|
+
)
|
|
42925
|
+
] }),
|
|
42926
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
42927
|
+
"button",
|
|
42928
|
+
{
|
|
42929
|
+
onClick: () => setKeychainOpen((o) => !o),
|
|
42930
|
+
className: "text-[10px] text-surface-500 hover:text-surface-300 text-left transition-colors w-fit",
|
|
42931
|
+
children: [
|
|
42932
|
+
keychainOpen ? "▾" : "▸",
|
|
42933
|
+
" Store in OS keychain instead"
|
|
42934
|
+
]
|
|
42935
|
+
}
|
|
42936
|
+
),
|
|
42937
|
+
keychainOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-1 pl-3 border-l border-surface-800", children: [
|
|
42938
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-surface-500 text-[10px]", children: "Paste a raw token here to encrypt it in your OS keychain. Useful for static long-lived API tokens. Leave the value field above empty to use the keychain." }),
|
|
42939
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
|
|
42940
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
42941
|
+
"input",
|
|
42942
|
+
{
|
|
42943
|
+
type: "password",
|
|
42944
|
+
value: secretValue,
|
|
42945
|
+
onChange: (e) => setSecretValue(e.target.value),
|
|
42946
|
+
placeholder: auth.tokenSecretRef ? `Stored as "${auth.tokenSecretRef}"` : "Paste token",
|
|
42947
|
+
className: "flex-1 bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500 font-mono"
|
|
42948
|
+
}
|
|
42949
|
+
),
|
|
42950
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
42951
|
+
"input",
|
|
42952
|
+
{
|
|
42953
|
+
value: auth.tokenSecretRef ?? "API_TOKEN",
|
|
42954
|
+
onChange: (e) => setAuth({ tokenSecretRef: e.target.value }),
|
|
42955
|
+
placeholder: "Keychain key",
|
|
42956
|
+
className: "w-32 bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
|
|
42957
|
+
}
|
|
42958
|
+
),
|
|
42959
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
42960
|
+
"button",
|
|
42961
|
+
{
|
|
42962
|
+
onClick: () => saveSecret(auth.tokenSecretRef ?? "API_TOKEN"),
|
|
42963
|
+
className: "px-2 py-1 bg-blue-700 hover:bg-blue-600 rounded transition-colors",
|
|
42964
|
+
children: saved ? "✓" : "Save"
|
|
42965
|
+
}
|
|
42966
|
+
)
|
|
42967
|
+
] })
|
|
42968
|
+
] })
|
|
42969
|
+
] });
|
|
42970
|
+
}
|
|
42434
42971
|
const noSemi = 316, noSemiType = 317, incdec = 1, incdecPrefix = 2, questionDot = 3, JSXStartTag = 4, insertSemi = 318, spaces = 320, newline = 321, LineComment = 5, BlockComment = 6, Dialect_jsx = 0;
|
|
42435
42972
|
const space = [
|
|
42436
42973
|
9,
|
|
@@ -43012,16 +43549,22 @@ const SNIPPET_GROUPS = [
|
|
|
43012
43549
|
group: "Variables — Set",
|
|
43013
43550
|
items: [
|
|
43014
43551
|
{
|
|
43015
|
-
label: "
|
|
43016
|
-
code:
|
|
43552
|
+
label: "Save token from response (use in next requests)",
|
|
43553
|
+
code: `// Use collectionVariables so the value persists across requests
|
|
43554
|
+
const json = sp.response.json();
|
|
43555
|
+
sp.collectionVariables.set("token", json.access_token);`
|
|
43556
|
+
},
|
|
43557
|
+
{
|
|
43558
|
+
label: "Set collection variable (persists across requests)",
|
|
43559
|
+
code: `sp.collectionVariables.set("variable_name", "value");`
|
|
43017
43560
|
},
|
|
43018
43561
|
{
|
|
43019
|
-
label: "Set environment variable",
|
|
43562
|
+
label: "Set environment variable (key must exist in env)",
|
|
43020
43563
|
code: `sp.environment.set("variable_name", "value");`
|
|
43021
43564
|
},
|
|
43022
43565
|
{
|
|
43023
|
-
label: "Set
|
|
43024
|
-
code: `sp.
|
|
43566
|
+
label: "Set variable (request-local only)",
|
|
43567
|
+
code: `sp.variables.set("variable_name", "value");`
|
|
43025
43568
|
},
|
|
43026
43569
|
{
|
|
43027
43570
|
label: "Set global variable",
|
|
@@ -49775,7 +50318,11 @@ function RequestBuilder({ request }) {
|
|
|
49775
50318
|
setTabResponse(activeTabId, null, null);
|
|
49776
50319
|
try {
|
|
49777
50320
|
const activeEnv = activeEnvironmentId ? environments[activeEnvironmentId]?.data ?? null : null;
|
|
49778
|
-
const
|
|
50321
|
+
const sessionVars = useStore.getState().sessionVars;
|
|
50322
|
+
const collectionVars = {
|
|
50323
|
+
...activeCollectionId ? collections[activeCollectionId]?.data.collectionVariables ?? {} : {},
|
|
50324
|
+
...sessionVars
|
|
50325
|
+
};
|
|
49779
50326
|
const inherited = useStore.getState().getInheritedAuthAndHeaders(request.id);
|
|
49780
50327
|
const mergedAuth = request.auth.type !== "none" ? request.auth : inherited.auth ?? request.auth;
|
|
49781
50328
|
const mergedHeaders = [
|
|
@@ -53381,7 +53928,7 @@ function RunnerModal() {
|
|
|
53381
53928
|
{
|
|
53382
53929
|
onClick: run,
|
|
53383
53930
|
disabled: runnerRunning,
|
|
53384
|
-
className: "px-4 py-1.5 text-xs bg-emerald-700 hover:bg-emerald-600 disabled:bg-surface-800 disabled:text-surface-400 rounded font-medium transition-colors flex items-center gap-1.5 whitespace-nowrap",
|
|
53931
|
+
className: "px-4 py-1.5 text-xs text-white bg-emerald-700 hover:bg-emerald-600 disabled:bg-surface-800 disabled:text-surface-400 rounded font-medium transition-colors flex items-center gap-1.5 whitespace-nowrap",
|
|
53385
53932
|
children: [
|
|
53386
53933
|
/* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "w-3.5 h-3.5", viewBox: "0 0 20 20", fill: "currentColor", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { fillRule: "evenodd", d: "M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z", clipRule: "evenodd" }) }),
|
|
53387
53934
|
runnerRunning ? "Running…" : "Run"
|
|
@@ -53489,7 +54036,7 @@ function RunnerModal() {
|
|
|
53489
54036
|
},
|
|
53490
54037
|
idx
|
|
53491
54038
|
)) }) }) }),
|
|
53492
|
-
summary && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 px-4 py-2 border-t border-surface-800 bg-surface-
|
|
54039
|
+
summary && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 px-4 py-2 border-t border-surface-800 bg-surface-800/30 flex-shrink-0 text-xs", children: [
|
|
53493
54040
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-emerald-400 font-medium", children: [
|
|
53494
54041
|
summary.passed,
|
|
53495
54042
|
" passed"
|
|
@@ -56195,7 +56742,7 @@ function App() {
|
|
|
56195
56742
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "#6aa3c8" }, children: "Spector" }),
|
|
56196
56743
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-[10px] font-normal opacity-50", children: [
|
|
56197
56744
|
"v",
|
|
56198
|
-
"0.1.
|
|
56745
|
+
"0.1.6"
|
|
56199
56746
|
] }),
|
|
56200
56747
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mx-2 opacity-30", children: "·" }),
|
|
56201
56748
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|