@zapier/zapier-sdk 0.51.0 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -63,6 +63,21 @@ function parseIntEnvVar(name) {
63
63
  }
64
64
  var ZAPIER_MAX_NETWORK_RETRIES = parseIntEnvVar("ZAPIER_MAX_NETWORK_RETRIES") ?? 3;
65
65
  var ZAPIER_MAX_NETWORK_RETRY_DELAY_MS = parseIntEnvVar("ZAPIER_MAX_NETWORK_RETRY_DELAY_MS") ?? 6e4;
66
+ var MAX_CONCURRENCY_LIMIT = 1e4;
67
+ function parseConcurrencyEnvVar(name) {
68
+ const value = globalThis.process?.env?.[name];
69
+ if (!value) return void 0;
70
+ if (value === "Infinity") return Infinity;
71
+ if (/^[1-9]\d*$/.test(value)) {
72
+ const parsed = parseInt(value, 10);
73
+ if (parsed <= MAX_CONCURRENCY_LIMIT) return parsed;
74
+ }
75
+ console.warn(
76
+ `[zapier-sdk] Invalid value for ${name}: "${value}" (expected positive integer 1-${MAX_CONCURRENCY_LIMIT} or "Infinity")`
77
+ );
78
+ return void 0;
79
+ }
80
+ var ZAPIER_MAX_CONCURRENT_REQUESTS = parseConcurrencyEnvVar("ZAPIER_MAX_CONCURRENT_REQUESTS") ?? 200;
66
81
  function getZapierApprovalMode() {
67
82
  const value = globalThis.process?.env?.ZAPIER_APPROVAL_MODE;
68
83
  if (value === "disabled" || value === "poll" || value === "throw")
@@ -5576,6 +5591,83 @@ async function pollUntilComplete(options) {
5576
5591
  }
5577
5592
  }
5578
5593
  }
