@zapier/zapier-sdk 0.15.0 → 0.15.2

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 (70) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +28 -0
  3. package/dist/api/client.d.ts.map +1 -1
  4. package/dist/api/client.integration.test.d.ts +5 -0
  5. package/dist/api/client.integration.test.d.ts.map +1 -0
  6. package/dist/api/client.integration.test.js +318 -0
  7. package/dist/api/client.js +31 -1
  8. package/dist/api/schemas.d.ts +3 -0
  9. package/dist/api/schemas.d.ts.map +1 -1
  10. package/dist/api/schemas.js +1 -0
  11. package/dist/index.cjs +386 -106
  12. package/dist/index.d.mts +290 -33
  13. package/dist/index.mjs +386 -106
  14. package/dist/plugins/getApp/index.test.js +17 -21
  15. package/dist/plugins/getInputFieldsSchema/index.d.ts +22 -0
  16. package/dist/plugins/getInputFieldsSchema/index.d.ts.map +1 -0
  17. package/dist/plugins/getInputFieldsSchema/index.js +51 -0
  18. package/dist/plugins/getInputFieldsSchema/index.test.d.ts +2 -0
  19. package/dist/plugins/getInputFieldsSchema/index.test.d.ts.map +1 -0
  20. package/dist/plugins/getInputFieldsSchema/index.test.js +288 -0
  21. package/dist/plugins/getInputFieldsSchema/schemas.d.ts +31 -0
  22. package/dist/plugins/getInputFieldsSchema/schemas.d.ts.map +1 -0
  23. package/dist/plugins/getInputFieldsSchema/schemas.js +13 -0
  24. package/dist/plugins/listActions/schemas.d.ts +4 -4
  25. package/dist/plugins/listApps/index.d.ts +1 -3
  26. package/dist/plugins/listApps/index.d.ts.map +1 -1
  27. package/dist/plugins/listApps/index.js +18 -44
  28. package/dist/plugins/listApps/index.test.js +89 -288
  29. package/dist/plugins/listApps/schemas.d.ts +19 -26
  30. package/dist/plugins/listApps/schemas.d.ts.map +1 -1
  31. package/dist/plugins/listApps/schemas.js +19 -18
  32. package/dist/plugins/listAuthentications/schemas.d.ts +4 -4
  33. package/dist/plugins/listInputFieldChoices/schemas.d.ts +4 -4
  34. package/dist/plugins/listInputFields/index.d.ts.map +1 -1
  35. package/dist/plugins/listInputFields/index.js +2 -0
  36. package/dist/plugins/listInputFields/schemas.d.ts +4 -4
  37. package/dist/plugins/runAction/schemas.d.ts +4 -4
  38. package/dist/sdk.d.ts +8 -2
  39. package/dist/sdk.d.ts.map +1 -1
  40. package/dist/sdk.js +2 -0
  41. package/dist/temporary-internal-core/handlers/listApps.d.ts +67 -0
  42. package/dist/temporary-internal-core/handlers/listApps.d.ts.map +1 -0
  43. package/dist/temporary-internal-core/handlers/listApps.js +121 -0
  44. package/dist/temporary-internal-core/handlers/listApps.test.d.ts +2 -0
  45. package/dist/temporary-internal-core/handlers/listApps.test.d.ts.map +1 -0
  46. package/dist/temporary-internal-core/handlers/listApps.test.js +328 -0
  47. package/dist/temporary-internal-core/index.d.ts +18 -0
  48. package/dist/temporary-internal-core/index.d.ts.map +1 -0
  49. package/dist/temporary-internal-core/index.js +18 -0
  50. package/dist/temporary-internal-core/schemas/apps/index.d.ts +582 -0
  51. package/dist/temporary-internal-core/schemas/apps/index.d.ts.map +1 -0
  52. package/dist/temporary-internal-core/schemas/apps/index.js +95 -0
  53. package/dist/temporary-internal-core/schemas/implementations/index.d.ts +511 -0
  54. package/dist/temporary-internal-core/schemas/implementations/index.d.ts.map +1 -0
  55. package/dist/temporary-internal-core/schemas/implementations/index.js +79 -0
  56. package/dist/temporary-internal-core/types/handler.d.ts +51 -0
  57. package/dist/temporary-internal-core/types/handler.d.ts.map +1 -0
  58. package/dist/temporary-internal-core/types/handler.js +8 -0
  59. package/dist/temporary-internal-core/types/index.d.ts +5 -0
  60. package/dist/temporary-internal-core/types/index.d.ts.map +1 -0
  61. package/dist/temporary-internal-core/types/index.js +4 -0
  62. package/dist/temporary-internal-core/utils/app-locators.d.ts +54 -0
  63. package/dist/temporary-internal-core/utils/app-locators.d.ts.map +1 -0
  64. package/dist/temporary-internal-core/utils/app-locators.js +83 -0
  65. package/dist/temporary-internal-core/utils/transformations.d.ts +18 -0
  66. package/dist/temporary-internal-core/utils/transformations.d.ts.map +1 -0
  67. package/dist/temporary-internal-core/utils/transformations.js +36 -0
  68. package/dist/types/sdk.d.ts +2 -1
  69. package/dist/types/sdk.d.ts.map +1 -1
  70. package/package.json +1 -1
