@zapier/zapier-sdk 0.5.1 → 0.6.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 (137) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +107 -83
  3. package/dist/api/index.d.ts +1 -1
  4. package/dist/api/index.d.ts.map +1 -1
  5. package/dist/api/schemas.d.ts +6 -6
  6. package/dist/api/types.d.ts +7 -7
  7. package/dist/api/types.d.ts.map +1 -1
  8. package/dist/index.cjs +343 -67
  9. package/dist/index.d.mts +416 -347
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +0 -1
  12. package/dist/index.mjs +343 -67
  13. package/dist/plugins/api/index.js +1 -1
  14. package/dist/plugins/apps/types.d.ts +1 -1
  15. package/dist/plugins/apps/types.d.ts.map +1 -1
  16. package/dist/plugins/findFirstAuthentication/index.d.ts.map +1 -1
  17. package/dist/plugins/findFirstAuthentication/index.js +1 -0
  18. package/dist/plugins/findUniqueAuthentication/index.d.ts.map +1 -1
  19. package/dist/plugins/findUniqueAuthentication/index.js +1 -0
  20. package/dist/plugins/getAction/index.d.ts.map +1 -1
  21. package/dist/plugins/getAction/index.js +1 -0
  22. package/dist/plugins/getAction/index.test.js +1 -1
  23. package/dist/plugins/getApp/index.d.ts +6 -3
  24. package/dist/plugins/getApp/index.d.ts.map +1 -1
  25. package/dist/plugins/getApp/index.js +8 -18
  26. package/dist/plugins/getApp/index.test.js +2 -0
  27. package/dist/plugins/getAuthentication/index.d.ts.map +1 -1
  28. package/dist/plugins/getAuthentication/index.js +1 -0
  29. package/dist/plugins/getAuthentication/index.test.js +12 -1
  30. package/dist/plugins/getProfile/index.d.ts.map +1 -1
  31. package/dist/plugins/getProfile/index.js +1 -0
  32. package/dist/plugins/listActions/index.d.ts +5 -3
  33. package/dist/plugins/listActions/index.d.ts.map +1 -1
  34. package/dist/plugins/listActions/index.js +6 -6
  35. package/dist/plugins/listActions/index.test.js +26 -74
  36. package/dist/plugins/listActions/schemas.d.ts +4 -4
  37. package/dist/plugins/listApps/index.d.ts.map +1 -1
  38. package/dist/plugins/listApps/index.js +1 -0
  39. package/dist/plugins/listApps/schemas.d.ts +2 -2
  40. package/dist/plugins/listAuthentications/index.d.ts +4 -2
  41. package/dist/plugins/listAuthentications/index.d.ts.map +1 -1
  42. package/dist/plugins/listAuthentications/index.js +9 -12
  43. package/dist/plugins/listAuthentications/index.test.js +33 -40
  44. package/dist/plugins/listAuthentications/schemas.d.ts +4 -4
  45. package/dist/plugins/listInputFields/index.d.ts +3 -1
  46. package/dist/plugins/listInputFields/index.d.ts.map +1 -1
  47. package/dist/plugins/listInputFields/index.js +5 -5
  48. package/dist/plugins/listInputFields/index.test.js +10 -8
  49. package/dist/plugins/listInputFields/schemas.d.ts +4 -4
  50. package/dist/plugins/lockVersion/index.d.ts +24 -0
  51. package/dist/plugins/lockVersion/index.d.ts.map +1 -0
  52. package/dist/plugins/lockVersion/index.js +72 -0
  53. package/dist/plugins/lockVersion/index.test.d.ts +2 -0
  54. package/dist/plugins/lockVersion/index.test.d.ts.map +1 -0
  55. package/dist/plugins/lockVersion/index.test.js +129 -0
  56. package/dist/plugins/lockVersion/schemas.d.ts +10 -0
  57. package/dist/plugins/lockVersion/schemas.d.ts.map +1 -0
  58. package/dist/plugins/lockVersion/schemas.js +6 -0
  59. package/dist/plugins/manifest/index.d.ts +24 -0
  60. package/dist/plugins/manifest/index.d.ts.map +1 -0
  61. package/dist/plugins/manifest/index.js +119 -0
  62. package/dist/plugins/manifest/index.test.d.ts +2 -0
  63. package/dist/plugins/manifest/index.test.d.ts.map +1 -0
  64. package/dist/plugins/manifest/index.test.js +331 -0
  65. package/dist/plugins/manifest/schemas.d.ts +64 -0
  66. package/dist/plugins/manifest/schemas.d.ts.map +1 -0
  67. package/dist/plugins/manifest/schemas.js +25 -0
  68. package/dist/plugins/registry/index.d.ts +9 -1
  69. package/dist/plugins/registry/index.d.ts.map +1 -1
  70. package/dist/plugins/registry/index.js +68 -3
  71. package/dist/plugins/request/index.d.ts.map +1 -1
  72. package/dist/plugins/request/index.js +1 -0
  73. package/dist/plugins/request/index.test.js +6 -1
  74. package/dist/plugins/request/schemas.d.ts +4 -4
  75. package/dist/plugins/runAction/index.d.ts +2 -0
  76. package/dist/plugins/runAction/index.d.ts.map +1 -1
  77. package/dist/plugins/runAction/index.js +5 -5
  78. package/dist/plugins/runAction/index.test.js +9 -8
  79. package/dist/plugins/runAction/schemas.d.ts +4 -4
  80. package/dist/schemas/Auth.d.ts +4 -4
  81. package/dist/schemas/Field.d.ts.map +1 -1
  82. package/dist/sdk.d.ts +3 -3
  83. package/dist/sdk.d.ts.map +1 -1
  84. package/dist/sdk.js +18 -7
  85. package/dist/sdk.test.js +1 -1
  86. package/dist/types/errors.d.ts +6 -6
  87. package/dist/types/errors.d.ts.map +1 -1
  88. package/dist/types/events.d.ts +1 -1
  89. package/dist/types/events.d.ts.map +1 -1
  90. package/dist/types/plugin.d.ts +10 -2
  91. package/dist/types/plugin.d.ts.map +1 -1
  92. package/dist/types/sdk.d.ts +13 -2
  93. package/dist/types/sdk.d.ts.map +1 -1
  94. package/dist/utils/validation.test.js +2 -1
  95. package/package.json +2 -2
  96. package/src/api/client.ts +3 -3
  97. package/src/api/index.ts +2 -0
  98. package/src/api/types.ts +15 -7
  99. package/src/index.ts +0 -2
  100. package/src/plugins/api/index.ts +1 -1
  101. package/src/plugins/apps/types.ts +1 -1
  102. package/src/plugins/findFirstAuthentication/index.ts +1 -0
  103. package/src/plugins/findUniqueAuthentication/index.ts +1 -0
  104. package/src/plugins/getAction/index.test.ts +1 -1
  105. package/src/plugins/getAction/index.ts +1 -0
  106. package/src/plugins/getApp/index.test.ts +2 -0
  107. package/src/plugins/getApp/index.ts +12 -24
  108. package/src/plugins/getAuthentication/index.test.ts +13 -3
  109. package/src/plugins/getAuthentication/index.ts +1 -0
  110. package/src/plugins/getProfile/index.ts +1 -0
  111. package/src/plugins/listActions/index.test.ts +30 -89
  112. package/src/plugins/listActions/index.ts +34 -27
  113. package/src/plugins/listApps/index.ts +1 -0
  114. package/src/plugins/listAuthentications/index.test.ts +38 -47
  115. package/src/plugins/listAuthentications/index.ts +21 -18
  116. package/src/plugins/listInputFields/index.test.ts +12 -9
  117. package/src/plugins/listInputFields/index.ts +10 -6
  118. package/src/plugins/lockVersion/index.test.ts +176 -0
  119. package/src/plugins/lockVersion/index.ts +112 -0
  120. package/src/plugins/lockVersion/schemas.ts +9 -0
  121. package/src/plugins/manifest/index.test.ts +439 -0
  122. package/src/plugins/manifest/index.ts +171 -0
  123. package/src/plugins/manifest/schemas.ts +53 -0
  124. package/src/plugins/registry/index.ts +89 -8
  125. package/src/plugins/request/index.test.ts +8 -4
  126. package/src/plugins/request/index.ts +1 -0
  127. package/src/plugins/runAction/index.test.ts +9 -8
  128. package/src/plugins/runAction/index.ts +18 -9
  129. package/src/schemas/Field.ts +5 -2
  130. package/src/sdk.test.ts +1 -1
  131. package/src/sdk.ts +22 -7
  132. package/src/types/errors.ts +9 -6
  133. package/src/types/events.ts +1 -1
  134. package/src/types/plugin.ts +14 -2
  135. package/src/types/sdk.ts +15 -1
  136. package/src/utils/validation.test.ts +2 -1
  137. package/tsconfig.tsbuildinfo +1 -1
