@zapier/zapier-sdk 0.13.6 → 0.13.8

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 (155) 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/schemas.d.ts +20 -20
  11. package/dist/api/types.d.ts +2 -0
  12. package/dist/api/types.d.ts.map +1 -1
  13. package/dist/auth.d.ts +3 -0
  14. package/dist/auth.d.ts.map +1 -1
  15. package/dist/auth.test.d.ts +2 -0
  16. package/dist/auth.test.d.ts.map +1 -0
  17. package/dist/auth.test.js +102 -0
  18. package/dist/constants.d.ts +4 -4
  19. package/dist/constants.d.ts.map +1 -1
  20. package/dist/constants.js +4 -4
  21. package/dist/index.cjs +89 -21
  22. package/dist/index.d.mts +21 -1
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +2 -0
  26. package/dist/index.mjs +88 -22
  27. package/dist/plugins/api/index.d.ts.map +1 -1
  28. package/dist/plugins/api/index.js +4 -1
  29. package/dist/plugins/eventEmission/index.d.ts +2 -0
  30. package/dist/plugins/eventEmission/index.d.ts.map +1 -1
  31. package/dist/plugins/eventEmission/index.js +35 -9
  32. package/dist/plugins/eventEmission/index.test.js +100 -0
  33. package/dist/schemas/Action.d.ts +2 -2
  34. package/dist/schemas/Auth.d.ts +4 -4
  35. package/dist/schemas/Field.d.ts +10 -10
  36. package/dist/sdk.test.js +121 -1
  37. package/dist/types/sdk.d.ts +3 -0
  38. package/dist/types/sdk.d.ts.map +1 -1
  39. package/dist/utils/url-utils.d.ts +19 -0
  40. package/dist/utils/url-utils.d.ts.map +1 -0
  41. package/dist/utils/url-utils.js +62 -0
  42. package/dist/utils/url-utils.test.d.ts +2 -0
  43. package/dist/utils/url-utils.test.d.ts.map +1 -0
  44. package/dist/utils/url-utils.test.js +103 -0
  45. package/package.json +8 -3
  46. package/src/api/auth.ts +0 -28
  47. package/src/api/client.ts +0 -491
  48. package/src/api/debug.test.ts +0 -76
  49. package/src/api/debug.ts +0 -154
  50. package/src/api/index.ts +0 -90
  51. package/src/api/polling.test.ts +0 -405
  52. package/src/api/polling.ts +0 -253
  53. package/src/api/schemas.ts +0 -465
  54. package/src/api/types.ts +0 -152
  55. package/src/auth.ts +0 -72
  56. package/src/constants.ts +0 -16
  57. package/src/index.ts +0 -111
  58. package/src/plugins/api/index.ts +0 -43
  59. package/src/plugins/apps/index.ts +0 -203
  60. package/src/plugins/apps/schemas.ts +0 -64
  61. package/src/plugins/eventEmission/builders.ts +0 -115
  62. package/src/plugins/eventEmission/index.test.ts +0 -169
  63. package/src/plugins/eventEmission/index.ts +0 -294
  64. package/src/plugins/eventEmission/transport.test.ts +0 -214
  65. package/src/plugins/eventEmission/transport.ts +0 -135
  66. package/src/plugins/eventEmission/types.ts +0 -58
  67. package/src/plugins/eventEmission/utils.ts +0 -121
  68. package/src/plugins/fetch/index.ts +0 -83
  69. package/src/plugins/fetch/schemas.ts +0 -37
  70. package/src/plugins/findFirstAuthentication/index.test.ts +0 -209
  71. package/src/plugins/findFirstAuthentication/index.ts +0 -68
  72. package/src/plugins/findFirstAuthentication/schemas.ts +0 -47
  73. package/src/plugins/findUniqueAuthentication/index.test.ts +0 -197
  74. package/src/plugins/findUniqueAuthentication/index.ts +0 -77
  75. package/src/plugins/findUniqueAuthentication/schemas.ts +0 -49
  76. package/src/plugins/getAction/index.test.ts +0 -239
  77. package/src/plugins/getAction/index.ts +0 -75
  78. package/src/plugins/getAction/schemas.ts +0 -41
  79. package/src/plugins/getApp/index.test.ts +0 -181
  80. package/src/plugins/getApp/index.ts +0 -60
  81. package/src/plugins/getApp/schemas.ts +0 -33
  82. package/src/plugins/getAuthentication/index.test.ts +0 -294
  83. package/src/plugins/getAuthentication/index.ts +0 -95
  84. package/src/plugins/getAuthentication/schemas.ts +0 -38
  85. package/src/plugins/getProfile/index.ts +0 -60
  86. package/src/plugins/getProfile/schemas.ts +0 -24
  87. package/src/plugins/listActions/index.test.ts +0 -526
  88. package/src/plugins/listActions/index.ts +0 -132
  89. package/src/plugins/listActions/schemas.ts +0 -55
  90. package/src/plugins/listApps/index.test.ts +0 -378
  91. package/src/plugins/listApps/index.ts +0 -159
  92. package/src/plugins/listApps/schemas.ts +0 -41
  93. package/src/plugins/listAuthentications/index.test.ts +0 -739
  94. package/src/plugins/listAuthentications/index.ts +0 -152
  95. package/src/plugins/listAuthentications/schemas.ts +0 -77
  96. package/src/plugins/listInputFieldChoices/index.test.ts +0 -653
  97. package/src/plugins/listInputFieldChoices/index.ts +0 -173
  98. package/src/plugins/listInputFieldChoices/schemas.ts +0 -125
  99. package/src/plugins/listInputFields/index.test.ts +0 -439
  100. package/src/plugins/listInputFields/index.ts +0 -294
  101. package/src/plugins/listInputFields/schemas.ts +0 -68
  102. package/src/plugins/manifest/index.test.ts +0 -776
  103. package/src/plugins/manifest/index.ts +0 -461
  104. package/src/plugins/manifest/schemas.ts +0 -60
  105. package/src/plugins/registry/index.ts +0 -160
  106. package/src/plugins/request/index.test.ts +0 -333
  107. package/src/plugins/request/index.ts +0 -105
  108. package/src/plugins/request/schemas.ts +0 -69
  109. package/src/plugins/runAction/index.test.ts +0 -388
  110. package/src/plugins/runAction/index.ts +0 -215
  111. package/src/plugins/runAction/schemas.ts +0 -60
  112. package/src/resolvers/actionKey.ts +0 -37
  113. package/src/resolvers/actionType.ts +0 -34
  114. package/src/resolvers/appKey.ts +0 -7
  115. package/src/resolvers/authenticationId.ts +0 -54
  116. package/src/resolvers/index.ts +0 -11
  117. package/src/resolvers/inputFieldKey.ts +0 -70
  118. package/src/resolvers/inputs.ts +0 -69
  119. package/src/schemas/Action.ts +0 -52
  120. package/src/schemas/App.ts +0 -45
  121. package/src/schemas/Auth.ts +0 -59
  122. package/src/schemas/Field.ts +0 -169
  123. package/src/schemas/Run.ts +0 -40
  124. package/src/schemas/UserProfile.ts +0 -60
  125. package/src/sdk.test.ts +0 -212
  126. package/src/sdk.ts +0 -178
  127. package/src/types/domain.test.ts +0 -50
  128. package/src/types/domain.ts +0 -66
  129. package/src/types/errors.ts +0 -278
  130. package/src/types/events.ts +0 -43
  131. package/src/types/functions.ts +0 -28
  132. package/src/types/optional-zapier-sdk-cli-login.d.ts +0 -37
  133. package/src/types/plugin.ts +0 -125
  134. package/src/types/properties.ts +0 -80
  135. package/src/types/sdk.ts +0 -111
  136. package/src/types/telemetry-events.ts +0 -85
  137. package/src/utils/array-utils.test.ts +0 -131
  138. package/src/utils/array-utils.ts +0 -41
  139. package/src/utils/domain-utils.test.ts +0 -433
  140. package/src/utils/domain-utils.ts +0 -267
  141. package/src/utils/file-utils.test.ts +0 -73
  142. package/src/utils/file-utils.ts +0 -94
  143. package/src/utils/function-utils.test.ts +0 -141
  144. package/src/utils/function-utils.ts +0 -245
  145. package/src/utils/pagination-utils.test.ts +0 -620
  146. package/src/utils/pagination-utils.ts +0 -242
  147. package/src/utils/schema-utils.ts +0 -207
  148. package/src/utils/string-utils.test.ts +0 -45
  149. package/src/utils/string-utils.ts +0 -54
  150. package/src/utils/validation.test.ts +0 -51
  151. package/src/utils/validation.ts +0 -44
  152. package/tsconfig.build.json +0 -18
  153. package/tsconfig.json +0 -20
  154. package/tsconfig.tsbuildinfo +0 -1
  155. package/tsup.config.ts +0 -23
