@zapier/zapier-sdk 0.5.2 → 0.6.1

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 (115) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +107 -83
  3. package/dist/index.cjs +320 -50
  4. package/dist/index.d.mts +409 -340
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +0 -1
  7. package/dist/index.mjs +320 -50
  8. package/dist/plugins/api/index.js +1 -1
  9. package/dist/plugins/findFirstAuthentication/index.d.ts.map +1 -1
  10. package/dist/plugins/findFirstAuthentication/index.js +1 -0
  11. package/dist/plugins/findUniqueAuthentication/index.d.ts.map +1 -1
  12. package/dist/plugins/findUniqueAuthentication/index.js +1 -0
  13. package/dist/plugins/getAction/index.d.ts.map +1 -1
  14. package/dist/plugins/getAction/index.js +1 -0
  15. package/dist/plugins/getAction/index.test.js +1 -1
  16. package/dist/plugins/getApp/index.d.ts +6 -3
  17. package/dist/plugins/getApp/index.d.ts.map +1 -1
  18. package/dist/plugins/getApp/index.js +8 -18
  19. package/dist/plugins/getApp/index.test.js +2 -0
  20. package/dist/plugins/getAuthentication/index.d.ts.map +1 -1
  21. package/dist/plugins/getAuthentication/index.js +1 -0
  22. package/dist/plugins/getAuthentication/index.test.js +12 -1
  23. package/dist/plugins/getProfile/index.d.ts.map +1 -1
  24. package/dist/plugins/getProfile/index.js +1 -0
  25. package/dist/plugins/listActions/index.d.ts +5 -3
  26. package/dist/plugins/listActions/index.d.ts.map +1 -1
  27. package/dist/plugins/listActions/index.js +6 -6
  28. package/dist/plugins/listActions/index.test.js +26 -74
  29. package/dist/plugins/listActions/schemas.d.ts +4 -4
  30. package/dist/plugins/listApps/index.d.ts.map +1 -1
  31. package/dist/plugins/listApps/index.js +1 -0
  32. package/dist/plugins/listApps/schemas.d.ts +2 -2
  33. package/dist/plugins/listAuthentications/index.d.ts +4 -2
  34. package/dist/plugins/listAuthentications/index.d.ts.map +1 -1
  35. package/dist/plugins/listAuthentications/index.js +9 -12
  36. package/dist/plugins/listAuthentications/index.test.js +33 -40
  37. package/dist/plugins/listAuthentications/schemas.d.ts +4 -4
  38. package/dist/plugins/listInputFields/index.d.ts +3 -1
  39. package/dist/plugins/listInputFields/index.d.ts.map +1 -1
  40. package/dist/plugins/listInputFields/index.js +5 -5
  41. package/dist/plugins/listInputFields/index.test.js +10 -8
  42. package/dist/plugins/listInputFields/schemas.d.ts +4 -4
  43. package/dist/plugins/lockVersion/index.d.ts +24 -0
  44. package/dist/plugins/lockVersion/index.d.ts.map +1 -0
  45. package/dist/plugins/lockVersion/index.js +72 -0
  46. package/dist/plugins/lockVersion/index.test.d.ts +2 -0
  47. package/dist/plugins/lockVersion/index.test.d.ts.map +1 -0
  48. package/dist/plugins/lockVersion/index.test.js +129 -0
  49. package/dist/plugins/lockVersion/schemas.d.ts +10 -0
  50. package/dist/plugins/lockVersion/schemas.d.ts.map +1 -0
  51. package/dist/plugins/lockVersion/schemas.js +6 -0
  52. package/dist/plugins/manifest/index.d.ts +24 -0
  53. package/dist/plugins/manifest/index.d.ts.map +1 -0
  54. package/dist/plugins/manifest/index.js +119 -0
  55. package/dist/plugins/manifest/index.test.d.ts +2 -0
  56. package/dist/plugins/manifest/index.test.d.ts.map +1 -0
  57. package/dist/plugins/manifest/index.test.js +331 -0
  58. package/dist/plugins/manifest/schemas.d.ts +64 -0
  59. package/dist/plugins/manifest/schemas.d.ts.map +1 -0
  60. package/dist/plugins/manifest/schemas.js +25 -0
  61. package/dist/plugins/registry/index.d.ts +9 -1
  62. package/dist/plugins/registry/index.d.ts.map +1 -1
  63. package/dist/plugins/registry/index.js +68 -3
  64. package/dist/plugins/request/index.d.ts.map +1 -1
  65. package/dist/plugins/request/index.js +1 -0
  66. package/dist/plugins/request/index.test.js +6 -1
  67. package/dist/plugins/request/schemas.d.ts +4 -4
  68. package/dist/plugins/runAction/index.d.ts +2 -0
  69. package/dist/plugins/runAction/index.d.ts.map +1 -1
  70. package/dist/plugins/runAction/index.js +5 -5
  71. package/dist/plugins/runAction/index.test.js +9 -8
  72. package/dist/plugins/runAction/schemas.d.ts +4 -4
  73. package/dist/sdk.d.ts +3 -3
  74. package/dist/sdk.d.ts.map +1 -1
  75. package/dist/sdk.js +18 -7
  76. package/dist/sdk.test.js +1 -1
  77. package/dist/types/plugin.d.ts +10 -2
  78. package/dist/types/plugin.d.ts.map +1 -1
  79. package/dist/types/sdk.d.ts +13 -2
  80. package/dist/types/sdk.d.ts.map +1 -1
  81. package/package.json +1 -1
  82. package/src/index.ts +0 -2
  83. package/src/plugins/api/index.ts +1 -1
  84. package/src/plugins/findFirstAuthentication/index.ts +1 -0
  85. package/src/plugins/findUniqueAuthentication/index.ts +1 -0
  86. package/src/plugins/getAction/index.test.ts +1 -1
  87. package/src/plugins/getAction/index.ts +1 -0
  88. package/src/plugins/getApp/index.test.ts +2 -0
  89. package/src/plugins/getApp/index.ts +12 -24
  90. package/src/plugins/getAuthentication/index.test.ts +13 -3
  91. package/src/plugins/getAuthentication/index.ts +1 -0
  92. package/src/plugins/getProfile/index.ts +1 -0
  93. package/src/plugins/listActions/index.test.ts +30 -89
  94. package/src/plugins/listActions/index.ts +13 -9
  95. package/src/plugins/listApps/index.ts +1 -0
  96. package/src/plugins/listAuthentications/index.test.ts +38 -47
  97. package/src/plugins/listAuthentications/index.ts +21 -18
  98. package/src/plugins/listInputFields/index.test.ts +12 -9
  99. package/src/plugins/listInputFields/index.ts +10 -6
  100. package/src/plugins/lockVersion/index.test.ts +176 -0
  101. package/src/plugins/lockVersion/index.ts +112 -0
  102. package/src/plugins/lockVersion/schemas.ts +9 -0
  103. package/src/plugins/manifest/index.test.ts +438 -0
  104. package/src/plugins/manifest/index.ts +171 -0
  105. package/src/plugins/manifest/schemas.ts +53 -0
  106. package/src/plugins/registry/index.ts +89 -8
  107. package/src/plugins/request/index.test.ts +8 -4
  108. package/src/plugins/request/index.ts +1 -0
  109. package/src/plugins/runAction/index.test.ts +9 -8
  110. package/src/plugins/runAction/index.ts +13 -7
  111. package/src/sdk.test.ts +1 -1
  112. package/src/sdk.ts +22 -7
  113. package/src/types/plugin.ts +14 -2
  114. package/src/types/sdk.ts +15 -1
  115. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,331 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
