@zapier/zapier-sdk-cli 0.44.0 → 0.45.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +392 -40
  3. package/bin/zapier-sdk-experimental.mjs +14 -0
  4. package/dist/cli.cjs +585 -37
  5. package/dist/cli.mjs +584 -36
  6. package/dist/experimental.cjs +3519 -0
  7. package/dist/experimental.d.mts +39 -0
  8. package/dist/experimental.d.ts +39 -0
  9. package/dist/experimental.mjs +3483 -0
  10. package/dist/index.cjs +507 -26
  11. package/dist/index.d.mts +3 -514
  12. package/dist/index.d.ts +3 -514
  13. package/dist/index.mjs +505 -24
  14. package/dist/package.json +14 -2
  15. package/dist/sdk-B3nKAZdN.d.mts +516 -0
  16. package/dist/sdk-B3nKAZdN.d.ts +516 -0
  17. package/dist/src/cli.js +26 -2
  18. package/dist/src/experimental.d.ts +33 -0
  19. package/dist/src/experimental.js +83 -0
  20. package/dist/src/generators/ast-generator.d.ts +2 -2
  21. package/dist/src/generators/ast-generator.js +1 -1
  22. package/dist/src/plugins/add/index.d.ts +2 -2
  23. package/dist/src/plugins/bundleCode/index.js +3 -12
  24. package/dist/src/plugins/curl/index.js +2 -2
  25. package/dist/src/plugins/curl/utils.d.ts +11 -1
  26. package/dist/src/plugins/curl/utils.js +14 -5
  27. package/dist/src/plugins/drainTriggerInbox/index.d.ts +46 -0
  28. package/dist/src/plugins/drainTriggerInbox/index.js +178 -0
  29. package/dist/src/plugins/generateAppTypes/index.d.ts +2 -2
  30. package/dist/src/plugins/index.d.ts +2 -0
  31. package/dist/src/plugins/index.js +2 -0
  32. package/dist/src/plugins/mcp/index.d.ts +1 -0
  33. package/dist/src/plugins/mcp/index.js +5 -1
  34. package/dist/src/plugins/watchTriggerInbox/index.d.ts +45 -0
  35. package/dist/src/plugins/watchTriggerInbox/index.js +157 -0
  36. package/dist/src/sdk.js +5 -1
  37. package/dist/src/utils/cli-generator.js +18 -1
  38. package/dist/src/utils/cli-renderer.d.ts +12 -0
  39. package/dist/src/utils/cli-renderer.js +22 -1
  40. package/dist/src/utils/parameter-resolver.d.ts +1 -0
  41. package/dist/src/utils/parameter-resolver.js +55 -9
  42. package/dist/src/utils/triggerDrain.d.ts +144 -0
  43. package/dist/src/utils/triggerDrain.js +351 -0
  44. package/dist/tsconfig.tsbuildinfo +1 -1
  45. package/package.json +16 -4
package/dist/index.mjs CHANGED
@@ -7,7 +7,7 @@ import crypto, { createHash } from 'crypto';
7
7
  import * as path from 'path';
8
8
  import { resolve, join, dirname, basename, relative, extname } from 'path';
9
9
  import * as lockfile from 'proper-lockfile';
10
- import { definePlugin, createPluginMethod, buildApplicationLifecycleEvent, OutputPropertySchema, DEFAULT_CONFIG_PATH, ZapierValidationError, ZapierUnknownError, injectCliLogin, isCredentialsObject, batch, toSnakeCase, ZapierError, createZapierSdk, getOsInfo, getPlatformVersions, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId } from '@zapier/zapier-sdk';
10
+ import { definePlugin, createPluginMethod, buildApplicationLifecycleEvent, OutputPropertySchema, ZapierBundleError, DEFAULT_CONFIG_PATH, ZapierValidationError, ZapierUnknownError, ZapierReleaseTriggerMessageSignal, injectCliLogin, isCredentialsObject, batch, toSnakeCase, ZapierAbortDrainSignal, ZapierError, createZapierSdk, getOsInfo, getPlatformVersions, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId } from '@zapier/zapier-sdk';
11
11
  import open from 'open';
