@zapier/zapier-sdk 0.69.3 → 0.70.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +12 -1
  3. package/dist/api/client.d.ts.map +1 -1
  4. package/dist/api/client.js +10 -1
  5. package/dist/api/error-classification.d.ts +7 -0
  6. package/dist/api/error-classification.d.ts.map +1 -1
  7. package/dist/api/error-classification.js +15 -2
  8. package/dist/api/index.d.ts +1 -1
  9. package/dist/api/index.d.ts.map +1 -1
  10. package/dist/api/sse-parser.d.ts +34 -0
  11. package/dist/api/sse-parser.d.ts.map +1 -1
  12. package/dist/api/sse-parser.js +28 -0
  13. package/dist/api/types.d.ts +9 -1
  14. package/dist/api/types.d.ts.map +1 -1
  15. package/dist/auth.d.ts.map +1 -1
  16. package/dist/auth.js +2 -2
  17. package/dist/experimental.cjs +152 -50
  18. package/dist/experimental.d.mts +12 -12
  19. package/dist/experimental.d.ts +10 -10
  20. package/dist/experimental.mjs +152 -50
  21. package/dist/{index-DuFFW71E.d.mts → index-DjLMJ3w8.d.mts} +36 -4
  22. package/dist/{index-DuFFW71E.d.ts → index-DjLMJ3w8.d.ts} +36 -4
  23. package/dist/index.cjs +32 -5
  24. package/dist/index.d.mts +1 -1
  25. package/dist/index.d.ts +1 -1
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.mjs +32 -5
  28. package/dist/plugins/codeSubstrate/cancelDurableRun/index.d.ts +1 -1
  29. package/dist/plugins/codeSubstrate/cancelDurableRun/index.d.ts.map +1 -1
  30. package/dist/plugins/codeSubstrate/cancelDurableRun/index.js +2 -1
  31. package/dist/plugins/codeSubstrate/createWorkflow/index.d.ts.map +1 -1
  32. package/dist/plugins/codeSubstrate/createWorkflow/index.js +2 -1
  33. package/dist/plugins/codeSubstrate/deleteWorkflow/index.d.ts.map +1 -1
  34. package/dist/plugins/codeSubstrate/deleteWorkflow/index.js +2 -1
  35. package/dist/plugins/codeSubstrate/deleteWorkflow/schemas.d.ts +4 -0
  36. package/dist/plugins/codeSubstrate/deleteWorkflow/schemas.d.ts.map +1 -1
  37. package/dist/plugins/codeSubstrate/deleteWorkflow/schemas.js +7 -0
  38. package/dist/plugins/codeSubstrate/disableWorkflow/index.d.ts.map +1 -1
  39. package/dist/plugins/codeSubstrate/disableWorkflow/index.js +2 -1
  40. package/dist/plugins/codeSubstrate/enableWorkflow/index.d.ts.map +1 -1
  41. package/dist/plugins/codeSubstrate/enableWorkflow/index.js +2 -1
  42. package/dist/plugins/codeSubstrate/getDurableRun/index.d.ts +5 -5
  43. package/dist/plugins/codeSubstrate/getDurableRun/index.d.ts.map +1 -1
  44. package/dist/plugins/codeSubstrate/getDurableRun/index.js +2 -1
  45. package/dist/plugins/codeSubstrate/getDurableRun/schemas.d.ts +24 -24
  46. package/dist/plugins/codeSubstrate/getDurableRun/schemas.d.ts.map +1 -1
  47. package/dist/plugins/codeSubstrate/getDurableRun/schemas.js +4 -9
  48. package/dist/plugins/codeSubstrate/listDurableRuns/index.d.ts +1 -1
  49. package/dist/plugins/codeSubstrate/listDurableRuns/index.d.ts.map +1 -1
  50. package/dist/plugins/codeSubstrate/listDurableRuns/index.js +6 -2
  51. package/dist/plugins/codeSubstrate/listDurableRuns/schemas.d.ts +6 -6
  52. package/dist/plugins/codeSubstrate/listDurableRuns/schemas.d.ts.map +1 -1
  53. package/dist/plugins/codeSubstrate/listDurableRuns/schemas.js +2 -3
  54. package/dist/plugins/codeSubstrate/runDurable/index.d.ts.map +1 -1
  55. package/dist/plugins/codeSubstrate/runDurable/index.js +3 -2
  56. package/dist/plugins/codeSubstrate/updateWorkflow/index.d.ts.map +1 -1
  57. package/dist/plugins/codeSubstrate/updateWorkflow/index.js +2 -1
  58. package/dist/plugins/triggers/drainTriggerInbox/index.d.ts +4 -2
  59. package/dist/plugins/triggers/drainTriggerInbox/index.d.ts.map +1 -1
  60. package/dist/plugins/triggers/drainTriggerInbox/index.js +39 -6
  61. package/dist/plugins/triggers/watchTriggerInbox/index.d.ts +4 -2
  62. package/dist/plugins/triggers/watchTriggerInbox/index.d.ts.map +1 -1
  63. package/dist/plugins/triggers/watchTriggerInbox/index.js +100 -16
  64. package/dist/plugins/triggers/watchTriggerInbox/sse.d.ts +8 -6
  65. package/dist/plugins/triggers/watchTriggerInbox/sse.d.ts.map +1 -1
  66. package/dist/plugins/triggers/watchTriggerInbox/sse.js +11 -13
  67. package/package.json +1 -1
