@requesto/cli 1.13.1 → 1.14.0
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.mjs +178 -37
- package/package.json +3 -3
package/dist/index.mjs
CHANGED
|
@@ -106618,6 +106618,7 @@ var require_proxy_service = __commonJS({
|
|
|
106618
106618
|
validateStatus: () => true,
|
|
106619
106619
|
timeout: opts.timeout ?? 3e4,
|
|
106620
106620
|
responseType: "arraybuffer",
|
|
106621
|
+
...opts.signal && { signal: opts.signal },
|
|
106621
106622
|
...httpsAgent && { httpsAgent }
|
|
106622
106623
|
};
|
|
106623
106624
|
const axiosAuth = (0, auth_1.getAxiosAuthConfig)(substitutedAuth);
|
|
@@ -134532,6 +134533,9 @@ function escapeXml(text) {
|
|
|
134532
134533
|
function seconds(ms) {
|
|
134533
134534
|
return ((ms ?? 0) / 1e3).toFixed(3);
|
|
134534
134535
|
}
|
|
134536
|
+
function skippedTestcaseCount(results) {
|
|
134537
|
+
return results.filter((r2) => r2.status === "skipped" || r2.status === "warned").length;
|
|
134538
|
+
}
|
|
134535
134539
|
function testcase(result, indent2) {
|
|
134536
134540
|
const classname = escapeXml(result.collectionName);
|
|
134537
134541
|
const lines = [];
|
|
@@ -134553,6 +134557,15 @@ function testcase(result, indent2) {
|
|
|
134553
134557
|
);
|
|
134554
134558
|
return lines;
|
|
134555
134559
|
}
|
|
134560
|
+
if (result.status === "warned") {
|
|
134561
|
+
const message = result.warning ?? "Warning";
|
|
134562
|
+
lines.push(
|
|
134563
|
+
`${indent2}<testcase name="${escapeXml(`Request: ${result.request.name}`)}" classname="${classname}" time="${seconds(result.duration)}">`,
|
|
134564
|
+
`${indent2} <skipped message="${escapeXml(message)}"/>`,
|
|
134565
|
+
`${indent2}</testcase>`
|
|
134566
|
+
);
|
|
134567
|
+
return lines;
|
|
134568
|
+
}
|
|
134556
134569
|
if (result.testResults.length === 0) {
|
|
134557
134570
|
lines.push(
|
|
134558
134571
|
`${indent2}<testcase name="Request: ${escapeXml(result.request.name)}" classname="${classname}" time="${seconds(result.duration)}"/>`
|
|
@@ -134594,7 +134607,7 @@ function buildJunitReport(summary) {
|
|
|
134594
134607
|
const time = seconds(results.reduce((acc, r2) => acc + (r2.duration ?? 0), 0));
|
|
134595
134608
|
suites.push(
|
|
134596
134609
|
[
|
|
134597
|
-
` <testsuite name="${escapeXml(collectionName)}" tests="${tests}" failures="${failures}" errors="${errors}" time="${time}">`,
|
|
134610
|
+
` <testsuite name="${escapeXml(collectionName)}" tests="${tests}" failures="${failures}" errors="${errors}" skipped="${skippedTestcaseCount(results)}" time="${time}">`,
|
|
134598
134611
|
...results.flatMap((r2) => testcase(r2, " ")),
|
|
134599
134612
|
` </testsuite>`
|
|
134600
134613
|
].join("\n")
|
|
@@ -134611,7 +134624,7 @@ function buildJunitReport(summary) {
|
|
|
134611
134624
|
const totalErrors = summary.results.filter((r2) => r2.status === "error").length;
|
|
134612
134625
|
return [
|
|
134613
134626
|
`<?xml version="1.0" encoding="UTF-8"?>`,
|
|
134614
|
-
`<testsuites name="requesto" tests="${totalTests}" failures="${totalFailures}" errors="${totalErrors}" time="${seconds(summary.totalDuration)}">`,
|
|
134627
|
+
`<testsuites name="requesto" tests="${totalTests}" failures="${totalFailures}" errors="${totalErrors}" skipped="${skippedTestcaseCount(summary.results)}" time="${seconds(summary.totalDuration)}">`,
|
|
134615
134628
|
...suites,
|
|
134616
134629
|
`</testsuites>`,
|
|
134617
134630
|
``
|
|
@@ -134627,6 +134640,7 @@ function buildJsonReport(summary) {
|
|
|
134627
134640
|
passed: summary.passed,
|
|
134628
134641
|
failed: summary.failed,
|
|
134629
134642
|
errored: summary.errored,
|
|
134643
|
+
warned: summary.warned,
|
|
134630
134644
|
skipped: summary.skipped
|
|
134631
134645
|
},
|
|
134632
134646
|
tests: {
|
|
@@ -134648,6 +134662,8 @@ function buildJsonReport(summary) {
|
|
|
134648
134662
|
httpStatus: result.response?.status ?? null,
|
|
134649
134663
|
durationMs: result.duration ?? null,
|
|
134650
134664
|
error: result.error ?? null,
|
|
134665
|
+
warning: result.warning ?? null,
|
|
134666
|
+
warningKind: result.warningKind ?? null,
|
|
134651
134667
|
tests: result.testResults.map((test) => ({
|
|
134652
134668
|
name: test.name,
|
|
134653
134669
|
passed: test.passed,
|
|
@@ -134676,6 +134692,8 @@ function statusIcon(result, paint) {
|
|
|
134676
134692
|
return paint.green("\u2713");
|
|
134677
134693
|
case "failed":
|
|
134678
134694
|
return paint.red("\u2717");
|
|
134695
|
+
case "warned":
|
|
134696
|
+
return paint.yellow("\u26A0");
|
|
134679
134697
|
case "error":
|
|
134680
134698
|
return paint.yellow("\u2717");
|
|
134681
134699
|
case "skipped":
|
|
@@ -134688,6 +134706,8 @@ function dotChar(result, paint) {
|
|
|
134688
134706
|
return paint.green("\xB7");
|
|
134689
134707
|
case "failed":
|
|
134690
134708
|
return paint.red("\xD7");
|
|
134709
|
+
case "warned":
|
|
134710
|
+
return paint.yellow("!");
|
|
134691
134711
|
case "error":
|
|
134692
134712
|
return paint.yellow("\xD7");
|
|
134693
134713
|
case "skipped":
|
|
@@ -134732,6 +134752,10 @@ function createConsoleReporter(mode, stream = process.stdout) {
|
|
|
134732
134752
|
const writeRequestLine = (result) => {
|
|
134733
134753
|
stream.write(` ${statusIcon(result, paint)} ${result.request.name}${paint.dim(durationTail(result))}
|
|
134734
134754
|
`);
|
|
134755
|
+
if (result.status === "warned" && result.warning) {
|
|
134756
|
+
stream.write(paint.yellow(` \u26A0 ${result.warning}
|
|
134757
|
+
`));
|
|
134758
|
+
}
|
|
134735
134759
|
};
|
|
134736
134760
|
const failureEntries = (summary) => summary.results.filter((r2) => r2.status === "failed" || r2.status === "error").map((r2) => ({
|
|
134737
134761
|
label: `${r2.collectionName} > ${r2.request.name}`,
|
|
@@ -134753,10 +134777,11 @@ function createConsoleReporter(mode, stream = process.stdout) {
|
|
|
134753
134777
|
}
|
|
134754
134778
|
};
|
|
134755
134779
|
const writeSummary = (summary, meta) => {
|
|
134756
|
-
const failed = summary.failed + summary.errored;
|
|
134757
134780
|
const counts = [
|
|
134758
134781
|
summary.passed > 0 ? paint.green(`${summary.passed} passed`) : null,
|
|
134759
|
-
failed > 0 ? paint.red(`${failed} failed`) : null,
|
|
134782
|
+
summary.failed > 0 ? paint.red(`${summary.failed} failed`) : null,
|
|
134783
|
+
summary.errored > 0 ? paint.yellow(`${summary.errored} errored`) : null,
|
|
134784
|
+
summary.warned > 0 ? paint.yellow(`${summary.warned} warnings`) : null,
|
|
134760
134785
|
summary.skipped > 0 ? paint.dim(`${summary.skipped} skipped`) : null
|
|
134761
134786
|
].filter(Boolean);
|
|
134762
134787
|
stream.write("\n");
|
|
@@ -134894,16 +134919,12 @@ function buildSavedGraphQLRequest(req) {
|
|
|
134894
134919
|
if (operation.operation !== "query") {
|
|
134895
134920
|
throw new Error("GraphQL GET requests can only execute query operations");
|
|
134896
134921
|
}
|
|
134897
|
-
|
|
134898
|
-
|
|
134899
|
-
|
|
134900
|
-
|
|
134901
|
-
|
|
134902
|
-
|
|
134903
|
-
params.set("query", document2);
|
|
134904
|
-
if (variables)
|
|
134905
|
-
params.set("variables", JSON.stringify(variables));
|
|
134906
|
-
return { method: "GET", url: `${path6}?${params}${hash}`, headers, auth: req.auth };
|
|
134922
|
+
return {
|
|
134923
|
+
method: "GET",
|
|
134924
|
+
url: encodeGraphQLGetUrl(req.url, document2, variables),
|
|
134925
|
+
headers,
|
|
134926
|
+
auth: req.auth
|
|
134927
|
+
};
|
|
134907
134928
|
}
|
|
134908
134929
|
setDefaultHeader(headers, "Content-Type", "application/json");
|
|
134909
134930
|
const body = {
|
|
@@ -134919,6 +134940,18 @@ function buildSavedGraphQLRequest(req) {
|
|
|
134919
134940
|
auth: req.auth
|
|
134920
134941
|
};
|
|
134921
134942
|
}
|
|
134943
|
+
function encodeGraphQLGetUrl(base, document2, variables) {
|
|
134944
|
+
const hashIndex = base.indexOf("#");
|
|
134945
|
+
const withoutHash = hashIndex < 0 ? base : base.slice(0, hashIndex);
|
|
134946
|
+
const hash = hashIndex < 0 ? "" : base.slice(hashIndex);
|
|
134947
|
+
const queryIndex = withoutHash.indexOf("?");
|
|
134948
|
+
const path6 = queryIndex < 0 ? withoutHash : withoutHash.slice(0, queryIndex);
|
|
134949
|
+
const params = new URLSearchParams(queryIndex < 0 ? "" : withoutHash.slice(queryIndex + 1));
|
|
134950
|
+
params.set("query", document2);
|
|
134951
|
+
if (variables)
|
|
134952
|
+
params.set("variables", JSON.stringify(variables));
|
|
134953
|
+
return `${path6}?${params}${hash}`;
|
|
134954
|
+
}
|
|
134922
134955
|
function buildProxyRequest(req, insecureTls) {
|
|
134923
134956
|
if (req.requestType === "graphql") {
|
|
134924
134957
|
return { ...buildSavedGraphQLRequest(req), insecureTls };
|
|
@@ -134935,6 +134968,31 @@ function buildProxyRequest(req, insecureTls) {
|
|
|
134935
134968
|
};
|
|
134936
134969
|
}
|
|
134937
134970
|
|
|
134971
|
+
// ../../packages/engine/dist/request/graphql-envelope.js
|
|
134972
|
+
function getGraphQLResponseInfo(response) {
|
|
134973
|
+
if (response.bodyEncoding !== "utf8")
|
|
134974
|
+
return null;
|
|
134975
|
+
try {
|
|
134976
|
+
const payload = JSON.parse(response.body);
|
|
134977
|
+
if (typeof payload !== "object" || payload === null || Array.isArray(payload))
|
|
134978
|
+
return null;
|
|
134979
|
+
const envelope = payload;
|
|
134980
|
+
if (!Array.isArray(envelope.errors))
|
|
134981
|
+
return null;
|
|
134982
|
+
const errors = envelope.errors.filter((error) => typeof error === "object" && error !== null).map((error) => ({
|
|
134983
|
+
message: typeof error.message === "string" ? error.message : "Unknown GraphQL error",
|
|
134984
|
+
...Array.isArray(error.path) && { path: error.path },
|
|
134985
|
+
...Array.isArray(error.locations) && {
|
|
134986
|
+
locations: error.locations.filter((location2) => typeof location2 === "object" && location2 !== null && typeof location2.line === "number" && typeof location2.column === "number")
|
|
134987
|
+
}
|
|
134988
|
+
}));
|
|
134989
|
+
const hasData = Object.prototype.hasOwnProperty.call(envelope, "data") && envelope.data !== null;
|
|
134990
|
+
return { errors, hasData, isPartial: hasData && errors.length > 0 };
|
|
134991
|
+
} catch {
|
|
134992
|
+
return null;
|
|
134993
|
+
}
|
|
134994
|
+
}
|
|
134995
|
+
|
|
134938
134996
|
// ../../packages/engine/dist/runner/display.js
|
|
134939
134997
|
function buildCollectionItems(collection, folderIds) {
|
|
134940
134998
|
const items = [];
|
|
@@ -135002,6 +135060,31 @@ function applyEnvOverrides(env2, overrides) {
|
|
|
135002
135060
|
}
|
|
135003
135061
|
return { ...env2, variables };
|
|
135004
135062
|
}
|
|
135063
|
+
function resolveStatus(allTestsPassed, testCount, response, warnings) {
|
|
135064
|
+
if (!allTestsPassed)
|
|
135065
|
+
return { status: "failed" };
|
|
135066
|
+
const warningsEnabled = warnings?.httpErrorStatuses !== false;
|
|
135067
|
+
const hasTests = testCount > 0;
|
|
135068
|
+
if (warningsEnabled && !hasTests) {
|
|
135069
|
+
if (response.status >= 400) {
|
|
135070
|
+
const statusText = response.statusText?.trim();
|
|
135071
|
+
return {
|
|
135072
|
+
status: "warned",
|
|
135073
|
+
warning: statusText ? `HTTP ${response.status} ${statusText}` : `HTTP ${response.status}`,
|
|
135074
|
+
warningKind: "http-status"
|
|
135075
|
+
};
|
|
135076
|
+
}
|
|
135077
|
+
const graphqlInfo = getGraphQLResponseInfo(response);
|
|
135078
|
+
if (graphqlInfo && graphqlInfo.errors.length > 0) {
|
|
135079
|
+
return {
|
|
135080
|
+
status: "warned",
|
|
135081
|
+
warning: graphqlInfo.errors[0].message,
|
|
135082
|
+
warningKind: "graphql-errors"
|
|
135083
|
+
};
|
|
135084
|
+
}
|
|
135085
|
+
}
|
|
135086
|
+
return { status: "passed" };
|
|
135087
|
+
}
|
|
135005
135088
|
async function runCollections(opts) {
|
|
135006
135089
|
const results = [];
|
|
135007
135090
|
const started = Date.now();
|
|
@@ -135085,8 +135168,16 @@ async function runCollections(opts) {
|
|
|
135085
135168
|
liveEnv = applyEnvOverrides(liveEnv, outcome);
|
|
135086
135169
|
}
|
|
135087
135170
|
const allPassed = testResults.every((t2) => t2.passed);
|
|
135088
|
-
const status = allPassed
|
|
135089
|
-
const result = {
|
|
135171
|
+
const { status, warning, warningKind } = resolveStatus(allPassed, testResults.length, response, opts.warnings);
|
|
135172
|
+
const result = {
|
|
135173
|
+
...base,
|
|
135174
|
+
status,
|
|
135175
|
+
response,
|
|
135176
|
+
testResults,
|
|
135177
|
+
...warning !== void 0 && { warning },
|
|
135178
|
+
...warningKind !== void 0 && { warningKind },
|
|
135179
|
+
duration: response.duration
|
|
135180
|
+
};
|
|
135090
135181
|
results.push(result);
|
|
135091
135182
|
opts.onEvent?.({ type: "request-end", result });
|
|
135092
135183
|
if (!allPassed && opts.bail)
|
|
@@ -135113,6 +135204,7 @@ async function runCollections(opts) {
|
|
|
135113
135204
|
passed: results.filter((r2) => r2.status === "passed").length,
|
|
135114
135205
|
failed: results.filter((r2) => r2.status === "failed").length,
|
|
135115
135206
|
errored: results.filter((r2) => r2.status === "error").length,
|
|
135207
|
+
warned: results.filter((r2) => r2.status === "warned").length,
|
|
135116
135208
|
skipped: results.filter((r2) => r2.status === "skipped").length,
|
|
135117
135209
|
totalTests: results.reduce((acc, r2) => acc + r2.testResults.length, 0),
|
|
135118
135210
|
passedTests: results.reduce((acc, r2) => acc + r2.testResults.filter((t2) => t2.passed).length, 0),
|
|
@@ -135573,7 +135665,11 @@ var CliWorkspace = class {
|
|
|
135573
135665
|
available ? `Environment "${selector}" not found. Available: ${available} (or "none").` : `Environment "${selector}" not found: this workspace has no environments (use "none" or define one).`
|
|
135574
135666
|
);
|
|
135575
135667
|
}
|
|
135576
|
-
/**
|
|
135668
|
+
/**
|
|
135669
|
+
* Send a request through the backend engine with the given per-run options.
|
|
135670
|
+
* The runner-provided abort signal is forwarded so an interrupted run can
|
|
135671
|
+
* cancel the in-flight HTTP request instead of waiting for its timeout.
|
|
135672
|
+
*/
|
|
135577
135673
|
sendRequest(request, opts) {
|
|
135578
135674
|
return this.proxyService.executeRequest(request, {
|
|
135579
135675
|
// The CLI substitutes variables itself against the live environment,
|
|
@@ -135581,6 +135677,7 @@ var CliWorkspace = class {
|
|
|
135581
135677
|
environment: null,
|
|
135582
135678
|
oauthResolver: opts.oauthResolver,
|
|
135583
135679
|
timeout: opts.timeout,
|
|
135680
|
+
signal: opts.signal,
|
|
135584
135681
|
saveHistory: false
|
|
135585
135682
|
});
|
|
135586
135683
|
}
|
|
@@ -135607,6 +135704,34 @@ function resolveWorkspacePath(input) {
|
|
|
135607
135704
|
|
|
135608
135705
|
// src/commands/run.ts
|
|
135609
135706
|
var BUILTIN_SERVER_VAR = "requestoServerUrl";
|
|
135707
|
+
function wireAbortSignal(opts) {
|
|
135708
|
+
const controller = new AbortController();
|
|
135709
|
+
const externalSignal = opts.signal ?? null;
|
|
135710
|
+
let interrupts = 0;
|
|
135711
|
+
const handleInterrupt = () => {
|
|
135712
|
+
interrupts += 1;
|
|
135713
|
+
if (interrupts > 1) {
|
|
135714
|
+
process.stderr.write("\nForcing exit (second interrupt).\n");
|
|
135715
|
+
process.exit(130);
|
|
135716
|
+
}
|
|
135717
|
+
controller.abort();
|
|
135718
|
+
process.stderr.write(
|
|
135719
|
+
"\nInterrupted: cancelling the in-flight request and skipping the rest of the run. Press Ctrl-C again to force exit.\n"
|
|
135720
|
+
);
|
|
135721
|
+
};
|
|
135722
|
+
const handleExternalAbort = () => {
|
|
135723
|
+
controller.abort(externalSignal?.reason);
|
|
135724
|
+
};
|
|
135725
|
+
process.on("SIGINT", handleInterrupt);
|
|
135726
|
+
externalSignal?.addEventListener("abort", handleExternalAbort);
|
|
135727
|
+
return {
|
|
135728
|
+
signal: controller.signal,
|
|
135729
|
+
dispose: () => {
|
|
135730
|
+
process.off("SIGINT", handleInterrupt);
|
|
135731
|
+
externalSignal?.removeEventListener("abort", handleExternalAbort);
|
|
135732
|
+
}
|
|
135733
|
+
};
|
|
135734
|
+
}
|
|
135610
135735
|
async function runCommand(opts) {
|
|
135611
135736
|
const started = Date.now();
|
|
135612
135737
|
const workspacePath = resolveWorkspacePath(opts.path);
|
|
@@ -135658,6 +135783,7 @@ async function runCommand(opts) {
|
|
|
135658
135783
|
serverUrl = embedded.url;
|
|
135659
135784
|
}
|
|
135660
135785
|
const runEnv = withBuiltinServerVar(effectiveEnv, serverUrl);
|
|
135786
|
+
const abort = wireAbortSignal(opts);
|
|
135661
135787
|
try {
|
|
135662
135788
|
const summary = await runCollections({
|
|
135663
135789
|
collections,
|
|
@@ -135670,6 +135796,8 @@ async function runCommand(opts) {
|
|
|
135670
135796
|
bail: opts.bail,
|
|
135671
135797
|
insecure: opts.insecure,
|
|
135672
135798
|
timeout: opts.timeout,
|
|
135799
|
+
signal: abort.signal,
|
|
135800
|
+
warnings: { httpErrorStatuses: !opts.noWarnHttpErrors },
|
|
135673
135801
|
onEvent: opts.onEvent
|
|
135674
135802
|
});
|
|
135675
135803
|
return {
|
|
@@ -135679,6 +135807,7 @@ async function runCommand(opts) {
|
|
|
135679
135807
|
serverUrl
|
|
135680
135808
|
};
|
|
135681
135809
|
} finally {
|
|
135810
|
+
abort.dispose();
|
|
135682
135811
|
if (embedded) {
|
|
135683
135812
|
try {
|
|
135684
135813
|
await embedded.stop();
|
|
@@ -135697,8 +135826,9 @@ async function runCommand(opts) {
|
|
|
135697
135826
|
}
|
|
135698
135827
|
}
|
|
135699
135828
|
}
|
|
135700
|
-
function computeExitCode(summary) {
|
|
135701
|
-
|
|
135829
|
+
function computeExitCode(summary, opts = {}) {
|
|
135830
|
+
const failing = summary.failed + summary.errored + (opts.failOnWarn ? summary.warned : 0);
|
|
135831
|
+
return failing > 0 ? 1 : 0;
|
|
135702
135832
|
}
|
|
135703
135833
|
function referencesBuiltin(env2) {
|
|
135704
135834
|
if (!env2) return false;
|
|
@@ -135780,6 +135910,26 @@ function writeFileReports(specs, result) {
|
|
|
135780
135910
|
`);
|
|
135781
135911
|
}
|
|
135782
135912
|
}
|
|
135913
|
+
function collectRunOptions(pathArg, opts) {
|
|
135914
|
+
return {
|
|
135915
|
+
path: pathArg,
|
|
135916
|
+
collections: opts.collection,
|
|
135917
|
+
excludeCollections: opts.excludeCollection,
|
|
135918
|
+
folders: opts.folder,
|
|
135919
|
+
environment: opts.environment,
|
|
135920
|
+
vars: opts.var,
|
|
135921
|
+
varFile: opts.varFile,
|
|
135922
|
+
tokens: opts.token,
|
|
135923
|
+
oauthSecrets: opts.oauthSecret,
|
|
135924
|
+
refreshTokens: opts.refreshToken,
|
|
135925
|
+
bail: opts.bail,
|
|
135926
|
+
insecure: opts.insecure,
|
|
135927
|
+
timeout: opts.timeout,
|
|
135928
|
+
persist: opts.persist,
|
|
135929
|
+
server: opts.server,
|
|
135930
|
+
noWarnHttpErrors: opts.warnHttpErrors === false
|
|
135931
|
+
};
|
|
135932
|
+
}
|
|
135783
135933
|
async function runCli(argv) {
|
|
135784
135934
|
const program2 = new Command();
|
|
135785
135935
|
program2.exitOverride();
|
|
@@ -135795,31 +135945,22 @@ The run never touches your workspace or any server data: collections targeting t
|
|
|
135795
135945
|
{{${BUILTIN_SERVER_VAR}}} variable run against an ephemeral scratch server that the CLI
|
|
135796
135946
|
boots and tears down itself. Use --server to test a deployed server instead.
|
|
135797
135947
|
|
|
135798
|
-
Exit codes: 0 = all passed, 1 = failures/errors, 2 = configuration error
|
|
135948
|
+
Exit codes: 0 = all passed, 1 = failures/errors, 2 = configuration error.
|
|
135949
|
+
|
|
135950
|
+
4xx/5xx responses with no test assertions land as warnings: they print as \u26A0 and
|
|
135951
|
+
never affect the exit code unless --fail-on-warn is given. Ctrl-C cancels the
|
|
135952
|
+
in-flight request and skips the rest; press again to exit immediately.`
|
|
135799
135953
|
).argument("[path]", "repository or .requesto directory", process.cwd()).option("-c, --collection <name>", "collection to run (name or id, repeatable; default: all)", collect, []).option("-C, --exclude-collection <name>", "collection to skip (name or id, repeatable; subtracts from the selection)", collect, []).option("-f, --folder <name>", "folder to run within the selected collections (name or id, repeatable)", collect, []).option("-e, --environment <name>", 'environment (name or id, or "none"; default: active environment)').option("--var <key=value>", "variable override (repeatable; highest precedence)", collect, []).option("--var-file <path>", ".env file providing variable overrides").option("--token <configId=accessToken>", "access token for an OAuth config, e.g. --token my-entra=eyJ... (repeatable; REQUESTO_TOKEN_* env vars work too)", collect, []).option("--oauth-secret <configId=secret>", "client secret for a non-interactive OAuth config (repeatable; REQUESTO_OAUTH_SECRET_* env vars work too)", collect, []).option("--refresh-token <configId=token>", "refresh token to seed for an OAuth config (repeatable; REQUESTO_REFRESH_TOKEN_* env vars work too)", collect, []).option("-x, --bail", "stop the run after the first failed or errored request", false).option("--insecure", "skip TLS certificate verification (self-signed certs)", false).option("--timeout <ms>", "per-request timeout in ms (default 30000)", (v) => {
|
|
135800
135954
|
const n = Number(v);
|
|
135801
135955
|
if (!Number.isFinite(n) || n <= 0) throw new CliError(`Invalid --timeout value "${v}"`);
|
|
135802
135956
|
return n;
|
|
135803
|
-
}).option("--persist", "persist OAuth tokens acquired during the run to .requesto/local/ (default: memory only)", false).option("--server <url>", "test a deployed Requesto server instead of the embedded scratch server (its active workspace is protected by a scratch workspace)").option("--reporter <spec>", "reporter: console, verbose, dot, junit:<path> or json:<path> (repeatable; default: console)", collect, []).action(async (pathArg, opts) => {
|
|
135957
|
+
}).option("--persist", "persist OAuth tokens acquired during the run to .requesto/local/ (default: memory only)", false).option("--server <url>", "test a deployed Requesto server instead of the embedded scratch server (its active workspace is protected by a scratch workspace)").option("--no-warn-http-errors", "disable warn-tier results for 4xx/5xx responses with no test assertions (default: warns are on)").option("--fail-on-warn", "exit 1 when any request is warned (default: warns never affect the exit code)", false).option("--reporter <spec>", "reporter: console, verbose, dot, junit:<path> or json:<path> (repeatable; default: console)", collect, []).action(async (pathArg, opts) => {
|
|
135804
135958
|
const specs = opts.reporter.map(parseReporterSpec);
|
|
135805
135959
|
const consoleMode = findConsoleMode(specs);
|
|
135806
135960
|
const consoleReporter = createConsoleReporter(consoleMode);
|
|
135961
|
+
const runOptions = collectRunOptions(pathArg, opts);
|
|
135807
135962
|
const result = await runCommand({
|
|
135808
|
-
|
|
135809
|
-
collections: opts.collection,
|
|
135810
|
-
excludeCollections: opts.excludeCollection,
|
|
135811
|
-
folders: opts.folder,
|
|
135812
|
-
environment: opts.environment,
|
|
135813
|
-
vars: opts.var,
|
|
135814
|
-
varFile: opts.varFile,
|
|
135815
|
-
tokens: opts.token,
|
|
135816
|
-
oauthSecrets: opts.oauthSecret,
|
|
135817
|
-
refreshTokens: opts.refreshToken,
|
|
135818
|
-
bail: opts.bail,
|
|
135819
|
-
insecure: opts.insecure,
|
|
135820
|
-
timeout: opts.timeout,
|
|
135821
|
-
persist: opts.persist,
|
|
135822
|
-
server: opts.server,
|
|
135963
|
+
...runOptions,
|
|
135823
135964
|
onEvent: (event) => consoleReporter.onEvent(event)
|
|
135824
135965
|
});
|
|
135825
135966
|
consoleReporter.finish(result.summary, {
|
|
@@ -135828,7 +135969,7 @@ Exit codes: 0 = all passed, 1 = failures/errors, 2 = configuration error.`
|
|
|
135828
135969
|
serverUrl: result.serverUrl
|
|
135829
135970
|
});
|
|
135830
135971
|
writeFileReports(specs, result);
|
|
135831
|
-
exitCode = computeExitCode(result.summary);
|
|
135972
|
+
exitCode = computeExitCode(result.summary, { failOnWarn: opts.failOnWarn });
|
|
135832
135973
|
});
|
|
135833
135974
|
await program2.parseAsync(argv, { from: "user" });
|
|
135834
135975
|
return exitCode;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@requesto/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.0",
|
|
4
4
|
"description": "Run your Requesto collections from the terminal and CI pipelines",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^26.6.4",
|
|
28
28
|
"esbuild": "^0.28.2",
|
|
29
|
-
"requesto-backend": "1.
|
|
30
|
-
"requesto-engine": "1.
|
|
29
|
+
"requesto-backend": "1.14.0",
|
|
30
|
+
"requesto-engine": "1.14.0",
|
|
31
31
|
"tsx": "^4.23.15",
|
|
32
32
|
"typescript": "^7.0.2",
|
|
33
33
|
"vitest": "^5.0.3"
|