@testsmith/api-spector 0.6.6 → 0.6.8

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-BRmVweue.js");
6
+ const requestExec = require("./request-exec-DltXYFsc.js");
7
7
  const Ajv = require("ajv");
8
8
  const jsYaml = require("js-yaml");
9
9
  require("node:http");
@@ -199,7 +199,15 @@ const IPC = {
199
199
  },
200
200
  // ─── App ───────────────────────────────────────────────────────────────────
201
201
  app: {
202
- checkUpdate: "app:checkUpdate"
202
+ checkUpdate: "app:checkUpdate",
203
+ /** 'auto' (packaged → electron-updater) vs 'npm' (run from the npm package). */
204
+ updateMode: "app:updateMode",
205
+ /** Renderer asks the main process to quit and apply a downloaded update. */
206
+ installUpdate: "app:installUpdate",
207
+ /** Main → renderer auto-update events (packaged builds only). */
208
+ onUpdateAvailable: "app:updateAvailable",
209
+ onUpdateDownloaded: "app:updateDownloaded",
210
+ onUpdateError: "app:updateError"
203
211
  },
204
212
  // ─── Cloud (API Spector Cloud integration) ──────────────────────────────────
205
213
  cloud: {
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const uuid = require("uuid");
4
- const soapHandler = require("./soap-handler-BznuMFIP.js");
5
- require("./handle-CL-nWtYA.js");
4
+ const soapHandler = require("./soap-handler-DYVGnmgi.js");
5
+ require("./handle-DHNkZoP1.js");
6
6
  require("node:https");
7
7
  require("node:http");
8
8
  require("@xmldom/xmldom");
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  const undici = require("undici");
25
25
  const promises$1 = require("fs/promises");
26
26
  const nodeTls = require("tls");
27
- const handle = require("./handle-CL-nWtYA.js");
27
+ const handle = require("./handle-DHNkZoP1.js");
28
28
  const fs = require("node:fs");
29
29
  const os = require("node:os");
30
30
  const path = require("node:path");
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const handle = require("./handle-CL-nWtYA.js");
2
+ const handle = require("./handle-DHNkZoP1.js");
3
3
  const https = require("node:https");
4
4
  const http = require("node:http");
5
5
  const xmldom = require("@xmldom/xmldom");
@@ -313,7 +313,7 @@ function registerSoapHandlers(ipc) {
313
313
  handle.handleIpc(ipc, handle.IPC.wsdl.import, async (_event, opts) => {
314
314
  const { validateWsdlImport } = await Promise.resolve().then(() => require("./ipc-validate-sqUFqRmE.js"));
315
315
  validateWsdlImport(opts);
316
- const { importWsdl } = await Promise.resolve().then(() => require("./import-DYssQzex.js"));
316
+ const { importWsdl } = await Promise.resolve().then(() => require("./import-CNwoS1_c.js"));
317
317
  const wsdlText = opts.xml ?? (opts.url ? await fetchUrl(opts.url) : "");
318
318
  if (!wsdlText) throw new Error("wsdl:import requires either `url` or `xml`");
319
319
  return importWsdl(wsdlText, { name: opts.name, existingMockPorts: opts.existingMockPorts });
@@ -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-CvRuiX3o.js");
5
+ const brokerClient = require("./chunks/broker-client-CN09i5Tl.js");
6
6
  const escape = require("./chunks/escape-DDVAlOvZ.js");
7
7
  const crypto = require("node:crypto");
8
8
  const undici = require("undici");
@@ -11,10 +11,10 @@ const cliCommon = require("./chunks/cli-common-Cq_cphpZ.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-BRmVweue.js");
14
+ require("./chunks/request-exec-DltXYFsc.js");
15
15
  require("fs/promises");
16
16
  require("tls");
17
- require("./chunks/handle-CL-nWtYA.js");
17
+ require("./chunks/handle-DHNkZoP1.js");
18
18
  require("node:fs");
19
19
  require("dayjs");
20
20
  require("node:vm");
package/out/main/index.js CHANGED
@@ -22,14 +22,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
  const electron = require("electron");
25
- const handle = require("./chunks/handle-CL-nWtYA.js");
25
+ const handle = require("./chunks/handle-DHNkZoP1.js");
26
26
  const path = require("node:path");
27
27
  const fs = require("node:fs");
28
28
  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-BRmVweue.js");
32
+ const requestExec = require("./chunks/request-exec-DltXYFsc.js");
33
33
  const ipcValidate = require("./chunks/ipc-validate-sqUFqRmE.js");
34
34
  const uuid = require("uuid");
35
35
  const jsYaml = require("js-yaml");
@@ -41,11 +41,12 @@ const WebSocket = require("ws");
41
41
  const os = require("node:os");
42
42
  const grpc = require("@grpc/grpc-js");
43
43
  const protoLoader = require("@grpc/proto-loader");
44
- const soapHandler = require("./chunks/soap-handler-BznuMFIP.js");
44
+ const soapHandler = require("./chunks/soap-handler-DYVGnmgi.js");
45
45
  const escape = require("./chunks/escape-DDVAlOvZ.js");
46
- const brokerClient = require("./chunks/broker-client-CvRuiX3o.js");
46
+ const brokerClient = require("./chunks/broker-client-CN09i5Tl.js");
47
47
  const simpleGit = require("simple-git");
48
48
  const recorder = require("./chunks/recorder-BkO8G_mB.js");
49
+ const electronUpdater = require("electron-updater");
49
50
  require("fs/promises");
50
51
  require("tls");
51
52
  require("dayjs");
@@ -5942,7 +5943,7 @@ function isNewer(a, b) {
5942
5943
  return a2 > b2;
5943
5944
  }
5944
5945
  async function checkForUpdate() {
5945
- const current = "0.6.6";
5946
+ const current = "0.6.8";
5946
5947
  try {
5947
5948
  const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(4e3) });
5948
5949
  if (!res.ok) return null;
@@ -5959,6 +5960,33 @@ async function checkForUpdate() {
5959
5960
  return null;
5960
5961
  }
5961
5962
  }
5963
+ function updateMode() {
5964
+ return electron.app.isPackaged ? "auto" : "npm";
5965
+ }
5966
+ let installReady = false;
5967
+ function initAutoUpdater() {
5968
+ if (updateMode() !== "auto") return;
5969
+ const send = (channel, payload) => {
5970
+ for (const w of electron.BrowserWindow.getAllWindows()) w.webContents.send(channel, payload);
5971
+ };
5972
+ electronUpdater.autoUpdater.autoDownload = true;
5973
+ electronUpdater.autoUpdater.autoInstallOnAppQuit = true;
5974
+ electronUpdater.autoUpdater.on("update-available", (info) => {
5975
+ send(handle.IPC.app.onUpdateAvailable, { version: info.version });
5976
+ });
5977
+ electronUpdater.autoUpdater.on("update-downloaded", (info) => {
5978
+ installReady = true;
5979
+ send(handle.IPC.app.onUpdateDownloaded, { version: info.version });
5980
+ });
5981
+ electronUpdater.autoUpdater.on("error", (err) => {
5982
+ send(handle.IPC.app.onUpdateError, { message: err instanceof Error ? err.message : String(err) });
5983
+ });
5984
+ electronUpdater.autoUpdater.checkForUpdates().catch(() => {
5985
+ });
5986
+ }
5987
+ function installUpdate() {
5988
+ if (installReady) electronUpdater.autoUpdater.quitAndInstall();
5989
+ }
5962
5990
  if (process.env.ELECTRON_NO_SANDBOX === "1") {
5963
5991
  electron.app.commandLine.appendSwitch("no-sandbox");
5964
5992
  electron.app.commandLine.appendSwitch("disable-features", "RendererCodeIntegrity");
@@ -6139,7 +6167,10 @@ electron.app.whenReady().then(async () => {
6139
6167
  registerCloudHandlers(electron.ipcMain);
6140
6168
  handle.handleIpc(electron.ipcMain, handle.IPC.shell.openExternal, (_e, url) => electron.shell.openExternal(url));
6141
6169
  handle.handleIpc(electron.ipcMain, handle.IPC.app.checkUpdate, () => checkForUpdate());
6170
+ handle.handleIpc(electron.ipcMain, handle.IPC.app.updateMode, () => updateMode());
6171
+ handle.handleIpc(electron.ipcMain, handle.IPC.app.installUpdate, () => installUpdate());
6142
6172
  createWindow();
6173
+ initAutoUpdater();
6143
6174
  if (process.platform !== "darwin") {
6144
6175
  const url = deepLinkFromArgv(process.argv);
6145
6176
  if (url) handleDeepLink(url);
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-BRmVweue.js");
4
+ const requestExec = require("./chunks/request-exec-DltXYFsc.js");
5
5
  require("node:http");
6
6
  require("node:crypto");
7
7
  require("node:vm");
@@ -10,7 +10,7 @@ require("@xmldom/xmldom");
10
10
  require("undici");
11
11
  require("fs/promises");
12
12
  require("tls");
13
- require("./chunks/handle-CL-nWtYA.js");
13
+ require("./chunks/handle-DHNkZoP1.js");
14
14
  require("node:fs");
15
15
  require("node:os");
16
16
  require("node:path");
@@ -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-BRmVweue.js");
5
+ const requestExec = require("./chunks/request-exec-DltXYFsc.js");
6
6
  const escape = require("./chunks/escape-DDVAlOvZ.js");
7
7
  const requestCollection = require("./chunks/request-collection-KGPuvN7o.js");
8
8
  const environments = require("./chunks/environments-iM3SUM-4.js");
@@ -10,7 +10,7 @@ const cliCommon = require("./chunks/cli-common-Cq_cphpZ.js");
10
10
  require("undici");
11
11
  require("fs/promises");
12
12
  require("tls");
13
- require("./chunks/handle-CL-nWtYA.js");
13
+ require("./chunks/handle-DHNkZoP1.js");
14
14
  require("node:fs");
15
15
  require("node:os");
16
16
  require("node:crypto");
@@ -495,7 +495,7 @@ async function main() {
495
495
  } else if (!envName && workspace.settings?.defaultEnvironment && !env) {
496
496
  console.warn(cliCommon.color(`Warning: default environment "${workspace.settings.defaultEnvironment}" not found. Running without environment.`, cliCommon.C.yellow));
497
497
  }
498
- const version = `v${"0.6.6"}`;
498
+ const version = `v${"0.6.8"}`;
499
499
  console.log("");
500
500
  console.log(cliCommon.color(" API Test Runner" + (version ? ` ${version}` : ""), cliCommon.C.bold, cliCommon.C.white));
501
501
  console.log(cliCommon.color(` Workspace: ${wsPath}`, cliCommon.C.gray));
package/out/main/wsdl.js CHANGED
@@ -4,10 +4,10 @@ const promises = require("node:fs/promises");
4
4
  const path = require("node:path");
5
5
  const https = require("node:https");
6
6
  const http = require("node:http");
7
- const soapHandler = require("./chunks/soap-handler-BznuMFIP.js");
8
- const _import = require("./chunks/import-DYssQzex.js");
7
+ const soapHandler = require("./chunks/soap-handler-DYVGnmgi.js");
8
+ const _import = require("./chunks/import-CNwoS1_c.js");
9
9
  const cliCommon = require("./chunks/cli-common-Cq_cphpZ.js");
10
- require("./chunks/handle-CL-nWtYA.js");
10
+ require("./chunks/handle-DHNkZoP1.js");
11
11
  require("@xmldom/xmldom");
12
12
  require("uuid");
13
13
  require("./chunks/data-files-BYqhsoPe.js");
@@ -200,7 +200,15 @@ const IPC = {
200
200
  },
201
201
  // ─── App ───────────────────────────────────────────────────────────────────
202
202
  app: {
203
- checkUpdate: "app:checkUpdate"
203
+ checkUpdate: "app:checkUpdate",
204
+ /** 'auto' (packaged → electron-updater) vs 'npm' (run from the npm package). */
205
+ updateMode: "app:updateMode",
206
+ /** Renderer asks the main process to quit and apply a downloaded update. */
207
+ installUpdate: "app:installUpdate",
208
+ /** Main → renderer auto-update events (packaged builds only). */
209
+ onUpdateAvailable: "app:updateAvailable",
210
+ onUpdateDownloaded: "app:updateDownloaded",
211
+ onUpdateError: "app:updateError"
204
212
  },
205
213
  // ─── Cloud (API Spector Cloud integration) ──────────────────────────────────
206
214
  cloud: {
@@ -419,6 +427,19 @@ const api = {
419
427
  // ─── Shell ────────────────────────────────────────────────────────────────
420
428
  openExternal: (url) => electron.ipcRenderer.invoke(IPC.shell.openExternal, url),
421
429
  checkForUpdate: () => electron.ipcRenderer.invoke(IPC.app.checkUpdate),
430
+ // 'auto' = packaged desktop app (electron-updater); 'npm' = run from npm.
431
+ getUpdateMode: () => electron.ipcRenderer.invoke(IPC.app.updateMode),
432
+ // Quit and apply a downloaded update (packaged builds only).
433
+ installUpdate: () => electron.ipcRenderer.invoke(IPC.app.installUpdate),
434
+ onUpdateAvailable: (cb) => {
435
+ electron.ipcRenderer.on(IPC.app.onUpdateAvailable, (_e, info) => cb(info));
436
+ },
437
+ onUpdateDownloaded: (cb) => {
438
+ electron.ipcRenderer.on(IPC.app.onUpdateDownloaded, (_e, info) => cb(info));
439
+ },
440
+ onUpdateError: (cb) => {
441
+ electron.ipcRenderer.on(IPC.app.onUpdateError, (_e, info) => cb(info));
442
+ },
422
443
  // ─── Zoom ─────────────────────────────────────────────────────────────────
423
444
  setZoomFactor: (factor) => electron.webFrame.setZoomFactor(factor),
424
445
  // ─── Platform ─────────────────────────────────────────────────────────────
@@ -1,5 +1,5 @@
1
1
  import { l as linter, E as EditorView, L as LanguageSupport, e as LRLanguage, s as styleTags, i as indentNodeProp, f as delimitedIndent, m as foldNodeProp, n as foldInside, S as StateField, p as LRParser, q as StateEffect, u as tags, r as reactExports, j as jsxRuntimeExports, c as ReactCodeMirror, o as oneDark, b as json } from "./codemirror-F6m3Hm1M.js";
2
- import { u as useT, a as useStore, b as useActiveEnvironment } from "./index-Br20ROPL.js";
2
+ import { u as useT, a as useStore, b as useActiveEnvironment } from "./index-BRHOhi5S.js";
3
3
  import "./ajv-2MAg6kGF.js";
4
4
  function devAssert(condition, message) {
5
5
  const booleanCondition = Boolean(condition);
@@ -1,5 +1,5 @@
1
1
  import { r as reactExports, j as jsxRuntimeExports, c as ReactCodeMirror, o as oneDark, x as xml } from "./codemirror-F6m3Hm1M.js";
2
- import { u as useT, c as btnPrimaryCls, d as commentKeymap } from "./index-Br20ROPL.js";
2
+ import { u as useT, c as btnPrimaryCls, d as commentKeymap } from "./index-BRHOhi5S.js";
3
3
  import "./ajv-2MAg6kGF.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-DYs21zjE.js","./codemirror-F6m3Hm1M.js","./ajv-2MAg6kGF.js","./SoapEditor-CMg7win3.js"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["./GraphQLEditor-ZFBdIcXA.js","./codemirror-F6m3Hm1M.js","./ajv-2MAg6kGF.js","./SoapEditor-B9W4JxTQ.js"])))=>i.map(i=>d[i]);
2
2
  import { r as reactExports, g as getDefaultExportFromCjs, R as React$2, a as autocompletion, h as hoverTooltip, j as jsxRuntimeExports, k as keymap, t as toggleComment, x as xml, b as json, c as ReactCodeMirror, o as oneDark, d as javascript } from "./codemirror-F6m3Hm1M.js";
3
3
  import { A as Ajv } from "./ajv-2MAg6kGF.js";
4
4
  var client = { exports: {} };
@@ -27438,8 +27438,8 @@ function jsonWithComments() {
27438
27438
  function xmlWithComments() {
27439
27439
  return [xml(), commentKeymap];
27440
27440
  }
27441
- const GraphQLEditor = reactExports.lazy(() => __vitePreload(() => import("./GraphQLEditor-DYs21zjE.js"), true ? __vite__mapDeps([0,1,2]) : void 0, import.meta.url).then((m) => ({ default: m.GraphQLEditor })));
27442
- const SoapEditor = reactExports.lazy(() => __vitePreload(() => import("./SoapEditor-CMg7win3.js"), true ? __vite__mapDeps([3,1,2]) : void 0, import.meta.url).then((m) => ({ default: m.SoapEditor })));
27441
+ const GraphQLEditor = reactExports.lazy(() => __vitePreload(() => import("./GraphQLEditor-ZFBdIcXA.js"), true ? __vite__mapDeps([0,1,2]) : void 0, import.meta.url).then((m) => ({ default: m.GraphQLEditor })));
27442
+ const SoapEditor = reactExports.lazy(() => __vitePreload(() => import("./SoapEditor-B9W4JxTQ.js"), true ? __vite__mapDeps([3,1,2]) : void 0, import.meta.url).then((m) => ({ default: m.SoapEditor })));
27443
27443
  function BodyTab({ request: request2, onChange }) {
27444
27444
  const t = useT();
27445
27445
  const editorFallback = /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 text-xs text-surface-500", children: t("Loading editor…") });
@@ -28373,7 +28373,7 @@ function renderMarkdown(md) {
28373
28373
  }
28374
28374
  function DocsEditor({ value: value2, onChange, placeholder, onGenerate, aiAvailable }) {
28375
28375
  const t = useT();
28376
- const [mode, setMode] = reactExports.useState("write");
28376
+ const [mode, setMode] = reactExports.useState(value2.trim() ? "preview" : "write");
28377
28377
  const [generating, setGenerating] = reactExports.useState(false);
28378
28378
  const [error2, setError] = reactExports.useState(null);
28379
28379
  const taRef = reactExports.useRef(null);
@@ -32534,8 +32534,11 @@ function WelcomeScreen() {
32534
32534
  const [gitError, setGitError] = reactExports.useState(null);
32535
32535
  reactExports.useEffect(() => {
32536
32536
  electron$k.getRecentWorkspaces().then(setRecents).catch(() => setRecents([]));
32537
- electron$k.checkForUpdate().then((info) => {
32538
- if (info?.updateAvailable) setUpdate(info);
32537
+ electron$k.getUpdateMode().then((mode) => {
32538
+ if (mode !== "npm") return;
32539
+ return electron$k.checkForUpdate().then((info) => {
32540
+ if (info?.updateAvailable) setUpdate(info);
32541
+ });
32539
32542
  }).catch(() => {
32540
32543
  });
32541
32544
  }, []);
@@ -32597,7 +32600,7 @@ function WelcomeScreen() {
32597
32600
  )
32598
32601
  ] }),
32599
32602
  /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-surface-400 text-sm max-w-sm", children: t("Local-first API testing with Robot Framework & Playwright code generation. Secrets stay on your machine.") }),
32600
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] mt-3", style: { color: "var(--text-muted)" }, children: t("version :version", { version: "0.6.6" }) })
32603
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-[11px] mt-3", style: { color: "var(--text-muted)" }, children: t("version :version", { version: "0.6.8" }) })
32601
32604
  ] }),
32602
32605
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-3 w-64", children: [
32603
32606
  /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -41256,49 +41259,92 @@ const { electron: electron$1 } = window;
41256
41259
  const DISMISS_KEY = STORAGE_KEYS.updateSkipped;
41257
41260
  function UpdateToast() {
41258
41261
  const t = useT();
41259
- const [info, setInfo] = reactExports.useState(null);
41262
+ const [npm, setNpm] = reactExports.useState(null);
41263
+ const [ready, setReady] = reactExports.useState(null);
41264
+ const [downloading, setDownloading] = reactExports.useState(null);
41260
41265
  const { copied, copy: doCopy } = useCopyFeedback(1500);
41261
41266
  reactExports.useEffect(() => {
41262
41267
  let cancelled = false;
41263
- electron$1.checkForUpdate().then((u) => {
41264
- if (cancelled || !u?.updateAvailable) return;
41265
- let skipped2 = "";
41266
- try {
41267
- skipped2 = localStorage.getItem(DISMISS_KEY) ?? "";
41268
- } catch {
41268
+ electron$1.getUpdateMode().then((mode) => {
41269
+ if (cancelled) return;
41270
+ if (mode === "auto") {
41271
+ electron$1.onUpdateAvailable(({ version }) => {
41272
+ if (!cancelled) setDownloading(version);
41273
+ });
41274
+ electron$1.onUpdateDownloaded(({ version }) => {
41275
+ if (!cancelled) {
41276
+ setDownloading(null);
41277
+ setReady(version);
41278
+ }
41279
+ });
41280
+ return;
41269
41281
  }
41270
- if (u.latest !== skipped2) setInfo(u);
41282
+ electron$1.checkForUpdate().then((u) => {
41283
+ if (cancelled || !u?.updateAvailable) return;
41284
+ let skipped2 = "";
41285
+ try {
41286
+ skipped2 = localStorage.getItem(DISMISS_KEY) ?? "";
41287
+ } catch {
41288
+ }
41289
+ if (u.latest !== skipped2) setNpm(u);
41290
+ }).catch(() => {
41291
+ });
41271
41292
  }).catch(() => {
41272
41293
  });
41273
41294
  return () => {
41274
41295
  cancelled = true;
41275
41296
  };
41276
41297
  }, []);
41277
- if (!info) return null;
41278
- const later = () => setInfo(null);
41298
+ if (ready) {
41299
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed bottom-4 right-4 z-[80] w-80 bg-surface-900 border border-surface-700 rounded-lg shadow-2xl overflow-hidden", children: [
41300
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 px-3 pt-3", children: [
41301
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mt-1 w-2 h-2 rounded-full bg-emerald-500 flex-shrink-0" }),
41302
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
41303
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-semibold text-white", children: t("Update ready") }),
41304
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-surface-300 mt-0.5", children: t("API Spector :latest has been downloaded. Restart to install it.", { latest: ready }) })
41305
+ ] }),
41306
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setReady(null), title: t("Later"), className: "text-surface-500 hover:text-surface-300 text-base leading-none px-0.5", children: "×" })
41307
+ ] }),
41308
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex justify-end gap-2 px-3 py-2.5", children: [
41309
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setReady(null), className: "px-2.5 py-1 text-[11px] rounded text-surface-400 hover:text-surface-200 hover:bg-surface-800 transition-colors", children: t("Later") }),
41310
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => {
41311
+ void electron$1.installUpdate();
41312
+ }, className: "px-3 py-1 text-xs rounded bg-blue-600 hover:bg-blue-500 text-white font-medium transition-colors", children: t("Restart to update") })
41313
+ ] })
41314
+ ] });
41315
+ }
41316
+ if (downloading) {
41317
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "fixed bottom-4 right-4 z-[80] w-80 bg-surface-900 border border-surface-700 rounded-lg shadow-2xl overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-3 py-3", children: [
41318
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "w-2 h-2 rounded-full bg-blue-500 animate-pulse flex-shrink-0" }),
41319
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-surface-300 flex-1 min-w-0", children: t("Downloading API Spector :latest…", { latest: downloading }) }),
41320
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setDownloading(null), title: t("Later"), className: "text-surface-500 hover:text-surface-300 text-base leading-none px-0.5", children: "×" })
41321
+ ] }) });
41322
+ }
41323
+ if (!npm) return null;
41324
+ const later = () => setNpm(null);
41279
41325
  const skip = () => {
41280
41326
  try {
41281
- localStorage.setItem(DISMISS_KEY, info.latest);
41327
+ localStorage.setItem(DISMISS_KEY, npm.latest);
41282
41328
  } catch {
41283
41329
  }
41284
- setInfo(null);
41330
+ setNpm(null);
41285
41331
  };
