@zapier/zapier-sdk 0.13.7 → 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.
Files changed (59) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/api/client.d.ts.map +1 -1
  3. package/dist/api/client.js +5 -5
  4. package/dist/api/client.test.d.ts +2 -0
  5. package/dist/api/client.test.d.ts.map +1 -0
  6. package/dist/api/client.test.js +80 -0
  7. package/dist/api/index.d.ts +1 -0
  8. package/dist/api/index.d.ts.map +1 -1
  9. package/dist/api/index.js +3 -1
  10. package/dist/api/polling.d.ts.map +1 -1
  11. package/dist/api/polling.js +1 -11
  12. package/dist/api/schemas.d.ts +20 -20
  13. package/dist/api/types.d.ts +2 -0
  14. package/dist/api/types.d.ts.map +1 -1
  15. package/dist/auth.d.ts +3 -0
  16. package/dist/auth.d.ts.map +1 -1
  17. package/dist/auth.test.d.ts +2 -0
  18. package/dist/auth.test.d.ts.map +1 -0
  19. package/dist/auth.test.js +102 -0
  20. package/dist/constants.d.ts +4 -4
  21. package/dist/constants.d.ts.map +1 -1
  22. package/dist/constants.js +4 -4
  23. package/dist/index.cjs +194 -33
  24. package/dist/index.d.mts +93 -1
  25. package/dist/index.d.ts +3 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +4 -0
  28. package/dist/index.mjs +192 -34
  29. package/dist/plugins/api/index.d.ts.map +1 -1
  30. package/dist/plugins/api/index.js +4 -1
  31. package/dist/plugins/eventEmission/index.d.ts +2 -0
  32. package/dist/plugins/eventEmission/index.d.ts.map +1 -1
  33. package/dist/plugins/eventEmission/index.js +35 -9
  34. package/dist/plugins/eventEmission/index.test.js +100 -0
  35. package/dist/schemas/Action.d.ts +2 -2
  36. package/dist/schemas/Auth.d.ts +4 -4
  37. package/dist/schemas/Field.d.ts +10 -10
  38. package/dist/sdk.test.js +121 -1
  39. package/dist/types/sdk.d.ts +3 -0
  40. package/dist/types/sdk.d.ts.map +1 -1
  41. package/dist/utils/batch-utils.d.ts +72 -0
  42. package/dist/utils/batch-utils.d.ts.map +1 -0
  43. package/dist/utils/batch-utils.js +162 -0
  44. package/dist/utils/batch-utils.test.d.ts +2 -0
  45. package/dist/utils/batch-utils.test.d.ts.map +1 -0
  46. package/dist/utils/batch-utils.test.js +476 -0
  47. package/dist/utils/retry-utils.d.ts +45 -0
  48. package/dist/utils/retry-utils.d.ts.map +1 -0
  49. package/dist/utils/retry-utils.js +51 -0
  50. package/dist/utils/retry-utils.test.d.ts +2 -0
  51. package/dist/utils/retry-utils.test.d.ts.map +1 -0
  52. package/dist/utils/retry-utils.test.js +90 -0
  53. package/dist/utils/url-utils.d.ts +19 -0
  54. package/dist/utils/url-utils.d.ts.map +1 -0
  55. package/dist/utils/url-utils.js +62 -0
  56. package/dist/utils/url-utils.test.d.ts +2 -0
  57. package/dist/utils/url-utils.test.d.ts.map +1 -0
  58. package/dist/utils/url-utils.test.js +103 -0
  59. package/package.json +2 -2
@@ -3,11 +3,11 @@ export declare const BaseFieldItemSchema: z.ZodObject<{
3
3
  type: z.ZodString;
4
4
  key: z.ZodString;
5
5
  }, "strip", z.ZodTypeAny, {
6
- type: string;
7
6
  key: string;
8
- }, {
9
7
  type: string;
8
+ }, {
10
9
  key: string;
10
+ type: string;
11
11
  }>;
