@zapier/zapier-sdk 0.94.1 → 0.96.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.
@@ -1539,6 +1539,11 @@ function declareOptionalProperty(config) {
1539
1539
  // import binding is still typed `TValue | undefined` from the descriptor.
1540
1540
  };
1541
1541
  }
1542
+ function declareDefault({
1543
+ plugin
1544
+ }) {
1545
+ return { ...plugin, defaultSource: plugin };
1546
+ }
1542
1547
  function defineHook(config) {
1543
1548
  const deps = normalizeImports(config.imports);
1544
1549
  return {
@@ -4208,6 +4213,321 @@ function createCorePlugin(options) {
4208
4213
  }
4209
4214
  });
4210
4215
  }
4216
+ function describeUnclaimedConnection(connection) {
4217
+ const delimiterIndex = connection.indexOf(":");
4218
+ if (delimiterIndex === -1) {
4219
+ return 'no auth provider claimed this connection, and it carries no "scheme:" prefix';
4220
+ }
4221
+ return `no auth provider claimed the "${connection.slice(0, delimiterIndex)}" connection scheme`;
4222
+ }
4223
+ var authorizeHttpRequestPlugin = defineMethod({
4224
+ name: "authorizeHttpRequest",
4225
+ namespace: "kitcore",
4226
+ inputSchema: z.custom(),
4227
+ skipInputValidation: true,
4228
+ run: async ({ input }) => {
4229
+ const { connection } = input.request;
4230
+ if (connection != null) {
4231
+ throw createCoreError({
4232
+ code: CoreErrorCode.Unknown,
4233
+ message: `authorizeHttpRequest: ${describeUnclaimedConnection(connection)}, so the request was not sent.`
4234
+ });
4235
+ }
4236
+ return input.request;
4237
+ }
4238
+ });
4239
+ function toFetchInput(request) {
4240
+ const init = { ...request };
4241
+ const { url } = request;
4242
+ delete init.url;
4243
+ delete init.connection;
4244
+ return { url, init };
4245
+ }
4246
+ var dispatchHttpRequestPlugin = defineMethod({
4247
+ name: "dispatchHttpRequest",
4248
+ namespace: "kitcore",
4249
+ inputSchema: z.custom(),
4250
+ skipInputValidation: true,
4251
+ run: async ({ input }) => {
4252
+ const { url, init } = toFetchInput(input.request);
4253
+ return fetch(url, init);
4254
+ }
4255
+ });
4256
+ var prepareHttpRequestPlugin = defineMethod({
4257
+ name: "prepareHttpRequest",
4258
+ namespace: "kitcore",
4259
+ inputSchema: z.custom(),
4260
+ skipInputValidation: true,
4261
+ run: async ({ input }) => input.request
4262
+ });
4263
+ var receiveHttpResponsePlugin = defineMethod({
4264
+ name: "receiveHttpResponse",
4265
+ namespace: "kitcore",
4266
+ inputSchema: z.custom(),
4267
+ skipInputValidation: true,
4268
+ run: async ({ input }) => input.response
4269
+ });
4270
+ var attemptHttpRequestPlugin = defineMethod({
4271
+ name: "attemptHttpRequest",
4272
+ namespace: "kitcore",
4273
+ imports: [
4274
+ declareDefault({ plugin: prepareHttpRequestPlugin }),
4275
+ declareDefault({ plugin: authorizeHttpRequestPlugin }),
4276
+ declareDefault({ plugin: dispatchHttpRequestPlugin }),
4277
+ declareDefault({ plugin: receiveHttpResponsePlugin })
4278
+ ],
4279
+ inputSchema: z.custom(),
4280
+ skipInputValidation: true,
4281
+ run: async ({ input, imports }) => {
4282
+ const { attempt } = input;
4283
+ const preparedRequest = await imports.prepareHttpRequest({
4284
+ request: input.request,
4285
+ attempt
4286
+ });
4287
+ const authorizedRequest = await imports.authorizeHttpRequest({
4288
+ request: preparedRequest,
4289
+ attempt
4290
+ });
4291
+ const response = await imports.dispatchHttpRequest({
4292
+ request: authorizedRequest,
4293
+ attempt
4294
+ });
4295
+ return imports.receiveHttpResponse({
4296
+ request: authorizedRequest,
4297
+ response,
4298
+ attempt
4299
+ });
4300
+ }
4301
+ });
4302
+ function isReplayableBody(body) {
4303
+ if (body == null || typeof body !== "object") return true;
4304
+ return typeof Blob !== "undefined" && body instanceof Blob || // File extends Blob
4305
+ typeof FormData !== "undefined" && body instanceof FormData || typeof URLSearchParams !== "undefined" && body instanceof URLSearchParams || body instanceof ArrayBuffer || ArrayBuffer.isView(body);
4306
+ }
4307
+ function withStringUrl(request) {
4308
+ return typeof request.url === "string" ? request : { ...request, url: String(request.url) };
4309
+ }
4310
+ var initializeHttpRequestPlugin = defineMethod({
4311
+ name: "initializeHttpRequest",
4312
+ namespace: "kitcore",
4313
+ inputSchema: z.custom(),
4314
+ skipInputValidation: true,
4315
+ run: async ({ input }) => {
4316
+ const request = withStringUrl(input.request);
4317
+ return {
4318
+ ...input.operation,
4319
+ request,
4320
+ replayable: isReplayableBody(request.body)
4321
+ };
4322
+ }
4323
+ });
4324
+ var RETRY_HTTP_REQUEST_OPTIONS_ID = "kitcore/retryHttpRequestOptions";
4325
+ var retryHttpRequestOptionsPluginRef = declareOptionalProperty({ id: RETRY_HTTP_REQUEST_OPTIONS_ID });
4326
+ var DEFAULT_MAX_ATTEMPTS = 3;
4327
+ var DEFAULT_MAX_DELAY_MILLISECONDS = 6e4;
4328
+ var DEFAULT_RETRY_STATUSES = [429, 500, 502, 503, 504];
4329
+ var DEFAULT_NON_IDEMPOTENT_RETRY_STATUSES = [429];
4330
+ var DEFAULT_IDEMPOTENT_METHODS = [
4331
+ "GET",
4332
+ "HEAD",
4333
+ "PUT",
4334
+ "DELETE",
4335
+ "OPTIONS",
4336
+ "TRACE"
4337
+ ];
4338
+ var BASE_BACKOFF_MILLISECONDS = 1e3;
4339
+ var JITTER_FACTOR = 0.5;
4340
+ function directedDelayMilliseconds(response) {
4341
+ const retryAfter = response.headers.get("retry-after");
4342
+ if (retryAfter) {
4343
+ const seconds = Number.parseInt(retryAfter, 10);
4344
+ if (!Number.isNaN(seconds)) return Math.max(0, seconds * 1e3);
4345
+ const date = Date.parse(retryAfter);
4346
+ if (!Number.isNaN(date)) return Math.max(0, date - Date.now());
4347
+ }
4348
+ const reset = response.headers.get("x-ratelimit-reset");
4349
+ if (reset) {
4350
+ const resetSeconds = Number.parseInt(reset, 10);
4351
+ if (!Number.isNaN(resetSeconds)) {
4352
+ return Math.max(0, resetSeconds * 1e3 - Date.now());
4353
+ }
4354
+ }
4355
+ return void 0;
4356
+ }
4357
+ function backoffMilliseconds(attemptNumber) {
4358
+ const base = BASE_BACKOFF_MILLISECONDS * 2 ** (attemptNumber - 1);
4359
+ return base + Math.random() * JITTER_FACTOR * base;
4360
+ }
4361
+ function abortReason(signal) {
4362
+ const reason = signal?.reason;
4363
+ return reason ?? new Error("The request was aborted.");
4364
+ }
4365
+ function sleep(milliseconds, signal) {
4366
+ return new Promise((resolve2, reject) => {
4367
+ const timer = setTimeout(finish, milliseconds);
4368
+ function finish() {
4369
+ clearTimeout(timer);
4370
+ signal?.removeEventListener("abort", cancel);
4371
+ resolve2();
4372
+ }
4373
+ function cancel() {
4374
+ clearTimeout(timer);
4375
+ reject(abortReason(signal));
4376
+ }
4377
+ if (signal?.aborted) return cancel();
4378
+ signal?.addEventListener("abort", cancel, { once: true });
4379
+ });
4380
+ }
4381
+ function isIdempotent(request, idempotentMethods) {
4382
+ const method = (request.method ?? "GET").toUpperCase();
4383
+ return idempotentMethods.includes(method);
4384
+ }
4385
+ defineHook({
4386
+ name: "retryHttpRequest",
4387
+ imports: [attemptHttpRequestPlugin, retryHttpRequestOptionsPluginRef],
4388
+ wrap: {
4389
+ attemptHttpRequest: async ({ input, imports, next }) => {
4390
+ const options = imports.retryHttpRequestOptions ?? {};
4391
+ const maxAttempts = options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS;
4392
+ const maxDelayMilliseconds = options.maxDelayMilliseconds ?? DEFAULT_MAX_DELAY_MILLISECONDS;
4393
+ const idempotentMethods = options.idempotentMethods ?? DEFAULT_IDEMPOTENT_METHODS;
4394
+ const statuses = isIdempotent(input.request, idempotentMethods) ? options.retryStatuses ?? DEFAULT_RETRY_STATUSES : options.nonIdempotentRetryStatuses ?? DEFAULT_NON_IDEMPOTENT_RETRY_STATUSES;
4395
+ for (let attemptNumber = 1; ; attemptNumber++) {
4396
+ const attempt = {
4397
+ ...input.attempt,
4398
+ attemptNumber,
4399
+ // Per-attempt scratch: a cross-stage handoff from a previous attempt
4400
+ // describes a request that is no longer in flight. `operation` rides
4401
+ // through unchanged, so the id and the caller's original request are
4402
+ // the same for every attempt.
4403
+ state: {}
4404
+ };
4405
+ let response;
4406
+ try {
4407
+ response = await next({ ...input, attempt });
4408
+ } catch (error) {
4409
+ if (!options.retryOnError || !canRetry(
4410
+ attemptNumber,
4411
+ maxAttempts,
4412
+ input.attempt.operation.replayable
4413
+ )) {
4414
+ throw error;
4415
+ }
4416
+ await sleep(
4417
+ Math.min(backoffMilliseconds(attemptNumber), maxDelayMilliseconds),
4418
+ attempt.signal
4419
+ );
4420
+ continue;
4421
+ }
4422
+ if (!statuses.includes(response.status) || !canRetry(
4423
+ attemptNumber,
4424
+ maxAttempts,
4425
+ input.attempt.operation.replayable
4426
+ )) {
4427
+ return response;
4428
+ }
4429
+ const directed = directedDelayMilliseconds(response);
4430
+ if (directed != null && directed > maxDelayMilliseconds)
4431
+ return response;
4432
+ const delay = Math.min(
4433
+ directed ?? backoffMilliseconds(attemptNumber),
4434
+ maxDelayMilliseconds
4435
+ );
4436
+ await response.body?.cancel().catch(() => {
4437
+ });
4438
+ await sleep(delay, attempt.signal);
4439
+ }
4440
+ }
4441
+ }
4442
+ });
4443
+ function canRetry(attemptNumber, maxAttempts, replayable) {
4444
+ return attemptNumber < maxAttempts && replayable;
4445
+ }
4446
+ function createOperationId() {
4447
+ return globalThis.crypto?.randomUUID?.() ?? `http-${Date.now()}`;
4448
+ }
4449
+ var sendHttpRequestPlugin = defineMethod({
4450
+ name: "sendHttpRequest",
4451
+ namespace: "kitcore",
4452
+ imports: [
4453
+ declareDefault({ plugin: initializeHttpRequestPlugin }),
4454
+ declareDefault({ plugin: attemptHttpRequestPlugin })
4455
+ ],
4456
+ inputSchema: z.custom(),
4457
+ skipInputValidation: true,
4458
+ run: async ({ input, imports }) => {
4459
+ const start2 = {
4460
+ operationId: createOperationId(),
4461
+ signal: input.signal
4462
+ };
4463
+ const operation = await imports.initializeHttpRequest({
4464
+ request: input,
4465
+ operation: start2
4466
+ });
4467
+ return imports.attemptHttpRequest({
4468
+ request: operation.request,
4469
+ attempt: {
4470
+ attemptNumber: 1,
4471
+ operation,
4472
+ signal: operation.signal,
4473
+ state: {}
4474
+ }
4475
+ });
4476
+ }
4477
+ });
4478
+ defineMethod({
4479
+ name: "fetch",
4480
+ namespace: "kitcore",
4481
+ imports: [declareDefault({ plugin: sendHttpRequestPlugin })],
4482
+ positional: ["url", "init"],
4483
+ inputSchema: z.custom(),
4484
+ skipInputValidation: true,
4485
+ run: ({ input, imports }) => {
4486
+ const { url, init } = input;
4487
+ return imports.sendHttpRequest({ url, ...init });
4488
+ }
4489
+ });
4490
+ var defaultConnectionSchemePlugin = defineMethod({
4491
+ name: "defaultConnectionScheme",
4492
+ namespace: "kitcore",
4493
+ inputSchema: z.custom(),
4494
+ skipInputValidation: true,
4495
+ run: () => void 0
4496
+ });
4497
+ defineMethod({
4498
+ name: "normalizeConnection",
4499
+ namespace: "kitcore",
4500
+ imports: [declareDefault({ plugin: defaultConnectionSchemePlugin })],
4501
+ inputSchema: z.custom(),
4502
+ skipInputValidation: true,
4503
+ run: ({ input, imports }) => {
4504
+ const { connection } = input;
4505
+ if (connection == null) {
4506
+ return void 0;
4507
+ }
4508
+ const delimiterIndex = connection.indexOf(":");
4509
+ if (delimiterIndex !== -1) {
4510
+ return {
4511
+ connection,
4512
+ scheme: connection.slice(0, delimiterIndex),
4513
+ value: connection.slice(delimiterIndex + 1)
4514
+ };
4515
+ }
4516
+ const scheme = imports.defaultConnectionScheme({ connection });
4517
+ return {
4518
+ connection,
4519
+ scheme,
4520
+ value: connection
4521
+ };
4522
+ }
4523
+ });
4524
+ defineMethod({
4525
+ name: "resolveConnection",
4526
+ namespace: "kitcore",
4527
+ inputSchema: z.custom(),
4528
+ skipInputValidation: true,
4529
+ run: ({ input }) => input.connection
4530
+ });
4211
4531
 