+ import { manifestPlugin, loadManifestFromFile } from "./index";
3
+ import { createSdk } from "../../sdk";
4
+ // Mock fs and path modules
5
+ vi.mock("fs", () => ({
6
+ readFileSync: vi.fn(),
7
+ }));
8
+ vi.mock("path", () => ({
9
+ resolve: vi.fn((path) => `/resolved/${path}`),
10
+ }));
11
+ import { readFileSync } from "fs";
12
+ import { resolve } from "path";
13
+ const mockReadFileSync = vi.mocked(readFileSync);
14
+ const mockResolve = vi.mocked(resolve);
15
+ describe("manifestPlugin", () => {
16
+ const mockManifest = {
17
+ apps: {
18
+ slack: {
19
+ implementationName: "SlackCLIAPI",
20
+ version: "1.21.1",
21
+ },
22
+ "google-sheets": {
23
+ implementationName: "GoogleSheetsCLIAPI",
24
+ version: "2.0.0",
25
+ },
26
+ },
27
+ };
28
+ const mockManifestContent = JSON.stringify(mockManifest);
29
+ let mockApiClient;
30
+ let mockSdk;
31
+ beforeEach(() => {
32
+ vi.clearAllMocks();
33
+ vi.spyOn(console, "warn").mockImplementation(() => { });
34
+ mockApiClient = {
35
+ get: vi.fn().mockResolvedValue({
36
+ count: 1,
37
+ next: null,
38
+ previous: null,
39
+ results: [
40
+ {
41
+ selected_api: "SlackCLIAPI@1.29.0",
42
+ app_id: null,
43
+ service_id: null,
44
+ auth_type: "oauth",
45
+ auth_fields: [
46
+ {
47
+ key: "access_token",
48
+ required: true,
49
+ type: "unicode",
50
+ computed: true,
51
+ },
52
+ ],
53
+ is_deprecated: false,
54
+ is_private_only: false,
55
+ is_invite_only: false,
56
+ is_beta: false,
57
+ is_premium: false,
58
+ is_hidden: false,
59
+ name: "Slack (1.29.0)",
60
+ name_clean: "Slack",
61
+ version: "1.29.0",
62
+ slug: null,
63
+ images: {
64
+ url_16x16: "https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=16&ixlib=python-3.0.0&q=50&w=16",
65
+ url_32x32: "https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=32&ixlib=python-3.0.0&q=50&w=32",
66
+ url_64x64: "https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=64&ixlib=python-3.0.0&q=50&w=64",
67
+ url_128x128: "https://zapier-images.imgix.net/storage/services/6cf3f5a461feadfba7abc93c4c395b33_2.png?auto=format%2Ccompress&fit=crop&h=128&ixlib=python-3.0.0&q=50&w=128",
68
+ },
69
+ primary_color: null,
70
+ secondary_color: null,
71
+ classification: "third-party",
72
+ current_implementation: "SlackCLIAPI@1.30.0",
73
+ is_adoptable: true,
74
+ is_usable: true,
75
+ update_cta_level: "info",
76
+ update_cta_message: "This version is legacy. Consider updating to the latest version for better support.",
77
+ badges: [
78
+ {
79
+ label: "Legacy",
80
+ color: "primary",
81
+ tooltip_markdown: "This version is legacy. Consider updating to the latest version for better support.",
82
+ },
83
+ ],
84
+ },
85
+ ],
86
+ }),
87
+ };
88
+ mockSdk = {
89
+ listApps: vi.fn().mockReturnValue({
90
+ items: vi.fn().mockReturnValue([
91
+ {
92
+ title: "Slack",
93
+ key: "slack",
94
+ current_implementation_id: "SlackCLIAPI@1.30.0",
95
+ description: "Team communication platform",
96
+ },
97
+ ][Symbol.iterator]()),
98
+ }),
99
+ };
100
+ });
101
+ afterEach(() => {
102
+ vi.restoreAllMocks();
103
+ });
104
+ const apiPlugin = () => ({
105
+ context: {
106
+ api: mockApiClient,
107
+ },
108
+ });
109
+ const listAppsMockPlugin = () => ({
110
+ listApps: mockSdk.listApps,
111
+ context: {
112
+ meta: {
113
+ listApps: {
114
+ inputSchema: {},
115
+ },
116
+ },
117
+ },
118
+ });
119
+ function createTestSdk(options = {}) {
120
+ return createSdk(options)
121
+ .addPlugin(apiPlugin)
122
+ .addPlugin(listAppsMockPlugin)
123
+ .addPlugin(manifestPlugin);
124
+ }
125
+ describe("plugin initialization", () => {
126
+ it("should provide manifest context with direct manifest", () => {
127
+ const sdk = createTestSdk({ manifest: mockManifest });
128
+ const context = sdk.getContext();
129
+ expect(context.manifest).toEqual(mockManifest);
130
+ expect(context.getVersionedImplementationId).toBeInstanceOf(Function);
131
+ expect(context.getImplementation).toBeInstanceOf(Function);
132
+ });
133
+ it("should provide manifest context with manifestPath", () => {
134
+ mockReadFileSync.mockReturnValue(mockManifestContent);
135
+ const sdk = createTestSdk({ manifestPath: "manifest.json" });
136
+ const context = sdk.getContext();
137
+ expect(mockResolve).toHaveBeenCalledWith("manifest.json");
138
+ expect(mockReadFileSync).toHaveBeenCalledWith("/resolved/manifest.json", "utf8");
139
+ expect(context.manifest).toEqual(mockManifest);
140
+ });
141
+ it("should provide null manifest when no manifest or path provided", () => {
142
+ const sdk = createTestSdk();
143
+ const context = sdk.getContext();
144
+ expect(context.manifest).toBeNull();
145
+ });
146
+ it("should prioritize direct manifest over manifestPath", () => {
147
+ mockReadFileSync.mockReturnValue('{"apps": {"other": {"implementationName": "Other", "version": "1.0.0"}}}');
148
+ const sdk = createTestSdk({
149
+ manifest: mockManifest,
150
+ manifestPath: "manifest.json",
151
+ });
152
+ const context = sdk.getContext();
153
+ expect(context.manifest).toEqual(mockManifest);
154
+ expect(mockReadFileSync).not.toHaveBeenCalled();
155
+ });
156
+ });
157
+ describe("getVersionedImplementationId function", () => {
158
+ it("should return versioned implementation ID when app exists in manifest", async () => {
159
+ const sdk = createTestSdk({ manifest: mockManifest });
160
+ const context = sdk.getContext();
161
+ const result = await context.getVersionedImplementationId("slack");
162
+ expect(result).toBe("SlackCLIAPI@1.21.1");
163
+ });
164
+ it("should fetch and return versioned implementation ID when app not in manifest", async () => {
165
+ const sdk = createTestSdk();
166
+ const context = sdk.getContext();
167
+ const result = await context.getVersionedImplementationId("slack");
168
+ expect(result).toBe("SlackCLIAPI@1.30.0");
169
+ });
170
+ it("should return null when app does not exist", async () => {
171
+ mockSdk.listApps = vi.fn().mockReturnValue({
172
+ items: vi.fn().mockReturnValue([][Symbol.iterator]()),
173
+ });
174
+ const sdk = createTestSdk();
175
+ const context = sdk.getContext();
176
+ const result = await context.getVersionedImplementationId("nonexistent");
177
+ expect(result).toBeNull();
178
+ });
179
+ });
180
+ describe("getImplementation function", () => {
181
+ it("should return app from manifest when available", async () => {
182
+ const sdk = createTestSdk({ manifest: mockManifest });
183
+ const context = sdk.getContext();
184
+ const result = await context.getImplementation("slack");
185
+ expect(result).toBeDefined();
186
+ expect(mockApiClient.get).toHaveBeenCalledWith("/api/v4/implementations/", {
187
+ searchParams: {
188
+ selected_apis: "SlackCLIAPI@1.21.1",
189
+ },
190
+ });
191
+ });
192
+ it("should fetch app from API when not in manifest", async () => {
193
+ const sdk = createTestSdk();
194
+ const context = sdk.getContext();
195
+ const result = await context.getImplementation("slack");
196
+ expect(result).toBeDefined();
197
+ expect(result?.title).toBe("Slack");
198
+ expect(result?.current_implementation_id).toBe("SlackCLIAPI@1.30.0");
199
+ });
200
+ it("should return null when app cannot be fetched", async () => {
201
+ mockSdk.listApps = vi.fn().mockReturnValue({
202
+ items: vi.fn().mockReturnValue([][Symbol.iterator]()),
203
+ });
204
+ const sdk = createTestSdk();
205
+ const context = sdk.getContext();
206
+ const result = await context.getImplementation("nonexistent");
207
+ expect(result).toBeNull();
208
+ });
209
+ });
210
+ describe("manifest parsing", () => {
211
+ it("should parse valid manifest content", () => {
212
+ const sdk = createTestSdk({ manifest: mockManifest });
213
+ const context = sdk.getContext();
214
+ expect(context.manifest).toEqual(mockManifest);
215
+ });
216
+ it("should handle manifest with missing version", () => {
217
+ const manifestWithoutVersion = {
218
+ apps: {
219
+ slack: {
220
+ implementationName: "SlackCLIAPI",
221
+ },
222
+ },
223
+ };
224
+ const sdk = createTestSdk({ manifest: manifestWithoutVersion });
225
+ const context = sdk.getContext();
226
+ expect(context.manifest).toEqual(manifestWithoutVersion);
227
+ });
228
+ it("should handle empty manifest", () => {
229
+ const sdk = createTestSdk({ manifest: {} });
230
+ const context = sdk.getContext();
231
+ expect(context.manifest).toEqual({});
232
+ });
233
+ });
234
+ describe("file loading", () => {
235
+ it("should load manifest from file successfully", () => {
236
+ mockReadFileSync.mockReturnValue(mockManifestContent);
237
+ const sdk = createTestSdk({ manifestPath: "manifest.json" });
238
+ const context = sdk.getContext();
239
+ expect(mockResolve).toHaveBeenCalledWith("manifest.json");
240
+ expect(mockReadFileSync).toHaveBeenCalledWith("/resolved/manifest.json", "utf8");
241
+ expect(context.manifest).toEqual(mockManifest);
242
+ });
243
+ it("should handle file read errors gracefully", () => {
244
+ mockReadFileSync.mockImplementation(() => {
245
+ throw new Error("File not found");
246
+ });
247
+ const sdk = createTestSdk({ manifestPath: "nonexistent.json" });
248
+ const context = sdk.getContext();
249
+ expect(context.manifest).toBeNull();
250
+ expect(console.warn).toHaveBeenCalledWith(expect.stringContaining("Failed to load manifest from nonexistent.json"));
251
+ });
252
+ it("should handle invalid JSON gracefully", () => {
253
+ mockReadFileSync.mockReturnValue("invalid json content");
254
+ const sdk = createTestSdk({ manifestPath: "invalid.json" });
255
+ const context = sdk.getContext();
256
+ expect(context.manifest).toBeNull();
257
+ expect(console.warn).toHaveBeenCalledWith(expect.stringContaining("Failed to parse manifest from /resolved/invalid.json"), expect.any(SyntaxError));
258
+ });
259
+ it("should handle JSON without apps property", () => {
260
+ mockReadFileSync.mockReturnValue('{"other": "data"}');
261
+ const sdk = createTestSdk({ manifestPath: "no-apps.json" });
262
+ const context = sdk.getContext();
263
+ expect(context.manifest).toBeNull();
264
+ });
265
+ it("should handle JSON with invalid apps format", () => {
266
+ mockReadFileSync.mockReturnValue('{"apps": "not an object"}');
267
+ const sdk = createTestSdk({ manifestPath: "invalid-apps.json" });
268
+ const context = sdk.getContext();
269
+ expect(context.manifest).toBeNull();
270
+ });
271
+ });
272
+ describe("integration with SDK", () => {
273
+ it("should work with createSdk", async () => {
274
+ const sdk = createSdk({ manifest: mockManifest })
275
+ .addPlugin(apiPlugin)
276
+ .addPlugin(listAppsMockPlugin)
277
+ .addPlugin(manifestPlugin);
278
+ const context = sdk.getContext();
279
+ expect(context.manifest).toEqual(mockManifest);
280
+ const versionedId = await context.getVersionedImplementationId("slack");
281
+ expect(versionedId).toBe("SlackCLIAPI@1.21.1");
282
+ });
283
+ });
284
+ });
285
+ describe("loadManifestFromFile", () => {
286
+ const mockManifestContent = JSON.stringify({
287
+ apps: {
288
+ slack: {
289
+ implementationName: "SlackCLIAPI",
290
+ version: "1.21.1",
291
+ },
292
+ "google-sheets": {
293
+ implementationName: "GoogleSheetsCLIAPI",
294
+ version: "2.0.0",
295
+ },
296
+ },
297
+ });
298
+ beforeEach(() => {
299
+ vi.clearAllMocks();
300
+ });
301
+ it("should load and parse manifest from file", () => {
302
+ mockReadFileSync.mockReturnValue(mockManifestContent);
303
+ const result = loadManifestFromFile("manifest.json");
304
+ expect(mockResolve).toHaveBeenCalledWith("manifest.json");
305
+ expect(mockReadFileSync).toHaveBeenCalledWith("/resolved/manifest.json", "utf8");
306
+ expect(result).toEqual({
307
+ apps: {
308
+ slack: {
309
+ implementationName: "SlackCLIAPI",
310
+ version: "1.21.1",
311
+ },
312
+ "google-sheets": {
313
+ implementationName: "GoogleSheetsCLIAPI",
314
+ version: "2.0.0",
315
+ },
316
+ },
317
+ });
318
+ });
319
+ it("should handle file read errors", () => {
320
+ mockReadFileSync.mockImplementation(() => {
321
+ throw new Error("File not found");
322
+ });
323
+ const result = loadManifestFromFile("nonexistent.json");
324
+ expect(result).toBeNull();
325
+ });
326
+ it("should handle invalid JSON content", () => {
327
+ mockReadFileSync.mockReturnValue("invalid json");
328
+ const result = loadManifestFromFile("invalid.json");
329
+ expect(result).toBeNull();
330
+ });
331
+ });
@@ -0,0 +1,64 @@
1
+ import { z } from "zod";
2
+ import { AppItem } from "../../types/domain";
3
+ export type ManifestEntry = {
4
+ implementationName: string;
5
+ version?: string;
6
+ };
7
+ export type GetManifestEntry = (appKey: string) => ManifestEntry | null;
8
+ export type GetVersionedImplementationId = (appKey: string) => Promise<string | null>;
9
+ export type GetImplementation = (appKey: string) => Promise<AppItem | null>;
10
+ export type Manifest = {
11
+ apps: Record<string, ManifestEntry>;
12
+ };
13
+ /**
14
+ * Manifest schema for version locking
15
+ * Maps app keys to their locked version information
16
+ */
17
+ export declare const ManifestSchema: z.ZodObject<{
18
+ apps: z.ZodRecord<z.ZodString, z.ZodObject<{
19
+ implementationName: z.ZodString;
20
+ version: z.ZodString;
21
+ }, "strip", z.ZodTypeAny, {
22
+ version: string;
23
+ implementationName: string;
24
+ }, {
25
+ version: string;
26
+ implementationName: string;
27
+ }>>;
28
+ }, "strip", z.ZodTypeAny, {
29
+ apps: Record<string, {
30
+ version: string;
31
+ implementationName: string;
32
+ }>;
33
+ }, {
34
+ apps: Record<string, {
35
+ version: string;
36
+ implementationName: string;
37
+ }>;
38
+ }>;
39
+ export declare const ManifestPluginOptionsSchema: z.ZodObject<{
40
+ manifestPath: z.ZodOptional<z.ZodString>;
41
+ manifest: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
42
+ implementationName: z.ZodString;
43
+ version: z.ZodOptional<z.ZodString>;
44
+ }, "strip", z.ZodTypeAny, {
45
+ implementationName: string;
46
+ version?: string | undefined;
47
+ }, {
48
+ implementationName: string;
49
+ version?: string | undefined;
50
+ }>>>;
51
+ }, "strip", z.ZodTypeAny, {
52
+ manifestPath?: string | undefined;
53
+ manifest?: Record<string, {
54
+ implementationName: string;
55
+ version?: string | undefined;
56
+ }> | undefined;
57
+ }, {
58
+ manifestPath?: string | undefined;
59
+ manifest?: Record<string, {
60
+ implementationName: string;
61
+ version?: string | undefined;
62
+ }> | undefined;
63
+ }>;
64
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/plugins/manifest/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,MAAM,aAAa,GAAG;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,aAAa,GAAG,IAAI,CAAC;AAExE,MAAM,MAAM,4BAA4B,GAAG,CACzC,MAAM,EAAE,MAAM,KACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;AAE5B,MAAM,MAAM,iBAAiB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AAE5E,MAAM,MAAM,QAAQ,GAAG;IACrB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACrC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;EAcoC,CAAC;AAEhE,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;EAYtC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Manifest schema for version locking
4
+ * Maps app keys to their locked version information
5
+ */
6
+ export const ManifestSchema = z
7
+ .object({
8
+ apps: z.record(z.string(), z.object({
9
+ implementationName: z
10
+ .string()
11
+ .describe("Base implementation name without version (e.g., 'SlackCLIAPI')"),
12
+ version: z.string().describe("Version string (e.g., '1.21.1')"),
13
+ })),
14
+ })
15
+ .describe("Manifest mapping app keys to version information");
16
+ export const ManifestPluginOptionsSchema = z.object({
17
+ manifestPath: z.string().optional().describe("Path to manifest file"),
18
+ manifest: z
19
+ .record(z.string(), z.object({
20
+ implementationName: z.string(),
21
+ version: z.string().optional(),
22
+ }))
23
+ .optional()
24
+ .describe("Direct manifest object"),
25
+ });
@@ -3,7 +3,15 @@ import { FunctionRegistryEntry } from "../../types/sdk";
3
3
  export interface RegisterPluginFunctionOptions {
4
4
  }