12
12
  export declare const InputFieldItemSchema: z.ZodObject<{
13
13
  key: z.ZodString;
@@ -30,8 +30,8 @@ export declare const InputFieldItemSchema: z.ZodObject<{
30
30
  type: string;
31
31
  }>>;
32
32
  }, "strip", z.ZodTypeAny, {
33
- type: "input_field";
34
33
  key: string;
34
+ type: "input_field";
35
35
  depends_on: string[];
36
36
  placeholder: string;
37
37
  description: string;
@@ -45,8 +45,8 @@ export declare const InputFieldItemSchema: z.ZodObject<{
45
45
  type: string;
46
46
  } | undefined;
47
47
  }, {
48
- type: "input_field";
49
48
  key: string;
49
+ type: "input_field";
50
50
  depends_on: string[];
51
51
  placeholder: string;
52
52
  description: string;
@@ -67,13 +67,13 @@ export declare const InfoFieldItemSchema: z.ZodObject<{
67
67
  description: z.ZodString;
68
68
  title: z.ZodOptional<z.ZodString>;
69
69
  }, "strip", z.ZodTypeAny, {
70
- type: "info_field";
71
70
  key: string;
71
+ type: "info_field";
72
72
  description: string;
73
73
  title?: string | undefined;
74
74
  }, {
75
- type: "info_field";
76
75
  key: string;
76
+ type: "info_field";
77
77
  description: string;
78
78
  title?: string | undefined;
79
79
  }>;
@@ -106,8 +106,8 @@ export declare const RootFieldItemSchema: z.ZodUnion<[z.ZodObject<{
106
106
  type: string;
107
107
  }>>;
108
108
  }, "strip", z.ZodTypeAny, {
109
- type: "input_field";
110
109
  key: string;
110
+ type: "input_field";
111
111
  depends_on: string[];
112
112
  placeholder: string;
113
113
  description: string;
@@ -121,8 +121,8 @@ export declare const RootFieldItemSchema: z.ZodUnion<[z.ZodObject<{
121
121
  type: string;
122
122
  } | undefined;
123
123
  }, {
124
- type: "input_field";
125
124
  key: string;
125
+ type: "input_field";
126
126
  depends_on: string[];
127
127
  placeholder: string;
128
128
  description: string;
@@ -142,13 +142,13 @@ export declare const RootFieldItemSchema: z.ZodUnion<[z.ZodObject<{
142
142
  description: z.ZodString;
143
143
  title: z.ZodOptional<z.ZodString>;
144
144
  }, "strip", z.ZodTypeAny, {
145
- type: "info_field";
146
145
  key: string;
146
+ type: "info_field";
147
147
  description: string;
148
148
  title?: string | undefined;
149
149
  }, {
150
- type: "info_field";
151
150
  key: string;
151
+ type: "info_field";
152
152
  description: string;
153
153
  title?: string | undefined;
154
154
  }>, z.ZodType<FieldsetItem, z.ZodTypeDef, FieldsetItem>]>;
package/dist/sdk.test.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // Test the flat plugin system
2
- import { describe, it, expect } from "vitest";
2
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
3
3
  import { createZapierSdk, createSdk } from "./sdk";
4
4
  describe("Flat Plugin System", () => {
5
5
  it("should create SDK with all expected methods", () => {
@@ -133,3 +133,123 @@ describe("Flat Plugin System", () => {
133
133
  expect(context.meta).not.toBeNull();
134
134
  });
135
135
  });
136
+ describe("Environment Variable Support", () => {
137
+ let originalEnv;
138
+ beforeEach(() => {
139
+ // Save original environment variable
140
+ originalEnv = process.env.ZAPIER_BASE_URL;
141
+ });
142
+ afterEach(() => {
143
+ // Restore original environment variable
144
+ if (originalEnv !== undefined) {
145
+ process.env.ZAPIER_BASE_URL = originalEnv;
146
+ }
147
+ else {
148
+ delete process.env.ZAPIER_BASE_URL;
149
+ }
150
+ // Clear module cache to ensure constants are re-evaluated
151
+ vi.resetModules();
152
+ });
153
+ it("should use custom base URL from ZAPIER_BASE_URL environment variable", async () => {
154
+ // Set custom base URL via environment variable
155
+ const customBaseUrl = "https://custom-zapier.example.com";
156
+ process.env.ZAPIER_BASE_URL = customBaseUrl;
157
+ // Clear module cache and re-import to get fresh constants
158
+ vi.resetModules();
159
+ const { createZapierSdk } = await import("./sdk");
160
+ // Create mock fetch function to capture requests
161
+ const mockFetch = vi.fn().mockResolvedValue({
162
+ ok: true,
163
+ status: 200,
164
+ json: async () => ({
165
+ results: [],
166
+ meta: { next_cursor: null },
167
+ }),
168
+ headers: new Headers(),
169
+ });
170
+ // Create SDK instance with mock fetch
171
+ const sdk = createZapierSdk({
172
+ token: "test-token",
173
+ fetch: mockFetch,
174
+ });
175
+ // Make an API call that should use the custom base URL
176
+ await sdk.listApps();
177
+ // Verify that the request was made to the custom base URL
178
+ expect(mockFetch).toHaveBeenCalledTimes(1);
179
+ const [actualUrl] = mockFetch.mock.calls[0];
180
+ expect(actualUrl).toMatch(new RegExp(`^${customBaseUrl}`));
181
+ expect(actualUrl).toContain("/api/v4/");
182
+ });
183
+ it("should use default base URL when ZAPIER_BASE_URL is not set", async () => {
184
+ // Ensure environment variable is not set
185
+ delete process.env.ZAPIER_BASE_URL;
186
+ // Clear module cache and re-import to get fresh constants
187
+ vi.resetModules();
188
+ const { createZapierSdk } = await import("./sdk");
189
+ // Create mock fetch function to capture requests
190
+ const mockFetch = vi.fn().mockResolvedValue({
191
+ ok: true,
192
+ status: 200,
193
+ json: async () => ({
194
+ results: [],
195
+ meta: { next_cursor: null },
196
+ }),
197
+ headers: new Headers(),
198
+ });
199
+ // Create SDK instance with mock fetch
200
+ const sdk = createZapierSdk({
201
+ token: "test-token",
202
+ fetch: mockFetch,
203
+ });
204
+ // Make an API call that should use the default base URL
205
+ await sdk.listApps();
206
+ // Verify that the request was made to the default base URL
207
+ expect(mockFetch).toHaveBeenCalledTimes(1);
208
+ const [actualUrl] = mockFetch.mock.calls[0];
209
+ expect(actualUrl).toMatch(/^https:\/\/zapier\.com/);
210
+ expect(actualUrl).toContain("/api/v4/");
211
+ });
212
+ it("should use explicit baseUrl option for SDK API requests", async () => {
213
+ // Clear environment variable to ensure we're testing the explicit option
214
+ delete process.env.ZAPIER_BASE_URL;
215
+ // Clear module cache and re-import to get fresh constants
216
+ vi.resetModules();
217
+ const { createZapierSdk } = await import("./sdk");
218
+ const customBaseUrl = "https://staging.zapier.com";
219
+ // Create mock fetch function to capture requests
220
+ const mockFetch = vi.fn().mockResolvedValue({
221
+ ok: true,
222
+ status: 200,
223
+ json: async () => ({
224
+ results: [],
225
+ meta: { next_cursor: null },
226
+ }),
227
+ headers: new Headers(),
228
+ });
229
+ // Create SDK instance with explicit baseUrl option and mock fetch
230
+ const sdk = createZapierSdk({
231
+ baseUrl: customBaseUrl,
232
+ token: "test-token",
233
+ fetch: mockFetch,
234
+ });
235
+ // Make an API call that should use the custom base URL
236
+ await sdk.listApps();
237
+ // Verify that the request was made to the custom base URL
238
+ expect(mockFetch).toHaveBeenCalledTimes(1);
239
+ const [actualUrl] = mockFetch.mock.calls[0];
240
+ expect(actualUrl).toMatch(new RegExp(`^${customBaseUrl}`));
241
+ expect(actualUrl).toContain("/api/v4/");
242
+ });
243
+ it("should accept authClientId in SDK options", async () => {
244
+ delete process.env.ZAPIER_BASE_URL;
245
+ vi.resetModules();
246
+ const { createZapierSdk } = await import("./sdk");
247
+ const sdk = createZapierSdk({
248
+ authClientId: "test-client-id",
249
+ token: "test-token",
250
+ });
251
+ // Verify SDK was created successfully with authClientId option
252
+ expect(sdk).toBeDefined();
253
+ expect(sdk.listApps).toBeDefined();
254
+ });
255
+ });
@@ -10,6 +10,9 @@ export interface BaseSdkOptions {
10
10
  onEvent?: EventCallback;
11
11
  fetch?: typeof fetch;
12
12
  baseUrl?: string;
13
+ authBaseUrl?: string;
14
+ authClientId?: string;
15
+ trackingBaseUrl?: string;
13
16
  debug?: boolean;
14
17
  manifestPath?: string;
15
18
  manifest?: Manifest;
@@ -1 +1 @@
1
- {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/types/sdk.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/types/sdk.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,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,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC7C,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAGD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AACrF,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACzF,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,4CAA4C,CAAC;AACrG,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,6CAA6C,CAAC;AACvG,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAE1E,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AACxF,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,8BAA8B,CAAC;AACpF,OAAO,KAAK,EAAE,qCAAqC,EAAE,MAAM,oCAAoC,CAAC;AAChG,OAAO,KAAK,EAAE,sCAAsC,EAAE,MAAM,qCAAqC,CAAC;AAClG,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,4BAA4B,CAAC;AAChF,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,kCAAkC,CAAC;AAC5F,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAMlE,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IAC1B,eAAe,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAA;KAAE,CAAC,CAAC;IAC/D,YAAY,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IAC3B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAGD,MAAM,WAAW,kBACf,SAAQ,0BAA0B,EAChC,4BAA4B,EAC5B,kCAAkC,EAClC,mCAAmC,EACnC,uBAAuB;CAE1B;AAUD,MAAM,WAAW,SACf,SAAQ,UAAU,CAChB,sBAAsB,GACpB,mBAAmB,GACnB,kBAAkB,GAClB,sBAAsB,GACtB,sBAAsB,GACtB,oBAAoB,GACpB,yBAAyB,GACzB,uBAAuB,GACvB,uBAAuB,GACvB,iCAAiC,GACjC,+BAA+B,GAC/B,qCAAqC,GACrC,sCAAsC,GACtC,6BAA6B,GAC7B,mCAAmC,GACnC,qBAAqB,GACrB,wBAAwB,GACxB,qBAAqB,GACrB,iBAAiB,CACpB;IAED,IAAI,EAAE,WAAW,GAAG,aAAa,CAAC;CACnC"}
@@ -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"}
@@ -0,0 +1,162 @@
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
+ import { setTimeout } from "timers/promises";
8
+ import { calculateWaitTime, MAX_CONSECUTIVE_ERRORS } from "./retry-utils";
9
+ import { ZapierTimeoutError } from "../types/errors";
10
+ /**
11
+ * Default number of concurrent operations
12
+ * Chosen to be "polite" to APIs while still providing good throughput
13
+ */
14
+ const DEFAULT_CONCURRENCY = 10;
15
+ /**
16
+ * Delay between starting each batch of concurrent operations (milliseconds)
17
+ * This prevents burst patterns that might trigger rate limiting
18
+ */
19
+ const BATCH_START_DELAY_MS = 25;
20
+ /**
21
+ * Default timeout for entire batch operation (milliseconds)
22
+ * Set to 3 minutes to match polling default timeout
23
+ */
24
+ const DEFAULT_BATCH_TIMEOUT_MS = 180000;
25
+ /**
26
+ * Execute multiple async operations with concurrency limiting and retry logic
27
+ *
28
+ * This prevents overwhelming APIs by:
29
+ * 1. Limiting concurrent operations (worker pool pattern)
30
+ * 2. Adding small delays between batches to avoid burst detection
31
+ * 3. Retrying failed operations with exponential backoff
32
+ *
33
+ * Problem Solved:
34
+ * - Rate limit prevention: Steady stream instead of burst requests
35
+ * - Connection pool management: Stays within browser/Node limits (~6-8 per domain)
36
+ * - Resilience: Transient failures are retried automatically
37
+ * - Observability: Returns detailed success/failure info for each operation
38
+ *
39
+ * Example Usage:
40
+ * ```typescript
41
+ * // Instead of Promise.allSettled (fires all at once):
42
+ * const results = await Promise.allSettled(
43
+ * actions.map(a => sdk.listInputFields(a))
44
+ * );
45
+ *
46
+ * // Use batch (controlled concurrency):
47
+ * const results = await batch(
48
+ * actions.map(a => () => sdk.listInputFields(a)),
49
+ * { concurrency: 10, retry: true }
50
+ * );
51
+ * ```
52
+ *
53
+ * @param tasks - Array of functions that return promises (NOT promises themselves!)
54
+ * @param options - Configuration for concurrency and retry behavior
55
+ * @returns Promise resolving to array of settled results (same as Promise.allSettled)
56
+ */
57
+ export async function batch(tasks, options = {}) {
58
+ const { concurrency = DEFAULT_CONCURRENCY, retry = true, batchDelay = BATCH_START_DELAY_MS, timeoutMs = DEFAULT_BATCH_TIMEOUT_MS, taskTimeoutMs, } = options;
59
+ // Validate inputs
60
+ if (concurrency <= 0) {
61
+ throw new Error("Concurrency must be greater than 0");
62
+ }
63
+ if (timeoutMs <= 0) {
64
+ throw new Error("Timeout must be greater than 0");
65
+ }
66
+ if (taskTimeoutMs !== undefined && taskTimeoutMs <= 0) {
67
+ throw new Error("Task timeout must be greater than 0");
68
+ }
69
+ if (tasks.length === 0) {
70
+ return [];
71
+ }
72
+ // Track overall batch timing
73
+ const startTime = Date.now();
74
+ // Pre-allocate results array to maintain input order
75
+ const results = new Array(tasks.length);
76
+ // Create task queue with retry state
77
+ const taskQueue = tasks.map((task, index) => ({
78
+ index,
79
+ task,
80
+ errorCount: 0,
81
+ }));
82
+ /**
83
+ * Execute a single task with retry logic and optional per-task timeout
84
+ */
85
+ async function executeTask(taskState) {
86
+ const { index, task, errorCount } = taskState;
87
+ try {
88
+ let result;
89
+ // Apply per-task timeout if specified
90
+ if (taskTimeoutMs !== undefined) {
91
+ const timeoutPromise = setTimeout(taskTimeoutMs).then(() => {
92
+ throw new ZapierTimeoutError(`Task timed out after ${taskTimeoutMs}ms`);
93
+ });
94
+ result = await Promise.race([task(), timeoutPromise]);
95
+ }
96
+ else {
97
+ result = await task();
98
+ }
99
+ results[index] = { status: "fulfilled", value: result };
100
+ }
101
+ catch (error) {
102
+ const newErrorCount = errorCount + 1;
103
+ // Don't retry timeout errors - they're unlikely to succeed on retry
104
+ const isTimeout = error instanceof ZapierTimeoutError;
105
+ // If retry is enabled and we haven't hit max errors and it's not a timeout, retry with backoff
106
+ if (retry && !isTimeout && newErrorCount < MAX_CONSECUTIVE_ERRORS) {
107
+ // Calculate backoff delay (base 1000ms with jitter and error scaling)
108
+ const waitTime = calculateWaitTime(1000, newErrorCount);
109
+ await setTimeout(waitTime);
110
+ // Re-queue the task with incremented error count
111
+ taskQueue.push({
112
+ index,
113
+ task,
114
+ errorCount: newErrorCount,
115
+ });
116
+ }
117
+ else {
118
+ // Max retries reached, retry disabled, or timeout error - mark as rejected
119
+ results[index] = { status: "rejected", reason: error };
120
+ }
121
+ }
122
+ }
123
+ /**
124
+ * Worker that continuously picks up and executes tasks from the queue
125
+ * Checks overall batch timeout before processing each task
126
+ */
127
+ async function worker() {
128
+ while (taskQueue.length > 0) {
129
+ // Check overall batch timeout before processing next task
130
+ const elapsedTime = Date.now() - startTime;
131
+ if (elapsedTime >= timeoutMs) {
132
+ throw new ZapierTimeoutError(`Batch operation timed out after ${Math.floor(elapsedTime / 1000)}s. ${taskQueue.length} task(s) not completed.`);
133
+ }
134
+ const taskState = taskQueue.shift();
135
+ if (!taskState)
136
+ break;
137
+ await executeTask(taskState);
138
+ // Small delay to prevent burst patterns within a worker
139
+ // Only delay if there are more tasks to process
140
+ if (taskQueue.length > 0 && batchDelay > 0) {
141
+ await setTimeout(batchDelay);
142
+ }
143
+ }
144
+ }
145
+ /**
146
+ * Start workers in small batches to avoid initial burst
147
+ * This helps avoid rate limit triggers when starting many workers
148
+ */
149
+ const workerCount = Math.min(concurrency, tasks.length);
150
+ const workers = [];
151
+ for (let i = 0; i < workerCount; i++) {
152
+ workers.push(worker());
153
+ // Add small delay between starting workers to stagger the initial requests
154
+ // Skip delay for last worker
155
+ if (i < workerCount - 1 && batchDelay > 0) {
156
+ await setTimeout(batchDelay / 10); // 10ms between worker starts
157
+ }
158
+ }
159
+ // Wait for all workers to complete
160
+ await Promise.all(workers);
161
+ return results;
162
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=batch-utils.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"batch-utils.test.d.ts","sourceRoot":"","sources":["../../src/utils/batch-utils.test.ts"],"names":[],"mappings":""}