@testsmith/api-spector 0.3.8 → 0.3.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.
@@ -54,6 +54,7 @@ const IPC = {
54
54
  insomnia: "import:insomnia",
55
55
  bruno: "import:bruno",
56
56
  http: "import:http",
57
+ spector: "import:spector",
57
58
  openapiSchemas: "import:openapi-schemas",
58
59
  openapiSchemasUrl: "import:openapi-schemas-url"
59
60
  },
@@ -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-h0dWIjOK.js");
5
- require("./handle-BCnNIZZr.js");
4
+ const soapHandler = require("./soap-handler-B1Huudj7.js");
5
+ require("./handle-Coax8Nz1.js");
6
6
  require("https");
7
7
  require("http");
8
8
  require("@xmldom/xmldom");
@@ -85,6 +85,25 @@ function getAllApplicableHooks(folderId, collection) {
85
85
  }
86
86
  return { beforeAll, before, after, afterAll };
87
87
  }
88
+ function authIsConfigured(auth) {
89
+ if (!auth || auth.type === "none") return false;
90
+ const set = (s) => !!(s && s.trim());
91
+ switch (auth.type) {
92
+ case "bearer":
93
+ return set(auth.token) || set(auth.tokenSecretRef);
94
+ case "basic":
95
+ case "digest":
96
+ return set(auth.username) || set(auth.password) || set(auth.passwordSecretRef);
97
+ case "ntlm":
98
+ return set(auth.username) || set(auth.password) || set(auth.passwordSecretRef);
99
+ case "apikey":
100
+ return set(auth.apiKeyValue) || set(auth.apiKeySecretRef);
101
+ case "oauth2":
102
+ return set(auth.oauth2TokenUrl) || set(auth.oauth2ClientId) || set(auth.oauth2CachedToken);
103
+ default:
104
+ return true;
105
+ }
106
+ }
88
107
  function resolveInheritedAuthAndHeaders(requestId, collection) {
89
108
  let inheritedAuth = collection.auth && collection.auth.type !== "none" ? collection.auth : null;
90
109
  let inheritedHeaders = collection.headers?.filter((h) => h.enabled && h.key) ?? [];
@@ -113,6 +132,7 @@ function buildRunPlan(collection, folderId, filterTags) {
113
132
  );
114
133
  }
115
134
  }
135
+ exports.authIsConfigured = authIsConfigured;
116
136
  exports.buildRunPlan = buildRunPlan;
117
137
  exports.getAllApplicableHooks = getAllApplicableHooks;
118
138
  exports.resolveInheritedAuthAndHeaders = resolveInheritedAuthAndHeaders;
@@ -23,7 +23,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  ));
24
24
  const undici = require("undici");
25
25
  const promises = require("fs/promises");
26
- const handle = require("./handle-BCnNIZZr.js");
26
+ const handle = require("./handle-Coax8Nz1.js");
27
27
  const crypto = require("crypto");
28
28
  const path = require("path");
29
29
  const dayjs = require("dayjs");
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  const undici = require("undici");
3
- const requestExec = require("./request-exec-AQD6cEgT.js");
3
+ const requestExec = require("./request-exec-C0DnGKdd.js");
4
4
  const promises = require("fs/promises");
5
5
  const path = require("path");
6
6
  const Ajv = require("ajv");
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const handle = require("./handle-BCnNIZZr.js");
2
+ const handle = require("./handle-Coax8Nz1.js");
3
3
  const https = require("https");
4
4
  const http = require("http");
5
5
  const xmldom = require("@xmldom/xmldom");