12
12
  import express from 'express';
13
13
  import pkceChallenge from 'pkce-challenge';
@@ -20,9 +20,10 @@ import { buildSync } from 'esbuild';
20
20
  import { mkdir, writeFile, access } from 'fs/promises';
21
21
  import * as ts from 'typescript';
22
22
  import 'is-installed-globally';
23
- import { execSync } from 'child_process';
23
+ import { execSync, spawn } from 'child_process';
24
24
  import Handlebars from 'handlebars';
25
25
  import { fileURLToPath } from 'url';
26
+ import 'wrap-ansi';
26
27
 
27
28
  var __defProp = Object.defineProperty;
28
29
  var __export = (target, all) => {
@@ -624,6 +625,14 @@ var ZapierCliExitError = class extends ZapierCliError {
624
625
  this.exitCode = exitCode;
625
626
  }
626
627
  };
628
+ var ZapierCliValidationError = class extends ZapierCliError {
629
+ constructor(message) {
630
+ super(message);
631
+ this.name = "ZapierCliValidationError";
632
+ this.code = "ZAPIER_CLI_VALIDATION_ERROR";
633
+ this.exitCode = 1;
634
+ }
635
+ };
627
636
 
628
637
  // src/utils/spinner.ts
629
638
  var spinPromise = async (promise, text) => {
@@ -960,7 +969,8 @@ var mcpPlugin = definePlugin(
960
969
  await startMcpServer({
961
970
  ...options,
962
971
  debug: sdk2.context.options?.debug,
963
- extensions: sdk2.context.extensions
972
+ extensions: sdk2.context.extensions,
973
+ experimental: sdk2.context.experimental
964
974
  });
965
975
  }
966
976
  })
@@ -983,15 +993,6 @@ var bundleCodePlugin = definePlugin(
983
993
  handler: async ({ options }) => bundleCode(options)
984
994
  })
985
995
  );
986
- var ZapierBundleError = class extends Error {
987
- constructor(message, details, originalError) {
988
- super(message);
989
- this.code = "ZAPIER_BUNDLE_ERROR";
990
- this.name = "ZapierBundleError";
991
- this.details = details;
992
- this.originalError = originalError;
993
- }
994
- };
995
996
  async function bundleCode(options) {
996
997
  const {
997
998
  input,
@@ -1021,7 +1022,7 @@ async function bundleCode(options) {
1021
1022
  const errorMessages = result.errors.map((e) => e.text);
1022
1023
  throw new ZapierBundleError(
1023
1024
  `Bundle failed: ${errorMessages.join(", ")}`,
1024
- errorMessages
1025
+ { buildErrors: errorMessages }
1025
1026
  );
1026
1027
  }
1027
1028
  const bundledCode = result.outputFiles?.[0]?.text;
@@ -1043,8 +1044,7 @@ async function bundleCode(options) {
1043
1044
  }
1044
1045
  throw new ZapierBundleError(
1045
1046
  `Bundle failed: ${error instanceof Error ? error.message : "Unknown error"}`,
1046
- void 0,
1047
- error instanceof Error ? error : void 0
1047
+ { cause: error instanceof Error ? error : void 0 }
1048
1048
  );
1049
1049
  }
1050
1050
  }
