@zapier/zapier-sdk 0.8.3 → 0.9.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +10 -33
  3. package/dist/index.cjs +346 -219
  4. package/dist/index.d.mts +181 -185
  5. package/dist/index.d.ts +1 -2
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +0 -1
  8. package/dist/index.mjs +343 -218
  9. package/dist/plugins/apps/index.d.ts +4 -0
  10. package/dist/plugins/apps/index.d.ts.map +1 -1
  11. package/dist/plugins/getApp/index.d.ts +2 -7
  12. package/dist/plugins/getApp/index.d.ts.map +1 -1
  13. package/dist/plugins/getApp/index.js +9 -9
  14. package/dist/plugins/getApp/index.test.js +1 -1
  15. package/dist/plugins/getAuthentication/index.test.js +1 -1
  16. package/dist/plugins/listActions/index.d.ts +2 -4
  17. package/dist/plugins/listActions/index.d.ts.map +1 -1
  18. package/dist/plugins/listActions/index.js +1 -1
  19. package/dist/plugins/listActions/index.test.js +4 -4
  20. package/dist/plugins/listApps/index.d.ts +4 -7
  21. package/dist/plugins/listApps/index.d.ts.map +1 -1
  22. package/dist/plugins/listApps/index.js +33 -17
  23. package/dist/plugins/listApps/index.test.js +22 -2
  24. package/dist/plugins/listAuthentications/index.d.ts +2 -4
  25. package/dist/plugins/listAuthentications/index.d.ts.map +1 -1
  26. package/dist/plugins/listAuthentications/index.js +4 -0
  27. package/dist/plugins/listAuthentications/index.test.js +39 -13
  28. package/dist/plugins/listAuthentications/schemas.d.ts +3 -0
  29. package/dist/plugins/listAuthentications/schemas.d.ts.map +1 -1
  30. package/dist/plugins/listAuthentications/schemas.js +4 -0
  31. package/dist/plugins/manifest/index.d.ts +25 -9
  32. package/dist/plugins/manifest/index.d.ts.map +1 -1
  33. package/dist/plugins/manifest/index.js +239 -67
  34. package/dist/plugins/manifest/index.test.js +426 -171
  35. package/dist/plugins/manifest/schemas.d.ts +5 -1
  36. package/dist/plugins/manifest/schemas.d.ts.map +1 -1
  37. package/dist/plugins/manifest/schemas.js +1 -0
  38. package/dist/sdk.d.ts +5 -11
  39. package/dist/sdk.d.ts.map +1 -1
  40. package/dist/sdk.js +1 -4
  41. package/dist/types/plugin.d.ts +1 -0
  42. package/dist/types/plugin.d.ts.map +1 -1
  43. package/dist/types/sdk.d.ts +6 -3
  44. package/dist/types/sdk.d.ts.map +1 -1
  45. package/dist/utils/domain-utils.d.ts +16 -0
  46. package/dist/utils/domain-utils.d.ts.map +1 -1
  47. package/dist/utils/domain-utils.js +46 -27
  48. package/dist/utils/domain-utils.test.js +157 -3
  49. package/dist/utils/file-utils.d.ts +4 -0
  50. package/dist/utils/file-utils.d.ts.map +1 -0
  51. package/dist/utils/file-utils.js +74 -0
  52. package/dist/utils/file-utils.test.d.ts +2 -0
  53. package/dist/utils/file-utils.test.d.ts.map +1 -0
  54. package/dist/utils/file-utils.test.js +51 -0
  55. package/package.json +1 -1
  56. package/src/index.ts +1 -1
  57. package/src/plugins/apps/index.ts +9 -2
  58. package/src/plugins/getApp/index.test.ts +1 -1
  59. package/src/plugins/getApp/index.ts +12 -14
  60. package/src/plugins/getAuthentication/index.test.ts +1 -1
  61. package/src/plugins/listActions/index.test.ts +8 -7
  62. package/src/plugins/listActions/index.ts +3 -3
  63. package/src/plugins/listApps/index.test.ts +23 -2
  64. package/src/plugins/listApps/index.ts +46 -25
  65. package/src/plugins/listAuthentications/index.test.ts +52 -15
  66. package/src/plugins/listAuthentications/index.ts +7 -2
  67. package/src/plugins/listAuthentications/schemas.ts +4 -0
  68. package/src/plugins/manifest/index.test.ts +503 -197
  69. package/src/plugins/manifest/index.ts +338 -82
  70. package/src/plugins/manifest/schemas.ts +9 -2
  71. package/src/sdk.ts +1 -5
  72. package/src/types/plugin.ts +3 -0
  73. package/src/types/sdk.ts +26 -21
  74. package/src/utils/domain-utils.test.ts +196 -2
  75. package/src/utils/domain-utils.ts +68 -35
  76. package/src/utils/file-utils.test.ts +73 -0
  77. package/src/utils/file-utils.ts +94 -0
  78. package/tsconfig.tsbuildinfo +1 -1
  79. package/dist/plugins/lockVersion/index.d.ts +0 -24
  80. package/dist/plugins/lockVersion/index.d.ts.map +0 -1
  81. package/dist/plugins/lockVersion/index.js +0 -72
  82. package/dist/plugins/lockVersion/index.test.d.ts +0 -2
  83. package/dist/plugins/lockVersion/index.test.d.ts.map +0 -1
  84. package/dist/plugins/lockVersion/index.test.js +0 -129
  85. package/dist/plugins/lockVersion/schemas.d.ts +0 -10
  86. package/dist/plugins/lockVersion/schemas.d.ts.map +0 -1
  87. package/dist/plugins/lockVersion/schemas.js +0 -6
  88. package/src/plugins/lockVersion/index.test.ts +0 -176
  89. package/src/plugins/lockVersion/index.ts +0 -112
  90. package/src/plugins/lockVersion/schemas.ts +0 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zapier/zapier-sdk",