@@ -39,7 +39,7 @@ describe("getApp plugin", () => {
39
39
  // Mock the API client to handle both resolveAppKeys and listApps calls
40
40
  context.api.get = vi
41
41
  .fn()
42
- // First call: resolveAppKeys may call to resolve slug to implementation name
42
+ // First call: resolveAppKeys calls listAppsForSlugsPage which expects raw API format
43
43
  .mockResolvedValueOnce({
44
44
  results: [
45
45
  {
@@ -49,27 +49,25 @@ describe("getApp plugin", () => {
49
49
  primary_color: "#4A154B",
50
50
  categories: ["communication"],
51
51
  slug: "slack",
52
- key: "SlackCLIAPI",
53
- version: "1.0.0",
54
52
  },
55
53
  ],
56
54
  next: null,
57
55
  })
58
- // Second call: listApps main API call
56
+ // Second call: listApps goes through handler which returns transformed format
59
57
  .mockResolvedValueOnce({
60
- results: [
58
+ data: [
61
59
  {
62
- id: "SlackCLIAPI@1.0.0",
63
- name: "Slack",
60
+ title: "Slack",
61
+ key: "SlackCLIAPI",
62
+ implementation_id: "SlackCLIAPI@1.0.0",
64
63
  description: "Team communication",
65
64
  primary_color: "#4A154B",
66
65
  categories: ["communication"],
67
66
  slug: "slack",
68
- key: "SlackCLIAPI",
69
67
  version: "1.0.0",
70
68
  },
71
69
  ],
72
- next: null,
70
+ nextCursor: undefined,
73
71
  });
74
72
  const result = await sdk.getApp({
75
73
  appKey: "slack",
@@ -92,10 +90,10 @@ describe("getApp plugin", () => {
92
90
  results: [],
93
91
  next: null,
94
92
  })
95
- // Second call: listApps main API call
93
+ // Second call: listApps main API call (returns transformed format)
96
94
  .mockResolvedValueOnce({
97
- results: [],
98
- next: null,
95
+ data: [],
96
+ nextCursor: undefined,
99
97
  });
100
98
  await expect(sdk.getApp({
101
99
  appKey: "nonexistent-app",
@@ -109,7 +107,7 @@ describe("getApp plugin", () => {
109
107
  // Mock the API client to handle both resolveAppKeys and listApps calls
110
108
  context.api.get = vi
111
109
  .fn()
112
- // First call: resolveAppKeys may call to resolve slug to implementation name
110
+ // First call: resolveAppKeys calls listAppsForSlugsPage which expects raw API format
113
111
  .mockResolvedValueOnce({
114
112
  results: [
115
113
  {
@@ -119,27 +117,25 @@ describe("getApp plugin", () => {
119
117
  primary_color: "#FF0000",
120
118
  categories: ["testing"],
121
119
  slug: "test",
122
- key: "TestCLIAPI",
123
- version: "1.0.0",
124
120
  },
125
121
  ],
126
122
  next: null,
127
123
  })
128
- // Second call: listApps main API call
124
+ // Second call: listApps goes through handler which returns transformed format
129
125
  .mockResolvedValueOnce({
130
- results: [
126
+ data: [
131
127
  {
132
- id: "TestCLIAPI@1.0.0",
133
- name: "Test App",
128
+ title: "Test App",
129
+ key: "TestCLIAPI",
130
+ implementation_id: "TestCLIAPI@1.0.0",
134
131
  description: "Test description",
135
132
  primary_color: "#FF0000",
136
133
  categories: ["testing"],
137
134
  slug: "test",
138
- key: "TestCLIAPI",
139
135
  version: "1.0.0",
140
136
  },
141
137
  ],
142
- next: null,
138
+ nextCursor: undefined,
143
139
  });
144
140
  const result = await sdk.getApp({
145
141
  appKey: "test",
@@ -0,0 +1,22 @@
1
+ import type { Plugin, GetSdkType } from "../../types/plugin";
2
+ import type { ApiClient } from "../../api";
3
+ import { GetInputFieldsSchemaSchema, type GetInputFieldsSchemaOptions as GetInputFieldsSchemaOptions } from "./schemas";
4
+ import type { GetActionPluginProvides } from "../getAction";
5
+ import type { GetVersionedImplementationId } from "../manifest/schemas";
6
+ export interface GetInputFieldsSchemaPluginProvides {
7
+ getInputFieldsSchema: (options: GetInputFieldsSchemaOptions) => Promise<{
8
+ data: Record<string, unknown>;
9
+ }>;
10
+ context: {
11
+ meta: {
12
+ getInputFieldsSchema: {
13
+ inputSchema: typeof GetInputFieldsSchemaSchema;
14
+ };
15
+ };
16
+ };
17
+ }
18
+ export declare const getInputFieldsSchemaPlugin: Plugin<GetSdkType<GetActionPluginProvides>, {
19
+ api: ApiClient;
20
+ getVersionedImplementationId: GetVersionedImplementationId;
21
+ }, GetInputFieldsSchemaPluginProvides>;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/getInputFieldsSchema/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACL,0BAA0B,EAC1B,KAAK,2BAA2B,IAAI,2BAA2B,EAChE,MAAM,WAAW,CAAC;AAGnB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAUxE,MAAM,WAAW,kCAAkC;IACjD,oBAAoB,EAAE,CACpB,OAAO,EAAE,2BAA2B,KACjC,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAChD,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,oBAAoB,EAAE;gBACpB,WAAW,EAAE,OAAO,0BAA0B,CAAC;aAChD,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAC7C,UAAU,CAAC,uBAAuB,CAAC,EACnC;IACE,GAAG,EAAE,SAAS,CAAC;IACf,4BAA4B,EAAE,4BAA4B,CAAC;CAC5D,EACD,kCAAkC,CAmEnC,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { GetInputFieldsSchemaSchema, } from "./schemas";
2
+ import { ZapierConfigurationError } from "../../types/errors";
3
+ import { createFunction } from "../../utils/function-utils";
4
+ import { appKeyResolver, actionTypeResolver, actionKeyResolver, authenticationIdResolver, inputsAllOptionalResolver, } from "../../resolvers";
5
+ import { fetchImplementationNeeds } from "../../services/implementations";
6
+ export const getInputFieldsSchemaPlugin = ({ sdk, context }) => {
7
+ const getInputFieldsSchema = createFunction(async function getInputFieldsSchema(options) {
8
+ const { api, getVersionedImplementationId } = context;
9
+ const { appKey, actionKey, actionType, authenticationId = null, inputs, } = options;
10
+ const selectedApi = await getVersionedImplementationId(appKey);
11
+ if (!selectedApi) {
12
+ throw new ZapierConfigurationError("No current_implementation_id found for app", { configType: "current_implementation_id" });
13
+ }
14
+ const { data: action } = await sdk.getAction({
15
+ appKey,
16
+ actionType,
17
+ actionKey,
18
+ });
19
+ const needsData = await fetchImplementationNeeds({
20
+ api,
21
+ selectedApi,
22
+ action: action.key,
23
+ actionType,
24
+ authenticationId,
25
+ inputs,
26
+ });
27
+ return {
28
+ data: needsData.schema || {},
29
+ };
30
+ }, GetInputFieldsSchemaSchema);
31
+ return {
32
+ getInputFieldsSchema,
33
+ context: {
34
+ meta: {
35
+ getInputFieldsSchema: {
36
+ categories: ["action"],
37
+ type: "item",
38
+ itemType: "InputSchema",
39
+ inputSchema: GetInputFieldsSchemaSchema,
40
+ resolvers: {
41
+ appKey: appKeyResolver,
42
+ actionType: actionTypeResolver,
43
+ actionKey: actionKeyResolver,
44
+ authenticationId: authenticationIdResolver,
45
+ inputs: inputsAllOptionalResolver,
46
+ },
47
+ },
48
+ },
49
+ },
50
+ };
51
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/plugins/getInputFieldsSchema/index.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,288 @@
1
+ import { describe, it, expect, vi, beforeEach } from "vitest";
2
+ import { ZapierValidationError, ZapierConfigurationError, ZapierApiError, } from "../../types/errors";
3
+ import { getInputFieldsSchemaPlugin } from "./index";
4
+ import { getActionPlugin } from "../getAction";
5
+ import { getAppPlugin } from "../getApp";
6
+ import { listActionsPlugin } from "../listActions";
7
+ import { listAppsPlugin } from "../listApps";
8
+ import { createSdk } from "../../sdk";
9
+ const mockSchema = {
10
+ type: "object",
11
+ properties: {
12
+ message: {
13
+ type: "string",
14
+ title: "Message",
15
+ description: "The message to send",
16
+ },
17
+ channel: {
18
+ type: "string",
19
+ title: "Channel",
20
+ description: "The channel to send to",
21
+ },
22
+ tags: {
23
+ type: "array",
24
+ items: {
25
+ type: "string",
26
+ },
27
+ title: "Tags",
28
+ description: "List of tags",
29
+ },
30
+ },
31
+ required: ["message", "channel"],
32
+ };
33
+ const mockNeedsResponse = {
34
+ success: true,
35
+ needs: [],
36
+ schema: mockSchema,
37
+ };
38
+ const mockActionsResponse = {
39
+ results: [
40
+ {
41
+ slug: "slack",
42
+ selected_api: "slack",
43
+ actions: [
44
+ {
45
+ key: "send_message",
46
+ name: "Send Message",
47
+ description: "Send a message to a channel",
48
+ type_of: "write",
49
+ type: "write",
50
+ id: "core:12345",
51
+ },
52
+ ],
53
+ },
54
+ ],
55
+ meta: {
56
+ next_cursor: null,
57
+ },
58
+ };
59
+ describe("getInputFieldsSchema plugin", () => {
60
+ let mockApiClient;
61
+ let mockGetVersionedImplementationId;
62
+ beforeEach(() => {
63
+ vi.clearAllMocks();
64
+ mockApiClient = {
65
+ get: vi.fn().mockResolvedValue(mockActionsResponse),
66
+ post: vi.fn().mockResolvedValue(mockNeedsResponse),
67
+ };
68
+ mockGetVersionedImplementationId = vi
69
+ .fn()
70
+ .mockResolvedValue("SlackCLIAPI@1.21.1");
71
+ });
72
+ function createTestSdk() {
73
+ return createSdk({}, {}, {
74
+ api: mockApiClient,
75
+ meta: {},
76
+ getVersionedImplementationId: mockGetVersionedImplementationId,
77
+ })
78
+ .addPlugin(listAppsPlugin)
79
+ .addPlugin(listActionsPlugin)
80
+ .addPlugin(getAppPlugin)
81
+ .addPlugin(getActionPlugin)
82
+ .addPlugin(getInputFieldsSchemaPlugin);
83
+ }
84
+ describe("schema validation", () => {
85
+ it("should throw validation error for missing required fields", async () => {
86
+ const sdk = createTestSdk();
87
+ await expect(sdk.getInputFieldsSchema({
88
+ // Missing required fields
89
+ })).rejects.toThrow(ZapierValidationError);
90
+ });
91
+ it("should throw validation error for invalid field types", async () => {
92
+ const sdk = createTestSdk();
93
+ await expect(sdk.getInputFieldsSchema({
94
+ appKey: 123,
95
+ actionType: "write",
96
+ actionKey: "send_message",
97
+ })).rejects.toThrow(ZapierValidationError);
98
+ });
99
+ it("should pass validation with all required fields", async () => {
100
+ const sdk = createTestSdk();
101
+ const result = await sdk.getInputFieldsSchema({
102
+ appKey: "slack",
103
+ actionType: "write",
104
+ actionKey: "send_message",
105
+ });
106
+ expect(result.data).toBeDefined();
107
+ });
108
+ it("should pass validation with optional fields", async () => {
109
+ const sdk = createTestSdk();
110
+ const result = await sdk.getInputFieldsSchema({
111
+ appKey: "slack",
112
+ actionType: "write",
113
+ actionKey: "send_message",
114
+ authenticationId: 123,
115
+ inputs: { channel: "#general" },
116
+ });
117
+ expect(result.data).toBeDefined();
118
+ });
119
+ });
120
+ describe("API integration", () => {
121
+ it("should call the correct API endpoint", async () => {
122
+ const sdk = createTestSdk();
123
+ await sdk.getInputFieldsSchema({
124
+ appKey: "slack",
125
+ actionType: "write",
126
+ actionKey: "send_message",
127
+ });
128
+ expect(mockApiClient.post).toHaveBeenCalledWith("/zapier/api/v4/implementations/needs/", {
129
+ selected_api: "SlackCLIAPI@1.21.1",
130
+ action: "send_message",
131
+ type_of: "write",
132
+ params: {},
133
+ });
134
+ });
135
+ it("should include authentication_id when provided", async () => {
136
+ const sdk = createTestSdk();
137
+ await sdk.getInputFieldsSchema({
138
+ appKey: "slack",
139
+ actionType: "write",
140
+ actionKey: "send_message",
141
+ authenticationId: 123,
142
+ });
143
+ expect(mockApiClient.post).toHaveBeenCalledWith("/zapier/api/v4/implementations/needs/", {
144
+ selected_api: "SlackCLIAPI@1.21.1",
145
+ action: "send_message",
146
+ type_of: "write",
147
+ params: {},
148
+ authentication_id: 123,
149
+ });
150
+ });
151
+ it("should exclude authentication_id when null", async () => {
152
+ const sdk = createTestSdk();
153
+ await sdk.getInputFieldsSchema({
154
+ appKey: "slack",
155
+ actionType: "write",
156
+ actionKey: "send_message",
157
+ authenticationId: null,
158
+ });
159
+ expect(mockApiClient.post).toHaveBeenCalledWith("/zapier/api/v4/implementations/needs/", {
160
+ selected_api: "SlackCLIAPI@1.21.1",
161
+ action: "send_message",
162
+ type_of: "write",
163
+ params: {},
164
+ // No authentication_id
165
+ });
166
+ });
167
+ it("should include inputs when provided", async () => {
168
+ const sdk = createTestSdk();
169
+ const inputs = { channel: "#general", message: "test" };
170
+ await sdk.getInputFieldsSchema({
171
+ appKey: "slack",
172
+ actionType: "write",
173
+ actionKey: "send_message",
174
+ inputs,
175
+ });
176
+ expect(mockApiClient.post).toHaveBeenCalledWith("/zapier/api/v4/implementations/needs/", {
177
+ selected_api: "SlackCLIAPI@1.21.1",
178
+ action: "send_message",
179
+ type_of: "write",
180
+ params: inputs,
181
+ });
182
+ });
183
+ });
184
+ describe("data return", () => {
185
+ it("should return the schema object from the API response", async () => {
186
+ const sdk = createTestSdk();
187
+ const result = await sdk.getInputFieldsSchema({
188
+ appKey: "slack",
189
+ actionType: "write",
190
+ actionKey: "send_message",
191
+ });
192
+ expect(result.data).toEqual(mockSchema);
193
+ });
194
+ it("should return empty object when schema is not present", async () => {
195
+ mockApiClient.post = vi.fn().mockResolvedValue({
196
+ success: true,
197
+ needs: [],
198
+ // No schema field
199
+ });
200
+ const sdk = createTestSdk();
201
+ const result = await sdk.getInputFieldsSchema({
202
+ appKey: "slack",
203
+ actionType: "write",
204
+ actionKey: "send_message",
205
+ });
206
+ expect(result.data).toEqual({});
207
+ });
208
+ it("should handle complex schema structures", async () => {
209
+ const complexSchema = {
210
+ type: "object",
211
+ properties: {
212
+ user: {
213
+ type: "object",
214
+ properties: {
215
+ name: { type: "string" },
216
+ age: { type: "number" },
217
+ },
218
+ required: ["name"],
219
+ },
220
+ tags: {
221
+ type: "array",
222
+ items: { type: "string" },
223
+ },
224
+ },
225
+ required: ["user"],
226
+ };
227
+ mockApiClient.post = vi.fn().mockResolvedValue({
228
+ success: true,
229
+ needs: [],
230
+ schema: complexSchema,
231
+ });
232
+ const sdk = createTestSdk();
233
+ const result = await sdk.getInputFieldsSchema({
234
+ appKey: "slack",
235
+ actionType: "write",
236
+ actionKey: "send_message",
237
+ });
238
+ expect(result.data).toEqual(complexSchema);
239
+ });
240
+ });
241
+ describe("error handling", () => {
242
+ it("should throw ZapierConfigurationError when app has no current_implementation_id", async () => {
243
+ mockGetVersionedImplementationId.mockResolvedValue(null);
244
+ const sdk = createTestSdk();
245
+ await expect(sdk.getInputFieldsSchema({
246
+ appKey: "invalid",
247
+ actionType: "write",
248
+ actionKey: "send_message",
249
+ })).rejects.toThrow(ZapierConfigurationError);
250
+ });
251
+ it("should throw ZapierApiError when API response indicates failure", async () => {
252
+ mockApiClient.post = vi.fn().mockResolvedValue({
253
+ success: false,
254
+ errors: ["Authentication failed", "Invalid credentials"],
255
+ });
256
+ const sdk = createTestSdk();
257
+ await expect(sdk.getInputFieldsSchema({
258
+ appKey: "slack",
259
+ actionType: "write",
260
+ actionKey: "send_message",
261
+ })).rejects.toThrow(ZapierApiError);
262
+ await expect(sdk.getInputFieldsSchema({
263
+ appKey: "slack",
264
+ actionType: "write",
265
+ actionKey: "send_message",
266
+ })).rejects.toThrow("Failed to get input fields: Authentication failed, Invalid credentials");
267
+ });
268
+ it("should handle API errors gracefully", async () => {
269
+ mockApiClient.post = vi
270
+ .fn()
271
+ .mockRejectedValue(new Error("Network error"));
272
+ const sdk = createTestSdk();
273
+ await expect(sdk.getInputFieldsSchema({
274
+ appKey: "slack",
275
+ actionType: "write",
276
+ actionKey: "send_message",
277
+ })).rejects.toThrow("Network error");
278
+ });
279
+ });
280
+ describe("context and metadata", () => {
281
+ it("should provide context with meta information", () => {
282
+ const sdk = createTestSdk();
283
+ const context = sdk.getContext();
284
+ expect(context.meta.getInputFieldsSchema).toBeDefined();
285
+ expect(context.meta.getInputFieldsSchema.inputSchema).toBeDefined();
286
+ });
287
+ });
288
+ });
@@ -0,0 +1,31 @@
1
+ import { z } from "zod";
2
+ import type { ZapierConfigurationError, ZapierApiError, ZapierAuthenticationError, ZapierAppNotFoundError, ZapierValidationError, ZapierUnknownError } from "../../types/errors";
3
+ export declare const GetInputFieldsSchemaSchema: z.ZodObject<{
4
+ appKey: z.ZodString & {
5
+ _def: z.ZodStringDef & import("../..").PositionalMetadata;
6
+ };
7
+ actionType: z.ZodEnum<["read", "read_bulk", "write", "run", "search", "search_or_write", "search_and_write", "filter"]>;
8
+ actionKey: z.ZodString;
9
+ authenticationId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
10
+ inputs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
11
+ }, "strip", z.ZodTypeAny, {
12
+ appKey: string;
13
+ actionType: "search" | "filter" | "read" | "read_bulk" | "run" | "search_and_write" | "search_or_write" | "write";
14
+ actionKey: string;
15
+ authenticationId?: number | null | undefined;
16
+ inputs?: Record<string, unknown> | undefined;
17
+ }, {
18
+ appKey: string;
19
+ actionType: "search" | "filter" | "read" | "read_bulk" | "run" | "search_and_write" | "search_or_write" | "write";
20
+ actionKey: string;
21
+ authenticationId?: number | null | undefined;
22
+ inputs?: Record<string, unknown> | undefined;
23
+ }>;
24
+ export type GetInputFieldsSchemaOptions = z.infer<typeof GetInputFieldsSchemaSchema>;
25
+ export type GetInputFieldsSchemaError = ZapierConfigurationError | ZapierApiError | ZapierAuthenticationError | ZapierAppNotFoundError | ZapierValidationError | ZapierUnknownError;
26
+ export interface GetInputFieldsSchemaSdkFunction {
27
+ getInputFieldsSchema: (options: GetInputFieldsSchemaOptions) => Promise<{
28
+ data: Record<string, unknown>;
29
+ }>;
30
+ }
31
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/plugins/getInputFieldsSchema/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,KAAK,EACV,wBAAwB,EACxB,cAAc,EACd,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAE5B,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;EAsBpC,CAAC;AAEJ,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAC/C,OAAO,0BAA0B,CAClC,CAAC;AAEF,MAAM,MAAM,yBAAyB,GACjC,wBAAwB,GACxB,cAAc,GACd,yBAAyB,GACzB,sBAAsB,GACtB,qBAAqB,GACrB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,+BAA+B;IAC9C,oBAAoB,EAAE,CACpB,OAAO,EAAE,2BAA2B,KACjC,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;CACjD"}
@@ -0,0 +1,13 @@
1
+ import { z } from "zod";
2
+ import { AppKeyPropertySchema, ActionTypePropertySchema, ActionKeyPropertySchema, AuthenticationIdPropertySchema, InputsPropertySchema, } from "../../types/properties";
3
+ export const GetInputFieldsSchemaSchema = z
4
+ .object({
5
+ appKey: AppKeyPropertySchema.describe("App key (e.g., 'SlackCLIAPI' or slug like 'github') to get the input schema for"),
6
+ actionType: ActionTypePropertySchema.describe("Action type that matches the action's defined type"),
7
+ actionKey: ActionKeyPropertySchema.describe("Action key to get the input schema for"),
8
+ authenticationId: AuthenticationIdPropertySchema.nullable()
9
+ .optional()
10
+ .describe("Authentication ID to use when fetching the schema. Required if the action needs authentication to determine available fields."),
11
+ inputs: InputsPropertySchema.optional().describe("Current input values that may affect the schema (e.g., when fields depend on other field values)"),
12
+ })
13
+ .describe("Get the JSON Schema representation of input fields for an action. Returns a JSON Schema object describing the structure, types, and validation rules for the action's input parameters.");
@@ -12,15 +12,15 @@ export declare const ListActionsSchema: z.ZodObject<{
12
12
  cursor: z.ZodOptional<z.ZodString>;
13
13
  }, "strip", z.ZodTypeAny, {
14
14
  appKey: string;
15
- cursor?: string | undefined;
16
- maxItems?: number | undefined;
17
15
  pageSize?: number | undefined;
16
+ maxItems?: number | undefined;
17
+ cursor?: string | undefined;
18
18
  actionType?: "search" | "filter" | "read" | "read_bulk" | "run" | "search_and_write" | "search_or_write" | "write" | undefined;
19
19
  }, {
20
20
  appKey: string;
21
- cursor?: string | undefined;
22
- maxItems?: number | undefined;
23
21
  pageSize?: number | undefined;
22
+ maxItems?: number | undefined;
23
+ cursor?: string | undefined;
24
24
  actionType?: "search" | "filter" | "read" | "read_bulk" | "run" | "search_and_write" | "search_or_write" | "write" | undefined;
25
25
  }>;
26
26
  export type ListActionsOptions = z.infer<typeof ListActionsSchema>;
@@ -1,7 +1,5 @@
1
1
  import type { GetContextType, Plugin } from "../../types/plugin";
2
- import { ListAppsSchema } from "./schemas";
3
- import type { ListAppsOptions } from "./schemas";
4
- import type { AppItem } from "../../types/domain";
2
+ import { ListAppsSchema, type ListAppsOptions, type AppItem } from "./schemas";
5
3
  import type { ManifestPluginProvides } from "../manifest";
6
4
  import type { ApiPluginProvides } from "../api";
7
5
  export interface ListAppsPluginProvides {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/listApps/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,WAAW,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAWlD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC;QAC/C,IAAI,EAAE,OAAO,EAAE,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,GACA,aAAa,CAAC;QAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG;QACxD,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;KACjC,CAAC;IACJ,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,QAAQ,EAAE;gBACR,WAAW,EAAE,OAAO,cAAc,CAAC;aACpC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,cAAc,EAAE,MAAM,CACjC,EAAE,EACF,cAAc,CAAC,iBAAiB,GAAG,sBAAsB,CAAC,EAC1D,sBAAsB,CAwHvB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/listApps/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjE,OAAO,EACL,cAAc,EACd,KAAK,eAAe,EAEpB,KAAK,OAAO,EACb,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC;QAC/C,IAAI,EAAE,OAAO,EAAE,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC,GACA,aAAa,CAAC;QAAE,IAAI,EAAE,OAAO,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG;QACxD,KAAK,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC;KACjC,CAAC;IACJ,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,QAAQ,EAAE;gBACR,WAAW,EAAE,OAAO,cAAc,CAAC;aACpC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,cAAc,EAAE,MAAM,CACjC,EAAE,EACF,cAAc,CAAC,iBAAiB,GAAG,sBAAsB,CAAC,EAC1D,sBAAsB,CAwEvB,CAAC"}
@@ -1,8 +1,6 @@
1
1
  import { createPaginatedFunction } from "../../utils/function-utils";
2
- import { ListAppsSchema } from "./schemas";
2
+ import { ListAppsSchema, } from "./schemas";
3
3
  import { AppItemSchema } from "../../schemas/App";
4
- import { normalizeImplementationMetaToAppItem, splitVersionedKey, toAppLocator, toImplementationId, } from "../../utils/domain-utils";
5
- import { extractCursor } from "../../utils/function-utils";
6
4
  export const listAppsPlugin = ({ context }) => {
7
5
  const listApps = createPaginatedFunction(async function listAppsPage(options) {
8
6
  const { api, resolveAppKeys } = context;
@@ -25,53 +23,29 @@ export const listAppsPlugin = ({ context }) => {
25
23
  if (duplicatedLookupAppKeys.length > 0) {
26
24
  throw new Error(`Duplicate lookup app keys found: ${duplicatedLookupAppKeys.join(", ")}`);
27
25
  }
28
- if (options.search) {
29
- const searchParams = {};
30
- searchParams.term = options.search;
31
- const searchEnvelope = await api.get("/zapier/api/v4/implementations-meta/search/", {
32
- searchParams,
33
- });
34
- const implementations = searchEnvelope.results.map(normalizeImplementationMetaToAppItem);
35
- const implementationNameSet = new Set(appLocators.map((locator) => locator.implementationName));
36
- for (const implementation of implementations) {
37
- const [implementationName] = splitVersionedKey(implementation.key);
38
- if (!implementationNameSet.has(implementationName)) {
39
- implementationNameSet.add(implementationName);
40
- appLocators.push({
41
- ...toAppLocator(implementation.key),
42
- implementationName,
43
- });
44
- }
45
- }
46
- }
47
- const searchParams = {};
48
- if (options.pageSize) {
49
- searchParams.limit = options.pageSize.toString();
50
- }
51
- if (appLocators.length === 0) {
52
- searchParams.latest_only = "true";
53
- }
54
- if (options.cursor) {
55
- searchParams.offset = options.cursor;
56
- }
57
- searchParams.selected_apis = appLocators
58
- .map((locator) => toImplementationId(locator))
59
- .join(",");
60
- // If we have app keys, but they resolved to an empty list, then we need to short-circuit and return an empty list.
61
- // Otherwise, the API will return all apps, since no selected_apis are provided.
62
- if (appKeys.length > 0 && appLocators.length === 0) {
26
+ // Step 2: Early return if user provided appKeys but they resolved to nothing AND no search
27
+ // This prevents the handler from returning all apps when the user explicitly filtered
28
+ // If search is provided, let the handler augment with search results
29
+ if (appKeys.length > 0 && appLocators.length === 0 && !options.search) {
63
30
  return {
64
31
  data: [],
65
32
  nextCursor: undefined,
66
33
  };
67
34
  }
68
- const implementationsEnvelope = await api.get("/zapier/api/v4/implementations-meta/lookup/", {
69
- searchParams,
35
+ const implementationIds = appLocators.map((locator) => {
36
+ const version = locator.version || "latest";
37
+ return `${locator.implementationName}@${version}`;
38
+ });
39
+ // Call the API, which will be routed to the handler via handlerOverride in pathConfig.
40
+ // When the handler is migrated to sdkapi, this same API call will go over the network.
41
+ return await api.get("/api/v0/apps", {
42
+ searchParams: {
43
+ implementationIds: implementationIds.join(","),
44
+ ...(options.search && { search: options.search }),
45
+ pageSize: options.pageSize.toString(),
46
+ ...(options.cursor && { cursor: options.cursor }),
47
+ },
70
48
  });
71
- return {
72
- data: implementationsEnvelope.results.map(normalizeImplementationMetaToAppItem),
73
- nextCursor: extractCursor(implementationsEnvelope),
74
- };
75
49
  }, ListAppsSchema);
76
50
  // Return flat structure - listApps goes directly to SDK
77
51
  return {