@testsmith/api-spector 0.7.2 → 0.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +2 -0
- package/out/main/agents.js +1 -1
- package/out/main/chunks/{broker-client-BSTNMPtT.js → broker-client-VwFF9sbp.js} +1 -1
- package/out/main/chunks/{cli-common-Cq_cphpZ.js → cli-common-GnihVSjU.js} +13 -0
- package/out/main/chunks/flow-engine-BVzjz4lJ.js +551 -0
- package/out/main/chunks/{handle-DDZ37J8G.js → handle-BY_jaVBT.js} +16 -0
- package/out/main/chunks/{import-CBAklepT.js → import-DR_r1DUP.js} +2 -2
- package/out/main/chunks/{request-exec-DLBjLZe1.js → request-exec-CcLHtkwG.js} +59 -18
- package/out/main/chunks/{soap-handler-C_LCcPwE.js → soap-handler-CkoLJHoI.js} +2 -2
- package/out/main/compare.js +1 -1
- package/out/main/contract.js +4 -4
- package/out/main/coverage.js +1 -1
- package/out/main/flow.js +401 -0
- package/out/main/generate-tests.js +1 -1
- package/out/main/index.js +173 -5
- package/out/main/lib.js +67 -2
- package/out/main/mock.js +1 -1
- package/out/main/record.js +1 -1
- package/out/main/runner.js +4 -4
- package/out/main/wsdl.js +4 -4
- package/out/preload/index.js +30 -0
- package/out/renderer/assets/{GraphQLEditor-D-zPak2W.js → GraphQLEditor-Ih9tb7XI.js} +1 -1
- package/out/renderer/assets/{SoapEditor-080lveVz.js → SoapEditor-CwrFQmAx.js} +1 -1
- package/out/renderer/assets/index-CkWcesWQ.css +627 -0
- package/out/renderer/assets/{index-LLqTi-5a.js → index-Cy2EGsQK.js} +12380 -1440
- package/out/renderer/index.html +2 -2
- package/package.json +2 -1
- package/out/renderer/assets/index-DfWnNkH3.css +0 -2
package/out/main/index.js
CHANGED
|
@@ -22,28 +22,29 @@ 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-
|
|
25
|
+
const handle = require("./chunks/handle-BY_jaVBT.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-
|
|
32
|
+
const requestExec = require("./chunks/request-exec-CcLHtkwG.js");
|
|
33
33
|
const ipcValidate = require("./chunks/ipc-validate-sqUFqRmE.js");
|
|
34
34
|
const uuid = require("uuid");
|
|
35
35
|
const jsYaml = require("js-yaml");
|
|
36
36
|
const undici = require("undici");
|
|
37
37
|
const requestCollection = require("./chunks/request-collection-KGPuvN7o.js");
|
|
38
|
+
const flowEngine = require("./chunks/flow-engine-BVzjz4lJ.js");
|
|
38
39
|
const mockServer = require("./chunks/mock-server-C4kTFkod.js");
|
|
39
40
|
const http = require("node:http");
|
|
40
41
|
const WebSocket = require("ws");
|
|
41
42
|
const os = require("node:os");
|
|
42
43
|
const grpc = require("@grpc/grpc-js");
|
|
43
44
|
const protoLoader = require("@grpc/proto-loader");
|
|
44
|
-
const soapHandler = require("./chunks/soap-handler-
|
|
45
|
+
const soapHandler = require("./chunks/soap-handler-CkoLJHoI.js");
|
|
45
46
|
const escape = require("./chunks/escape-DDVAlOvZ.js");
|
|
46
|
-
const brokerClient = require("./chunks/broker-client-
|
|
47
|
+
const brokerClient = require("./chunks/broker-client-VwFF9sbp.js");
|
|
47
48
|
const simpleGit = require("simple-git");
|
|
48
49
|
const recorder = require("./chunks/recorder-BkO8G_mB.js");
|
|
49
50
|
const electronUpdater = require("electron-updater");
|
|
@@ -164,6 +165,7 @@ function readmeContents(workspaceFileName) {
|
|
|
164
165
|
`environments/ ← per-env variable files (dev, staging, prod, …)`,
|
|
165
166
|
`mocks/ ← saved mock servers (optional)`,
|
|
166
167
|
`contracts/ ← pinned OpenAPI snapshots (optional)`,
|
|
168
|
+
`flows/ ← visual flows chaining saved requests (optional)`,
|
|
167
169
|
`.gitignore ← excludes secrets, generated docs, run reports`,
|
|
168
170
|
`.vscode/settings.json ← maps *.spector to JSON for editor highlighting`,
|
|
169
171
|
"```",
|
|
@@ -310,6 +312,7 @@ Create a workspace in this folder and add "${path.basename(wsPath)}" to it? The
|
|
|
310
312
|
await requestExec.loadGlobals(workspaceDir);
|
|
311
313
|
await promises.mkdir(path.join(workspaceDir, "collections"), { recursive: true });
|
|
312
314
|
await promises.mkdir(path.join(workspaceDir, "environments"), { recursive: true });
|
|
315
|
+
await promises.mkdir(path.join(workspaceDir, "flows"), { recursive: true });
|
|
313
316
|
await ensureGitignore(workspaceDir);
|
|
314
317
|
await ensureVscodeFileAssociation(workspaceDir);
|
|
315
318
|
await ensureReadme(workspaceDir, path.basename(result.filePath));
|
|
@@ -353,6 +356,17 @@ Create a workspace in this folder and add "${path.basename(wsPath)}" to it? The
|
|
|
353
356
|
await promises.mkdir(path.dirname(fullPath), { recursive: true });
|
|
354
357
|
await atomicWrite(fullPath, JSON.stringify(env, null, 2));
|
|
355
358
|
});
|
|
359
|
+
handle.handleIpc(ipc, handle.IPC.file.loadFlow, async (_e, relPath) => {
|
|
360
|
+
if (!workspaceDir) throw new Error("No workspace open");
|
|
361
|
+
const raw = await promises.readFile(path.resolve(workspaceDir, relPath), "utf8");
|
|
362
|
+
return JSON.parse(raw);
|
|
363
|
+
});
|
|
364
|
+
handle.handleIpc(ipc, handle.IPC.file.saveFlow, async (_e, relPath, flow) => {
|
|
365
|
+
if (!workspaceDir) throw new Error("No workspace open");
|
|
366
|
+
const fullPath = path.resolve(workspaceDir, relPath);
|
|
367
|
+
await promises.mkdir(path.dirname(fullPath), { recursive: true });
|
|
368
|
+
await atomicWrite(fullPath, JSON.stringify(flow, null, 2));
|
|
369
|
+
});
|
|
356
370
|
handle.handleIpc(ipc, handle.IPC.file.deleteWorkspaceFile, async (_e, relPath) => {
|
|
357
371
|
if (!workspaceDir) throw new Error("No workspace open");
|
|
358
372
|
const fullPath = path.resolve(workspaceDir, relPath);
|
|
@@ -4684,6 +4698,107 @@ function registerRunnerHandler(ipc) {
|
|
|
4684
4698
|
return summary;
|
|
4685
4699
|
});
|
|
4686
4700
|
}
|
|
4701
|
+
function registerFlowHandler(ipc) {
|
|
4702
|
+
handle.handleIpc(ipc, handle.IPC.flow.run, async (event, payload) => {
|
|
4703
|
+
const { collections, environment, globals: payloadGlobals, proxy, tls, piiMaskPatterns = [] } = payload;
|
|
4704
|
+
const flow = flowEngine.normalizeFlow(payload.flow);
|
|
4705
|
+
const flows = (payload.flows ?? []).map(flowEngine.normalizeFlow);
|
|
4706
|
+
const envVars = await requestExec.buildEnvVars(environment);
|
|
4707
|
+
const globals = { ...payloadGlobals, ...requestExec.getGlobals() };
|
|
4708
|
+
const dispatcher = await requestExec.buildDispatcher(proxy, tls);
|
|
4709
|
+
const colById = new Map(collections.map((c) => [c.id, c]));
|
|
4710
|
+
const deps = {
|
|
4711
|
+
runRequest: async (ref, input) => {
|
|
4712
|
+
const col = colById.get(ref.collectionId);
|
|
4713
|
+
const original = col?.requests[ref.requestId];
|
|
4714
|
+
if (!col || !original) return null;
|
|
4715
|
+
const req = JSON.parse(JSON.stringify(original));
|
|
4716
|
+
const inherited = requestCollection.resolveInheritedAuthAndHeaders(original.id, col);
|
|
4717
|
+
if (!requestCollection.authIsConfigured(req.auth) && inherited.auth && inherited.auth.type !== "none") {
|
|
4718
|
+
req.auth = inherited.auth;
|
|
4719
|
+
}
|
|
4720
|
+
const inheritedHeaders = inherited.headers.filter((h) => h.enabled && h.key);
|
|
4721
|
+
if (inheritedHeaders.length) req.headers = [...inheritedHeaders, ...req.headers ?? []];
|
|
4722
|
+
const { result, updatedEnvVars, updatedCollectionVars, updatedGlobals, updatedLocalVars } = await requestExec.executeRunnerRequest({
|
|
4723
|
+
req,
|
|
4724
|
+
collectionVars: { ...col.collectionVariables ?? {}, ...input.collectionVars },
|
|
4725
|
+
envVars: input.envVars,
|
|
4726
|
+
globals: input.globals,
|
|
4727
|
+
localVars: input.localVars,
|
|
4728
|
+
dispatcher,
|
|
4729
|
+
// Flows chain on the real response (e.g. extracting an access_token
|
|
4730
|
+
// the next block sends as a Bearer), so the body must NOT be PII-
|
|
4731
|
+
// masked here — masking would feed downstream blocks a sentinel.
|
|
4732
|
+
piiMaskPatterns: [],
|
|
4733
|
+
proxy,
|
|
4734
|
+
tls
|
|
4735
|
+
});
|
|
4736
|
+
const rr = result.receivedResponse;
|
|
4737
|
+
const response = rr ? { status: rr.status, statusText: rr.statusText, headers: rr.headers, body: rr.body, bodySize: rr.body?.length ?? 0, durationMs: result.durationMs ?? 0 } : null;
|
|
4738
|
+
return {
|
|
4739
|
+
envVars: updatedEnvVars,
|
|
4740
|
+
collectionVars: updatedCollectionVars,
|
|
4741
|
+
globals: updatedGlobals,
|
|
4742
|
+
localVars: updatedLocalVars,
|
|
4743
|
+
response,
|
|
4744
|
+
status: result.status,
|
|
4745
|
+
httpStatus: result.httpStatus,
|
|
4746
|
+
durationMs: result.durationMs,
|
|
4747
|
+
error: result.error,
|
|
4748
|
+
testResults: result.testResults,
|
|
4749
|
+
name: result.name,
|
|
4750
|
+
method: result.method,
|
|
4751
|
+
resolvedUrl: result.resolvedUrl
|
|
4752
|
+
};
|
|
4753
|
+
},
|
|
4754
|
+
runScript: async (code, input) => {
|
|
4755
|
+
const out = await requestExec.runScript(code, {
|
|
4756
|
+
envVars: input.envVars,
|
|
4757
|
+
collectionVars: input.collectionVars,
|
|
4758
|
+
globals: input.globals,
|
|
4759
|
+
localVars: input.localVars,
|
|
4760
|
+
response: input.response ?? void 0,
|
|
4761
|
+
piiMaskPatterns,
|
|
4762
|
+
data: input.data
|
|
4763
|
+
});
|
|
4764
|
+
return {
|
|
4765
|
+
envVars: out.updatedEnvVars,
|
|
4766
|
+
collectionVars: out.updatedCollectionVars,
|
|
4767
|
+
globals: out.updatedGlobals,
|
|
4768
|
+
localVars: out.updatedLocalVars,
|
|
4769
|
+
testResults: out.testResults,
|
|
4770
|
+
consoleOutput: out.consoleOutput,
|
|
4771
|
+
error: out.error
|
|
4772
|
+
};
|
|
4773
|
+
},
|
|
4774
|
+
evalExpression: async (code, input) => {
|
|
4775
|
+
const out = await requestExec.evaluateExpression(code, {
|
|
4776
|
+
envVars: input.envVars,
|
|
4777
|
+
collectionVars: input.collectionVars,
|
|
4778
|
+
globals: input.globals,
|
|
4779
|
+
localVars: input.localVars,
|
|
4780
|
+
response: input.response ?? void 0,
|
|
4781
|
+
piiMaskPatterns,
|
|
4782
|
+
data: input.data
|
|
4783
|
+
});
|
|
4784
|
+
return {
|
|
4785
|
+
envVars: out.updatedEnvVars,
|
|
4786
|
+
collectionVars: out.updatedCollectionVars,
|
|
4787
|
+
globals: out.updatedGlobals,
|
|
4788
|
+
localVars: out.updatedLocalVars,
|
|
4789
|
+
value: out.value,
|
|
4790
|
+
consoleOutput: out.consoleOutput,
|
|
4791
|
+
error: out.error
|
|
4792
|
+
};
|
|
4793
|
+
},
|
|
4794
|
+
resolveFlow: (flowId) => flows.find((f) => f.id === flowId) ?? null,
|
|
4795
|
+
sleep: (ms) => new Promise((resolve2) => setTimeout(resolve2, ms)),
|
|
4796
|
+
interpolate: (str, vars) => requestExec.interpolate(str, vars),
|
|
4797
|
+
onEvent: (evt) => event.sender.send(handle.IPC.flow.progress, evt)
|
|
4798
|
+
};
|
|
4799
|
+
return flowEngine.runFlow(flow, deps, { envVars, globals });
|
|
4800
|
+
});
|
|
4801
|
+
}
|
|
4687
4802
|
function registerMockHandlers(ipc) {
|
|
4688
4803
|
handle.handleIpc(ipc, handle.IPC.mock.start, async (e, server) => {
|
|
4689
4804
|
mockServer.setHitCallback((hit) => e.sender.send(handle.IPC.mock.hit, hit));
|
|
@@ -5741,6 +5856,41 @@ function registerRecordHandlers(ipc, getWebContents) {
|
|
|
5741
5856
|
return recorder.entriesToMockServer(entries, upstream, name, port);
|
|
5742
5857
|
});
|
|
5743
5858
|
}
|
|
5859
|
+
async function buildFlowDefinition(input) {
|
|
5860
|
+
const envVars = await requestExec.buildEnvVars(input.environment);
|
|
5861
|
+
const colById = new Map(input.collections.map((c) => [c.id, c]));
|
|
5862
|
+
const collectionVars = {};
|
|
5863
|
+
for (const c of input.collections) Object.assign(collectionVars, c.collectionVariables ?? {});
|
|
5864
|
+
const requests = {};
|
|
5865
|
+
for (const f of [input.flow, ...input.flows ?? []]) {
|
|
5866
|
+
for (const node of f.nodes ?? []) {
|
|
5867
|
+
const ref = node.config?.ref;
|
|
5868
|
+
if (node.type !== "request" || !ref) continue;
|
|
5869
|
+
const col = colById.get(ref.collectionId);
|
|
5870
|
+
const req = col?.requests[ref.requestId];
|
|
5871
|
+
if (!col || !req) continue;
|
|
5872
|
+
const cloned = JSON.parse(JSON.stringify(req));
|
|
5873
|
+
const inherited = requestCollection.resolveInheritedAuthAndHeaders(req.id, col);
|
|
5874
|
+
if (!requestCollection.authIsConfigured(cloned.auth) && inherited.auth && inherited.auth.type !== "none") cloned.auth = inherited.auth;
|
|
5875
|
+
const inhHeaders = inherited.headers.filter((h) => h.enabled && h.key);
|
|
5876
|
+
if (inhHeaders.length) cloned.headers = [...inhHeaders, ...cloned.headers ?? []];
|
|
5877
|
+
requests[`${ref.collectionId}:${ref.requestId}`] = cloned;
|
|
5878
|
+
}
|
|
5879
|
+
}
|
|
5880
|
+
return {
|
|
5881
|
+
flow: input.flow,
|
|
5882
|
+
flows: input.flows ?? [],
|
|
5883
|
+
requests,
|
|
5884
|
+
envVars,
|
|
5885
|
+
collectionVars,
|
|
5886
|
+
globals: input.globals ?? {},
|
|
5887
|
+
// Record which environment's values were baked (for the cloud UI). null when
|
|
5888
|
+
// no environment was active at push time — a common cause of "works locally,
|
|
5889
|
+
// fails in the cloud" when requests rely on environment variables.
|
|
5890
|
+
environmentName: input.environment?.name ?? null,
|
|
5891
|
+
envVarCount: Object.keys(envVars).length
|
|
5892
|
+
};
|
|
5893
|
+
}
|
|
5744
5894
|
const CLOUD_TOKEN_REF = "cloud:token";
|
|
5745
5895
|
const CLOUD_ENDPOINT = brokerClient.resolveCloudEndpoint();
|
|
5746
5896
|
async function cloudFetch(path2, method, body) {
|
|
@@ -5912,6 +6062,23 @@ function registerCloudHandlers(ipc) {
|
|
|
5912
6062
|
handle.handleIpc(ipc, handle.IPC.cloud.openMatrix, async () => {
|
|
5913
6063
|
await electron.shell.openExternal(CLOUD_ENDPOINT + "/matrix");
|
|
5914
6064
|
});
|
|
6065
|
+
handle.handleIpc(ipc, handle.IPC.cloud.pushFlow, async (_e, input) => {
|
|
6066
|
+
const definition = await buildFlowDefinition(input);
|
|
6067
|
+
return cloudFetch("/api/flows", "POST", {
|
|
6068
|
+
name: input.flow.name,
|
|
6069
|
+
slug: slugify(input.flow.name),
|
|
6070
|
+
definition
|
|
6071
|
+
});
|
|
6072
|
+
});
|
|
6073
|
+
handle.handleIpc(ipc, handle.IPC.cloud.runFlow, async (_e, name) => {
|
|
6074
|
+
return cloudFetch("/api/flows/" + encodeURIComponent(slugify(name)) + "/run", "POST");
|
|
6075
|
+
});
|
|
6076
|
+
handle.handleIpc(ipc, handle.IPC.cloud.getFlowRun, async (_e, arg) => {
|
|
6077
|
+
return cloudFetch(`/api/flows/${encodeURIComponent(slugify(arg.name))}/runs/${encodeURIComponent(String(arg.runId))}`, "GET");
|
|
6078
|
+
});
|
|
6079
|
+
handle.handleIpc(ipc, handle.IPC.cloud.openFlow, async (_e, name) => {
|
|
6080
|
+
await electron.shell.openExternal(CLOUD_ENDPOINT + "/flows/" + encodeURIComponent(slugify(name)));
|
|
6081
|
+
});
|
|
5915
6082
|
handle.handleIpc(ipc, handle.IPC.cloud.pushMonitor, async (_e, input) => {
|
|
5916
6083
|
const { request, environment, collectionVars, globals } = input;
|
|
5917
6084
|
const envVars = await requestExec.buildEnvVars(environment);
|
|
@@ -5943,7 +6110,7 @@ function isNewer(a, b) {
|
|
|
5943
6110
|
return a2 > b2;
|
|
5944
6111
|
}
|
|
5945
6112
|
async function checkForUpdate() {
|
|
5946
|
-
const current = "0.7.
|
|
6113
|
+
const current = "0.7.4";
|
|
5947
6114
|
try {
|
|
5948
6115
|
const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(4e3) });
|
|
5949
6116
|
if (!res.ok) return null;
|
|
@@ -6156,6 +6323,7 @@ electron.app.whenReady().then(async () => {
|
|
|
6156
6323
|
registerImportHandlers(electron.ipcMain);
|
|
6157
6324
|
registerGenerateHandlers(electron.ipcMain);
|
|
6158
6325
|
registerRunnerHandler(electron.ipcMain);
|
|
6326
|
+
registerFlowHandler(electron.ipcMain);
|
|
6159
6327
|
registerMockHandlers(electron.ipcMain);
|
|
6160
6328
|
registerOAuth2Handlers(electron.ipcMain);
|
|
6161
6329
|
registerVaultHandlers(electron.ipcMain);
|
package/out/main/lib.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
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-
|
|
4
|
+
const requestExec = require("./chunks/request-exec-CcLHtkwG.js");
|
|
5
|
+
const flowEngine = require("./chunks/flow-engine-BVzjz4lJ.js");
|
|
5
6
|
require("node:http");
|
|
6
7
|
require("node:crypto");
|
|
7
8
|
require("node:vm");
|
|
@@ -10,7 +11,7 @@ require("@xmldom/xmldom");
|
|
|
10
11
|
require("undici");
|
|
11
12
|
require("fs/promises");
|
|
12
13
|
require("tls");
|
|
13
|
-
require("./chunks/handle-
|
|
14
|
+
require("./chunks/handle-BY_jaVBT.js");
|
|
14
15
|
require("node:fs");
|
|
15
16
|
require("node:os");
|
|
16
17
|
require("node:path");
|
|
@@ -18,6 +19,66 @@ require("node:fs/promises");
|
|
|
18
19
|
require("tv4");
|
|
19
20
|
require("jsonpath-plus");
|
|
20
21
|
require("ajv");
|
|
22
|
+
const refKey = (ref) => `${ref.collectionId}:${ref.requestId}`;
|
|
23
|
+
async function runFlowHeadless(input) {
|
|
24
|
+
const flow = flowEngine.normalizeFlow(input.flow);
|
|
25
|
+
const flows = (input.flows ?? []).map(flowEngine.normalizeFlow);
|
|
26
|
+
const requests = input.requests ?? {};
|
|
27
|
+
const dispatcher = await requestExec.buildDispatcher(input.proxy, input.tls);
|
|
28
|
+
const deps = {
|
|
29
|
+
runRequest: async (ref, i) => {
|
|
30
|
+
const original = requests[refKey(ref)];
|
|
31
|
+
if (!original) return null;
|
|
32
|
+
const req = JSON.parse(JSON.stringify(original));
|
|
33
|
+
const { result, updatedEnvVars, updatedCollectionVars, updatedGlobals, updatedLocalVars } = await requestExec.executeRunnerRequest({
|
|
34
|
+
req,
|
|
35
|
+
collectionVars: i.collectionVars,
|
|
36
|
+
envVars: i.envVars,
|
|
37
|
+
globals: i.globals,
|
|
38
|
+
localVars: i.localVars,
|
|
39
|
+
dispatcher,
|
|
40
|
+
piiMaskPatterns: [],
|
|
41
|
+
proxy: input.proxy,
|
|
42
|
+
tls: input.tls
|
|
43
|
+
});
|
|
44
|
+
const rr = result.receivedResponse;
|
|
45
|
+
const response = rr ? { status: rr.status, statusText: rr.statusText, headers: rr.headers, body: rr.body, bodySize: rr.body?.length ?? 0, durationMs: result.durationMs ?? 0 } : null;
|
|
46
|
+
return {
|
|
47
|
+
envVars: updatedEnvVars,
|
|
48
|
+
collectionVars: updatedCollectionVars,
|
|
49
|
+
globals: updatedGlobals,
|
|
50
|
+
localVars: updatedLocalVars,
|
|
51
|
+
response,
|
|
52
|
+
status: result.status,
|
|
53
|
+
httpStatus: result.httpStatus,
|
|
54
|
+
durationMs: result.durationMs,
|
|
55
|
+
error: result.error,
|
|
56
|
+
testResults: result.testResults,
|
|
57
|
+
name: result.name,
|
|
58
|
+
method: result.method,
|
|
59
|
+
resolvedUrl: result.resolvedUrl,
|
|
60
|
+
sentRequest: {
|
|
61
|
+
method: result.method,
|
|
62
|
+
url: result.resolvedUrl,
|
|
63
|
+
headers: result.sentRequest?.headers ?? {},
|
|
64
|
+
body: result.sentRequest?.body
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
},
|
|
68
|
+
runScript: async (code, i) => {
|
|
69
|
+
const o = await requestExec.runScript(code, { envVars: i.envVars, collectionVars: i.collectionVars, globals: i.globals, localVars: i.localVars, response: i.response ?? void 0, data: i.data, piiMaskPatterns: [] });
|
|
70
|
+
return { envVars: o.updatedEnvVars, collectionVars: o.updatedCollectionVars, globals: o.updatedGlobals, localVars: o.updatedLocalVars, testResults: o.testResults, consoleOutput: o.consoleOutput, error: o.error };
|
|
71
|
+
},
|
|
72
|
+
evalExpression: async (code, i) => {
|
|
73
|
+
const o = await requestExec.evaluateExpression(code, { envVars: i.envVars, collectionVars: i.collectionVars, globals: i.globals, localVars: i.localVars, response: i.response ?? void 0, data: i.data, piiMaskPatterns: [] });
|
|
74
|
+
return { envVars: o.updatedEnvVars, collectionVars: o.updatedCollectionVars, globals: o.updatedGlobals, localVars: o.updatedLocalVars, value: o.value, consoleOutput: o.consoleOutput, error: o.error };
|
|
75
|
+
},
|
|
76
|
+
resolveFlow: (id) => flows.find((f) => f.id === id) ?? null,
|
|
77
|
+
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
78
|
+
onEvent: input.onEvent
|
|
79
|
+
};
|
|
80
|
+
return flowEngine.runFlow(flow, deps, { envVars: input.envVars, collectionVars: input.collectionVars, globals: input.globals });
|
|
81
|
+
}
|
|
21
82
|
exports.findRoute = mockServer.findRoute;
|
|
22
83
|
exports.getRunningIds = mockServer.getRunningIds;
|
|
23
84
|
exports.handleRequest = mockServer.handleRequest;
|
|
@@ -43,3 +104,7 @@ exports.registeredSchemes = requestExec.registeredSchemes;
|
|
|
43
104
|
exports.resolveExternalSecret = requestExec.resolveExternalSecret;
|
|
44
105
|
exports.setSecretsConfig = requestExec.setSecretsConfig;
|
|
45
106
|
exports.syntheticHttpFailure = requestExec.syntheticHttpFailure;
|
|
107
|
+
exports.BLOCK_SPECS = flowEngine.BLOCK_SPECS;
|
|
108
|
+
exports.normalizeFlow = flowEngine.normalizeFlow;
|
|
109
|
+
exports.runFlow = flowEngine.runFlow;
|
|
110
|
+
exports.runFlowHeadless = runFlowHeadless;
|
package/out/main/mock.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
const mockServer = require("./chunks/mock-server-C4kTFkod.js");
|
|
4
|
-
const cliCommon = require("./chunks/cli-common-
|
|
4
|
+
const cliCommon = require("./chunks/cli-common-GnihVSjU.js");
|
|
5
5
|
require("node:http");
|
|
6
6
|
require("node:crypto");
|
|
7
7
|
require("node:vm");
|
package/out/main/record.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
const promises = require("node:fs/promises");
|
|
4
4
|
const path = require("node:path");
|
|
5
5
|
const recorder = require("./chunks/recorder-BkO8G_mB.js");
|
|
6
|
-
const cliCommon = require("./chunks/cli-common-
|
|
6
|
+
const cliCommon = require("./chunks/cli-common-GnihVSjU.js");
|
|
7
7
|
require("node:http");
|
|
8
8
|
require("node:crypto");
|
|
9
9
|
require("undici");
|
package/out/main/runner.js
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
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-
|
|
5
|
+
const requestExec = require("./chunks/request-exec-CcLHtkwG.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");
|
|
9
|
-
const cliCommon = require("./chunks/cli-common-
|
|
9
|
+
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-
|
|
13
|
+
require("./chunks/handle-BY_jaVBT.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.
|
|
498
|
+
const version = `v${"0.7.4"}`;
|
|
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-
|
|
8
|
-
const _import = require("./chunks/import-
|
|
9
|
-
const cliCommon = require("./chunks/cli-common-
|
|
10
|
-
require("./chunks/handle-
|
|
7
|
+
const soapHandler = require("./chunks/soap-handler-CkoLJHoI.js");
|
|
8
|
+
const _import = require("./chunks/import-DR_r1DUP.js");
|
|
9
|
+
const cliCommon = require("./chunks/cli-common-GnihVSjU.js");
|
|
10
|
+
require("./chunks/handle-BY_jaVBT.js");
|
|
11
11
|
require("@xmldom/xmldom");
|
|
12
12
|
require("uuid");
|
|
13
13
|
require("./chunks/data-files-BYqhsoPe.js");
|
package/out/preload/index.js
CHANGED
|
@@ -21,6 +21,8 @@ const IPC = {
|
|
|
21
21
|
deleteWorkspaceFile: "file:deleteWorkspaceFile",
|
|
22
22
|
saveMock: "file:saveMock",
|
|
23
23
|
loadMock: "file:loadMock",
|
|
24
|
+
saveFlow: "file:saveFlow",
|
|
25
|
+
loadFlow: "file:loadFlow",
|
|
24
26
|
loadHistory: "file:loadHistory",
|
|
25
27
|
saveHistory: "file:saveHistory"
|
|
26
28
|
},
|
|
@@ -59,6 +61,12 @@ const IPC = {
|
|
|
59
61
|
/** Event: per-request progress pushed from main during a run. */
|
|
60
62
|
progress: "runner:progress"
|
|
61
63
|
},
|
|
64
|
+
// ─── Flow runner ───────────────────────────────────────────────────────────
|
|
65
|
+
flow: {
|
|
66
|
+
run: "flow:run",
|
|
67
|
+
/** Event: per-block progress pushed from main during a flow run. */
|
|
68
|
+
progress: "flow:progress"
|
|
69
|
+
},
|
|
62
70
|
// ─── Run results export ────────────────────────────────────────────────────
|
|
63
71
|
results: {
|
|
64
72
|
save: "results:save"
|
|
@@ -227,6 +235,14 @@ const IPC = {
|
|
|
227
235
|
pushDesignContract: "cloud:pushDesignContract",
|
|
228
236
|
/** Publish a provider OpenAPI spec (PUT /api/provider-contracts). */
|
|
229
237
|
pushSpec: "cloud:pushSpec",
|
|
238
|
+
/** Upload a self-contained flow definition (POST /api/flows). */
|
|
239
|
+
pushFlow: "cloud:pushFlow",
|
|
240
|
+
/** Trigger a server-side run of an uploaded flow (POST /api/flows/{slug}/run). */
|
|
241
|
+
runFlow: "cloud:runFlow",
|
|
242
|
+
/** Poll a flow run's status/result (GET /api/flows/{slug}/runs/{id}). */
|
|
243
|
+
getFlowRun: "cloud:getFlowRun",
|
|
244
|
+
/** Open a flow's page in the cloud UI. */
|
|
245
|
+
openFlow: "cloud:openFlow",
|
|
230
246
|
/** Open the cloud deployment matrix in the browser. */
|
|
231
247
|
openMatrix: "cloud:openMatrix"
|
|
232
248
|
}
|
|
@@ -282,6 +298,14 @@ const api = {
|
|
|
282
298
|
electron.ipcRenderer.removeAllListeners(IPC.runner.progress);
|
|
283
299
|
},
|
|
284
300
|
saveResults: (content, defaultName) => electron.ipcRenderer.invoke(IPC.results.save, content, defaultName),
|
|
301
|
+
// ─── Flow runner ──────────────────────────────────────────────────────────
|
|
302
|
+
runFlow: (payload) => electron.ipcRenderer.invoke(IPC.flow.run, payload),
|
|
303
|
+
onFlowProgress: (cb) => {
|
|
304
|
+
electron.ipcRenderer.on(IPC.flow.progress, (_e, evt) => cb(evt));
|
|
305
|
+
},
|
|
306
|
+
offFlowProgress: () => {
|
|
307
|
+
electron.ipcRenderer.removeAllListeners(IPC.flow.progress);
|
|
308
|
+
},
|
|
285
309
|
// ─── Import ────────────────────────────────────────────────────────────────
|
|
286
310
|
importPostman: () => electron.ipcRenderer.invoke(IPC.import.postman),
|
|
287
311
|
importOpenApi: () => electron.ipcRenderer.invoke(IPC.import.openapi),
|
|
@@ -313,6 +337,10 @@ const api = {
|
|
|
313
337
|
cloudPushDesignContract: (input) => electron.ipcRenderer.invoke(IPC.cloud.pushDesignContract, input),
|
|
314
338
|
cloudPushSpec: (input) => electron.ipcRenderer.invoke(IPC.cloud.pushSpec, input),
|
|
315
339
|
cloudOpenMatrix: () => electron.ipcRenderer.invoke(IPC.cloud.openMatrix),
|
|
340
|
+
cloudPushFlow: (input) => electron.ipcRenderer.invoke(IPC.cloud.pushFlow, input),
|
|
341
|
+
cloudRunFlow: (name) => electron.ipcRenderer.invoke(IPC.cloud.runFlow, name),
|
|
342
|
+
cloudGetFlowRun: (arg) => electron.ipcRenderer.invoke(IPC.cloud.getFlowRun, arg),
|
|
343
|
+
cloudOpenFlow: (name) => electron.ipcRenderer.invoke(IPC.cloud.openFlow, name),
|
|
316
344
|
// ─── Mock servers ─────────────────────────────────────────────────────────────
|
|
317
345
|
mockStart: (server) => electron.ipcRenderer.invoke(IPC.mock.start, server),
|
|
318
346
|
mockStop: (id) => electron.ipcRenderer.invoke(IPC.mock.stop, id),
|
|
@@ -320,6 +348,8 @@ const api = {
|
|
|
320
348
|
mockRunningIds: () => electron.ipcRenderer.invoke(IPC.mock.runningIds),
|
|
321
349
|
saveMock: (relPath, server) => electron.ipcRenderer.invoke(IPC.file.saveMock, relPath, server),
|
|
322
350
|
loadMock: (relPath) => electron.ipcRenderer.invoke(IPC.file.loadMock, relPath),
|
|
351
|
+
saveFlow: (relPath, flow) => electron.ipcRenderer.invoke(IPC.file.saveFlow, relPath, flow),
|
|
352
|
+
loadFlow: (relPath) => electron.ipcRenderer.invoke(IPC.file.loadFlow, relPath),
|
|
323
353
|
mockUpdateRoutes: (id, routes) => electron.ipcRenderer.invoke(IPC.mock.updateRoutes, id, routes),
|
|
324
354
|
onMockHit: (cb) => {
|
|
325
355
|
electron.ipcRenderer.on(IPC.mock.hit, (_e, hit) => cb(hit));
|
|
@@ -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-
|
|
2
|
+
import { u as useT, a as useStore, b as useActiveEnvironment } from "./index-Cy2EGsQK.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-
|
|
2
|
+
import { u as useT, c as btnPrimaryCls, d as commentKeymap } from "./index-Cy2EGsQK.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";
|