@testsmith/api-spector 0.7.5 → 0.7.7

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-DHxjokyP.js");
6
+ const requestExec = require("./request-exec-B-F0K-pN.js");
7
7
  const Ajv = require("ajv");
8
8
  const jsYaml = require("js-yaml");
9
9
  require("node:http");
@@ -41,6 +41,7 @@ const IPC = {
41
41
  secret: {
42
42
  checkMasterKey: "secret:checkMasterKey",
43
43
  setMasterKey: "secret:setMasterKey",
44
+ encryptWithMasterKey: "secret:encryptWithMasterKey",
44
45
  set: "secret:set",
45
46
  has: "secret:has",
46
47
  delete: "secret:delete"
@@ -73,6 +74,7 @@ const IPC = {
73
74
  // ─── Import ────────────────────────────────────────────────────────────────
74
75
  import: {
75
76
  postman: "import:postman",
77
+ postmanEnvironment: "import:postman-environment",
76
78
  openapi: "import:openapi",
77
79
  openapiUrl: "import:openapi-url",
78
80
  insomnia: "import:insomnia",
@@ -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-CkoLJHoI.js");
5
- require("./handle-BY_jaVBT.js");
4
+ const soapHandler = require("./soap-handler-DqIPcIQL.js");
5
+ require("./handle-Bz0C56Eq.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-BY_jaVBT.js");
27
+ const handle = require("./handle-Bz0C56Eq.js");
28
28
  const fs = require("node:fs");
29
29
  const os = require("node:os");
30
30
  const path = require("node:path");
@@ -719,6 +719,11 @@ function registerSecretHandlers(ipc) {
719
719
  handle.handleIpc(ipc, handle.IPC.secret.setMasterKey, (_e, value) => {
720
720
  process.env[MASTER_KEY_ENV] = value;
721
721
  });
722
+ handle.handleIpc(ipc, handle.IPC.secret.encryptWithMasterKey, (_e, plaintext) => {
723
+ const password = process.env[MASTER_KEY_ENV];
724
+ if (!password) throw new Error("Master password is not set in this process.");
725
+ return encryptSecret(plaintext, password);
726
+ });
722
727
  handle.handleIpc(ipc, handle.IPC.secret.set, async (_e, ref, value) => {
723
728
  const ss = getSafeStorage();
724
729
  if (!ss?.isEncryptionAvailable()) {
@@ -737,6 +742,20 @@ function registerSecretHandlers(ipc) {
737
742
  }
738
743
  });
739
744
  }
745
+ function encryptSecret(plaintext, password) {
746
+ const salt = crypto.randomBytes(16);
747
+ const iv = crypto.randomBytes(12);
748
+ const key = crypto.pbkdf2Sync(password, salt, 1e5, 32, "sha256");
749
+ const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
750
+ const ciphertext = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
751
+ const authTag = cipher.getAuthTag();
752
+ return {
753
+ secretEncrypted: Buffer.concat([ciphertext, authTag]).toString("base64"),
754
+ secretSalt: salt.toString("base64"),
755
+ secretIv: iv.toString("base64"),
756
+ secretHash: crypto.createHash("sha256").update(plaintext, "utf8").digest("hex").slice(0, 8)
757
+ };
758
+ }
740
759
  function decryptSecret(encrypted, salt, iv, password) {
741
760
  const saltBuf = Buffer.from(salt, "base64");
742
761
  const ivBuf = Buffer.from(iv, "base64");
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const handle = require("./handle-BY_jaVBT.js");
2
+ const handle = require("./handle-Bz0C56Eq.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-DR_r1DUP.js"));
316
+ const { importWsdl } = await Promise.resolve().then(() => require("./import-BhGBiW7j.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-D0wYVblb.js");
5
+ const brokerClient = require("./chunks/broker-client-Df4PpJqB.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-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-DHxjokyP.js");
14
+ require("./chunks/request-exec-B-F0K-pN.js");
15
15
  require("fs/promises");
16
16
  require("tls");
17
- require("./chunks/handle-BY_jaVBT.js");
17
+ require("./chunks/handle-Bz0C56Eq.js");
18
18
  require("node:fs");
19
19
  require("dayjs");
20
20
  require("node:vm");
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-DHxjokyP.js");
5
+ const requestExec = require("./chunks/request-exec-B-F0K-pN.js");
6
6
  const requestCollection = require("./chunks/request-collection-KGPuvN7o.js");
7
7
  const environments = require("./chunks/environments-iM3SUM-4.js");
8
8
  const flowEngine = require("./chunks/flow-engine-BVzjz4lJ.js");
@@ -10,7 +10,7 @@ const cliCommon = require("./chunks/cli-common-GnihVSjU.js");
10
10
  require("undici");
11
11
  require("fs/promises");
12
12
  require("tls");
13
- require("./chunks/handle-BY_jaVBT.js");
13
+ require("./chunks/handle-Bz0C56Eq.js");
14
14
  require("node:fs");
15
15
  require("node:os");
16
16
  require("node:crypto");
@@ -265,7 +265,7 @@ async function main() {
265
265
  const envName = args.environment ?? args.env;
266
266
  const env = environments.selectEnvironment(workspace, environments$1, envName);
267
267
  const verbose = Boolean(args.verbose);
268
- const version = `v${"0.7.5"}`;
268
+ const version = `v${"0.7.7"}`;
269
269
  console.log("");
270
270
  console.log(cliCommon.color(" API Flow Runner" + (version ? ` ${version}` : ""), cliCommon.C.bold, cliCommon.C.white));
271
271
  console.log(cliCommon.color(` Flow: ${flow.name}`, cliCommon.C.gray));
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-BY_jaVBT.js");
25
+ const handle = require("./chunks/handle-Bz0C56Eq.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-DHxjokyP.js");
32
+ const requestExec = require("./chunks/request-exec-B-F0K-pN.js");
33
33
  const ipcValidate = require("./chunks/ipc-validate-sqUFqRmE.js");
34
34
  const uuid = require("uuid");
35
35
  const jsYaml = require("js-yaml");
@@ -42,9 +42,9 @@ const WebSocket = require("ws");
42
42
  const os = require("node:os");
43
43
  const grpc = require("@grpc/grpc-js");
44
44
  const protoLoader = require("@grpc/proto-loader");
45
- const soapHandler = require("./chunks/soap-handler-CkoLJHoI.js");
45
+ const soapHandler = require("./chunks/soap-handler-DqIPcIQL.js");
46
46
  const escape = require("./chunks/escape-DDVAlOvZ.js");
47
- const brokerClient = require("./chunks/broker-client-D0wYVblb.js");
47
+ const brokerClient = require("./chunks/broker-client-Df4PpJqB.js");
48
48
  const simpleGit = require("simple-git");
49
49
  const recorder = require("./chunks/recorder-BkO8G_mB.js");
50
50
  const electronUpdater = require("electron-updater");
@@ -1299,6 +1299,29 @@ async function importPostman(filePath) {
1299
1299
  requests
1300
1300
  };
1301
1301
  }
1302
+ async function importPostmanEnvironment(filePath) {
1303
+ const raw = await promises.readFile(filePath, "utf8");
1304
+ let data;
1305
+ try {
1306
+ data = JSON.parse(raw);
1307
+ } catch {
1308
+ throw new Error("Not valid JSON — pick a Postman environment export file.");
1309
+ }
1310
+ if (!Array.isArray(data.values) || data._postman_variable_scope === "collection") {
1311
+ throw new Error('Not a Postman environment file (no "values" array found).');
1312
+ }
1313
+ const variables = data.values.filter((v) => !!v && typeof v.key === "string" && v.key.length > 0).map((v) => ({
1314
+ key: v.key,
1315
+ value: v.value == null ? "" : String(v.value),
1316
+ enabled: v.enabled !== false
1317
+ }));
1318
+ return {
1319
+ version: "1.0",
1320
+ id: uuid.v4(),
1321
+ name: data.name && String(data.name).trim() || "Imported Environment",
1322
+ variables
1323
+ };
1324
+ }
1302
1325
  async function loadSpec(filePath) {
1303
1326
  const raw = await promises.readFile(filePath, "utf8");
1304
1327
  if (filePath.endsWith(".yaml") || filePath.endsWith(".yml")) {
@@ -2041,6 +2064,15 @@ function registerImportHandlers(ipc) {
2041
2064
  if (result.canceled || !result.filePaths[0]) return null;
2042
2065
  return importPostman(result.filePaths[0]);
2043
2066
  });
2067
+ handle.handleIpc(ipc, handle.IPC.import.postmanEnvironment, async () => {
2068
+ const result = await electron.dialog.showOpenDialog({
2069
+ title: "Import Postman Environment",
2070
+ filters: [{ name: "JSON", extensions: ["json"] }],
2071
+ properties: ["openFile"]
2072
+ });
2073
+ if (result.canceled || !result.filePaths[0]) return null;
2074
+ return importPostmanEnvironment(result.filePaths[0]);
2075
+ });
2044
2076
  handle.handleIpc(ipc, handle.IPC.import.openapi, async () => {
2045
2077
  const result = await electron.dialog.showOpenDialog({
2046
2078
  title: "Import OpenAPI Definition",
@@ -6110,7 +6142,7 @@ function isNewer(a, b) {
6110
6142
  return a2 > b2;
6111
6143
  }
6112
6144
  async function checkForUpdate() {
6113
- const current = "0.7.5";
6145
+ const current = "0.7.7";
6114
6146
  try {
6115
6147
  const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(4e3) });
6116
6148
  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-DHxjokyP.js");
4
+ const requestExec = require("./chunks/request-exec-B-F0K-pN.js");
5
5
  const flowEngine = require("./chunks/flow-engine-BVzjz4lJ.js");
6
6
  require("node:http");
7
7
  require("node:crypto");
@@ -11,7 +11,7 @@ require("@xmldom/xmldom");
11
11
  require("undici");
12
12
  require("fs/promises");
13
13
  require("tls");
14
- require("./chunks/handle-BY_jaVBT.js");
14
+ require("./chunks/handle-Bz0C56Eq.js");
15
15
  require("node:fs");
16
16
  require("node:os");
17
17
  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-DHxjokyP.js");
5
+ const requestExec = require("./chunks/request-exec-B-F0K-pN.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-GnihVSjU.js");
10
10
  require("undici");
11
11
  require("fs/promises");
12
12
  require("tls");
13
- require("./chunks/handle-BY_jaVBT.js");
13
+ require("./chunks/handle-Bz0C56Eq.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.7.5"}`;
498
+ const version = `v${"0.7.7"}`;
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-CkoLJHoI.js");
8
- const _import = require("./chunks/import-DR_r1DUP.js");
7
+ const soapHandler = require("./chunks/soap-handler-DqIPcIQL.js");
8
+ const _import = require("./chunks/import-BhGBiW7j.js");
9
9
  const cliCommon = require("./chunks/cli-common-GnihVSjU.js");
10
- require("./chunks/handle-BY_jaVBT.js");
10
+ require("./chunks/handle-Bz0C56Eq.js");
11
11
  require("@xmldom/xmldom");
12
12
  require("uuid");
13
13
  require("./chunks/data-files-BYqhsoPe.js");
@@ -42,6 +42,7 @@ const IPC = {
42
42
  secret: {
43
43
  checkMasterKey: "secret:checkMasterKey",
44
44
  setMasterKey: "secret:setMasterKey",
45
+ encryptWithMasterKey: "secret:encryptWithMasterKey",
45
46
  set: "secret:set",
46
47
  has: "secret:has",
47
48
  delete: "secret:delete"
@@ -74,6 +75,7 @@ const IPC = {
74
75
  // ─── Import ────────────────────────────────────────────────────────────────
75
76
  import: {
76
77
  postman: "import:postman",
78
+ postmanEnvironment: "import:postman-environment",
77
79
  openapi: "import:openapi",
78
80
  openapiUrl: "import:openapi-url",
79
81
  insomnia: "import:insomnia",
@@ -278,6 +280,9 @@ const api = {
278
280
  // ─── Secrets (encrypted, master-key-based) ───────────────────────────────
279
281
  checkMasterKey: () => electron.ipcRenderer.invoke(IPC.secret.checkMasterKey),
280
282
  setMasterKey: (value) => electron.ipcRenderer.invoke(IPC.secret.setMasterKey, value),
283
+ /** Encrypt a secret in the main process with the master key already set there
284
+ * (API_SPECTOR_MASTER_KEY) — no password prompt needed. */
285
+ encryptWithMasterKey: (plaintext) => electron.ipcRenderer.invoke(IPC.secret.encryptWithMasterKey, plaintext),
281
286
  /** Save a named secret to the OS keychain (safeStorage). */
282
287
  setSecret: (ref, value) => electron.ipcRenderer.invoke(IPC.secret.set, ref, value),
283
288
  /** Whether a secret exists (never returns the value itself). */
@@ -308,6 +313,7 @@ const api = {
308
313
  },
309
314
  // ─── Import ────────────────────────────────────────────────────────────────
310
315
  importPostman: () => electron.ipcRenderer.invoke(IPC.import.postman),
316
+ importPostmanEnvironment: () => electron.ipcRenderer.invoke(IPC.import.postmanEnvironment),
311
317
  importOpenApi: () => electron.ipcRenderer.invoke(IPC.import.openapi),
312
318
  importOpenApiFromUrl: (url) => electron.ipcRenderer.invoke(IPC.import.openapiUrl, url),
313
319
  importInsomnia: () => electron.ipcRenderer.invoke(IPC.import.insomnia),
@@ -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-CUCX3V01.js";
2
+ import { u as useT, a as useStore, b as useActiveEnvironment } from "./index-Gcd_t6pX.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-CUCX3V01.js";
2
+ import { u as useT, c as btnPrimaryCls, d as commentKeymap } from "./index-Gcd_t6pX.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";