41286
41332
  const copy2 = () => {
41287
- void doCopy(info.command);
41333
+ void doCopy(npm.command);
41288
41334
  };
41289
41335
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "fixed bottom-4 right-4 z-[80] w-80 bg-surface-900 border border-surface-700 rounded-lg shadow-2xl overflow-hidden", children: [
41290
41336
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 px-3 pt-3", children: [
41291
41337
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mt-1 w-2 h-2 rounded-full bg-blue-500 flex-shrink-0" }),
41292
41338
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [
41293
41339
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm font-semibold text-white", children: t("Update available") }),
41294
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-surface-300 mt-0.5", children: t("API Spector :latest is available. You have :current.", { latest: info.latest, current: info.current }) })
41340
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-surface-300 mt-0.5", children: t("API Spector :latest is available. You have :current.", { latest: npm.latest, current: npm.current }) })
41295
41341
  ] }),
41296
41342
  /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: later, title: t("Later"), className: "text-surface-500 hover:text-surface-300 text-base leading-none px-0.5", children: "×" })
41297
41343
  ] }),
41298
41344
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-3 pt-2", children: [
41299
41345
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-[10px] uppercase tracking-wider text-surface-500 mb-1", children: t("Update with") }),
41300
41346
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1", children: [
41301
- /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "flex-1 text-[11px] font-mono text-blue-300 bg-surface-950 border border-surface-800 rounded px-2 py-1.5 select-all break-all", children: info.command }),
41347
+ /* @__PURE__ */ jsxRuntimeExports.jsx("code", { className: "flex-1 text-[11px] font-mono text-blue-300 bg-surface-950 border border-surface-800 rounded px-2 py-1.5 select-all break-all", children: npm.command }),
41302
41348
  /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: copy2, className: "px-2 py-1.5 text-xs rounded bg-surface-700 hover:bg-surface-600 transition-colors", children: copied ? t("Copied") : t("Copy") })