3
- "version": "0.8.3",
3
+ "version": "0.9.0",
4
4
  "description": "Complete Zapier SDK - combines all Zapier SDK packages",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
package/src/index.ts CHANGED
@@ -17,7 +17,6 @@ export * from "./plugins/findUniqueAuthentication";
17
17
  export * from "./plugins/runAction";
18
18
  export * from "./plugins/request";
19
19
  export * from "./plugins/manifest";
20
- export * from "./plugins/lockVersion";
21
20
  export * from "./plugins/getProfile";
22
21
  export * from "./plugins/api";
23
22
 
@@ -74,6 +73,7 @@ export type {
74
73
  PluginDependencies,
75
74
  PluginOptions,
76
75
  GetSdkType,
76
+ GetContextType,
77
77
  Sdk,
78
78
  } from "./types/plugin";
79
79
 
@@ -1,5 +1,4 @@
1
- import type { ActionExecutionOptions } from "./types";
2
- import type { ActionProxy } from "./types";
1
+ import type { ActionExecutionOptions, ActionProxy } from "./types";
3
2
  import { ZapierValidationError } from "../../types/errors";
4
3
  import type { Plugin, GetSdkType } from "../../types/plugin";
5
4
  import type { FetchPluginProvides } from "../fetch/index";
@@ -173,3 +172,11 @@ export const appsPlugin: Plugin<
173
172
  apps: createAppsProxy({ sdk }),
174
173
  };
175
174
  };
175
+
176
+ // Export types for use in generated code
177
+ export type { ActionExecutionOptions } from "./types";
178
+ export type { ActionExecutionResult } from "../../api/types";
179
+
180
+ // Interface for generated apps - will be augmented by generated .d.ts files
181
+ // This interface will contain only the specifically typed apps
182
+ export interface ZapierSdkApps {}
@@ -12,8 +12,8 @@ import { manifestPlugin } from "../manifest";
12
12
  function createTestSdk() {
13
13
  return createSdk()
14
14
  .addPlugin(apiPlugin, { fetch: global.fetch })
15
- .addPlugin(listAppsPlugin)
16
15
  .addPlugin(manifestPlugin)
16
+ .addPlugin(listAppsPlugin)
17
17
  .addPlugin(getAppPlugin);
18
18
  }
19
19
 
@@ -5,8 +5,7 @@ import type { GetAppOptions } from "./schemas";
5
5
  import type { AppItem } from "../../types/domain";
6
6
  import { ZapierAppNotFoundError } from "../../types/errors";
7
7
  import type { GetSdkType } from "../../types/plugin";
8
- import type { GetImplementation } from "../manifest/schemas";
9
- import type { ManifestPluginProvides } from "../manifest";
8
+ import type { ListAppsPluginProvides } from "../listApps";
10
9
 
11
10
  // GetApp plugin provides interface - getApp goes directly to SDK root