4212
4532
  // src/constants.ts
4213
4533
  var ZAPIER_BASE_URL = globalThis.process?.env?.ZAPIER_BASE_URL || "https://zapier.com";
@@ -4912,9 +5232,9 @@ function createDebugFetch(options) {
4912
5232
  var MAX_CONSECUTIVE_ERRORS = 3;
4913
5233
  var BASE_ERROR_BACKOFF_MILLISECONDS = 1e3;
4914
5234
  var BASE_EXPONENTIAL_BACKOFF_MILLISECONDS = 1e3;
4915
- var JITTER_FACTOR = 0.5;
5235
+ var JITTER_FACTOR2 = 0.5;
4916
5236
  function calculateErrorBackoffMs(baseInterval, errorCount) {
4917
- const jitter = Math.random() * JITTER_FACTOR * baseInterval;
5237
+ const jitter = Math.random() * JITTER_FACTOR2 * baseInterval;
4918
5238
  const errorBackoff = Math.min(
4919
5239
  BASE_ERROR_BACKOFF_MILLISECONDS * (errorCount / 2),
4920
5240
  baseInterval * 2
@@ -4924,10 +5244,10 @@ function calculateErrorBackoffMs(baseInterval, errorCount) {
4924
5244
  }
4925
5245
  function calculateExponentialBackoffMs(attempt, baseDelayMs = BASE_EXPONENTIAL_BACKOFF_MILLISECONDS) {
4926
5246
  const baseDelay = baseDelayMs * Math.pow(2, attempt - 1);
4927
- const jitter = Math.random() * JITTER_FACTOR * baseDelay;
5247
+ const jitter = Math.random() * JITTER_FACTOR2 * baseDelay;
4928
5248
  return Math.floor(baseDelay + jitter);
4929
5249
  }
4930
- function sleep(ms, signal) {
5250
+ function sleep2(ms, signal) {
4931
5251
  if (!signal) {
4932
5252
  return new Promise((resolve2) => setTimeout(resolve2, ms));
4933
5253
  }
@@ -5139,7 +5459,7 @@ async function pollUntilComplete(options) {
5139
5459
  let attempts = 0;
5140
5460
  let errorCount = 0;
5141
5461
  if (initialDelay > 0) {
5142
- await sleep(initialDelay, signal);
5462
+ await sleep2(initialDelay, signal);
5143
5463
  if (signal?.aborted) throw makeAbortError();
5144
5464
  }
5145
5465
  while (true) {
@@ -5157,7 +5477,7 @@ async function pollUntilComplete(options) {
5157
5477
  const interval = getPollingInterval(elapsedTime);
5158
5478
  const waitTime = calculateErrorBackoffMs(interval, errorCount);
5159
5479
  const cappedWaitTime = maxPollingIntervalMs === void 0 ? waitTime : Math.min(waitTime, maxPollingIntervalMs);
5160
- await sleep(cappedWaitTime, signal);
5480
+ await sleep2(cappedWaitTime, signal);
5161
5481
  if (signal?.aborted) throw makeAbortError();
5162
5482
  }
5163
5483
  attempts++;
@@ -6192,7 +6512,7 @@ function parseDeprecationDate(value) {
6192
6512
  }
6193
6513
 
6194
6514
  // src/sdk-version.ts
6195
- var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.94.1" : void 0) || "unknown";
6515
+ var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.96.0" : void 0) || "unknown";
6196
6516
 
6197
6517
  // src/utils/open-url.ts
6198
6518
  var nodePrefix = "node:";
@@ -6301,7 +6621,11 @@ var PollApprovalResponseSchema = z.object({
6301
6621
  status: ApprovalStatusSchema,
6302
6622
  approval_id: z.string().optional(),
6303
6623
  mode: ApprovalModeSchema.optional(),
6304
- reason: z.string().optional()
6624
+ reason: z.string().optional(),
6625
+ // Present when an auto-mode agent escalated the approval to a human reviewer.
6626
+ // The SDK uses review_status to detect escalation and approval_url to open the browser.
6627
+ review_status: z.enum(["in_review", "escalated"]).optional(),
6628
+ approval_url: z.string().optional()
6305
6629
  });
6306
6630
  var APPROVAL_MAX_POLLING_INTERVAL_MILLISECONDS = 5e3;
6307
6631
  function validateSdkPath(path) {
@@ -6422,6 +6746,15 @@ var pathConfig = {
6422
6746
  "/code-substrate-workflows": {
6423
6747
  authHeader: "Authorization",
6424
6748
  pathPrefix: "/api/v0/sdk/code-substrate-workflows"
6749
+ },
6750
+ // e.g. /forms/v0/forms -> https://api.zapier.com/forms/v0/forms
6751
+ // The Forms API is registered on the Public API Gateway and has no sdkapi
6752
+ // proxy route, so it goes straight to the gateway. Its governance metadata
6753
+ // rewrites /forms/v0/... to the backend's /api/forms/v0/..., which is why no
6754
+ // pathPrefix is applied here.
6755
+ "/forms": {
6756
+ authHeader: "Authorization",
6757
+ subdomain: "api"
6425
6758
  }
6426
6759
  };
6427
6760
  var ZapierApiClient = class {
@@ -6484,7 +6817,7 @@ var ZapierApiClient = class {
6484
6817
  method: init?.method ?? "GET",
6485
6818
  rateLimit: rateLimitInfo
6486
6819
  });
6487
- await sleep(delayMs, init?.signal ?? void 0);
6820
+ await sleep2(delayMs, init?.signal ?? void 0);
6488
6821
  }
6489
6822
  };
6490
6823
  /**
@@ -6962,7 +7295,8 @@ var ZapierApiClient = class {
6962
7295
  const zapierBaseUrl = getZapierBaseUrl(this.options.baseUrl);
6963
7296
  if (zapierBaseUrl === this.options.baseUrl.replace(/\/$/, "")) {
6964
7297
  const originalBaseUrl = new URL(this.options.baseUrl);
6965
- const finalBaseUrl = `https://sdkapi.${originalBaseUrl.hostname}`;
7298
+ const subdomain = routingMatch?.config.subdomain ?? "sdkapi";
7299
+ const finalBaseUrl = `https://${subdomain}.${originalBaseUrl.hostname}`;
6966
7300
  const url2 = new URL(finalPath, finalBaseUrl);
6967
7301
  return buildResult(url2);
6968
7302
  }
@@ -7311,6 +7645,7 @@ var ZapierApiClient = class {
7311
7645
  await openApproval(approval.approval_url);
7312
7646
  }
7313
7647
  const timeoutMs = this.options.approvalTimeoutMilliseconds ?? this.options.approvalTimeoutMs ?? DEFAULT_APPROVAL_TIMEOUT_MILLISECONDS;
7648
+ const approvalDeadline = Date.now() + timeoutMs;
7314
7649
  let streamAbortController;
7315
7650
  let streamPromise;
7316
7651
  let removeStreamAbortListener;
@@ -7332,75 +7667,87 @@ var ZapierApiClient = class {
7332
7667
  emitEvent: (type, payload) => this.emitEvent(type, payload)
7333
7668
  });
7334
7669
  }
7335
- let rawPollResult;
7336
- try {
7337
- rawPollResult = await pollUntilComplete({
7338
- // poll_url is an absolute URL supplied by the server, so we use
7339
- // rawFetchUrl directly (skipping path resolution) but still share
7340
- // auth + interactive-header + 429-retry with the rest of the SDK.
7341
- // Each individual poll request goes through the concurrency
7342
- // semaphore — but we deliberately do not hold a slot across the
7343
- // sleep between polls or across the human-approval wait.
7344
- fetchPoll: () => this.withSemaphore(
7345
- { url: approval.poll_url, method: "GET", signal },
7346
- () => this.rawFetchUrl(approval.poll_url, {
7347
- method: "GET",
7348
- headers: { Accept: "application/json" },
7349
- signal
7350
- })
7351
- ),
7352
- timeoutMs,
7353
- maxPollingIntervalMs: APPROVAL_MAX_POLLING_INTERVAL_MILLISECONDS,
7354
- signal,
7355
- isPending: (body2) => {
7356
- const parsed = PollApprovalResponseSchema.safeParse(body2);
7357
- return parsed.success && parsed.data.status === "pending_approval";
7358
- }
7359
- });
7360
- } catch (err) {
7361
- if (!isZapierTimeoutError(err)) {
7362
- this.emitEvent("approval:error", {
7363
- approvalId: approval.id,
7364
- message: err instanceof Error ? err.message : String(err)
7670
+ const fetchApprovalPoll = () => this.withSemaphore(
7671
+ { url: approval.poll_url, method: "GET", signal },
7672
+ () => this.rawFetchUrl(approval.poll_url, {
7673
+ method: "GET",
7674
+ headers: { Accept: "application/json" },
7675
+ signal
7676
+ })
7677
+ );
7678
+ const pollApprovalUntilComplete = async (isPending, deadlineMs = approvalDeadline) => {
7679
+ try {
7680
+ return await pollUntilComplete({
7681
+ fetchPoll: fetchApprovalPoll,
7682
+ timeoutMs: Math.max(1, deadlineMs - Date.now()),
7683
+ maxPollingIntervalMs: APPROVAL_MAX_POLLING_INTERVAL_MILLISECONDS,
7684
+ signal,
7685
+ isPending
7365
7686
  });
7366
- throw err;
7687
+ } catch (err) {
7688
+ if (!isZapierTimeoutError(err)) {
7689
+ this.emitEvent("approval:error", {
7690
+ approvalId: approval.id,
7691
+ message: err instanceof Error ? err.message : String(err)
7692
+ });
7693
+ throw err;
7694
+ }
7695
+ this.emitEvent("approval:timeout", { approvalId: approval.id });
7696
+ throw new ZapierApprovalError(
7697
+ `Approval timed out after ${timeoutMs / 1e3} seconds`,
7698
+ {
7699
+ approvalId: approval.id,
7700
+ approvalUrl: approval.approval_url,
7701
+ pollUrl: approval.poll_url,
7702
+ streamUrl: approval.stream_url,
7703
+ status: "timeout",
7704
+ cause: err
7705
+ }
7706
+ );
7367
7707
  }
7368
- this.emitEvent("approval:timeout", {
7369
- approvalId: approval.id
7708
+ };
7709
+ let rawPollResult;
7710
+ try {
7711
+ rawPollResult = await pollApprovalUntilComplete((body2) => {
7712
+ const parsed = PollApprovalResponseSchema.safeParse(body2);
7713
+ if (!parsed.success) return false;
7714
+ if (parsed.data.review_status === "escalated") return false;
7715
+ return parsed.data.status === "pending_approval";
7370
7716
  });
7371
- throw new ZapierApprovalError(
7372
- `Approval timed out after ${timeoutMs / 1e3} seconds`,
7373
- {
7374
- approvalId: approval.id,
7375
- approvalUrl: approval.approval_url,
7376
- pollUrl: approval.poll_url,
7377
- streamUrl: approval.stream_url,
7378
- status: "timeout",
7379
- cause: err
7380
- }
7381
- );
7382
7717
  } finally {
7383
7718
  removeStreamAbortListener?.();
7384
7719
  streamAbortController?.abort();
7385
7720
  await streamPromise;
7386
7721
  }
7387
- const pollParse = PollApprovalResponseSchema.safeParse(rawPollResult);
7388
- if (!pollParse.success) {
7389
- const bodyPreview = typeof rawPollResult === "string" ? rawPollResult : JSON.stringify(rawPollResult);
7390
- this.emitEvent("approval:error", {
7722
+ const parsePollResult = (raw) => {
7723
+ const parsed = PollApprovalResponseSchema.safeParse(raw);
7724
+ if (!parsed.success) {
7725
+ const bodyPreview = typeof raw === "string" ? raw : JSON.stringify(raw);
7726
+ this.emitEvent("approval:error", {
7727
+ approvalId: approval.id,
7728
+ message: `Failed to parse approval poll response: ${bodyPreview}`
7729
+ });
7730
+ throw new ZapierApiError(
7731
+ `Failed to parse approval poll response: ${bodyPreview}`,
7732
+ { statusCode: 0, cause: parsed.error, response: raw }
7733
+ );
7734
+ }
7735
+ return parsed.data;
7736
+ };
7737
+ const pollResult = parsePollResult(rawPollResult);
7738
+ if (pollResult.review_status === "escalated") {
7739
+ const escalationUrl = pollResult.approval_url ?? approval.approval_url;
7740
+ this.emitEvent("approval:escalated", {
7391
7741
  approvalId: approval.id,
7392
- message: `Failed to parse approval poll response: ${bodyPreview}`
7742
+ approvalUrl: escalationUrl
7393
7743
  });
7394
- throw new ZapierApiError(
7395
- `Failed to parse approval poll response: ${bodyPreview}`,
7396
- {
7397
- statusCode: 0,
7398
- cause: pollParse.error,
7399
- response: rawPollResult
7400
- }
7401
- );
7744
+ await openApproval(escalationUrl);
7745
+ const humanRaw = await pollApprovalUntilComplete((body2) => {
7746
+ const parsed = PollApprovalResponseSchema.safeParse(body2);
7747
+ return parsed.success && parsed.data.status === "pending_approval";
7748
+ });
7749
+ Object.assign(pollResult, parsePollResult(humanRaw));
7402
7750
  }
7403
- const pollResult = pollParse.data;
7404
7751
  if (pollResult.status === "denied") {
7405
7752
  this.emitEvent("approval:denied", {
7406
7753
  approvalId: approval.id,
@@ -8354,7 +8701,7 @@ function buildAbortHandle({
8354
8701
  return combineAbortSignals({ handles });
8355
8702
  }
8356
8703
  var FetchInitSdkValidationSchema = z.looseObject(FetchInitZapierFieldsSchema.shape).optional();
8357
- var fetchPlugin = defineMethod({
8704
+ var fetchPlugin2 = defineMethod({
8358
8705
  name: "fetch",
8359
8706
  imports: [coreOptionsPluginRef, connectionsPluginRef, apiPluginRef],
8360
8707
  output: "raw",
@@ -10686,7 +11033,7 @@ function createAppsProxy(imports) {
10686
11033
  }
10687
11034
  var appsPlugin = defineProperty({
10688
11035
  name: "apps",
10689
- imports: [fetchPlugin, runActionPlugin],
11036
+ imports: [fetchPlugin2, runActionPlugin],
10690
11037
  // Build the proxy once from the imported methods (stable callables).
10691
11038
  setup: ({ imports }) => (
10692
11039
  // Cast: ZapierSdkApps is augmented by user-generated .d.ts files to give
@@ -12040,7 +12387,7 @@ var RelayFetchSchema = RelayRequestSchema;
12040
12387
  // src/plugins/request/index.ts
12041
12388
  var requestPlugin = defineMethod({
12042
12389
  name: "request",
12043
- imports: [fetchPlugin, coreOptionsPluginRef],
12390
+ imports: [fetchPlugin2, coreOptionsPluginRef],
12044
12391
  output: "raw",
12045
12392
  inputSchema: RelayRequestSchema,
12046
12393
  skipInputValidation: true,
@@ -13865,7 +14212,7 @@ async function drainRunner({
13865
14212
  `[zapier-sdk] Retrying drain for inbox ${inboxId} (attempt ${errorAttempts}, retry in ${delay}ms)${httpPart}: ${errorMessage(error)}`
13866
14213
  );
13867
14214
  }
13868
- await sleep(delay, signal);
14215
+ await sleep2(delay, signal);
13869
14216
  if (signal.aborted) return { kind: "aborted" };
13870
14217
  drainRequest.request();
13871
14218
  continue;
@@ -13932,7 +14279,7 @@ async function sseLoop({
13932
14279
  }
13933
14280
  attempt = 0;
13934
14281
  if (signal.aborted) return;
13935
- await sleep(safetyDrainMs, signal);
14282
+ await sleep2(safetyDrainMs, signal);
13936
14283
  continue;
13937
14284
  }
13938
14285
  if (connected) attempt = 0;
@@ -13952,7 +14299,7 @@ async function sseLoop({
13952
14299
  `[zapier-sdk] Reconnecting real-time wake-ups for inbox ${inboxId} (attempt ${attempt}, retry in ${delay}ms)${httpPart}: ${errorMsg}`
13953
14300
  );
13954
14301
  }
13955
- await sleep(delay, signal);
14302
+ await sleep2(delay, signal);
13956
14303
  }
13957
14304
  }
13958
14305
  async function safetyTimerLoop({
@@ -13961,7 +14308,7 @@ async function safetyTimerLoop({
13961
14308
  signal
13962
14309
  }) {
13963
14310
  while (!signal.aborted) {
13964
- await sleep(safetyDrainMs, signal);
14311
+ await sleep2(safetyDrainMs, signal);
13965
14312
  if (signal.aborted) return;
13966
14313
  drainRequest.request();
13967
14314
  }
@@ -15843,7 +16190,7 @@ var zapierSdkPlugin = definePlugin({
15843
16190
  createActionRunPlugin,
15844
16191
  getActionRunPlugin,
15845
16192
  runActionPlugin,
15846
- fetchPlugin,
16193
+ fetchPlugin2,
15847
16194
  requestPlugin,
15848
16195
  appsPlugin,
15849
16196
  // Triggers. `list*` plugins are exported before their `get*` / mutation
@@ -15927,7 +16274,7 @@ async function batch(tasks, options = {}) {
15927
16274
  try {
15928
16275
  let result;
15929
16276
  if (taskTimeoutMs !== void 0) {
15930
- const timeoutPromise = sleep(taskTimeoutMs).then(() => {
16277
+ const timeoutPromise = sleep2(taskTimeoutMs).then(() => {
15931
16278
  throw new ZapierTimeoutError(
15932
16279
  `Task timed out after ${taskTimeoutMs}ms`
15933
16280
  );
@@ -15942,7 +16289,7 @@ async function batch(tasks, options = {}) {
15942
16289
  const isTimeout = isZapierTimeoutError(error);
15943
16290
  if (retry && !isTimeout && newErrorCount < MAX_CONSECUTIVE_ERRORS) {
15944
16291
  const waitTime = calculateErrorBackoffMs(1e3, newErrorCount);
15945
- await sleep(waitTime);
16292
+ await sleep2(waitTime);
15946
16293
  taskQueue.push({
15947
16294
  index,
15948
16295
  task,
@@ -15965,7 +16312,7 @@ async function batch(tasks, options = {}) {
15965
16312
  if (!taskState) break;
15966
16313
  await executeTask(taskState);
15967
16314
  if (taskQueue.length > 0 && batchDelay > 0) {
15968
- await sleep(batchDelay);
16315
+ await sleep2(batchDelay);
15969
16316
  }
15970
16317
  }
15971
16318
  }
@@ -15974,7 +16321,7 @@ async function batch(tasks, options = {}) {
15974
16321
  for (let i = 0; i < workerCount; i++) {
15975
16322
  workers.push(worker());
15976
16323
  if (i < workerCount - 1 && batchDelay > 0) {
15977
- await sleep(batchDelay / 10);
16324
+ await sleep2(batchDelay / 10);
15978
16325
  }
15979
16326
  }
15980
16327
  await Promise.all(workers);
@@ -16056,4 +16403,4 @@ var registryPlugin = (_sdk) => {
16056
16403
  return {};
16057
16404
  };
16058
16405
 
16059
- export { ACTION_RUNS_PATH, API_ID, ActionKeyPropertySchema, ActionPropertySchema, ActionTimeoutMillisecondsPropertySchema, ActionTimeoutSecondsPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AppPropertySchema, AppsPropertySchema, AuthMechanism, AuthenticationIdPropertySchema, BaseSdkOptionsSchema, CONNECTIONS_ID, CONTEXT, CONTEXT_CACHE_MAX_SIZE, CONTEXT_CACHE_TTL_MILLISECONDS, CORE_ERROR_SYMBOL, CORE_OPTIONS_ID, CORE_SIGNAL_SYMBOL, ClientCredentialsObjectSchema, ConnectionEntrySchema, ConnectionIdPropertySchema, ConnectionPropertySchema, ConnectionsMapSchema, ConnectionsPropertySchema, CoreCancelledSignal, CoreDisposeError, CoreErrorCode, CoreSignal, CredentialsFunctionSchema, CredentialsObjectSchema, CredentialsSchema, DEFAULT_ACTION_TIMEOUT_MILLISECONDS, DEFAULT_APPROVAL_TIMEOUT_MILLISECONDS, DEFAULT_CONFIG_PATH, DEFAULT_MAX_APPROVAL_RETRIES, DEFAULT_PAGE_SIZE, DEPRECATION_NOTICE_EVENT, DebugPropertySchema, DrainTriggerInboxSchema, EVENT_EMISSION_ID, FieldsPropertySchema, InputFieldPropertySchema, InputsPropertySchema, LeaseLimitPropertySchema, LeasePropertySchema, LeaseSecondsPropertySchema, LimitPropertySchema, MANIFEST_ID, MAX_CONCURRENCY_LIMIT, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, PkceCredentialsObjectSchema, RESOLVE_CREDENTIALS_ID, RecordPropertySchema, RecordsPropertySchema, RelayFetchSchema, RelayRequestSchema, ResolvedCredentialsSchema, SDK_OPTIONS_ID, TablePropertySchema, TablesPropertySchema, TriggerInboxKeyPropertySchema, TriggerInboxNamePropertySchema, TriggerInboxPropertySchema, WatchTriggerInboxSchema, ZAPIER_BASE_URL, ZAPIER_MAX_CONCURRENT_REQUESTS, ZAPIER_MAX_NETWORK_RETRIES, ZAPIER_MAX_NETWORK_RETRY_DELAY_MILLISECONDS, ZapierAbortDrainSignal, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierApprovalError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierConflictError, ZapierError, ZapierNotFoundError, ZapierRateLimitError, ZapierRelayError, ZapierReleaseTriggerMessageSignal, ZapierResourceNotFoundError, ZapierSignal, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, addPlugin, apiPlugin, apiPluginRef, appKeyResolver, appsPlugin, batch, buildApplicationLifecycleEvent, buildCapabilityMessage, buildErrorEvent, buildErrorEventWithContext, buildMethodCalledEvent, cleanupEventListeners, clearTokenCache, clientCredentialsNameResolver, clientIdResolver, composePlugins, connectionIdGenericResolver, connectionIdResolver, connectionsPlugin, connectionsPluginRef, createActionRunPlugin, createBaseEvent, createClientCredentialsPlugin, createController, createCorePlugin, createFunction, createMemoryCache, createPaginatedFunction, createPaginatedPluginMethod, createPluginMethod, createPluginStack, createSdk, createTableFieldsPlugin, createTablePlugin, createTableRecordsPlugin, createZapierApi, createZapierSdk, createZapierSdkWithoutRegistry, declareMethod, declareOptionalProperty, declarePlugin, declareProperty, defineFormatter, defineLegacyMerge, defineMethod, defineMethodOverride, definePlugin, defineProperty, defineResolver, deleteClientCredentialsPlugin, deleteTableFieldsPlugin, deleteTablePlugin, deleteTableRecordsPlugin, disposeSdk, durableRunIdResolver, eventEmissionHookPlugin, eventEmissionPlugin, eventEmissionPluginRef, extractErrorDetail, fetchPlugin, findFirstConnectionPlugin, findManifestEntry, findUniqueConnectionPlugin, formatErrorMessage, fromFunctionPlugin, generateEventId, getActionInputFieldsSchemaPlugin, getActionPlugin, getActionRunPlugin, getAgent, getAppPlugin, getBaseUrlFromCredentials, getCallerContext, getCiPlatform, getClientIdFromCredentials, getConnectionPlugin, getContext, getCoreErrorCause, getCoreErrorCode, getCpuTime, getCurrentTimestamp, getMemoryUsage, getNegatable, getOrCreateApiClient, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getRegistryPlugin, getReleaseId, getTablePlugin, getTableRecordPlugin, getTokenFromCliLogin, getTtyContext, getZapierApprovalMode, getZapierDefaultApprovalMode, getZapierOpenAutoModeApprovalsInBrowser, getZapierSdkService, injectCliLogin, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, invalidateCachedToken, invalidateCredentialsToken, isCi, isCliLoginAvailable, isClientCredentials, isCoreCancelledSignal, isCoreError, isCoreSignal, isCredentialsFunction, isCredentialsObject, isPermanentHttpError, isPkceCredentials, isPositional, isZapierAbortDrainSignal, isZapierActionError, isZapierAppNotFoundError, isZapierApprovalError, isZapierAuthenticationError, isZapierBundleError, isZapierConflictError, isZapierError, isZapierNotFoundError, isZapierRateLimitError, isZapierReleaseTriggerMessageSignal, isZapierResourceNotFoundError, isZapierSignal, isZapierTimeoutError, isZapierValidationError, listActionInputFieldChoicesPlugin, listActionInputFieldsPlugin, listActionsPlugin, listAppsPlugin, listClientCredentialsPlugin, listConnectionsPlugin, listTableFieldsPlugin, listTableRecordsPlugin, listTablesPlugin, logDeprecation2 as logDeprecation, manifestPlugin, manifestPluginRef, omitExports, openEnum, operationAnnotatorPlugin, parseConcurrencyEnvVar, readManifestFromFile, registryPlugin, requestPlugin, resetDeprecationWarnings2 as resetDeprecationWarnings, resolveAuth, resolveAuthToken, resolveCredentials, resolveCredentialsFromEnv, resolveCredentialsPlugin, resolveCredentialsPluginRef, resolvePlugin, runActionPlugin, runInMethodScope, runWithCallerContext, runWithTelemetryContext, sdkOptionsPluginRef, selectExports, tableFieldIdsResolver, tableFieldsResolver, tableFiltersResolver, tableIdResolver, tableNameResolver, tableRecordIdResolver, tableRecordIdsResolver, tableRecordsResolver, tableSortResolver, tableUpdateRecordsResolver, toSnakeCase, toTitleCase, triggerInboxResolver, triggerMessagesResolver, updateTableRecordsPlugin, workflowDraftIdResolver, workflowIdResolver, workflowRunIdResolver, workflowVersionIdResolver, zapierAdaptError, zapierCoreOptions, zapierSdkPlugin };
16406
+ export { ACTION_RUNS_PATH, API_ID, ActionKeyPropertySchema, ActionPropertySchema, ActionTimeoutMillisecondsPropertySchema, ActionTimeoutSecondsPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AppPropertySchema, AppsPropertySchema, AuthMechanism, AuthenticationIdPropertySchema, BaseSdkOptionsSchema, CONNECTIONS_ID, CONTEXT, CONTEXT_CACHE_MAX_SIZE, CONTEXT_CACHE_TTL_MILLISECONDS, CORE_ERROR_SYMBOL, CORE_OPTIONS_ID, CORE_SIGNAL_SYMBOL, ClientCredentialsObjectSchema, ConnectionEntrySchema, ConnectionIdPropertySchema, ConnectionPropertySchema, ConnectionsMapSchema, ConnectionsPropertySchema, CoreCancelledSignal, CoreDisposeError, CoreErrorCode, CoreSignal, CredentialsFunctionSchema, CredentialsObjectSchema, CredentialsSchema, DEFAULT_ACTION_TIMEOUT_MILLISECONDS, DEFAULT_APPROVAL_TIMEOUT_MILLISECONDS, DEFAULT_CONFIG_PATH, DEFAULT_MAX_APPROVAL_RETRIES, DEFAULT_PAGE_SIZE, DEPRECATION_NOTICE_EVENT, DebugPropertySchema, DrainTriggerInboxSchema, EVENT_EMISSION_ID, FieldsPropertySchema, InputFieldPropertySchema, InputsPropertySchema, LeaseLimitPropertySchema, LeasePropertySchema, LeaseSecondsPropertySchema, LimitPropertySchema, MANIFEST_ID, MAX_CONCURRENCY_LIMIT, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, PkceCredentialsObjectSchema, RESOLVE_CREDENTIALS_ID, RecordPropertySchema, RecordsPropertySchema, RelayFetchSchema, RelayRequestSchema, ResolvedCredentialsSchema, SDK_OPTIONS_ID, TablePropertySchema, TablesPropertySchema, TriggerInboxKeyPropertySchema, TriggerInboxNamePropertySchema, TriggerInboxPropertySchema, WatchTriggerInboxSchema, ZAPIER_BASE_URL, ZAPIER_MAX_CONCURRENT_REQUESTS, ZAPIER_MAX_NETWORK_RETRIES, ZAPIER_MAX_NETWORK_RETRY_DELAY_MILLISECONDS, ZapierAbortDrainSignal, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierApprovalError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierConflictError, ZapierError, ZapierNotFoundError, ZapierRateLimitError, ZapierRelayError, ZapierReleaseTriggerMessageSignal, ZapierResourceNotFoundError, ZapierSignal, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, addPlugin, apiPlugin, apiPluginRef, appKeyResolver, appsPlugin, batch, buildApplicationLifecycleEvent, buildCapabilityMessage, buildErrorEvent, buildErrorEventWithContext, buildMethodCalledEvent, cleanupEventListeners, clearTokenCache, clientCredentialsNameResolver, clientIdResolver, composePlugins, connectionIdGenericResolver, connectionIdResolver, connectionsPlugin, connectionsPluginRef, createActionRunPlugin, createBaseEvent, createClientCredentialsPlugin, createController, createCorePlugin, createFunction, createMemoryCache, createPaginatedFunction, createPaginatedPluginMethod, createPluginMethod, createPluginStack, createSdk, createTableFieldsPlugin, createTablePlugin, createTableRecordsPlugin, createZapierApi, createZapierSdk, createZapierSdkWithoutRegistry, declareMethod, declareOptionalProperty, declarePlugin, declareProperty, defineFormatter, defineLegacyMerge, defineMethod, defineMethodOverride, definePlugin, defineProperty, defineResolver, deleteClientCredentialsPlugin, deleteTableFieldsPlugin, deleteTablePlugin, deleteTableRecordsPlugin, disposeSdk, durableRunIdResolver, eventEmissionHookPlugin, eventEmissionPlugin, eventEmissionPluginRef, extractErrorDetail, fetchPlugin2 as fetchPlugin, findFirstConnectionPlugin, findManifestEntry, findUniqueConnectionPlugin, formatErrorMessage, fromFunctionPlugin, generateEventId, getActionInputFieldsSchemaPlugin, getActionPlugin, getActionRunPlugin, getAgent, getAppPlugin, getBaseUrlFromCredentials, getCallerContext, getCiPlatform, getClientIdFromCredentials, getConnectionPlugin, getContext, getCoreErrorCause, getCoreErrorCode, getCpuTime, getCurrentTimestamp, getMemoryUsage, getNegatable, getOrCreateApiClient, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getRegistryPlugin, getReleaseId, getTablePlugin, getTableRecordPlugin, getTokenFromCliLogin, getTtyContext, getZapierApprovalMode, getZapierDefaultApprovalMode, getZapierOpenAutoModeApprovalsInBrowser, getZapierSdkService, injectCliLogin, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, invalidateCachedToken, invalidateCredentialsToken, isCi, isCliLoginAvailable, isClientCredentials, isCoreCancelledSignal, isCoreError, isCoreSignal, isCredentialsFunction, isCredentialsObject, isPermanentHttpError, isPkceCredentials, isPositional, isZapierAbortDrainSignal, isZapierActionError, isZapierAppNotFoundError, isZapierApprovalError, isZapierAuthenticationError, isZapierBundleError, isZapierConflictError, isZapierError, isZapierNotFoundError, isZapierRateLimitError, isZapierReleaseTriggerMessageSignal, isZapierResourceNotFoundError, isZapierSignal, isZapierTimeoutError, isZapierValidationError, listActionInputFieldChoicesPlugin, listActionInputFieldsPlugin, listActionsPlugin, listAppsPlugin, listClientCredentialsPlugin, listConnectionsPlugin, listTableFieldsPlugin, listTableRecordsPlugin, listTablesPlugin, logDeprecation2 as logDeprecation, manifestPlugin, manifestPluginRef, omitExports, openEnum, operationAnnotatorPlugin, parseConcurrencyEnvVar, readManifestFromFile, registryPlugin, requestPlugin, resetDeprecationWarnings2 as resetDeprecationWarnings, resolveAuth, resolveAuthToken, resolveCredentials, resolveCredentialsFromEnv, resolveCredentialsPlugin, resolveCredentialsPluginRef, resolvePlugin, runActionPlugin, runInMethodScope, runWithCallerContext, runWithTelemetryContext, sdkOptionsPluginRef, selectExports, tableFieldIdsResolver, tableFieldsResolver, tableFiltersResolver, tableIdResolver, tableNameResolver, tableRecordIdResolver, tableRecordIdsResolver, tableRecordsResolver, tableSortResolver, tableUpdateRecordsResolver, toSnakeCase, toTitleCase, triggerInboxResolver, triggerMessagesResolver, updateTableRecordsPlugin, workflowDraftIdResolver, workflowIdResolver, workflowRunIdResolver, workflowVersionIdResolver, zapierAdaptError, zapierCoreOptions, zapierSdkPlugin };