@zapier/zapier-sdk-cli 0.30.0 → 0.31.1
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/CHANGELOG.md +21 -0
- package/README.md +34 -13
- package/dist/cli.cjs +473 -17
- package/dist/cli.mjs +476 -20
- package/dist/index.cjs +434 -2
- package/dist/index.mjs +437 -4
- package/dist/package.json +1 -1
- package/dist/src/cli.js +3 -2
- package/dist/src/plugins/cliOverrides/index.d.ts +21 -0
- package/dist/src/plugins/cliOverrides/index.js +19 -0
- package/dist/src/plugins/curl/index.d.ts +17 -0
- package/dist/src/plugins/curl/index.js +234 -0
- package/dist/src/plugins/curl/schemas.d.ts +39 -0
- package/dist/src/plugins/curl/schemas.js +101 -0
- package/dist/src/plugins/curl/utils.d.ts +24 -0
- package/dist/src/plugins/curl/utils.js +141 -0
- package/dist/src/plugins/index.d.ts +2 -0
- package/dist/src/plugins/index.js +2 -0
- package/dist/src/sdk.js +4 -1
- package/dist/src/utils/cli-generator.js +47 -12
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
package/dist/cli.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import inquirer from 'inquirer';
|
|
|
6
6
|
import chalk3 from 'chalk';
|
|
7
7
|
import util from 'util';
|
|
8
8
|
import open from 'open';
|
|
9
|
-
import crypto from 'crypto';
|
|
9
|
+
import crypto, { createHash } from 'crypto';
|
|
10
10
|
import express from 'express';
|
|
11
11
|
import pkceChallenge from 'pkce-challenge';
|
|
12
12
|
import { logout, getConfigPath, getLoggedInUser, getPkceLoginConfig, AUTH_MODE_HEADER, updateLogin } from '@zapier/zapier-sdk-cli-login';
|
|
@@ -14,9 +14,9 @@ import ora from 'ora';
|
|
|
14
14
|
import { startMcpServer } from '@zapier/zapier-sdk-mcp';
|
|
15
15
|
import { buildSync } from 'esbuild';
|
|
16
16
|
import * as fs from 'fs';
|
|
17
|
-
import { existsSync } from 'fs';
|
|
17
|
+
import { promises, createWriteStream, existsSync } from 'fs';
|
|
18
18
|
import * as path from 'path';
|
|
19
|
-
import { resolve, join } from 'path';
|
|
19
|
+
import { resolve, join, dirname, basename } from 'path';
|
|
20
20
|
import { mkdir, writeFile, access } from 'fs/promises';
|
|
21
21
|
import * as ts from 'typescript';
|
|
22
22
|
import packageJsonLib from 'package-json';
|
|
@@ -927,7 +927,7 @@ function analyzeZodField(name, schema, functionInfo) {
|
|
|
927
927
|
paramType = "string";
|
|
928
928
|
choices = baseSchema.options;
|
|
929
929
|
} else if (baseSchema instanceof z.ZodRecord) {
|
|
930
|
-
paramType = "
|
|
930
|
+
paramType = "object";
|
|
931
931
|
}
|
|
932
932
|
let paramHasResolver = false;
|
|
933
933
|
if (functionInfo?.resolvers?.[name]) {
|
|
@@ -1242,9 +1242,14 @@ ${confirmMessageAfter}`));
|
|
|
1242
1242
|
description,
|
|
1243
1243
|
parameters,
|
|
1244
1244
|
handler,
|
|
1245
|
-
hidden: functionInfo.categories?.includes("deprecated") ?? false
|
|
1245
|
+
hidden: functionInfo.categories?.includes("deprecated") ?? false,
|
|
1246
|
+
aliases: functionInfo.aliases
|
|
1246
1247
|
};
|
|
1247
1248
|
}
|
|
1249
|
+
function collect(value, previous = []) {
|
|
1250
|
+
previous.push(value);
|
|
1251
|
+
return previous;
|
|
1252
|
+
}
|
|
1248
1253
|
function addCommand(program2, commandName, config2) {
|
|
1249
1254
|
const command = program2.command(commandName, { hidden: config2.hidden ?? false }).description(config2.description);
|
|
1250
1255
|
let hasPositionalArray = false;
|
|
@@ -1263,10 +1268,12 @@ function addCommand(program2, commandName, config2) {
|
|
|
1263
1268
|
);
|
|
1264
1269
|
} else if (param.required && param.type === "array") {
|
|
1265
1270
|
const flags = [`--${kebabName}`];
|
|
1266
|
-
const flagSignature = flags.join(", ") + ` <
|
|
1271
|
+
const flagSignature = flags.join(", ") + ` <value>`;
|
|
1267
1272
|
command.requiredOption(
|
|
1268
1273
|
flagSignature,
|
|
1269
|
-
param.description || `${kebabName} parameter (required)
|
|
1274
|
+
param.description || `${kebabName} parameter (required, repeatable)`,
|
|
1275
|
+
collect,
|
|
1276
|
+
[]
|
|
1270
1277
|
);
|
|
1271
1278
|
} else if (param.required) {
|
|
1272
1279
|
command.argument(
|
|
@@ -1279,16 +1286,17 @@ function addCommand(program2, commandName, config2) {
|
|
|
1279
1286
|
param.description || `${kebabName} parameter`
|
|
1280
1287
|
);
|
|
1281
1288
|
} else {
|
|
1282
|
-
const flags = [
|
|
1289
|
+
const flags = [];
|
|
1290
|
+
const alias = config2.aliases?.[param.name];
|
|
1291
|
+
if (alias && alias.length === 1) {
|
|
1292
|
+
flags.push(`-${alias}`);
|
|
1293
|
+
}
|
|
1294
|
+
flags.push(`--${kebabName}`);
|
|
1283
1295
|
if (param.type === "boolean") {
|
|
1284
1296
|
command.option(flags.join(", "), param.description);
|
|
1285
1297
|
} else if (param.type === "array") {
|
|
1286
|
-
const flagSignature = flags.join(", ") + ` <
|
|
1287
|
-
command.option(
|
|
1288
|
-
flagSignature,
|
|
1289
|
-
param.description,
|
|
1290
|
-
param.default
|
|
1291
|
-
);
|
|
1298
|
+
const flagSignature = flags.join(", ") + ` <value>`;
|
|
1299
|
+
command.option(flagSignature, param.description || "", collect, []);
|
|
1292
1300
|
} else {
|
|
1293
1301
|
const flagSignature = flags.join(", ") + ` <${param.type}>`;
|
|
1294
1302
|
command.option(
|
|
@@ -1299,7 +1307,10 @@ function addCommand(program2, commandName, config2) {
|
|
|
1299
1307
|
}
|
|
1300
1308
|
}
|
|
1301
1309
|
});
|
|
1302
|
-
|
|
1310
|
+
const hasJsonParam = config2.parameters.some((p) => p.name === "json");
|
|
1311
|
+
if (!hasJsonParam) {
|
|
1312
|
+
command.option("--json", "Output raw JSON instead of formatted results");
|
|
1313
|
+
}
|
|
1303
1314
|
command.action(config2.handler);
|
|
1304
1315
|
}
|
|
1305
1316
|
function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
|
|
@@ -1318,6 +1329,9 @@ function convertCliArgsToSdkParams(parameters, positionalArgs, options) {
|
|
|
1318
1329
|
const camelKey = key.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
1319
1330
|
const param = parameters.find((p) => p.name === camelKey);
|
|
1320
1331
|
if (param && value !== void 0) {
|
|
1332
|
+
if (param.type === "array" && Array.isArray(value) && value.length === 0) {
|
|
1333
|
+
return;
|
|
1334
|
+
}
|
|
1321
1335
|
sdkParams[camelKey] = convertValue(value, param.type);
|
|
1322
1336
|
}
|
|
1323
1337
|
});
|
|
@@ -1335,6 +1349,16 @@ function convertValue(value, type) {
|
|
|
1335
1349
|
case "array":
|
|
1336
1350
|
return Array.isArray(value) ? value : [value];
|
|
1337
1351
|
case "string":
|
|
1352
|
+
return value;
|
|
1353
|
+
case "object":
|
|
1354
|
+
if (typeof value === "string") {
|
|
1355
|
+
try {
|
|
1356
|
+
return JSON.parse(value);
|
|
1357
|
+
} catch {
|
|
1358
|
+
return value;
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
return value;
|
|
1338
1362
|
default:
|
|
1339
1363
|
if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) {
|
|
1340
1364
|
try {
|
|
@@ -1744,7 +1768,7 @@ var LoginSchema = z.object({
|
|
|
1744
1768
|
|
|
1745
1769
|
// package.json
|
|
1746
1770
|
var package_default = {
|
|
1747
|
-
version: "0.
|
|
1771
|
+
version: "0.31.1"};
|
|
1748
1772
|
|
|
1749
1773
|
// src/telemetry/builders.ts
|
|
1750
1774
|
function createCliBaseEvent(context = {}) {
|
|
@@ -3080,18 +3104,450 @@ var feedbackPlugin = ({
|
|
|
3080
3104
|
}
|
|
3081
3105
|
};
|
|
3082
3106
|
};
|
|
3107
|
+
var CurlSchema = z.object({
|
|
3108
|
+
url: z.string().describe("Request URL"),
|
|
3109
|
+
request: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).optional().describe("HTTP method (defaults to GET, or POST if data is provided)"),
|
|
3110
|
+
header: z.array(z.string()).optional().describe("HTTP headers in 'Key: Value' format (repeatable)"),
|
|
3111
|
+
data: z.array(z.string()).optional().describe("HTTP POST data (repeatable, joined with &)"),
|
|
3112
|
+
dataRaw: z.array(z.string()).optional().describe("HTTP POST data without special interpretation (repeatable)"),
|
|
3113
|
+
dataAscii: z.array(z.string()).optional().describe("HTTP POST ASCII data (repeatable)"),
|
|
3114
|
+
dataBinary: z.array(z.string()).optional().describe("HTTP POST binary data (repeatable)"),
|
|
3115
|
+
dataUrlencode: z.array(z.string()).optional().describe("HTTP POST data, URL-encoded (repeatable)"),
|
|
3116
|
+
json: z.string().optional().describe("Send JSON body (sets Content-Type and Accept headers)"),
|
|
3117
|
+
form: z.array(z.string()).optional().describe("Multipart form data as 'name=value' (repeatable)"),
|
|
3118
|
+
formString: z.array(z.string()).optional().describe("Multipart form string field (repeatable)"),
|
|
3119
|
+
get: z.boolean().optional().describe("Force GET method and append data to query string"),
|
|
3120
|
+
head: z.boolean().optional().describe("Fetch headers only (HEAD request)"),
|
|
3121
|
+
location: z.boolean().optional().describe("Follow redirects"),
|
|
3122
|
+
include: z.boolean().optional().describe("Include response headers in output"),
|
|
3123
|
+
output: z.string().optional().describe("Write output to file instead of stdout"),
|
|
3124
|
+
remoteName: z.boolean().optional().describe("Write output to file named like the remote file"),
|
|
3125
|
+
verbose: z.boolean().optional().describe("Verbose output (show request/response headers on stderr)"),
|
|
3126
|
+
silent: z.boolean().optional().describe("Silent mode (suppress errors)"),
|
|
3127
|
+
showError: z.boolean().optional().describe("Show errors even when in silent mode"),
|
|
3128
|
+
fail: z.boolean().optional().describe("Fail silently on HTTP errors (exit code 22)"),
|
|
3129
|
+
failWithBody: z.boolean().optional().describe("Fail on HTTP errors but still output the body"),
|
|
3130
|
+
writeOut: z.string().optional().describe("Output format string after completion (e.g., '%{http_code}')"),
|
|
3131
|
+
maxTime: z.number().optional().describe("Maximum time in seconds for the request"),
|
|
3132
|
+
user: z.string().optional().describe("Basic auth credentials as 'user:password'"),
|
|
3133
|
+
compressed: z.boolean().optional().describe("Request compressed response (sends Accept-Encoding header)"),
|
|
3134
|
+
connectionId: z.union([z.string(), z.number()]).optional().describe("Zapier connection ID for authentication")
|
|
3135
|
+
}).describe("Make HTTP requests through Zapier Relay with curl-like options");
|
|
3136
|
+
var CurlExitError = class extends Error {
|
|
3137
|
+
constructor(message, exitCode) {
|
|
3138
|
+
super(message);
|
|
3139
|
+
this.exitCode = exitCode;
|
|
3140
|
+
this.name = "CurlExitError";
|
|
3141
|
+
}
|
|
3142
|
+
};
|
|
3143
|
+
function parseHeaderLine(input) {
|
|
3144
|
+
const idx = input.indexOf(":");
|
|
3145
|
+
if (idx === -1) {
|
|
3146
|
+
return null;
|
|
3147
|
+
}
|
|
3148
|
+
const key = input.slice(0, idx).trim();
|
|
3149
|
+
const value = input.slice(idx + 1).trim();
|
|
3150
|
+
if (!key) {
|
|
3151
|
+
return null;
|
|
3152
|
+
}
|
|
3153
|
+
return { key, value };
|
|
3154
|
+
}
|
|
3155
|
+
function basicAuthHeader(userpass) {
|
|
3156
|
+
const idx = userpass.indexOf(":");
|
|
3157
|
+
const user = idx === -1 ? userpass : userpass.slice(0, idx);
|
|
3158
|
+
const pass = idx === -1 ? "" : userpass.slice(idx + 1);
|
|
3159
|
+
const token = Buffer.from(`${user}:${pass}`, "utf8").toString("base64");
|
|
3160
|
+
return `Basic ${token}`;
|
|
3161
|
+
}
|
|
3162
|
+
function deriveRemoteFilename(url) {
|
|
3163
|
+
const path2 = url.pathname;
|
|
3164
|
+
const candidate = path2.endsWith("/") ? "index.html" : basename(path2);
|
|
3165
|
+
return candidate || "index.html";
|
|
3166
|
+
}
|
|
3167
|
+
function decodeWriteOutEscapes(input) {
|
|
3168
|
+
return input.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ");
|
|
3169
|
+
}
|
|
3170
|
+
function formatWriteOut(params) {
|
|
3171
|
+
const { template } = params;
|
|
3172
|
+
const replacements = {
|
|
3173
|
+
"%{http_code}": String(params.httpCode).padStart(3, "0"),
|
|
3174
|
+
"%{time_total}": params.timeTotalSeconds.toFixed(3),
|
|
3175
|
+
"%{size_download}": String(params.sizeDownloadBytes),
|
|
3176
|
+
"%{url_effective}": params.urlEffective,
|
|
3177
|
+
"%{content_type}": params.contentType ?? ""
|
|
3178
|
+
};
|
|
3179
|
+
let out = template;
|
|
3180
|
+
for (const [token, value] of Object.entries(replacements)) {
|
|
3181
|
+
out = out.split(token).join(value);
|
|
3182
|
+
}
|
|
3183
|
+
return decodeWriteOutEscapes(out);
|
|
3184
|
+
}
|
|
3185
|
+
function appendQueryParams(url, dataParts) {
|
|
3186
|
+
const out = new URL(url.toString());
|
|
3187
|
+
for (const part of dataParts) {
|
|
3188
|
+
const segments = part.split("&");
|
|
3189
|
+
for (const seg of segments) {
|
|
3190
|
+
if (!seg) continue;
|
|
3191
|
+
const idx = seg.indexOf("=");
|
|
3192
|
+
if (idx === -1) {
|
|
3193
|
+
out.searchParams.append(seg, "");
|
|
3194
|
+
} else {
|
|
3195
|
+
out.searchParams.append(seg.slice(0, idx), seg.slice(idx + 1));
|
|
3196
|
+
}
|
|
3197
|
+
}
|
|
3198
|
+
}
|
|
3199
|
+
return out;
|
|
3200
|
+
}
|
|
3201
|
+
async function readAllStdin() {
|
|
3202
|
+
const chunks = [];
|
|
3203
|
+
for await (const chunk of process.stdin) {
|
|
3204
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
3205
|
+
}
|
|
3206
|
+
return Buffer.concat(chunks);
|
|
3207
|
+
}
|
|
3208
|
+
async function resolveDataArgText(raw) {
|
|
3209
|
+
if (!raw.startsWith("@")) {
|
|
3210
|
+
return raw;
|
|
3211
|
+
}
|
|
3212
|
+
const source = raw.slice(1);
|
|
3213
|
+
if (source === "-") {
|
|
3214
|
+
const buf2 = await readAllStdin();
|
|
3215
|
+
return buf2.toString("utf8");
|
|
3216
|
+
}
|
|
3217
|
+
const buf = await promises.readFile(source);
|
|
3218
|
+
return buf.toString("utf8");
|
|
3219
|
+
}
|
|
3220
|
+
async function resolveDataArgBinary(raw) {
|
|
3221
|
+
if (!raw.startsWith("@")) {
|
|
3222
|
+
return Buffer.from(raw, "utf8");
|
|
3223
|
+
}
|
|
3224
|
+
const source = raw.slice(1);
|
|
3225
|
+
if (source === "-") {
|
|
3226
|
+
return await readAllStdin();
|
|
3227
|
+
}
|
|
3228
|
+
return await promises.readFile(source);
|
|
3229
|
+
}
|
|
3230
|
+
async function buildFormData(formArgs, formStringArgs) {
|
|
3231
|
+
if (typeof FormData === "undefined") {
|
|
3232
|
+
throw new CurlExitError(
|
|
3233
|
+
"FormData is not available in this runtime; cannot use --form.",
|
|
3234
|
+
2
|
|
3235
|
+
);
|
|
3236
|
+
}
|
|
3237
|
+
const fd = new FormData();
|
|
3238
|
+
const addField = async (item, forceString) => {
|
|
3239
|
+
const idx = item.indexOf("=");
|
|
3240
|
+
if (idx === -1) {
|
|
3241
|
+
throw new CurlExitError(
|
|
3242
|
+
`Invalid form field: '${item}'. Expected 'name=value' or 'name=@file'.`,
|
|
3243
|
+
2
|
|
3244
|
+
);
|
|
3245
|
+
}
|
|
3246
|
+
const name = item.slice(0, idx);
|
|
3247
|
+
const value = item.slice(idx + 1);
|
|
3248
|
+
if (!name) {
|
|
3249
|
+
throw new CurlExitError(
|
|
3250
|
+
`Invalid form field: '${item}'. Field name cannot be empty.`,
|
|
3251
|
+
2
|
|
3252
|
+
);
|
|
3253
|
+
}
|
|
3254
|
+
if (!forceString && value.startsWith("@")) {
|
|
3255
|
+
const filePath = value.slice(1);
|
|
3256
|
+
const buf = filePath === "-" ? await readAllStdin() : await promises.readFile(filePath);
|
|
3257
|
+
if (typeof Blob === "undefined") {
|
|
3258
|
+
fd.append(name, buf.toString("utf8"));
|
|
3259
|
+
return;
|
|
3260
|
+
}
|
|
3261
|
+
const blob = new Blob([buf]);
|
|
3262
|
+
const filename = filePath === "-" ? `stdin-${createHash("sha1").update(buf).digest("hex").slice(0, 8)}` : basename(filePath);
|
|
3263
|
+
fd.append(name, blob, filename);
|
|
3264
|
+
return;
|
|
3265
|
+
}
|
|
3266
|
+
fd.append(name, value);
|
|
3267
|
+
};
|
|
3268
|
+
for (const item of formArgs) {
|
|
3269
|
+
await addField(item, false);
|
|
3270
|
+
}
|
|
3271
|
+
for (const item of formStringArgs) {
|
|
3272
|
+
await addField(item, true);
|
|
3273
|
+
}
|
|
3274
|
+
return fd;
|
|
3275
|
+
}
|
|
3276
|
+
|
|
3277
|
+
// src/plugins/curl/index.ts
|
|
3278
|
+
var curlPlugin = ({
|
|
3279
|
+
sdk: sdk2
|
|
3280
|
+
}) => {
|
|
3281
|
+
async function curl(options) {
|
|
3282
|
+
const {
|
|
3283
|
+
url: rawUrl,
|
|
3284
|
+
request,
|
|
3285
|
+
header = [],
|
|
3286
|
+
data = [],
|
|
3287
|
+
dataRaw = [],
|
|
3288
|
+
dataAscii = [],
|
|
3289
|
+
dataBinary = [],
|
|
3290
|
+
dataUrlencode = [],
|
|
3291
|
+
json,
|
|
3292
|
+
form = [],
|
|
3293
|
+
formString = [],
|
|
3294
|
+
get: forceGet,
|
|
3295
|
+
head: forceHead,
|
|
3296
|
+
location,
|
|
3297
|
+
include,
|
|
3298
|
+
output,
|
|
3299
|
+
remoteName,
|
|
3300
|
+
verbose,
|
|
3301
|
+
silent,
|
|
3302
|
+
showError,
|
|
3303
|
+
fail,
|
|
3304
|
+
failWithBody,
|
|
3305
|
+
writeOut,
|
|
3306
|
+
maxTime,
|
|
3307
|
+
user,
|
|
3308
|
+
compressed,
|
|
3309
|
+
connectionId
|
|
3310
|
+
} = options;
|
|
3311
|
+
const parsedUrl = new URL(rawUrl);
|
|
3312
|
+
const headers = {};
|
|
3313
|
+
for (const h of header) {
|
|
3314
|
+
const parsed = parseHeaderLine(h);
|
|
3315
|
+
if (parsed) {
|
|
3316
|
+
headers[parsed.key] = parsed.value;
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
if (user) {
|
|
3320
|
+
headers["Authorization"] = basicAuthHeader(user);
|
|
3321
|
+
}
|
|
3322
|
+
if (compressed) {
|
|
3323
|
+
headers["Accept-Encoding"] = "gzip, deflate, br";
|
|
3324
|
+
}
|
|
3325
|
+
const rawTextDataArgs = [...data, ...dataRaw, ...dataAscii];
|
|
3326
|
+
const rawBinaryDataArgs = [...dataBinary];
|
|
3327
|
+
const rawUrlencodeArgs = [...dataUrlencode];
|
|
3328
|
+
const hasForm = form.length > 0 || formString.length > 0;
|
|
3329
|
+
const hasJson = json !== void 0;
|
|
3330
|
+
const hasAnyData = hasJson || hasForm || rawTextDataArgs.length > 0 || rawBinaryDataArgs.length > 0 || rawUrlencodeArgs.length > 0;
|
|
3331
|
+
let method = "GET";
|
|
3332
|
+
if (forceHead) {
|
|
3333
|
+
method = "HEAD";
|
|
3334
|
+
} else if (request) {
|
|
3335
|
+
method = request;
|
|
3336
|
+
} else if (forceGet) {
|
|
3337
|
+
method = "GET";
|
|
3338
|
+
} else if (hasAnyData) {
|
|
3339
|
+
method = "POST";
|
|
3340
|
+
}
|
|
3341
|
+
let body;
|
|
3342
|
+
let effectiveUrl = parsedUrl;
|
|
3343
|
+
if (hasJson) {
|
|
3344
|
+
if (!headers["Content-Type"]) {
|
|
3345
|
+
headers["Content-Type"] = "application/json";
|
|
3346
|
+
}
|
|
3347
|
+
if (!headers["Accept"]) {
|
|
3348
|
+
headers["Accept"] = "application/json";
|
|
3349
|
+
}
|
|
3350
|
+
body = json;
|
|
3351
|
+
} else if (hasForm) {
|
|
3352
|
+
body = await buildFormData(form, formString);
|
|
3353
|
+
} else {
|
|
3354
|
+
const resolvedTextParts = [];
|
|
3355
|
+
for (const raw of rawTextDataArgs) {
|
|
3356
|
+
resolvedTextParts.push(await resolveDataArgText(raw));
|
|
3357
|
+
}
|
|
3358
|
+
const resolvedUrlEncodeParts = [];
|
|
3359
|
+
for (const raw of rawUrlencodeArgs) {
|
|
3360
|
+
if (raw.startsWith("@")) {
|
|
3361
|
+
const content = await resolveDataArgText(raw);
|
|
3362
|
+
resolvedUrlEncodeParts.push(encodeURIComponent(content));
|
|
3363
|
+
continue;
|
|
3364
|
+
}
|
|
3365
|
+
const atIdx = raw.indexOf("@");
|
|
3366
|
+
const eqIdx = raw.indexOf("=");
|
|
3367
|
+
if (eqIdx !== -1) {
|
|
3368
|
+
const key = raw.slice(0, eqIdx);
|
|
3369
|
+
const value = raw.slice(eqIdx + 1);
|
|
3370
|
+
resolvedUrlEncodeParts.push(
|
|
3371
|
+
`${encodeURIComponent(key)}=${encodeURIComponent(value)}`
|
|
3372
|
+
);
|
|
3373
|
+
} else if (atIdx !== -1) {
|
|
3374
|
+
const key = raw.slice(0, atIdx);
|
|
3375
|
+
const filePath = raw.slice(atIdx + 1);
|
|
3376
|
+
const buf2 = filePath === "-" ? await readAllStdin() : await promises.readFile(filePath);
|
|
3377
|
+
resolvedUrlEncodeParts.push(
|
|
3378
|
+
`${encodeURIComponent(key)}=${encodeURIComponent(buf2.toString("utf8"))}`
|
|
3379
|
+
);
|
|
3380
|
+
} else {
|
|
3381
|
+
resolvedUrlEncodeParts.push(encodeURIComponent(raw));
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
const resolvedBinaryParts = [];
|
|
3385
|
+
for (const raw of rawBinaryDataArgs) {
|
|
3386
|
+
resolvedBinaryParts.push(await resolveDataArgBinary(raw));
|
|
3387
|
+
}
|
|
3388
|
+
const allTextParts = [...resolvedTextParts, ...resolvedUrlEncodeParts];
|
|
3389
|
+
if (forceGet && allTextParts.length > 0) {
|
|
3390
|
+
effectiveUrl = appendQueryParams(parsedUrl, allTextParts);
|
|
3391
|
+
} else if (resolvedBinaryParts.length > 0) {
|
|
3392
|
+
body = Buffer.concat(resolvedBinaryParts);
|
|
3393
|
+
} else if (allTextParts.length > 0) {
|
|
3394
|
+
body = allTextParts.join("&");
|
|
3395
|
+
if (!headers["Content-Type"]) {
|
|
3396
|
+
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
|
3397
|
+
}
|
|
3398
|
+
}
|
|
3399
|
+
}
|
|
3400
|
+
const redirect = location ? "follow" : "manual";
|
|
3401
|
+
if (verbose && !silent) {
|
|
3402
|
+
process.stderr.write(`> ${method} ${effectiveUrl.toString()}
|
|
3403
|
+
`);
|
|
3404
|
+
for (const [k, v] of Object.entries(headers)) {
|
|
3405
|
+
process.stderr.write(`> ${k}: ${v}
|
|
3406
|
+
`);
|
|
3407
|
+
}
|
|
3408
|
+
process.stderr.write(">\n");
|
|
3409
|
+
}
|
|
3410
|
+
const signal = maxTime ? AbortSignal.timeout(maxTime * 1e3) : void 0;
|
|
3411
|
+
const start = performance.now();
|
|
3412
|
+
const response = await sdk2.fetch(effectiveUrl.toString(), {
|
|
3413
|
+
method,
|
|
3414
|
+
headers,
|
|
3415
|
+
body,
|
|
3416
|
+
redirect,
|
|
3417
|
+
signal,
|
|
3418
|
+
connectionId
|
|
3419
|
+
});
|
|
3420
|
+
const timeTotalSeconds = (performance.now() - start) / 1e3;
|
|
3421
|
+
if (verbose && !silent) {
|
|
3422
|
+
process.stderr.write(
|
|
3423
|
+
`< HTTP ${response.status} ${response.statusText}
|
|
3424
|
+
`
|
|
3425
|
+
);
|
|
3426
|
+
response.headers.forEach((value, key) => {
|
|
3427
|
+
process.stderr.write(`< ${key}: ${value}
|
|
3428
|
+
`);
|
|
3429
|
+
});
|
|
3430
|
+
process.stderr.write("<\n");
|
|
3431
|
+
}
|
|
3432
|
+
const isHttpError = response.status >= 400;
|
|
3433
|
+
const shouldFail = (fail || failWithBody) && isHttpError;
|
|
3434
|
+
const shouldOutputBody = !shouldFail || !!failWithBody;
|
|
3435
|
+
const headerText = include ? `HTTP ${response.status} ${response.statusText}
|
|
3436
|
+
${Array.from(
|
|
3437
|
+
response.headers.entries()
|
|
3438
|
+
).map(([k, v]) => `${k}: ${v}`).join("\n")}
|
|
3439
|
+
|
|
3440
|
+
` : "";
|
|
3441
|
+
let bodyBytes = 0;
|
|
3442
|
+
const buf = shouldOutputBody ? Buffer.from(await response.arrayBuffer()) : Buffer.alloc(0);
|
|
3443
|
+
bodyBytes = buf.length;
|
|
3444
|
+
const outputFile = output && output !== "-" ? output : remoteName ? deriveRemoteFilename(parsedUrl) : void 0;
|
|
3445
|
+
if (outputFile) {
|
|
3446
|
+
const dir = dirname(outputFile);
|
|
3447
|
+
if (dir !== ".") {
|
|
3448
|
+
await promises.mkdir(dir, { recursive: true });
|
|
3449
|
+
}
|
|
3450
|
+
const ws = createWriteStream(outputFile);
|
|
3451
|
+
if (headerText) {
|
|
3452
|
+
ws.write(headerText);
|
|
3453
|
+
}
|
|
3454
|
+
if (buf.length) {
|
|
3455
|
+
ws.write(buf);
|
|
3456
|
+
}
|
|
3457
|
+
await new Promise((resolve4, reject) => {
|
|
3458
|
+
ws.end(() => resolve4());
|
|
3459
|
+
ws.on("error", reject);
|
|
3460
|
+
});
|
|
3461
|
+
} else {
|
|
3462
|
+
if (headerText) {
|
|
3463
|
+
process.stdout.write(headerText);
|
|
3464
|
+
}
|
|
3465
|
+
if (buf.length) {
|
|
3466
|
+
process.stdout.write(buf);
|
|
3467
|
+
}
|
|
3468
|
+
}
|
|
3469
|
+
if (writeOut) {
|
|
3470
|
+
const formatted = formatWriteOut({
|
|
3471
|
+
template: writeOut,
|
|
3472
|
+
urlEffective: response.url || effectiveUrl.toString(),
|
|
3473
|
+
httpCode: response.status,
|
|
3474
|
+
timeTotalSeconds,
|
|
3475
|
+
sizeDownloadBytes: bodyBytes,
|
|
3476
|
+
contentType: response.headers.get("content-type")
|
|
3477
|
+
});
|
|
3478
|
+
process.stdout.write(formatted);
|
|
3479
|
+
}
|
|
3480
|
+
if (shouldFail) {
|
|
3481
|
+
if (!silent || showError) {
|
|
3482
|
+
process.stderr.write(
|
|
3483
|
+
`curl: (22) The requested URL returned error: ${response.status}
|
|
3484
|
+
`
|
|
3485
|
+
);
|
|
3486
|
+
}
|
|
3487
|
+
throw new CurlExitError("HTTP request failed", 22);
|
|
3488
|
+
}
|
|
3489
|
+
return void 0;
|
|
3490
|
+
}
|
|
3491
|
+
return {
|
|
3492
|
+
curl,
|
|
3493
|
+
context: {
|
|
3494
|
+
meta: {
|
|
3495
|
+
curl: {
|
|
3496
|
+
description: "Make authenticated HTTP requests to any API through Zapier. Pass a connection ID to automatically inject the user's stored credentials (OAuth tokens, API keys, etc.) into the outgoing request. Use it in place of the native curl command with additional Zapier-specific options.",
|
|
3497
|
+
categories: ["http"],
|
|
3498
|
+
inputSchema: CurlSchema,
|
|
3499
|
+
aliases: {
|
|
3500
|
+
request: "X",
|
|
3501
|
+
header: "H",
|
|
3502
|
+
data: "d",
|
|
3503
|
+
form: "F",
|
|
3504
|
+
get: "G",
|
|
3505
|
+
head: "I",
|
|
3506
|
+
location: "L",
|
|
3507
|
+
include: "i",
|
|
3508
|
+
output: "o",
|
|
3509
|
+
remoteName: "O",
|
|
3510
|
+
verbose: "v",
|
|
3511
|
+
silent: "s",
|
|
3512
|
+
showError: "S",
|
|
3513
|
+
writeOut: "w",
|
|
3514
|
+
maxTime: "m",
|
|
3515
|
+
user: "u"
|
|
3516
|
+
}
|
|
3517
|
+
}
|
|
3518
|
+
}
|
|
3519
|
+
}
|
|
3520
|
+
};
|
|
3521
|
+
};
|
|
3522
|
+
|
|
3523
|
+
// src/plugins/cliOverrides/index.ts
|
|
3524
|
+
var cliOverridesPlugin = ({ context }) => {
|
|
3525
|
+
if (!context.meta.fetch) {
|
|
3526
|
+
return { context: { meta: {} } };
|
|
3527
|
+
}
|
|
3528
|
+
return {
|
|
3529
|
+
context: {
|
|
3530
|
+
meta: {
|
|
3531
|
+
fetch: {
|
|
3532
|
+
...context.meta.fetch,
|
|
3533
|
+
categories: [...context.meta.fetch.categories || [], "deprecated"]
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
}
|
|
3537
|
+
};
|
|
3538
|
+
};
|
|
3083
3539
|
|
|
3084
3540
|
// src/sdk.ts
|
|
3085
3541
|
function createZapierCliSdk(options = {}) {
|
|
3086
3542
|
return createZapierSdkWithoutRegistry({
|
|
3087
3543
|
...options
|
|
3088
|
-
}).addPlugin(generateAppTypesPlugin).addPlugin(buildManifestPlugin).addPlugin(bundleCodePlugin).addPlugin(getLoginConfigPathPlugin).addPlugin(addPlugin).addPlugin(feedbackPlugin).addPlugin(mcpPlugin).addPlugin(loginPlugin).addPlugin(logoutPlugin).addPlugin(registryPlugin);
|
|
3544
|
+
}).addPlugin(generateAppTypesPlugin).addPlugin(buildManifestPlugin).addPlugin(bundleCodePlugin).addPlugin(getLoginConfigPathPlugin).addPlugin(addPlugin).addPlugin(feedbackPlugin).addPlugin(curlPlugin).addPlugin(mcpPlugin).addPlugin(loginPlugin).addPlugin(logoutPlugin).addPlugin(cliOverridesPlugin).addPlugin(registryPlugin);
|
|
3089
3545
|
}
|
|
3090
3546
|
|
|
3091
3547
|
// package.json with { type: 'json' }
|
|
3092
3548
|
var package_default2 = {
|
|
3093
3549
|
name: "@zapier/zapier-sdk-cli",
|
|
3094
|
-
version: "0.
|
|
3550
|
+
version: "0.31.1"};
|
|
3095
3551
|
function detectPackageManager(cwd = process.cwd()) {
|
|
3096
3552
|
const ua = process.env.npm_config_user_agent;
|
|
3097
3553
|
if (ua) {
|
|
@@ -3294,7 +3750,7 @@ async function checkAndNotifyUpdates({
|
|
|
3294
3750
|
|
|
3295
3751
|
// src/cli.ts
|
|
3296
3752
|
var program = new Command();
|
|
3297
|
-
program.name("zapier-sdk").description("CLI for Zapier SDK").version(package_default2.version,
|
|
3753
|
+
program.name("zapier-sdk").description("CLI for Zapier SDK").version(package_default2.version, void 0, "Display version number").option("--debug", "Enable debug logging").option("--base-url <url>", "Base URL for Zapier API endpoints").option("--credentials <token>", "Authentication token").option("--credentials-client-id <id>", "OAuth client ID for authentication").option(
|
|
3298
3754
|
"--credentials-client-secret <secret>",
|
|
3299
3755
|
"OAuth client secret for authentication"
|
|
3300
3756
|
).option(
|
|
@@ -3306,7 +3762,7 @@ program.name("zapier-sdk").description("CLI for Zapier SDK").version(package_def
|
|
|
3306
3762
|
).option(
|
|
3307
3763
|
"--max-network-retry-delay-ms <ms>",
|
|
3308
3764
|
"Max delay in ms to wait for rate limit retry (default: 60000)"
|
|
3309
|
-
);
|
|
3765
|
+
).helpOption("-h, --help", "Display help for command");
|
|
3310
3766
|
var isDebugMode = process.env.DEBUG === "true" || process.argv.includes("--debug");
|
|
3311
3767
|
function getFlagValue(flagName) {
|
|
3312
3768
|
const index = process.argv.indexOf(flagName);
|