@withone/cli 1.35.0 → 1.36.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/README.md
CHANGED
|
@@ -255,6 +255,7 @@ one actions execute stripe <actionId> <connectionKey> \
|
|
|
255
255
|
| `--dry-run` | Show the request without executing it |
|
|
256
256
|
| `--mock` | Return example response without making an API call |
|
|
257
257
|
| `--skip-validation` | Skip input validation against the action schema |
|
|
258
|
+
| `--output <path>` | Save response to a file (for binary downloads) |
|
|
258
259
|
|
|
259
260
|
The CLI validates required parameters (path variables, query params, body fields) against the action schema before executing. Missing params return a clear error with the flag name and description. Pass `--skip-validation` to bypass.
|
|
260
261
|
|
|
@@ -11,6 +11,10 @@ import { exec, spawn } from "child_process";
|
|
|
11
11
|
import { promisify } from "util";
|
|
12
12
|
|
|
13
13
|
// src/lib/api.ts
|
|
14
|
+
import { createWriteStream } from "fs";
|
|
15
|
+
import { resolve } from "path";
|
|
16
|
+
import { pipeline } from "stream/promises";
|
|
17
|
+
import { Readable } from "stream";
|
|
14
18
|
var ApiError = class extends Error {
|
|
15
19
|
constructor(status, message, retryAfterSeconds) {
|
|
16
20
|
super(message);
|
|
@@ -328,12 +332,45 @@ var OneApi = class {
|
|
|
328
332
|
const text = await response.text();
|
|
329
333
|
throw new ApiError(response.status, text || `HTTP ${response.status}`);
|
|
330
334
|
}
|
|
335
|
+
const responseContentType = response.headers.get("content-type") || "";
|
|
336
|
+
const isExplicitJson = responseContentType.includes("application/json") || responseContentType.includes("text/");
|
|
337
|
+
if (isExplicitJson || !responseContentType) {
|
|
338
|
+
const responseText2 = await response.text();
|
|
339
|
+
const responseData = responseText2 ? JSON.parse(responseText2) : {};
|
|
340
|
+
return { requestConfig: sanitizedConfig, responseData };
|
|
341
|
+
}
|
|
342
|
+
if (args.output) {
|
|
343
|
+
const outputPath = resolve(args.output);
|
|
344
|
+
const body = response.body;
|
|
345
|
+
if (!body) {
|
|
346
|
+
throw new ApiError(0, "Response body is null \u2014 cannot save to file");
|
|
347
|
+
}
|
|
348
|
+
const nodeReadable = Readable.fromWeb(body);
|
|
349
|
+
await pipeline(nodeReadable, createWriteStream(outputPath));
|
|
350
|
+
const contentLength = response.headers.get("content-length");
|
|
351
|
+
const size = contentLength ? parseInt(contentLength, 10) : void 0;
|
|
352
|
+
return {
|
|
353
|
+
requestConfig: sanitizedConfig,
|
|
354
|
+
responseData: { saved: true, path: outputPath, size, contentType: responseContentType }
|
|
355
|
+
};
|
|
356
|
+
}
|
|
331
357
|
const responseText = await response.text();
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
requestConfig: sanitizedConfig,
|
|
335
|
-
|
|
336
|
-
|
|
358
|
+
try {
|
|
359
|
+
const responseData = responseText ? JSON.parse(responseText) : {};
|
|
360
|
+
return { requestConfig: sanitizedConfig, responseData };
|
|
361
|
+
} catch {
|
|
362
|
+
const contentLength = response.headers.get("content-length");
|
|
363
|
+
const size = contentLength ? parseInt(contentLength, 10) : responseText.length;
|
|
364
|
+
return {
|
|
365
|
+
requestConfig: sanitizedConfig,
|
|
366
|
+
responseData: {
|
|
367
|
+
binary: true,
|
|
368
|
+
size,
|
|
369
|
+
contentType: responseContentType,
|
|
370
|
+
message: "Binary response received. Use --output <path> to save to a file."
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
}
|
|
337
374
|
}
|
|
338
375
|
// Webhook Relay methods
|
|
339
376
|
async createRelayEndpoint(body) {
|
|
@@ -394,7 +431,7 @@ var TimeoutError = class extends Error {
|
|
|
394
431
|
}
|
|
395
432
|
};
|
|
396
433
|
function sleep(ms) {
|
|
397
|
-
return new Promise((
|
|
434
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
398
435
|
}
|
|
399
436
|
function replacePathVariables(path3, variables) {
|
|
400
437
|
if (!path3) return path3;
|
|
@@ -532,7 +569,7 @@ function setByDotPath(obj, dotPath, value) {
|
|
|
532
569
|
// src/lib/flow-engine.ts
|
|
533
570
|
var execAsync = promisify(exec);
|
|
534
571
|
function sleep2(ms) {
|
|
535
|
-
return new Promise((
|
|
572
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
536
573
|
}
|
|
537
574
|
var StepTimeoutError = class extends Error {
|
|
538
575
|
errorCode = "TIMEOUT";
|
|
@@ -843,7 +880,7 @@ async function executeCodeModule(stepId, modulePath, context, options) {
|
|
|
843
880
|
const { env: _omitEnv, ...safeContext } = context;
|
|
844
881
|
void _omitEnv;
|
|
845
882
|
const stdinPayload = JSON.stringify(safeContext);
|
|
846
|
-
return await new Promise((
|
|
883
|
+
return await new Promise((resolve2, reject) => {
|
|
847
884
|
const child = spawn(process.execPath, [absPath], {
|
|
848
885
|
cwd: rootDir,
|
|
849
886
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -862,11 +899,11 @@ async function executeCodeModule(stepId, modulePath, context, options) {
|
|
|
862
899
|
}
|
|
863
900
|
const trimmed = stdout.trim();
|
|
864
901
|
if (trimmed === "") {
|
|
865
|
-
|
|
902
|
+
resolve2(void 0);
|
|
866
903
|
return;
|
|
867
904
|
}
|
|
868
905
|
try {
|
|
869
|
-
|
|
906
|
+
resolve2(JSON.parse(stripCodeFences(trimmed)));
|
|
870
907
|
} catch (err) {
|
|
871
908
|
reject(new Error(`Code module "${modulePath}" did not print valid JSON to stdout: ${err.message}`));
|
|
872
909
|
}
|
|
@@ -1042,7 +1079,7 @@ async function executeSubflowStep(step, context, api, permissions, allowedAction
|
|
|
1042
1079
|
if (flowStack.includes(resolvedKey)) {
|
|
1043
1080
|
throw new Error(`Circular flow detected: ${[...flowStack, resolvedKey].join(" \u2192 ")}`);
|
|
1044
1081
|
}
|
|
1045
|
-
const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-
|
|
1082
|
+
const { loadFlowWithMeta: loadFlowWithMeta2 } = await import("./flow-runner-OVOGDXNR.js");
|
|
1046
1083
|
const { flow: subFlow, rootDir: subRootDir } = loadFlowWithMeta2(resolvedKey);
|
|
1047
1084
|
const subContext = await executeFlow(
|
|
1048
1085
|
subFlow,
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
resolveFlowPath,
|
|
20
20
|
saveFlow,
|
|
21
21
|
validateActionInput
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-MNJJE4PJ.js";
|
|
23
23
|
|
|
24
24
|
// src/index.ts
|
|
25
25
|
import { createRequire as createRequire2 } from "module";
|
|
@@ -2771,7 +2771,8 @@ async function actionsExecuteCommand(platform, actionId, connectionKey, options)
|
|
|
2771
2771
|
headers,
|
|
2772
2772
|
isFormData: options.formData,
|
|
2773
2773
|
isFormUrlEncoded: options.formUrlEncoded,
|
|
2774
|
-
dryRun: options.dryRun
|
|
2774
|
+
dryRun: options.dryRun,
|
|
2775
|
+
output: options.output
|
|
2775
2776
|
},
|
|
2776
2777
|
actionDetails
|
|
2777
2778
|
);
|
|
@@ -8006,6 +8007,7 @@ one --agent actions execute <platform> <actionId> <key> -d '{}' # Execute it
|
|
|
8006
8007
|
- \`--dry-run\` \u2014 Preview request without executing
|
|
8007
8008
|
- \`--mock\` \u2014 Return example response without making an API call (useful for building UI against a response shape)
|
|
8008
8009
|
- \`--skip-validation\` \u2014 Skip input validation against the action schema
|
|
8010
|
+
- \`--output <path>\` \u2014 Save response to a file (for binary downloads like PDFs, images, documents)
|
|
8009
8011
|
|
|
8010
8012
|
The CLI validates required parameters against the action schema before executing. If you're missing a required path variable, query param, or body field, you'll get a clear error listing what's missing and which flag to use. Pass \`--skip-validation\` to bypass.
|
|
8011
8013
|
|
|
@@ -8129,6 +8131,7 @@ one --agent actions execute <platform> <actionId> <connectionKey> [options]
|
|
|
8129
8131
|
- \`--dry-run\` \u2014 Preview without executing
|
|
8130
8132
|
- \`--mock\` \u2014 Return example response without making an API call
|
|
8131
8133
|
- \`--skip-validation\` \u2014 Skip input validation against the action schema
|
|
8134
|
+
- \`--output <path>\` \u2014 Save response to a file (for binary downloads like PDFs, images, documents)
|
|
8132
8135
|
|
|
8133
8136
|
**Do NOT** pass path or query parameters in \`-d\`. Use the correct flags.
|
|
8134
8137
|
|
|
@@ -9369,7 +9372,7 @@ actions.command("search <platform> <query>").description('Search for actions on
|
|
|
9369
9372
|
actions.command("knowledge <platform> <actionId>").alias("k").description("Get full docs for an action \u2014 MUST call before execute to know required params").option("--no-cache", "Skip cache, fetch fresh from API").option("--cache-status", "Print cache metadata without fetching").action(async (platform, actionId, options) => {
|
|
9370
9373
|
await actionsKnowledgeCommand(platform, actionId, options);
|
|
9371
9374
|
});
|
|
9372
|
-
actions.command("execute [platform] [actionId] [connectionKey]").alias("x").allowUnknownOption(true).allowExcessArguments(true).description("Execute an action (or multiple with --parallel, separated by --)").option("-d, --data <json>", "Request body as JSON").option("--path-vars <json>", "Path variables as JSON").option("--query-params <json>", "Query parameters as JSON").option("--headers <json>", "Additional headers as JSON").option("--form-data", "Send as multipart/form-data").option("--form-url-encoded", "Send as application/x-www-form-urlencoded").option("--dry-run", "Show request that would be sent without executing").option("--mock", "Return example response without making an API call").option("--skip-validation", "Skip input validation against the action schema").option("--parallel", "Execute multiple actions concurrently (separate actions with --)").option("--max-concurrency <n>", "Max concurrent actions when using --parallel (default: 5)", "5").action(async (platform, actionId, connectionKey, options) => {
|
|
9375
|
+
actions.command("execute [platform] [actionId] [connectionKey]").alias("x").allowUnknownOption(true).allowExcessArguments(true).description("Execute an action (or multiple with --parallel, separated by --)").option("-d, --data <json>", "Request body as JSON").option("--path-vars <json>", "Path variables as JSON").option("--query-params <json>", "Query parameters as JSON").option("--headers <json>", "Additional headers as JSON").option("--form-data", "Send as multipart/form-data").option("--form-url-encoded", "Send as application/x-www-form-urlencoded").option("--dry-run", "Show request that would be sent without executing").option("--mock", "Return example response without making an API call").option("--skip-validation", "Skip input validation against the action schema").option("--output <path>", "Save binary response to a file (for non-JSON responses like file downloads)").option("--parallel", "Execute multiple actions concurrently (separate actions with --)").option("--max-concurrency <n>", "Max concurrent actions when using --parallel (default: 5)", "5").action(async (platform, actionId, connectionKey, options) => {
|
|
9373
9376
|
if (options.parallel) {
|
|
9374
9377
|
await actionsExecuteParallelCommand();
|
|
9375
9378
|
return;
|
|
@@ -9386,7 +9389,8 @@ actions.command("execute [platform] [actionId] [connectionKey]").alias("x").allo
|
|
|
9386
9389
|
formUrlEncoded: options.formUrlEncoded,
|
|
9387
9390
|
dryRun: options.dryRun,
|
|
9388
9391
|
mock: options.mock,
|
|
9389
|
-
skipValidation: options.skipValidation
|
|
9392
|
+
skipValidation: options.skipValidation,
|
|
9393
|
+
output: options.output
|
|
9390
9394
|
});
|
|
9391
9395
|
});
|
|
9392
9396
|
var flow = program.command("flow").alias("f").description("Create, execute, and manage multi-step workflows");
|
package/package.json
CHANGED
package/skills/one/SKILL.md
CHANGED
|
@@ -87,6 +87,7 @@ Options:
|
|
|
87
87
|
- `--dry-run` — Preview the request without executing
|
|
88
88
|
- `--mock` — Return example response without making an API call (useful for building UI)
|
|
89
89
|
- `--skip-validation` — Skip input validation against the action schema
|
|
90
|
+
- `--output <path>` — Save response to a file (for binary downloads like PDFs, images, documents)
|
|
90
91
|
|
|
91
92
|
The CLI validates required parameters before executing. Missing params return a structured error with the flag name, parameter name, and description. Pass `--skip-validation` to bypass.
|
|
92
93
|
|