@zapier/zapier-sdk-cli 0.30.0 → 0.31.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/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 = "string";
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(", ") + ` <values...>`;
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 = [`--${kebabName}`];
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(", ") + ` <values...>`;
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
- command.option("--json", "Output raw JSON instead of formatted results");
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) {
@@ -1335,6 +1346,16 @@ function convertValue(value, type) {
1335
1346
  case "array":
1336
1347
  return Array.isArray(value) ? value : [value];
1337
1348
  case "string":
1349
+ return value;
1350
+ case "object":
1351
+ if (typeof value === "string") {
1352
+ try {
1353
+ return JSON.parse(value);
1354
+ } catch {
1355
+ return value;
1356
+ }
1357
+ }
1358
+ return value;
1338
1359
  default:
1339
1360
  if (typeof value === "string" && (value.startsWith("{") || value.startsWith("["))) {
1340
1361
  try {
@@ -1744,7 +1765,7 @@ var LoginSchema = z.object({
1744
1765
 
1745
1766
  // package.json
1746
1767
  var package_default = {
1747
- version: "0.30.0"};
1768
+ version: "0.31.0"};
1748
1769
 
1749
1770
  // src/telemetry/builders.ts
1750
1771
  function createCliBaseEvent(context = {}) {
@@ -3080,18 +3101,450 @@ var feedbackPlugin = ({
3080
3101
  }
3081
3102
  };
3082
3103
  };
3104
+ var CurlSchema = z.object({
3105
+ url: z.string().describe("Request URL"),
3106
+ request: z.enum(["GET", "POST", "PUT", "DELETE", "PATCH", "HEAD", "OPTIONS"]).optional().describe("HTTP method (defaults to GET, or POST if data is provided)"),
3107
+ header: z.array(z.string()).optional().describe("HTTP headers in 'Key: Value' format (repeatable)"),
3108
+ data: z.array(z.string()).optional().describe("HTTP POST data (repeatable, joined with &)"),
3109
+ dataRaw: z.array(z.string()).optional().describe("HTTP POST data without special interpretation (repeatable)"),
3110
+ dataAscii: z.array(z.string()).optional().describe("HTTP POST ASCII data (repeatable)"),
3111
+ dataBinary: z.array(z.string()).optional().describe("HTTP POST binary data (repeatable)"),
3112
+ dataUrlencode: z.array(z.string()).optional().describe("HTTP POST data, URL-encoded (repeatable)"),
3113
+ json: z.string().optional().describe("Send JSON body (sets Content-Type and Accept headers)"),
3114
+ form: z.array(z.string()).optional().describe("Multipart form data as 'name=value' (repeatable)"),
3115
+ formString: z.array(z.string()).optional().describe("Multipart form string field (repeatable)"),
3116
+ get: z.boolean().optional().describe("Force GET method and append data to query string"),
3117
+ head: z.boolean().optional().describe("Fetch headers only (HEAD request)"),
3118
+ location: z.boolean().optional().describe("Follow redirects"),
3119
+ include: z.boolean().optional().describe("Include response headers in output"),
3120
+ output: z.string().optional().describe("Write output to file instead of stdout"),
3121
+ remoteName: z.boolean().optional().describe("Write output to file named like the remote file"),
3122
+ verbose: z.boolean().optional().describe("Verbose output (show request/response headers on stderr)"),
3123
+ silent: z.boolean().optional().describe("Silent mode (suppress errors)"),
3124
+ showError: z.boolean().optional().describe("Show errors even when in silent mode"),
3125
+ fail: z.boolean().optional().describe("Fail silently on HTTP errors (exit code 22)"),
3126
+ failWithBody: z.boolean().optional().describe("Fail on HTTP errors but still output the body"),
3127
+ writeOut: z.string().optional().describe("Output format string after completion (e.g., '%{http_code}')"),
3128
+ maxTime: z.number().optional().describe("Maximum time in seconds for the request"),
3129
+ user: z.string().optional().describe("Basic auth credentials as 'user:password'"),
3130
+ compressed: z.boolean().optional().describe("Request compressed response (sends Accept-Encoding header)"),
3131
+ connectionId: z.union([z.string(), z.number()]).optional().describe("Zapier connection ID for authentication")
3132
+ }).describe("Make HTTP requests through Zapier Relay with curl-like options");
3133
+ var CurlExitError = class extends Error {
3134
+ constructor(message, exitCode) {
3135
+ super(message);
3136
+ this.exitCode = exitCode;
3137
+ this.name = "CurlExitError";
3138
+ }
3139
+ };
3140
+ function parseHeaderLine(input) {
3141
+ const idx = input.indexOf(":");
3142
+ if (idx === -1) {
3143
+ return null;
3144
+ }
3145
+ const key = input.slice(0, idx).trim();
3146
+ const value = input.slice(idx + 1).trim();
3147
+ if (!key) {
3148
+ return null;
3149
+ }
3150
+ return { key, value };
3151
+ }
3152
+ function basicAuthHeader(userpass) {
3153
+ const idx = userpass.indexOf(":");
3154
+ const user = idx === -1 ? userpass : userpass.slice(0, idx);
3155
+ const pass = idx === -1 ? "" : userpass.slice(idx + 1);
3156
+ const token = Buffer.from(`${user}:${pass}`, "utf8").toString("base64");
3157
+ return `Basic ${token}`;
3158
+ }
3159
+ function deriveRemoteFilename(url) {
3160
+ const path2 = url.pathname;
3161
+ const candidate = path2.endsWith("/") ? "index.html" : basename(path2);
3162
+ return candidate || "index.html";
3163
+ }
3164
+ function decodeWriteOutEscapes(input) {
3165
+ return input.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ");
3166
+ }
3167
+ function formatWriteOut(params) {
3168
+ const { template } = params;
3169
+ const replacements = {
3170
+ "%{http_code}": String(params.httpCode).padStart(3, "0"),
3171
+ "%{time_total}": params.timeTotalSeconds.toFixed(3),
3172
+ "%{size_download}": String(params.sizeDownloadBytes),
3173
+ "%{url_effective}": params.urlEffective,
3174
+ "%{content_type}": params.contentType ?? ""
3175
+ };
3176
+ let out = template;
3177
+ for (const [token, value] of Object.entries(replacements)) {
3178
+ out = out.split(token).join(value);
3179
+ }
3180
+ return decodeWriteOutEscapes(out);
3181
+ }
3182
+ function appendQueryParams(url, dataParts) {
3183
+ const out = new URL(url.toString());
3184
+ for (const part of dataParts) {
3185
+ const segments = part.split("&");
3186
+ for (const seg of segments) {
3187
+ if (!seg) continue;
3188
+ const idx = seg.indexOf("=");
3189
+ if (idx === -1) {
3190
+ out.searchParams.append(seg, "");
3191
+ } else {
3192
+ out.searchParams.append(seg.slice(0, idx), seg.slice(idx + 1));
3193
+ }
3194
+ }
3195
+ }
3196
+ return out;
3197
+ }
3198
+ async function readAllStdin() {
3199
+ const chunks = [];
3200
+ for await (const chunk of process.stdin) {
3201
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
3202
+ }
3203
+ return Buffer.concat(chunks);
3204
+ }
3205
+ async function resolveDataArgText(raw) {
3206
+ if (!raw.startsWith("@")) {
3207
+ return raw;
3208
+ }
3209
+ const source = raw.slice(1);
3210
+ if (source === "-") {
3211
+ const buf2 = await readAllStdin();
3212
+ return buf2.toString("utf8");
3213
+ }
3214
+ const buf = await promises.readFile(source);
3215
+ return buf.toString("utf8");
3216
+ }
3217
+ async function resolveDataArgBinary(raw) {
3218
+ if (!raw.startsWith("@")) {
3219
+ return Buffer.from(raw, "utf8");
3220
+ }
3221
+ const source = raw.slice(1);
3222
+ if (source === "-") {
3223
+ return await readAllStdin();
3224
+ }
3225
+ return await promises.readFile(source);
3226
+ }
3227
+ async function buildFormData(formArgs, formStringArgs) {
3228
+ if (typeof FormData === "undefined") {
3229
+ throw new CurlExitError(
3230
+ "FormData is not available in this runtime; cannot use --form.",
3231
+ 2
3232
+ );
3233
+ }
3234
+ const fd = new FormData();
3235
+ const addField = async (item, forceString) => {
3236
+ const idx = item.indexOf("=");
3237
+ if (idx === -1) {
3238
+ throw new CurlExitError(
3239
+ `Invalid form field: '${item}'. Expected 'name=value' or 'name=@file'.`,
3240
+ 2
3241
+ );
3242
+ }
3243
+ const name = item.slice(0, idx);
3244
+ const value = item.slice(idx + 1);
3245
+ if (!name) {
3246
+ throw new CurlExitError(
3247
+ `Invalid form field: '${item}'. Field name cannot be empty.`,
3248
+ 2
3249
+ );
3250
+ }
3251
+ if (!forceString && value.startsWith("@")) {
3252
+ const filePath = value.slice(1);
3253
+ const buf = filePath === "-" ? await readAllStdin() : await promises.readFile(filePath);
3254
+ if (typeof Blob === "undefined") {
3255
+ fd.append(name, buf.toString("utf8"));
3256
+ return;
3257
+ }
3258
+ const blob = new Blob([buf]);
3259
+ const filename = filePath === "-" ? `stdin-${createHash("sha1").update(buf).digest("hex").slice(0, 8)}` : basename(filePath);
3260
+ fd.append(name, blob, filename);
3261
+ return;
3262
+ }
3263
+ fd.append(name, value);
3264
+ };
3265
+ for (const item of formArgs) {
3266
+ await addField(item, false);
3267
+ }
3268
+ for (const item of formStringArgs) {
3269
+ await addField(item, true);
3270
+ }
3271
+ return fd;
3272
+ }
3273
+
3274
+ // src/plugins/curl/index.ts
3275
+ var curlPlugin = ({
3276
+ sdk: sdk2
3277
+ }) => {
3278
+ async function curl(options) {
3279
+ const {
3280
+ url: rawUrl,
3281
+ request,
3282
+ header = [],
3283
+ data = [],
3284
+ dataRaw = [],
3285
+ dataAscii = [],
3286
+ dataBinary = [],
3287
+ dataUrlencode = [],
3288
+ json,
3289
+ form = [],
3290
+ formString = [],
3291
+ get: forceGet,
3292
+ head: forceHead,
3293
+ location,
3294
+ include,
3295
+ output,
3296
+ remoteName,
3297
+ verbose,
3298
+ silent,
3299
+ showError,
3300
+ fail,
3301
+ failWithBody,
3302
+ writeOut,
3303
+ maxTime,
3304
+ user,
3305
+ compressed,
3306
+ connectionId
3307
+ } = options;
3308
+ const parsedUrl = new URL(rawUrl);
3309
+ const headers = {};
3310
+ for (const h of header) {
3311
+ const parsed = parseHeaderLine(h);
3312
+ if (parsed) {
3313
+ headers[parsed.key] = parsed.value;
3314
+ }
3315
+ }
3316
+ if (user) {
3317
+ headers["Authorization"] = basicAuthHeader(user);
3318
+ }
3319
+ if (compressed) {
3320
+ headers["Accept-Encoding"] = "gzip, deflate, br";
3321
+ }
3322
+ const rawTextDataArgs = [...data, ...dataRaw, ...dataAscii];
3323
+ const rawBinaryDataArgs = [...dataBinary];
3324
+ const rawUrlencodeArgs = [...dataUrlencode];
3325
+ const hasForm = form.length > 0 || formString.length > 0;
3326
+ const hasJson = json !== void 0;
3327
+ const hasAnyData = hasJson || hasForm || rawTextDataArgs.length > 0 || rawBinaryDataArgs.length > 0 || rawUrlencodeArgs.length > 0;
3328
+ let method = "GET";
3329
+ if (forceHead) {
3330
+ method = "HEAD";
3331
+ } else if (request) {
3332
+ method = request;
3333
+ } else if (forceGet) {
3334
+ method = "GET";
3335
+ } else if (hasAnyData) {
3336
+ method = "POST";
3337
+ }
3338
+ let body;
3339
+ let effectiveUrl = parsedUrl;
3340
+ if (hasJson) {
3341
+ if (!headers["Content-Type"]) {
3342
+ headers["Content-Type"] = "application/json";
3343
+ }
3344
+ if (!headers["Accept"]) {
3345
+ headers["Accept"] = "application/json";
3346
+ }
3347
+ body = json;
3348
+ } else if (hasForm) {
3349
+ body = await buildFormData(form, formString);
3350
+ } else {
3351
+ const resolvedTextParts = [];
3352
+ for (const raw of rawTextDataArgs) {
3353
+ resolvedTextParts.push(await resolveDataArgText(raw));
3354
+ }
3355
+ const resolvedUrlEncodeParts = [];
3356
+ for (const raw of rawUrlencodeArgs) {
3357
+ if (raw.startsWith("@")) {
3358
+ const content = await resolveDataArgText(raw);
3359
+ resolvedUrlEncodeParts.push(encodeURIComponent(content));
3360
+ continue;
3361
+ }
3362
+ const atIdx = raw.indexOf("@");
3363
+ const eqIdx = raw.indexOf("=");
3364
+ if (eqIdx !== -1) {
3365
+ const key = raw.slice(0, eqIdx);
3366
+ const value = raw.slice(eqIdx + 1);
3367
+ resolvedUrlEncodeParts.push(
3368
+ `${encodeURIComponent(key)}=${encodeURIComponent(value)}`
3369
+ );
3370
+ } else if (atIdx !== -1) {
3371
+ const key = raw.slice(0, atIdx);
3372
+ const filePath = raw.slice(atIdx + 1);
3373
+ const buf2 = filePath === "-" ? await readAllStdin() : await promises.readFile(filePath);
3374
+ resolvedUrlEncodeParts.push(
3375
+ `${encodeURIComponent(key)}=${encodeURIComponent(buf2.toString("utf8"))}`
3376
+ );
3377
+ } else {
3378
+ resolvedUrlEncodeParts.push(encodeURIComponent(raw));
3379
+ }
3380
+ }
3381
+ const resolvedBinaryParts = [];
3382
+ for (const raw of rawBinaryDataArgs) {
3383
+ resolvedBinaryParts.push(await resolveDataArgBinary(raw));
3384
+ }
3385
+ const allTextParts = [...resolvedTextParts, ...resolvedUrlEncodeParts];
3386
+ if (forceGet && allTextParts.length > 0) {
3387
+ effectiveUrl = appendQueryParams(parsedUrl, allTextParts);
3388
+ } else if (resolvedBinaryParts.length > 0) {
3389
+ body = Buffer.concat(resolvedBinaryParts);
3390
+ } else if (allTextParts.length > 0) {
3391
+ body = allTextParts.join("&");
3392
+ if (!headers["Content-Type"]) {
3393
+ headers["Content-Type"] = "application/x-www-form-urlencoded";
3394
+ }
3395
+ }
3396
+ }
3397
+ const redirect = location ? "follow" : "manual";
3398
+ if (verbose && !silent) {
3399
+ process.stderr.write(`> ${method} ${effectiveUrl.toString()}
3400
+ `);
3401
+ for (const [k, v] of Object.entries(headers)) {
3402
+ process.stderr.write(`> ${k}: ${v}
3403
+ `);
3404
+ }
3405
+ process.stderr.write(">\n");
3406
+ }
3407
+ const signal = maxTime ? AbortSignal.timeout(maxTime * 1e3) : void 0;
3408
+ const start = performance.now();
3409
+ const response = await sdk2.fetch(effectiveUrl.toString(), {
3410
+ method,
3411
+ headers,
3412
+ body,
3413
+ redirect,
3414
+ signal,
3415
+ connectionId
3416
+ });
3417
+ const timeTotalSeconds = (performance.now() - start) / 1e3;
3418
+ if (verbose && !silent) {
3419
+ process.stderr.write(
3420
+ `< HTTP ${response.status} ${response.statusText}
3421
+ `
3422
+ );
3423
+ response.headers.forEach((value, key) => {
3424
+ process.stderr.write(`< ${key}: ${value}
3425
+ `);
3426
+ });
3427
+ process.stderr.write("<\n");
3428
+ }
3429
+ const isHttpError = response.status >= 400;
3430
+ const shouldFail = (fail || failWithBody) && isHttpError;
3431
+ const shouldOutputBody = !shouldFail || !!failWithBody;
3432
+ const headerText = include ? `HTTP ${response.status} ${response.statusText}
3433
+ ${Array.from(
3434
+ response.headers.entries()
3435
+ ).map(([k, v]) => `${k}: ${v}`).join("\n")}
3436
+
3437
+ ` : "";
3438
+ let bodyBytes = 0;
3439
+ const buf = shouldOutputBody ? Buffer.from(await response.arrayBuffer()) : Buffer.alloc(0);
3440
+ bodyBytes = buf.length;
3441
+ const outputFile = output && output !== "-" ? output : remoteName ? deriveRemoteFilename(parsedUrl) : void 0;
3442
+ if (outputFile) {
3443
+ const dir = dirname(outputFile);
3444
+ if (dir !== ".") {
3445
+ await promises.mkdir(dir, { recursive: true });
3446
+ }
3447
+ const ws = createWriteStream(outputFile);
3448
+ if (headerText) {
3449
+ ws.write(headerText);
3450
+ }
3451
+ if (buf.length) {
3452
+ ws.write(buf);
3453
+ }
3454
+ await new Promise((resolve4, reject) => {
3455
+ ws.end(() => resolve4());
3456
+ ws.on("error", reject);
3457
+ });
3458
+ } else {
3459
+ if (headerText) {
3460
+ process.stdout.write(headerText);
3461
+ }
3462
+ if (buf.length) {
3463
+ process.stdout.write(buf);
3464
+ }
3465
+ }
3466
+ if (writeOut) {
3467
+ const formatted = formatWriteOut({
3468
+ template: writeOut,
3469
+ urlEffective: response.url || effectiveUrl.toString(),
3470
+ httpCode: response.status,
3471
+ timeTotalSeconds,
3472
+ sizeDownloadBytes: bodyBytes,
3473
+ contentType: response.headers.get("content-type")
3474
+ });
3475
+ process.stdout.write(formatted);
3476
+ }
3477
+ if (shouldFail) {
3478
+ if (!silent || showError) {
3479
+ process.stderr.write(
3480
+ `curl: (22) The requested URL returned error: ${response.status}
3481
+ `
3482
+ );
3483
+ }
3484
+ throw new CurlExitError("HTTP request failed", 22);
3485
+ }
3486
+ return void 0;
3487
+ }
3488
+ return {
3489
+ curl,
3490
+ context: {
3491
+ meta: {
3492
+ curl: {
3493
+ 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.",
3494
+ categories: ["http"],
3495
+ inputSchema: CurlSchema,
3496
+ aliases: {
3497
+ request: "X",
3498
+ header: "H",
3499
+ data: "d",
3500
+ form: "F",
3501
+ get: "G",
3502
+ head: "I",
3503
+ location: "L",
3504
+ include: "i",
3505
+ output: "o",
3506
+ remoteName: "O",
3507
+ verbose: "v",
3508
+ silent: "s",
3509
+ showError: "S",
3510
+ writeOut: "w",
3511
+ maxTime: "m",
3512
+ user: "u"
3513
+ }
3514
+ }
3515
+ }
3516
+ }
3517
+ };
3518
+ };
3519
+
3520
+ // src/plugins/cliOverrides/index.ts
3521
+ var cliOverridesPlugin = ({ context }) => {
3522
+ if (!context.meta.fetch) {
3523
+ return { context: { meta: {} } };
3524
+ }
3525
+ return {
3526
+ context: {
3527
+ meta: {
3528
+ fetch: {
3529
+ ...context.meta.fetch,
3530
+ categories: [...context.meta.fetch.categories || [], "deprecated"]
3531
+ }
3532
+ }
3533
+ }
3534
+ };
3535
+ };
3083
3536
 
3084
3537
  // src/sdk.ts
3085
3538
  function createZapierCliSdk(options = {}) {
3086
3539
  return createZapierSdkWithoutRegistry({
3087
3540
  ...options
3088
- }).addPlugin(generateAppTypesPlugin).addPlugin(buildManifestPlugin).addPlugin(bundleCodePlugin).addPlugin(getLoginConfigPathPlugin).addPlugin(addPlugin).addPlugin(feedbackPlugin).addPlugin(mcpPlugin).addPlugin(loginPlugin).addPlugin(logoutPlugin).addPlugin(registryPlugin);
3541
+ }).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
3542
  }
3090
3543
 
3091
3544
  // package.json with { type: 'json' }
3092
3545
  var package_default2 = {
3093
3546
  name: "@zapier/zapier-sdk-cli",
3094
- version: "0.30.0"};
3547
+ version: "0.31.0"};
3095
3548
  function detectPackageManager(cwd = process.cwd()) {
3096
3549
  const ua = process.env.npm_config_user_agent;
3097
3550
  if (ua) {
@@ -3294,7 +3747,7 @@ async function checkAndNotifyUpdates({
3294
3747
 
3295
3748
  // src/cli.ts
3296
3749
  var program = new Command();
3297
- program.name("zapier-sdk").description("CLI for Zapier SDK").version(package_default2.version, "-v, --version", "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(
3750
+ 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
3751
  "--credentials-client-secret <secret>",
3299
3752
  "OAuth client secret for authentication"
3300
3753
  ).option(
@@ -3306,7 +3759,7 @@ program.name("zapier-sdk").description("CLI for Zapier SDK").version(package_def
3306
3759
  ).option(
3307
3760
  "--max-network-retry-delay-ms <ms>",
3308
3761
  "Max delay in ms to wait for rate limit retry (default: 60000)"
3309
- );
3762
+ ).helpOption("-h, --help", "Display help for command");
3310
3763
  var isDebugMode = process.env.DEBUG === "true" || process.argv.includes("--debug");
3311
3764
  function getFlagValue(flagName) {
3312
3765
  const index = process.argv.indexOf(flagName);