5
5
  export interface RegistryPluginProvides {
6
- __registry: FunctionRegistryEntry[];
6
+ getRegistry: () => {
7
+ functions: FunctionRegistryEntry[];
8
+ categories: {
9
+ key: string;
10
+ title: string;
11
+ titlePlural: string;
12
+ functions: string[];
13
+ }[];
14
+ };
7
15
  }
8
16
  export declare const registryPlugin: Plugin<{}, // accepts any SDK shape
9
17
  {}, // requires no context
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/registry/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,WAAW,6BAA6B;CAAG;AAGjD,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,qBAAqB,EAAE,CAAC;CACrC;AAGD,eAAO,MAAM,cAAc,EAAE,MAAM,CACjC,EAAE,EAAE,wBAAwB;AAC5B,EAAE,EAAE,sBAAsB;AAC1B,sBAAsB,CAevB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/registry/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,WAAW,6BAA6B;CAAG;AAEjD,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM;QACjB,SAAS,EAAE,qBAAqB,EAAE,CAAC;QACnC,UAAU,EAAE;YACV,GAAG,EAAE,MAAM,CAAC;YACZ,KAAK,EAAE,MAAM,CAAC;YACd,WAAW,EAAE,MAAM,CAAC;YACpB,SAAS,EAAE,MAAM,EAAE,CAAC;SACrB,EAAE,CAAC;KACL,CAAC;CACH;AAGD,eAAO,MAAM,cAAc,EAAE,MAAM,CACjC,EAAE,EAAE,wBAAwB;AAC5B,EAAE,EAAE,sBAAsB;AAC1B,sBAAsB,CAyFvB,CAAC"}
@@ -1,14 +1,79 @@
1
1
  // Registry plugin requires no context but collects SDK metadata
