@testsmith/api-spector 0.7.8 → 0.7.9

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.
@@ -3,7 +3,7 @@ const promises = require("node:fs/promises");
3
3
  const path = require("node:path");
4
4
  const crypto = require("node:crypto");
5
5
  const undici = require("undici");
6
- const requestExec = require("./request-exec-Cv2jkrO1.js");
6
+ const requestExec = require("./request-exec-CgyqbNWk.js");
7
7
  const Ajv = require("ajv");
8
8
  const jsYaml = require("js-yaml");
9
9
  require("node:http");
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const requestExec = require("./request-exec-Cv2jkrO1.js");
2
+ const requestExec = require("./request-exec-CgyqbNWk.js");
3
3
  const grpc = require("@grpc/grpc-js");
4
4
  const protoLoader = require("@grpc/proto-loader");
5
5
  const fs = require("node:fs");
@@ -841,6 +841,10 @@ function buildUrl(baseUrl, params, vars) {
841
841
  templateTokens.add(String(name).trim());
842
842
  return "";
843
843
  });
844
+ baseUrl.replaceAll(/\[([A-Za-z_]\w*)\]/g, (_m, name) => {
845
+ templateTokens.add(String(name));
846
+ return "";
847
+ });
844
848
  const enabled = (params ?? []).filter((p) => p.enabled && p.key);
845
849
  const pathRows = [];
846
850
  const queryRows = [];
@@ -853,7 +857,8 @@ function buildUrl(baseUrl, params, vars) {
853
857
  ...vars,
854
858
  ...Object.fromEntries(pathRows.map((p) => [p.key, interpolate(p.value, vars)]))
855
859
  } : vars;
856
- const url = interpolate(baseUrl, mergedVars);
860
+ let url = interpolate(baseUrl, mergedVars);
861
+ url = url.replaceAll(/\[([A-Za-z_]\w*)\]/g, (m, name) => name in mergedVars ? mergedVars[name] : m);
857
862
  if (!queryRows.length) return url;
858
863
  const sep = url.includes("?") ? "&" : "?";
859
864
  const qs = queryRows.map((p) => `${encodeURIComponent(interpolate(p.key, vars))}=${encodeURIComponent(interpolate(p.value, vars))}`).join("&");
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
  const promises = require("node:fs/promises");
4
4
  const path = require("node:path");
5
- const brokerClient = require("./chunks/broker-client-BYpWeOWT.js");
5
+ const brokerClient = require("./chunks/broker-client-CJBfpvbd.js");
6
6
  const escape = require("./chunks/escape-DDVAlOvZ.js");
7
7
  const crypto = require("node:crypto");
8
8
  const undici = require("undici");
@@ -11,7 +11,7 @@ const cliCommon = require("./chunks/cli-common-GnihVSjU.js");
11
11
  const node_child_process = require("node:child_process");
12
12
  const jsYaml = require("js-yaml");
13
13
  const environments = require("./chunks/environments-iM3SUM-4.js");
14
- require("./chunks/request-exec-Cv2jkrO1.js");
14
+ require("./chunks/request-exec-CgyqbNWk.js");
15
15
  require("fs/promises");
16
16
  require("tls");
17
17
  require("./chunks/handle-Crv1i9hb.js");
package/out/main/flow.js CHANGED
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
  const promises = require("node:fs/promises");
4
4
  const path = require("node:path");
5
- const requestExec = require("./chunks/request-exec-Cv2jkrO1.js");
5
+ const requestExec = require("./chunks/request-exec-CgyqbNWk.js");
6
6
  const requestCollection = require("./chunks/request-collection-gkOYlWml.js");
7
7
  const environments = require("./chunks/environments-iM3SUM-4.js");
8
8
  const flowEngine = require("./chunks/flow-engine-BxwjEy37.js");
@@ -268,7 +268,7 @@ async function main() {
268
268
  const envName = args.environment ?? args.env;
269
269
  const env = environments.selectEnvironment(workspace, environments$1, envName);
270
270
  const verbose = Boolean(args.verbose);
271
- const version = `v${"0.7.8"}`;
271
+ const version = `v${"0.7.9"}`;
272
272
  console.log("");
273
273
  console.log(cliCommon.color(" API Flow Runner" + (version ? ` ${version}` : ""), cliCommon.C.bold, cliCommon.C.white));
274
274
  console.log(cliCommon.color(` Flow: ${flow.name}`, cliCommon.C.gray));
package/out/main/index.js CHANGED
@@ -29,7 +29,7 @@ const promises = require("node:fs/promises");
29
29
  const crypto = require("node:crypto");
30
30
  const JSZip = require("jszip");
31
31
  const dataFiles = require("./chunks/data-files-BYqhsoPe.js");
32
- const requestExec = require("./chunks/request-exec-Cv2jkrO1.js");
32
+ const requestExec = require("./chunks/request-exec-CgyqbNWk.js");
33
33
  const ipcValidate = require("./chunks/ipc-validate-sqUFqRmE.js");
34
34
  const uuid = require("uuid");
35
35
  const jsYaml = require("js-yaml");
@@ -48,7 +48,7 @@ const grpc = require("@grpc/grpc-js");
48
48
  const protoLoader = require("@grpc/proto-loader");
49
49
  const soapHandler = require("./chunks/soap-handler-Brr7BPWO.js");
50
50
  const escape = require("./chunks/escape-DDVAlOvZ.js");
51
- const brokerClient = require("./chunks/broker-client-BYpWeOWT.js");
51
+ const brokerClient = require("./chunks/broker-client-CJBfpvbd.js");
52
52
  const simpleGit = require("simple-git");
53
53
  const recorder = require("./chunks/recorder-BkO8G_mB.js");
54
54
  const electronUpdater = require("electron-updater");
@@ -5498,6 +5498,11 @@ function registerMockHandlers(ipc) {
5498
5498
  return JSON.parse(raw);
5499
5499
  });
