@zapier/zapier-sdk 0.15.1 → 0.15.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.integration.test.d.ts +5 -0
- package/dist/api/client.integration.test.d.ts.map +1 -0
- package/dist/api/client.integration.test.js +318 -0
- package/dist/api/client.js +31 -1
- package/dist/index.cjs +401 -108
- package/dist/index.d.mts +360 -56
- package/dist/index.mjs +401 -108
- package/dist/plugins/fetch/schemas.d.ts +2 -2
- package/dist/plugins/getAction/schemas.d.ts +2 -2
- package/dist/plugins/getApp/index.test.js +17 -21
- package/dist/plugins/getInputFieldsSchema/schemas.d.ts +2 -2
- package/dist/plugins/listActions/index.test.js +25 -0
- package/dist/plugins/listActions/schemas.d.ts +6 -6
- package/dist/plugins/listApps/index.d.ts +1 -3
- package/dist/plugins/listApps/index.d.ts.map +1 -1
- package/dist/plugins/listApps/index.js +18 -44
- package/dist/plugins/listApps/index.test.js +89 -288
- package/dist/plugins/listApps/schemas.d.ts +19 -26
- package/dist/plugins/listApps/schemas.d.ts.map +1 -1
- package/dist/plugins/listApps/schemas.js +19 -18
- package/dist/plugins/listAuthentications/index.test.js +20 -0
- package/dist/plugins/listAuthentications/schemas.d.ts +4 -4
- package/dist/plugins/listInputFieldChoices/schemas.d.ts +8 -8
- package/dist/plugins/listInputFields/schemas.d.ts +8 -8
- package/dist/plugins/manifest/index.d.ts +42 -3
- package/dist/plugins/manifest/index.d.ts.map +1 -1
- package/dist/plugins/manifest/index.js +68 -1
- package/dist/plugins/manifest/index.test.js +513 -1
- package/dist/plugins/manifest/schemas.d.ts +75 -2
- package/dist/plugins/manifest/schemas.d.ts.map +1 -1
- package/dist/plugins/manifest/schemas.js +27 -3
- package/dist/plugins/request/schemas.d.ts +4 -4
- package/dist/plugins/runAction/schemas.d.ts +8 -8
- package/dist/sdk.d.ts +24 -2
- package/dist/sdk.d.ts.map +1 -1
- package/dist/temporary-internal-core/handlers/listApps.d.ts +67 -0
- package/dist/temporary-internal-core/handlers/listApps.d.ts.map +1 -0
- package/dist/temporary-internal-core/handlers/listApps.js +121 -0
- package/dist/temporary-internal-core/handlers/listApps.test.d.ts +2 -0
- package/dist/temporary-internal-core/handlers/listApps.test.d.ts.map +1 -0
- package/dist/temporary-internal-core/handlers/listApps.test.js +328 -0
- package/dist/temporary-internal-core/index.d.ts +4 -0
- package/dist/temporary-internal-core/index.d.ts.map +1 -1
- package/dist/temporary-internal-core/index.js +5 -1
- package/dist/temporary-internal-core/schemas/apps/index.d.ts +582 -0
- package/dist/temporary-internal-core/schemas/apps/index.d.ts.map +1 -0
- package/dist/temporary-internal-core/schemas/apps/index.js +95 -0
- package/dist/temporary-internal-core/schemas/implementations/index.d.ts +511 -0
- package/dist/temporary-internal-core/schemas/implementations/index.d.ts.map +1 -0
- package/dist/temporary-internal-core/schemas/implementations/index.js +79 -0
- package/dist/temporary-internal-core/types/handler.d.ts +51 -0
- package/dist/temporary-internal-core/types/handler.d.ts.map +1 -0
- package/dist/temporary-internal-core/types/handler.js +8 -0
- package/dist/temporary-internal-core/types/index.d.ts +5 -0
- package/dist/temporary-internal-core/types/index.d.ts.map +1 -0
- package/dist/temporary-internal-core/types/index.js +4 -0
- package/dist/temporary-internal-core/utils/app-locators.d.ts +54 -0
- package/dist/temporary-internal-core/utils/app-locators.d.ts.map +1 -0
- package/dist/temporary-internal-core/utils/app-locators.js +83 -0
- package/dist/temporary-internal-core/utils/transformations.d.ts +18 -0
- package/dist/temporary-internal-core/utils/transformations.d.ts.map +1 -0
- package/dist/temporary-internal-core/utils/transformations.js +36 -0
- package/package.json +1 -1
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { handleListApps, } from "./listApps";
|
|
3
|
+
import { ListAppsResponseSchema, } from "../schemas/apps";
|
|
4
|
+
describe("handleListApps", () => {
|
|
5
|
+
const mockImplementation = (id, name) => ({
|
|
6
|
+
id,
|
|
7
|
+
name,
|
|
8
|
+
slug: name.toLowerCase().replace(/\s+/g, "-"),
|
|
9
|
+
description: `${name} description`,
|
|
10
|
+
primary_color: "#000000",
|
|
11
|
+
categories: [{ id: 1, name: "test", slug: "test" }],
|
|
12
|
+
});
|
|
13
|
+
describe("pageSize handling", () => {
|
|
14
|
+
it("should use default pageSize of 20 when not provided", async () => {
|
|
15
|
+
const mockHttpClient = {
|
|
16
|
+
get: vi.fn().mockResolvedValue({
|
|
17
|
+
count: 0,
|
|
18
|
+
results: [],
|
|
19
|
+
}),
|
|
20
|
+
};
|
|
21
|
+
await handleListApps({
|
|
22
|
+
request: {
|
|
23
|
+
implementationIds: [],
|
|
24
|
+
search: undefined,
|
|
25
|
+
pageSize: undefined,
|
|
26
|
+
cursor: undefined,
|
|
27
|
+
},
|
|
28
|
+
deps: { httpClient: mockHttpClient },
|
|
29
|
+
});
|
|
30
|
+
expect(mockHttpClient.get).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
|
|
31
|
+
searchParams: expect.objectContaining({
|
|
32
|
+
limit: "20",
|
|
33
|
+
}),
|
|
34
|
+
}));
|
|
35
|
+
});
|
|
36
|
+
it("should use custom pageSize when provided", async () => {
|
|
37
|
+
const mockHttpClient = {
|
|
38
|
+
get: vi.fn().mockResolvedValue({
|
|
39
|
+
count: 0,
|
|
40
|
+
results: [],
|
|
41
|
+
}),
|
|
42
|
+
};
|
|
43
|
+
await handleListApps({
|
|
44
|
+
request: {
|
|
45
|
+
implementationIds: [],
|
|
46
|
+
search: undefined,
|
|
47
|
+
pageSize: 50,
|
|
48
|
+
cursor: undefined,
|
|
49
|
+
},
|
|
50
|
+
deps: { httpClient: mockHttpClient },
|
|
51
|
+
});
|
|
52
|
+
expect(mockHttpClient.get).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
|
|
53
|
+
searchParams: expect.objectContaining({
|
|
54
|
+
limit: "50",
|
|
55
|
+
}),
|
|
56
|
+
}));
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
describe("empty implementation IDs handling", () => {
|
|
60
|
+
it("should fetch all apps when no implementationIds and no search", async () => {
|
|
61
|
+
const mockResponse = {
|
|
62
|
+
count: 2,
|
|
63
|
+
results: [
|
|
64
|
+
mockImplementation("SlackCLIAPI@1.0.0", "Slack"),
|
|
65
|
+
mockImplementation("GitHubCLIAPI@1.0.0", "GitHub"),
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
const mockHttpClient = {
|
|
69
|
+
get: vi.fn().mockResolvedValue(mockResponse),
|
|
70
|
+
};
|
|
71
|
+
const result = await handleListApps({
|
|
72
|
+
request: {
|
|
73
|
+
implementationIds: [],
|
|
74
|
+
search: undefined,
|
|
75
|
+
pageSize: undefined,
|
|
76
|
+
cursor: undefined,
|
|
77
|
+
},
|
|
78
|
+
deps: { httpClient: mockHttpClient },
|
|
79
|
+
});
|
|
80
|
+
expect(result.data).toHaveLength(2);
|
|
81
|
+
expect(mockHttpClient.get).toHaveBeenCalledWith("/zapier/api/v4/implementations-meta/lookup/", expect.objectContaining({
|
|
82
|
+
searchParams: expect.objectContaining({
|
|
83
|
+
latest_only: "true",
|
|
84
|
+
selected_apis: "",
|
|
85
|
+
}),
|
|
86
|
+
}));
|
|
87
|
+
});
|
|
88
|
+
it("should return empty when search finds nothing (bug fix)", async () => {
|
|
89
|
+
const mockSearchResponse = {
|
|
90
|
+
count: 0,
|
|
91
|
+
results: [],
|
|
92
|
+
};
|
|
93
|
+
const mockHttpClient = {
|
|
94
|
+
get: vi.fn().mockResolvedValue(mockSearchResponse),
|
|
95
|
+
};
|
|
96
|
+
const result = await handleListApps({
|
|
97
|
+
request: {
|
|
98
|
+
implementationIds: [],
|
|
99
|
+
search: "NonexistentApp",
|
|
100
|
+
pageSize: undefined,
|
|
101
|
+
cursor: undefined,
|
|
102
|
+
},
|
|
103
|
+
deps: { httpClient: mockHttpClient },
|
|
104
|
+
});
|
|
105
|
+
// Should only call search endpoint
|
|
106
|
+
expect(mockHttpClient.get).toHaveBeenCalledTimes(1);
|
|
107
|
+
expect(mockHttpClient.get).toHaveBeenCalledWith("/zapier/api/v4/implementations-meta/search/", expect.objectContaining({
|
|
108
|
+
searchParams: { term: "NonexistentApp" },
|
|
109
|
+
}));
|
|
110
|
+
// Should return empty (bug fix - not all apps)
|
|
111
|
+
expect(result.data).toHaveLength(0);
|
|
112
|
+
expect(result.nextCursor).toBeUndefined();
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
describe("search augmentation", () => {
|
|
116
|
+
it("should augment results with search when search term provided", async () => {
|
|
117
|
+
const mockSearchResponse = {
|
|
118
|
+
count: 1,
|
|
119
|
+
results: [mockImplementation("SlackCLIAPI@1.0.0", "Slack")],
|
|
120
|
+
};
|
|
121
|
+
const mockLookupResponse = {
|
|
122
|
+
count: 2,
|
|
123
|
+
results: [
|
|
124
|
+
mockImplementation("GitHubCLIAPI@1.0.0", "GitHub"),
|
|
125
|
+
mockImplementation("SlackCLIAPI@1.0.0", "Slack"),
|
|
126
|
+
],
|
|
127
|
+
next: null,
|
|
128
|
+
};
|
|
129
|
+
const mockHttpClient = {
|
|
130
|
+
get: vi
|
|
131
|
+
.fn()
|
|
132
|
+
.mockResolvedValueOnce(mockSearchResponse) // First call: search
|
|
133
|
+
.mockResolvedValueOnce(mockLookupResponse), // Second call: lookup
|
|
134
|
+
};
|
|
135
|
+
const result = await handleListApps({
|
|
136
|
+
request: {
|
|
137
|
+
implementationIds: ["GitHubCLIAPI@1.0.0"],
|
|
138
|
+
search: "Slack",
|
|
139
|
+
pageSize: undefined,
|
|
140
|
+
cursor: undefined,
|
|
141
|
+
},
|
|
142
|
+
deps: { httpClient: mockHttpClient },
|
|
143
|
+
});
|
|
144
|
+
// Should call both search and lookup
|
|
145
|
+
expect(mockHttpClient.get).toHaveBeenCalledTimes(2);
|
|
146
|
+
expect(mockHttpClient.get).toHaveBeenNthCalledWith(1, "/zapier/api/v4/implementations-meta/search/", expect.objectContaining({
|
|
147
|
+
searchParams: { term: "Slack" },
|
|
148
|
+
}));
|
|
149
|
+
expect(mockHttpClient.get).toHaveBeenNthCalledWith(2, "/zapier/api/v4/implementations-meta/lookup/", expect.objectContaining({
|
|
150
|
+
searchParams: expect.objectContaining({
|
|
151
|
+
selected_apis: "GitHubCLIAPI@1.0.0,SlackCLIAPI@1.0.0",
|
|
152
|
+
}),
|
|
153
|
+
}));
|
|
154
|
+
expect(result.data).toHaveLength(2);
|
|
155
|
+
});
|
|
156
|
+
it("should not duplicate apps when search returns apps already in implementationIds", async () => {
|
|
157
|
+
const mockSearchResponse = {
|
|
158
|
+
count: 1,
|
|
159
|
+
results: [mockImplementation("SlackCLIAPI@1.0.0", "Slack")],
|
|
160
|
+
};
|
|
161
|
+
const mockLookupResponse = {
|
|
162
|
+
count: 1,
|
|
163
|
+
results: [mockImplementation("SlackCLIAPI@1.0.0", "Slack")],
|
|
164
|
+
next: null,
|
|
165
|
+
};
|
|
166
|
+
const mockHttpClient = {
|
|
167
|
+
get: vi
|
|
168
|
+
.fn()
|
|
169
|
+
.mockResolvedValueOnce(mockSearchResponse)
|
|
170
|
+
.mockResolvedValueOnce(mockLookupResponse),
|
|
171
|
+
};
|
|
172
|
+
await handleListApps({
|
|
173
|
+
request: {
|
|
174
|
+
implementationIds: ["SlackCLIAPI@1.0.0"],
|
|
175
|
+
search: "Slack",
|
|
176
|
+
pageSize: undefined,
|
|
177
|
+
cursor: undefined,
|
|
178
|
+
},
|
|
179
|
+
deps: { httpClient: mockHttpClient },
|
|
180
|
+
});
|
|
181
|
+
// Should call search and lookup but deduplicate IDs
|
|
182
|
+
expect(mockHttpClient.get).toHaveBeenCalledTimes(2);
|
|
183
|
+
expect(mockHttpClient.get).toHaveBeenNthCalledWith(2, "/zapier/api/v4/implementations-meta/lookup/", expect.objectContaining({
|
|
184
|
+
searchParams: expect.objectContaining({
|
|
185
|
+
selected_apis: "SlackCLIAPI@1.0.0",
|
|
186
|
+
}),
|
|
187
|
+
}));
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
describe("specific implementation IDs", () => {
|
|
191
|
+
it("should fetch specific apps when implementationIds provided", async () => {
|
|
192
|
+
const mockResponse = {
|
|
193
|
+
count: 2,
|
|
194
|
+
results: [
|
|
195
|
+
mockImplementation("SlackCLIAPI@1.0.0", "Slack"),
|
|
196
|
+
mockImplementation("GitHubCLIAPI@1.0.0", "GitHub"),
|
|
197
|
+
],
|
|
198
|
+
};
|
|
199
|
+
const mockHttpClient = {
|
|
200
|
+
get: vi.fn().mockResolvedValue(mockResponse),
|
|
201
|
+
};
|
|
202
|
+
const result = await handleListApps({
|
|
203
|
+
request: {
|
|
204
|
+
implementationIds: ["SlackCLIAPI@1.0.0", "GitHubCLIAPI@1.0.0"],
|
|
205
|
+
search: undefined,
|
|
206
|
+
pageSize: undefined,
|
|
207
|
+
cursor: undefined,
|
|
208
|
+
},
|
|
209
|
+
deps: { httpClient: mockHttpClient },
|
|
210
|
+
});
|
|
211
|
+
expect(result.data).toHaveLength(2);
|
|
212
|
+
expect(mockHttpClient.get).toHaveBeenCalledWith("/zapier/api/v4/implementations-meta/lookup/", expect.objectContaining({
|
|
213
|
+
searchParams: expect.objectContaining({
|
|
214
|
+
selected_apis: "SlackCLIAPI@1.0.0,GitHubCLIAPI@1.0.0",
|
|
215
|
+
}),
|
|
216
|
+
}));
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
describe("pagination", () => {
|
|
220
|
+
it("should pass cursor to API when provided", async () => {
|
|
221
|
+
const mockResponse = {
|
|
222
|
+
count: 0,
|
|
223
|
+
results: [],
|
|
224
|
+
};
|
|
225
|
+
const mockHttpClient = {
|
|
226
|
+
get: vi.fn().mockResolvedValue(mockResponse),
|
|
227
|
+
};
|
|
228
|
+
await handleListApps({
|
|
229
|
+
request: {
|
|
230
|
+
implementationIds: ["SlackCLIAPI@1.0.0"],
|
|
231
|
+
search: undefined,
|
|
232
|
+
pageSize: undefined,
|
|
233
|
+
cursor: "page-2-cursor",
|
|
234
|
+
},
|
|
235
|
+
deps: { httpClient: mockHttpClient },
|
|
236
|
+
});
|
|
237
|
+
expect(mockHttpClient.get).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
|
|
238
|
+
searchParams: expect.objectContaining({
|
|
239
|
+
offset: "page-2-cursor",
|
|
240
|
+
}),
|
|
241
|
+
}));
|
|
242
|
+
});
|
|
243
|
+
it("should extract nextCursor from response", async () => {
|
|
244
|
+
const mockResponse = {
|
|
245
|
+
count: 1,
|
|
246
|
+
results: [mockImplementation("SlackCLIAPI@1.0.0", "Slack")],
|
|
247
|
+
next: "https://api.zapier.com/v4/implementations-meta/lookup/?offset=next-page",
|
|
248
|
+
};
|
|
249
|
+
const mockHttpClient = {
|
|
250
|
+
get: vi.fn().mockResolvedValue(mockResponse),
|
|
251
|
+
};
|
|
252
|
+
const result = await handleListApps({
|
|
253
|
+
request: {
|
|
254
|
+
implementationIds: [],
|
|
255
|
+
search: undefined,
|
|
256
|
+
pageSize: undefined,
|
|
257
|
+
cursor: undefined,
|
|
258
|
+
},
|
|
259
|
+
deps: { httpClient: mockHttpClient },
|
|
260
|
+
});
|
|
261
|
+
expect(result.nextCursor).toBe("next-page");
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
describe("request validation", () => {
|
|
265
|
+
it("should reject request with invalid implementationIds type", async () => {
|
|
266
|
+
const mockHttpClient = {
|
|
267
|
+
get: vi.fn(),
|
|
268
|
+
};
|
|
269
|
+
const invalidRequest = {
|
|
270
|
+
implementationIds: "not-an-array",
|
|
271
|
+
search: undefined,
|
|
272
|
+
pageSize: undefined,
|
|
273
|
+
cursor: undefined,
|
|
274
|
+
};
|
|
275
|
+
const deps = {
|
|
276
|
+
httpClient: mockHttpClient,
|
|
277
|
+
};
|
|
278
|
+
await expect(handleListApps({ request: invalidRequest, deps })).rejects.toThrow();
|
|
279
|
+
});
|
|
280
|
+
it("should reject request with negative pageSize", async () => {
|
|
281
|
+
const mockHttpClient = {
|
|
282
|
+
get: vi.fn(),
|
|
283
|
+
};
|
|
284
|
+
const invalidRequest = {
|
|
285
|
+
implementationIds: [],
|
|
286
|
+
search: undefined,
|
|
287
|
+
pageSize: -1,
|
|
288
|
+
cursor: undefined,
|
|
289
|
+
};
|
|
290
|
+
const deps = {
|
|
291
|
+
httpClient: mockHttpClient,
|
|
292
|
+
};
|
|
293
|
+
await expect(handleListApps({ request: invalidRequest, deps })).rejects.toThrow();
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
describe("response validation", () => {
|
|
297
|
+
it("should return response matching ListAppsResponseSchema", async () => {
|
|
298
|
+
const mockHttpClient = {
|
|
299
|
+
get: vi.fn().mockResolvedValue({
|
|
300
|
+
count: 1,
|
|
301
|
+
results: [
|
|
302
|
+
{
|
|
303
|
+
id: "SlackCLIAPI@1.0.0",
|
|
304
|
+
name: "SlackCLIAPI",
|
|
305
|
+
slug: "slack",
|
|
306
|
+
description: "Slack app",
|
|
307
|
+
primary_color: "#000000",
|
|
308
|
+
},
|
|
309
|
+
],
|
|
310
|
+
}),
|
|
311
|
+
};
|
|
312
|
+
const request = {
|
|
313
|
+
implementationIds: [],
|
|
314
|
+
search: undefined,
|
|
315
|
+
pageSize: 20,
|
|
316
|
+
cursor: undefined,
|
|
317
|
+
};
|
|
318
|
+
const deps = {
|
|
319
|
+
httpClient: mockHttpClient,
|
|
320
|
+
};
|
|
321
|
+
const result = await handleListApps({ request, deps });
|
|
322
|
+
expect(() => ListAppsResponseSchema.parse(result)).not.toThrow();
|
|
323
|
+
expect(result).toHaveProperty("data");
|
|
324
|
+
expect(Array.isArray(result.data)).toBe(true);
|
|
325
|
+
expect(result).toHaveProperty("nextCursor");
|
|
326
|
+
});
|
|
327
|
+
});
|
|
328
|
+
});
|
|
@@ -11,4 +11,8 @@
|
|
|
11
11
|
* - Lives inside zapier-sdk during extraction/migration (bundles when published)
|
|
12
12
|
* - Will be extracted to separate package
|
|
13
13
|
*/
|
|
14
|
+
export type { HandlerDeps, Handler, ValidatedHandler } from "./types";
|
|
15
|
+
export * from "./schemas/apps";
|
|
16
|
+
export * from "./schemas/implementations";
|
|
17
|
+
export { handleListApps, type ListAppsHandlerDeps } from "./handlers/listApps";
|
|
14
18
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/temporary-internal-core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/temporary-internal-core/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAGtE,cAAc,gBAAgB,CAAC;AAC/B,cAAc,2BAA2B,CAAC;AAG1C,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* temporary-internal-core
|
|
4
3
|
*
|
|
@@ -12,3 +11,8 @@
|
|
|
12
11
|
* - Lives inside zapier-sdk during extraction/migration (bundles when published)
|
|
13
12
|
* - Will be extracted to separate package
|
|
14
13
|
*/
|
|
14
|
+
// Schemas
|
|
15
|
+
export * from "./schemas/apps";
|
|
16
|
+
export * from "./schemas/implementations";
|
|
17
|
+
// Handlers
|
|
18
|
+
export { handleListApps } from "./handlers/listApps";
|