@@ -315,7 +315,7 @@ function registerSoapHandlers(ipc) {
315
315
  handle.handleIpc(ipc, handle.IPC.wsdl.import, async (_event, opts) => {
316
316
  const { validateWsdlImport } = await Promise.resolve().then(() => require("./ipc-validate-k6KI8adf.js"));
317
317
  validateWsdlImport(opts);
318
- const { importWsdl } = await Promise.resolve().then(() => require("./import-DUKaMYGO.js"));
318
+ const { importWsdl } = await Promise.resolve().then(() => require("./import-Bilo697Z.js"));
319
319
  const wsdlText = opts.xml ?? (opts.url ? await fetchUrl(opts.url) : "");
320
320
  if (!wsdlText) throw new Error("wsdl:import requires either `url` or `xml`");
321
321
  return importWsdl(wsdlText, { name: opts.name, existingMockPorts: opts.existingMockPorts });
@@ -24,14 +24,14 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
  const promises = require("fs/promises");
26
26
  const path = require("path");
27
- const snapshots = require("./chunks/snapshots-NGkGQNZ4.js");
27
+ const snapshots = require("./chunks/snapshots-CatB4zLh.js");
28
28
  const crypto = require("crypto");
29
29
  const undici = require("undici");
30
30
  const os = require("os");
31
31
  const cliCommon = require("./chunks/cli-common-CDQY1erJ.js");
32
32
  const environments = require("./chunks/environments-iM3SUM-4.js");
33
- require("./chunks/request-exec-AQD6cEgT.js");
34
- require("./chunks/handle-BCnNIZZr.js");
33
+ require("./chunks/request-exec-C0DnGKdd.js");
34
+ require("./chunks/handle-Coax8Nz1.js");
35
35
  require("dayjs");
36
36
  require("vm");
37
37
  require("tv4");
package/out/main/index.js CHANGED
@@ -22,24 +22,24 @@ 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-BCnNIZZr.js");
25
+ const handle = require("./chunks/handle-Coax8Nz1.js");
26
26
  const path = require("path");
27
27
  const fs = require("fs");
28
28
  const promises = require("fs/promises");
29
- const requestExec = require("./chunks/request-exec-AQD6cEgT.js");
29
+ const crypto = require("crypto");
30
+ const requestExec = require("./chunks/request-exec-C0DnGKdd.js");
30
31
  const ipcValidate = require("./chunks/ipc-validate-k6KI8adf.js");
31
32
  const uuid = require("uuid");
32
33
  const jsYaml = require("js-yaml");
33
34
  const undici = require("undici");
34
35
  const JSZip = require("jszip");
35
- const requestCollection = require("./chunks/request-collection-CBuPjBwa.js");
36
+ const requestCollection = require("./chunks/request-collection-CJoXpvOw.js");
36
37
  const mockServer = require("./chunks/mock-server-DSLR2ulH.js");
37
38
  const http = require("http");
38
39
  const WebSocket = require("ws");
39
- const soapHandler = require("./chunks/soap-handler-h0dWIjOK.js");
40
+ const soapHandler = require("./chunks/soap-handler-B1Huudj7.js");
40
41
  const os = require("os");
41
- const crypto = require("crypto");
42
- const snapshots = require("./chunks/snapshots-NGkGQNZ4.js");
42
+ const snapshots = require("./chunks/snapshots-CatB4zLh.js");
43
43
  const simpleGit = require("simple-git");
44
44
  const recorder = require("./chunks/recorder-0Ij921El.js");
45
45
  require("dayjs");
@@ -224,12 +224,27 @@ function registerFileHandlers(ipc) {
224
224
  });
225
225
  if (result.canceled || !result.filePaths[0]) return null;
226
226
  const wsPath = result.filePaths[0];
227
+ const raw = await promises.readFile(wsPath, "utf8");
228
+ const parsed = JSON.parse(raw);
229
+ if (looksLikeCollection(parsed)) {
230
+ const { response } = await electron.dialog.showMessageBox({
231
+ type: "question",
232
+ buttons: ["Create Workspace", "Cancel"],
233
+ defaultId: 0,
234
+ cancelId: 1,
235
+ message: "This is a collection, not a workspace.",
236
+ detail: `API Spector opens workspaces, which contain collections.
237
+
238
+ Create a workspace in this folder and add "${path.basename(wsPath)}" to it? The collection is moved into a collections/ folder and this file becomes the workspace.`
239
+ });
240
+ if (response !== 0) return null;
241
+ return wrapCollectionAsWorkspace(wsPath, parsed);
242
+ }
227
243
  workspaceDir = path.dirname(wsPath);
228
244
  workspaceFile = wsPath;
229
245
  await requestExec.loadGlobals(workspaceDir);
230
246
  await saveLastWorkspacePath(wsPath);
231
- const raw = await promises.readFile(wsPath, "utf8");
232
- return { workspace: JSON.parse(raw), workspacePath: wsPath };
247
+ return { workspace: parsed, workspacePath: wsPath };
233
248
  });