5500
5500
  }
5501
+ async function resolveVars(ctx) {
5502
+ const envVars = await requestExec.buildEnvVars(ctx?.environment ?? null);
5503
+ const dynamic = await requestExec.buildDynamicVars();
5504
+ return requestExec.mergeVars(envVars, ctx?.collectionVars ?? {}, ctx?.globals ?? {}, {}, dynamic);
5505
+ }
5501
5506
  async function resolveClientSecret(auth, vars) {
5502
5507
  let secret = auth.oauth2ClientSecret ?? "";
5503
5508
  if (!secret && auth.oauth2ClientSecretRef) {
@@ -5518,7 +5523,8 @@ async function browserFlow(auth, vars, flow) {
5518
5523
  authUrlFull.searchParams.set("client_id", clientId);
5519
5524
  authUrlFull.searchParams.set("redirect_uri", redirectUri);
5520
5525
  authUrlFull.searchParams.set("state", state);
5521
- if (auth.oauth2Scopes) authUrlFull.searchParams.set("scope", auth.oauth2Scopes);
5526
+ const scopes = requestExec.interpolate(auth.oauth2Scopes ?? "", vars);
5527
+ if (scopes) authUrlFull.searchParams.set("scope", scopes);
5522
5528
  const captured = await new Promise((resolve2, reject) => {
5523
5529
  const server = http.createServer((req, res) => {
5524
5530
  const reqUrl = new URL(req.url ?? "/", `http://localhost:${port}`);
@@ -5593,15 +5599,17 @@ async function browserFlow(auth, vars, flow) {
5593
5599
  };
5594
5600
  }
5595
5601
  function registerOAuth2Handlers(ipc) {
5596
- handle.handleIpc(ipc, handle.IPC.oauth2.startFlow, async (_e, auth, vars) => {
5602
+ handle.handleIpc(ipc, handle.IPC.oauth2.startFlow, async (_e, auth, ctx) => {
5597
5603
  if (auth.type !== "oauth2") throw new Error("OAuth 2.0: auth is not an oauth2 config.");
5604
+ const vars = await resolveVars(ctx);
5598
5605
  const flow = auth.oauth2Flow ?? "client_credentials";
5599
5606
  if (flow === "authorization_code" || flow === "implicit") {
5600
5607
  return browserFlow(auth, vars, flow);
5601
5608
  }
5602
5609
  return requestExec.fetchOAuth2Token(auth, vars);
5603
5610
  });
5604
- handle.handleIpc(ipc, handle.IPC.oauth2.refreshToken, async (_e, auth, vars, refreshToken) => {
5611
+ handle.handleIpc(ipc, handle.IPC.oauth2.refreshToken, async (_e, auth, ctx, refreshToken) => {
5612
+ const vars = await resolveVars(ctx);
5605
5613
  const tokenUrl = requestExec.interpolate(auth.oauth2TokenUrl ?? "", vars);
5606
5614
  const clientId = requestExec.interpolate(auth.oauth2ClientId ?? "", vars);
5607
5615
  let clientSecret = auth.oauth2ClientSecret ?? "";
@@ -7268,9 +7276,9 @@ function registerCloudHandlers(ipc) {
7268
7276
  const liveGlobals = { ...globals, ...requestExec.getGlobals() };
7269
7277
  const staticVars = requestExec.mergeVars(envVars, collectionVars ?? {}, liveGlobals, {}, {});
7270
7278
  const setup = input.setup ?? [];
7271
- const resolveVars = omitKeys(staticVars, setVarNames(setup));
7272
- const monitorRequest = resolveRequest(request, resolveVars);
7273
- const setupRequests = setup.map((h) => resolveRequest(h, resolveVars));
7279
+ const resolveVars2 = omitKeys(staticVars, setVarNames(setup));
7280
+ const monitorRequest = resolveRequest(request, resolveVars2);
7281
+ const setupRequests = setup.map((h) => resolveRequest(h, resolveVars2));
7274
7282
  const payload = {
7275
7283
  name: input.name || request.name || "Monitor",
7276
7284
  target_url: monitorRequest.url,
@@ -7293,7 +7301,7 @@ function isNewer(a, b) {
7293
7301
  return a2 > b2;
7294
7302
  }
7295
7303
  async function checkForUpdate() {
7296
- const current = "0.7.8";
7304
+ const current = "0.7.9";
7297
7305
  try {
7298
7306
  const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(4e3) });
7299
7307
  if (!res.ok) return null;
package/out/main/lib.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const mockServer = require("./chunks/mock-server-C4kTFkod.js");
4
- const requestExec = require("./chunks/request-exec-Cv2jkrO1.js");
4
+ const requestExec = require("./chunks/request-exec-CgyqbNWk.js");
5
5
  const flowEngine = require("./chunks/flow-engine-BxwjEy37.js");
6
6
  require("node:http");
7
7
  require("node:crypto");
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
- const perfRun = require("./chunks/perf-run-uZBqnG3S.js");
3
- const requestExec = require("./chunks/request-exec-Cv2jkrO1.js");
2
+ const perfRun = require("./chunks/perf-run-Co_5unBR.js");
3
+ const requestExec = require("./chunks/request-exec-CgyqbNWk.js");
4
4
  require("@grpc/grpc-js");
5
5
  require("@grpc/proto-loader");
6
6
  require("node:fs");
package/out/main/perf.js CHANGED
@@ -2,10 +2,10 @@
2
2
  "use strict";
3
3
  const promises = require("node:fs/promises");
4
4
  const path = require("node:path");
5
- const requestExec = require("./chunks/request-exec-Cv2jkrO1.js");
5
+ const requestExec = require("./chunks/request-exec-CgyqbNWk.js");
6
6
  const environments = require("./chunks/environments-iM3SUM-4.js");
7
7
  const flowEngine = require("./chunks/flow-engine-BxwjEy37.js");
8
- const perfRun = require("./chunks/perf-run-uZBqnG3S.js");
8
+ const perfRun = require("./chunks/perf-run-Co_5unBR.js");
9
9
  const perfReport = require("./chunks/perf-report-ChaO3K0w.js");
10
10
  const cliCommon = require("./chunks/cli-common-GnihVSjU.js");
11
11
  require("undici");
@@ -191,7 +191,7 @@ async function main() {
191
191
  targetLabel = `flow: ${flow.name}`;
192
192
  }
193
193
  const load = perfRun.deriveLoad(plan);
194
- const version = `v${"0.7.8"}`;
194
+ const version = `v${"0.7.9"}`;
195
195
  console.log("");
196
196
  console.log(cliCommon.color(" API Performance" + (version ? ` ${version}` : ""), cliCommon.C.bold, cliCommon.C.white));
197
197
  console.log(cliCommon.color(` Plan: ${plan.name}`, cliCommon.C.gray));
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
  const promises = require("node:fs/promises");
4
4
  const path = require("node:path");
5
- const requestExec = require("./chunks/request-exec-Cv2jkrO1.js");
5
+ const requestExec = require("./chunks/request-exec-CgyqbNWk.js");
6
6
  const escape = require("./chunks/escape-DDVAlOvZ.js");
7
7
  const requestCollection = require("./chunks/request-collection-gkOYlWml.js");
8
8
  const runConcurrent = require("./chunks/run-concurrent-468tH0AX.js");
@@ -551,7 +551,7 @@ async function main() {
551
551
  } else if (!envName && workspace.settings?.defaultEnvironment && !env) {
552
552
  console.warn(cliCommon.color(`Warning: default environment "${workspace.settings.defaultEnvironment}" not found. Running without environment.`, cliCommon.C.yellow));
553
553
  }
554
- const version = `v${"0.7.8"}`;
554
+ const version = `v${"0.7.9"}`;
555
555
  console.log("");
556
556
  console.log(cliCommon.color(" API Test Runner" + (version ? ` ${version}` : ""), cliCommon.C.bold, cliCommon.C.white));
557
557
  console.log(cliCommon.color(` Workspace: ${wsPath}`, cliCommon.C.gray));
@@ -396,8 +396,10 @@ const api = {
396
396
  // ─── HashiCorp Vault (interactive OIDC login) ─────────────────────────────
397
397
  vaultOidcLogin: (opts) => electron.ipcRenderer.invoke(IPC.vault.oidcLogin, opts),
398
398
  // ─── OAuth 2.0 ────────────────────────────────────────────────────────────
399
- oauth2StartFlow: (auth, vars) => electron.ipcRenderer.invoke(IPC.oauth2.startFlow, auth, vars),
400
- oauth2RefreshToken: (auth, vars, refreshToken) => electron.ipcRenderer.invoke(IPC.oauth2.refreshToken, auth, vars, refreshToken),
399
+ // `ctx` is the active scope; main resolves the full {{var}} map from it
400
+ // (environment incl. secret-manager refs, collection vars, globals).
401
+ oauth2StartFlow: (auth, ctx) => electron.ipcRenderer.invoke(IPC.oauth2.startFlow, auth, ctx),
402
+ oauth2RefreshToken: (auth, ctx, refreshToken) => electron.ipcRenderer.invoke(IPC.oauth2.refreshToken, auth, ctx, refreshToken),
401
403
  // ─── Cloud integration ────────────────────────────────────────────────────────
402
404
  cloudTest: () => electron.ipcRenderer.invoke(IPC.cloud.test),
403
405
  cloudPushMock: (server) => electron.ipcRenderer.invoke(IPC.cloud.pushMock, server),
@@ -1,5 +1,5 @@
1
1
  import { l as linter, E as EditorView, L as LanguageSupport, f as LRLanguage, s as styleTags, i as indentNodeProp, m as delimitedIndent, n as foldNodeProp, p as foldInside, S as StateField, q as LRParser, u as StateEffect, v as tags, a as reactExports, j as jsxRuntimeExports, d as ReactCodeMirror, o as oneDark, c as json } from "./codemirror-CdIFBPs2.js";
2
- import { u as useT, a as useStore, b as useActiveEnvironment, i as isSubscriptionQuery } from "./index-CtCdFiRx.js";
2
+ import { u as useT, a as useStore, b as useActiveEnvironment, i as isSubscriptionQuery } from "./index-BUFSn_qD.js";
3
3
  import "./ajv-CJPwFjiP.js";
4
4
  function devAssert(condition, message) {
5
5
  const booleanCondition = Boolean(condition);
@@ -1,5 +1,5 @@
1
1
  import { a as reactExports, j as jsxRuntimeExports, d as ReactCodeMirror, o as oneDark, x as xml } from "./codemirror-CdIFBPs2.js";
2
- import { u as useT, c as btnPrimaryCls, d as commentKeymap } from "./index-CtCdFiRx.js";
2
+ import { u as useT, c as btnPrimaryCls, d as commentKeymap } from "./index-BUFSn_qD.js";
3
3
  import "./ajv-CJPwFjiP.js";
4
4
  const SOAP_11_CONTENT_TYPE = "text/xml; charset=utf-8";
5
5
  const SOAP_12_CONTENT_TYPE = "application/soap+xml; charset=utf-8";
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./GraphQLEditor-Dv2K4wdd.js","./codemirror-CdIFBPs2.js","./ajv-CJPwFjiP.js","./SoapEditor-Cnz3M4Dz.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./GraphQLEditor-CXvLKrnv.js","./codemirror-CdIFBPs2.js","./ajv-CJPwFjiP.js","./SoapEditor-7hxhISPZ.js"])))=>i.map(i=>d[i]);
2
2
  import { r as requireReact, g as getDefaultExportFromCjs, R as React, a as reactExports, b as autocompletion, h as hoverTooltip, j as jsxRuntimeExports, k as keymap, t as toggleComment, x as xml, c as json, d as ReactCodeMirror, o as oneDark, e as javascript } from "./codemirror-CdIFBPs2.js";
3
3
  import { r as requireAjv } from "./ajv-CJPwFjiP.js";
4
4
  var client = { exports: {} };
@@ -24384,12 +24384,15 @@ const ICON = {
24384
24384
  };
24385
24385
  function parseVarTokens(str) {
24386
24386
  const found = [];
24387
- const re = /\{\{([^}]+)\}\}/g;
24388
- let m;
24389
- while ((m = re.exec(str)) !== null) {
24390
- const name = m[1].trim();
24391
- if (!found.includes(name)) found.push(name);
24392
- }
24387
+ const seen2 = /* @__PURE__ */ new Set();
24388
+ const push = (name, display) => {
24389
+ if (!seen2.has(display)) {
24390
+ seen2.add(display);
24391
+ found.push({ name, display });
24392
+ }
24393
+ };
24394
+ for (const m of str.matchAll(/\{\{([^}]+)\}\}/g)) push(m[1].trim(), `{{${m[1].trim()}}}`);
24395
+ for (const m of str.matchAll(/\[([A-Za-z_]\w*)\]/g)) push(m[1], `[${m[1]}]`);
24393
24396
  return found;
24394
24397
  }
24395
24398
  function PortalDropdown({
@@ -24425,11 +24428,14 @@ function PortalDropdown({
24425
24428
  document.body
24426
24429
  );
24427
24430
  }
24428
- function VarInput({ value: value2, onChange, className, wrapperClassName, staticSuggestions, ...rest }) {
24431
+ function VarInput({ value: value2, onChange, className, wrapperClassName, staticSuggestions, extraVars, ...rest }) {
24429
24432
  const t2 = useT();
24430
24433
  const varNames = useVarNames();
24431
24434
  const varValues = useVarValues();
24432
24435
  const inputRef = reactExports.useRef(null);
24436
+ const extraKeys = extraVars ? Object.keys(extraVars) : [];
24437
+ const mergedNames = extraKeys.length ? Array.from(/* @__PURE__ */ new Set([...extraKeys, ...varNames])) : varNames;
24438
+ const mergedValues = extraKeys.length ? { ...varValues, ...extraVars } : varValues;
24433
24439
  const [suggestions, setSuggestions] = reactExports.useState([]);
24434
24440
  const [suggestionMode, setSuggestionMode] = reactExports.useState("var");
24435
24441
  const [activeIndex, setActiveIndex] = reactExports.useState(-1);
@@ -24482,7 +24488,7 @@ function VarInput({ value: value2, onChange, className, wrapperClassName, static
24482
24488
  m = /\{\{(\$?\w*)$/.exec(before);
24483
24489
  if (m) {
24484
24490
  const q = m[1].toLowerCase();
24485
- const vars = varNames.filter((n2) => n2.toLowerCase().includes(q)).map((n2) => ({ label: n2, insert: n2, type: "variable", close: true, boost: n2.startsWith("$") ? 1 : 0 }));
24491
+ const vars = mergedNames.filter((n2) => n2.toLowerCase().includes(q)).map((n2) => ({ label: n2, insert: n2, type: "variable", close: true, boost: n2.startsWith("$") ? 1 : 0 }));
24486
24492
  const starters = [
24487
24493
  { label: "faker", insert: "faker.", type: "property" },
24488
24494
  { label: "dayjs", insert: "dayjs().", type: "function" }
@@ -24559,9 +24565,10 @@ function VarInput({ value: value2, onChange, className, wrapperClassName, static
24559
24565
  }
24560
24566
  const tokens = parseVarTokens(value2);
24561
24567
  const hasVars = tokens.length > 0;
24562
- const previewItems = tokens.map((name) => ({
24568
+ const previewItems = tokens.map(({ name, display }) => ({
24563
24569
  name,
24564
- resolved: varValues[name] ?? null
24570
+ display,
24571
+ resolved: mergedValues[name] ?? null
24565
24572
  }));
24566
24573
  const { onFocus: _f, onBlur: _b, ...inputRest } = rest;
24567
24574
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -24594,11 +24601,11 @@ function VarInput({ value: value2, onChange, className, wrapperClassName, static
24594
24601
  onPick: apply
24595
24602
  }
24596
24603
  ),
24597
- 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, 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: [
24598
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-blue-400 shrink-0", children: `{{${name}}}` }),
24604
+ 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(({ display, 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: [
24605
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-blue-400 shrink-0", children: display }),
24599
24606
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-500 mx-0.5", children: "→" }),
24600
24607
  resolved !== null ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono text-emerald-400 truncate", children: resolved }) : /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-orange-400 italic", children: t2("undefined") })
24601
- ] }, name)) })
24608
+ ] }, display)) })
24602
24609
  ]
24603
24610
  }
24604
24611
  );
@@ -24933,6 +24940,14 @@ function Modal({
24933
24940
  const { electron: electron$F } = window;
24934
24941
  function Oauth2Form({ auth, onChange }) {
24935
24942
  const t2 = useT();
24943
+ const activeEnv = useActiveEnvironment();
24944
+ const globals = useStore$1((s) => s.globals);
24945
+ const activeCollectionId = useStore$1((s) => s.activeCollectionId);
24946
+ const collections = useStore$1((s) => s.collections);
24947
+ function resolveCtx() {
24948
+ const collectionVars = activeCollectionId ? collections[activeCollectionId]?.data.collectionVariables ?? {} : {};
24949
+ return { environment: activeEnv, collectionVars, globals };
24950
+ }
24936
24951
  const [secretValue, setSecretValue] = reactExports.useState("");
24937
24952
  const [saved, setSaved] = reactExports.useState(false);
24938
24953
  const [status, setStatus] = reactExports.useState("idle");
@@ -24951,7 +24966,7 @@ function Oauth2Form({ auth, onChange }) {
24951
24966
  setStatus("fetching");
24952
24967
  setError("");
24953
24968
  try {
24954
- const result = await electron$F.oauth2StartFlow(auth, {});
24969
+ const result = await electron$F.oauth2StartFlow(auth, resolveCtx());
24955
24970
  onChange({ oauth2CachedToken: result.accessToken, oauth2TokenExpiry: result.expiresAt });
24956
24971
  if (result.refreshToken) setRefreshToken(result.refreshToken);
24957
24972
  setStatus("ok");
@@ -24965,7 +24980,7 @@ function Oauth2Form({ auth, onChange }) {
24965
24980
  setStatus("fetching");
24966
24981
  setError("");
24967
24982
  try {
24968
- const result = await electron$F.oauth2RefreshToken(auth, {}, refreshToken);
24983
+ const result = await electron$F.oauth2RefreshToken(auth, resolveCtx(), refreshToken);
24969
24984
  onChange({ oauth2CachedToken: result.accessToken, oauth2TokenExpiry: result.expiresAt });
24970
24985
  if (result.refreshToken) setRefreshToken(result.refreshToken);
24971
24986
  setStatus("ok");
@@ -25013,10 +25028,10 @@ function Oauth2Form({ auth, onChange }) {
25013
25028
  flow !== "implicit" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
25014
25029
  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: t2("Token URL") }),
25015
25030
  /* @__PURE__ */ jsxRuntimeExports.jsx(
25016
- "input",
25031
+ VarInput,
25017
25032
  {
25018
25033
  value: auth.oauth2TokenUrl ?? "",
25019
- onChange: (e) => onChange({ oauth2TokenUrl: e.target.value }),
25034
+ onChange: (v) => onChange({ oauth2TokenUrl: v }),
25020
25035
  placeholder: "https://auth.example.com/oauth/token",
25021
25036
  className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500 font-mono"
25022
25037
  }
@@ -25026,10 +25041,10 @@ function Oauth2Form({ auth, onChange }) {
25026
25041
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25027
25042
  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: t2("Auth URL") }),
25028
25043
  /* @__PURE__ */ jsxRuntimeExports.jsx(
25029
- "input",
25044
+ VarInput,
25030
25045
  {
25031
25046
  value: auth.oauth2AuthUrl ?? "",
25032
- onChange: (e) => onChange({ oauth2AuthUrl: e.target.value }),
25047
+ onChange: (v) => onChange({ oauth2AuthUrl: v }),
25033
25048
  placeholder: "https://auth.example.com/oauth/authorize",
25034
25049
  className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500 font-mono"
25035
25050
  }
@@ -25052,10 +25067,10 @@ function Oauth2Form({ auth, onChange }) {
25052
25067
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25053
25068
  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: t2("Client ID") }),
25054
25069
  /* @__PURE__ */ jsxRuntimeExports.jsx(
25055
- "input",
25070
+ VarInput,
25056
25071
  {
25057
25072
  value: auth.oauth2ClientId ?? "",
25058
- onChange: (e) => onChange({ oauth2ClientId: e.target.value }),
25073
+ onChange: (v) => onChange({ oauth2ClientId: v }),
25059
25074
  className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
25060
25075
  }
25061
25076
  )
@@ -25131,10 +25146,10 @@ function Oauth2Form({ auth, onChange }) {
25131
25146
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25132
25147
  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: t2("Username") }),
25133
25148
  /* @__PURE__ */ jsxRuntimeExports.jsx(
25134
- "input",
25149
+ VarInput,
25135
25150
  {
25136
25151
  value: auth.username ?? "",
25137
- onChange: (e) => onChange({ username: e.target.value }),
25152
+ onChange: (v) => onChange({ username: v }),
25138
25153
  className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
25139
25154
  }
25140
25155
  )
@@ -25142,11 +25157,10 @@ function Oauth2Form({ auth, onChange }) {
25142
25157
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25143
25158
  /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: t2("Password") }),
25144
25159
  /* @__PURE__ */ jsxRuntimeExports.jsx(
25145
- "input",
25160
+ VarInput,
25146
25161
  {
25147
- type: "password",
25148
25162
  value: auth.password ?? "",
25149
- onChange: (e) => onChange({ password: e.target.value }),
25163
+ onChange: (v) => onChange({ password: v }),
25150
25164
  className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500 font-mono"
25151
25165
  }
25152
25166
  )
@@ -25159,10 +25173,10 @@ function Oauth2Form({ auth, onChange }) {
25159
25173
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-600", children: t2("(space-separated)") })
25160
25174
  ] }),
25161
25175
  /* @__PURE__ */ jsxRuntimeExports.jsx(
25162
- "input",
25176
+ VarInput,
25163
25177
  {
25164
25178
  value: auth.oauth2Scopes ?? "",
25165
- onChange: (e) => onChange({ oauth2Scopes: e.target.value }),
25179
+ onChange: (v) => onChange({ oauth2Scopes: v }),
25166
25180
  placeholder: t2("read write"),
25167
25181
  className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
25168
25182
  }
@@ -25266,109 +25280,24 @@ function AuthEditor({
25266
25280
  }
25267
25281
  ) : /* @__PURE__ */ jsxRuntimeExports.jsx(PlainCredentialsFields, { auth, onChange })),
25268
25282
  auth.type === "ntlm" && (secrets ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [
25269
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
25270
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25271
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: t2("Username") }),
25272
- /* @__PURE__ */ jsxRuntimeExports.jsx(
25273
- "input",
25274
- {
25275
- value: auth.username ?? "",
25276
- onChange: (e) => onChange({ username: e.target.value }),
25277
- className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
25278
- }
25279
- )
25280
- ] }),
25281
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25282
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: t2("Password") }),
25283
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1 mt-1", children: [
25284
- /* @__PURE__ */ jsxRuntimeExports.jsx(
25285
- "input",
25286
- {
25287
- type: "password",
25288
- value: secrets.secretValue,
25289
- onChange: (e) => secrets.setSecretValue(e.target.value),
25290
- placeholder: auth.passwordSecretRef ? t2('Stored as ":ref"', { ref: auth.passwordSecretRef }) : t2("Password"),
25291
- className: "flex-1 bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500 font-mono"
25292
- }
25293
- ),
25294
- /* @__PURE__ */ jsxRuntimeExports.jsx(
25295
- "button",
25296
- {
25297
- onClick: () => {
25298
- const ref = auth.passwordSecretRef ?? "NTLM_PASSWORD";
25299
- onChange({ passwordSecretRef: ref });
25300
- void secrets.saveSecret(ref);
25301
- },
25302
- className: "px-2 py-1 bg-blue-700 hover:bg-blue-600 rounded transition-colors",
25303
- children: secrets.saved ? "✓" : t2("Save")
25304
- }
25305
- )
25306
- ] })
25307
- ] })
25308
- ] }),
25309
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
25310
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25311
- /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-surface-400", children: [
25312
- t2("Domain"),
25313
- " ",
25314
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-600", children: t2("(optional)") })
25315
- ] }),
25316
- /* @__PURE__ */ jsxRuntimeExports.jsx(
25317
- "input",
25318
- {
25319
- value: auth.ntlmDomain ?? "",
25320
- onChange: (e) => onChange({ ntlmDomain: e.target.value }),
25321
- placeholder: "WORKGROUP",
25322
- className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
25323
- }
25324
- )
25325
- ] }),
25326
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25327
- /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-surface-400", children: [
25328
- t2("Workstation"),
25329
- " ",
25330
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-600", children: t2("(optional)") })
25331
- ] }),
25332
- /* @__PURE__ */ jsxRuntimeExports.jsx(
25333
- "input",
25334
- {
25335
- value: auth.ntlmWorkstation ?? "",
25336
- onChange: (e) => onChange({ ntlmWorkstation: e.target.value }),
25337
- placeholder: "MACHINE",
25338
- className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
25339
- }
25340
- )
25341
- ] })
25342
- ] }),
25283
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
25284
+ BasicCredentialsFields,
25285
+ {
25286
+ auth,
25287
+ secretValue: secrets.secretValue,
25288
+ setSecretValue: secrets.setSecretValue,
25289
+ saved: secrets.saved,
25290
+ setAuth: onChange,
25291
+ saveSecret: secrets.saveSecret,
25292
+ label: t2("NTLM Auth"),
25293
+ secretRefDefault: "NTLM_PASSWORD"
25294
+ }
25295
+ ),
25296
+ /* @__PURE__ */ jsxRuntimeExports.jsx(NtlmDomainFields, { auth, onChange }),
25343
25297
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-surface-400 text-[10px] bg-surface-800 border border-surface-700 rounded px-2 py-1", children: t2("Uses NTLMv2 over a single keep-alive connection. Not supported through a proxy.") })
25344
25298
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-2", children: [
25345
25299
  /* @__PURE__ */ jsxRuntimeExports.jsx(PlainCredentialsFields, { auth, onChange }),