@@ -2691,7 +2691,7 @@ export declare function createZapierSdkStack(options?: ZapierSdkOptions): import
2691
2691
  maxItems?: number;
2692
2692
  }) | undefined) => import("kitcore").PaginatedSdkResult<{
2693
2693
  id: string;
2694
- status: "initialized" | "started" | "finished" | "failed" | "cancelled";
2694
+ status: string;
2695
2695
  input: unknown;
2696
2696
  output: unknown;
2697
2697
  error: {
@@ -2716,7 +2716,7 @@ export declare function createZapierSdkStack(options?: ZapierSdkOptions): import
2716
2716
  } | undefined) => Promise<{
2717
2717
  data: {
2718
2718
  id: string;
2719
- status: "initialized" | "started" | "finished" | "failed" | "cancelled";
2719
+ status: string;
2720
2720
  input: unknown;
2721
2721
  output: unknown;
2722
2722
  error: {
@@ -2727,7 +2727,7 @@ export declare function createZapierSdkStack(options?: ZapierSdkOptions): import
2727
2727
  execution: {
2728
2728
  id: string;
2729
2729
  name: string;
2730
- status: "failed" | "waiting" | "completed" | "running";
2730
+ status: string;
2731
2731
  input: unknown;
2732
2732
  created_at: string;
2733
2733
  output?: unknown;
@@ -2747,8 +2747,8 @@ export declare function createZapierSdkStack(options?: ZapierSdkOptions): import
2747
2747
  id: string;
2748
2748
  execution_id: string;
2749
2749
  name: string;
2750
- type: "step" | "wait" | "callback";
2751
- status: "pending" | "failed" | "exhausted" | "completed";
2750
+ type: string;
2751
+ status: string;
2752
2752
  retry_count: number;
2753
2753
  created_at: string;
2754
2754
  result?: unknown;
@@ -5696,7 +5696,7 @@ export declare function createZapierSdk(options?: ZapierSdkOptions): import("kit
5696
5696
  maxItems?: number;
5697
5697
  }) | undefined) => import("kitcore").PaginatedSdkResult<{
5698
5698
  id: string;
5699
- status: "initialized" | "started" | "finished" | "failed" | "cancelled";
5699
+ status: string;
5700
5700
  input: unknown;
5701
5701
  output: unknown;
5702
5702
  error: {
@@ -5721,7 +5721,7 @@ export declare function createZapierSdk(options?: ZapierSdkOptions): import("kit
5721
5721
  } | undefined) => Promise<{
5722
5722
  data: {
5723
5723
  id: string;
5724
- status: "initialized" | "started" | "finished" | "failed" | "cancelled";
5724
+ status: string;
5725
5725
  input: unknown;
5726
5726
  output: unknown;
5727
5727
  error: {
@@ -5732,7 +5732,7 @@ export declare function createZapierSdk(options?: ZapierSdkOptions): import("kit
5732
5732
  execution: {
5733
5733
  id: string;
5734
5734
  name: string;
5735
- status: "failed" | "waiting" | "completed" | "running";
5735
+ status: string;
5736
5736
  input: unknown;
5737
5737
  created_at: string;
5738
5738
  output?: unknown;
@@ -5752,8 +5752,8 @@ export declare function createZapierSdk(options?: ZapierSdkOptions): import("kit
5752
5752
  id: string;
5753
5753
  execution_id: string;
5754
5754
  name: string;
5755
- type: "step" | "wait" | "callback";
5756
- status: "pending" | "failed" | "exhausted" | "completed";
5755
+ type: string;
5756
+ status: string;
5757
5757
  retry_count: number;
5758
5758
  created_at: string;
5759
5759
  result?: unknown;
@@ -1014,6 +1014,9 @@ function isPositional(schema) {
1014
1014
  }
1015
1015
  return false;
1016
1016
  }
1017
+ function openEnum(values, description) {
1018
+ return z.union([z.enum(values), z.string()]).describe(description);
1019
+ }
1017
1020
 
1018
1021
  // src/utils/logging.ts
1019
1022
  var { logDeprecation: logDeprecation2, resetDeprecationWarnings: resetDeprecationWarnings2 } = createDeprecationLogger("zapier-sdk");
@@ -2893,13 +2896,16 @@ async function exchangeClientCredentials(options) {
2893
2896
  },
2894
2897
  timestamp: Date.now()
2895
2898
  });
2896
- throw new Error(
2897
- `Client credentials exchange failed: ${response.status} ${response.statusText}`
2899
+ throw new ZapierAuthenticationError(
2900
+ `Client credentials exchange failed: ${response.status} ${response.statusText}`,
2901
+ { statusCode: response.status }
2898
2902
  );
2899
2903
  }
2900
2904
  const data = await response.json();
2901
2905
  if (!data.access_token) {
2902
- throw new Error("Client credentials response missing access_token");
2906
+ throw new ZapierAuthenticationError(
2907
+ "Client credentials response missing access_token"
2908
+ );
2903
2909
  }
2904
2910
  onEvent?.({
2905
2911
  type: "auth_success",
@@ -3122,6 +3128,17 @@ async function invalidateCredentialsToken(options) {
3122
3128
  }
3123
3129
 
3124
3130
  // src/api/sse-parser.ts
3131
+ async function* jsonFrames(source) {
3132
+ for await (const { data } of source) {
3133
+ let frame;
3134
+ try {
3135
+ frame = { parsed: true, data: JSON.parse(data), raw: data };
3136
+ } catch {
3137
+ frame = { parsed: false, data: null, raw: data };
3138
+ }
3139
+ yield frame;
3140
+ }
3141
+ }
3125
3142
  function createSseParserStream() {
3126
3143
  let buffer = "";
3127
3144
  let data = "";
@@ -3169,7 +3186,7 @@ function createSseParserStream() {
3169
3186
  }
3170
3187
 
3171
3188
  // src/sdk-version.ts
3172
- var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.69.3" : void 0) || "unknown";
3189
+ var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.70.1" : void 0) || "unknown";
3173
3190
 
3174
3191
  // src/utils/open-url.ts
3175
3192
  var nodePrefix = "node:";
@@ -3544,6 +3561,15 @@ var ZapierApiClient = class {
3544
3561
  * never pins a slot — see `withSemaphore`.
3545
3562
  */
3546
3563
  this.fetchStream = (path, init) => this.streamSse(path, init);
3564
+ /**
3565
+ * Like `fetchStream`, but parses each frame's `data` as JSON. Diverges from
3566
+ * `fetchJson` deliberately: that throws on invalid JSON, but a long-lived
3567
+ * stream must survive a single malformed frame, so a parse failure is yielded
3568
+ * as `{ parsed: false, data: null, raw }` rather than thrown. A non-ok
3569
+ * response still throws the shared `ZapierError` (from `fetchStream`, before
3570
+ * any frame), so transport / auth failures surface as usual.
3571
+ */
3572
+ this.fetchJsonStream = (path, init) => jsonFrames(this.fetchStream(path, init));
3547
3573
  this.get = async (path, options = {}) => {
3548
3574
  return this.fetchJson("GET", path, void 0, options);
3549
3575
  };
@@ -3750,16 +3776,16 @@ var ZapierApiClient = class {
3750
3776
  if (typeof errorInfo.data === "string") {
3751
3777
  return { message: `${fallbackMessage}: ${errorInfo.data}` };
3752
3778
  }
3753
- const errorMessage = this.extractErrorMessage(errorInfo.data) || fallbackMessage;
3779
+ const errorMessage2 = this.extractErrorMessage(errorInfo.data) || fallbackMessage;
3754
3780
  if (this.hasErrorArray(errorInfo.data)) {
3755
3781
  if (this.isApiErrorArray(errorInfo.data.errors)) {
3756
3782
  return {
3757
- message: errorMessage,
3783
+ message: errorMessage2,
3758
3784
  errors: errorInfo.data.errors
3759
3785
  };
3760
3786
  } else {
3761
3787
  return {
3762
- message: errorMessage,
3788
+ message: errorMessage2,
3763
3789
  errors: errorInfo.data.errors.map((e) => ({
3764
3790
  status: errorInfo.status,
3765
3791
  code: String(errorInfo.status),
@@ -3769,7 +3795,7 @@ var ZapierApiClient = class {
3769
3795
  };
3770
3796
  }
3771
3797
  }
3772
- return { message: errorMessage };
3798
+ return { message: errorMessage2 };
3773
3799
  } catch {
3774
3800
  return { message: fallbackMessage };
3775
3801
  }
@@ -4109,7 +4135,11 @@ var createZapierApi = (options) => {
4109
4135
 
4110
4136
  // src/api/error-classification.ts
4111
4137
  function isPermanentHttpError(err) {
4112
- const statusCode = err instanceof ZapierError ? err.statusCode : void 0;
4138
+ if (!(err instanceof ZapierError)) return false;
4139
+ if (err instanceof ZapierAuthenticationError && err.statusCode === void 0) {
4140
+ return true;
4141
+ }
4142
+ const { statusCode } = err;
4113
4143
  return statusCode !== void 0 && statusCode >= 400 && statusCode < 500 && statusCode !== 429;
4114
4144
  }
4115
4145
 
@@ -6097,11 +6127,11 @@ var runActionPlugin = definePlugin(
6097
6127
  timeoutMs
6098
6128
  });
6099
6129
  if (result.errors && result.errors.length > 0) {
6100
- const errorMessage = result.errors.map(
6130
+ const errorMessage2 = result.errors.map(
6101
6131
  (error) => error.detail || error.title || "Unknown error"
6102
6132
  ).join("; ");
6103
6133
  throw new ZapierActionError(
6104
- `Action execution failed: ${errorMessage}`,
6134
+ `Action execution failed: ${errorMessage2}`,
6105
6135
  { appKey, actionKey }
6106
6136
  );
6107
6137
  }
@@ -9275,10 +9305,10 @@ var eventEmissionPlugin = definePlugin(
9275
9305
  registeredListeners.uncaughtException = uncaughtExceptionHandler;
9276
9306
  globalThis.process.on("uncaughtException", uncaughtExceptionHandler);
9277
9307
  const unhandledRejectionHandler = async (reason, promise) => {
9278
- const errorMessage = reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "Unhandled promise rejection";
9308
+ const errorMessage2 = reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "Unhandled promise rejection";
9279
9309
  const errorStack = reason instanceof Error ? reason.stack : null;
9280
9310
  let errorEvent = buildErrorEventWithContext({
9281
- error_message: errorMessage,
9311
+ error_message: errorMessage2,
9282
9312
  error_type: "UnhandledRejection",
9283
9313
  error_stack_trace: errorStack,
9284
9314
  error_severity: "critical",
@@ -10465,6 +10495,16 @@ async function runBatchedDrainPipeline(options) {
10465
10495
  }
10466
10496
 
10467
10497
  // src/plugins/triggers/drainTriggerInbox/index.ts
10498
+ var nonRetryableDrainErrors = /* @__PURE__ */ new WeakSet();
10499
+ function markNonRetryableDrainError(err) {
10500
+ if (typeof err === "object" && err !== null) {
10501
+ nonRetryableDrainErrors.add(err);
10502
+ }
10503
+ return err;
10504
+ }
10505
+ function isNonRetryableDrainError(err) {
10506
+ return typeof err === "object" && err !== null && nonRetryableDrainErrors.has(err);
10507
+ }
10468
10508
  function isLeaseExpiredError(err) {
10469
10509
  if (!(err instanceof ZapierValidationError)) return false;
10470
10510
  return err.errors?.some((e) => e.code === "lease_expired") ?? false;
@@ -10485,6 +10525,7 @@ async function runDrainPass(options) {
10485
10525
  } = options;
10486
10526
  let firstFetch = options.firstFetch;
10487
10527
  let abortedFromCallback = false;
10528
+ let handlerErrorCaptured = false;
10488
10529
  let firstHandlerError = void 0;
10489
10530
  const outcomes = await runBatchedDrainPipeline({
10490
10531
  concurrency,
@@ -10506,8 +10547,10 @@ async function runDrainPass(options) {
10506
10547
  }
10507
10548
  if (lease.results.length === 0) {
10508
10549
  if (firstFetch && lease.inbox_attributes.status === "initialization_failure") {
10509
- throw new ZapierApiError(
10510
- `Trigger inbox ${inboxId} is in initialization_failure state \u2014 inspect via getTriggerInbox.`
10550
+ throw markNonRetryableDrainError(
10551
+ new ZapierApiError(
10552
+ `Trigger inbox ${inboxId} is in initialization_failure state \u2014 inspect via getTriggerInbox.`
10553
+ )
10511
10554
  );
10512
10555
  }
10513
10556
  firstFetch = false;
@@ -10547,7 +10590,10 @@ async function runDrainPass(options) {
10547
10590
  }
10548
10591
  }
10549
10592
  if (!continueOnError && !(err instanceof ZapierSignal)) {
10550
- if (firstHandlerError === void 0) firstHandlerError = err;
10593
+ if (!handlerErrorCaptured) {
10594
+ firstHandlerError = err;
10595
+ handlerErrorCaptured = true;
10596
+ }
10551
10597
  abort = true;
10552
10598
  }
10553
10599
  return { value: message, action, abort };
@@ -10576,7 +10622,9 @@ async function runDrainPass(options) {
10576
10622
  }
10577
10623
  }
10578
10624
  });
10579
- if (firstHandlerError !== void 0) throw firstHandlerError;
10625
+ if (handlerErrorCaptured) {
10626
+ throw markNonRetryableDrainError(firstHandlerError);
10627
+ }
10580
10628
  return { abortedFromCallback, processed: outcomes.length };
10581
10629
  }
10582
10630
  function requireOnMessage(onMessage) {
@@ -10650,16 +10698,12 @@ async function* readInboxEvents({
10650
10698
  signal,
10651
10699
  onOpen
10652
10700
  }) {
10653
- for await (const message of api.fetchStream(
10701
+ for await (const message of api.fetchJsonStream(
10654
10702
  `/trigger-inbox/api/v1/inboxes/${encodeURIComponent(inboxId)}/events`,
10655
10703
  { method: "GET", signal, authRequired: true, onOpen }
10656
10704
  )) {
10657
- let parsed;
10658
- try {
10659
- parsed = JSON.parse(message.data);
10660
- } catch {
10661
- continue;
10662
- }
10705
+ if (!message.parsed) continue;
10706
+ const parsed = message.data;
10663
10707
  if (typeof parsed === "object" && parsed !== null && typeof parsed.inbox_id === "string" && // Only wake on a frame for this inbox. Case-insensitive: the endpoint
10664
10708
  // echoes the canonical lowercase UUID, but resolveTriggerInboxId passes
10665
10709
  // a UUID-shaped `inbox` through unchanged, so its casing may differ.
@@ -10673,6 +10717,7 @@ async function* readInboxEvents({
10673
10717
  var SSE_RECONNECT_BACKOFF_MS = [500, 1e3, 2e3, 5e3];
10674
10718
  var DEFAULT_SAFETY_DRAIN_INTERVAL_MS = 3e5;
10675
10719
  var SSE_HEALTHY_CONNECTION_MS = 5e3;
10720
+ var ERROR_BACKOFF_CAP = 4;
10676
10721
  function createDrainLatch() {
10677
10722
  let pending = false;
10678
10723
  const make = () => {
@@ -10703,9 +10748,14 @@ function createDrainLatch() {
10703
10748
  async function drainRunner({
10704
10749
  drainOptions,
10705
10750
  drainRequest,
10706
- signal
10751
+ signal,
10752
+ inboxId,
10753
+ debug
10707
10754
  }) {
10708
10755
  let firstFetch = true;
10756
+ let consecutiveErrors = 0;
10757
+ let errorAttempts = 0;
10758
+ let drainDegraded = false;
10709
10759
  while (!signal.aborted) {
10710
10760
  await drainRequest.waitForRequest();
10711
10761
  if (signal.aborted) return { kind: "aborted" };
@@ -10716,17 +10766,47 @@ async function drainRunner({
10716
10766
  firstFetch
10717
10767
  }));
10718
10768
  } catch (error) {
10719
- return { kind: "error", error };
10769
+ if (signal.aborted) return { kind: "aborted" };
10770
+ const isNonObjectThrow = typeof error !== "object" || error === null;
10771
+ if (isNonObjectThrow || isNonRetryableDrainError(error) || isPermanentHttpError(error)) {
10772
+ return { kind: "error", error };
10773
+ }
10774
+ consecutiveErrors = Math.min(consecutiveErrors + 1, ERROR_BACKOFF_CAP);
10775
+ errorAttempts += 1;
10776
+ const delay = calculateErrorBackoffMs(
10777
+ BASE_ERROR_BACKOFF_MS,
10778
+ consecutiveErrors
10779
+ );
10780
+ const statusCode = errorStatusCode(error);
10781
+ const httpPart = statusCode !== void 0 ? ` (HTTP ${statusCode})` : "";
10782
+ if (!drainDegraded && consecutiveErrors >= ERROR_BACKOFF_CAP) {
10783
+ console.warn(
10784
+ `[zapier-sdk] Draining inbox ${inboxId}${httpPart} is failing repeatedly: ${errorMessage(error)}. Continuing to retry with backoff.`
10785
+ );
10786
+ drainDegraded = true;
10787
+ }
10788
+ if (debug) {
10789
+ console.error(
10790
+ `[zapier-sdk] Retrying drain for inbox ${inboxId} (attempt ${errorAttempts}, retry in ${delay}ms)${httpPart}: ${errorMessage(error)}`
10791
+ );
10792
+ }
10793
+ await sleep(delay, signal);
10794
+ if (signal.aborted) return { kind: "aborted" };
10795
+ drainRequest.request();
10796
+ continue;
10720
10797
  }
10721
10798
  firstFetch = false;
10799
+ consecutiveErrors = 0;
10800
+ errorAttempts = 0;
10801
+ drainDegraded = false;
10722
10802
  if (abortedFromCallback) return { kind: "abortedFromCallback" };
10723
10803
  }
10724
10804
  return { kind: "aborted" };
10725
10805
  }
10726
- function sseErrorStatusCode(err) {
10806
+ function errorStatusCode(err) {
10727
10807
  return err instanceof ZapierError ? err.statusCode : void 0;
10728
10808
  }
10729
- function sseErrorMessage(err) {
10809
+ function errorMessage(err) {
10730
10810
  return err instanceof Error ? err.message : String(err);
10731
10811
  }
10732
10812
  async function sseLoop({
@@ -10767,8 +10847,8 @@ async function sseLoop({
10767
10847
  if (signal.aborted || isAbortError(err)) return;
10768
10848
  if (isPermanentHttpError(err)) {
10769
10849
  if (!degraded) {
10770
- const statusCode = sseErrorStatusCode(err);
10771
- const errorMsg = sseErrorMessage(err);
10850
+ const statusCode = errorStatusCode(err);
10851
+ const errorMsg = errorMessage(err);
10772
10852
  const httpPart = statusCode !== void 0 ? ` (HTTP ${statusCode})` : "";
10773
10853
  console.warn(
10774
10854
  `[zapier-sdk] Real-time wake-ups for inbox ${inboxId}${httpPart} paused: ${errorMsg}. Falling back to the periodic safety drain.`
@@ -10787,8 +10867,8 @@ async function sseLoop({
10787
10867
  const delay = SSE_RECONNECT_BACKOFF_MS[Math.min(attempt, SSE_RECONNECT_BACKOFF_MS.length - 1)];
10788
10868
  attempt = Math.min(attempt + 1, SSE_RECONNECT_BACKOFF_MS.length - 1);
10789
10869
  if (transientError !== void 0 && debug) {
10790
- const statusCode = sseErrorStatusCode(transientError);
10791
- const errorMsg = sseErrorMessage(transientError);
10870
+ const statusCode = errorStatusCode(transientError);
10871
+ const errorMsg = errorMessage(transientError);
10792
10872
  const httpPart = statusCode !== void 0 ? ` (HTTP ${statusCode})` : "";
10793
10873
  console.error(
10794
10874
  `[zapier-sdk] Reconnecting real-time wake-ups for inbox ${inboxId} (attempt ${attempt}, retry in ${delay}ms)${httpPart}: ${errorMsg}`
@@ -10848,7 +10928,13 @@ var watchTriggerInboxPlugin = definePlugin(
10848
10928
  signal
10849
10929
  };
10850
10930
  drainRequest.request();
10851
- const runnerDone = drainRunner({ drainOptions, drainRequest, signal });
10931
+ const runnerDone = drainRunner({
10932
+ drainOptions,
10933
+ drainRequest,
10934
+ signal,
10935
+ inboxId,
10936
+ debug
10937
+ });
10852
10938
  const sseDone = sseLoop({
10853
10939
  api: sdk.context.api,
10854
10940
  inboxId,
@@ -10881,7 +10967,7 @@ var watchTriggerInboxPlugin = definePlugin(
10881
10967
  watchTriggerInbox: {
10882
10968
  ...triggersDefaults,
10883
10969
  type: "create",
10884
- description: "Continuously consume a trigger inbox: drain currently-available messages via onMessage, then subscribe to SSE notifications for new arrivals until aborted. A periodic safety drain runs every maxDrainIntervalSeconds (default: 300) to guarantee forward progress if SSE events are missed. Resolves cleanly on signal abort or ZapierAbortDrainSignal from a handler; rejects on fatal SDK errors or fail-fast handler errors. Real-time wake-up health is reported on stderr: a warning when wake-ups pause and the watch falls back to the safety drain, plus (with debug) transient reconnect notices.",
10970
+ description: "Continuously consume a trigger inbox: drain currently-available messages via onMessage, then subscribe to SSE notifications for new arrivals until aborted. A periodic safety drain runs every maxDrainIntervalSeconds (default: 300) to guarantee forward progress if SSE events are missed. Resolves cleanly on signal abort or ZapierAbortDrainSignal from a handler. Transient drain failures (5xx, 429, network blips) retry indefinitely with bounded backoff until they succeed or the watch is aborted; it rejects on a fail-fast handler error, an initialization_failure, or a permanent HTTP error. Real-time wake-up health is reported on stderr: a warning when wake-ups pause and the watch falls back to the safety drain, plus (with debug) transient reconnect notices. Persistent drain failures likewise warn once on stderr while bounded-backoff retries continue.",
10885
10971
  itemType: "void",
10886
10972
  // See drainTriggerInbox: override the doc generator's default
10887
10973
  // suffix so the rendered return type is Promise<void>, not
@@ -11216,11 +11302,12 @@ var createWorkflowPlugin = definePlugin(
11216
11302
  if (options.is_private !== void 0) {
11217
11303
  body.is_private = options.is_private;
11218
11304
  }
11219
- const data = await sdk2.context.api.post(
11305
+ const raw = await sdk2.context.api.post(
11220
11306
  "/durableworkflowzaps/api/v0/workflows",
11221
11307
  body,
11222
11308
  { authRequired: true }
11223
11309
  );
11310
+ const data = CreateWorkflowResponseSchema.parse(raw);
11224
11311
  return { data };
11225
11312
  }
11226
11313
  })
@@ -11262,7 +11349,7 @@ var updateWorkflowPlugin = definePlugin(
11262
11349
  if (options.description !== void 0) {
11263
11350
  body.description = options.description;
11264
11351
  }
11265
- const data = await sdk2.context.api.patch(
11352
+ const raw = await sdk2.context.api.patch(
11266
11353
  `/durableworkflowzaps/api/v0/workflows/${encodeURIComponent(options.workflow)}`,
11267
11354
  body,
11268
11355
  {
@@ -11270,6 +11357,7 @@ var updateWorkflowPlugin = definePlugin(
11270
11357
  resource: { type: "workflow", id: options.workflow }
11271
11358
  }
11272
11359
  );
11360
+ const data = UpdateWorkflowResponseSchema.parse(raw);
11273
11361
  return { data };
11274
11362
  }
11275
11363
  })
@@ -11293,7 +11381,7 @@ var enableWorkflowPlugin = definePlugin(
11293
11381
  outputSchema: EnableWorkflowResponseSchema,
11294
11382
  resolvers: { workflow: workflowIdResolver },
11295
11383
  handler: async ({ sdk: sdk2, options }) => {
11296
- const data = await sdk2.context.api.post(
11384
+ const raw = await sdk2.context.api.post(
11297
11385
  `/durableworkflowzaps/api/v0/workflows/${encodeURIComponent(options.workflow)}/enable`,
11298
11386
  void 0,
11299
11387
  {
@@ -11301,6 +11389,7 @@ var enableWorkflowPlugin = definePlugin(
11301
11389
  resource: { type: "workflow", id: options.workflow }
11302
11390
  }
11303
11391
  );
11392
+ const data = EnableWorkflowResponseSchema.parse(raw);
11304
11393
  return { data };
11305
11394
  }
11306
11395
  })
@@ -11326,7 +11415,7 @@ var disableWorkflowPlugin = definePlugin(
11326
11415
  outputSchema: DisableWorkflowResponseSchema,
11327
11416
  resolvers: { workflow: workflowIdResolver },
11328
11417
  handler: async ({ sdk: sdk2, options }) => {
11329
- const data = await sdk2.context.api.post(
11418
+ const raw = await sdk2.context.api.post(
11330
11419
  `/durableworkflowzaps/api/v0/workflows/${encodeURIComponent(options.workflow)}/disable`,
11331
11420
  void 0,
11332
11421
  {
@@ -11334,6 +11423,7 @@ var disableWorkflowPlugin = definePlugin(
11334
11423
  resource: { type: "workflow", id: options.workflow }
11335
11424
  }
11336
11425
  );
11426
+ const data = DisableWorkflowResponseSchema.parse(raw);
11337
11427
  return { data };
11338
11428
  }
11339
11429
  })
@@ -11343,6 +11433,9 @@ var DeleteWorkflowOptionsSchema = z.object({
11343
11433
  }).describe(
11344
11434
  "Delete a durable workflow. Throws `ZapierNotFoundError` if the workflow doesn't exist; callers wanting idempotency should catch that themselves."
11345
11435
  );
11436
+ var DeleteWorkflowResponseSchema = z.object({
11437
+ id: z.string().describe("Workflow ID that was targeted for deletion")
11438
+ });
11346
11439
 
11347
11440
  // src/plugins/codeSubstrate/deleteWorkflow/index.ts
11348
11441
  var deleteWorkflowPlugin = definePlugin(
@@ -11353,6 +11446,7 @@ var deleteWorkflowPlugin = definePlugin(
11353
11446
  itemType: "Workflow",
11354
11447
  confirm: "delete",
11355
11448
  inputSchema: DeleteWorkflowOptionsSchema,
11449
+ outputSchema: DeleteWorkflowResponseSchema,
11356
11450
  resolvers: { workflow: workflowIdResolver },
11357
11451
  handler: async ({ sdk: sdk2, options }) => {
11358
11452
  await sdk2.context.api.delete(
@@ -11367,7 +11461,8 @@ var deleteWorkflowPlugin = definePlugin(
11367
11461
  }
11368
11462
  })
11369
11463
  );
11370
- var RunStatusSchema = z.enum(["initialized", "started", "finished", "failed", "cancelled"]).describe(
11464
+ var RunStatusSchema = openEnum(
11465
+ ["initialized", "started", "finished", "failed", "cancelled"],
11371
11466
  "Run lifecycle status. `finished` / `failed` / `cancelled` are terminal."
11372
11467
  );
11373
11468
  var RunErrorSchema = z.object({
@@ -11400,7 +11495,7 @@ var ListDurableRunsOptionsSchema = z.object({
11400
11495
  }).describe(
11401
11496
  "List run-once durable runs for the authenticated account, newest first"
11402
11497
  );
11403
- z.object({
11498
+ var ListDurableRunsApiResponseSchema = z.object({
11404
11499
  results: z.array(RunItemSchema),
11405
11500
  meta: z.object({
11406
11501
  limit: z.number(),
@@ -11430,10 +11525,11 @@ var listDurableRunsPlugin = definePlugin(
11430
11525
  if (options.cursor) {
11431
11526
  searchParams.cursor = options.cursor;
11432
11527
  }
11433
- const response = await sdk2.context.api.get(
11434
- "/sdkdurableapi/api/v0/runs",
11435
- { searchParams, authRequired: true }
11436
- );
11528
+ const raw = await sdk2.context.api.get("/sdkdurableapi/api/v0/runs", {
11529
+ searchParams,
11530
+ authRequired: true
11531
+ });
11532
+ const response = ListDurableRunsApiResponseSchema.parse(raw);
11437
11533
  return {
11438
11534
  data: response.results,
11439
11535
  nextCursor: response.meta.next_cursor ?? void 0
@@ -11441,10 +11537,12 @@ var listDurableRunsPlugin = definePlugin(
11441
11537
  }
11442
11538
  })
11443
11539
  );
11444
- var OperationTypeSchema = z.enum(["step", "wait", "callback"]).describe(
11540
+ var OperationTypeSchema = openEnum(
11541
+ ["step", "wait", "callback"],
11445
11542
  "Operation kind: `step` is a journaled function call; `wait` is a time-based suspension; `callback` is a wait on an external callback."
11446
11543
  );
11447
- var OperationStatusSchema = z.enum(["pending", "completed", "failed", "exhausted"]).describe(
11544
+ var OperationStatusSchema = openEnum(
11545
+ ["pending", "completed", "failed", "exhausted"],
11448
11546
  "Operation lifecycle status. `exhausted` means retries were exceeded."
11449
11547
  );
11450
11548
  var OperationSchema = z.object({
@@ -11472,7 +11570,8 @@ var OperationSchema = z.object({
11472
11570
  completed_at: z.string().optional().describe("When the operation reached a terminal state (ISO-8601)"),
11473
11571
  created_at: z.string().describe("When the operation was created (ISO-8601)")
11474
11572
  });
11475
- var ExecutionStatusSchema = z.enum(["running", "waiting", "completed", "failed"]).describe(
11573
+ var ExecutionStatusSchema = openEnum(
11574
+ ["running", "waiting", "completed", "failed"],
11476
11575
  "Execution lifecycle status. `waiting` means blocked on a wait or callback operation."
11477
11576
  );
11478
11577
  var ExecutionSummarySchema = z.object({
@@ -11536,13 +11635,14 @@ var getDurableRunPlugin = definePlugin(
11536
11635
  outputSchema: GetDurableRunResponseSchema,
11537
11636
  resolvers: { run: durableRunIdResolver },
11538
11637
  handler: async ({ sdk: sdk2, options }) => {
11539
- const data = await sdk2.context.api.get(
11638
+ const raw = await sdk2.context.api.get(
11540
11639
  `/sdkdurableapi/api/v0/runs/${encodeURIComponent(options.run)}`,
11541
11640
  {
11542
11641
  authRequired: true,
11543
11642
  resource: { type: "run", id: options.run }
11544
11643
  }
11545
11644
  );
11645
+ const data = GetDurableRunResponseSchema.parse(raw);
11546
11646
  return { data };
11547
11647
  }
11548
11648
  })
@@ -11621,11 +11721,12 @@ var runDurablePlugin = definePlugin(
11621
11721
  if (options.private !== void 0) {
11622
11722
  body.is_private = options.private;
11623
11723
  }
11624
- const data = await sdk2.context.api.post(
11724
+ const raw = await sdk2.context.api.post(
11625
11725
  "/sdkdurableapi/api/v0/runs",
11626
11726
  body,
11627
11727
  { authRequired: true }
11628
11728
  );
11729
+ const data = RunDurableResponseSchema.parse(raw);
11629
11730
  return { data };
11630
11731
  }
11631
11732
  })
@@ -11635,7 +11736,7 @@ var CancelDurableRunOptionsSchema = z.object({
11635
11736
  }).describe(
11636
11737
  "Cancel a run-once durable run in initialized or started status. Returns 409 if the run is already terminal."
11637
11738
  );
11638
- z.object({
11739
+ var CancelDurableRunResponseSchema = z.object({
11639
11740
  id: z.string().describe("Run ID that was targeted"),
11640
11741
  status: z.literal("cancelled").describe(
11641
11742
  "Always `cancelled` on a successful call. Synthesized client-side \u2014 the backend returns 204; callers needing the run's full state should follow up with getDurableRun."
@@ -11650,6 +11751,7 @@ var cancelDurableRunPlugin = definePlugin(
11650
11751
  type: "update",
11651
11752
  itemType: "DurableRun",
11652
11753
  inputSchema: CancelDurableRunOptionsSchema,
11754
+ outputSchema: CancelDurableRunResponseSchema,
11653
11755
  resolvers: { run: durableRunIdResolver },
11654
11756
  handler: async ({ sdk: sdk2, options }) => {
11655
11757
  await sdk2.context.api.post(