12
11
  export interface GetAppPluginProvides {
@@ -22,21 +21,20 @@ export interface GetAppPluginProvides {
22
21
 
23
22
  // GetApp plugin depends on listApps SDK function
24
23
  export const getAppPlugin: Plugin<
25
- GetSdkType<ManifestPluginProvides>, // depends on manifest plugin with getImplementation in context
26
- { getImplementation: GetImplementation }, //
24
+ GetSdkType<ListAppsPluginProvides>,
25
+ {},
27
26
  GetAppPluginProvides
28
- > = ({ context }) => {
27
+ > = ({ sdk }) => {
29
28
  const getApp = createFunction(async function getApp(options: GetAppOptions) {
30
- const app = await context.getImplementation(options.appKey);
31
- if (!app) {
32
- throw new ZapierAppNotFoundError("App not found", {
33
- appKey: options.appKey,
34
- });
29
+ const appsIterator = sdk.listApps({ appKeys: [options.appKey] }).items();
30
+ for await (const app of appsIterator) {
31
+ return {
32
+ data: app,
33
+ };
35
34
  }
36
-
37
- return {
38
- data: app,
39
- };
35
+ throw new ZapierAppNotFoundError("App not found", {
36
+ appKey: options.appKey,
37
+ });
40
38
  }, GetAppSchema);
41
39
 
42
40
  // Return flat structure - getApp goes directly to SDK
@@ -45,8 +45,8 @@ describe("getAuthentication plugin", () => {
45
45
  function createTestSdk() {
46
46
  return createSdk()
47
47
  .addPlugin(apiPlugin)
48
- .addPlugin(listAppsPlugin)
49
48
  .addPlugin(manifestPlugin)
49
+ .addPlugin(listAppsPlugin)
50
50
  .addPlugin(getAuthenticationPlugin);
51
51
  }
52
52
 
@@ -68,6 +68,8 @@ describe("listActions plugin", () => {
68
68
  .mockResolvedValue("SlackCLIAPI@1.21.1");
69
69
  });
70
70
 
71
+ const mockResolveAppKeys = vi.fn().mockResolvedValue([]);
72
+
71
73
  function createTestSdk() {
72
74
  // Create a proper plugin chain with context dependencies
73
75
 
@@ -76,18 +78,17 @@ describe("listActions plugin", () => {
76
78
  .addPlugin(() => ({
77
79
  context: {
78
80
  api: mockApiClient,
79
- getVersionedImplementationId: mockGetVersionedImplementationId,
80
81
  },
81
82
  }))
82
- .addPlugin(listAppsPlugin)
83
83
  .addPlugin(() => ({
84
84
  context: {
85
85
  manifest: null,
86
- getManifestEntry: () => null,
87
86
  getVersionedImplementationId: mockGetVersionedImplementationId,
88
- getImplementation: () => Promise.resolve(null),
87
+ resolveAppKeys: mockResolveAppKeys,
88
+ updateManifestEntry: vi.fn().mockResolvedValue(["test-key", {}]),
89
89
  },
90
90
  }))
91
+ .addPlugin(listAppsPlugin)
91
92
  .addPlugin(listActionsPlugin);
92
93
  }
93
94
 
@@ -166,7 +167,7 @@ describe("listActions plugin", () => {
166
167
 
167
168
  expect(result.data).toHaveLength(2); // Only write actions
168
169
  expect(
169
- result.data.every((action) => action.action_type === "write"),
170
+ result.data.every((action: any) => action.action_type === "write"),
170
171
  ).toBe(true);
171
172
  });
172
173
  });
@@ -309,9 +310,9 @@ describe("listActions plugin", () => {
309
310
 
310
311
  expect(result.data).toHaveLength(2);
311
312
  expect(
312
- result.data.every((action) => action.action_type === "write"),
313
+ result.data.every((action: any) => action.action_type === "write"),
313
314
  ).toBe(true);
314
- expect(result.data.map((action) => action.key)).toEqual([
315
+ expect(result.data.map((action: any) => action.key)).toEqual([
315
316
  "send_message",
316
317
  "create_channel",
317
318
  ]);
@@ -32,11 +32,11 @@ export interface ListActionsPluginProvides {
32
32
  }
33
33
 
34
34
  export const listActionsPlugin: Plugin<
35
- GetSdkType<ManifestPluginProvides>, // requires getApp in SDK
35
+ GetSdkType<ManifestPluginProvides>,
36
36
  {
37
37
  api: ApiClient;
38
38
  getVersionedImplementationId: GetVersionedImplementationId;
39
- }, // requires api and getVersionedImplementationId in context
39
+ },
40
40
  ListActionsPluginProvides
41
41
  > = ({ context }) => {
42
42
  const listActions = createPaginatedFunction(async function listActionsPage(
@@ -44,7 +44,7 @@ export const listActionsPlugin: Plugin<
44
44
  ): Promise<ListActionsPage> {
45
45
  const { api, getVersionedImplementationId } = context;
46
46
 
47
- // Use the getApp function from the SDK (dependency injection)
47
+ // Use getVersionedImplementationId (optimized to check manifest first)
48
48
  const selectedApi = await getVersionedImplementationId(options.appKey);
49
49
 
50
50
  if (!selectedApi) {
@@ -28,9 +28,26 @@ const mockAppsResponse = {
28
28
  },
29
29
  };
30
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
+
31
43
  function createTestSdk() {
32
44
  return createSdk()
33
45
  .addPlugin(apiPlugin, { fetch: global.fetch })
46
+ .addPlugin(() => ({
47
+ context: {
48
+ resolveAppKeys: mockResolveAppKeys,
49
+ },
50
+ }))
34
51
  .addPlugin(listAppsPlugin as any);
35
52
  }
36
53
 
@@ -100,7 +117,11 @@ describe("listApps plugin", () => {
100
117
  expect((context.api as any).get).toHaveBeenCalledWith(
101
118
  "/api/v4/implementations-meta/lookup/",
102
119
  {
103
- searchParams: { latest_only: "true", limit: "100" },
120
+ searchParams: {
121
+ latest_only: "true",
122
+ limit: "100",
123
+ selected_apis: "",
124
+ },
104
125
  },
105
126
  );
106
127
  });
@@ -338,7 +359,7 @@ describe("listApps plugin", () => {
338
359
  expect.stringContaining("implementations-meta"),
339
360
  expect.objectContaining({
340
361
  searchParams: expect.objectContaining({
341
- selected_apis: "SlackCLIAPI,GitHubCLIAPI",
362
+ selected_apis: "SlackCLIAPI@latest,GitHubCLIAPI@latest",
342
363
  }),
343
364
  }),
344
365
  );
@@ -1,16 +1,19 @@
1
- import type { Plugin } from "../../types/plugin";
2
- import type { ApiClient } from "../../api/types";
1
+ import type { GetContextType, Plugin } from "../../types/plugin";
3
2
  import { createPaginatedFunction } from "../../utils/function-utils";
4
3
  import { ListAppsSchema } from "./schemas";
5
4
  import type { ListAppsOptions, ListAppsPage } from "./schemas";
6
5
  import type { AppItem } from "../../types/domain";
6
+ import type { ResolvedAppLocator } from "../../utils/domain-utils";
7
7
  import {
8
- groupAppKeysByType,
9
8
  normalizeImplementationMetaToAppItem,
10
9
  splitVersionedKey,
10
+ toAppLocator,
11
+ toImplementationId,
11
12
  } from "../../utils/domain-utils";
12
13
  import { extractCursor } from "../../utils/function-utils";
13
14
  import type { ImplementationsMetaResponse } from "../../api/types";
15
+ import type { ManifestPluginProvides } from "../manifest";
16
+ import type { ApiPluginProvides } from "../api";
14
17
  // ListApps plugin provides interface - listApps goes directly to SDK root
15
18
  export interface ListAppsPluginProvides {
16
19
  listApps: (options?: ListAppsOptions) => Promise<{ data: AppItem[] }> &
@@ -26,10 +29,9 @@ export interface ListAppsPluginProvides {
26
29
  };
27
30
  }
28
31
 
29
- // Direct plugin function - takes options + sdk + context in one object
30
32
  export const listAppsPlugin: Plugin<
31
- {}, // no SDK dependencies
32
- { api: ApiClient }, // requires api in context
33
+ {},
34
+ GetContextType<ApiPluginProvides & ManifestPluginProvides>,
33
35
  ListAppsPluginProvides
34
36
  > = ({ context }) => {
35
37
  const listApps = createPaginatedFunction(async function listAppsPage(
@@ -38,9 +40,28 @@ export const listAppsPlugin: Plugin<
38
40
  const api = context.api;
39
41
  const opts = options;
40
42
 
41
- const appKeys = [...(opts.appKeys ?? [])].map(
42
- (key) => splitVersionedKey(key)[0],
43
- );
43
+ const appLocators = await context.resolveAppKeys({
44
+ appKeys: [...(opts.appKeys ?? [])],
45
+ });
46
+ const implementationNameToLocator: Record<string, ResolvedAppLocator[]> =
47
+ {};
48
+ for (const locator of appLocators) {
49
+ implementationNameToLocator[locator.implementationName] = [
50
+ ...(implementationNameToLocator[locator.implementationName] ?? []),
51
+ locator,
52
+ ];
53
+ }
54
+ const duplicatedLookupAppKeys = Object.keys(implementationNameToLocator)
55
+ .filter((key) => implementationNameToLocator[key].length > 1)
56
+ .map((key) => implementationNameToLocator[key])
57
+ .flat()
58
+ .map((locator) => locator.lookupAppKey);
59
+
60
+ if (duplicatedLookupAppKeys.length > 0) {
61
+ throw new Error(
62
+ `Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`,
63
+ );
64
+ }
44
65
 
45
66
  if (opts.search) {
46
67
  const searchParams: Record<string, string> = {};
@@ -58,12 +79,18 @@ export const listAppsPlugin: Plugin<
58
79
  normalizeImplementationMetaToAppItem,
59
80
  );
60
81
 
61
- const appKeysSet = new Set(appKeys);
82
+ const implementationNameSet = new Set<string>(
83
+ appLocators.map((locator) => locator.implementationName),
84
+ );
62
85
 
63
86
  for (const implementation of implementations) {
64
- if (!appKeysSet.has(implementation.key)) {
65
- appKeysSet.add(implementation.key);
66
- appKeys.push(implementation.key);
87
+ const [implementationName] = splitVersionedKey(implementation.key);
88
+ if (!implementationNameSet.has(implementationName)) {
89
+ implementationNameSet.add(implementationName);
90
+ appLocators.push({
91
+ ...toAppLocator(implementation.key),
92
+ implementationName,
93
+ });
67
94
  }
68
95
  }
69
96
  }
@@ -74,23 +101,17 @@ export const listAppsPlugin: Plugin<
74
101
  searchParams.limit = opts.pageSize.toString();
75
102
  }
76
103
 
77
- searchParams.latest_only = "true";
104
+ if (appLocators.length === 0) {
105
+ searchParams.latest_only = "true";
106
+ }
78
107
 
79
108
  if (opts.cursor) {
80
109
  searchParams.offset = opts.cursor;
81
110
  }
82
111
 
83
- if (appKeys.length > 0) {
84
- const groupedAppKeys = groupAppKeysByType(appKeys);
85
-
86
- if (groupedAppKeys.selectedApi.length > 0) {
87
- searchParams.selected_apis = groupedAppKeys.selectedApi.join(",");
88
- }
89
-
90
- if (groupedAppKeys.slug.length > 0) {
91
- searchParams.slugs = groupedAppKeys.slug.join(",");
92
- }
93
- }
112
+ searchParams.selected_apis = appLocators
113
+ .map((locator) => toImplementationId(locator))
114
+ .join(",");
94
115
 
95
116
  const implementationsEnvelope: ImplementationsMetaResponse = await api.get(
96
117
  "/api/v4/implementations-meta/lookup/",
@@ -6,7 +6,6 @@ import {
6
6
  import { listAuthenticationsPlugin } from "./index";
7
7
  import { createSdk } from "../../sdk";
8
8
  import type { ApiClient } from "../../api";
9
- import type { AppItem } from "../../types/domain";
10
9
 
11
10
  const mockAuthenticationsResponse = {
12
11
  results: [
@@ -42,15 +41,6 @@ const mockAuthenticationsResponse = {
42
41
  previous: null,
43
42
  };
44
43
 
45
- const mockSlackApp: AppItem = {
46
- title: "Slack",
47
- key: "SlackCLIAPI",
48
- current_implementation_id: "SlackCLIAPI@1.21.1",
49
- version: "1.21.1",
50
- description: "Team communication platform",
51
- slug: "slack",
52
- };
53
-
54
44
  describe("listAuthentications plugin", () => {
55
45
  let mockApiClient: ApiClient;
56
46
  let mockGetVersionedImplementationId: any;
@@ -72,15 +62,14 @@ describe("listAuthentications plugin", () => {
72
62
  },
73
63
  });
74
64
 
65
+ const mockResolveAppKeys = vi.fn().mockResolvedValue([]);
66
+
75
67
  const manifestPlugin = () => ({
76
68
  context: {
77
69
  manifest: null,
78
70
  getVersionedImplementationId: mockGetVersionedImplementationId,
79
- getManifestEntry: () => ({
80
- implementationName: "SlackCLIAPI",
81
- version: "1.21.1",
82
- }),
83
- getImplementation: vi.fn().mockResolvedValue(mockSlackApp),
71
+ resolveAppKeys: mockResolveAppKeys,
72
+ updateManifestEntry: vi.fn().mockResolvedValue(["test-key", {}]),
84
73
  },
85
74
  });
86
75
 
@@ -152,6 +141,21 @@ describe("listAuthentications plugin", () => {
152
141
  }).toThrow(ZapierValidationError);
153
142
  });
154
143
 
144
+ it("should throw validation error for invalid authenticationIds type", () => {
145
+ const sdk = createTestSdk();
146
+ expect(() => {
147
+ sdk.listAuthentications({
148
+ authenticationIds: "123" as any, // Should be array of strings
149
+ });
150
+ }).toThrow(ZapierValidationError);
151
+
152
+ expect(() => {
153
+ sdk.listAuthentications({
154
+ authenticationIds: [123] as any, // Should be array of strings, not numbers
155
+ });
156
+ }).toThrow(ZapierValidationError);
157
+ });
158
+
155
159
  it("should throw validation error for invalid pageSize", () => {
156
160
  const sdk = createTestSdk();
157
161
  expect(() => {
@@ -186,6 +190,7 @@ describe("listAuthentications plugin", () => {
186
190
  const sdk = createTestSdk();
187
191
  const result = await sdk.listAuthentications({
188
192
  appKey: "slack",
193
+ authenticationIds: ["123", "456"],
189
194
  search: "workspace",
190
195
  title: "My Slack Workspace",
191
196
  accountId: "acc_123",
@@ -336,6 +341,38 @@ describe("listAuthentications plugin", () => {
336
341
  }),
337
342
  );
338
343
  });
344
+
345
+ it("should pass authenticationIds as ids parameter to API", async () => {
346
+ const sdk = createTestSdk();
347
+ await sdk.listAuthentications({
348
+ authenticationIds: ["123", "456", "789"],
349
+ });
350
+
351
+ expect(mockApiClient.get).toHaveBeenCalledWith(
352
+ "/api/v4/authentications/",
353
+ expect.objectContaining({
354
+ searchParams: expect.objectContaining({
355
+ ids: "123,456,789",
356
+ }),
357
+ }),
358
+ );
359
+ });
360
+
361
+ it("should not include ids parameter when authenticationIds is empty", async () => {
362
+ const sdk = createTestSdk();
363
+ await sdk.listAuthentications({
364
+ authenticationIds: [],
365
+ });
366
+
367
+ expect(mockApiClient.get).toHaveBeenCalledWith(
368
+ "/api/v4/authentications/",
369
+ expect.objectContaining({
370
+ searchParams: expect.not.objectContaining({
371
+ ids: expect.anything(),
372
+ }),
373
+ }),
374
+ );
375
+ });
339
376
  });
340
377
 
341
378
  describe("pagination", () => {
@@ -36,11 +36,11 @@ export interface ListAuthenticationsPluginProvides {
36
36
  }
37
37
 
38
38
  export const listAuthenticationsPlugin: Plugin<
39
- GetSdkType<ManifestPluginProvides>, // requires getApp in SDK
39
+ GetSdkType<ManifestPluginProvides>,
40
40
  {
41
41
  api: ApiClient;
42
42
  getVersionedImplementationId: GetVersionedImplementationId;
43
- }, // requires api in context
43
+ },
44
44
  ListAuthenticationsPluginProvides
45
45
  > = ({ context }) => {
46
46
  const listAuthentications = createPaginatedFunction(
@@ -64,6 +64,11 @@ export const listAuthenticationsPlugin: Plugin<
64
64
  }
65
65
  }
66
66
 
67
+ // Add authenticationIds as ids parameter if provided
68
+ if (options.authenticationIds && options.authenticationIds.length > 0) {
69
+ searchParams.ids = options.authenticationIds.join(",");
70
+ }
71
+
67
72
  // Add other query parameters if provided
68
73
  // Use title as search if no explicit search provided
69
74
  if (options.search) {
@@ -16,6 +16,10 @@ export const ListAuthenticationsSchema = z
16
16
  appKey: AppKeyPropertySchema.optional().describe(
17
17
  "App key of authentications to list (e.g., 'SlackCLIAPI')",
18
18
  ),
19
+ authenticationIds: z
20
+ .array(z.string())
21
+ .optional()
22
+ .describe("List of authentication IDs to filter by"),
19
23
  search: z
20
24
  .string()
21
25
  .optional()