234
249
  handle.handleIpc(ipc, handle.IPC.file.newWorkspace, async () => {
235
250
  const startDir = dialogStartDir();
@@ -390,6 +405,30 @@ async function tryOpenWorkspaceInDir(dir) {
390
405
  function getWorkspaceDir() {
391
406
  return workspaceDir;
392
407
  }
408
+ function looksLikeCollection(obj) {
409
+ if (!obj || typeof obj !== "object") return false;
410
+ const o = obj;
411
+ return !Array.isArray(o["collections"]) && (!!o["rootFolder"] || !!o["requests"]);
412
+ }
413
+ async function wrapCollectionAsWorkspace(collFilePath, collection) {
414
+ const dir = path.dirname(collFilePath);
415
+ const base = path.basename(collFilePath).replace(/\.(spector|json)$/i, "");
416
+ const safe = base.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "collection";
417
+ const collRel = `collections/${safe}.json`;
418
+ if (!collection.id) collection.id = crypto.randomUUID();
419
+ await promises.mkdir(path.join(dir, "collections"), { recursive: true });
420
+ await atomicWrite(path.join(dir, collRel), JSON.stringify(collection, null, 2));
421
+ const ws = { version: "1.0", collections: [collRel], environments: [], activeEnvironmentId: null };
422
+ await ensureGitignore(dir);
423
+ await ensureVscodeFileAssociation(dir);
424
+ await ensureReadme(dir, path.basename(collFilePath));
425
+ await atomicWrite(collFilePath, JSON.stringify(ws, null, 2));
426
+ workspaceDir = dir;
427
+ workspaceFile = collFilePath;
428
+ await requestExec.loadGlobals(dir);
429
+ await saveLastWorkspacePath(collFilePath);
430
+ return { workspace: ws, workspacePath: collFilePath };
431
+ }
393
432
  function asObject(value) {
394
433
  return value && typeof value === "object" ? value : null;
395
434
  }
@@ -1593,6 +1632,30 @@ function registerImportHandlers(ipc) {
1593
1632
  if (result.canceled || !result.filePaths[0]) return null;
1594
1633
  return importHttpFile(result.filePaths[0]);
1595
1634
  });
1635
+ handle.handleIpc(ipc, handle.IPC.import.spector, async () => {
1636
+ const result = await electron.dialog.showOpenDialog({
1637
+ title: "Import API Spector Collection",
1638
+ filters: [{ name: "API Spector Collection", extensions: ["json", "spector"] }],
1639
+ properties: ["openFile"]
1640
+ });
1641
+ if (result.canceled || !result.filePaths[0]) return null;
1642
+ const raw = await promises.readFile(result.filePaths[0], "utf8");
1643
+ let parsed;
1644
+ try {
1645
+ parsed = JSON.parse(raw);
1646
+ } catch {
1647
+ throw new Error("Not a valid JSON file.");
1648
+ }
1649
+ if (Array.isArray(parsed["collections"])) {
1650
+ throw new Error("This is a workspace file, not a collection. Open it with File > Open Workspace instead.");
1651
+ }
1652
+ if (!parsed["rootFolder"] || !parsed["requests"]) {
1653
+ throw new Error("This does not look like an API Spector collection (no rootFolder / requests).");
1654
+ }
1655
+ const collection = parsed;
1656
+ collection.id = crypto.randomUUID();
1657
+ return collection;
1658
+ });
1596
1659
  handle.handleIpc(ipc, handle.IPC.import.openapiSchemas, async () => {
1597
1660
  const result = await electron.dialog.showOpenDialog({
1598
1661
  title: "Load OpenAPI spec for schema sync",
@@ -1719,7 +1782,7 @@ function javaClass(name) {
1719
1782
  return name.replace(/[^\w\s]/g, " ").split(/\s+/).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
1720
1783
  }
1721
1784
  function resolveEffectiveAuth(req, inherited) {
1722
- return req.auth.type !== "none" ? req.auth : inherited.auth ?? req.auth;
1785
+ return requestCollection.authIsConfigured(req.auth) ? req.auth : inherited.auth ?? req.auth;
1723
1786
  }
1724
1787
  function mergeHeaders(req, inherited) {
1725
1788
  return [...inherited.headers.filter((h) => h.enabled && h.key), ...req.headers.filter((h) => h.enabled && h.key)];
@@ -2,12 +2,12 @@
2
2
  "use strict";
3
3
  const promises = require("fs/promises");
4
4
  const path = require("path");
5
- const requestExec = require("./chunks/request-exec-AQD6cEgT.js");
6
- const requestCollection = require("./chunks/request-collection-CBuPjBwa.js");
5
+ const requestExec = require("./chunks/request-exec-C0DnGKdd.js");
6
+ const requestCollection = require("./chunks/request-collection-CJoXpvOw.js");
7
7
  const environments = require("./chunks/environments-iM3SUM-4.js");
8
8
  const cliCommon = require("./chunks/cli-common-CDQY1erJ.js");
9
9
  require("undici");
10
- require("./chunks/handle-BCnNIZZr.js");
10
+ require("./chunks/handle-Coax8Nz1.js");
11
11
  require("crypto");
12
12
  require("dayjs");
13
13
  require("vm");
@@ -396,7 +396,7 @@ async function main() {
396
396
  } else if (!envName && workspace.settings?.defaultEnvironment && !env) {
397
397
  console.warn(cliCommon.color(`Warning: default environment "${workspace.settings.defaultEnvironment}" not found. Running without environment.`, cliCommon.C.yellow));
398
398
  }
399
- const version = `v${"0.3.8"}`;
399
+ const version = `v${"0.3.9"}`;
400
400
  console.log("");
401
401
  console.log(cliCommon.color(" API Test Runner" + (version ? ` ${version}` : ""), cliCommon.C.bold, cliCommon.C.white));
402
402
  console.log(cliCommon.color(` Workspace: ${wsPath}`, cliCommon.C.gray));
@@ -448,7 +448,7 @@ async function main() {
448
448
  for (const item of items) {
449
449
  const req = item.request;
450
450
  const inherited = requestCollection.resolveInheritedAuthAndHeaders(req.id, col);
451
- if (req.auth.type === "none" && inherited.auth && inherited.auth.type !== "none") {
451
+ if (!requestCollection.authIsConfigured(req.auth) && inherited.auth && inherited.auth.type !== "none") {
452
452
  req.auth = inherited.auth;
453
453
  }
454
454
  const inheritedHeaders = inherited.headers.filter((h) => h.enabled && h.key);
package/out/main/wsdl.js CHANGED
@@ -4,10 +4,10 @@ const promises = require("fs/promises");
4
4
  const path = require("path");
5
5
  const https = require("https");
6
6
  const http = require("http");
7
- const soapHandler = require("./chunks/soap-handler-h0dWIjOK.js");
8
- const _import = require("./chunks/import-DUKaMYGO.js");
7
+ const soapHandler = require("./chunks/soap-handler-B1Huudj7.js");
8
+ const _import = require("./chunks/import-Bilo697Z.js");
9
9
  const cliCommon = require("./chunks/cli-common-CDQY1erJ.js");
10
- require("./chunks/handle-BCnNIZZr.js");
10
+ require("./chunks/handle-Coax8Nz1.js");
11
11
  require("@xmldom/xmldom");
12
12
  require("uuid");
13
13
  function fetchUrl(url) {
@@ -55,6 +55,7 @@ const IPC = {
55
55
  insomnia: "import:insomnia",
56
56
  bruno: "import:bruno",
57
57
  http: "import:http",
58
+ spector: "import:spector",
58
59
  openapiSchemas: "import:openapi-schemas",
59
60
  openapiSchemasUrl: "import:openapi-schemas-url"
60
61
  },
@@ -198,6 +199,7 @@ const api = {
198
199
  importInsomnia: () => electron.ipcRenderer.invoke(IPC.import.insomnia),
199
200
  importBruno: () => electron.ipcRenderer.invoke(IPC.import.bruno),
200
201
  importHttpFile: () => electron.ipcRenderer.invoke(IPC.import.http),
202
+ importSpectorCollection: () => electron.ipcRenderer.invoke(IPC.import.spector),
201
203
  /** Extract response-body schemas from an OpenAPI spec file (no full import). */
202
204
  extractOpenApiSchemas: () => electron.ipcRenderer.invoke(IPC.import.openapiSchemas),
203
205
  /** Extract response-body schemas from an OpenAPI spec URL (no full import). */
@@ -14350,14 +14350,14 @@ function useWorkspaceLoader() {
14350
14350
  } else {
14351
14351
  useStore.getState().setHistory([]);
14352
14352
  }
14353
- for (const colPath of ws2.collections) {
14353
+ for (const colPath of ws2.collections ?? []) {
14354
14354
  try {
14355
14355
  const col = await electron$r.loadCollection(colPath);
14356
14356
  loadCollection(colPath, col);
14357
14357
  } catch {
14358
14358
  }
14359
14359
  }
14360
- for (const envPath of ws2.environments) {
14360
+ for (const envPath of ws2.environments ?? []) {
14361
14361
  try {
14362
14362
  const env = await electron$r.loadEnvironment(envPath);
14363
14363
  loadEnvironment(envPath, env);
@@ -14388,7 +14388,7 @@ function useWorkspaceLoader() {
14388
14388
  for (const { relPath, snapshot } of snapshots) loadContractSnapshot(relPath, snapshot);
14389
14389
  } catch {
14390
14390
  }
14391
- if (ws2.collections.length > 0) {
14391
+ if ((ws2.collections ?? []).length > 0) {
14392
14392
  try {
14393
14393
  const firstCol = await electron$r.loadCollection(ws2.collections[0]);
14394
14394
  setActiveCollection(firstCol.id);
@@ -36531,6 +36531,10 @@ function DotsBtn({ items: items2 }) {
36531
36531
  menu && /* @__PURE__ */ jsxRuntimeExports.jsx(ContextMenu, { items: items2, x: menu.x, y: menu.y, onClose: () => setMenu(null) })
36532
36532
  ] });
36533
36533
  }
36534
+ function requestPath(url) {
36535
+ const trimmed = url.trim().replace(/^\{\{[^}]+\}\}/, "").replace(/^https?:\/\/[^/]+/i, "");
36536
+ return trimmed || url.trim();
36537
+ }
36534
36538
  const HOOK_LABELS = {
36535
36539
  beforeAll: "Before All",
36536
36540
  before: "Before",
@@ -36557,6 +36561,7 @@ function RequestRow({
36557
36561
  folderId,
36558
36562
  reqIndex,
36559
36563
  name: name2,
36564
+ url,
36560
36565
  method,
36561
36566
  protocol,
36562
36567
  authType,
@@ -36658,6 +36663,10 @@ function RequestRow({
36658
36663
  }
36659
36664
  )
36660
36665
  ] }),
36666
+ (() => {
36667
+ const path = requestPath(url);
36668
+ return path && path !== name2 ? /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-[10px] text-surface-500 font-mono truncate leading-tight", title: url, children: path }) : null;
36669
+ })(),
36661
36670
  (tags2.length > 0 || addingTag) && /* @__PURE__ */ jsxRuntimeExports.jsx(
36662
36671
  TagChips,
36663
36672
  {
@@ -37241,6 +37250,7 @@ function FolderContents({
37241
37250
  folderId: folder.id,
37242
37251
  reqIndex,
37243
37252
  name: req.name,
37253
+ url: req.url,
37244
37254
  method: req.method,
37245
37255
  protocol: req.protocol,
37246
37256
  authType: req.auth.type,
@@ -37358,6 +37368,25 @@ function getHooksForRequest(requestId, collection) {
37358
37368
  }
37359
37369
  return { before, after: afterReversed.reverse() };
37360
37370
  }
37371
+ function authIsConfigured(auth) {
37372
+ if (!auth || auth.type === "none") return false;
37373
+ const set2 = (s) => !!(s && s.trim());
37374
+ switch (auth.type) {
37375
+ case "bearer":
37376
+ return set2(auth.token) || set2(auth.tokenSecretRef);
37377
+ case "basic":
37378
+ case "digest":
37379
+ return set2(auth.username) || set2(auth.password) || set2(auth.passwordSecretRef);
37380
+ case "ntlm":
37381
+ return set2(auth.username) || set2(auth.password) || set2(auth.passwordSecretRef);
37382
+ case "apikey":
37383
+ return set2(auth.apiKeyValue) || set2(auth.apiKeySecretRef);
37384
+ case "oauth2":
37385
+ return set2(auth.oauth2TokenUrl) || set2(auth.oauth2ClientId) || set2(auth.oauth2CachedToken);
37386
+ default:
37387
+ return true;
37388
+ }
37389
+ }
37361
37390
  function resolveInheritedAuthAndHeaders(requestId, collection) {
37362
37391
  let inheritedAuth = collection.auth && collection.auth.type !== "none" ? collection.auth : null;
37363
37392
  let inheritedHeaders = collection.headers?.filter((h) => h.enabled && h.key) ?? [];
@@ -63829,7 +63858,7 @@ function RequestBuilder({ request }) {
63829
63858
  };
63830
63859
  let liveGlobals = { ...globals };
63831
63860
  const inherited = useStore.getState().getInheritedAuthAndHeaders(request.id);
63832
- const mergedAuth = request.auth.type !== "none" ? request.auth : inherited.auth ?? request.auth;
63861
+ const mergedAuth = authIsConfigured(request.auth) ? request.auth : inherited.auth ?? request.auth;
63833
63862
  const mergedHeaders = [
63834
63863
  ...inherited.headers.filter((h) => h.enabled),
63835
63864
  ...request.headers
@@ -67233,7 +67262,8 @@ const OPTIONS = [
67233
67262
  { id: "openapi", label: "OpenAPI", description: "JSON or YAML (v3.x)", supportsUrl: true },
67234
67263
  { id: "insomnia", label: "Insomnia", description: "Export v4 JSON" },
67235
67264
  { id: "bruno", label: "Bruno", description: "bruno.json collection file" },
67236
- { id: "http", label: "HTTP file", description: ".http / .rest (REST Client)" }
67265
+ { id: "http", label: "HTTP file", description: ".http / .rest (REST Client)" },
67266
+ { id: "spector", label: "API Spector", description: "An existing .spector / .json collection" }
67237
67267
  ];
67238
67268
  function listEndpoints(col) {
67239
67269
  const result = [];
@@ -67304,6 +67334,7 @@ function ImportModal({ onImport, onClose }) {
67304
67334
  if (opt2.id === "insomnia") col = await electron$9.importInsomnia();
67305
67335
  if (opt2.id === "bruno") col = await electron$9.importBruno();
67306
67336
  if (opt2.id === "http") col = await electron$9.importHttpFile();
67337
+ if (opt2.id === "spector") col = await electron$9.importSpectorCollection();
67307
67338
  if (!col) {
67308
67339
  setLoading(false);
67309
67340
  return;
@@ -68506,7 +68537,7 @@ function RunnerModal() {
68506
68537
  items2 = items2.map((item) => {
68507
68538
  const inherited = resolveInheritedAuthAndHeaders(item.request.id, col);
68508
68539
  const req = JSON.parse(JSON.stringify(item.request));
68509
- if (req.auth?.type === "none" && inherited.auth && inherited.auth.type !== "none") {
68540
+ if (!authIsConfigured(req.auth) && inherited.auth && inherited.auth.type !== "none") {
68510
68541
  req.auth = inherited.auth;
68511
68542
  }
68512
68543
  const inheritedHeaders = inherited.headers.filter((h) => h.enabled && h.key);
@@ -72054,7 +72085,7 @@ function App() {
72054
72085
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { color: "#6aa3c8" }, children: "Spector" }),
72055
72086
  /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-[10px] font-normal opacity-50", children: [
72056
72087
  "v",
72057
- "0.3.8"
72088
+ "0.3.9"
72058
72089
  ] }),
72059
72090
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "mx-2 opacity-30", children: "·" }),
72060
72091
  /* @__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-BK58GuOI.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-BdUvP_cg.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="./assets/index-B6kFQEbI.css">
10
10
  </head>
11
11
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@testsmith/api-spector",
3
3
  "productName": "API Spector",
4
- "version": "0.3.8",
4
+ "version": "0.3.9",
5
5
  "description": "Local-first API testing tool to inspect, test and mock APIs",
6
6
  "repository": {
7
7
  "type": "git",