@@ -3,9 +3,16 @@ import { FunctionRegistryEntry } from "../../types/sdk";
3
3
 
4
4
  export interface RegisterPluginFunctionOptions {}
5
5
 
6
- // Registry plugin creates and populates __registry for CLI backward compatibility
7
6
  export interface RegistryPluginProvides {
8
- __registry: FunctionRegistryEntry[];
7
+ getRegistry: () => {
8
+ functions: FunctionRegistryEntry[];
9
+ categories: {
10
+ key: string;
11
+ title: string;
12
+ titlePlural: string;
13
+ functions: string[];
14
+ }[];
15
+ };
9
16
  }
10
17
 
11
18
  // Registry plugin requires no context but collects SDK metadata
@@ -16,15 +23,89 @@ export const registryPlugin: Plugin<
16
23
  > = ({ sdk, context }) => {
17
24
  const metaKeys = Object.keys(context.meta || {});
18
25
 
19
- const registryEntries = metaKeys.map((key) => {
26
+ const categoryDefinitions: Record<
27
+ string,
28
+ { title: string; titlePlural?: string }
29
+ > = {
30
+ app: {
31
+ title: "App",
32
+ titlePlural: "Apps",
33
+ },
34
+ authentication: {
35
+ title: "Authentication",
36
+ },
37
+ action: {
38
+ title: "Action",
39
+ },
40
+ http: {
41
+ title: "HTTP Request",
42
+ },
43
+ user: {
44
+ title: "User",
45
+ },
46
+ utility: {
47
+ title: "Utility",
48
+ titlePlural: "Utilities",
49
+ },
50
+ other: {
51
+ title: "Other",
52
+ },
53
+ };
54
+
55
+ const functions = metaKeys
56
+ .filter((key) => typeof sdk[key as keyof typeof sdk] === "function")
57
+ .map((key) => {
58
+ return {
59
+ ...context.meta[key],
60
+ categories: context.meta[key].categories || [],
61
+ name: key,
62
+ };
63
+ })
64
+ .sort((a, b) => a.name.localeCompare(b.name));
65
+
66
+ const knownCategories = Object.keys(categoryDefinitions);
67
+
68
+ const categories = knownCategories
69
+ .sort((a, b) => {
70
+ // Keep "other" category last
71
+ if (a === "other") return 1;
72
+ if (b === "other") return -1;
73
+ // Alphabetize by title, not key
74
+ const titleA = categoryDefinitions[a].title;
75
+ const titleB = categoryDefinitions[b].title;
76
+ return titleA.localeCompare(titleB);
77
+ })
78
+ .map((categoryKey) => {
79
+ // Find the functions that are in this category
80
+ const categoryFunctions = functions
81
+ .filter(
82
+ (f) =>
83
+ f.categories.includes(categoryKey) ||
84
+ // If the category is "other" and the function is not in any other category, include it
85
+ (categoryKey === "other" &&
86
+ !f.categories.some((c) => knownCategories.includes(c))),
87
+ )
88
+ .map((f) => f.name)
89
+ .sort(); // Alphabetize functions within each category
90
+
91
+ const definition = categoryDefinitions[categoryKey];
92
+ const title = definition.title;
93
+ return {
94
+ key: categoryKey,
95
+ title,
96
+ titlePlural: definition.titlePlural ?? `${title}s`,
97
+ functions: categoryFunctions,
98
+ };
99
+ });
100
+
101
+ function getRegistry() {
20
102
  return {
21
- ...context.meta[key],
22
- name: key,
23
- implementation: sdk[key as keyof typeof sdk],
103
+ functions,
104
+ categories,
24
105
  };
25
- });
106
+ }
26
107
 
27
108
  return {
28
- __registry: registryEntries,
109
+ getRegistry,
29
110
  };
30
111
  };