@@ -1219,7 +1219,7 @@ var AstTypeGenerator = class {
1219
1219
  const actions = actionsResult.data;
1220
1220
  const actionsWithFields = [];
1221
1221
  const inputFieldsTasks = actions.map(
1222
- (action) => () => sdk.listInputFields({
1222
+ (action) => () => sdk.listActionInputFields({
1223
1223
  appKey: app.implementation_id,
1224
1224
  actionKey: action.key,
1225
1225
  actionType: action.action_type,
@@ -2096,11 +2096,12 @@ var CurlSchema = z.object({
2096
2096
  /** @deprecated Use `connection` instead. */
2097
2097
  connectionId: z.union([z.string(), z.number()]).optional().meta({ deprecated: true })
2098
2098
  }).describe("Make HTTP requests through Zapier Relay with curl-like options");
2099
- var CurlExitError = class extends Error {
2099
+ var ZapierCurlExitError = class extends ZapierError {
2100
2100
  constructor(message, exitCode) {
2101
2101
  super(message);
2102
+ this.name = "ZapierCurlExitError";
2103
+ this.code = "ZAPIER_CURL_EXIT_ERROR";
2102
2104
  this.exitCode = exitCode;
2103
- this.name = "CurlExitError";
2104
2105
  }
2105
2106
  };
2106
2107
  function parseHeaderLine(input) {
@@ -2192,7 +2193,7 @@ async function resolveDataArgBinary(raw) {
2192
2193
  }
2193
2194
  async function buildFormData(formArgs, formStringArgs) {
2194
2195
  if (typeof FormData === "undefined") {
2195
- throw new CurlExitError(
2196
+ throw new ZapierCurlExitError(
2196
2197
  "FormData is not available in this runtime; cannot use --form.",
2197
2198
  2
2198
2199
  );
@@ -2201,7 +2202,7 @@ async function buildFormData(formArgs, formStringArgs) {
2201
2202
  const addField = async (item, forceString) => {
2202
2203
  const idx = item.indexOf("=");
2203
2204
  if (idx === -1) {
2204
- throw new CurlExitError(
2205
+ throw new ZapierCurlExitError(
2205
2206
  `Invalid form field: '${item}'. Expected 'name=value' or 'name=@file'.`,
2206
2207
  2
2207
2208
  );
@@ -2209,7 +2210,7 @@ async function buildFormData(formArgs, formStringArgs) {
2209
2210
  const name = item.slice(0, idx);
2210
2211
  const value = item.slice(idx + 1);
2211
2212
  if (!name) {
2212
- throw new CurlExitError(
2213
+ throw new ZapierCurlExitError(
2213
2214
  `Invalid form field: '${item}'. Field name cannot be empty.`,
2214
2215
  2
2215
2216
  );
@@ -2446,7 +2447,7 @@ ${Array.from(
2446
2447
  `
2447
2448
  );
2448
2449
  }
2449
- throw new CurlExitError("HTTP request failed", 22);
2450
+ throw new ZapierCurlExitError("HTTP request failed", 22);
2450
2451
  }
2451
2452
  return void 0;
2452
2453
  }
@@ -2965,11 +2966,491 @@ var initPlugin = definePlugin(
2965
2966
  }
2966
2967
  })
2967
2968
  );
2969
+ function jsonReplacer(_key, value) {
2970
+ if (value instanceof Error) {
2971
+ return {
2972
+ name: value.name,
2973
+ message: value.message,
2974
+ ...value.stack ? { stack: value.stack } : {}
2975
+ };
2976
+ }
2977
+ return value;
2978
+ }
2979
+ var CliSkipLeaseExpireError = class extends Error {
2980
+ constructor() {
2981
+ super("user skipped (let lease expire)");
2982
+ this.name = "CliSkipLeaseExpireError";
2983
+ }
2984
+ };
2985
+ function createInteractiveCallback() {
2986
+ let messageNumber = 0;
2987
+ return async (message) => {
2988
+ messageNumber++;
2989
+ const attrs = message.message_attributes;
2990
+ console.log(
2991
+ `
2992
+ ${chalk3.bold(`Message #${messageNumber}`)} ${chalk3.dim(message.id)} ${chalk3.dim(`(lease #${attrs.lease_count})`)}`
2993
+ );
2994
+ if (attrs.error_message) {
2995
+ console.log(chalk3.yellow(` upstream error: ${attrs.error_message}`));
2996
+ }
2997
+ if (attrs.possible_duplicate_data) {
2998
+ console.log(chalk3.yellow(" possible duplicate data"));
2999
+ }
3000
+ while (true) {
3001
+ let action;
3002
+ try {
3003
+ const answer = await inquirer.prompt([
3004
+ {
3005
+ type: "list",
3006
+ name: "action",
3007
+ message: "Action?",
3008
+ choices: [
3009
+ { name: "Ack (remove from inbox)", value: "ack" },
3010
+ {
3011
+ name: "Skip (release after draining)",
3012
+ value: "skip-release"
3013
+ },
3014
+ { name: "Skip (let lease expire)", value: "skip-expire" },
3015
+ { name: "View payload", value: "view" },
3016
+ { name: "Quit", value: "quit" }
3017
+ ]
3018
+ }
3019
+ ]);
3020
+ action = answer.action;
3021
+ } catch (error) {
3022
+ if (error instanceof Error && error.name === "ExitPromptError") {
3023
+ throw new ZapierAbortDrainSignal("user pressed Ctrl-C");
3024
+ }
3025
+ throw error;
3026
+ }
3027
+ if (action === "view") {
3028
+ console.log(chalk3.dim(JSON.stringify(message.payload, null, 2)));
3029
+ continue;
3030
+ }
3031
+ if (action === "ack") {
3032
+ return;
3033
+ }
3034
+ if (action === "skip-release") {
3035
+ throw new ZapierReleaseTriggerMessageSignal("user skipped (release)");
3036
+ }
3037
+ if (action === "skip-expire") {
3038
+ throw new CliSkipLeaseExpireError();
3039
+ }
3040
+ if (action === "quit") {
3041
+ throw new ZapierAbortDrainSignal("user requested quit");
3042
+ }
3043
+ }
3044
+ };
3045
+ }
3046
+ function createNdjsonCallback() {
3047
+ return (message) => new Promise((resolve4, reject) => {
3048
+ process.stdout.write(JSON.stringify(message) + "\n", (err) => {
3049
+ if (err) reject(err);
3050
+ else resolve4();
3051
+ });
3052
+ });
3053
+ }
3054
+ function runSubprocess(options) {
3055
+ const { command, args, shell, label, message, signal } = options;
3056
+ return new Promise((resolve4, reject) => {
3057
+ const child = spawn(command, args, {
3058
+ shell,
3059
+ stdio: ["pipe", "inherit", "inherit"]
3060
+ });
3061
+ let abortListener;
3062
+ if (signal) {
3063
+ if (signal.aborted) {
3064
+ child.kill();
3065
+ } else {
3066
+ abortListener = () => {
3067
+ child.kill();
3068
+ };
3069
+ signal.addEventListener("abort", abortListener, { once: true });
3070
+ }
3071
+ }
3072
+ child.on("error", (err) => {
3073
+ if (signal && abortListener) {
3074
+ signal.removeEventListener("abort", abortListener);
3075
+ }
3076
+ reject(err);
3077
+ });
3078
+ child.on("close", (code) => {
3079
+ if (signal && abortListener) {
3080
+ signal.removeEventListener("abort", abortListener);
3081
+ }
3082
+ if (signal?.aborted) {
3083
+ reject(new ZapierAbortDrainSignal(`${label} aborted`));
3084
+ return;
3085
+ }
3086
+ if (code === 0) resolve4();
3087
+ else
3088
+ reject(
3089
+ new Error(
3090
+ `${label} exited with code ${code} for message ${message.id}`
3091
+ )
3092
+ );
3093
+ });
3094
+ child.stdin.on("error", (err) => {
3095
+ if (err.code !== "EPIPE") reject(err);
3096
+ });
3097
+ child.stdin.end(JSON.stringify(message) + "\n");
3098
+ });
3099
+ }
3100
+ function runShellCommand(command, message, signal) {
3101
+ return runSubprocess({
3102
+ command,
3103
+ args: [],
3104
+ shell: true,
3105
+ label: "exec-shell",
3106
+ message,
3107
+ signal
3108
+ });
3109
+ }
3110
+ function runExecCommand(argv, message, signal) {
3111
+ if (argv.length === 0) {
3112
+ return Promise.reject(
3113
+ new Error("exec requires at least one element (the binary)")
3114
+ );
3115
+ }
3116
+ const [command, ...args] = argv;
3117
+ return runSubprocess({
3118
+ command,
3119
+ args,
3120
+ shell: false,
3121
+ label: "exec",
3122
+ message,
3123
+ signal
3124
+ });
3125
+ }
3126
+ function describeReason(reason) {
3127
+ return reason instanceof Error ? reason.message : String(reason);
3128
+ }
3129
+ function printDrainError(reason, message) {
3130
+ console.error(
3131
+ chalk3.red(`Error processing ${message.id}: ${describeReason(reason)}`)
3132
+ );
3133
+ }
3134
+ function printDrainSummary(counts) {
3135
+ const skipped = counts.skipped ?? 0;
3136
+ const total = counts.fulfilled + counts.rejected + skipped;
3137
+ const parts = [`${counts.fulfilled} fulfilled`];
3138
+ if (skipped > 0) parts.push(`${skipped} skipped`);
3139
+ parts.push(`${counts.rejected} rejected`);
3140
+ console.log(
3141
+ chalk3.dim(
3142
+ `
3143
+ Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
3144
+ )
3145
+ );
3146
+ }
3147
+ function warnInteractiveContinueOnErrorOverride() {
3148
+ console.warn(
3149
+ chalk3.yellow(
3150
+ 'Note: continueOnError=false is overridden to true in interactive mode (the "Skip (let lease expire)" choice would otherwise terminate the drain).'
3151
+ )
3152
+ );
3153
+ }
3154
+ function requireInteractiveTty(commandName) {
3155
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
3156
+ throw new ZapierCliValidationError(
3157
+ `${commandName} needs an interactive terminal by default. Pass --exec '<bin>' (with optional \`-- args...\`) or --exec-shell '<cmd>' to run a script per message, or --json for non-interactive output.`
3158
+ );
3159
+ }
3160
+ }
3161
+ function rejectExecJsonMutex(opts) {
3162
+ const picked = [
3163
+ opts.exec ? "--exec" : null,
3164
+ opts.execShell ? "--exec-shell" : null,
3165
+ opts.json ? "--json" : null
3166
+ ].filter((x) => x !== null);
3167
+ if (picked.length > 1) {
3168
+ throw new ZapierCliValidationError(
3169
+ `${picked.join(", ")} are mutually exclusive. Pick one.`
3170
+ );
3171
+ }
3172
+ }
3173
+ function getPostDashArgs(argv = process.argv) {
3174
+ const idx = argv.indexOf("--");
3175
+ if (idx === -1) return [];
3176
+ return argv.slice(idx + 1);
3177
+ }
3178
+ function combineSignals(a, b) {
3179
+ if (!a) {
3180
+ return { signal: b, dispose: () => void 0 };
3181
+ }
3182
+ const controller = new AbortController();
3183
+ const onAbort = () => controller.abort();
3184
+ if (a.aborted || b.aborted) controller.abort();
3185
+ else {
3186
+ a.addEventListener("abort", onAbort, { once: true });
3187
+ b.addEventListener("abort", onAbort, { once: true });
3188
+ }
3189
+ return {
3190
+ signal: controller.signal,
3191
+ dispose: () => {
3192
+ a.removeEventListener("abort", onAbort);
3193
+ b.removeEventListener("abort", onAbort);
3194
+ }
3195
+ };
3196
+ }
3197
+
3198
+ // src/plugins/drainTriggerInbox/index.ts
3199
+ var JsonProperty = z.boolean().optional().describe(
3200
+ "Format the drained result as a JSON object on stdout: { data, errors }. Use for scripts or piping. Mutually exclusive with --exec / --exec-shell and the interactive default."
3201
+ );
3202
+ var ExecCliProperty = z.string().optional().describe(
3203
+ "Run a binary per message with no shell interpretation. Message JSON is piped to stdin; exit code 0 acks, non-zero records the error per the same rules as a thrown handler. Pass extra argv after `--` (e.g. `--exec ./handler -- --verbose`). Mutually exclusive with --exec-shell and --json."
3204
+ );
3205
+ var ExecShellCliProperty = z.string().optional().describe(
3206
+ "Run a shell command per message. Message JSON is piped to the subprocess on stdin; exit code 0 acks, non-zero records the error per the same rules as a thrown handler. Interpreted by the platform's default shell (sh on POSIX, cmd.exe on Windows). Mutually exclusive with --exec and --json."
3207
+ );
3208
+ definePlugin(
3209
+ (sdk) => {
3210
+ const original = sdk.drainTriggerInbox;
3211
+ const existingMeta = sdk.context.meta.drainTriggerInbox;
3212
+ const baseInputSchema = existingMeta.inputSchema;
3213
+ const extendedInputSchema = baseInputSchema ? baseInputSchema.extend({
3214
+ exec: ExecCliProperty,
3215
+ execShell: ExecShellCliProperty,
3216
+ json: JsonProperty
3217
+ }) : z.object({
3218
+ exec: ExecCliProperty,
3219
+ execShell: ExecShellCliProperty,
3220
+ json: JsonProperty
3221
+ });
3222
+ return {
3223
+ drainTriggerInbox: async (options) => {
3224
+ const { json, exec, execShell, ...sdkArgs } = options;
3225
+ rejectExecJsonMutex({ exec, execShell, json });
3226
+ if (!exec && !execShell && !json) {
3227
+ requireInteractiveTty("drain-trigger-inbox");
3228
+ }
3229
+ const sigintController = new AbortController();
3230
+ const onSigint = () => sigintController.abort();
3231
+ process.on("SIGINT", onSigint);
3232
+ const combined = combineSignals(
3233
+ sdkArgs.signal,
3234
+ sigintController.signal
3235
+ );
3236
+ let fulfilled = 0;
3237
+ let rejected = 0;
3238
+ let skipped = 0;
3239
+ const liveOnError = (reason, message) => {
3240
+ rejected++;
3241
+ printDrainError(reason, message);
3242
+ };
3243
+ try {
3244
+ if (exec) {
3245
+ const execArgv = [exec, ...getPostDashArgs()];
3246
+ await original({
3247
+ ...sdkArgs,
3248
+ signal: combined.signal,
3249
+ onMessage: async (message) => {
3250
+ await runExecCommand(execArgv, message, combined.signal);
3251
+ fulfilled++;
3252
+ },
3253
+ onError: liveOnError
3254
+ });
3255
+ return;
3256
+ }
3257
+ if (execShell) {
3258
+ await original({
3259
+ ...sdkArgs,
3260
+ signal: combined.signal,
3261
+ onMessage: async (message) => {
3262
+ await runShellCommand(execShell, message, combined.signal);
3263
+ fulfilled++;
3264
+ },
3265
+ onError: liveOnError
3266
+ });
3267
+ return;
3268
+ }
3269
+ if (json) {
3270
+ const data = [];
3271
+ const errors = [];
3272
+ await original({
3273
+ ...sdkArgs,
3274
+ signal: combined.signal,
3275
+ continueOnError: true,
3276
+ onMessage: (message) => {
3277
+ data.push(message);
3278
+ },
3279
+ onError: (reason, message) => {
3280
+ errors.push({ reason, message });
3281
+ }
3282
+ });
3283
+ process.stdout.write(
3284
+ JSON.stringify({ data, errors }, jsonReplacer, 2) + "\n"
3285
+ );
3286
+ return;
3287
+ }
3288
+ if (sdkArgs.continueOnError === false) {
3289
+ warnInteractiveContinueOnErrorOverride();
3290
+ }
3291
+ const interactive = createInteractiveCallback();
3292
+ await original({
3293
+ ...sdkArgs,
3294
+ signal: combined.signal,
3295
+ concurrency: 1,
3296
+ continueOnError: true,
3297
+ onMessage: async (message) => {
3298
+ try {
3299
+ await interactive(message);
3300
+ fulfilled++;
3301
+ } catch (err) {
3302
+ if (err instanceof ZapierReleaseTriggerMessageSignal || err instanceof CliSkipLeaseExpireError) {
3303
+ skipped++;
3304
+ }
3305
+ throw err;
3306
+ }
3307
+ }
3308
+ });
3309
+ } finally {
3310
+ process.off("SIGINT", onSigint);
3311
+ combined.dispose();
3312
+ if (!json) {
3313
+ printDrainSummary({ fulfilled, rejected, skipped });
3314
+ }
3315
+ }
3316
+ },
3317
+ context: {
3318
+ meta: {
3319
+ drainTriggerInbox: {
3320
+ ...existingMeta,
3321
+ inputSchema: extendedInputSchema,
3322
+ packages: void 0
3323
+ }
3324
+ }
3325
+ }
3326
+ };
3327
+ }
3328
+ );
3329
+ var JsonProperty2 = z.boolean().optional().describe(
3330
+ "Stream each message as JSON to stdout (one record per line, NDJSON), acking as each write completes. Use for piping to other tools. Mutually exclusive with --exec / --exec-shell and the interactive default."
3331
+ );
3332
+ var ExecCliProperty2 = z.string().optional().describe(
3333
+ "Run a binary per message with no shell interpretation. Message JSON is piped to stdin; exit code 0 acks, non-zero records the error per the same rules as a thrown handler. Pass extra argv after `--` (e.g. `--exec ./handler -- --verbose`). Mutually exclusive with --exec-shell and --json."
3334
+ );
3335
+ var ExecShellCliProperty2 = z.string().optional().describe(
3336
+ "Run a shell command per message. Message JSON is piped to the subprocess on stdin; exit code 0 acks, non-zero records the error per the same rules as a thrown handler. Interpreted by the platform's default shell (sh on POSIX, cmd.exe on Windows). Mutually exclusive with --exec and --json."
3337
+ );
3338
+ definePlugin(
3339
+ (sdk) => {
3340
+ const original = sdk.watchTriggerInbox;
3341
+ const existingMeta = sdk.context.meta.watchTriggerInbox;
3342
+ const baseInputSchema = existingMeta.inputSchema;
3343
+ const extendedInputSchema = baseInputSchema ? baseInputSchema.extend({
3344
+ exec: ExecCliProperty2,
3345
+ execShell: ExecShellCliProperty2,
3346
+ json: JsonProperty2
3347
+ }) : z.object({
3348
+ exec: ExecCliProperty2,
3349
+ execShell: ExecShellCliProperty2,
3350
+ json: JsonProperty2
3351
+ });
3352
+ return {
3353
+ watchTriggerInbox: async (options) => {
3354
+ const { json, exec, execShell, ...sdkArgs } = options;
3355
+ rejectExecJsonMutex({ exec, execShell, json });
3356
+ if (!exec && !execShell && !json) {
3357
+ requireInteractiveTty("watch-trigger-inbox");
3358
+ }
3359
+ const sigintController = new AbortController();
3360
+ const onSigint = () => sigintController.abort();
3361
+ process.on("SIGINT", onSigint);
3362
+ const combined = combineSignals(
3363
+ sdkArgs.signal,
3364
+ sigintController.signal
3365
+ );
3366
+ let fulfilled = 0;
3367
+ let rejected = 0;
3368
+ let skipped = 0;
3369
+ const liveOnError = (reason, message) => {
3370
+ rejected++;
3371
+ printDrainError(reason, message);
3372
+ };
3373
+ try {
3374
+ if (exec) {
3375
+ const execArgv = [exec, ...getPostDashArgs()];
3376
+ await original({
3377
+ ...sdkArgs,
3378
+ signal: combined.signal,
3379
+ onMessage: async (message) => {
3380
+ await runExecCommand(execArgv, message, combined.signal);
3381
+ fulfilled++;
3382
+ },
3383
+ onError: liveOnError
3384
+ });
3385
+ } else if (execShell) {
3386
+ await original({
3387
+ ...sdkArgs,
3388
+ signal: combined.signal,
3389
+ onMessage: async (message) => {
3390
+ await runShellCommand(execShell, message, combined.signal);
3391
+ fulfilled++;
3392
+ },
3393
+ onError: liveOnError
3394
+ });
3395
+ } else if (json) {
3396
+ const ndjson = createNdjsonCallback();
3397
+ await original({
3398
+ ...sdkArgs,
3399
+ signal: combined.signal,
3400
+ onMessage: async (message) => {
3401
+ await ndjson(message);
3402
+ fulfilled++;
3403
+ },
3404
+ onError: liveOnError
3405
+ });
3406
+ } else {
3407
+ if (sdkArgs.continueOnError === false) {
3408
+ warnInteractiveContinueOnErrorOverride();
3409
+ }
3410
+ const interactive = createInteractiveCallback();
3411
+ await original({
3412
+ ...sdkArgs,
3413
+ signal: combined.signal,
3414
+ concurrency: 1,
3415
+ continueOnError: true,
3416
+ onMessage: async (message) => {
3417
+ try {
3418
+ await interactive(message);
3419
+ fulfilled++;
3420
+ } catch (err) {
3421
+ if (err instanceof ZapierReleaseTriggerMessageSignal || err instanceof CliSkipLeaseExpireError) {
3422
+ skipped++;
3423
+ }
3424
+ throw err;
3425
+ }
3426
+ }
3427
+ });
3428
+ }
3429
+ } finally {
3430
+ process.off("SIGINT", onSigint);
3431
+ combined.dispose();
3432
+ if (!json) {
3433
+ printDrainSummary({ fulfilled, rejected, skipped });
3434
+ }
3435
+ }
3436
+ },
3437
+ context: {
3438
+ meta: {
3439
+ watchTriggerInbox: {
3440
+ ...existingMeta,
3441
+ inputSchema: extendedInputSchema,
3442
+ packages: void 0
3443
+ }
3444
+ }
3445
+ }
3446
+ };
3447
+ }
3448
+ );
2968
3449
 
2969
3450
  // package.json with { type: 'json' }
2970
3451
  var package_default = {
2971
3452
  name: "@zapier/zapier-sdk-cli",
2972
- version: "0.44.0"};
3453
+ version: "0.45.0"};
2973
3454
 
2974
3455
  // src/sdk.ts
2975
3456
  injectCliLogin(login_exports);
@@ -2997,7 +3478,7 @@ function createZapierCliSdk(options = {}) {
2997
3478
 
2998
3479
  // package.json
2999
3480
  var package_default2 = {
3000
- version: "0.44.0"};
3481
+ version: "0.45.0"};
3001
3482
 
3002
3483
  // src/telemetry/builders.ts
3003
3484
  function createCliBaseEvent(context = {}) {
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zapier/zapier-sdk-cli",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
4
4
  "description": "Command line interface for Zapier SDK",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -27,10 +27,22 @@
27
27
  "types": "./dist/login.d.mts",
28
28
  "default": "./dist/login.mjs"
29
29
  }
30
+ },
31
+ "./experimental": {
32
+ "source": "./src/experimental.ts",
33
+ "require": {
34
+ "types": "./dist/experimental.d.ts",
35
+ "default": "./dist/experimental.cjs"
36
+ },
37
+ "import": {
38
+ "types": "./dist/experimental.d.mts",
39
+ "default": "./dist/experimental.mjs"
40
+ }
30
41
  }
31
42
  },
32
43
  "bin": {
33
- "zapier-sdk": "./bin/zapier-sdk.mjs"
44
+ "zapier-sdk": "./bin/zapier-sdk.mjs",
45
+ "zapier-sdk-experimental": "./bin/zapier-sdk-experimental.mjs"
34
46
  },
35
47
  "scripts": {
36
48
  "test": "vitest",