5594
+
5595
+ // src/api/concurrency.ts
5596
+ var NO_OP_RELEASE = () => {
5597
+ };
5598
+ var NO_OP_SEMAPHORE = {
5599
+ acquire: async () => NO_OP_RELEASE,
5600
+ tryAcquire: () => NO_OP_RELEASE
5601
+ };
5602
+ function createSemaphore(maxPermits) {
5603
+ if (maxPermits === Infinity) {
5604
+ return NO_OP_SEMAPHORE;
5605
+ }
5606
+ if (!Number.isInteger(maxPermits) || maxPermits <= 0) {
5607
+ throw new Error(
5608
+ `maxPermits must be a positive integer or Infinity, got: ${maxPermits}`
5609
+ );
5610
+ }
5611
+ let permits = maxPermits;
5612
+ const waiters = [];
5613
+ const release = () => {
5614
+ const next = waiters.shift();
5615
+ if (next) {
5616
+ next.grant();
5617
+ } else {
5618
+ permits++;
5619
+ }
5620
+ };
5621
+ const makeReleaseOnce = () => {
5622
+ let released = false;
5623
+ return () => {
5624
+ if (released) return;
5625
+ released = true;
5626
+ release();
5627
+ };
5628
+ };
5629
+ return {
5630
+ tryAcquire() {
5631
+ if (permits > 0) {
5632
+ permits--;
5633
+ return makeReleaseOnce();
5634
+ }
5635
+ return null;
5636
+ },
5637
+ async acquire(signal) {
5638
+ if (signal?.aborted) {
5639
+ throw signal.reason ?? new DOMException("Aborted", "AbortError");
5640
+ }
5641
+ if (permits > 0) {
5642
+ permits--;
5643
+ return makeReleaseOnce();
5644
+ }
5645
+ return new Promise((resolve2, reject) => {
5646
+ const onAbort = () => {
5647
+ const idx = waiters.indexOf(waiter);
5648
+ if (idx !== -1) {
5649
+ waiters.splice(idx, 1);
5650
+ waiter.cancel(
5651
+ signal?.reason ?? new DOMException("Aborted", "AbortError")
5652
+ );
5653
+ }
5654
+ };
5655
+ const waiter = {
5656
+ grant: () => {
5657
+ signal?.removeEventListener("abort", onAbort);
5658
+ resolve2(makeReleaseOnce());
5659
+ },
5660
+ cancel: (reason) => {
5661
+ signal?.removeEventListener("abort", onAbort);
5662
+ reject(reason);
5663
+ }
5664
+ };
5665
+ signal?.addEventListener("abort", onAbort);
5666
+ waiters.push(waiter);
5667
+ });
5668
+ }
5669
+ };
5670
+ }
5579
5671
  var ClientCredentialsObjectSchema = zod.z.object({
5580
5672
  type: zod.z.enum(["client_credentials"]).optional().meta({ internal: true }),
5581
5673
  clientId: zod.z.string().describe("OAuth client ID for authentication.").meta({ valueHint: "id" }),
@@ -6170,7 +6262,7 @@ async function invalidateCredentialsToken(options) {
6170
6262
  }
6171
6263
 
6172
6264
  // src/sdk-version.ts
6173
- var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.51.0" : void 0) || "unknown";
6265
+ var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.52.0" : void 0) || "unknown";
6174
6266
 
6175
6267
  // src/utils/open-url.ts
6176
6268
  var nodePrefix = "node:";
@@ -6380,9 +6472,61 @@ var ZapierApiClient = class {
6380
6472
  await sleep(delayMs, init?.signal ?? void 0);
6381
6473
  }
6382
6474
  };
6475
+ /**
6476
+ * Wrap an outbound HTTP call with the concurrency semaphore. Used by both
6477
+ * `rawFetch` (path-based) and the approval-poll path (absolute URL); each
6478
+ * caller acquires per-attempt, so 429 retry sleep is held but the gap
6479
+ * between approval polls and the human-approval wait are not.
6480
+ *
6481
+ * The release is registered in a finally that wraps the entire post-
6482
+ * acquire flow — including the `wait_end` event emission — so a throwing
6483
+ * `onEvent` handler can never leak a permit.
6484
+ *
6485
+ * Slot lifetime is intentionally tied to "fetch resolves" (headers
6486
+ * received), NOT to "response body fully consumed". WHATWG `fetch()`
6487
+ * resolves once headers are in; the body is still streaming. We rely on
6488
+ * that boundary so streaming responses (SSE, long-running chunked reads)
6489
+ * don't pin a permit for the lifetime of the stream — a single SSE
6490
+ * consumer would otherwise hold one of N slots for as long as the
6491
+ * connection stays open. Do not move the release into a path that awaits
6492
+ * body consumption (e.g. `parseResult` / `response.text()`); doing so
6493
+ * would silently break streaming consumers without failing any of the
6494
+ * short-request tests.
6495
+ */
6496
+ this.withSemaphore = async (context, fn) => {
6497
+ const fastRelease = this.semaphore.tryAcquire();
6498
+ let waitStart = null;
6499
+ let release = fastRelease;
6500
+ if (release === null) {
6501
+ waitStart = Date.now();
6502
+ this.emitEvent("api:concurrency_wait_start", {
6503
+ url: context.url,
6504
+ method: context.method
6505
+ });
6506
+ release = await this.semaphore.acquire(context.signal ?? void 0);
6507
+ }
6508
+ const acquiredRelease = release;
6509
+ try {
6510
+ if (waitStart !== null) {
6511
+ this.emitEvent("api:concurrency_wait_end", {
6512
+ url: context.url,
6513
+ method: context.method,
6514
+ waitedMs: Date.now() - waitStart
6515
+ });
6516
+ }
6517
+ return await fn();
6518
+ } finally {
6519
+ acquiredRelease();
6520
+ }
6521
+ };
6383
6522
  /**
6384
6523
  * Perform a request with auth, header merging, and rate-limit (429) retries.
6385
6524
  * Does NOT handle 403 approval_required — that's routed by `fetch`.
6525
+ *
6526
+ * Concurrency: a semaphore slot is held across the entire call, including
6527
+ * the 429 retry sleep inside `rawFetchUrl`. That keeps backpressure
6528
+ * coherent — when the server is rate-limiting us, we don't dump more
6529
+ * parallelism into the queue.
6386
6530
  */
6387
6531
  this.rawFetch = async (path, init) => {
6388
6532
  if (!path.startsWith("/")) {
@@ -6391,7 +6535,10 @@ var ZapierApiClient = class {
6391
6535
  );
6392
6536
  }
6393
6537
  const { url, pathConfig: pathConfig2 } = this.buildUrl(path, init?.searchParams);
6394
- return this.rawFetchUrl(url, init, pathConfig2);
6538
+ return this.withSemaphore(
6539
+ { url, method: init?.method ?? "GET", signal: init?.signal },
6540
+ () => this.rawFetchUrl(url, init, pathConfig2)
6541
+ );
6395
6542
  };
6396
6543
  /**
6397
6544
  * Approval-aware HTTP fetch.
@@ -6499,6 +6646,15 @@ var ZapierApiClient = class {
6499
6646
  };
6500
6647
  this.maxNetworkRetries = options.maxNetworkRetries ?? ZAPIER_MAX_NETWORK_RETRIES;
6501
6648
  this.maxNetworkRetryDelayMs = options.maxNetworkRetryDelayMs ?? ZAPIER_MAX_NETWORK_RETRY_DELAY_MS;
6649
+ const requested = options.maxConcurrentRequests;
6650
+ const limit = requested === void 0 || Number.isNaN(requested) ? ZAPIER_MAX_CONCURRENT_REQUESTS : requested;
6651
+ if (limit !== Infinity && (!Number.isInteger(limit) || limit < 1 || limit > MAX_CONCURRENCY_LIMIT)) {
6652
+ throw new ZapierConfigurationError(
6653
+ `Invalid maxConcurrentRequests: ${limit} (expected positive integer 1-${MAX_CONCURRENCY_LIMIT} or Infinity)`,
6654
+ { configType: "maxConcurrentRequests" }
6655
+ );
6656
+ }
6657
+ this.semaphore = createSemaphore(limit);
6502
6658
  }
6503
6659
  // Emit an event if onEvent handler is configured
6504
6660
  emitEvent(type, payload) {
@@ -6876,10 +7032,16 @@ var ZapierApiClient = class {
6876
7032
  // poll_url is an absolute URL supplied by the server, so we use
6877
7033
  // rawFetchUrl directly (skipping path resolution) but still share
6878
7034
  // auth + interactive-header + 429-retry with the rest of the SDK.
6879
- fetchPoll: () => this.rawFetchUrl(approval.poll_url, {
6880
- method: "GET",
6881
- headers: { Accept: "application/json" }
6882
- }),
7035
+ // Each individual poll request goes through the concurrency
7036
+ // semaphore — but we deliberately do not hold a slot across the
7037
+ // sleep between polls or across the human-approval wait.
7038
+ fetchPoll: () => this.withSemaphore(
7039
+ { url: approval.poll_url, method: "GET" },
7040
+ () => this.rawFetchUrl(approval.poll_url, {
7041
+ method: "GET",
7042
+ headers: { Accept: "application/json" }
7043
+ })
7044
+ ),
6883
7045
  timeoutMs,
6884
7046
  isPending: (body2) => {
6885
7047
  const parsed = PollApprovalResponseSchema.safeParse(body2);
@@ -6981,6 +7143,7 @@ var apiPlugin = definePlugin(
6981
7143
  debug = false,
6982
7144
  maxNetworkRetries = ZAPIER_MAX_NETWORK_RETRIES,
6983
7145
  maxNetworkRetryDelayMs = ZAPIER_MAX_NETWORK_RETRY_DELAY_MS,
7146
+ maxConcurrentRequests = ZAPIER_MAX_CONCURRENT_REQUESTS,
6984
7147
  approvalTimeoutMs,
6985
7148
  maxApprovalRetries,
6986
7149
  approvalMode,
@@ -6995,6 +7158,7 @@ var apiPlugin = definePlugin(
6995
7158
  onEvent,
6996
7159
  maxNetworkRetries,
6997
7160
  maxNetworkRetryDelayMs,
7161
+ maxConcurrentRequests,
6998
7162
  approvalTimeoutMs,
6999
7163
  maxApprovalRetries,
7000
7164
  approvalMode,
@@ -8880,6 +9044,24 @@ var BaseSdkOptionsSchema = zod.z.object({
8880
9044
  * Default is 60000 (60 seconds).
8881
9045
  */
8882
9046
  maxNetworkRetryDelayMs: zod.z.number().optional().describe("Max delay in ms to wait for retry (default: 60000).").meta({ valueHint: "ms" }),
9047
+ /**
9048
+ * Maximum number of concurrent in-flight HTTP requests per client.
9049
+ * Requests beyond this limit queue in FIFO order until a slot frees.
9050
+ * Pass `Infinity` to disable. Default: 200.
9051
+ *
9052
+ * The description and meta are duplicated across the outer wrapper and
9053
+ * the inner numeric branch because the SDK and CLI doc generators walk
9054
+ * the schema differently — the SDK reader looks at wrappers only, while
9055
+ * the CLI reader recurses into union branches.
9056
+ */
9057
+ maxConcurrentRequests: zod.z.union([
9058
+ zod.z.number().int().min(1).max(MAX_CONCURRENCY_LIMIT).describe(
9059
+ `Max concurrent in-flight HTTP requests (default: 200, max: ${MAX_CONCURRENCY_LIMIT}).`
9060
+ ).meta({ valueHint: "count" }),
9061
+ zod.z.literal(Infinity)
9062
+ ]).optional().describe(
9063
+ `Max concurrent in-flight HTTP requests (default: 200, max: ${MAX_CONCURRENCY_LIMIT}).`
9064
+ ).meta({ valueHint: "count" }),
8883
9065
  approvalTimeoutMs: zod.z.number().optional().describe("Timeout in ms for approval polling. Default: 600000 (10 min).").meta({ valueHint: "ms" }),
8884
9066
  maxApprovalRetries: zod.z.number().optional().describe(
8885
9067
  "Maximum number of sequential approval rounds per request (one per gating policy) before giving up. Default: 2."
@@ -8944,6 +9126,7 @@ exports.LeaseLimitPropertySchema = LeaseLimitPropertySchema;
8944
9126
  exports.LeasePropertySchema = LeasePropertySchema;
8945
9127
  exports.LeaseSecondsPropertySchema = LeaseSecondsPropertySchema;
8946
9128
  exports.LimitPropertySchema = LimitPropertySchema;
9129
+ exports.MAX_CONCURRENCY_LIMIT = MAX_CONCURRENCY_LIMIT;
8947
9130
  exports.MAX_PAGE_LIMIT = MAX_PAGE_LIMIT;
8948
9131
  exports.OffsetPropertySchema = OffsetPropertySchema;
8949
9132
  exports.OutputPropertySchema = OutputPropertySchema;
@@ -8959,6 +9142,7 @@ exports.TablesPropertySchema = TablesPropertySchema;
8959
9142
  exports.TriggerInboxNamePropertySchema = TriggerInboxNamePropertySchema;
8960
9143
  exports.TriggerInboxPropertySchema = TriggerInboxPropertySchema;
8961
9144
  exports.ZAPIER_BASE_URL = ZAPIER_BASE_URL;
9145
+ exports.ZAPIER_MAX_CONCURRENT_REQUESTS = ZAPIER_MAX_CONCURRENT_REQUESTS;
8962
9146
  exports.ZAPIER_MAX_NETWORK_RETRIES = ZAPIER_MAX_NETWORK_RETRIES;
8963
9147
  exports.ZAPIER_MAX_NETWORK_RETRY_DELAY_MS = ZAPIER_MAX_NETWORK_RETRY_DELAY_MS;
8964
9148
  exports.ZapierAbortDrainSignal = ZapierAbortDrainSignal;
@@ -9070,6 +9254,7 @@ exports.listTableRecordsPlugin = listTableRecordsPlugin;
9070
9254
  exports.listTablesPlugin = listTablesPlugin;
9071
9255
  exports.logDeprecation = logDeprecation;
9072
9256
  exports.manifestPlugin = manifestPlugin;
9257
+ exports.parseConcurrencyEnvVar = parseConcurrencyEnvVar;
9073
9258
  exports.readManifestFromFile = readManifestFromFile;
9074
9259
  exports.registryPlugin = registryPlugin;
9075
9260
  exports.requestPlugin = requestPlugin;
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { u as Action, d as ActionEntry, cg as ActionExecutionOptions, y as ActionExecutionResult, z as ActionField, H as ActionFieldChoice, aU as ActionItem, bv as ActionKeyProperty, b3 as ActionKeyPropertySchema, bw as ActionProperty, b4 as ActionPropertySchema, aq as ActionResolverItem, bH as ActionTimeoutMsProperty, bf as ActionTimeoutMsPropertySchema, ar as ActionTypeItem, bu as ActionTypeProperty, b2 as ActionTypePropertySchema, b as AddActionEntryOptions, c as AddActionEntryResult, A as ApiClient, bU as ApiError, dB as ApiEvent, c_ as ApiPluginOptions, d0 as ApiPluginProvides, v as App, ch as AppFactoryInput, aS as AppItem, bs as AppKeyProperty, b0 as AppKeyPropertySchema, bt as AppProperty, b1 as AppPropertySchema, aB as ApplicationLifecycleEventData, c9 as ApprovalStatus, cf as AppsPluginProvides, bM as AppsProperty, bk as AppsPropertySchema, a0 as ArrayResolver, dA as AuthEvent, bA as AuthenticationIdProperty, b7 as AuthenticationIdPropertySchema, ax as BaseEvent, aj as BaseSdkOptionsSchema, a8 as BatchOptions, cN as CONTEXT_CACHE_MAX_SIZE, cM as CONTEXT_CACHE_TTL_MS, x as Choice, dH as ClientCredentialsObject, dS as ClientCredentialsObjectSchema, K as Connection, d_ as ConnectionEntry, dZ as ConnectionEntrySchema, by as ConnectionIdProperty, b6 as ConnectionIdPropertySchema, aT as ConnectionItem, bz as ConnectionProperty, b8 as ConnectionPropertySchema, e0 as ConnectionsMap, d$ as ConnectionsMapSchema, e2 as ConnectionsPluginProvides, bO as ConnectionsProperty, bm as ConnectionsPropertySchema, O as ConnectionsResponse, cz as CreateClientCredentialsPluginProvides, eo as CreateTableFieldsPluginProvides, ei as CreateTablePluginProvides, ew as CreateTableRecordsPluginProvides, dE as Credentials, dX as CredentialsFunction, dW as CredentialsFunctionSchema, dG as CredentialsObject, dU as CredentialsObjectSchema, dY as CredentialsSchema, e7 as DEFAULT_ACTION_TIMEOUT_MS, eb as DEFAULT_APPROVAL_TIMEOUT_MS, cW as DEFAULT_CONFIG_PATH, ec as DEFAULT_MAX_APPROVAL_RETRIES, e6 as DEFAULT_PAGE_SIZE, bF as DebugProperty, bd as DebugPropertySchema, cB as DeleteClientCredentialsPluginProvides, eq as DeleteTableFieldsPluginProvides, ek as DeleteTablePluginProvides, ey as DeleteTableRecordsPluginProvides, o as DrainTriggerInboxCallback, p as DrainTriggerInboxErrorObserver, D as DrainTriggerInboxOptions, i as DynamicResolver, aC as EnhancedErrorEventData, bV as ErrorOptions, dD as EventCallback, aA as EventContext, E as EventEmissionContext, az as EventEmissionProvides, cj as FetchPluginProvides, w as Field, bL as FieldsProperty, bj as FieldsPropertySchema, a3 as FieldsResolver, F as FieldsetItem, s as FindFirstAuthenticationPluginProvides, cJ as FindFirstConnectionPluginProvides, t as FindUniqueAuthenticationPluginProvides, cL as FindUniqueConnectionPluginProvides, Y as FormatMetadata, X as FormattedItem, ai as FunctionDeprecation, aZ as FunctionOptions, ah as FunctionRegistryEntry, ct as GetActionInputFieldsSchemaPluginProvides, cF as GetActionPluginProvides, cD as GetAppPluginProvides, G as GetAuthenticationPluginProvides, cH as GetConnectionPluginProvides, cZ as GetProfilePluginProvides, eg as GetTablePluginProvides, es as GetTableRecordPluginProvides, aW as InfoFieldItem, aV as InputFieldItem, bx as InputFieldProperty, b5 as InputFieldPropertySchema, bB as InputsProperty, b9 as InputsPropertySchema, bT as LeaseLimitProperty, br as LeaseLimitPropertySchema, bR as LeaseProperty, bp as LeasePropertySchema, bS as LeaseSecondsProperty, bq as LeaseSecondsPropertySchema, L as LeasedTriggerMessageItem, bC as LimitProperty, ba as LimitPropertySchema, cr as ListActionInputFieldChoicesPluginProvides, cp as ListActionInputFieldsPluginProvides, cn as ListActionsPluginProvides, cl as ListAppsPluginProvides, q as ListAuthenticationsPluginProvides, cx as ListClientCredentialsPluginProvides, cv as ListConnectionsPluginProvides, em as ListTableFieldsPluginProvides, eu as ListTableRecordsPluginProvides, ee as ListTablesPluginProvides, dC as LoadingEvent, e5 as MAX_PAGE_LIMIT, M as Manifest, cX as ManifestEntry, cS as ManifestPluginOptions, cV as ManifestPluginProvides, ay as MethodCalledEvent, aD as MethodCalledEventData, N as Need, I as NeedsRequest, J as NeedsResponse, bD as OffsetProperty, bb as OffsetPropertySchema, _ as OutputFormatter, bE as OutputProperty, bc as OutputPropertySchema, a$ as PaginatedSdkFunction, e as PaginatedSdkResult, bG as ParamsProperty, be as ParamsPropertySchema, dI as PkceCredentialsObject, dT as PkceCredentialsObjectSchema, ak as Plugin, P as PluginMeta, al as PluginProvides, au as PollOptions, g as PositionalMetadata, c7 as RateLimitInfo, bJ as RecordProperty, bh as RecordPropertySchema, bK as RecordsProperty, bi as RecordsPropertySchema, ad as RelayFetchSchema, ac as RelayRequestSchema, at as RequestOptions, cR as RequestPluginProvides, dm as ResolveAuthTokenOptions, dN as ResolveCredentialsOptions, R as ResolvedAppLocator, dF as ResolvedCredentials, dV as ResolvedCredentialsSchema, $ as Resolver, a1 as ResolverMetadata, aX as RootFieldItem, cP as RunActionPluginProvides, dz as SdkEvent, a_ as SdkPage, a2 as StaticResolver, bI as TableProperty, bg as TablePropertySchema, bN as TablesProperty, bl as TablesPropertySchema, bQ as TriggerInboxNameProperty, bo as TriggerInboxNamePropertySchema, bP as TriggerInboxProperty, bn as TriggerInboxPropertySchema, T as TriggerMessageStatus, U as UpdateManifestEntryOptions, a as UpdateManifestEntryResult, eA as UpdateTableRecordsPluginProvides, Q as UserProfile, aY as UserProfileItem, j as WatchTriggerInboxOptions, W as WithAddPlugin, e3 as ZAPIER_BASE_URL, e8 as ZAPIER_MAX_NETWORK_RETRIES, e9 as ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, m as ZapierAbortDrainSignal, c5 as ZapierActionError, bX as ZapierApiError, bY as ZapierAppNotFoundError, ca as ZapierApprovalError, b$ as ZapierAuthenticationError, c3 as ZapierBundleError, dv as ZapierCache, dw as ZapierCacheEntry, dx as ZapierCacheSetOptions, c2 as ZapierConfigurationError, c6 as ZapierConflictError, bW as ZapierError, h as ZapierFetchInitOptions, c0 as ZapierNotFoundError, c8 as ZapierRateLimitError, cb as ZapierRelayError, n as ZapierReleaseTriggerMessageSignal, c1 as ZapierResourceNotFoundError, eC as ZapierSdk, l as ZapierSdkApps, Z as ZapierSdkOptions, cd as ZapierSignal, c4 as ZapierTimeoutError, b_ as ZapierUnknownError, bZ as ZapierValidationError, d3 as actionKeyResolver, d2 as actionTypeResolver, c$ as apiPlugin, d1 as appKeyResolver, ce as appsPlugin, d5 as authenticationIdGenericResolver, d4 as authenticationIdResolver, a7 as batch, aN as buildApplicationLifecycleEvent, a9 as buildCapabilityMessage, aP as buildErrorEvent, aO as buildErrorEventWithContext, aR as buildMethodCalledEvent, dn as clearTokenCache, d9 as clientCredentialsNameResolver, da as clientIdResolver, ap as composePlugins, d5 as connectionIdGenericResolver, d4 as connectionIdResolver, e1 as connectionsPlugin, aQ as createBaseEvent, cy as createClientCredentialsPlugin, V as createFunction, dy as createMemoryCache, ag as createOptionsPlugin, ao as createPaginatedPluginMethod, an as createPluginMethod, af as createSdk, en as createTableFieldsPlugin, eh as createTablePlugin, ev as createTableRecordsPlugin, av as createZapierApi, eB as createZapierSdk, ae as createZapierSdkWithoutRegistry, am as definePlugin, cA as deleteClientCredentialsPlugin, ep as deleteTableFieldsPlugin, ej as deleteTablePlugin, ex as deleteTableRecordsPlugin, ci as fetchPlugin, cI as findFirstConnectionPlugin, f as findManifestEntry, cK as findUniqueConnectionPlugin, cc as formatErrorMessage, aE as generateEventId, cs as getActionInputFieldsSchemaPlugin, cE as getActionPlugin, cC as getAppPlugin, dQ as getBaseUrlFromCredentials, aK as getCiPlatform, dR as getClientIdFromCredentials, cG as getConnectionPlugin, aM as getCpuTime, aF as getCurrentTimestamp, aL as getMemoryUsage, aw as getOrCreateApiClient, aH as getOsInfo, aI as getPlatformVersions, cT as getPreferredManifestEntryKey, cY as getProfilePlugin, aG as getReleaseId, ef as getTablePlugin, er as getTableRecordPlugin, ds as getTokenFromCliLogin, ea as getZapierApprovalMode, e4 as getZapierSdkService, dq as injectCliLogin, d8 as inputFieldKeyResolver, d7 as inputsAllOptionalResolver, d6 as inputsResolver, dp as invalidateCachedToken, du as invalidateCredentialsToken, aJ as isCi, dr as isCliLoginAvailable, dJ as isClientCredentials, dM as isCredentialsFunction, dL as isCredentialsObject, dK as isPkceCredentials, S as isPositional, cq as listActionInputFieldChoicesPlugin, co as listActionInputFieldsPlugin, cm as listActionsPlugin, ck as listAppsPlugin, cw as listClientCredentialsPlugin, cu as listConnectionsPlugin, el as listTableFieldsPlugin, et as listTableRecordsPlugin, ed as listTablesPlugin, aa as logDeprecation, cU as manifestPlugin, r as readManifestFromFile, as as registryPlugin, cQ as requestPlugin, ab as resetDeprecationWarnings, dt as resolveAuthToken, dP as resolveCredentials, dO as resolveCredentialsFromEnv, cO as runActionPlugin, a4 as runWithTelemetryContext, df as tableFieldIdsResolver, dh as tableFieldsResolver, dk as tableFiltersResolver, db as tableIdResolver, dg as tableNameResolver, dd as tableRecordIdResolver, de as tableRecordIdsResolver, di as tableRecordsResolver, dl as tableSortResolver, dj as tableUpdateRecordsResolver, a5 as toSnakeCase, a6 as toTitleCase, dc as triggerInboxResolver, ez as updateTableRecordsPlugin } from './index-C52BjTXh.mjs';
1
+ export { u as Action, d as ActionEntry, cg as ActionExecutionOptions, y as ActionExecutionResult, z as ActionField, H as ActionFieldChoice, aU as ActionItem, bv as ActionKeyProperty, b3 as ActionKeyPropertySchema, bw as ActionProperty, b4 as ActionPropertySchema, aq as ActionResolverItem, bH as ActionTimeoutMsProperty, bf as ActionTimeoutMsPropertySchema, ar as ActionTypeItem, bu as ActionTypeProperty, b2 as ActionTypePropertySchema, b as AddActionEntryOptions, c as AddActionEntryResult, A as ApiClient, bU as ApiError, dB as ApiEvent, c_ as ApiPluginOptions, d0 as ApiPluginProvides, v as App, ch as AppFactoryInput, aS as AppItem, bs as AppKeyProperty, b0 as AppKeyPropertySchema, bt as AppProperty, b1 as AppPropertySchema, aB as ApplicationLifecycleEventData, c9 as ApprovalStatus, cf as AppsPluginProvides, bM as AppsProperty, bk as AppsPropertySchema, a0 as ArrayResolver, dA as AuthEvent, bA as AuthenticationIdProperty, b7 as AuthenticationIdPropertySchema, ax as BaseEvent, aj as BaseSdkOptionsSchema, a8 as BatchOptions, cN as CONTEXT_CACHE_MAX_SIZE, cM as CONTEXT_CACHE_TTL_MS, x as Choice, dH as ClientCredentialsObject, dS as ClientCredentialsObjectSchema, K as Connection, d_ as ConnectionEntry, dZ as ConnectionEntrySchema, by as ConnectionIdProperty, b6 as ConnectionIdPropertySchema, aT as ConnectionItem, bz as ConnectionProperty, b8 as ConnectionPropertySchema, e0 as ConnectionsMap, d$ as ConnectionsMapSchema, e2 as ConnectionsPluginProvides, bO as ConnectionsProperty, bm as ConnectionsPropertySchema, O as ConnectionsResponse, cz as CreateClientCredentialsPluginProvides, er as CreateTableFieldsPluginProvides, el as CreateTablePluginProvides, ez as CreateTableRecordsPluginProvides, dE as Credentials, dX as CredentialsFunction, dW as CredentialsFunctionSchema, dG as CredentialsObject, dU as CredentialsObjectSchema, dY as CredentialsSchema, e7 as DEFAULT_ACTION_TIMEOUT_MS, ee as DEFAULT_APPROVAL_TIMEOUT_MS, cW as DEFAULT_CONFIG_PATH, ef as DEFAULT_MAX_APPROVAL_RETRIES, e6 as DEFAULT_PAGE_SIZE, bF as DebugProperty, bd as DebugPropertySchema, cB as DeleteClientCredentialsPluginProvides, et as DeleteTableFieldsPluginProvides, en as DeleteTablePluginProvides, eB as DeleteTableRecordsPluginProvides, o as DrainTriggerInboxCallback, p as DrainTriggerInboxErrorObserver, D as DrainTriggerInboxOptions, i as DynamicResolver, aC as EnhancedErrorEventData, bV as ErrorOptions, dD as EventCallback, aA as EventContext, E as EventEmissionContext, az as EventEmissionProvides, cj as FetchPluginProvides, w as Field, bL as FieldsProperty, bj as FieldsPropertySchema, a3 as FieldsResolver, F as FieldsetItem, s as FindFirstAuthenticationPluginProvides, cJ as FindFirstConnectionPluginProvides, t as FindUniqueAuthenticationPluginProvides, cL as FindUniqueConnectionPluginProvides, Y as FormatMetadata, X as FormattedItem, ai as FunctionDeprecation, aZ as FunctionOptions, ah as FunctionRegistryEntry, ct as GetActionInputFieldsSchemaPluginProvides, cF as GetActionPluginProvides, cD as GetAppPluginProvides, G as GetAuthenticationPluginProvides, cH as GetConnectionPluginProvides, cZ as GetProfilePluginProvides, ej as GetTablePluginProvides, ev as GetTableRecordPluginProvides, aW as InfoFieldItem, aV as InputFieldItem, bx as InputFieldProperty, b5 as InputFieldPropertySchema, bB as InputsProperty, b9 as InputsPropertySchema, bT as LeaseLimitProperty, br as LeaseLimitPropertySchema, bR as LeaseProperty, bp as LeasePropertySchema, bS as LeaseSecondsProperty, bq as LeaseSecondsPropertySchema, L as LeasedTriggerMessageItem, bC as LimitProperty, ba as LimitPropertySchema, cr as ListActionInputFieldChoicesPluginProvides, cp as ListActionInputFieldsPluginProvides, cn as ListActionsPluginProvides, cl as ListAppsPluginProvides, q as ListAuthenticationsPluginProvides, cx as ListClientCredentialsPluginProvides, cv as ListConnectionsPluginProvides, ep as ListTableFieldsPluginProvides, ex as ListTableRecordsPluginProvides, eh as ListTablesPluginProvides, dC as LoadingEvent, ea as MAX_CONCURRENCY_LIMIT, e5 as MAX_PAGE_LIMIT, M as Manifest, cX as ManifestEntry, cS as ManifestPluginOptions, cV as ManifestPluginProvides, ay as MethodCalledEvent, aD as MethodCalledEventData, N as Need, I as NeedsRequest, J as NeedsResponse, bD as OffsetProperty, bb as OffsetPropertySchema, _ as OutputFormatter, bE as OutputProperty, bc as OutputPropertySchema, a$ as PaginatedSdkFunction, e as PaginatedSdkResult, bG as ParamsProperty, be as ParamsPropertySchema, dI as PkceCredentialsObject, dT as PkceCredentialsObjectSchema, ak as Plugin, P as PluginMeta, al as PluginProvides, au as PollOptions, g as PositionalMetadata, c7 as RateLimitInfo, bJ as RecordProperty, bh as RecordPropertySchema, bK as RecordsProperty, bi as RecordsPropertySchema, ad as RelayFetchSchema, ac as RelayRequestSchema, at as RequestOptions, cR as RequestPluginProvides, dm as ResolveAuthTokenOptions, dN as ResolveCredentialsOptions, R as ResolvedAppLocator, dF as ResolvedCredentials, dV as ResolvedCredentialsSchema, $ as Resolver, a1 as ResolverMetadata, aX as RootFieldItem, cP as RunActionPluginProvides, dz as SdkEvent, a_ as SdkPage, a2 as StaticResolver, bI as TableProperty, bg as TablePropertySchema, bN as TablesProperty, bl as TablesPropertySchema, bQ as TriggerInboxNameProperty, bo as TriggerInboxNamePropertySchema, bP as TriggerInboxProperty, bn as TriggerInboxPropertySchema, T as TriggerMessageStatus, U as UpdateManifestEntryOptions, a as UpdateManifestEntryResult, eD as UpdateTableRecordsPluginProvides, Q as UserProfile, aY as UserProfileItem, j as WatchTriggerInboxOptions, W as WithAddPlugin, e3 as ZAPIER_BASE_URL, ec as ZAPIER_MAX_CONCURRENT_REQUESTS, e8 as ZAPIER_MAX_NETWORK_RETRIES, e9 as ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, m as ZapierAbortDrainSignal, c5 as ZapierActionError, bX as ZapierApiError, bY as ZapierAppNotFoundError, ca as ZapierApprovalError, b$ as ZapierAuthenticationError, c3 as ZapierBundleError, dv as ZapierCache, dw as ZapierCacheEntry, dx as ZapierCacheSetOptions, c2 as ZapierConfigurationError, c6 as ZapierConflictError, bW as ZapierError, h as ZapierFetchInitOptions, c0 as ZapierNotFoundError, c8 as ZapierRateLimitError, cb as ZapierRelayError, n as ZapierReleaseTriggerMessageSignal, c1 as ZapierResourceNotFoundError, eF as ZapierSdk, l as ZapierSdkApps, Z as ZapierSdkOptions, cd as ZapierSignal, c4 as ZapierTimeoutError, b_ as ZapierUnknownError, bZ as ZapierValidationError, d3 as actionKeyResolver, d2 as actionTypeResolver, c$ as apiPlugin, d1 as appKeyResolver, ce as appsPlugin, d5 as authenticationIdGenericResolver, d4 as authenticationIdResolver, a7 as batch, aN as buildApplicationLifecycleEvent, a9 as buildCapabilityMessage, aP as buildErrorEvent, aO as buildErrorEventWithContext, aR as buildMethodCalledEvent, dn as clearTokenCache, d9 as clientCredentialsNameResolver, da as clientIdResolver, ap as composePlugins, d5 as connectionIdGenericResolver, d4 as connectionIdResolver, e1 as connectionsPlugin, aQ as createBaseEvent, cy as createClientCredentialsPlugin, V as createFunction, dy as createMemoryCache, ag as createOptionsPlugin, ao as createPaginatedPluginMethod, an as createPluginMethod, af as createSdk, eq as createTableFieldsPlugin, ek as createTablePlugin, ey as createTableRecordsPlugin, av as createZapierApi, eE as createZapierSdk, ae as createZapierSdkWithoutRegistry, am as definePlugin, cA as deleteClientCredentialsPlugin, es as deleteTableFieldsPlugin, em as deleteTablePlugin, eA as deleteTableRecordsPlugin, ci as fetchPlugin, cI as findFirstConnectionPlugin, f as findManifestEntry, cK as findUniqueConnectionPlugin, cc as formatErrorMessage, aE as generateEventId, cs as getActionInputFieldsSchemaPlugin, cE as getActionPlugin, cC as getAppPlugin, dQ as getBaseUrlFromCredentials, aK as getCiPlatform, dR as getClientIdFromCredentials, cG as getConnectionPlugin, aM as getCpuTime, aF as getCurrentTimestamp, aL as getMemoryUsage, aw as getOrCreateApiClient, aH as getOsInfo, aI as getPlatformVersions, cT as getPreferredManifestEntryKey, cY as getProfilePlugin, aG as getReleaseId, ei as getTablePlugin, eu as getTableRecordPlugin, ds as getTokenFromCliLogin, ed as getZapierApprovalMode, e4 as getZapierSdkService, dq as injectCliLogin, d8 as inputFieldKeyResolver, d7 as inputsAllOptionalResolver, d6 as inputsResolver, dp as invalidateCachedToken, du as invalidateCredentialsToken, aJ as isCi, dr as isCliLoginAvailable, dJ as isClientCredentials, dM as isCredentialsFunction, dL as isCredentialsObject, dK as isPkceCredentials, S as isPositional, cq as listActionInputFieldChoicesPlugin, co as listActionInputFieldsPlugin, cm as listActionsPlugin, ck as listAppsPlugin, cw as listClientCredentialsPlugin, cu as listConnectionsPlugin, eo as listTableFieldsPlugin, ew as listTableRecordsPlugin, eg as listTablesPlugin, aa as logDeprecation, cU as manifestPlugin, eb as parseConcurrencyEnvVar, r as readManifestFromFile, as as registryPlugin, cQ as requestPlugin, ab as resetDeprecationWarnings, dt as resolveAuthToken, dP as resolveCredentials, dO as resolveCredentialsFromEnv, cO as runActionPlugin, a4 as runWithTelemetryContext, df as tableFieldIdsResolver, dh as tableFieldsResolver, dk as tableFiltersResolver, db as tableIdResolver, dg as tableNameResolver, dd as tableRecordIdResolver, de as tableRecordIdsResolver, di as tableRecordsResolver, dl as tableSortResolver, dj as tableUpdateRecordsResolver, a5 as toSnakeCase, a6 as toTitleCase, dc as triggerInboxResolver, eC as updateTableRecordsPlugin } from './index-DcdtPei-.mjs';
2
2
  import 'zod';
3
3
  import '@zapier/zapier-sdk-core/v0/schemas/connections';
4
4
  import '@zapier/policy-context';
package/dist/index.mjs CHANGED
@@ -61,6 +61,21 @@ function parseIntEnvVar(name) {
61
61
  }
62
62
  var ZAPIER_MAX_NETWORK_RETRIES = parseIntEnvVar("ZAPIER_MAX_NETWORK_RETRIES") ?? 3;
63
63
  var ZAPIER_MAX_NETWORK_RETRY_DELAY_MS = parseIntEnvVar("ZAPIER_MAX_NETWORK_RETRY_DELAY_MS") ?? 6e4;
64
+ var MAX_CONCURRENCY_LIMIT = 1e4;
65
+ function parseConcurrencyEnvVar(name) {
66
+ const value = globalThis.process?.env?.[name];
67
+ if (!value) return void 0;
68
+ if (value === "Infinity") return Infinity;
69
+ if (/^[1-9]\d*$/.test(value)) {
70
+ const parsed = parseInt(value, 10);
71
+ if (parsed <= MAX_CONCURRENCY_LIMIT) return parsed;
72
+ }
73
+ console.warn(
74
+ `[zapier-sdk] Invalid value for ${name}: "${value}" (expected positive integer 1-${MAX_CONCURRENCY_LIMIT} or "Infinity")`
75
+ );
76
+ return void 0;
77
+ }
78
+ var ZAPIER_MAX_CONCURRENT_REQUESTS = parseConcurrencyEnvVar("ZAPIER_MAX_CONCURRENT_REQUESTS") ?? 200;
64
79
  function getZapierApprovalMode() {
65
80
  const value = globalThis.process?.env?.ZAPIER_APPROVAL_MODE;
66
81
  if (value === "disabled" || value === "poll" || value === "throw")
@@ -5574,6 +5589,83 @@ async function pollUntilComplete(options) {
5574
5589
  }
5575
5590
  }
5576
5591
  }
5592
+
5593
+ // src/api/concurrency.ts
5594
+ var NO_OP_RELEASE = () => {
5595
+ };
5596
+ var NO_OP_SEMAPHORE = {
5597
+ acquire: async () => NO_OP_RELEASE,
5598
+ tryAcquire: () => NO_OP_RELEASE
5599
+ };
5600
+ function createSemaphore(maxPermits) {
5601
+ if (maxPermits === Infinity) {
5602
+ return NO_OP_SEMAPHORE;
5603
+ }
5604
+ if (!Number.isInteger(maxPermits) || maxPermits <= 0) {
5605
+ throw new Error(
5606
+ `maxPermits must be a positive integer or Infinity, got: ${maxPermits}`
5607
+ );
5608
+ }
5609
+ let permits = maxPermits;
5610
+ const waiters = [];
5611
+ const release = () => {
5612
+ const next = waiters.shift();
5613
+ if (next) {
5614
+ next.grant();
5615
+ } else {
5616
+ permits++;
5617
+ }
5618
+ };
5619
+ const makeReleaseOnce = () => {
5620
+ let released = false;
5621
+ return () => {
5622
+ if (released) return;
5623
+ released = true;
5624
+ release();
5625
+ };
5626
+ };
5627
+ return {
5628
+ tryAcquire() {
5629
+ if (permits > 0) {
5630
+ permits--;
5631
+ return makeReleaseOnce();
5632
+ }
5633
+ return null;
5634
+ },
5635
+ async acquire(signal) {
5636
+ if (signal?.aborted) {
5637
+ throw signal.reason ?? new DOMException("Aborted", "AbortError");
5638
+ }
5639
+ if (permits > 0) {
5640
+ permits--;
5641
+ return makeReleaseOnce();
5642
+ }
5643
+ return new Promise((resolve2, reject) => {
5644
+ const onAbort = () => {
5645
+ const idx = waiters.indexOf(waiter);
5646
+ if (idx !== -1) {
5647
+ waiters.splice(idx, 1);
5648
+ waiter.cancel(
5649
+ signal?.reason ?? new DOMException("Aborted", "AbortError")
5650
+ );
5651
+ }
5652
+ };
5653
+ const waiter = {
5654
+ grant: () => {
5655
+ signal?.removeEventListener("abort", onAbort);
5656
+ resolve2(makeReleaseOnce());
5657
+ },
5658
+ cancel: (reason) => {
5659
+ signal?.removeEventListener("abort", onAbort);
5660
+ reject(reason);
5661
+ }
5662
+ };
5663
+ signal?.addEventListener("abort", onAbort);
5664
+ waiters.push(waiter);
5665
+ });
5666
+ }
5667
+ };
5668
+ }
5577
5669
  var ClientCredentialsObjectSchema = z.object({
5578
5670
  type: z.enum(["client_credentials"]).optional().meta({ internal: true }),
5579
5671
  clientId: z.string().describe("OAuth client ID for authentication.").meta({ valueHint: "id" }),
@@ -6168,7 +6260,7 @@ async function invalidateCredentialsToken(options) {
6168
6260
  }
6169
6261
 
6170
6262
  // src/sdk-version.ts
6171
- var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.51.0" : void 0) || "unknown";
6263
+ var SDK_VERSION = (typeof process !== "undefined" && process.env ? "0.52.0" : void 0) || "unknown";
6172
6264
 
6173
6265
  // src/utils/open-url.ts
6174
6266
  var nodePrefix = "node:";
@@ -6378,9 +6470,61 @@ var ZapierApiClient = class {
6378
6470
  await sleep(delayMs, init?.signal ?? void 0);
6379
6471
  }
6380
6472
  };
6473
+ /**
6474
+ * Wrap an outbound HTTP call with the concurrency semaphore. Used by both
6475
+ * `rawFetch` (path-based) and the approval-poll path (absolute URL); each
6476
+ * caller acquires per-attempt, so 429 retry sleep is held but the gap
6477
+ * between approval polls and the human-approval wait are not.
6478
+ *
6479
+ * The release is registered in a finally that wraps the entire post-
6480
+ * acquire flow — including the `wait_end` event emission — so a throwing
6481
+ * `onEvent` handler can never leak a permit.
6482
+ *
6483
+ * Slot lifetime is intentionally tied to "fetch resolves" (headers
6484
+ * received), NOT to "response body fully consumed". WHATWG `fetch()`
6485
+ * resolves once headers are in; the body is still streaming. We rely on
6486
+ * that boundary so streaming responses (SSE, long-running chunked reads)
6487
+ * don't pin a permit for the lifetime of the stream — a single SSE
6488
+ * consumer would otherwise hold one of N slots for as long as the
6489
+ * connection stays open. Do not move the release into a path that awaits
6490
+ * body consumption (e.g. `parseResult` / `response.text()`); doing so
6491
+ * would silently break streaming consumers without failing any of the
6492
+ * short-request tests.
6493
+ */
6494
+ this.withSemaphore = async (context, fn) => {
6495
+ const fastRelease = this.semaphore.tryAcquire();
6496
+ let waitStart = null;
6497
+ let release = fastRelease;
6498
+ if (release === null) {
6499
+ waitStart = Date.now();
6500
+ this.emitEvent("api:concurrency_wait_start", {
6501
+ url: context.url,
6502
+ method: context.method
6503
+ });
6504
+ release = await this.semaphore.acquire(context.signal ?? void 0);
6505
+ }
6506
+ const acquiredRelease = release;
6507
+ try {
6508
+ if (waitStart !== null) {
6509
+ this.emitEvent("api:concurrency_wait_end", {
6510
+ url: context.url,
6511
+ method: context.method,
6512
+ waitedMs: Date.now() - waitStart
6513
+ });
6514
+ }
6515
+ return await fn();
6516
+ } finally {
6517
+ acquiredRelease();
6518
+ }
6519
+ };
6381
6520
  /**
6382
6521
  * Perform a request with auth, header merging, and rate-limit (429) retries.
6383
6522
  * Does NOT handle 403 approval_required — that's routed by `fetch`.
6523
+ *
6524
+ * Concurrency: a semaphore slot is held across the entire call, including
6525
+ * the 429 retry sleep inside `rawFetchUrl`. That keeps backpressure
6526
+ * coherent — when the server is rate-limiting us, we don't dump more
6527
+ * parallelism into the queue.
6384
6528
  */
6385
6529
  this.rawFetch = async (path, init) => {
6386
6530
  if (!path.startsWith("/")) {
@@ -6389,7 +6533,10 @@ var ZapierApiClient = class {
6389
6533
  );
6390
6534
  }
6391
6535
  const { url, pathConfig: pathConfig2 } = this.buildUrl(path, init?.searchParams);
6392
- return this.rawFetchUrl(url, init, pathConfig2);
6536
+ return this.withSemaphore(
6537
+ { url, method: init?.method ?? "GET", signal: init?.signal },
6538
+ () => this.rawFetchUrl(url, init, pathConfig2)
6539
+ );
6393
6540
  };
6394
6541
  /**
6395
6542
  * Approval-aware HTTP fetch.
@@ -6497,6 +6644,15 @@ var ZapierApiClient = class {
6497
6644
  };
6498
6645
  this.maxNetworkRetries = options.maxNetworkRetries ?? ZAPIER_MAX_NETWORK_RETRIES;
6499
6646
  this.maxNetworkRetryDelayMs = options.maxNetworkRetryDelayMs ?? ZAPIER_MAX_NETWORK_RETRY_DELAY_MS;
6647
+ const requested = options.maxConcurrentRequests;
6648
+ const limit = requested === void 0 || Number.isNaN(requested) ? ZAPIER_MAX_CONCURRENT_REQUESTS : requested;
6649
+ if (limit !== Infinity && (!Number.isInteger(limit) || limit < 1 || limit > MAX_CONCURRENCY_LIMIT)) {
6650
+ throw new ZapierConfigurationError(
6651
+ `Invalid maxConcurrentRequests: ${limit} (expected positive integer 1-${MAX_CONCURRENCY_LIMIT} or Infinity)`,
6652
+ { configType: "maxConcurrentRequests" }
6653
+ );
6654
+ }
6655
+ this.semaphore = createSemaphore(limit);
6500
6656
  }
6501
6657
  // Emit an event if onEvent handler is configured
6502
6658
  emitEvent(type, payload) {
@@ -6874,10 +7030,16 @@ var ZapierApiClient = class {
6874
7030
  // poll_url is an absolute URL supplied by the server, so we use
6875
7031
  // rawFetchUrl directly (skipping path resolution) but still share
6876
7032
  // auth + interactive-header + 429-retry with the rest of the SDK.
6877
- fetchPoll: () => this.rawFetchUrl(approval.poll_url, {
6878
- method: "GET",
6879
- headers: { Accept: "application/json" }
6880
- }),
7033
+ // Each individual poll request goes through the concurrency
7034
+ // semaphore — but we deliberately do not hold a slot across the
7035
+ // sleep between polls or across the human-approval wait.
7036
+ fetchPoll: () => this.withSemaphore(
7037
+ { url: approval.poll_url, method: "GET" },
7038
+ () => this.rawFetchUrl(approval.poll_url, {
7039
+ method: "GET",
7040
+ headers: { Accept: "application/json" }
7041
+ })
7042
+ ),
6881
7043
  timeoutMs,
6882
7044
  isPending: (body2) => {
6883
7045
  const parsed = PollApprovalResponseSchema.safeParse(body2);
@@ -6979,6 +7141,7 @@ var apiPlugin = definePlugin(
6979
7141
  debug = false,
6980
7142
  maxNetworkRetries = ZAPIER_MAX_NETWORK_RETRIES,
6981
7143
  maxNetworkRetryDelayMs = ZAPIER_MAX_NETWORK_RETRY_DELAY_MS,
7144
+ maxConcurrentRequests = ZAPIER_MAX_CONCURRENT_REQUESTS,
6982
7145
  approvalTimeoutMs,
6983
7146
  maxApprovalRetries,
6984
7147
  approvalMode,
@@ -6993,6 +7156,7 @@ var apiPlugin = definePlugin(
6993
7156
  onEvent,
6994
7157
  maxNetworkRetries,
6995
7158
  maxNetworkRetryDelayMs,
7159
+ maxConcurrentRequests,
6996
7160
  approvalTimeoutMs,
6997
7161
  maxApprovalRetries,
6998
7162
  approvalMode,
@@ -8878,6 +9042,24 @@ var BaseSdkOptionsSchema = z.object({
8878
9042
  * Default is 60000 (60 seconds).
8879
9043
  */
8880
9044
  maxNetworkRetryDelayMs: z.number().optional().describe("Max delay in ms to wait for retry (default: 60000).").meta({ valueHint: "ms" }),
9045
+ /**
9046
+ * Maximum number of concurrent in-flight HTTP requests per client.
9047
+ * Requests beyond this limit queue in FIFO order until a slot frees.
9048
+ * Pass `Infinity` to disable. Default: 200.
9049
+ *
9050
+ * The description and meta are duplicated across the outer wrapper and
9051
+ * the inner numeric branch because the SDK and CLI doc generators walk
9052
+ * the schema differently — the SDK reader looks at wrappers only, while
9053
+ * the CLI reader recurses into union branches.
9054
+ */
9055
+ maxConcurrentRequests: z.union([
9056
+ z.number().int().min(1).max(MAX_CONCURRENCY_LIMIT).describe(
9057
+ `Max concurrent in-flight HTTP requests (default: 200, max: ${MAX_CONCURRENCY_LIMIT}).`
9058
+ ).meta({ valueHint: "count" }),
9059
+ z.literal(Infinity)
9060
+ ]).optional().describe(
9061
+ `Max concurrent in-flight HTTP requests (default: 200, max: ${MAX_CONCURRENCY_LIMIT}).`
9062
+ ).meta({ valueHint: "count" }),
8881
9063
  approvalTimeoutMs: z.number().optional().describe("Timeout in ms for approval polling. Default: 600000 (10 min).").meta({ valueHint: "ms" }),
8882
9064
  maxApprovalRetries: z.number().optional().describe(
8883
9065
  "Maximum number of sequential approval rounds per request (one per gating policy) before giving up. Default: 2."
@@ -8909,4 +9091,4 @@ var registryPlugin = definePlugin((_sdk) => {
8909
9091
  return {};
8910
9092
  });
8911
9093
 
8912
- export { ActionKeyPropertySchema, ActionPropertySchema, ActionTimeoutMsPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AppPropertySchema, AppsPropertySchema, AuthenticationIdPropertySchema, BaseSdkOptionsSchema, CONTEXT_CACHE_MAX_SIZE, CONTEXT_CACHE_TTL_MS, ClientCredentialsObjectSchema, ConnectionEntrySchema, ConnectionIdPropertySchema, ConnectionPropertySchema, ConnectionsMapSchema, ConnectionsPropertySchema, CredentialsFunctionSchema, CredentialsObjectSchema, CredentialsSchema, DEFAULT_ACTION_TIMEOUT_MS, DEFAULT_APPROVAL_TIMEOUT_MS, DEFAULT_CONFIG_PATH, DEFAULT_MAX_APPROVAL_RETRIES, DEFAULT_PAGE_SIZE, DebugPropertySchema, FieldsPropertySchema, InputFieldPropertySchema, InputsPropertySchema, LeaseLimitPropertySchema, LeasePropertySchema, LeaseSecondsPropertySchema, LimitPropertySchema, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, PkceCredentialsObjectSchema, RecordPropertySchema, RecordsPropertySchema, RelayFetchSchema, RelayRequestSchema, ResolvedCredentialsSchema, TablePropertySchema, TablesPropertySchema, TriggerInboxNamePropertySchema, TriggerInboxPropertySchema, ZAPIER_BASE_URL, ZAPIER_MAX_NETWORK_RETRIES, ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, ZapierAbortDrainSignal, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierApprovalError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierConflictError, ZapierError, ZapierNotFoundError, ZapierRateLimitError, ZapierRelayError, ZapierReleaseTriggerMessageSignal, ZapierResourceNotFoundError, ZapierSignal, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, connectionIdGenericResolver as authenticationIdGenericResolver, connectionIdResolver as authenticationIdResolver, batch, buildApplicationLifecycleEvent, buildCapabilityMessage, buildErrorEvent, buildErrorEventWithContext, buildMethodCalledEvent, clearTokenCache, clientCredentialsNameResolver, clientIdResolver, composePlugins, connectionIdGenericResolver, connectionIdResolver, connectionsPlugin, createBaseEvent, createClientCredentialsPlugin, createFunction, createMemoryCache, createOptionsPlugin, createPaginatedPluginMethod, createPluginMethod, createSdk, createTableFieldsPlugin, createTablePlugin, createTableRecordsPlugin, createZapierApi, createZapierSdk, createZapierSdkWithoutRegistry, definePlugin, deleteClientCredentialsPlugin, deleteTableFieldsPlugin, deleteTablePlugin, deleteTableRecordsPlugin, fetchPlugin, findFirstConnectionPlugin, findManifestEntry, findUniqueConnectionPlugin, formatErrorMessage, generateEventId, getActionInputFieldsSchemaPlugin, getActionPlugin, getAppPlugin, getBaseUrlFromCredentials, getCiPlatform, getClientIdFromCredentials, getConnectionPlugin, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOrCreateApiClient, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTablePlugin, getTableRecordPlugin, getTokenFromCliLogin, getZapierApprovalMode, getZapierSdkService, injectCliLogin, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, invalidateCachedToken, invalidateCredentialsToken, isCi, isCliLoginAvailable, isClientCredentials, isCredentialsFunction, isCredentialsObject, isPkceCredentials, isPositional, listActionInputFieldChoicesPlugin, listActionInputFieldsPlugin, listActionsPlugin, listAppsPlugin, listClientCredentialsPlugin, listConnectionsPlugin, listTableFieldsPlugin, listTableRecordsPlugin, listTablesPlugin, logDeprecation, manifestPlugin, readManifestFromFile, registryPlugin, requestPlugin, resetDeprecationWarnings, resolveAuthToken, resolveCredentials, resolveCredentialsFromEnv, runActionPlugin, runWithTelemetryContext, tableFieldIdsResolver, tableFieldsResolver, tableFiltersResolver, tableIdResolver, tableNameResolver, tableRecordIdResolver, tableRecordIdsResolver, tableRecordsResolver, tableSortResolver, tableUpdateRecordsResolver, toSnakeCase, toTitleCase, triggerInboxResolver, updateTableRecordsPlugin };
9094
+ export { ActionKeyPropertySchema, ActionPropertySchema, ActionTimeoutMsPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AppPropertySchema, AppsPropertySchema, AuthenticationIdPropertySchema, BaseSdkOptionsSchema, CONTEXT_CACHE_MAX_SIZE, CONTEXT_CACHE_TTL_MS, ClientCredentialsObjectSchema, ConnectionEntrySchema, ConnectionIdPropertySchema, ConnectionPropertySchema, ConnectionsMapSchema, ConnectionsPropertySchema, CredentialsFunctionSchema, CredentialsObjectSchema, CredentialsSchema, DEFAULT_ACTION_TIMEOUT_MS, DEFAULT_APPROVAL_TIMEOUT_MS, DEFAULT_CONFIG_PATH, DEFAULT_MAX_APPROVAL_RETRIES, DEFAULT_PAGE_SIZE, DebugPropertySchema, FieldsPropertySchema, InputFieldPropertySchema, InputsPropertySchema, LeaseLimitPropertySchema, LeasePropertySchema, LeaseSecondsPropertySchema, LimitPropertySchema, MAX_CONCURRENCY_LIMIT, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, PkceCredentialsObjectSchema, RecordPropertySchema, RecordsPropertySchema, RelayFetchSchema, RelayRequestSchema, ResolvedCredentialsSchema, TablePropertySchema, TablesPropertySchema, TriggerInboxNamePropertySchema, TriggerInboxPropertySchema, ZAPIER_BASE_URL, ZAPIER_MAX_CONCURRENT_REQUESTS, ZAPIER_MAX_NETWORK_RETRIES, ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, ZapierAbortDrainSignal, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierApprovalError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierConflictError, ZapierError, ZapierNotFoundError, ZapierRateLimitError, ZapierRelayError, ZapierReleaseTriggerMessageSignal, ZapierResourceNotFoundError, ZapierSignal, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, connectionIdGenericResolver as authenticationIdGenericResolver, connectionIdResolver as authenticationIdResolver, batch, buildApplicationLifecycleEvent, buildCapabilityMessage, buildErrorEvent, buildErrorEventWithContext, buildMethodCalledEvent, clearTokenCache, clientCredentialsNameResolver, clientIdResolver, composePlugins, connectionIdGenericResolver, connectionIdResolver, connectionsPlugin, createBaseEvent, createClientCredentialsPlugin, createFunction, createMemoryCache, createOptionsPlugin, createPaginatedPluginMethod, createPluginMethod, createSdk, createTableFieldsPlugin, createTablePlugin, createTableRecordsPlugin, createZapierApi, createZapierSdk, createZapierSdkWithoutRegistry, definePlugin, deleteClientCredentialsPlugin, deleteTableFieldsPlugin, deleteTablePlugin, deleteTableRecordsPlugin, fetchPlugin, findFirstConnectionPlugin, findManifestEntry, findUniqueConnectionPlugin, formatErrorMessage, generateEventId, getActionInputFieldsSchemaPlugin, getActionPlugin, getAppPlugin, getBaseUrlFromCredentials, getCiPlatform, getClientIdFromCredentials, getConnectionPlugin, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOrCreateApiClient, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTablePlugin, getTableRecordPlugin, getTokenFromCliLogin, getZapierApprovalMode, getZapierSdkService, injectCliLogin, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, invalidateCachedToken, invalidateCredentialsToken, isCi, isCliLoginAvailable, isClientCredentials, isCredentialsFunction, isCredentialsObject, isPkceCredentials, isPositional, listActionInputFieldChoicesPlugin, listActionInputFieldsPlugin, listActionsPlugin, listAppsPlugin, listClientCredentialsPlugin, listConnectionsPlugin, listTableFieldsPlugin, listTableRecordsPlugin, listTablesPlugin, logDeprecation, manifestPlugin, parseConcurrencyEnvVar, readManifestFromFile, registryPlugin, requestPlugin, resetDeprecationWarnings, resolveAuthToken, resolveCredentials, resolveCredentialsFromEnv, runActionPlugin, runWithTelemetryContext, tableFieldIdsResolver, tableFieldsResolver, tableFiltersResolver, tableIdResolver, tableNameResolver, tableRecordIdResolver, tableRecordIdsResolver, tableRecordsResolver, tableSortResolver, tableUpdateRecordsResolver, toSnakeCase, toTitleCase, triggerInboxResolver, updateTableRecordsPlugin };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/api/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAStD,MAAM,WAAW,gBAAiB,SAAQ,cAAc;CAAG;AAE3D,eAAO,MAAM,SAAS;aACH;QAAE,OAAO,EAAE,cAAc,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;CA6C7C,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/api/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAUtD,MAAM,WAAW,gBAAiB,SAAQ,cAAc;CAAG;AAE3D,eAAO,MAAM,SAAS;aACH;QAAE,OAAO,EAAE,cAAc,CAAA;KAAE;;;;;;;;;;;;;;;;;;;;;CA+C7C,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,SAAS,CAAC,CAAC"}
@@ -1,10 +1,10 @@
1
1
  import { createZapierApi } from "../../api";
2
2
  import { definePlugin } from "../../utils/plugin-utils";
3
3
  import { resolveCredentials } from "../../credentials";
4
- import { ZAPIER_BASE_URL, ZAPIER_MAX_NETWORK_RETRIES, ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, } from "../../constants";
4
+ import { ZAPIER_BASE_URL, ZAPIER_MAX_CONCURRENT_REQUESTS, ZAPIER_MAX_NETWORK_RETRIES, ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, } from "../../constants";
5
5
  export const apiPlugin = definePlugin((sdk) => {
6
6
  // Extract all options - everything passed to the plugin
7
- const { fetch: customFetch = globalThis.fetch, baseUrl = ZAPIER_BASE_URL, credentials, token, onEvent, debug = false, maxNetworkRetries = ZAPIER_MAX_NETWORK_RETRIES, maxNetworkRetryDelayMs = ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, approvalTimeoutMs, maxApprovalRetries, approvalMode, callerPackage, } = sdk.context.options;
7
+ const { fetch: customFetch = globalThis.fetch, baseUrl = ZAPIER_BASE_URL, credentials, token, onEvent, debug = false, maxNetworkRetries = ZAPIER_MAX_NETWORK_RETRIES, maxNetworkRetryDelayMs = ZAPIER_MAX_NETWORK_RETRY_DELAY_MS, maxConcurrentRequests = ZAPIER_MAX_CONCURRENT_REQUESTS, approvalTimeoutMs, maxApprovalRetries, approvalMode, callerPackage, } = sdk.context.options;
8
8
  // Create the API client - it will handle token resolution internally
9
9
  const api = createZapierApi({
10
10
  baseUrl,
@@ -15,6 +15,7 @@ export const apiPlugin = definePlugin((sdk) => {
15
15
  onEvent,
16
16
  maxNetworkRetries,
17
17
  maxNetworkRetryDelayMs,
18
+ maxConcurrentRequests,
18
19
  approvalTimeoutMs,
19
20
  maxApprovalRetries,
20
21
  approvalMode,
@@ -58,6 +58,7 @@ export declare const BaseSdkOptionsSchema: z.ZodObject<{
58
58
  trackingBaseUrl: z.ZodOptional<z.ZodString>;
59
59
  maxNetworkRetries: z.ZodOptional<z.ZodNumber>;
60
60
  maxNetworkRetryDelayMs: z.ZodOptional<z.ZodNumber>;
61
+ maxConcurrentRequests: z.ZodOptional<z.ZodUnion<readonly [z.ZodNumber, z.ZodLiteral<number>]>>;
61
62
  approvalTimeoutMs: z.ZodOptional<z.ZodNumber>;
62
63
  maxApprovalRetries: z.ZodOptional<z.ZodNumber>;
63
64
  approvalMode: z.ZodOptional<z.ZodEnum<{
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/types/sdk.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAuEb,MAAM;iBAAW,MAAM;;cAAvB,MAAM;iBAAW,MAAM;;;;;;;iBAiBzC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAGlE,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,0CAA0C,CAAC;AACjG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AACjF,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AAC7F,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAC/F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE1E,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAG7E,MAAM,WAAW,kBACf,SAAQ,gCAAgC,EACtC,wBAAwB,EACxB,8BAA8B,EAC9B,+BAA+B,EAC/B,uBAAuB;CAAG"}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/types/sdk.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAG5C,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAmGb,MAAM;iBAAW,MAAM;;cAAvB,MAAM;iBAAW,MAAM;;;;;;;iBAiBzC,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAGlE,OAAO,KAAK,EAAE,gCAAgC,EAAE,MAAM,0CAA0C,CAAC;AACjG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AACjF,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,wCAAwC,CAAC;AAC7F,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAC/F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE1E,YAAY,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAG7E,MAAM,WAAW,kBACf,SAAQ,gCAAgC,EACtC,wBAAwB,EACxB,8BAA8B,EAC9B,+BAA+B,EAC/B,uBAAuB;CAAG"}