@@ -2,8 +2,8 @@ import { describe, it, expect, vi, beforeEach } from "vitest";
2
2
  import { ZapierValidationError } from "../../types/errors";
3
3
  import { requestPlugin } from "./index";
4
4
  import { createSdk } from "../../sdk";
5
- import type { ApiClient } from "../../api";
6
5
  import type { RelayRequestOptions } from "./schemas";
6
+ import type { ApiClient } from "../../api";
7
7
 
8
8
  describe("request plugin", () => {
9
9
  let mockApiClient: ApiClient;
@@ -23,10 +23,14 @@ describe("request plugin", () => {
23
23
  } as Partial<ApiClient> as ApiClient;
24
24
  });
25
25
 
26
+ const apiPlugin = () => ({
27
+ context: {
28
+ api: mockApiClient,
29
+ },
30
+ });
31
+
26
32
  function createTestSdk() {
27
- return createSdk({}, { api: mockApiClient, meta: {} }).addPlugin(
28
- requestPlugin,
29
- );
33
+ return createSdk().addPlugin(apiPlugin).addPlugin(requestPlugin);
30
34
  }
31
35
 
32
36
  describe("schema validation", () => {
@@ -95,6 +95,7 @@ export const requestPlugin: Plugin<
95
95
  context: {
96
96
  meta: {
97
97
  request: {
98
+ categories: ["http"],
98
99
  inputSchema: RelayRequestSchema,
99
100
  },
100
101
  },
@@ -44,16 +44,17 @@ describe("runAction plugin", () => {
44
44
  mockGetAction = vi.fn().mockResolvedValue({
45
45
  data: mockAction,
46
46
  });
47
-
48
- mockGetApp = vi.fn().mockResolvedValue({
49
- data: { current_implementation_id: "SlackCLIAPI" },
50
- });
51
47
  });
52
48
 
53
49
  function createTestSdk() {
54
50
  return createSdk(
51
+ {},
55
52
  { getAction: mockGetAction, getApp: mockGetApp }, // Provide getAction and getApp in SDK
56
- { api: mockApiClient, meta: {} },
53
+ {
54
+ api: mockApiClient,
55
+ meta: {},
56
+ getVersionedImplementationId: () => "SlackCLIAPI@1.21.1",
57
+ },
57
58
  ).addPlugin(runActionPlugin as any);
58
59
  }
59
60
 
@@ -151,7 +152,7 @@ describe("runAction plugin", () => {
151
152
 
152
153
  expect(mockApiClient.post).toHaveBeenCalledWith("/api/actions/v1/runs", {
153
154
  data: {
154
- selected_api: "SlackCLIAPI",
155
+ selected_api: "SlackCLIAPI@1.21.1",
155
156
  action_key: "send_message",
156
157
  action_type: "write",
157
158
  inputs: { message: "Hello", channel: "#general" },
@@ -180,7 +181,7 @@ describe("runAction plugin", () => {
180
181
 
181
182
  expect(mockApiClient.post).toHaveBeenCalledWith("/api/actions/v1/runs", {
182
183
  data: {
183
- selected_api: "SlackCLIAPI",
184
+ selected_api: "SlackCLIAPI@1.21.1",
184
185
  action_key: "send_message",
185
186
  action_type: "write",
186
187
  inputs: { message: "Hello" },
@@ -206,7 +207,7 @@ describe("runAction plugin", () => {
206
207
  expect.objectContaining({
207
208
  data: expect.objectContaining({
208
209
  inputs: { message: "Hello" },
209
- selected_api: "SlackCLIAPI",
210
+ selected_api: "SlackCLIAPI@1.21.1",
210
211
  action_key: "send_message",
211
212
  action_type: "write",
212
213
  }),
@@ -13,6 +13,7 @@ import {
13
13
  import { createPaginatedFunction } from "../../utils/function-utils";
14
14
  import type { GetActionPluginProvides } from "../getAction";
15
15
  import type { GetAppPluginProvides } from "../getApp";
16
+ import { GetVersionedImplementationId } from "../manifest/schemas";
16
17
 
17
18
  export interface RunActionPluginProvides {
18
19
  runAction: (options?: RunActionOptions) => Promise<{ data: any[] }> &
@@ -30,7 +31,9 @@ export interface RunActionPluginProvides {
30
31
 
31
32
  interface ExecuteActionOptions {
32
33
  api: ApiClient;
33
- sdk: GetSdkType<GetActionPluginProvides & GetAppPluginProvides>;
34
+ context: {
35
+ getVersionedImplementationId: GetVersionedImplementationId;
36
+ };
34
37
  appKey: string;
35
38
  actionKey: string;
36
39
  actionType: string;
@@ -45,7 +48,7 @@ async function executeAction(actionOptions: ExecuteActionOptions): Promise<{
45
48
  }> {
46
49
  const {
47
50
  api,
48
- sdk,
51
+ context,
49
52
  appKey,
50
53
  actionKey,
51
54
  actionType,
@@ -53,9 +56,8 @@ async function executeAction(actionOptions: ExecuteActionOptions): Promise<{
53
56
  authenticationId,
54
57
  } = actionOptions;
55
58
 
56
- // Use the getApp plugin to get the current implementation ID
57
- const appData = await sdk.getApp({ appKey });
58
- const selectedApi = appData.data.current_implementation_id;
59
+ // Use the manifest plugin to get the current implementation ID
60
+ const selectedApi = await context.getVersionedImplementationId(appKey);
59
61
 
60
62
  if (!selectedApi) {
61
63
  throw new ZapierConfigurationError(
@@ -87,20 +89,26 @@ async function executeAction(actionOptions: ExecuteActionOptions): Promise<{
87
89
  data: runRequestData,
88
90
  };
89
91
 
90
- const runData = await api.post("/api/actions/v1/runs", runRequest);
92
+ const runData = await api.post<{ data: { id: string } }>(
93
+ "/api/actions/v1/runs",
94
+ runRequest,
95
+ );
91
96
  const runId = runData.data.id;
92
97
 
93
98
  // Step 2: Poll GET /actions/v1/runs/{run_id} for results
94
99
  return await api.poll(`/api/actions/v1/runs/${runId}`, {
95
100
  successStatus: 200,
96
101
  pendingStatus: 202,
97
- resultExtractor: (result: { data: unknown }) => result.data,
102
+ resultExtractor: (result: unknown) => (result as { data: unknown }).data,
98
103
  });
99
104
  }
100
105
 
101
106
  export const runActionPlugin: Plugin<
102
107
  GetSdkType<GetActionPluginProvides & GetAppPluginProvides>, // requires getAction and getApp in SDK
103
- { api: ApiClient }, // requires api in context
108
+ {
109
+ api: ApiClient;
110
+ getVersionedImplementationId: GetVersionedImplementationId;
111
+ }, // requires api in context
104
112
  RunActionPluginProvides
105
113
  > = ({ sdk, context }) => {
106
114
  const runAction = createPaginatedFunction(async function runActionPage(
@@ -132,7 +140,7 @@ export const runActionPlugin: Plugin<
132
140
  // Execute the action using the Actions API (supports all action types)
133
141
  const result = await executeAction({
134
142
  api,
135
- sdk,
143
+ context,
136
144
  appKey,
137
145
  actionKey,
138
146
  actionType,
@@ -168,6 +176,7 @@ export const runActionPlugin: Plugin<
168
176
  context: {
169
177
  meta: {
170
178
  runAction: {
179
+ categories: ["action"],
171
180
  inputSchema: RunActionSchema,
172
181
  },
173
182
  },
@@ -65,10 +65,13 @@ export const InputFieldItemSchema = withFormatter(
65
65
  if (item.choices && item.choices.length > 0) {
66
66
  const choiceText =
67
67
  item.choices.length <= 3
68
- ? `Choices: ${item.choices.map((c: any) => c.label || c.value).join(", ")}`
68
+ ? `Choices: ${item.choices.map((c: { label?: string; value: string | number }) => c.label || c.value).join(", ")}`
69
69
  : `Choices: ${item.choices
70
70
  .slice(0, 3)
71
- .map((c: any) => c.label || c.value)
71
+ .map(
72
+ (c: { label?: string; value: string | number }) =>
73
+ c.label || c.value,
74
+ )
72
75
  .join(", ")} (+${item.choices.length - 3} more)`;
73
76
  details.push({ text: choiceText, style: "accent" as const });
74
77
  }
package/src/sdk.test.ts CHANGED
@@ -181,7 +181,7 @@ describe("Flat Plugin System", () => {
181
181
 
182
182
  const baseSdk = { existingMethod: () => "base" };
183
183
  const baseContext = { customContext: "custom", meta: {} };
184
- const sdk = createSdk(baseSdk, baseContext).addPlugin(pluginWithHelper);
184
+ const sdk = createSdk({}, baseSdk, baseContext).addPlugin(pluginWithHelper);
185
185
 
186
186
  expect(sdk.helperMethod()).toBe("Helper: base + custom");
187
187
  expect(sdk.existingMethod()).toBe("base"); // Original method still works
package/src/sdk.ts CHANGED
@@ -10,6 +10,7 @@ import type {
10
10
  Plugin,
11
11
  ExtractContextProperties,
12
12
  PluginProvides,
13
+ PluginMeta,
13
14
  } from "./types/plugin";
14
15
 
15
16
  // Import plugin functions
@@ -29,6 +30,8 @@ import { findFirstAuthenticationPlugin } from "./plugins/findFirstAuthentication
29
30
  import { findUniqueAuthenticationPlugin } from "./plugins/findUniqueAuthentication";
30
31
  import { listInputFieldsPlugin } from "./plugins/listInputFields";
31
32
  import { requestPlugin } from "./plugins/request";
33
+ import { manifestPlugin } from "./plugins/manifest";
34
+ import { lockVersionPlugin } from "./plugins/lockVersion";
32
35
 
33
36
  // Full SDK interface with plugins applied
34
37
  // Note: ZapierSdk is now defined as ReturnType<typeof createZapierSdk> at the bottom of this file
@@ -38,8 +41,9 @@ export interface ZapierSdkOptions extends BaseSdkOptions {}
38
41
  // Create SDK that supports flat plugins - returns an SDK, not a builder
39
42
  export function createSdk<
40
43
  TCurrentSdk = {},
41
- TCurrentContext = { meta: Record<string, any> },
44
+ TCurrentContext = { meta: Record<string, PluginMeta> },
42
45
  >(
46
+ options: ZapierSdkOptions = {},
43
47
  initialSdk: TCurrentSdk = {} as TCurrentSdk,
44
48
  initialContext: TCurrentContext = { meta: {} } as TCurrentContext,
45
49
  ): Sdk<TCurrentSdk, TCurrentContext> {
@@ -52,7 +56,7 @@ export function createSdk<
52
56
  TRequiresContext,
53
57
  TProvides
54
58
  >,
55
- options: any = {},
59
+ addPluginOptions: any = {},
56
60
  ) {
57
61
  // Create SDK with getContext method for plugins to use
58
62
  const currentSdkWithContext = {
@@ -63,8 +67,12 @@ export function createSdk<
63
67
  // Apply the plugin with options merged in
64
68
  const pluginResult = plugin({
65
69
  sdk: currentSdkWithContext,
66
- context: initialContext,
67
- ...options,
70
+ context: {
71
+ ...initialContext,
72
+ // Add the options that createSdk was called with to context
73
+ options,
74
+ },
75
+ ...addPluginOptions,
68
76
  });
69
77
 
70
78
  // Extract context from plugin result if present
@@ -77,6 +85,7 @@ export function createSdk<
77
85
  // Ensure meta is always present, starting with existing or empty object
78
86
  let newContext = {
79
87
  ...initialContext,
88
+ ...addPluginOptions,
80
89
  meta: (initialContext as any).meta || {},
81
90
  } as TCurrentContext & NonNullable<ExtractContextProperties<TProvides>>;
82
91
 
@@ -103,19 +112,22 @@ export function createSdk<
103
112
  }
104
113
 
105
114
  // Recursively create new SDK with updated properties
106
- return createSdk(newSdk, newContext) as any;
115
+ return createSdk(options, newSdk, newContext) as any;
107
116
  },
108
117
  };
109
118
  }
110
119
 
111
120
  export function createZapierSdk(options: ZapierSdkOptions = {}): ZapierSdk {
112
121
  return (
113
- createSdk()
122
+ createSdk(options)
114
123
  // Provides the API client in context
115
- .addPlugin(apiPlugin, options)
124
+ .addPlugin(apiPlugin)
125
+
126
+ // Manifest plugin (provides version locking context)
116
127
 
117
128
  // Apps/actions/fields
118
129
  .addPlugin(listAppsPlugin)
130
+ .addPlugin(manifestPlugin)
119
131
  .addPlugin(getAppPlugin)
120
132
  .addPlugin(listActionsPlugin)
121
133
  .addPlugin(getActionPlugin)
@@ -124,6 +136,9 @@ export function createZapierSdk(options: ZapierSdkOptions = {}): ZapierSdk {
124
136
  // Run action
125
137
  .addPlugin(runActionPlugin)
126
138
 
139
+ // Version locking
140
+ .addPlugin(lockVersionPlugin)
141
+
127
142
  // Authentications
128
143
  .addPlugin(listAuthenticationsPlugin)
129
144
  .addPlugin(getAuthenticationPlugin)
@@ -6,8 +6,8 @@ export interface ApiError {
6
6
  code: string;
7
7
  title: string;
8
8
  detail: string;
9
- source?: any;
10
- meta?: any;
9
+ source?: unknown;
10
+ meta?: unknown;
11
11
  }
12
12
 
13
13
  /**
@@ -17,7 +17,7 @@ export interface ErrorOptions {
17
17
  statusCode?: number;
18
18
  errors?: ApiError[];
19
19
  cause?: unknown;
20
- response?: any;
20
+ response?: unknown;
21
21
  }
22
22
 
23
23
  /**
@@ -29,7 +29,7 @@ export abstract class ZapierError extends Error {
29
29
  public statusCode?: number;
30
30
  public errors?: ApiError[];
31
31
  public cause?: unknown;
32
- public response?: any;
32
+ public response?: unknown;
33
33
 
34
34
  constructor(message: string, options: ErrorOptions = {}) {
35
35
  super(message);
@@ -74,9 +74,12 @@ export class ZapierAppNotFoundError extends ZapierError {
74
74
  */
75
75
  export class ZapierValidationError extends ZapierError {
76
76
  readonly name = "ZapierValidationError";
77
- public details?: any;
77
+ public details?: unknown;
78
78
 
79
- constructor(message: string, options: ErrorOptions & { details?: any } = {}) {
79
+ constructor(
80
+ message: string,
81
+ options: ErrorOptions & { details?: unknown } = {},
82
+ ) {
80
83
  super(message, options);
81
84
  this.details = options.details;
82
85
  }
@@ -8,7 +8,7 @@
8
8
  // Generic event system
9
9
  export interface SdkEvent {
10
10
  type: string;
11
- payload?: Record<string, any>;
11
+ payload?: Record<string, unknown>;
12
12
  timestamp?: number;
13
13
  }
14
14
 
@@ -7,6 +7,9 @@
7
7
  * ability to catch missing context at compile time.
8
8
  */
9
9
 
10
+ import type { z } from "zod";
11
+ import { BaseSdkOptions } from "./sdk";
12
+
10
13
  export interface PluginDependencies<TSdk = {}, TContext = {}> {
11
14
  sdk: TSdk;
12
15
  context: TContext;
@@ -17,6 +20,12 @@ export interface PluginProvides extends Record<string, any> {
17
20
  context?: Record<string, any>;
18
21
  }
19
22
 
23
+ export interface PluginMeta {
24
+ categories: string[];
25
+ inputSchema: z.ZodSchema;
26
+ [key: string]: any;
27
+ }
28
+
20
29
  // Utility type to extract SDK properties (everything except 'context')
21
30
  export type ExtractSdkProperties<T extends Record<string, any>> = Omit<
22
31
  T,
@@ -52,7 +61,10 @@ export interface Plugin<
52
61
  > {
53
62
  (params: {
54
63
  sdk: TSdk;
55
- context: TRequiresContext & { meta: Record<string, any> };
64
+ context: TRequiresContext & {
65
+ meta: Record<string, PluginMeta>;
66
+ options: BaseSdkOptions;
67
+ };
56
68
  }): TProvides;
57
69
  }
58
70
 
@@ -86,7 +98,7 @@ type ContextError<TRequired, TCurrent> =
86
98
  */
87
99
  export type Sdk<
88
100
  TCurrentSdk = {},
89
- TCurrentContext = { meta: Record<string, any> },
101
+ TCurrentContext = { meta: Record<string, PluginMeta> },
90
102
  > = TCurrentSdk & {
91
103
  addPlugin<TRequiresContext, TProvides extends PluginProvides>(
92
104
  plugin: Plugin<
package/src/types/sdk.ts CHANGED
@@ -12,6 +12,15 @@ export interface BaseSdkOptions {
12
12
  fetch?: typeof fetch;
13
13
  baseUrl?: string;
14
14
  debug?: boolean;
15
+ manifestPath?: string;
16
+ manifest?: {
17
+ apps: {
18
+ [appKey: string]: {
19
+ implementationName: string;
20
+ version?: string;
21
+ };
22
+ };
23
+ };
15
24
  }
16
25
 
17
26
  // SDK interface composed from individual function interfaces
@@ -20,6 +29,8 @@ import type { GetAuthenticationSdkFunction } from "../plugins/getAuthentication/
20
29
  import type { FindFirstAuthenticationSdkFunction } from "../plugins/findFirstAuthentication/schemas";
21
30
  import type { FindUniqueAuthenticationSdkFunction } from "../plugins/findUniqueAuthentication/schemas";
22
31
  import type { RelayRequestSdkFunction } from "../plugins/request/schemas";
32
+ import type { LockVersionPluginProvides } from "../plugins/lockVersion";
33
+
23
34
  import type { z } from "zod";
24
35
  import { RegistryPluginProvides } from "../plugins/registry";
25
36
  import { GetProfilePluginProvides } from "../plugins/getProfile";
@@ -37,6 +48,7 @@ import { FindUniqueAuthenticationPluginProvides } from "../plugins/findUniqueAut
37
48
  import { ListInputFieldsPluginProvides } from "../plugins/listInputFields";
38
49
  import { RequestPluginProvides } from "../plugins/request";
39
50
  import { GetSdkType } from "./plugin";
51
+ import { ManifestPluginProvides } from "../plugins/manifest";
40
52
 
41
53
  // Plugin interfaces
42
54
  // Note: Plugin extension types removed - now using new plugin system
@@ -45,7 +57,7 @@ import { GetSdkType } from "./plugin";
45
57
  export interface FunctionRegistryEntry {
46
58
  name: string;
47
59
  inputSchema: z.ZodSchema;
48
- implementation: Function;
60
+ categories: string[];
49
61
  }
50
62
 
51
63
  // Compose SDK functions from individual function interfaces
@@ -71,10 +83,12 @@ export type ZapierSdk = GetSdkType<
71
83
  FetchPluginProvides &
72
84
  AppsPluginProvides &
73
85
  ListAppsPluginProvides &
86
+ ManifestPluginProvides &
74
87
  GetAppPluginProvides &
75
88
  ListActionsPluginProvides &
76
89
  GetActionPluginProvides &
77
90
  RunActionPluginProvides &
91
+ LockVersionPluginProvides &
78
92
  ListAuthenticationsPluginProvides &
79
93
  GetAuthenticationPluginProvides &
80
94
  FindFirstAuthenticationPluginProvides &
@@ -42,7 +42,8 @@ describe("validation utilities", () => {
42
42
  expect((error as ZapierValidationError).message).toContain("name:");
43
43
  expect((error as ZapierValidationError).message).toContain("age:");
44
44
  expect(
45
- (error as ZapierValidationError).details.zodErrors,
45
+ ((error as ZapierValidationError).details as { zodErrors: unknown })
46
+ ?.zodErrors,
46
47
  ).toBeDefined();
47
48
  }
48
49
  });