2
2
  export const registryPlugin = ({ sdk, context }) => {
3
3
  const metaKeys = Object.keys(context.meta || {});
4
- const registryEntries = metaKeys.map((key) => {
4
+ const categoryDefinitions = {
5
+ app: {
6
+ title: "App",
7
+ titlePlural: "Apps",
8
+ },
9
+ authentication: {
10
+ title: "Authentication",
11
+ },
12
+ action: {
13
+ title: "Action",
14
+ },
15
+ http: {
16
+ title: "HTTP Request",
17
+ },
18
+ user: {
19
+ title: "User",
20
+ },
21
+ utility: {
22
+ title: "Utility",
23
+ titlePlural: "Utilities",
24
+ },
25
+ other: {
26
+ title: "Other",
27
+ },
28
+ };
29
+ const functions = metaKeys
30
+ .filter((key) => typeof sdk[key] === "function")
31
+ .map((key) => {
5
32
  return {
6
33
  ...context.meta[key],
34
+ categories: context.meta[key].categories || [],
7
35
  name: key,
8
- implementation: sdk[key],
36
+ };
37
+ })
38
+ .sort((a, b) => a.name.localeCompare(b.name));
39
+ const knownCategories = Object.keys(categoryDefinitions);
40
+ const categories = knownCategories
41
+ .sort((a, b) => {
42
+ // Keep "other" category last
43
+ if (a === "other")
44
+ return 1;
45
+ if (b === "other")
46
+ return -1;
47
+ // Alphabetize by title, not key
48
+ const titleA = categoryDefinitions[a].title;
49
+ const titleB = categoryDefinitions[b].title;
50
+ return titleA.localeCompare(titleB);
51
+ })
52
+ .map((categoryKey) => {
53
+ // Find the functions that are in this category
54
+ const categoryFunctions = functions
55
+ .filter((f) => f.categories.includes(categoryKey) ||
56
+ // If the category is "other" and the function is not in any other category, include it
57
+ (categoryKey === "other" &&
58
+ !f.categories.some((c) => knownCategories.includes(c))))
59
+ .map((f) => f.name)
60
+ .sort(); // Alphabetize functions within each category
61
+ const definition = categoryDefinitions[categoryKey];
62
+ const title = definition.title;
63
+ return {
64
+ key: categoryKey,
65
+ title,
66
+ titlePlural: definition.titlePlural ?? `${title}s`,
67
+ functions: categoryFunctions,
9
68
  };
10
69
  });
70
+ function getRegistry() {
71
+ return {
72
+ functions,
73
+ categories,
74
+ };
75
+ }
11
76
  return {
12
- __registry: registryEntries,
77
+ getRegistry,
13
78
  };
14
79
  };
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/request/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAmBzE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7D,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,OAAO,EAAE;gBACP,WAAW,EAAE,OAAO,kBAAkB,CAAC;aACxC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAChC,EAAE,EAAE,sBAAsB;AAC1B;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,EAAE,0BAA0B;AAC9C,qBAAqB,CAmEtB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/request/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAmBzE,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7D,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,OAAO,EAAE;gBACP,WAAW,EAAE,OAAO,kBAAkB,CAAC;aACxC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,aAAa,EAAE,MAAM,CAChC,EAAE,EAAE,sBAAsB;AAC1B;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,EAAE,0BAA0B;AAC9C,qBAAqB,CAoEtB,CAAC"}
@@ -54,6 +54,7 @@ export const requestPlugin = ({ context }) => {
54
54
  context: {
55
55
  meta: {
56
56
  request: {
57
+ categories: ["http"],
57
58
  inputSchema: RelayRequestSchema,
58
59
  },
59
60
  },
@@ -15,8 +15,13 @@ describe("request plugin", () => {
15
15
  fetch: mockFetch,
16
16
  };
17
17
  });
18
+ const apiPlugin = () => ({
19
+ context: {
20
+ api: mockApiClient,
21
+ },
22
+ });
18
23
  function createTestSdk() {
19
- return createSdk({}, { api: mockApiClient, meta: {} }).addPlugin(requestPlugin);
24
+ return createSdk().addPlugin(apiPlugin).addPlugin(requestPlugin);
20
25
  }
21
26
  describe("schema validation", () => {
22
27
  it("should throw validation error for missing url", async () => {
@@ -12,8 +12,8 @@ export declare const RelayRequestSchema: z.ZodObject<{
12
12
  }, "strip", z.ZodTypeAny, {
13
13
  url: string;
14
14
  method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | undefined;
15
- body?: any;
16
15
  authenticationId?: number | undefined;
16
+ body?: any;
17
17
  callbackUrl?: string | undefined;
18
18
  authenticationTemplate?: string | undefined;
19
19
  headers?: Record<string, string> | [string, string][] | Headers | undefined;
@@ -21,8 +21,8 @@ export declare const RelayRequestSchema: z.ZodObject<{
21
21
  }, {
22
22
  url: string;
23
23
  method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | undefined;
24
- body?: any;
25
24
  authenticationId?: number | undefined;
25
+ body?: any;
26
26
  callbackUrl?: string | undefined;
27
27
  authenticationTemplate?: string | undefined;
28
28
  headers?: Record<string, string> | [string, string][] | Headers | undefined;
@@ -46,8 +46,8 @@ export declare const RelayFetchSchema: z.ZodObject<{
46
46
  }, "strip", z.ZodTypeAny, {
47
47
  url: string;
48
48
  method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | undefined;
49
- body?: any;
50
49
  authenticationId?: number | undefined;
50
+ body?: any;
51
51
  callbackUrl?: string | undefined;
52
52
  authenticationTemplate?: string | undefined;
53
53
  headers?: Record<string, string> | [string, string][] | Headers | undefined;
@@ -55,8 +55,8 @@ export declare const RelayFetchSchema: z.ZodObject<{
55
55
  }, {
56
56
  url: string;
57
57
  method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | undefined;
58
- body?: any;
59
58
  authenticationId?: number | undefined;
59
+ body?: any;
60
60
  callbackUrl?: string | undefined;
61
61
  authenticationTemplate?: string | undefined;
62
62
  headers?: Record<string, string> | [string, string][] | Headers | undefined;
@@ -3,6 +3,7 @@ import type { ApiClient } from "../../api";
3
3
  import { RunActionSchema, type RunActionOptions } from "./schemas";
4
4
  import type { GetActionPluginProvides } from "../getAction";
5
5
  import type { GetAppPluginProvides } from "../getApp";
6
+ import { GetVersionedImplementationId } from "../manifest/schemas";
6
7
  export interface RunActionPluginProvides {
7
8
  runAction: (options?: RunActionOptions) => Promise<{
8
9
  data: any[];
@@ -23,6 +24,7 @@ export interface RunActionPluginProvides {
23
24
  export declare const runActionPlugin: Plugin<GetSdkType<GetActionPluginProvides & GetAppPluginProvides>, // requires getAction and getApp in SDK
24
25
  {
25
26
  api: ApiClient;
27
+ getVersionedImplementationId: GetVersionedImplementationId;
26
28
  }, // requires api in context
27
29
  RunActionPluginProvides>;
28
30
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/runAction/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,eAAe,EACf,KAAK,gBAAgB,EAEtB,MAAM,WAAW,CAAC;AAOnB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAEtD,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,GACjE,aAAa,CAAC;QAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG;QACpD,KAAK,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC;KAC7B,CAAC;IACJ,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,SAAS,EAAE;gBACT,WAAW,EAAE,OAAO,eAAe,CAAC;aACrC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AA2ED,eAAO,MAAM,eAAe,EAAE,MAAM,CAClC,UAAU,CAAC,uBAAuB,GAAG,oBAAoB,CAAC,EAAE,uCAAuC;AACnG;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,EAAE,0BAA0B;AAC9C,uBAAuB,CAwExB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/runAction/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,eAAe,EACf,KAAK,gBAAgB,EAEtB,MAAM,WAAW,CAAC;AAOnB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAEnE,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,GAAG,EAAE,CAAA;KAAE,CAAC,GACjE,aAAa,CAAC;QAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG;QACpD,KAAK,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC;KAC7B,CAAC;IACJ,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,SAAS,EAAE;gBACT,WAAW,EAAE,OAAO,eAAe,CAAC;aACrC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AA4ED,eAAO,MAAM,eAAe,EAAE,MAAM,CAClC,UAAU,CAAC,uBAAuB,GAAG,oBAAoB,CAAC,EAAE,uCAAuC;AACnG;IACE,GAAG,EAAE,SAAS,CAAC;IACf,4BAA4B,EAAE,4BAA4B,CAAC;CAC5D,EAAE,0BAA0B;AAC7B,uBAAuB,CAyExB,CAAC"}
@@ -2,10 +2,9 @@ import { RunActionSchema, } from "./schemas";
2
2
  import { ZapierValidationError, ZapierConfigurationError, ZapierActionError, } from "../../types/errors";
3
3
  import { createPaginatedFunction } from "../../utils/function-utils";
4
4
  async function executeAction(actionOptions) {
5
- const { api, sdk, appKey, actionKey, actionType, executionOptions, authenticationId, } = actionOptions;
6
- // Use the getApp plugin to get the current implementation ID
7
- const appData = await sdk.getApp({ appKey });
8
- const selectedApi = appData.data.current_implementation_id;
5
+ const { api, context, appKey, actionKey, actionType, executionOptions, authenticationId, } = actionOptions;
6
+ // Use the manifest plugin to get the current implementation ID
7
+ const selectedApi = await context.getVersionedImplementationId(appKey);
9
8
  if (!selectedApi) {
10
9
  throw new ZapierConfigurationError("No current_implementation_id found for app", { configType: "current_implementation_id" });
11
10
  }
@@ -49,7 +48,7 @@ export const runActionPlugin = ({ sdk, context }) => {
49
48
  // Execute the action using the Actions API (supports all action types)
50
49
  const result = await executeAction({
51
50
  api,
52
- sdk,
51
+ context,
53
52
  appKey,
54
53
  actionKey,
55
54
  actionType,
@@ -78,6 +77,7 @@ export const runActionPlugin = ({ sdk, context }) => {
78
77
  context: {
79
78
  meta: {
80
79
  runAction: {
80
+ categories: ["action"],
81
81
  inputSchema: RunActionSchema,
82
82
  },
83
83
  },