jetic-cli 0.2.7 → 0.2.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.
package/dist/index.js
CHANGED
|
@@ -272670,11 +272670,13 @@ var require_workflow_simulator = __commonJS({
|
|
|
272670
272670
|
"use strict";
|
|
272671
272671
|
init_cjs_shims();
|
|
272672
272672
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
272673
|
-
exports2.WorkflowSimulator = void 0;
|
|
272673
|
+
exports2.WorkflowSimulator = exports2.CONNECTION_ERROR_CODES = void 0;
|
|
272674
|
+
exports2.networkErrorCode = networkErrorCode2;
|
|
272675
|
+
exports2.probeTarget = probeTarget2;
|
|
272674
272676
|
var memory_1 = require_dist12();
|
|
272675
272677
|
var faker_1 = require("@faker-js/faker");
|
|
272676
272678
|
var conditions_1 = require_conditions();
|
|
272677
|
-
|
|
272679
|
+
exports2.CONNECTION_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
272678
272680
|
"ECONNREFUSED",
|
|
272679
272681
|
"ECONNRESET",
|
|
272680
272682
|
"ENOTFOUND",
|
|
@@ -272685,7 +272687,7 @@ var require_workflow_simulator = __commonJS({
|
|
|
272685
272687
|
"UND_ERR_CONNECT_TIMEOUT",
|
|
272686
272688
|
"UND_ERR_SOCKET"
|
|
272687
272689
|
]);
|
|
272688
|
-
function
|
|
272690
|
+
function networkErrorCode2(error) {
|
|
272689
272691
|
const raw = error?.cause?.code ?? error?.cause?.errno ?? error?.code ?? error?.errno;
|
|
272690
272692
|
return typeof raw === "string" ? raw : void 0;
|
|
272691
272693
|
}
|
|
@@ -272723,7 +272725,7 @@ var require_workflow_simulator = __commonJS({
|
|
|
272723
272725
|
this.requestTimeoutMs = options?.requestTimeoutMs ?? 3e4;
|
|
272724
272726
|
const startTime = Date.now();
|
|
272725
272727
|
const preflightMode = options?.preflight ?? "off";
|
|
272726
|
-
const preflight = preflightMode !== "off" && workflow.steps.length > 0 ? await
|
|
272728
|
+
const preflight = preflightMode !== "off" && workflow.steps.length > 0 ? await probeTarget2(this.environment.baseUrl, options?.preflightTimeoutMs ?? 3e3) : void 0;
|
|
272727
272729
|
if (preflight && preflightMode === "abort" && preflight.verdict === "unreachable") {
|
|
272728
272730
|
preflight.aborted = true;
|
|
272729
272731
|
return {
|
|
@@ -272783,6 +272785,21 @@ var require_workflow_simulator = __commonJS({
|
|
|
272783
272785
|
async runSteps(workflow, options, state, lineage) {
|
|
272784
272786
|
const baseUrl = this.environment.baseUrl;
|
|
272785
272787
|
const resolve2 = (value) => this.resolveTemplateString(value, false);
|
|
272788
|
+
const record = async (result) => {
|
|
272789
|
+
state.results.push(result);
|
|
272790
|
+
if (!options?.onStepResult)
|
|
272791
|
+
return;
|
|
272792
|
+
try {
|
|
272793
|
+
await options.onStepResult(result, {
|
|
272794
|
+
totalSteps: workflow.steps.length,
|
|
272795
|
+
executedSteps: state.results.length,
|
|
272796
|
+
passedSteps: state.results.filter((r) => r.passed).length,
|
|
272797
|
+
failedSteps: state.results.filter((r) => !r.passed).length,
|
|
272798
|
+
skippedSteps: state.results.filter((r) => r.skipped).length
|
|
272799
|
+
});
|
|
272800
|
+
} catch {
|
|
272801
|
+
}
|
|
272802
|
+
};
|
|
272786
272803
|
for (let i = 0; i < workflow.steps.length; i++) {
|
|
272787
272804
|
const step = workflow.steps[i];
|
|
272788
272805
|
const stepStartTime = Date.now();
|
|
@@ -272790,7 +272807,7 @@ var require_workflow_simulator = __commonJS({
|
|
|
272790
272807
|
const kind = step.condition === void 0 ? void 0 : (0, conditions_1.conditionKind)(step.condition);
|
|
272791
272808
|
if (kind === "invalid") {
|
|
272792
272809
|
const reason = (0, conditions_1.describeInvalidCondition)(step.condition);
|
|
272793
|
-
|
|
272810
|
+
await record({
|
|
272794
272811
|
stepIndex: i + 1,
|
|
272795
272812
|
name: stepName,
|
|
272796
272813
|
method: step.method,
|
|
@@ -272799,6 +272816,8 @@ var require_workflow_simulator = __commonJS({
|
|
|
272799
272816
|
expectedStatus: step.expectStatus ?? 200,
|
|
272800
272817
|
actualStatus: 0,
|
|
272801
272818
|
durationMs: Date.now() - stepStartTime,
|
|
272819
|
+
startedAt: new Date(stepStartTime).toISOString(),
|
|
272820
|
+
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
272802
272821
|
passed: false,
|
|
272803
272822
|
skipped: false,
|
|
272804
272823
|
retryCount: 0,
|
|
@@ -272815,7 +272834,7 @@ var require_workflow_simulator = __commonJS({
|
|
|
272815
272834
|
if (kind === "legacy") {
|
|
272816
272835
|
const condResult = await (0, conditions_1.evaluateLegacyCondition)(step.condition, resolve2);
|
|
272817
272836
|
if (!condResult.matched) {
|
|
272818
|
-
|
|
272837
|
+
await record({
|
|
272819
272838
|
stepIndex: i + 1,
|
|
272820
272839
|
name: stepName,
|
|
272821
272840
|
method: step.method,
|
|
@@ -272824,6 +272843,8 @@ var require_workflow_simulator = __commonJS({
|
|
|
272824
272843
|
expectedStatus: step.expectStatus ?? 200,
|
|
272825
272844
|
actualStatus: 0,
|
|
272826
272845
|
durationMs: Date.now() - stepStartTime,
|
|
272846
|
+
startedAt: new Date(stepStartTime).toISOString(),
|
|
272847
|
+
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
272827
272848
|
passed: true,
|
|
272828
272849
|
skipped: true,
|
|
272829
272850
|
retryCount: 0,
|
|
@@ -272852,7 +272873,7 @@ var require_workflow_simulator = __commonJS({
|
|
|
272852
272873
|
resolvedPath = await this.resolvePathParams(step.path, finalBody);
|
|
272853
272874
|
fullUrl = `${baseUrl.replace(/\/$/, "")}${resolvedPath}`;
|
|
272854
272875
|
} catch (err) {
|
|
272855
|
-
|
|
272876
|
+
await record({
|
|
272856
272877
|
stepIndex: i + 1,
|
|
272857
272878
|
name: stepName,
|
|
272858
272879
|
method: step.method,
|
|
@@ -272861,6 +272882,8 @@ var require_workflow_simulator = __commonJS({
|
|
|
272861
272882
|
expectedStatus: step.expectStatus ?? 200,
|
|
272862
272883
|
actualStatus: 0,
|
|
272863
272884
|
durationMs: Date.now() - stepStartTime,
|
|
272885
|
+
startedAt: new Date(stepStartTime).toISOString(),
|
|
272886
|
+
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
272864
272887
|
passed: false,
|
|
272865
272888
|
skipped: false,
|
|
272866
272889
|
retryCount: 0,
|
|
@@ -272875,11 +272898,42 @@ var require_workflow_simulator = __commonJS({
|
|
|
272875
272898
|
return "stop";
|
|
272876
272899
|
}
|
|
272877
272900
|
const expectedStatus = step.expectStatus ?? 200;
|
|
272901
|
+
let requestUrl = fullUrl;
|
|
272902
|
+
{
|
|
272903
|
+
const upperMethod = step.method.toUpperCase();
|
|
272904
|
+
const bodyAsQuery = ["GET", "HEAD"].includes(upperMethod) && Object.keys(finalBody).length > 0;
|
|
272905
|
+
if (Object.keys(resolvedQuery).length > 0 || bodyAsQuery) {
|
|
272906
|
+
const params = new URLSearchParams();
|
|
272907
|
+
const append = (source) => {
|
|
272908
|
+
for (const [k, v] of Object.entries(source)) {
|
|
272909
|
+
if (v === void 0 || v === null)
|
|
272910
|
+
continue;
|
|
272911
|
+
if (Array.isArray(v)) {
|
|
272912
|
+
for (const item of v)
|
|
272913
|
+
params.append(k, typeof item === "object" ? JSON.stringify(item) : String(item));
|
|
272914
|
+
} else {
|
|
272915
|
+
params.append(k, typeof v === "object" ? JSON.stringify(v) : String(v));
|
|
272916
|
+
}
|
|
272917
|
+
}
|
|
272918
|
+
};
|
|
272919
|
+
append(resolvedQuery);
|
|
272920
|
+
if (bodyAsQuery)
|
|
272921
|
+
append(finalBody);
|
|
272922
|
+
const qs = params.toString();
|
|
272923
|
+
if (qs)
|
|
272924
|
+
requestUrl = `${fullUrl}${fullUrl.includes("?") ? "&" : "?"}${qs}`;
|
|
272925
|
+
}
|
|
272926
|
+
}
|
|
272927
|
+
const actualRequestHeaders = {
|
|
272928
|
+
"Content-Type": "application/json",
|
|
272929
|
+
...injectedHeaders
|
|
272930
|
+
};
|
|
272878
272931
|
const maxAttempts = Math.max(1, step.retry?.times ?? workflow.retry?.times ?? 1);
|
|
272879
272932
|
const retryDelayMs = step.retry?.delayMs ?? workflow.retry?.delayMs ?? 0;
|
|
272880
272933
|
let attempts = 0;
|
|
272881
272934
|
let responseStatus = 0;
|
|
272882
272935
|
let responseBody = null;
|
|
272936
|
+
let responseHeaders;
|
|
272883
272937
|
let stepPassed = false;
|
|
272884
272938
|
let errorMsg;
|
|
272885
272939
|
let connectionCode;
|
|
@@ -272890,6 +272944,7 @@ var require_workflow_simulator = __commonJS({
|
|
|
272890
272944
|
}
|
|
272891
272945
|
responseStatus = 0;
|
|
272892
272946
|
responseBody = null;
|
|
272947
|
+
responseHeaders = void 0;
|
|
272893
272948
|
errorMsg = void 0;
|
|
272894
272949
|
connectionCode = void 0;
|
|
272895
272950
|
const timeoutMs = step.timeoutMs ?? this.requestTimeoutMs;
|
|
@@ -272897,7 +272952,7 @@ var require_workflow_simulator = __commonJS({
|
|
|
272897
272952
|
const upperMethod = step.method.toUpperCase();
|
|
272898
272953
|
const fetchOptions = {
|
|
272899
272954
|
method: upperMethod,
|
|
272900
|
-
headers:
|
|
272955
|
+
headers: actualRequestHeaders
|
|
272901
272956
|
};
|
|
272902
272957
|
if (!["GET", "HEAD"].includes(upperMethod) && Object.keys(finalBody).length > 0) {
|
|
272903
272958
|
fetchOptions.body = JSON.stringify(finalBody);
|
|
@@ -272905,31 +272960,9 @@ var require_workflow_simulator = __commonJS({
|
|
|
272905
272960
|
if (timeoutMs > 0) {
|
|
272906
272961
|
fetchOptions.signal = AbortSignal.timeout(timeoutMs);
|
|
272907
272962
|
}
|
|
272908
|
-
|
|
272909
|
-
const bodyAsQuery = ["GET", "HEAD"].includes(upperMethod) && Object.keys(finalBody).length > 0;
|
|
272910
|
-
if (Object.keys(resolvedQuery).length > 0 || bodyAsQuery) {
|
|
272911
|
-
const params = new URLSearchParams();
|
|
272912
|
-
const append = (source) => {
|
|
272913
|
-
for (const [k, v] of Object.entries(source)) {
|
|
272914
|
-
if (v === void 0 || v === null)
|
|
272915
|
-
continue;
|
|
272916
|
-
if (Array.isArray(v)) {
|
|
272917
|
-
for (const item of v)
|
|
272918
|
-
params.append(k, typeof item === "object" ? JSON.stringify(item) : String(item));
|
|
272919
|
-
} else {
|
|
272920
|
-
params.append(k, typeof v === "object" ? JSON.stringify(v) : String(v));
|
|
272921
|
-
}
|
|
272922
|
-
}
|
|
272923
|
-
};
|
|
272924
|
-
append(resolvedQuery);
|
|
272925
|
-
if (bodyAsQuery)
|
|
272926
|
-
append(finalBody);
|
|
272927
|
-
const qs = params.toString();
|
|
272928
|
-
if (qs)
|
|
272929
|
-
finalUrl = `${fullUrl}${fullUrl.includes("?") ? "&" : "?"}${qs}`;
|
|
272930
|
-
}
|
|
272931
|
-
const resp = await fetch(finalUrl, fetchOptions);
|
|
272963
|
+
const resp = await fetch(requestUrl, fetchOptions);
|
|
272932
272964
|
responseStatus = resp.status;
|
|
272965
|
+
responseHeaders = Object.fromEntries(resp.headers.entries());
|
|
272933
272966
|
const ct = resp.headers.get("content-type") || "";
|
|
272934
272967
|
if (ct.includes("application/json")) {
|
|
272935
272968
|
try {
|
|
@@ -272946,7 +272979,7 @@ var require_workflow_simulator = __commonJS({
|
|
|
272946
272979
|
break;
|
|
272947
272980
|
} catch (err) {
|
|
272948
272981
|
stepPassed = false;
|
|
272949
|
-
connectionCode =
|
|
272982
|
+
connectionCode = networkErrorCode2(err);
|
|
272950
272983
|
if (err?.name === "TimeoutError" || connectionCode === "ETIMEDOUT") {
|
|
272951
272984
|
errorMsg = `Request timed out after ${timeoutMs}ms (${step.method} ${resolvedPath}).`;
|
|
272952
272985
|
} else if (connectionCode === "ECONNREFUSED") {
|
|
@@ -272964,26 +272997,30 @@ var require_workflow_simulator = __commonJS({
|
|
|
272964
272997
|
method: step.method,
|
|
272965
272998
|
path: step.path,
|
|
272966
272999
|
targetUrl: fullUrl,
|
|
273000
|
+
resolvedUrl: requestUrl,
|
|
272967
273001
|
expectedStatus,
|
|
272968
273002
|
actualStatus: responseStatus,
|
|
272969
273003
|
durationMs: Date.now() - stepStartTime,
|
|
273004
|
+
startedAt: new Date(stepStartTime).toISOString(),
|
|
273005
|
+
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
272970
273006
|
passed: stepPassed,
|
|
272971
273007
|
skipped: false,
|
|
272972
273008
|
retryCount: attempts - 1,
|
|
272973
|
-
requestHeaders:
|
|
273009
|
+
requestHeaders: actualRequestHeaders,
|
|
272974
273010
|
requestBody: finalBody,
|
|
272975
273011
|
...Object.keys(resolvedQuery).length > 0 ? { requestQuery: resolvedQuery } : {},
|
|
272976
273012
|
responseBody,
|
|
273013
|
+
...responseHeaders ? { responseHeaders } : {},
|
|
272977
273014
|
capturedMemory: stepPassed ? [...inputCaptured, ...responseCaptured] : [...inputCaptured],
|
|
272978
273015
|
...stepPassed ? {} : {
|
|
272979
273016
|
failureHandling: onFailure === "continue" ? "continued" : "aborted",
|
|
272980
273017
|
error: errorMsg
|
|
272981
273018
|
}
|
|
272982
273019
|
};
|
|
272983
|
-
|
|
273020
|
+
await record(result);
|
|
272984
273021
|
if (!stepPassed) {
|
|
272985
273022
|
state.allPassed = false;
|
|
272986
|
-
if (connectionCode && CONNECTION_ERROR_CODES.has(connectionCode)) {
|
|
273023
|
+
if (connectionCode && exports2.CONNECTION_ERROR_CODES.has(connectionCode)) {
|
|
272987
273024
|
const remaining = workflow.steps.length - (i + 1);
|
|
272988
273025
|
result.failureHandling = "aborted";
|
|
272989
273026
|
result.error = `${result.error || "Connection failed"}; aborting early because the target is unreachable${remaining > 0 ? ` (${remaining} step(s) not executed)` : ""}.`;
|
|
@@ -273233,39 +273270,39 @@ var require_workflow_simulator = __commonJS({
|
|
|
273233
273270
|
}
|
|
273234
273271
|
return result;
|
|
273235
273272
|
}
|
|
273236
|
-
async runPreflight(baseUrl, timeoutMs) {
|
|
273237
|
-
const probe = { url: baseUrl, verdict: "unreachable", message: "", aborted: false };
|
|
273238
|
-
try {
|
|
273239
|
-
const resp = await fetch(baseUrl, {
|
|
273240
|
-
method: "GET",
|
|
273241
|
-
redirect: "manual",
|
|
273242
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
273243
|
-
});
|
|
273244
|
-
probe.status = resp.status;
|
|
273245
|
-
if (resp.status >= 500) {
|
|
273246
|
-
probe.verdict = "server-error";
|
|
273247
|
-
probe.message = `Server is reachable at ${baseUrl} but responded HTTP ${resp.status} \u2014 the app is likely failing (database/init error). Check the server logs before simulating.`;
|
|
273248
|
-
} else {
|
|
273249
|
-
probe.verdict = "healthy";
|
|
273250
|
-
probe.message = `Server reachable at ${baseUrl} (HTTP ${resp.status}).`;
|
|
273251
|
-
}
|
|
273252
|
-
} catch (err) {
|
|
273253
|
-
const code = networkErrorCode(err);
|
|
273254
|
-
probe.status = void 0;
|
|
273255
|
-
if (err?.name === "TimeoutError" || code === "ETIMEDOUT") {
|
|
273256
|
-
probe.message = `No response from ${baseUrl} within ${timeoutMs}ms \u2014 the server may be down or hanging.`;
|
|
273257
|
-
} else if (code === "ECONNREFUSED") {
|
|
273258
|
-
probe.message = `Connection refused at ${baseUrl} \u2014 nothing is listening there. Start the app (check its PORT/.env) and retry.`;
|
|
273259
|
-
} else if (code === "ENOTFOUND" || code === "EAI_AGAIN") {
|
|
273260
|
-
probe.message = `DNS lookup failed for ${baseUrl}${code ? ` (${code})` : ""} \u2014 check the host name.`;
|
|
273261
|
-
} else {
|
|
273262
|
-
probe.message = `Cannot reach ${baseUrl}${code ? ` (${code})` : ""}: ${err?.message || err}`;
|
|
273263
|
-
}
|
|
273264
|
-
}
|
|
273265
|
-
return probe;
|
|
273266
|
-
}
|
|
273267
273273
|
};
|
|
273268
273274
|
exports2.WorkflowSimulator = WorkflowSimulator2;
|
|
273275
|
+
async function probeTarget2(baseUrl, timeoutMs = 3e3) {
|
|
273276
|
+
const probe = { url: baseUrl, verdict: "unreachable", message: "", aborted: false };
|
|
273277
|
+
try {
|
|
273278
|
+
const resp = await fetch(baseUrl, {
|
|
273279
|
+
method: "GET",
|
|
273280
|
+
redirect: "manual",
|
|
273281
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
273282
|
+
});
|
|
273283
|
+
probe.status = resp.status;
|
|
273284
|
+
if (resp.status >= 500) {
|
|
273285
|
+
probe.verdict = "server-error";
|
|
273286
|
+
probe.message = `Server is reachable at ${baseUrl} but responded HTTP ${resp.status} \u2014 the app is likely failing (database/init error). Check the server logs before simulating.`;
|
|
273287
|
+
} else {
|
|
273288
|
+
probe.verdict = "healthy";
|
|
273289
|
+
probe.message = `Server reachable at ${baseUrl} (HTTP ${resp.status}).`;
|
|
273290
|
+
}
|
|
273291
|
+
} catch (err) {
|
|
273292
|
+
const code = networkErrorCode2(err);
|
|
273293
|
+
probe.status = void 0;
|
|
273294
|
+
if (err?.name === "TimeoutError" || code === "ETIMEDOUT") {
|
|
273295
|
+
probe.message = `No response from ${baseUrl} within ${timeoutMs}ms \u2014 the server may be down or hanging.`;
|
|
273296
|
+
} else if (code === "ECONNREFUSED") {
|
|
273297
|
+
probe.message = `Connection refused at ${baseUrl} \u2014 nothing is listening there. Start the app (check its PORT/.env) and retry.`;
|
|
273298
|
+
} else if (code === "ENOTFOUND" || code === "EAI_AGAIN") {
|
|
273299
|
+
probe.message = `DNS lookup failed for ${baseUrl}${code ? ` (${code})` : ""} \u2014 check the host name.`;
|
|
273300
|
+
} else {
|
|
273301
|
+
probe.message = `Cannot reach ${baseUrl}${code ? ` (${code})` : ""}: ${err?.message || err}`;
|
|
273302
|
+
}
|
|
273303
|
+
}
|
|
273304
|
+
return probe;
|
|
273305
|
+
}
|
|
273269
273306
|
}
|
|
273270
273307
|
});
|
|
273271
273308
|
|
|
@@ -273291,7 +273328,7 @@ var require_dist13 = __commonJS({
|
|
|
273291
273328
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
|
|
273292
273329
|
};
|
|
273293
273330
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
273294
|
-
exports2.WorkflowSimulator = exports2.ResponseValidator = exports2.DataGenerator = exports2.EndpointSimulator = void 0;
|
|
273331
|
+
exports2.CONNECTION_ERROR_CODES = exports2.networkErrorCode = exports2.probeTarget = exports2.WorkflowSimulator = exports2.ResponseValidator = exports2.DataGenerator = exports2.EndpointSimulator = void 0;
|
|
273295
273332
|
var simulator_1 = require_simulator();
|
|
273296
273333
|
Object.defineProperty(exports2, "EndpointSimulator", { enumerable: true, get: function() {
|
|
273297
273334
|
return simulator_1.EndpointSimulator;
|
|
@@ -273308,6 +273345,15 @@ var require_dist13 = __commonJS({
|
|
|
273308
273345
|
Object.defineProperty(exports2, "WorkflowSimulator", { enumerable: true, get: function() {
|
|
273309
273346
|
return workflow_simulator_1.WorkflowSimulator;
|
|
273310
273347
|
} });
|
|
273348
|
+
Object.defineProperty(exports2, "probeTarget", { enumerable: true, get: function() {
|
|
273349
|
+
return workflow_simulator_1.probeTarget;
|
|
273350
|
+
} });
|
|
273351
|
+
Object.defineProperty(exports2, "networkErrorCode", { enumerable: true, get: function() {
|
|
273352
|
+
return workflow_simulator_1.networkErrorCode;
|
|
273353
|
+
} });
|
|
273354
|
+
Object.defineProperty(exports2, "CONNECTION_ERROR_CODES", { enumerable: true, get: function() {
|
|
273355
|
+
return workflow_simulator_1.CONNECTION_ERROR_CODES;
|
|
273356
|
+
} });
|
|
273311
273357
|
__exportStar(require_conditions(), exports2);
|
|
273312
273358
|
}
|
|
273313
273359
|
});
|
|
@@ -273506,14 +273552,19 @@ var require_run_store = __commonJS({
|
|
|
273506
273552
|
};
|
|
273507
273553
|
})();
|
|
273508
273554
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
273555
|
+
exports2.MAX_PERSISTED_BODY_CHARS = void 0;
|
|
273509
273556
|
exports2.newRunId = newRunId;
|
|
273510
273557
|
exports2.runsDir = runsDir;
|
|
273511
273558
|
exports2.runDir = runDir;
|
|
273512
273559
|
exports2.deriveRunStatus = deriveRunStatus;
|
|
273560
|
+
exports2.stepToProgress = stepToProgress;
|
|
273561
|
+
exports2.statsFromSteps = statsFromSteps;
|
|
273562
|
+
exports2.truncateResultForStorage = truncateResultForStorage;
|
|
273513
273563
|
exports2.writeSimulationRun = writeSimulationRun;
|
|
273514
273564
|
exports2.readSimulationRun = readSimulationRun;
|
|
273515
273565
|
exports2.readRunStatus = readRunStatus;
|
|
273516
273566
|
exports2.writeRunningStatus = writeRunningStatus;
|
|
273567
|
+
exports2.updateRunStatus = updateRunStatus;
|
|
273517
273568
|
exports2.writeRunError = writeRunError;
|
|
273518
273569
|
exports2.listRuns = listRuns;
|
|
273519
273570
|
exports2.compactSimulationResult = compactSimulationResult;
|
|
@@ -273542,6 +273593,50 @@ var require_run_store = __commonJS({
|
|
|
273542
273593
|
return "aborted";
|
|
273543
273594
|
return "failed";
|
|
273544
273595
|
}
|
|
273596
|
+
function stepToProgress(r) {
|
|
273597
|
+
return {
|
|
273598
|
+
index: r.stepIndex,
|
|
273599
|
+
name: r.name,
|
|
273600
|
+
method: r.method,
|
|
273601
|
+
path: r.path,
|
|
273602
|
+
status: r.skipped ? "skipped" : r.passed ? "passed" : "failed",
|
|
273603
|
+
expectedStatus: r.expectedStatus,
|
|
273604
|
+
...r.skipped ? {} : { actualStatus: r.actualStatus },
|
|
273605
|
+
passed: r.passed,
|
|
273606
|
+
skipped: r.skipped,
|
|
273607
|
+
...r.retryCount > 0 ? { retryCount: r.retryCount } : {},
|
|
273608
|
+
durationMs: r.durationMs,
|
|
273609
|
+
startedAt: r.startedAt,
|
|
273610
|
+
finishedAt: r.finishedAt,
|
|
273611
|
+
...r.error ? { error: r.error } : {}
|
|
273612
|
+
};
|
|
273613
|
+
}
|
|
273614
|
+
function statsFromSteps(steps) {
|
|
273615
|
+
const completed = steps.filter((s) => s.status !== "pending");
|
|
273616
|
+
return {
|
|
273617
|
+
totalSteps: steps.length,
|
|
273618
|
+
executedSteps: completed.length,
|
|
273619
|
+
passedSteps: completed.filter((s) => s.status === "passed" || s.status === "skipped").length,
|
|
273620
|
+
failedSteps: completed.filter((s) => s.status === "failed").length,
|
|
273621
|
+
skippedSteps: completed.filter((s) => s.status === "skipped").length
|
|
273622
|
+
};
|
|
273623
|
+
}
|
|
273624
|
+
exports2.MAX_PERSISTED_BODY_CHARS = 16384;
|
|
273625
|
+
function truncateResultForStorage(result, maxChars = exports2.MAX_PERSISTED_BODY_CHARS) {
|
|
273626
|
+
const clone = JSON.parse(JSON.stringify(result));
|
|
273627
|
+
for (const step of clone.results) {
|
|
273628
|
+
if (step.responseBody === void 0 || step.responseBody === null)
|
|
273629
|
+
continue;
|
|
273630
|
+
const serialized = typeof step.responseBody === "string" ? step.responseBody : JSON.stringify(step.responseBody);
|
|
273631
|
+
if (serialized.length <= maxChars)
|
|
273632
|
+
continue;
|
|
273633
|
+
const removed = serialized.length - maxChars;
|
|
273634
|
+
step.responseBody = typeof step.responseBody === "string" ? `${step.responseBody.slice(0, maxChars)}
|
|
273635
|
+
\u2026[truncated: ${removed} more characters]` : { _truncated: true, preview: serialized.slice(0, maxChars), fullLengthChars: serialized.length };
|
|
273636
|
+
step.responseBodyTruncated = true;
|
|
273637
|
+
}
|
|
273638
|
+
return clone;
|
|
273639
|
+
}
|
|
273545
273640
|
function writeSimulationRun(jeticDir, runId, result, meta) {
|
|
273546
273641
|
const status = deriveRunStatus(result);
|
|
273547
273642
|
const durationMs = result.stats?.totalTimeMs ?? 0;
|
|
@@ -273556,7 +273651,7 @@ var require_run_store = __commonJS({
|
|
|
273556
273651
|
startedAt: meta.startedAt,
|
|
273557
273652
|
finishedAt: meta.finishedAt,
|
|
273558
273653
|
durationMs,
|
|
273559
|
-
result
|
|
273654
|
+
result: truncateResultForStorage(result)
|
|
273560
273655
|
};
|
|
273561
273656
|
const rPath = reportPath(jeticDir, runId);
|
|
273562
273657
|
(0, core_1.writeJsonSync)(rPath, report);
|
|
@@ -273578,6 +273673,7 @@ var require_run_store = __commonJS({
|
|
|
273578
273673
|
failedSteps: result.stats?.failedSteps ?? 0,
|
|
273579
273674
|
skippedSteps: result.results.filter((r) => r.skipped).length
|
|
273580
273675
|
},
|
|
273676
|
+
steps: result.results.map(stepToProgress),
|
|
273581
273677
|
reportPath: rPath
|
|
273582
273678
|
};
|
|
273583
273679
|
(0, core_1.writeJsonSync)(sPath, statusDoc);
|
|
@@ -273590,6 +273686,13 @@ var require_run_store = __commonJS({
|
|
|
273590
273686
|
return (0, core_1.readJsonSync)(statusPath(jeticDir, runId));
|
|
273591
273687
|
}
|
|
273592
273688
|
function writeRunningStatus(jeticDir, runId, meta) {
|
|
273689
|
+
const steps = meta.steps?.map((s, i) => ({
|
|
273690
|
+
index: i + 1,
|
|
273691
|
+
name: s.name,
|
|
273692
|
+
method: s.method,
|
|
273693
|
+
path: s.path,
|
|
273694
|
+
status: "pending"
|
|
273695
|
+
}));
|
|
273593
273696
|
const doc = {
|
|
273594
273697
|
type: "simulation",
|
|
273595
273698
|
runId,
|
|
@@ -273598,11 +273701,25 @@ var require_run_store = __commonJS({
|
|
|
273598
273701
|
baseUrl: meta.baseUrl,
|
|
273599
273702
|
status: "running",
|
|
273600
273703
|
startedAt: meta.startedAt,
|
|
273601
|
-
stats: {
|
|
273704
|
+
stats: {
|
|
273705
|
+
totalSteps: steps?.length ?? 0,
|
|
273706
|
+
executedSteps: 0,
|
|
273707
|
+
passedSteps: 0,
|
|
273708
|
+
failedSteps: 0,
|
|
273709
|
+
skippedSteps: 0
|
|
273710
|
+
},
|
|
273711
|
+
...steps ? { steps } : {},
|
|
273602
273712
|
reportPath: reportPath(jeticDir, runId)
|
|
273603
273713
|
};
|
|
273604
273714
|
(0, core_1.writeJsonSync)(statusPath(jeticDir, runId), doc);
|
|
273605
273715
|
}
|
|
273716
|
+
function updateRunStatus(jeticDir, runId, update) {
|
|
273717
|
+
const doc = (0, core_1.readJsonSync)(statusPath(jeticDir, runId));
|
|
273718
|
+
if (!doc)
|
|
273719
|
+
return;
|
|
273720
|
+
update(doc);
|
|
273721
|
+
(0, core_1.writeJsonSync)(statusPath(jeticDir, runId), doc);
|
|
273722
|
+
}
|
|
273606
273723
|
function writeRunError(jeticDir, runId, error, meta) {
|
|
273607
273724
|
const doc = {
|
|
273608
273725
|
type: "simulation",
|
|
@@ -273941,11 +274058,17 @@ var require_workflow_tools = __commonJS({
|
|
|
273941
274058
|
const simulator = new simulator_1.WorkflowSimulator(model, effectiveEnv, { projectRoot });
|
|
273942
274059
|
const runId = (0, run_store_1.newRunId)();
|
|
273943
274060
|
const startedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
274061
|
+
const plannedSteps = workflowDef.steps.map((s) => ({
|
|
274062
|
+
name: s.name || `${s.method} ${s.path}`,
|
|
274063
|
+
method: s.method,
|
|
274064
|
+
path: s.path
|
|
274065
|
+
}));
|
|
273944
274066
|
const runMeta = {
|
|
273945
274067
|
workflowName: workflowDef.name || selectedItem.name,
|
|
273946
274068
|
environment: effectiveEnv.name,
|
|
273947
274069
|
baseUrl: effectiveEnv.baseUrl,
|
|
273948
|
-
startedAt
|
|
274070
|
+
startedAt,
|
|
274071
|
+
steps: plannedSteps
|
|
273949
274072
|
};
|
|
273950
274073
|
const execute = async () => {
|
|
273951
274074
|
const result2 = await simulator.simulateWorkflow(workflowDef, {
|
|
@@ -273953,7 +274076,21 @@ var require_workflow_tools = __commonJS({
|
|
|
273953
274076
|
loadWorkflow: (slugOrName) => (0, model_1.loadWorkflowByName)(workflowsDir, slugOrName),
|
|
273954
274077
|
strictTemplates: args.strictTemplates ?? true,
|
|
273955
274078
|
preflight: args.preflight ?? "abort",
|
|
273956
|
-
requestTimeoutMs: args.requestTimeoutMs ?? 3e4
|
|
274079
|
+
requestTimeoutMs: args.requestTimeoutMs ?? 3e4,
|
|
274080
|
+
// Persist per-step progress so jetic_get_run can be polled while the run is in flight.
|
|
274081
|
+
onStepResult: (step) => {
|
|
274082
|
+
(0, run_store_1.updateRunStatus)(jeticDir, runId, (doc) => {
|
|
274083
|
+
if (!doc.steps)
|
|
274084
|
+
doc.steps = [];
|
|
274085
|
+
const progress = (0, run_store_1.stepToProgress)(step);
|
|
274086
|
+
const at = doc.steps.findIndex((s) => s.index === step.stepIndex && s.name === step.name);
|
|
274087
|
+
if (at >= 0)
|
|
274088
|
+
doc.steps[at] = progress;
|
|
274089
|
+
else
|
|
274090
|
+
doc.steps.push(progress);
|
|
274091
|
+
doc.stats = (0, run_store_1.statsFromSteps)(doc.steps);
|
|
274092
|
+
});
|
|
274093
|
+
}
|
|
273957
274094
|
});
|
|
273958
274095
|
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
273959
274096
|
const { reportPath: reportPath2 } = (0, run_store_1.writeSimulationRun)(jeticDir, runId, result2, {
|
|
@@ -289781,8 +289918,13 @@ var require_run_tools = __commonJS({
|
|
|
289781
289918
|
const projectRoot = path15.resolve((0, types_1.resolveProjectInput)(args.projectPath));
|
|
289782
289919
|
const config = (0, core_1.loadConfig)(projectRoot);
|
|
289783
289920
|
const report = (0, run_store_1.readSimulationRun)(config.jeticDir, args.runId);
|
|
289784
|
-
if (report)
|
|
289785
|
-
return {
|
|
289921
|
+
if (report) {
|
|
289922
|
+
return {
|
|
289923
|
+
found: true,
|
|
289924
|
+
...report,
|
|
289925
|
+
steps: report.result?.results ? report.result.results.map(run_store_1.stepToProgress) : []
|
|
289926
|
+
};
|
|
289927
|
+
}
|
|
289786
289928
|
const status = (0, run_store_1.readRunStatus)(config.jeticDir, args.runId);
|
|
289787
289929
|
if (status) {
|
|
289788
289930
|
return {
|
|
@@ -289796,6 +289938,7 @@ var require_run_tools = __commonJS({
|
|
|
289796
289938
|
startedAt: status.startedAt,
|
|
289797
289939
|
finishedAt: status.finishedAt,
|
|
289798
289940
|
stats: status.stats,
|
|
289941
|
+
...status.steps ? { steps: status.steps } : {},
|
|
289799
289942
|
reportPath: status.reportPath,
|
|
289800
289943
|
...status.error ? { error: status.error } : {},
|
|
289801
289944
|
...status.status === "running" ? { message: "Run still in progress \u2014 poll again shortly." } : {}
|
|
@@ -290997,6 +291140,14 @@ function deepGet(obj, dotPath) {
|
|
|
290997
291140
|
}
|
|
290998
291141
|
return current;
|
|
290999
291142
|
}
|
|
291143
|
+
var TRACE_BODY_CAP = 16384;
|
|
291144
|
+
function truncateTraceBody(value) {
|
|
291145
|
+
if (value === void 0 || value === null) return value;
|
|
291146
|
+
const serialized = typeof value === "string" ? value : JSON.stringify(value);
|
|
291147
|
+
if (serialized.length <= TRACE_BODY_CAP) return value;
|
|
291148
|
+
return typeof value === "string" ? `${value.slice(0, TRACE_BODY_CAP)}
|
|
291149
|
+
\u2026[truncated: ${serialized.length - TRACE_BODY_CAP} more characters]` : { _truncated: true, preview: serialized.slice(0, TRACE_BODY_CAP), fullLengthChars: serialized.length };
|
|
291150
|
+
}
|
|
291000
291151
|
async function resolveConditionRef(ref, context = "condition") {
|
|
291001
291152
|
return ref.replace(/\{\{([^}]+)\}\}/g, () => "").trim() === ref.trim() ? ref : await resolveTemplateString(ref, context);
|
|
291002
291153
|
}
|
|
@@ -291006,7 +291157,21 @@ async function evaluateStepCondition(condition, context = "condition") {
|
|
|
291006
291157
|
async function preStepCondition(step) {
|
|
291007
291158
|
if (!step.condition) return null;
|
|
291008
291159
|
const label = step.name || `${step.method} ${step.path}`;
|
|
291009
|
-
const
|
|
291160
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
291161
|
+
const base = {
|
|
291162
|
+
step,
|
|
291163
|
+
status: 0,
|
|
291164
|
+
responseBody: null,
|
|
291165
|
+
durationMs: 0,
|
|
291166
|
+
startedAt: now,
|
|
291167
|
+
finishedAt: now,
|
|
291168
|
+
passed: false,
|
|
291169
|
+
captured: [],
|
|
291170
|
+
injected: {},
|
|
291171
|
+
requestHeaders: {},
|
|
291172
|
+
requestBody: {},
|
|
291173
|
+
resolvedUrl: ""
|
|
291174
|
+
};
|
|
291010
291175
|
const kind = (0, import_simulator2.conditionKind)(step.condition);
|
|
291011
291176
|
if (kind === "invalid") {
|
|
291012
291177
|
return { ...base, passed: false, error: `Step "${label}": ${(0, import_simulator2.describeInvalidCondition)(step.condition)}` };
|
|
@@ -291139,10 +291304,24 @@ async function resolveTemplateString(value, context) {
|
|
|
291139
291304
|
}
|
|
291140
291305
|
return result;
|
|
291141
291306
|
}
|
|
291307
|
+
async function resolveDeepValue(value, context) {
|
|
291308
|
+
if (typeof value === "string") return resolveTemplateString(value, context);
|
|
291309
|
+
if (Array.isArray(value)) {
|
|
291310
|
+
const out = [];
|
|
291311
|
+
for (const item of value) out.push(await resolveDeepValue(item, context));
|
|
291312
|
+
return out;
|
|
291313
|
+
}
|
|
291314
|
+
if (value && typeof value === "object") {
|
|
291315
|
+
const out = {};
|
|
291316
|
+
for (const [key, item] of Object.entries(value)) out[key] = await resolveDeepValue(item, context);
|
|
291317
|
+
return out;
|
|
291318
|
+
}
|
|
291319
|
+
return value;
|
|
291320
|
+
}
|
|
291142
291321
|
async function resolveBodyTemplates(body, context) {
|
|
291143
291322
|
const resolved = {};
|
|
291144
291323
|
for (const [key, value] of Object.entries(body)) {
|
|
291145
|
-
resolved[key] =
|
|
291324
|
+
resolved[key] = await resolveDeepValue(value, context);
|
|
291146
291325
|
}
|
|
291147
291326
|
return resolved;
|
|
291148
291327
|
}
|
|
@@ -291161,6 +291340,10 @@ async function resolveInjections(inject, memory, allMemory, context) {
|
|
|
291161
291340
|
if (value === null) continue;
|
|
291162
291341
|
strValue = typeof value === "string" ? value : JSON.stringify(value);
|
|
291163
291342
|
}
|
|
291343
|
+
const headerName = target.startsWith("header:") ? target.slice(7) : target.startsWith("body:") ? null : target;
|
|
291344
|
+
if (headerName && headerName.toLowerCase() === "authorization" && strValue && !/^[A-Za-z][A-Za-z0-9-]*\s/.test(strValue)) {
|
|
291345
|
+
strValue = `Bearer ${strValue}`;
|
|
291346
|
+
}
|
|
291164
291347
|
if (target.startsWith("body:")) {
|
|
291165
291348
|
body[target.slice(5)] = strValue;
|
|
291166
291349
|
} else if (target.startsWith("header:")) {
|
|
@@ -291203,8 +291386,10 @@ async function resolvePathParams(urlPath, body) {
|
|
|
291203
291386
|
return `:${param}`;
|
|
291204
291387
|
});
|
|
291205
291388
|
}
|
|
291389
|
+
var REQUEST_TIMEOUT_MS = 3e4;
|
|
291206
291390
|
async function executeStep(step, baseUrl, defaultBody) {
|
|
291207
291391
|
const startTime = Date.now();
|
|
291392
|
+
const startedAt = new Date(startTime).toISOString();
|
|
291208
291393
|
const memory = new import_memory2.JeticMemory({ scope: "workflow" });
|
|
291209
291394
|
const stepLabel = step.name || `${step.method} ${step.path}`;
|
|
291210
291395
|
const { headers, body: injectedBody } = await resolveInjections(step.inject, memory, memory, stepLabel);
|
|
@@ -291214,13 +291399,12 @@ async function executeStep(step, baseUrl, defaultBody) {
|
|
|
291214
291399
|
const resolvedPath = await resolvePathParams(step.path, requestBody);
|
|
291215
291400
|
const url = `${baseUrl.replace(/\/$/, "")}${resolvedPath}`;
|
|
291216
291401
|
const expectedStatus = step.expectStatus ?? 200;
|
|
291402
|
+
const requestHeaders = { "Content-Type": "application/json", ...headers };
|
|
291217
291403
|
try {
|
|
291218
291404
|
const fetchOptions = {
|
|
291219
291405
|
method: step.method.toUpperCase(),
|
|
291220
|
-
headers:
|
|
291221
|
-
|
|
291222
|
-
...headers
|
|
291223
|
-
}
|
|
291406
|
+
headers: requestHeaders,
|
|
291407
|
+
signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS)
|
|
291224
291408
|
};
|
|
291225
291409
|
if (!["GET", "HEAD"].includes(step.method.toUpperCase()) && Object.keys(requestBody).length > 0) {
|
|
291226
291410
|
fetchOptions.body = JSON.stringify(requestBody);
|
|
@@ -291253,20 +291437,39 @@ async function executeStep(step, baseUrl, defaultBody) {
|
|
|
291253
291437
|
status: response.status,
|
|
291254
291438
|
responseBody,
|
|
291255
291439
|
durationMs,
|
|
291440
|
+
startedAt,
|
|
291441
|
+
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
291256
291442
|
passed,
|
|
291257
291443
|
captured: [...inputCaptured, ...captured],
|
|
291258
|
-
injected: headers
|
|
291444
|
+
injected: headers,
|
|
291445
|
+
requestHeaders,
|
|
291446
|
+
requestBody,
|
|
291447
|
+
resolvedUrl: finalUrl,
|
|
291448
|
+
responseHeaders: Object.fromEntries(response.headers.entries())
|
|
291259
291449
|
};
|
|
291260
291450
|
} catch (err) {
|
|
291451
|
+
const code = (0, import_simulator2.networkErrorCode)(err);
|
|
291452
|
+
let message = err.message || String(err);
|
|
291453
|
+
if (err?.name === "TimeoutError" || code === "ETIMEDOUT") {
|
|
291454
|
+
message = `Request timed out after ${REQUEST_TIMEOUT_MS}ms (${step.method} ${resolvedPath}).`;
|
|
291455
|
+
} else if (code === "ECONNREFUSED") {
|
|
291456
|
+
message = `Connection refused (ECONNREFUSED) at ${baseUrl} \u2014 the server is not accepting connections.`;
|
|
291457
|
+
}
|
|
291261
291458
|
return {
|
|
291262
291459
|
step,
|
|
291263
291460
|
status: 0,
|
|
291264
291461
|
responseBody: null,
|
|
291265
291462
|
durationMs: Date.now() - startTime,
|
|
291463
|
+
startedAt,
|
|
291464
|
+
finishedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
291266
291465
|
passed: false,
|
|
291267
291466
|
captured: inputCaptured,
|
|
291268
|
-
error:
|
|
291269
|
-
injected: headers
|
|
291467
|
+
error: message,
|
|
291468
|
+
injected: headers,
|
|
291469
|
+
requestHeaders,
|
|
291470
|
+
requestBody,
|
|
291471
|
+
resolvedUrl: url,
|
|
291472
|
+
connectionError: code ? import_simulator2.CONNECTION_ERROR_CODES.has(code) : false
|
|
291270
291473
|
};
|
|
291271
291474
|
}
|
|
291272
291475
|
}
|
|
@@ -291514,17 +291717,23 @@ var simulateWorkflowCommand = new import_commander14.Command("workflow").descrip
|
|
|
291514
291717
|
}
|
|
291515
291718
|
const checkSpinner = new Spinner();
|
|
291516
291719
|
checkSpinner.start(`Checking if backend is active at ${baseUrl}...`);
|
|
291517
|
-
|
|
291518
|
-
|
|
291519
|
-
checkSpinner.stop(` ${c.green}\u2713${c.reset} Backend is active`);
|
|
291520
|
-
console.log("");
|
|
291521
|
-
} catch (e) {
|
|
291720
|
+
const probe = await (0, import_simulator2.probeTarget)(baseUrl, 3e3);
|
|
291721
|
+
if (probe.verdict === "unreachable") {
|
|
291522
291722
|
checkSpinner.stop();
|
|
291523
291723
|
console.log(` ${c.red}\u2717${c.reset} Backend is unreachable at ${c.bold}${baseUrl}${c.reset}`);
|
|
291524
|
-
console.log(` ${c.
|
|
291724
|
+
console.log(` ${c.red}${probe.message}${c.reset}`);
|
|
291725
|
+
console.log(` ${c.yellow}\u26A0${c.reset} Start your backend project and try again.
|
|
291525
291726
|
`);
|
|
291526
291727
|
process.exit(1);
|
|
291527
291728
|
}
|
|
291729
|
+
if (probe.verdict === "server-error") {
|
|
291730
|
+
checkSpinner.stop(` ${c.yellow}\u26A0${c.reset} Backend reachable but failing (HTTP ${probe.status}) at ${baseUrl}`);
|
|
291731
|
+
console.log(` ${c.yellow}${probe.message}${c.reset}
|
|
291732
|
+
`);
|
|
291733
|
+
} else {
|
|
291734
|
+
checkSpinner.stop(` ${c.green}\u2713${c.reset} Backend is active (HTTP ${probe.status})`);
|
|
291735
|
+
console.log("");
|
|
291736
|
+
}
|
|
291528
291737
|
renderWorkflowHeader(workflow);
|
|
291529
291738
|
console.log(` ${c.magenta}\u{1F680}${c.reset} Executing workflow steps...
|
|
291530
291739
|
`);
|
|
@@ -291638,6 +291847,12 @@ var simulateWorkflowCommand = new import_commander14.Command("workflow").descrip
|
|
|
291638
291847
|
const icon = result.skipped ? SKIP : result.passed ? TICK : CROSS;
|
|
291639
291848
|
spinner.stop(` ${icon} ${stepLabel} ${formatStatus(result.status)} ${c.dim}${result.durationMs}ms${c.reset}`);
|
|
291640
291849
|
renderStepResult(result, i, workflow.steps.length);
|
|
291850
|
+
if (result.connectionError) {
|
|
291851
|
+
console.log(` ${c.red}${c.bold}\u26A0 Target unreachable \u2014 aborting early.${c.reset}
|
|
291852
|
+
`);
|
|
291853
|
+
stopOnFailure = true;
|
|
291854
|
+
break;
|
|
291855
|
+
}
|
|
291641
291856
|
if (!result.passed && result.error && !result.status && (0, import_simulator2.conditionKind)(step.condition) === "invalid") {
|
|
291642
291857
|
console.log(` ${c.red}${c.bold}\u26A0 Unrecognized condition \u2014 stopping workflow.${c.reset}
|
|
291643
291858
|
`);
|
|
@@ -291690,12 +291905,19 @@ var simulateWorkflowCommand = new import_commander14.Command("workflow").descrip
|
|
|
291690
291905
|
path: r.step?.path,
|
|
291691
291906
|
description: r.step?.description,
|
|
291692
291907
|
status: r.status,
|
|
291908
|
+
responseStatus: r.status,
|
|
291693
291909
|
passed: r.passed,
|
|
291694
291910
|
durationMs: r.durationMs,
|
|
291911
|
+
startedAt: r.startedAt,
|
|
291912
|
+
finishedAt: r.finishedAt,
|
|
291913
|
+
resolvedUrl: r.resolvedUrl,
|
|
291914
|
+
requestHeaders: r.requestHeaders,
|
|
291915
|
+
requestBody: r.requestBody,
|
|
291916
|
+
requestBodySpec: r.step?.body,
|
|
291917
|
+
responseHeaders: r.responseHeaders,
|
|
291918
|
+
responseBody: truncateTraceBody(r.responseBody),
|
|
291695
291919
|
captured: Object.fromEntries((r.captured ?? []).map((cap) => [cap, "(captured)"])),
|
|
291696
291920
|
injected: r.injected ?? {},
|
|
291697
|
-
requestBody: r.step?.body,
|
|
291698
|
-
responseBody: r.responseBody,
|
|
291699
291921
|
error: r.error ?? null,
|
|
291700
291922
|
expectStatus: r.step?.expectStatus,
|
|
291701
291923
|
captureSpec: r.step?.capture,
|
|
@@ -293321,7 +293543,7 @@ var mcpCommand = new import_commander18.Command("mcp").description("Launch Model
|
|
|
293321
293543
|
|
|
293322
293544
|
// src/index.ts
|
|
293323
293545
|
var program = new import_commander19.Command();
|
|
293324
|
-
program.name("jetic").description("AI-Native API Behavior Testing").version("0.2.
|
|
293546
|
+
program.name("jetic").description("AI-Native API Behavior Testing").version("0.2.7");
|
|
293325
293547
|
program.addCommand(initCommand);
|
|
293326
293548
|
program.addCommand(scanCommand);
|
|
293327
293549
|
program.addCommand(inspectCommand);
|