25346
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
25347
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25348
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: t2("Domain") }),
25349
- /* @__PURE__ */ jsxRuntimeExports.jsx(
25350
- "input",
25351
- {
25352
- value: auth.ntlmDomain ?? "",
25353
- onChange: (e) => onChange({ ntlmDomain: e.target.value }),
25354
- placeholder: "WORKGROUP",
25355
- className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
25356
- }
25357
- )
25358
- ] }),
25359
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25360
- /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "text-surface-400", children: t2("Workstation") }),
25361
- /* @__PURE__ */ jsxRuntimeExports.jsx(
25362
- "input",
25363
- {
25364
- value: auth.ntlmWorkstation ?? "",
25365
- onChange: (e) => onChange({ ntlmWorkstation: e.target.value }),
25366
- placeholder: "MACHINE",
25367
- className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
25368
- }
25369
- )
25370
- ] })
25371
- ] })
25300
+ /* @__PURE__ */ jsxRuntimeExports.jsx(NtlmDomainFields, { auth, onChange })
25372
25301
  ] })),
25373
25302
  auth.type === "apikey" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-1.5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
25374
25303
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
@@ -25474,6 +25403,46 @@ function PlainCredentialsFields({
25474
25403
  ] })
25475
25404
  ] });
25476
25405
  }