41303
41349
  ] })
41304
41350
  ] }),
@@ -41334,7 +41380,6 @@ function IconGit() {
41334
41380
  /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M6 8.5 C6 13 18 10 18 8.5" })
41335
41381
  ] });
41336
41382
  }
41337
- const WELCOME_SCREEN_DELAY_MS = 1500;
41338
41383
  function ActivityBarBtn({
41339
41384
  active: active2,
41340
41385
  onClick,
@@ -41477,14 +41522,6 @@ function App() {
41477
41522
  window.removeEventListener("mouseup", onMouseUp);
41478
41523
  };
41479
41524
  }, []);
41480
- reactExports.useEffect(() => {
41481
- const id = setTimeout(() => {
41482
- electron.getLastWorkspace().then((result) => {
41483
- if (result) applyWorkspace(result.workspace, result.workspacePath);
41484
- });
41485
- }, WELCOME_SCREEN_DELAY_MS);
41486
- return () => clearTimeout(id);
41487
- }, [applyWorkspace]);
41488
41525
  reactExports.useEffect(() => {
41489
41526
  electron.onOpenFromGit(async (repoUrl) => {
41490
41527
  try {
@@ -41590,7 +41627,7 @@ function App() {
41590
41627
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "#6aa3c8" }, children: "Spector" }),
41591
41628
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-[10px] font-normal opacity-50", children: [
41592
41629
  "v",
41593
- "0.6.6"
41630
+ "0.6.8"
41594
41631
  ] }),
41595
41632
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mx-2 opacity-30", children: "·" }),
41596
41633
  /* @__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-Br20ROPL.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-BRHOhi5S.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="./assets/codemirror-F6m3Hm1M.js">
10
10
  <link rel="modulepreload" crossorigin href="./assets/ajv-2MAg6kGF.js">
11
11
  <link rel="stylesheet" crossorigin href="./assets/index-B3mtLdU3.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.6.6",
4
+ "version": "0.6.8",
5
5
  "description": "Local-first API testing tool to inspect, test and mock APIs",
6
6
  "repository": {
7
7
  "type": "git",
@@ -94,6 +94,7 @@
94
94
  "ajv": "^8.18.0",
95
95
  "cm6-graphql": "^0.2.1",
96
96
  "dayjs": "^1.11.20",
97
+ "electron-updater": "^6.8.9",
97
98
  "graphql": "^16.13.2",
98
99
  "immer": "^11.1.4",
99
100
  "js-yaml": "^4.1.1",