@@ -1,378 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach } from "vitest";
2
- import { ZapierValidationError } from "../../types/errors";
3
- import { listAppsPlugin } from "./index";
4
- import { createSdk } from "../../sdk";
5
- import { apiPlugin } from "../api/index";
6
-
7
- const mockAppsResponse = {
8
- results: [
9
- {
10
- id: "SlackCLIAPI@1.0.0",
11
- slug: "slack",
12
- name: "Slack",
13
- description: "Team communication",
14
- primary_color: "#4A154B",
15
- categories: ["communication"],
16
- },
17
- {
18
- id: "GoogleSheetsCLIAPI@1.0.0",
19
- slug: "google-sheets",
20
- name: "Google Sheets",
21
- description: "Online spreadsheets",
22
- primary_color: "#34A853",
23
- categories: ["productivity"],
24
- },
25
- ],
26
- meta: {
27
- next_cursor: null,
28
- },
29
- };
30
-
31
- const mockResolveAppKeys = vi
32
- .fn()
33
- .mockImplementation(async ({ appKeys }: { appKeys: string[] }) => {
34
- // Mock implementation that returns resolved locators for the app keys
35
- return appKeys.map((appKey) => ({
36
- lookupAppKey: appKey,
37
- implementationName: appKey, // For testing, use appKey as implementationName
38
- slug: appKey.toLowerCase(),
39
- version: undefined,
40
- }));
41
- });
42
-
43
- function createTestSdk() {
44
- return createSdk()
45
- .addPlugin(apiPlugin, { fetch: global.fetch })
46
- .addPlugin(() => ({
47
- context: {
48
- resolveAppKeys: mockResolveAppKeys,
49
- },
50
- }))
51
- .addPlugin(listAppsPlugin as any);
52
- }
53
-
54
- describe("listApps plugin", () => {
55
- beforeEach(() => {
56
- vi.clearAllMocks();
57
- });
58
-
59
- describe("schema validation", () => {
60
- it("should pass validation with empty options", async () => {
61
- const mockServicesResponse = {
62
- results: [
63
- {
64
- id: "slack_service_id",
65
- slug: "slack",
66
- name: "Slack",
67
- description: "Team communication",
68
- current_implementation_id: "SlackCLIAPI@1.0.0",
69
- },
70
- {
71
- id: "sheets_service_id",
72
- slug: "google-sheets",
73
- name: "Google Sheets",
74
- description: "Online spreadsheets",
75
- current_implementation_id: "GoogleSheetsCLIAPI@1.0.0",
76
- },
77
- ],
78
- next: null,
79
- };
80
-
81
- const sdk = createTestSdk();
82
- const context = sdk.getContext();
83
- // Mock the API client in context
84
- (context.api as any).get = vi
85
- .fn()
86
- .mockResolvedValue(mockServicesResponse);
87
-
88
- const result = await sdk.listApps({});
89
- expect(result.data).toHaveLength(2);
90
- });
91
-
92
- it("should handle undefined options by converting to empty object", async () => {
93
- const sdk = createTestSdk();
94
- const context = sdk.getContext();
95
-
96
- // Mock the API client in context
97
- (context.api as any).get = vi.fn().mockResolvedValueOnce({
98
- results: [
99
- {
100
- id: "SlackCLIAPI@1.0.0",
101
- name: "Slack",
102
- description: "Team communication",
103
- primary_color: "#4A154B",
104
- categories: ["communication"],
105
- },
106
- ],
107
- next: null,
108
- });
109
-
110
- const result = await sdk.listApps(undefined as any);
111
-
112
- expect(result.data).toHaveLength(1);
113
- expect(result.data[0]).toMatchObject({
114
- key: "SlackCLIAPI",
115
- title: "Slack",
116
- });
117
- expect((context.api as any).get).toHaveBeenCalledWith(
118
- "/api/v4/implementations-meta/lookup/",
119
- {
120
- searchParams: {
121
- latest_only: "true",
122
- limit: "100",
123
- selected_apis: "",
124
- },
125
- },
126
- );
127
- });
128
-
129
- it("should throw validation error for invalid pageSize", () => {
130
- const sdk = createTestSdk();
131
- expect(() => {
132
- sdk.listApps({
133
- pageSize: 0, // Should be >= 1
134
- });
135
- }).toThrow(ZapierValidationError);
136
-
137
- expect(() => {
138
- sdk.listApps({
139
- pageSize: -5, // Should be >= 1
140
- });
141
- }).toThrow(ZapierValidationError);
142
- });
143
-
144
- it("should throw validation error for invalid maxItems", () => {
145
- const sdk = createTestSdk();
146
- expect(() => {
147
- sdk.listApps({
148
- maxItems: 0 as any, // Should be >= 1
149
- });
150
- }).toThrow(ZapierValidationError);
151
-
152
- expect(() => {
153
- sdk.listApps({
154
- maxItems: -10 as any, // Should be >= 1
155
- });
156
- }).toThrow(ZapierValidationError);
157
- });
158
-
159
- it("should throw validation error for invalid appKeys type", () => {
160
- const sdk = createTestSdk();
161
- expect(() => {
162
- sdk.listApps({
163
- appKeys: 123 as any,
164
- });
165
- }).toThrow(ZapierValidationError);
166
- });
167
-
168
- it("should pass validation with all valid fields", async () => {
169
- const sdk = createTestSdk();
170
- const context = sdk.getContext();
171
-
172
- // Mock the API client in context
173
- (context.api as any).get = vi.fn().mockResolvedValueOnce({
174
- results: [
175
- {
176
- id: "SlackCLIAPI@1.0.0",
177
- name: "Slack",
178
- description: "Team communication",
179
- primary_color: "#4A154B",
180
- categories: ["communication"],
181
- },
182
- {
183
- id: "GitHubCLIAPI@1.0.0",
184
- name: "GitHub",
185
- description: "Code repository hosting",
186
- primary_color: "#24292e",
187
- categories: ["developer-tools"],
188
- },
189
- ],
190
- next: null,
191
- });
192
-
193
- const result = await sdk.listApps({
194
- appKeys: ["SlackCLIAPI", "GitHubCLIAPI"],
195
- pageSize: 10,
196
- maxItems: 50,
197
- });
198
-
199
- expect(result.data).toHaveLength(2);
200
- expect(result.data[0].key).toBe("SlackCLIAPI");
201
- expect(result.data[1].key).toBe("GitHubCLIAPI");
202
- });
203
- });
204
-
205
- describe("data mapping", () => {
206
- it("should return essential app properties", async () => {
207
- const mockServicesResponse = {
208
- results: [
209
- {
210
- id: "slack_service_id",
211
- slug: "slack",
212
- name: "Slack",
213
- description: "Team communication",
214
- current_implementation_id: "SlackCLIAPI@1.0.0",
215
- },
216
- ],
217
- next: null,
218
- };
219
-
220
- const sdk = createTestSdk();
221
- const context = sdk.getContext();
222
- // Mock the API client in context
223
- (context.api as any).get = vi
224
- .fn()
225
- .mockResolvedValue(mockServicesResponse);
226
-
227
- const result = await sdk.listApps({});
228
-
229
- expect(result.data[0]).toHaveProperty("title");
230
- expect(result.data[0]).toHaveProperty("key");
231
- expect(result.data[0]).toHaveProperty("implementation_id");
232
- // Version is optional
233
- expect(result.data[0]).toHaveProperty("version");
234
- });
235
- });
236
-
237
- describe("pagination", () => {
238
- it("should handle pagination with maxItems", async () => {
239
- const mockServicesResponse = {
240
- results: [
241
- {
242
- id: "slack_service_id",
243
- slug: "slack",
244
- name: "Slack",
245
- description: "Team communication",
246
- current_implementation_id: "SlackCLIAPI@1.0.0",
247
- },
248
- {
249
- id: "sheets_service_id",
250
- slug: "google-sheets",
251
- name: "Google Sheets",
252
- description: "Online spreadsheets",
253
- current_implementation_id: "GoogleSheetsCLIAPI@1.0.0",
254
- },
255
- ],
256
- next: null,
257
- };
258
-
259
- const sdk = createTestSdk();
260
- const context = sdk.getContext();
261
- const mockGet = vi.fn().mockResolvedValue(mockServicesResponse);
262
- (context.api as any).get = mockGet;
263
-
264
- const result = await sdk.listApps({ maxItems: 5 });
265
-
266
- // Should return all items since maxItems (5) is greater than available items (2)
267
- expect(result.data).toHaveLength(2);
268
- expect(mockGet).toHaveBeenCalledTimes(1);
269
- });
270
-
271
- it("should support async iteration over pages", async () => {
272
- const sdk = createTestSdk();
273
- const context = sdk.getContext();
274
- const mockGet = vi
275
- .fn()
276
- .mockResolvedValueOnce({
277
- results: [
278
- {
279
- id: "SlackCLIAPI@1.0.0",
280
- slug: "slack",
281
- name: "Slack",
282
- description: "Team communication",
283
- },
284
- ],
285
- next: "https://zapier.com/api/v4/services/?offset=cursor-page-2",
286
- })
287
- .mockResolvedValueOnce({
288
- results: [
289
- {
290
- id: "GoogleSheetsCLIAPI@1.0.0",
291
- slug: "google-sheets",
292
- name: "Google Sheets",
293
- description: "Online spreadsheets",
294
- },
295
- ],
296
- next: null,
297
- });
298
- (context.api as any).get = mockGet;
299
-
300
- const pages = [];
301
- for await (const page of sdk.listApps({ pageSize: 1 })) {
302
- pages.push(page);
303
- if (pages.length >= 2) break;
304
- }
305
-
306
- expect(pages).toHaveLength(2);
307
- expect(pages[0].data).toHaveLength(1);
308
- expect(pages[1].data).toHaveLength(1);
309
- expect(pages[0].data[0].key).toBe("SlackCLIAPI");
310
- expect(pages[1].data[0].key).toBe("GoogleSheetsCLIAPI");
311
- });
312
-
313
- it("should support async iteration over individual items", async () => {
314
- const mockServicesResponse = {
315
- results: [
316
- {
317
- id: "SlackCLIAPI@1.0.0",
318
- slug: "slack",
319
- name: "Slack",
320
- description: "Team communication",
321
- },
322
- {
323
- id: "GoogleSheetsCLIAPI@1.0.0",
324
- slug: "google-sheets",
325
- name: "Google Sheets",
326
- description: "Online spreadsheets",
327
- },
328
- ],
329
- next: null,
330
- };
331
-
332
- const sdk = createTestSdk();
333
- const context = sdk.getContext();
334
- (context.api as any).get = vi
335
- .fn()
336
- .mockResolvedValue(mockServicesResponse);
337
-
338
- const items = [];
339
- for await (const item of sdk.listApps({ maxItems: 2 }).items()) {
340
- items.push(item);
341
- }
342
-
343
- expect(items).toHaveLength(2);
344
- expect(items[0].key).toBe("SlackCLIAPI");
345
- expect(items[1].key).toBe("GoogleSheetsCLIAPI");
346
- });
347
- });
348
-
349
- describe("API integration", () => {
350
- it("should pass appKeys filter to API", async () => {
351
- const sdk = createTestSdk();
352
- const context = sdk.getContext();
353
- const mockGet = vi.fn().mockResolvedValue(mockAppsResponse);
354
- (context.api as any).get = mockGet;
355
-
356
- await sdk.listApps({ appKeys: ["SlackCLIAPI", "GitHubCLIAPI"] });
357
-
358
- expect(mockGet).toHaveBeenCalledWith(
359
- expect.stringContaining("implementations-meta"),
360
- expect.objectContaining({
361
- searchParams: expect.objectContaining({
362
- selected_apis: "SlackCLIAPI@latest,GitHubCLIAPI@latest",
363
- }),
364
- }),
365
- );
366
- });
367
- });
368
-
369
- describe("plugin integration", () => {
370
- it("should provide metadata in context", () => {
371
- const sdk = createTestSdk();
372
- const context = sdk.getContext();
373
-
374
- expect((context.meta as any).listApps).toBeDefined();
375
- expect((context.meta as any).listApps.inputSchema).toBeDefined();
376
- });
377
- });
378
- });
@@ -1,159 +0,0 @@
1
- import type { GetContextType, Plugin } from "../../types/plugin";
2
- import { createPaginatedFunction } from "../../utils/function-utils";
3
- import { ListAppsSchema } from "./schemas";
4
- import type { ListAppsOptions, ListAppsPage } from "./schemas";
5
- import type { AppItem } from "../../types/domain";
6
- import { AppItemSchema } from "../../schemas/App";
7
- import type { ResolvedAppLocator } from "../../utils/domain-utils";
8
- import {
9
- normalizeImplementationMetaToAppItem,
10
- splitVersionedKey,
11
- toAppLocator,
12
- toImplementationId,
13
- } from "../../utils/domain-utils";
14
- import { extractCursor } from "../../utils/function-utils";
15
- import type { ImplementationsMetaResponse } from "../../api/types";
16
- import type { ManifestPluginProvides } from "../manifest";
17
- import type { ApiPluginProvides } from "../api";
18
- // ListApps plugin provides interface - listApps goes directly to SDK root
19
- export interface ListAppsPluginProvides {
20
- listApps: (options?: ListAppsOptions) => Promise<{
21
- data: AppItem[];
22
- nextCursor?: string;
23
- }> &
24
- AsyncIterable<{ data: AppItem[]; nextCursor?: string }> & {
25
- items(): AsyncIterable<AppItem>;
26
- };
27
- context: {
28
- meta: {
29
- listApps: {
30
- inputSchema: typeof ListAppsSchema;
31
- };
32
- };
33
- };
34
- }
35
-
36
- export const listAppsPlugin: Plugin<
37
- {},
38
- GetContextType<ApiPluginProvides & ManifestPluginProvides>,
39
- ListAppsPluginProvides
40
- > = ({ context }) => {
41
- const listApps = createPaginatedFunction(async function listAppsPage(
42
- options: ListAppsOptions & { cursor?: string } & { pageSize: number },
43
- ): Promise<ListAppsPage> {
44
- const { api, resolveAppKeys } = context;
45
- const appKeys = options.appKeys ?? [];
46
-
47
- const appLocators = await resolveAppKeys({
48
- appKeys: [...appKeys],
49
- });
50
- const implementationNameToLocator: Record<string, ResolvedAppLocator[]> =
51
- {};
52
- for (const locator of appLocators) {
53
- implementationNameToLocator[locator.implementationName] = [
54
- ...(implementationNameToLocator[locator.implementationName] ?? []),
55
- locator,
56
- ];
57
- }
58
- const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator)
59
- .filter((key) => implementationNameToLocator[key].length > 1)
60
- .map((key) => implementationNameToLocator[key])
61
- .flat()
62
- .map((locator) => locator.lookupAppKey);
63
-
64
- if (duplicatedLookupAppKeys.length > 0) {
65
- throw new Error(
66
- `Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`,
67
- );
68
- }
69
-
70
- if (options.search) {
71
- const searchParams: Record<string, string> = {};
72
-
73
- searchParams.term = options.search;
74
-
75
- const searchEnvelope: ImplementationsMetaResponse = await api.get(
76
- "/api/v4/implementations-meta/search/",
77
- {
78
- searchParams,
79
- },
80
- );
81
-
82
- const implementations = searchEnvelope.results.map(
83
- normalizeImplementationMetaToAppItem,
84
- );
85
-
86
- const implementationNameSet = new Set<string>(
87
- appLocators.map((locator) => locator.implementationName),
88
- );
89
-
90
- for (const implementation of implementations) {
91
- const [implementationName] = splitVersionedKey(implementation.key);
92
- if (!implementationNameSet.has(implementationName)) {
93
- implementationNameSet.add(implementationName);
94
- appLocators.push({
95
- ...toAppLocator(implementation.key),
96
- implementationName,
97
- });
98
- }
99
- }
100
- }
101
-
102
- const searchParams: Record<string, string> = {};
103
-
104
- if (options.pageSize) {
105
- searchParams.limit = options.pageSize.toString();
106
- }
107
-
108
- if (appLocators.length === 0) {
109
- searchParams.latest_only = "true";
110
- }
111
-
112
- if (options.cursor) {
113
- searchParams.offset = options.cursor;
114
- }
115
-
116
- searchParams.selected_apis = appLocators
117
- .map((locator) => toImplementationId(locator))
118
- .join(",");
119
-
120
- // If we have app keys, but they resolved to an empty list, then we need to short-circuit and return an empty list.
121
- // Otherwise, the API will return all apps, since no selected_apis are provided.
122
- if (appKeys.length > 0 && appLocators.length === 0) {
123
- return {
124
- data: [],
125
- nextCursor: undefined,
126
- };
127
- }
128
-
129
- const implementationsEnvelope: ImplementationsMetaResponse = await api.get(
130
- "/api/v4/implementations-meta/lookup/",
131
- {
132
- searchParams,
133
- },
134
- );
135
-
136
- return {
137
- data: implementationsEnvelope.results.map(
138
- normalizeImplementationMetaToAppItem,
139
- ),
140
- nextCursor: extractCursor(implementationsEnvelope),
141
- };
142
- }, ListAppsSchema);
143
-
144
- // Return flat structure - listApps goes directly to SDK
145
- return {
146
- listApps,
147
- context: {
148
- meta: {
149
- listApps: {
150
- categories: ["app"],
151
- type: "list",
152
- itemType: "App",
153
- inputSchema: ListAppsSchema,
154
- outputSchema: AppItemSchema,
155
- },
156
- },
157
- },
158
- };
159
- };
@@ -1,41 +0,0 @@
1
- import { z } from "zod";
2
- import type { AppItem } from "../../types/domain";
3
- import type { PaginatedSdkFunction } from "../../types/functions";
4
- import type { ZapierApiError, ZapierValidationError } from "../../types/errors";
5
-
6
- // Union of all possible errors for listApps
7
- export type ListAppsError = ZapierApiError | ZapierValidationError;
8
-
9
- // A page of results returned when awaiting listApps
10
- export interface ListAppsPage {
11
- data: AppItem[];
12
- nextCursor?: string;
13
- }
14
-
15
- // Pure Zod schema - no pagination metadata exposed
16
- export const ListAppsSchema = z
17
- .object({
18
- appKeys: z
19
- .array(z.string())
20
- .optional()
21
- .describe(
22
- "Filter apps by app keys (e.g., 'SlackCLIAPI' or slug like 'github')",
23
- ),
24
- search: z.string().optional().describe("Search for apps by name"),
25
- pageSize: z.number().min(1).optional().describe("Number of apps per page"),
26
- maxItems: z
27
- .number()
28
- .min(1)
29
- .optional()
30
- .describe("Maximum total items to return across all pages"),
31
- cursor: z.string().optional().describe("Cursor to start from"),
32
- })
33
- .describe("List all available apps with optional filtering");
34
-
35
- // Type inferred from schema
36
- export type ListAppsOptions = z.infer<typeof ListAppsSchema>;
37
-
38
- // SDK function interface
39
- export interface ListAppsSdkFunction {
40
- listApps: PaginatedSdkFunction<ListAppsOptions | undefined, AppItem>;
41
- }