@zapier/zapier-sdk 0.13.8 → 0.13.9

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @zapier/zapier-sdk
2
2
 
3
+ ## 0.13.9
4
+
5
+ ### Patch Changes
6
+
7
+ - 492e2f9: - Add new `batch` utility method to handle concurency limits, retries, timeouts and exponential backoffs.
8
+ - Refactor `generateAppTypes` in CLI to use the new `batch` utility
9
+
3
10
  ## 0.13.8
4
11
 
5
12
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/api/polling.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+BH;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,OAAO,GAAG,OAAO;IAC5C,8CAA8C;IAC9C,SAAS,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC;IACjD,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,mBAAW,UAAU;IACnB,OAAO,YAAY;IACnB,QAAQ,aAAa;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,OAAO,GAAG,OAAO,IAAI;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAuEF;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAG,OAAO,EACvD,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC,CAyGlB"}
1
+ {"version":3,"file":"polling.d.ts","sourceRoot":"","sources":["../../src/api/polling.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgCH;;GAEG;AACH,MAAM,WAAW,WAAW,CAAC,OAAO,GAAG,OAAO;IAC5C,8CAA8C;IAC9C,SAAS,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iEAAiE;IACjE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uDAAuD;IACvD,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,OAAO,CAAC;IACjD,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,mBAAW,UAAU;IACnB,OAAO,YAAY;IACnB,QAAQ,aAAa;CACtB;AAED;;GAEG;AACH,MAAM,MAAM,UAAU,CAAC,OAAO,GAAG,OAAO,IAAI;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAwDF;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAG,OAAO,EACvD,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,GAC5B,OAAO,CAAC,OAAO,CAAC,CAyGlB"}
@@ -6,16 +6,14 @@
6
6
  */
7
7
  import { ZapierTimeoutError, ZapierApiError, ZapierValidationError, } from "../types/errors";
8
8
  import { setTimeout } from "timers/promises";
9
+ import { calculateWaitTime, MAX_CONSECUTIVE_ERRORS, } from "../utils/retry-utils";
9
10
  // Constants
10
11
  const DEFAULT_TIMEOUT_MS = 180000;
11
12
  const DEFAULT_SUCCESS_STATUS = 200;
12
13
  const DEFAULT_PENDING_STATUS = 202;
13
14
  const DEFAULT_INITIAL_DELAY_MS = 50;
14
15
  const DEFAULT_MAX_POLLING_INTERVAL_MS = 10000;
15
- const MAX_CONSECUTIVE_ERRORS = 3;
16
16
  const MAX_TIMEOUT_BUFFER_MS = 10000;
17
- const BASE_ERROR_BACKOFF_MS = 1000;
18
- const JITTER_FACTOR = 0.5;
19
17
  // Polling stages: [threshold_ms, interval_ms]
20
18
  // Note: These are default stages, actual hard timeout is enforced separately below
21
19
  const DEFAULT_POLLING_STAGES = [
@@ -26,14 +24,6 @@ const DEFAULT_POLLING_STAGES = [
26
24
  [30000, 2500], // Up to 30s: poll every 2.5s
27
25
  [60000, 5000], // Up to 60s: poll every 5s
28
26
  ];
29
- // Helper to calculate wait time with jitter and error backoff
30
- const calculateWaitTime = (baseInterval, errorCount) => {
31
- // Jitter to avoid thundering herd
32
- const jitter = Math.random() * JITTER_FACTOR * baseInterval;
33
- // More backoff added if errors are seen
34
- const errorBackoff = Math.min(BASE_ERROR_BACKOFF_MS * (errorCount / 2), baseInterval * 2);
35
- return Math.floor(baseInterval + jitter + errorBackoff);
36
- };
37
27
  const processResponse = async (response, successStatus, pendingStatus, resultExtractor, errorCount) => {
38
28
  // Handle other error responses
39
29
  if (!response.ok) {
package/dist/index.cjs CHANGED
@@ -3101,15 +3101,28 @@ function createDebugFetch(options) {
3101
3101
  }
3102
3102
  };
3103
3103
  }
3104
+
3105
+ // src/utils/retry-utils.ts
3106
+ var MAX_CONSECUTIVE_ERRORS = 3;
3107
+ var BASE_ERROR_BACKOFF_MS = 1e3;
3108
+ var JITTER_FACTOR = 0.5;
3109
+ function calculateWaitTime(baseInterval, errorCount) {
3110
+ const jitter = Math.random() * JITTER_FACTOR * baseInterval;
3111
+ const errorBackoff = Math.min(
3112
+ BASE_ERROR_BACKOFF_MS * (errorCount / 2),
3113
+ baseInterval * 2
3114
+ // Cap error backoff at 2x the base interval
3115
+ );
3116
+ return Math.floor(baseInterval + jitter + errorBackoff);
3117
+ }
3118
+
3119
+ // src/api/polling.ts
3104
3120
  var DEFAULT_TIMEOUT_MS = 18e4;
3105
3121
  var DEFAULT_SUCCESS_STATUS = 200;
3106
3122
  var DEFAULT_PENDING_STATUS = 202;
3107
3123
  var DEFAULT_INITIAL_DELAY_MS = 50;
3108
3124
  var DEFAULT_MAX_POLLING_INTERVAL_MS = 1e4;
3109
- var MAX_CONSECUTIVE_ERRORS = 3;
3110
3125
  var MAX_TIMEOUT_BUFFER_MS = 1e4;
3111
- var BASE_ERROR_BACKOFF_MS = 1e3;
3112
- var JITTER_FACTOR = 0.5;
3113
3126
  var DEFAULT_POLLING_STAGES = [
3114
3127
  [125, 125],
3115
3128
  // Up to 125ms: poll every 125ms
@@ -3124,15 +3137,6 @@ var DEFAULT_POLLING_STAGES = [
3124
3137
  [6e4, 5e3]
3125
3138
  // Up to 60s: poll every 5s
3126
3139
  ];
3127
- var calculateWaitTime = (baseInterval, errorCount) => {
3128
- const jitter = Math.random() * JITTER_FACTOR * baseInterval;
3129
- const errorBackoff = Math.min(
3130
- BASE_ERROR_BACKOFF_MS * (errorCount / 2),
3131
- baseInterval * 2
3132
- // Cap error backoff at 2x the base interval
3133
- );
3134
- return Math.floor(baseInterval + jitter + errorBackoff);
3135
- };
3136
3140
  var processResponse = async (response, successStatus, pendingStatus, resultExtractor, errorCount) => {
3137
3141
  if (!response.ok) {
3138
3142
  return {
@@ -3613,6 +3617,94 @@ var apiPlugin = (params) => {
3613
3617
  }
3614
3618
  };
3615
3619
  };
3620
+ var DEFAULT_CONCURRENCY = 10;
3621
+ var BATCH_START_DELAY_MS = 25;
3622
+ var DEFAULT_BATCH_TIMEOUT_MS = 18e4;
3623
+ async function batch(tasks, options = {}) {
3624
+ const {
3625
+ concurrency = DEFAULT_CONCURRENCY,
3626
+ retry = true,
3627
+ batchDelay = BATCH_START_DELAY_MS,
3628
+ timeoutMs = DEFAULT_BATCH_TIMEOUT_MS,
3629
+ taskTimeoutMs
3630
+ } = options;
3631
+ if (concurrency <= 0) {
3632
+ throw new Error("Concurrency must be greater than 0");
3633
+ }
3634
+ if (timeoutMs <= 0) {
3635
+ throw new Error("Timeout must be greater than 0");
3636
+ }
3637
+ if (taskTimeoutMs !== void 0 && taskTimeoutMs <= 0) {
3638
+ throw new Error("Task timeout must be greater than 0");
3639
+ }
3640
+ if (tasks.length === 0) {
3641
+ return [];
3642
+ }
3643
+ const startTime = Date.now();
3644
+ const results = new Array(tasks.length);
3645
+ const taskQueue = tasks.map((task, index) => ({
3646
+ index,
3647
+ task,
3648
+ errorCount: 0
3649
+ }));
3650
+ async function executeTask(taskState) {
3651
+ const { index, task, errorCount } = taskState;
3652
+ try {
3653
+ let result;
3654
+ if (taskTimeoutMs !== void 0) {
3655
+ const timeoutPromise = promises.setTimeout(taskTimeoutMs).then(() => {
3656
+ throw new ZapierTimeoutError(
3657
+ `Task timed out after ${taskTimeoutMs}ms`
3658
+ );
3659
+ });
3660
+ result = await Promise.race([task(), timeoutPromise]);
3661
+ } else {
3662
+ result = await task();
3663
+ }
3664
+ results[index] = { status: "fulfilled", value: result };
3665
+ } catch (error) {
3666
+ const newErrorCount = errorCount + 1;
3667
+ const isTimeout = error instanceof ZapierTimeoutError;
3668
+ if (retry && !isTimeout && newErrorCount < MAX_CONSECUTIVE_ERRORS) {
3669
+ const waitTime = calculateWaitTime(1e3, newErrorCount);
3670
+ await promises.setTimeout(waitTime);
3671
+ taskQueue.push({
3672
+ index,
3673
+ task,
3674
+ errorCount: newErrorCount
3675
+ });
3676
+ } else {
3677
+ results[index] = { status: "rejected", reason: error };
3678
+ }
3679
+ }
3680
+ }
3681
+ async function worker() {
3682
+ while (taskQueue.length > 0) {
3683
+ const elapsedTime = Date.now() - startTime;
3684
+ if (elapsedTime >= timeoutMs) {
3685
+ throw new ZapierTimeoutError(
3686
+ `Batch operation timed out after ${Math.floor(elapsedTime / 1e3)}s. ${taskQueue.length} task(s) not completed.`
3687
+ );
3688
+ }
3689
+ const taskState = taskQueue.shift();
3690
+ if (!taskState) break;
3691
+ await executeTask(taskState);
3692
+ if (taskQueue.length > 0 && batchDelay > 0) {
3693
+ await promises.setTimeout(batchDelay);
3694
+ }
3695
+ }
3696
+ }
3697
+ const workerCount = Math.min(concurrency, tasks.length);
3698
+ const workers = [];
3699
+ for (let i = 0; i < workerCount; i++) {
3700
+ workers.push(worker());
3701
+ if (i < workerCount - 1 && batchDelay > 0) {
3702
+ await promises.setTimeout(batchDelay / 10);
3703
+ }
3704
+ }
3705
+ await Promise.all(workers);
3706
+ return results;
3707
+ }
3616
3708
 
3617
3709
  // src/plugins/registry/index.ts
3618
3710
  var registryPlugin = ({ sdk, context }) => {
@@ -3997,7 +4089,7 @@ function getCpuTime() {
3997
4089
 
3998
4090
  // package.json
3999
4091
  var package_default = {
4000
- version: "0.13.8"};
4092
+ version: "0.13.9"};
4001
4093
 
4002
4094
  // src/plugins/eventEmission/builders.ts
4003
4095
  function createBaseEvent(context = {}) {
@@ -4399,6 +4491,7 @@ exports.appKeyResolver = appKeyResolver;
4399
4491
  exports.appsPlugin = appsPlugin;
4400
4492
  exports.authenticationIdGenericResolver = authenticationIdGenericResolver;
4401
4493
  exports.authenticationIdResolver = authenticationIdResolver;
4494
+ exports.batch = batch;
4402
4495
  exports.buildApplicationLifecycleEvent = buildApplicationLifecycleEvent;
4403
4496
  exports.buildErrorEvent = buildErrorEvent;
4404
4497
  exports.buildErrorEventWithContext = buildErrorEventWithContext;
package/dist/index.d.mts CHANGED
@@ -3133,6 +3133,78 @@ declare function toTitleCase(input: string): string;
3133
3133
  */
3134
3134
  declare function toSnakeCase(input: string): string;
3135
3135
 
3136
+ /**
3137
+ * Batch Operation Utilities
3138
+ *
3139
+ * This module provides utilities for executing multiple async operations
3140
+ * with concurrency control and retry logic.
3141
+ */
3142
+ /**
3143
+ * Options for batch execution
3144
+ */
3145
+ interface BatchOptions {
3146
+ /**
3147
+ * Maximum number of concurrent operations (default: 10)
3148
+ * Lower values are more "polite" but slower
3149
+ * Higher values are faster but risk rate limits
3150
+ */
3151
+ concurrency?: number;
3152
+ /**
3153
+ * Whether to retry failed operations (default: true)
3154
+ * When enabled, each operation gets up to MAX_CONSECUTIVE_ERRORS retries
3155
+ */
3156
+ retry?: boolean;
3157
+ /**
3158
+ * Delay in milliseconds between starting batches (default: 100ms)
3159
+ * Adds a small delay between concurrent batches to avoid burst patterns
3160
+ */
3161
+ batchDelay?: number;
3162
+ /**
3163
+ * Overall timeout for the entire batch operation in milliseconds (default: 180000ms / 3 minutes)
3164
+ * When exceeded, throws ZapierTimeoutError and stops processing remaining tasks
3165
+ */
3166
+ timeoutMs?: number;
3167
+ /**
3168
+ * Timeout for individual tasks in milliseconds (default: none)
3169
+ * When set, each task will be cancelled if it exceeds this duration
3170
+ * Tasks that timeout will be marked as rejected in the results
3171
+ */
3172
+ taskTimeoutMs?: number;
3173
+ }
3174
+ /**
3175
+ * Execute multiple async operations with concurrency limiting and retry logic
3176
+ *
3177
+ * This prevents overwhelming APIs by:
3178
+ * 1. Limiting concurrent operations (worker pool pattern)
3179
+ * 2. Adding small delays between batches to avoid burst detection
3180
+ * 3. Retrying failed operations with exponential backoff
3181
+ *
3182
+ * Problem Solved:
3183
+ * - Rate limit prevention: Steady stream instead of burst requests
3184
+ * - Connection pool management: Stays within browser/Node limits (~6-8 per domain)
3185
+ * - Resilience: Transient failures are retried automatically
3186
+ * - Observability: Returns detailed success/failure info for each operation
3187
+ *
3188
+ * Example Usage:
3189
+ * ```typescript
3190
+ * // Instead of Promise.allSettled (fires all at once):
3191
+ * const results = await Promise.allSettled(
3192
+ * actions.map(a => sdk.listInputFields(a))
3193
+ * );
3194
+ *
3195
+ * // Use batch (controlled concurrency):
3196
+ * const results = await batch(
3197
+ * actions.map(a => () => sdk.listInputFields(a)),
3198
+ * { concurrency: 10, retry: true }
3199
+ * );
3200
+ * ```
3201
+ *
3202
+ * @param tasks - Array of functions that return promises (NOT promises themselves!)
3203
+ * @param options - Configuration for concurrency and retry behavior
3204
+ * @returns Promise resolving to array of settled results (same as Promise.allSettled)
3205
+ */
3206
+ declare function batch<T>(tasks: (() => Promise<T>)[], options?: BatchOptions): Promise<PromiseSettledResult<T>[]>;
3207
+
3136
3208
  declare const appKeyResolver: StaticResolver;
3137
3209
 
3138
3210
  interface ActionTypeItem {
@@ -3346,4 +3418,4 @@ declare function createZapierSdkWithoutRegistry(options?: ZapierSdkOptions): Sdk
3346
3418
  }>;
3347
3419
  declare function createZapierSdk(options?: ZapierSdkOptions): ZapierSdk;
3348
3420
 
3349
- export { type Action, type ActionExecutionOptions, type ActionExecutionResult, type ActionField, type ActionFieldChoice, type ActionItem$1 as ActionItem, type ActionKeyProperty, ActionKeyPropertySchema, type ActionTypeProperty, ActionTypePropertySchema, type ApiError, type ApiEvent, type ApiPluginOptions, type ApiPluginProvides, type App, type AppItem, type AppKeyProperty, AppKeyPropertySchema, type ApplicationLifecycleEventData, type AppsPluginProvides, type AuthEvent, type AuthOptions, type Authentication, type AuthenticationIdProperty, AuthenticationIdPropertySchema, type AuthenticationItem, type AuthenticationsResponse, type BaseEvent, type Choice, DEFAULT_CONFIG_PATH, type DebugProperty, DebugPropertySchema, type EnhancedErrorEventData, type ErrorOptions, type EventCallback, type EventContext, type EventEmissionContext, type FetchPluginProvides, type Field, type FieldsetItem, type FindFirstAuthenticationPluginProvides, type FindUniqueAuthenticationPluginProvides, type FormatMetadata, type FormattedItem, type FunctionOptions, type FunctionRegistryEntry, type GetActionPluginProvides, type GetAppPluginProvides, type GetAuthenticationPluginProvides, type GetContextType, type GetProfilePluginProvides, type GetSdkType, type InfoFieldItem, type InputFieldItem, type InputsProperty, InputsPropertySchema, type LimitProperty, LimitPropertySchema, type ListActionsPluginProvides, type ListAppsPluginProvides, type ListAuthenticationsPluginProvides, type ListInputFieldsPluginProvides, type LoadingEvent, MAX_PAGE_LIMIT, type Manifest, type ManifestEntry, type ManifestPluginOptions, type ManifestPluginProvides, type Need, type NeedsRequest, type NeedsResponse, type OffsetProperty, OffsetPropertySchema, type OutputProperty, OutputPropertySchema, type PaginatedSdkFunction, type ParamsProperty, ParamsPropertySchema, type Plugin, type PluginDependencies, type PluginOptions, type PluginProvides, type PositionalMetadata, RelayFetchSchema, RelayRequestSchema, type RequestPluginProvides, type RootFieldItem, type RunActionPluginProvides, type Sdk, type SdkEvent, type UpdateManifestEntryOptions, type UserProfile, type UserProfileItem, ZAPIER_BASE_URL, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, type ZapierFetchInitOptions, ZapierNotFoundError, ZapierResourceNotFoundError, type ZapierSdk, type ZapierSdkApps, type ZapierSdkOptions, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, authenticationIdGenericResolver, authenticationIdResolver, buildApplicationLifecycleEvent, buildErrorEvent, buildErrorEventWithContext, createBaseEvent, createFunction, createSdk, createZapierSdk, createZapierSdkWithoutRegistry, fetchPlugin, findFirstAuthenticationPlugin, findManifestEntry, findUniqueAuthenticationPlugin, formatErrorMessage, generateEventId, getActionPlugin, getAppPlugin, getAuthenticationPlugin, getCiPlatform, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTokenFromCliLogin, getTokenFromEnv, getTokenFromEnvOrConfig, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, isCi, isPositional, listActionsPlugin, listAppsPlugin, listAuthenticationsPlugin, listInputFieldsPlugin, manifestPlugin, readManifestFromFile, registryPlugin, requestPlugin, runActionPlugin, toSnakeCase, toTitleCase };
3421
+ export { type Action, type ActionExecutionOptions, type ActionExecutionResult, type ActionField, type ActionFieldChoice, type ActionItem$1 as ActionItem, type ActionKeyProperty, ActionKeyPropertySchema, type ActionTypeProperty, ActionTypePropertySchema, type ApiError, type ApiEvent, type ApiPluginOptions, type ApiPluginProvides, type App, type AppItem, type AppKeyProperty, AppKeyPropertySchema, type ApplicationLifecycleEventData, type AppsPluginProvides, type AuthEvent, type AuthOptions, type Authentication, type AuthenticationIdProperty, AuthenticationIdPropertySchema, type AuthenticationItem, type AuthenticationsResponse, type BaseEvent, type BatchOptions, type Choice, DEFAULT_CONFIG_PATH, type DebugProperty, DebugPropertySchema, type EnhancedErrorEventData, type ErrorOptions, type EventCallback, type EventContext, type EventEmissionContext, type FetchPluginProvides, type Field, type FieldsetItem, type FindFirstAuthenticationPluginProvides, type FindUniqueAuthenticationPluginProvides, type FormatMetadata, type FormattedItem, type FunctionOptions, type FunctionRegistryEntry, type GetActionPluginProvides, type GetAppPluginProvides, type GetAuthenticationPluginProvides, type GetContextType, type GetProfilePluginProvides, type GetSdkType, type InfoFieldItem, type InputFieldItem, type InputsProperty, InputsPropertySchema, type LimitProperty, LimitPropertySchema, type ListActionsPluginProvides, type ListAppsPluginProvides, type ListAuthenticationsPluginProvides, type ListInputFieldsPluginProvides, type LoadingEvent, MAX_PAGE_LIMIT, type Manifest, type ManifestEntry, type ManifestPluginOptions, type ManifestPluginProvides, type Need, type NeedsRequest, type NeedsResponse, type OffsetProperty, OffsetPropertySchema, type OutputProperty, OutputPropertySchema, type PaginatedSdkFunction, type ParamsProperty, ParamsPropertySchema, type Plugin, type PluginDependencies, type PluginOptions, type PluginProvides, type PositionalMetadata, RelayFetchSchema, RelayRequestSchema, type RequestPluginProvides, type RootFieldItem, type RunActionPluginProvides, type Sdk, type SdkEvent, type UpdateManifestEntryOptions, type UserProfile, type UserProfileItem, ZAPIER_BASE_URL, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, type ZapierFetchInitOptions, ZapierNotFoundError, ZapierResourceNotFoundError, type ZapierSdk, type ZapierSdkApps, type ZapierSdkOptions, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, authenticationIdGenericResolver, authenticationIdResolver, batch, buildApplicationLifecycleEvent, buildErrorEvent, buildErrorEventWithContext, createBaseEvent, createFunction, createSdk, createZapierSdk, createZapierSdkWithoutRegistry, fetchPlugin, findFirstAuthenticationPlugin, findManifestEntry, findUniqueAuthenticationPlugin, formatErrorMessage, generateEventId, getActionPlugin, getAppPlugin, getAuthenticationPlugin, getCiPlatform, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTokenFromCliLogin, getTokenFromEnv, getTokenFromEnvOrConfig, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, isCi, isPositional, listActionsPlugin, listAppsPlugin, listAuthenticationsPlugin, listInputFieldsPlugin, manifestPlugin, readManifestFromFile, registryPlugin, requestPlugin, runActionPlugin, toSnakeCase, toTitleCase };
package/dist/index.d.ts CHANGED
@@ -23,6 +23,8 @@ export { isPositional, PositionalMetadata } from "./utils/schema-utils";
23
23
  export { createFunction } from "./utils/function-utils";
24
24
  export type { FormattedItem, FormatMetadata } from "./utils/schema-utils";
25
25
  export { toSnakeCase, toTitleCase } from "./utils/string-utils";
26
+ export { batch } from "./utils/batch-utils";
27
+ export type { BatchOptions } from "./utils/batch-utils";
26
28
  export * from "./resolvers";
27
29
  export * from "./auth";
28
30
  export * from "./constants";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAG9B,YAAY,EACV,MAAM,EACN,GAAG,EACH,IAAI,EACJ,KAAK,EACL,MAAM,EACN,qBAAqB,EACrB,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,uBAAuB,EACvB,WAAW,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG1E,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGhE,cAAc,aAAa,CAAC;AAG5B,cAAc,QAAQ,CAAC;AAGvB,cAAc,aAAa,CAAC;AAI5B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,eAAe,EACf,8BAA8B,EAC9B,SAAS,EACT,gBAAgB,GACjB,MAAM,OAAO,CAAC;AAGf,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGzD,YAAY,EACV,MAAM,EACN,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,cAAc,EACd,GAAG,GACJ,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACT,mBAAmB,EACnB,IAAI,EACJ,aAAa,EACb,cAAc,EACd,UAAU,EACV,8BAA8B,EAC9B,0BAA0B,EAC1B,eAAe,EACf,eAAe,GAChB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,eAAe,CAAC;AAG9B,YAAY,EACV,MAAM,EACN,GAAG,EACH,IAAI,EACJ,KAAK,EACL,MAAM,EACN,qBAAqB,EACrB,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,cAAc,EACd,uBAAuB,EACvB,WAAW,GACZ,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG1E,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGhE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGxD,cAAc,aAAa,CAAC;AAG5B,cAAc,QAAQ,CAAC;AAGvB,cAAc,aAAa,CAAC;AAI5B,OAAO,EACL,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EACL,eAAe,EACf,8BAA8B,EAC9B,SAAS,EACT,gBAAgB,GACjB,MAAM,OAAO,CAAC;AAGf,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAGzD,YAAY,EACV,MAAM,EACN,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,cAAc,EACd,GAAG,GACJ,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,YAAY,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,YAAY,EACV,oBAAoB,EACpB,YAAY,EACZ,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,YAAY,EACZ,SAAS,EACT,mBAAmB,EACnB,IAAI,EACJ,aAAa,EACb,cAAc,EACd,UAAU,EACV,8BAA8B,EAC9B,0BAA0B,EAC1B,eAAe,EACf,eAAe,GAChB,MAAM,yBAAyB,CAAC"}
package/dist/index.js CHANGED
@@ -24,6 +24,8 @@ export { isPositional } from "./utils/schema-utils";
24
24
  export { createFunction } from "./utils/function-utils";
25
25
  // Export string utilities
26
26
  export { toSnakeCase, toTitleCase } from "./utils/string-utils";
27
+ // Export batch utilities
28
+ export { batch } from "./utils/batch-utils";
27
29
  // Export resolver utilities for CLI
28
30
  export * from "./resolvers";
29
31
  // Export auth utilities for CLI use
package/dist/index.mjs CHANGED
@@ -3079,15 +3079,28 @@ function createDebugFetch(options) {
3079
3079
  }
3080
3080
  };
3081
3081
  }
3082
+
3083
+ // src/utils/retry-utils.ts
3084
+ var MAX_CONSECUTIVE_ERRORS = 3;
3085
+ var BASE_ERROR_BACKOFF_MS = 1e3;
3086
+ var JITTER_FACTOR = 0.5;
3087
+ function calculateWaitTime(baseInterval, errorCount) {
3088
+ const jitter = Math.random() * JITTER_FACTOR * baseInterval;
3089
+ const errorBackoff = Math.min(
3090
+ BASE_ERROR_BACKOFF_MS * (errorCount / 2),
3091
+ baseInterval * 2
3092
+ // Cap error backoff at 2x the base interval
3093
+ );
3094
+ return Math.floor(baseInterval + jitter + errorBackoff);
3095
+ }
3096
+
3097
+ // src/api/polling.ts
3082
3098
  var DEFAULT_TIMEOUT_MS = 18e4;
3083
3099
  var DEFAULT_SUCCESS_STATUS = 200;
3084
3100
  var DEFAULT_PENDING_STATUS = 202;
3085
3101
  var DEFAULT_INITIAL_DELAY_MS = 50;
3086
3102
  var DEFAULT_MAX_POLLING_INTERVAL_MS = 1e4;
3087
- var MAX_CONSECUTIVE_ERRORS = 3;
3088
3103
  var MAX_TIMEOUT_BUFFER_MS = 1e4;
3089
- var BASE_ERROR_BACKOFF_MS = 1e3;
3090
- var JITTER_FACTOR = 0.5;
3091
3104
  var DEFAULT_POLLING_STAGES = [
3092
3105
  [125, 125],
3093
3106
  // Up to 125ms: poll every 125ms
@@ -3102,15 +3115,6 @@ var DEFAULT_POLLING_STAGES = [
3102
3115
  [6e4, 5e3]
3103
3116
  // Up to 60s: poll every 5s
3104
3117
  ];
3105
- var calculateWaitTime = (baseInterval, errorCount) => {
3106
- const jitter = Math.random() * JITTER_FACTOR * baseInterval;
3107
- const errorBackoff = Math.min(
3108
- BASE_ERROR_BACKOFF_MS * (errorCount / 2),
3109
- baseInterval * 2
3110
- // Cap error backoff at 2x the base interval
3111
- );
3112
- return Math.floor(baseInterval + jitter + errorBackoff);
3113
- };
3114
3118
  var processResponse = async (response, successStatus, pendingStatus, resultExtractor, errorCount) => {
3115
3119
  if (!response.ok) {
3116
3120
  return {
@@ -3591,6 +3595,94 @@ var apiPlugin = (params) => {
3591
3595
  }
3592
3596
  };
3593
3597
  };
3598
+ var DEFAULT_CONCURRENCY = 10;
3599
+ var BATCH_START_DELAY_MS = 25;
3600
+ var DEFAULT_BATCH_TIMEOUT_MS = 18e4;
3601
+ async function batch(tasks, options = {}) {
3602
+ const {
3603
+ concurrency = DEFAULT_CONCURRENCY,
3604
+ retry = true,
3605
+ batchDelay = BATCH_START_DELAY_MS,
3606
+ timeoutMs = DEFAULT_BATCH_TIMEOUT_MS,
3607
+ taskTimeoutMs
3608
+ } = options;
3609
+ if (concurrency <= 0) {
3610
+ throw new Error("Concurrency must be greater than 0");
3611
+ }
3612
+ if (timeoutMs <= 0) {
3613
+ throw new Error("Timeout must be greater than 0");
3614
+ }
3615
+ if (taskTimeoutMs !== void 0 && taskTimeoutMs <= 0) {
3616
+ throw new Error("Task timeout must be greater than 0");
3617
+ }
3618
+ if (tasks.length === 0) {
3619
+ return [];
3620
+ }
3621
+ const startTime = Date.now();
3622
+ const results = new Array(tasks.length);
3623
+ const taskQueue = tasks.map((task, index) => ({
3624
+ index,
3625
+ task,
3626
+ errorCount: 0
3627
+ }));
3628
+ async function executeTask(taskState) {
3629
+ const { index, task, errorCount } = taskState;
3630
+ try {
3631
+ let result;
3632
+ if (taskTimeoutMs !== void 0) {
3633
+ const timeoutPromise = setTimeout$1(taskTimeoutMs).then(() => {
3634
+ throw new ZapierTimeoutError(
3635
+ `Task timed out after ${taskTimeoutMs}ms`
3636
+ );
3637
+ });
3638
+ result = await Promise.race([task(), timeoutPromise]);
3639
+ } else {
3640
+ result = await task();
3641
+ }
3642
+ results[index] = { status: "fulfilled", value: result };
3643
+ } catch (error) {
3644
+ const newErrorCount = errorCount + 1;
3645
+ const isTimeout = error instanceof ZapierTimeoutError;
3646
+ if (retry && !isTimeout && newErrorCount < MAX_CONSECUTIVE_ERRORS) {
3647
+ const waitTime = calculateWaitTime(1e3, newErrorCount);
3648
+ await setTimeout$1(waitTime);
3649
+ taskQueue.push({
3650
+ index,
3651
+ task,
3652
+ errorCount: newErrorCount
3653
+ });
3654
+ } else {
3655
+ results[index] = { status: "rejected", reason: error };
3656
+ }
3657
+ }
3658
+ }
3659
+ async function worker() {
3660
+ while (taskQueue.length > 0) {
3661
+ const elapsedTime = Date.now() - startTime;
3662
+ if (elapsedTime >= timeoutMs) {
3663
+ throw new ZapierTimeoutError(
3664
+ `Batch operation timed out after ${Math.floor(elapsedTime / 1e3)}s. ${taskQueue.length} task(s) not completed.`
3665
+ );
3666
+ }
3667
+ const taskState = taskQueue.shift();
3668
+ if (!taskState) break;
3669
+ await executeTask(taskState);
3670
+ if (taskQueue.length > 0 && batchDelay > 0) {
3671
+ await setTimeout$1(batchDelay);
3672
+ }
3673
+ }
3674
+ }
3675
+ const workerCount = Math.min(concurrency, tasks.length);
3676
+ const workers = [];
3677
+ for (let i = 0; i < workerCount; i++) {
3678
+ workers.push(worker());
3679
+ if (i < workerCount - 1 && batchDelay > 0) {
3680
+ await setTimeout$1(batchDelay / 10);
3681
+ }
3682
+ }
3683
+ await Promise.all(workers);
3684
+ return results;
3685
+ }
3594
3686
 
3595
3687
  // src/plugins/registry/index.ts
3596
3688
  var registryPlugin = ({ sdk, context }) => {
@@ -3975,7 +4067,7 @@ function getCpuTime() {
3975
4067
 
3976
4068
  // package.json
3977
4069
  var package_default = {
3978
- version: "0.13.8"};
4070
+ version: "0.13.9"};
3979
4071
 
3980
4072
  // src/plugins/eventEmission/builders.ts
3981
4073
  function createBaseEvent(context = {}) {
@@ -4343,4 +4435,4 @@ function createZapierSdk(options = {}) {
4343
4435
  return createZapierSdkWithoutRegistry(options).addPlugin(registryPlugin);
4344
4436
  }
4345
4437
 
4346
- export { ActionKeyPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AuthenticationIdPropertySchema, DEFAULT_CONFIG_PATH, DebugPropertySchema, InputsPropertySchema, LimitPropertySchema, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, RelayFetchSchema, RelayRequestSchema, ZAPIER_BASE_URL, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, ZapierNotFoundError, ZapierResourceNotFoundError, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, authenticationIdGenericResolver, authenticationIdResolver, buildApplicationLifecycleEvent, buildErrorEvent, buildErrorEventWithContext, createBaseEvent, createFunction, createSdk, createZapierSdk, createZapierSdkWithoutRegistry, fetchPlugin, findFirstAuthenticationPlugin, findManifestEntry, findUniqueAuthenticationPlugin, formatErrorMessage, generateEventId, getActionPlugin, getAppPlugin, getAuthenticationPlugin, getCiPlatform, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTokenFromCliLogin, getTokenFromEnv, getTokenFromEnvOrConfig, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, isCi, isPositional, listActionsPlugin, listAppsPlugin, listAuthenticationsPlugin, listInputFieldsPlugin, manifestPlugin, readManifestFromFile, registryPlugin, requestPlugin, runActionPlugin, toSnakeCase, toTitleCase };
4438
+ export { ActionKeyPropertySchema, ActionTypePropertySchema, AppKeyPropertySchema, AuthenticationIdPropertySchema, DEFAULT_CONFIG_PATH, DebugPropertySchema, InputsPropertySchema, LimitPropertySchema, MAX_PAGE_LIMIT, OffsetPropertySchema, OutputPropertySchema, ParamsPropertySchema, RelayFetchSchema, RelayRequestSchema, ZAPIER_BASE_URL, ZapierActionError, ZapierApiError, ZapierAppNotFoundError, ZapierAuthenticationError, ZapierBundleError, ZapierConfigurationError, ZapierError, ZapierNotFoundError, ZapierResourceNotFoundError, ZapierTimeoutError, ZapierUnknownError, ZapierValidationError, actionKeyResolver, actionTypeResolver, apiPlugin, appKeyResolver, appsPlugin, authenticationIdGenericResolver, authenticationIdResolver, batch, buildApplicationLifecycleEvent, buildErrorEvent, buildErrorEventWithContext, createBaseEvent, createFunction, createSdk, createZapierSdk, createZapierSdkWithoutRegistry, fetchPlugin, findFirstAuthenticationPlugin, findManifestEntry, findUniqueAuthenticationPlugin, formatErrorMessage, generateEventId, getActionPlugin, getAppPlugin, getAuthenticationPlugin, getCiPlatform, getCpuTime, getCurrentTimestamp, getMemoryUsage, getOsInfo, getPlatformVersions, getPreferredManifestEntryKey, getProfilePlugin, getReleaseId, getTokenFromCliLogin, getTokenFromEnv, getTokenFromEnvOrConfig, inputFieldKeyResolver, inputsAllOptionalResolver, inputsResolver, isCi, isPositional, listActionsPlugin, listAppsPlugin, listAuthenticationsPlugin, listInputFieldsPlugin, manifestPlugin, readManifestFromFile, registryPlugin, requestPlugin, runActionPlugin, toSnakeCase, toTitleCase };
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Batch Operation Utilities
3
+ *
4
+ * This module provides utilities for executing multiple async operations
5
+ * with concurrency control and retry logic.
6
+ */
7
+ /**
8
+ * Options for batch execution
9
+ */
10
+ export interface BatchOptions {
11
+ /**
12
+ * Maximum number of concurrent operations (default: 10)
13
+ * Lower values are more "polite" but slower
14
+ * Higher values are faster but risk rate limits
15
+ */
16
+ concurrency?: number;
17
+ /**
18
+ * Whether to retry failed operations (default: true)
19
+ * When enabled, each operation gets up to MAX_CONSECUTIVE_ERRORS retries
20
+ */
21
+ retry?: boolean;
22
+ /**
23
+ * Delay in milliseconds between starting batches (default: 100ms)
24
+ * Adds a small delay between concurrent batches to avoid burst patterns
25
+ */
26
+ batchDelay?: number;
27
+ /**
28
+ * Overall timeout for the entire batch operation in milliseconds (default: 180000ms / 3 minutes)
29
+ * When exceeded, throws ZapierTimeoutError and stops processing remaining tasks
30
+ */
31
+ timeoutMs?: number;
32
+ /**
33
+ * Timeout for individual tasks in milliseconds (default: none)
34
+ * When set, each task will be cancelled if it exceeds this duration
35
+ * Tasks that timeout will be marked as rejected in the results
36
+ */
37
+ taskTimeoutMs?: number;
38
+ }
39
+ /**
40
+ * Execute multiple async operations with concurrency limiting and retry logic
41
+ *
42
+ * This prevents overwhelming APIs by:
43
+ * 1. Limiting concurrent operations (worker pool pattern)
44
+ * 2. Adding small delays between batches to avoid burst detection
45
+ * 3. Retrying failed operations with exponential backoff
46
+ *
47
+ * Problem Solved:
48
+ * - Rate limit prevention: Steady stream instead of burst requests
49
+ * - Connection pool management: Stays within browser/Node limits (~6-8 per domain)
50
+ * - Resilience: Transient failures are retried automatically
51
+ * - Observability: Returns detailed success/failure info for each operation
52
+ *
53
+ * Example Usage:
54
+ * ```typescript
55
+ * // Instead of Promise.allSettled (fires all at once):
56
+ * const results = await Promise.allSettled(
57
+ * actions.map(a => sdk.listInputFields(a))
58
+ * );
59
+ *
60
+ * // Use batch (controlled concurrency):
61
+ * const results = await batch(
62
+ * actions.map(a => () => sdk.listInputFields(a)),
63
+ * { concurrency: 10, retry: true }
64
+ * );
65
+ * ```
66
+ *
67
+ * @param tasks - Array of functions that return promises (NOT promises themselves!)
68
+ * @param options - Configuration for concurrency and retry behavior
69
+ * @returns Promise resolving to array of settled results (same as Promise.allSettled)
70
+ */
71
+ export declare function batch<T>(tasks: (() => Promise<T>)[], options?: BatchOptions): Promise<PromiseSettledResult<T>[]>;
72
+ //# sourceMappingURL=batch-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-utils.d.ts","sourceRoot":"","sources":["../../src/utils/batch-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwBH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAWD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,KAAK,CAAC,CAAC,EAC3B,KAAK,EAAE,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,EAC3B,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,CAuIpC"}