25406
+ function NtlmDomainFields({
25407
+ auth,
25408
+ onChange
25409
+ }) {
25410
+ const t2 = useT();
25411
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
25412
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25413
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-surface-400", children: [
25414
+ t2("Domain"),
25415
+ " ",
25416
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-600", children: t2("(optional)") })
25417
+ ] }),
25418
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
25419
+ VarInput,
25420
+ {
25421
+ value: auth.ntlmDomain ?? "",
25422
+ onChange: (v) => onChange({ ntlmDomain: v }),
25423
+ placeholder: "WORKGROUP",
25424
+ className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
25425
+ }
25426
+ )
25427
+ ] }),
25428
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
25429
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-surface-400", children: [
25430
+ t2("Workstation"),
25431
+ " ",
25432
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-surface-600", children: t2("(optional)") })
25433
+ ] }),
25434
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
25435
+ VarInput,
25436
+ {
25437
+ value: auth.ntlmWorkstation ?? "",
25438
+ onChange: (v) => onChange({ ntlmWorkstation: v }),
25439
+ placeholder: "MACHINE",
25440
+ className: "mt-1 w-full bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
25441
+ }
25442
+ )
25443
+ ] })
25444
+ ] });
25445
+ }
25477
25446
  function BasicCredentialsFields({
25478
25447
  auth,
25479
25448
  secretValue,
@@ -25482,7 +25451,8 @@ function BasicCredentialsFields({
25482
25451
  setAuth,
25483
25452
  saveSecret,
25484
25453
  label,
25485
- note
25454
+ note,
25455
+ secretRefDefault = "API_PASSWORD"
25486
25456
  }) {
25487
25457
  const t2 = useT();
25488
25458
  const [keychainOpen, setKeychainOpen] = reactExports.useState(!!auth.passwordSecretRef);
@@ -25546,7 +25516,7 @@ function BasicCredentialsFields({
25546
25516
  /* @__PURE__ */ jsxRuntimeExports.jsx(
25547
25517
  "input",
25548
25518
  {
25549
- value: auth.passwordSecretRef ?? "API_PASSWORD",
25519
+ value: auth.passwordSecretRef ?? secretRefDefault,
25550
25520
  onChange: (e) => setAuth({ passwordSecretRef: e.target.value }),
25551
25521
  placeholder: t2("Keychain key"),
25552
25522
  className: "w-32 bg-surface-800 border border-surface-700 rounded px-2 py-1 focus:outline-none focus:border-blue-500"
@@ -25556,7 +25526,7 @@ function BasicCredentialsFields({
25556
25526
  "button",
25557
25527
  {
25558
25528
  onClick: () => {
25559
- const ref = auth.passwordSecretRef ?? "API_PASSWORD";
25529
+ const ref = auth.passwordSecretRef ?? secretRefDefault;
25560
25530
  setAuth({ passwordSecretRef: ref });
25561
25531
  void saveSecret(ref);
25562
25532
  },
@@ -28298,6 +28268,40 @@ function extractQueryParams(rawUrl, existing) {
28298
28268
  const kept = (existing ?? []).filter((p) => (p.key || p.value) && !pastedKeys.has(p.key));
28299
28269
  return { url: nextUrl, params: [...kept, ...parsed], changed: true };
28300
28270
  }
28271
+ const PATH_PARAM_RE = /\[([A-Za-z_]\w*)\]/g;
28272
+ function extractPathParamNames(url) {
28273
+ const names = [];
28274
+ for (const m of url.matchAll(PATH_PARAM_RE)) {
28275
+ if (!names.includes(m[1])) names.push(m[1]);
28276
+ }
28277
+ return names;
28278
+ }
28279
+ function referencedNames(url) {
28280
+ const names = new Set(extractPathParamNames(url));
28281
+ for (const m of url.matchAll(/\{\{([^}]+)\}\}/g)) names.add(m[1].trim());
28282
+ return names;
28283
+ }
28284
+ function syncParamsFromUrl(rawUrl, existing) {
28285
+ const q = extractQueryParams(rawUrl, existing);
28286
+ const url = q.url;
28287
+ let changed2 = q.changed;
28288
+ const pathNames = extractPathParamNames(url);
28289
+ const referenced = referencedNames(url);
28290
+ let params = q.params.filter((p) => {
28291
+ if (p.paramType === "path" && !p.value && p.key && !referenced.has(p.key)) {
28292
+ changed2 = true;
28293
+ return false;
28294
+ }
28295
+ return true;
28296
+ });
28297
+ const have = new Set(params.filter((p) => p.key).map((p) => p.key));
28298
+ const additions = pathNames.filter((n2) => !have.has(n2)).map((n2) => ({ key: n2, value: "", enabled: true, paramType: "path" }));
28299
+ if (additions.length) {
28300
+ changed2 = true;
28301
+ params = [...params, ...additions];
28302
+ }
28303
+ return { url, params, changed: changed2 };
28304
+ }
28301
28305
  function ParamsTab({ request: request2, onChange }) {
28302
28306
  const t2 = useT();
28303
28307
  return /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -28423,8 +28427,8 @@ function jsonWithComments() {
28423
28427
  function xmlWithComments() {
28424
28428
  return [xml(), commentKeymap];
28425
28429
  }
28426
- const GraphQLEditor = reactExports.lazy(() => __vitePreload(() => import("./GraphQLEditor-Dv2K4wdd.js"), true ? __vite__mapDeps([0,1,2]) : void 0, import.meta.url).then((m) => ({ default: m.GraphQLEditor })));
28427
- const SoapEditor = reactExports.lazy(() => __vitePreload(() => import("./SoapEditor-Cnz3M4Dz.js"), true ? __vite__mapDeps([3,1,2]) : void 0, import.meta.url).then((m) => ({ default: m.SoapEditor })));
28430
+ const GraphQLEditor = reactExports.lazy(() => __vitePreload(() => import("./GraphQLEditor-CXvLKrnv.js"), true ? __vite__mapDeps([0,1,2]) : void 0, import.meta.url).then((m) => ({ default: m.GraphQLEditor })));
28431
+ const SoapEditor = reactExports.lazy(() => __vitePreload(() => import("./SoapEditor-7hxhISPZ.js"), true ? __vite__mapDeps([3,1,2]) : void 0, import.meta.url).then((m) => ({ default: m.SoapEditor })));
28428
28432
  function BodyTab({ request: request2, onChange }) {
28429
28433
  const t2 = useT();
28430
28434
  const editorFallback = /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 text-xs text-surface-500", children: t2("Loading editor…") });
@@ -31491,17 +31495,20 @@ function RequestBuilder({ request: request2 }) {
31491
31495
  }
31492
31496
  function handleUrlPaste(e) {
31493
31497
  const pasted = e.clipboardData.getData("text");
31494
- if (!pasted.includes("?")) return;
31495
31498
  const input = e.currentTarget;
31496
31499
  const start2 = input.selectionStart ?? request2.url.length;
31497
31500
  const end = input.selectionEnd ?? request2.url.length;
31498
31501
  const resulting = request2.url.slice(0, start2) + pasted + request2.url.slice(end);
31499
- const split = extractQueryParams(resulting, request2.params ?? []);
31500
- if (split.changed) {
31502
+ const synced = syncParamsFromUrl(resulting, request2.params ?? []);
31503
+ if (synced.changed) {
31501
31504
  e.preventDefault();
31502
- update({ url: split.url, params: split.params });
31505
+ update({ url: synced.url, params: synced.params });
31503
31506
  }
31504
31507
  }
31508
+ function handleUrlBlur() {
31509
+ const synced = syncParamsFromUrl(request2.url, request2.params ?? []);
31510
+ if (synced.changed) update({ url: synced.url, params: synced.params });
31511
+ }
31505
31512
  const sendSignal = useStore$1((s) => s.sendSignal);
31506
31513
  const lastSendSignal = reactExports.useRef(sendSignal);
31507
31514
  reactExports.useEffect(() => {
@@ -31903,6 +31910,10 @@ function RequestBuilder({ request: request2 }) {
31903
31910
  value: request2.url,
31904
31911
  onChange: (url) => update({ url }),
31905
31912
  onPaste: handleUrlPaste,
31913
+ onBlur: handleUrlBlur,
31914
+ extraVars: Object.fromEntries(
31915
+ (request2.params ?? []).filter((p) => p.enabled && p.key).map((p) => [p.key, p.value])
31916
+ ),
31906
31917
  placeholder: isWs ? "ws://example.com/socket" : isSoap ? t2("Endpoint (auto-filled from WSDL <soap:address>)") : isGrpc ? "localhost:50051" : isMqtt ? "mqtt://broker.example.com:1883" : "https://api.example.com/endpoint",
31907
31918
  wrapperClassName: "flex-1",
31908
31919
  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"}`
@@ -35866,7 +35877,7 @@ function WelcomeScreen() {
35866
35877
  )
35867
35878
  ] }),
35868
35879
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-surface-400 text-sm max-w-sm", children: t2("Local-first API testing with Robot Framework & Playwright code generation. Secrets stay on your machine.") }),
35869
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] mt-3", style: { color: "var(--text-muted)" }, children: t2("version :version", { version: "0.7.8" }) })
35880
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] mt-3", style: { color: "var(--text-muted)" }, children: t2("version :version", { version: "0.7.9" }) })
35870
35881
  ] }),
35871
35882
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3 w-64", children: [
35872
35883
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -56001,7 +56012,7 @@ function App() {
56001
56012
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "#6aa3c8" }, children: "Spector" }),
56002
56013
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-[10px] font-normal opacity-50", children: [
56003
56014
  "v",
56004
- "0.7.8"
56015
+ "0.7.9"
56005
56016
  ] }),
56006
56017
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mx-2 opacity-30", children: "·" }),
56007
56018
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -5,7 +5,7 @@
5
5
  <meta charset="UTF-8" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>API Spector</title>
8
- <script type="module" crossorigin src="./assets/index-CtCdFiRx.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-BUFSn_qD.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="./assets/codemirror-CdIFBPs2.js">
10
10
  <link rel="modulepreload" crossorigin href="./assets/ajv-CJPwFjiP.js">
11
11
  <link rel="stylesheet" crossorigin href="./assets/index-DkhdKzQJ.css">
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@testsmith/api-spector",
3
3
  "productName": "API Spector",
4
- "version": "0.7.8",
4
+ "version": "0.7.9",
5
5
  "description": "Local-first API testing tool to inspect, test and mock APIs",
6
6
  "repository": {
7
7
  "type": "git",