@zapier/zapier-sdk 0.0.1 → 0.0.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.
Files changed (49) hide show
  1. package/dist/actions-sdk.d.ts +47 -0
  2. package/dist/actions-sdk.js +208 -0
  3. package/dist/api.d.ts +62 -0
  4. package/dist/api.js +227 -0
  5. package/dist/functions/bundleCode.d.ts +18 -0
  6. package/dist/functions/bundleCode.js +91 -0
  7. package/dist/functions/generateTypes.d.ts +16 -0
  8. package/dist/functions/generateTypes.js +271 -0
  9. package/dist/functions/getAction.d.ts +16 -0
  10. package/dist/functions/getAction.js +25 -0
  11. package/dist/functions/getApp.d.ts +14 -0
  12. package/dist/functions/getApp.js +41 -0
  13. package/dist/functions/listActions.d.ts +15 -0
  14. package/dist/functions/listActions.js +127 -0
  15. package/dist/functions/listApps.d.ts +16 -0
  16. package/dist/functions/listApps.js +50 -0
  17. package/dist/functions/listAuths.d.ts +18 -0
  18. package/dist/functions/listAuths.js +118 -0
  19. package/dist/functions/listFields.d.ts +18 -0
  20. package/dist/functions/listFields.js +67 -0
  21. package/dist/functions/runAction.d.ts +18 -0
  22. package/dist/functions/runAction.js +156 -0
  23. package/dist/index.d.ts +12 -3
  24. package/dist/index.js +24 -5
  25. package/dist/output-schemas.d.ts +95 -0
  26. package/dist/output-schemas.js +138 -0
  27. package/dist/schemas.d.ts +338 -0
  28. package/dist/schemas.js +336 -0
  29. package/dist/sdk.d.ts +5 -5
  30. package/dist/sdk.js +8 -8
  31. package/dist/types.d.ts +196 -0
  32. package/dist/types.js +41 -0
  33. package/package.json +5 -3
  34. package/src/actions-sdk.ts +356 -0
  35. package/src/api.ts +361 -0
  36. package/src/functions/bundleCode.ts +85 -0
  37. package/src/functions/generateTypes.ts +309 -0
  38. package/src/functions/getAction.ts +34 -0
  39. package/src/functions/getApp.ts +47 -0
  40. package/src/functions/listActions.ts +151 -0
  41. package/src/functions/listApps.ts +65 -0
  42. package/src/functions/listAuths.ts +161 -0
  43. package/src/functions/listFields.ts +95 -0
  44. package/src/functions/runAction.ts +256 -0
  45. package/src/index.ts +15 -4
  46. package/src/output-schemas.ts +196 -0
  47. package/src/schemas.ts +467 -0
  48. package/src/sdk.ts +13 -13
  49. package/src/types.ts +257 -0
@@ -0,0 +1,161 @@
1
+ import { getOrCreateApiClient } from "../api";
2
+ import type {
3
+ Authentication,
4
+ AuthenticationsResponse,
5
+ FunctionConfig,
6
+ } from "../types";
7
+ import { getApp } from "./getApp";
8
+
9
+ export interface ListAuthsOptions extends FunctionConfig {
10
+ appKey?: string;
11
+ account_id?: string;
12
+ owner?: string;
13
+ limit?: number;
14
+ offset?: number;
15
+ }
16
+
17
+ /**
18
+ * List available authentications with optional filtering
19
+ *
20
+ * This function can be used standalone without instantiating a full SDK,
21
+ * which enables better tree-shaking in applications that only need this functionality.
22
+ *
23
+ * @param options - Filtering, pagination, and API configuration options
24
+ * @returns Promise<Authentication[]> with pagination metadata
25
+ */
26
+ export async function listAuths(
27
+ options: ListAuthsOptions = {},
28
+ ): Promise<Authentication[]> {
29
+ const { token } = options;
30
+
31
+ if (!token && !process.env.ZAPIER_TOKEN) {
32
+ throw new Error(
33
+ "Authentication token is required to list authentications. Please provide token in options or set ZAPIER_TOKEN environment variable.",
34
+ );
35
+ }
36
+
37
+ const api = getOrCreateApiClient(options);
38
+
39
+ // Local function to handle the actual API fetching
40
+ const listAuthsInternal = async (
41
+ options: ListAuthsOptions = {},
42
+ ): Promise<Authentication[]> => {
43
+ // Build search parameters
44
+ const searchParams: Record<string, string> = {};
45
+
46
+ // Handle appKey filtering by getting the selected_api first
47
+ if (options.appKey) {
48
+ try {
49
+ // Use the standalone getApp function
50
+ const app = await getApp({
51
+ key: options.appKey,
52
+ api,
53
+ token: options.token,
54
+ baseUrl: options.baseUrl,
55
+ debug: options.debug,
56
+ fetch: options.fetch,
57
+ });
58
+ const selectedApi = app.current_implementation_id;
59
+ if (selectedApi) {
60
+ // Use versionless_selected_api to find auths across all app versions
61
+ // Extract the base name without the version (e.g., "SlackCLIAPI" from "SlackCLIAPI@1.21.1")
62
+ const versionlessApi = selectedApi.split("@")[0];
63
+ searchParams.versionless_selected_api = versionlessApi;
64
+ }
65
+ } catch (error) {
66
+ // If it's an AppNotFoundError, re-throw it
67
+ if (error instanceof Error && error.name === "AppNotFoundError") {
68
+ throw error;
69
+ }
70
+ // For other errors, continue without app filtering
71
+ console.warn(
72
+ `Warning: Could not filter by app ${options.appKey}:`,
73
+ error instanceof Error ? error.message : "Unknown error",
74
+ );
75
+ }
76
+ }
77
+
78
+ // Add other query parameters if provided
79
+ if (options.account_id) {
80
+ searchParams.account_id = options.account_id;
81
+ }
82
+ if (options.owner) {
83
+ searchParams.owner = options.owner;
84
+ }
85
+ if (options.limit) {
86
+ searchParams.limit = options.limit.toString();
87
+ }
88
+ if (options.offset) {
89
+ searchParams.offset = options.offset.toString();
90
+ }
91
+
92
+ const data: AuthenticationsResponse = await api.get(
93
+ "/api/v4/authentications/",
94
+ {
95
+ searchParams,
96
+ customErrorHandler: (response) => {
97
+ if (response.status === 401) {
98
+ return new Error(
99
+ `Authentication failed. Your token may not have permission to access authentications or may be expired. (HTTP ${response.status})`,
100
+ );
101
+ }
102
+ if (response.status === 403) {
103
+ return new Error(
104
+ `Access forbidden. Your token may not have the required scopes to list authentications. (HTTP ${response.status})`,
105
+ );
106
+ }
107
+ return undefined;
108
+ },
109
+ },
110
+ );
111
+
112
+ // Transform API response
113
+ const auths = data.results || [];
114
+
115
+ // Add pagination metadata to the response
116
+ if (auths.length > 0) {
117
+ (auths as any).__pagination = {
118
+ count: data.count,
119
+ hasNext: !!data.next,
120
+ hasPrevious: !!data.previous,
121
+ nextUrl: data.next,
122
+ previousUrl: data.previous,
123
+ };
124
+ }
125
+
126
+ return auths;
127
+ };
128
+
129
+ // If a limit is provided and no specific owner filter, prioritize owned auths
130
+ if (options.limit && options.owner === undefined) {
131
+ // First get owned auths
132
+ const ownedAuths = await listAuthsInternal({
133
+ ...options,
134
+ owner: "me",
135
+ });
136
+
137
+ // If we have enough owned auths, just slice and return
138
+ if (ownedAuths.length >= options.limit) {
139
+ return ownedAuths.slice(0, options.limit);
140
+ }
141
+
142
+ // Get all auths up to the original limit to fill remaining slots
143
+ const allAuths = await listAuthsInternal({
144
+ ...options,
145
+ owner: undefined,
146
+ });
147
+
148
+ // Filter out auths the user already owns to avoid duplicates
149
+ const ownedAuthIds = new Set(ownedAuths.map((auth) => auth.id));
150
+ const additionalAuths = allAuths.filter(
151
+ (auth) => !ownedAuthIds.has(auth.id),
152
+ );
153
+
154
+ // Combine and slice to the requested limit
155
+ const combined = [...ownedAuths, ...additionalAuths];
156
+ return combined.slice(0, options.limit);
157
+ }
158
+
159
+ // Standard implementation for non-prioritized requests
160
+ return listAuthsInternal(options);
161
+ }
@@ -0,0 +1,95 @@
1
+ import { getOrCreateApiClient } from "../api";
2
+ import type {
3
+ ActionField,
4
+ NeedsRequest,
5
+ NeedsResponse,
6
+ FunctionConfig,
7
+ } from "../types";
8
+ import { getApp } from "./getApp";
9
+
10
+ export interface ListFieldsOptions extends FunctionConfig {
11
+ app: string;
12
+ action: string;
13
+ type: string;
14
+ authId?: number;
15
+ params?: Record<string, any>;
16
+ }
17
+
18
+ /**
19
+ * List available fields for an action
20
+ *
21
+ * This function can be used standalone without instantiating a full SDK,
22
+ * which enables better tree-shaking in applications that only need this functionality.
23
+ *
24
+ * @param options - Action details, auth ID, params, and API configuration options
25
+ * @returns Promise<ActionField[]>
26
+ */
27
+ export async function listFields(
28
+ options: ListFieldsOptions,
29
+ ): Promise<ActionField[]> {
30
+ const api = getOrCreateApiClient(options);
31
+
32
+ // Map consistent parameter names to internal API names
33
+ const { app, action, type, authId, params } = options;
34
+ const appKey = app;
35
+ const actionKey = action;
36
+ const actionType = type;
37
+
38
+ // Use the standalone getApp function
39
+ const appData = await getApp({
40
+ key: appKey,
41
+ api,
42
+ token: options.token,
43
+ baseUrl: options.baseUrl,
44
+ debug: options.debug,
45
+ fetch: options.fetch,
46
+ });
47
+ const selectedApi = appData.current_implementation_id;
48
+
49
+ if (!selectedApi) {
50
+ throw new Error("No current_implementation_id found for app");
51
+ }
52
+
53
+ // Build needs request
54
+ const needsRequest: NeedsRequest = {
55
+ selected_api: selectedApi,
56
+ action: actionKey,
57
+ type_of: actionType,
58
+ authentication_id: authId,
59
+ params: params || {},
60
+ };
61
+
62
+ const needsData: NeedsResponse = await api.post(
63
+ "/api/v4/implementations/needs/",
64
+ needsRequest,
65
+ );
66
+
67
+ if (!needsData.success) {
68
+ throw new Error(
69
+ `Failed to get action fields: ${
70
+ needsData.errors?.join(", ") || "Unknown error"
71
+ }`,
72
+ );
73
+ }
74
+
75
+ // Transform API response to our ActionField interface
76
+ return (needsData.needs || []).map((need: any) => ({
77
+ key: need.key,
78
+ label: need.label,
79
+ required: need.required || false,
80
+ type: need.type,
81
+ helpText: need.help_text,
82
+ helpTextHtml: need.help_text_html,
83
+ choices: need.choices?.map((choice: any) => ({
84
+ value: choice.value,
85
+ label: choice.label,
86
+ })),
87
+ default: need.default,
88
+ placeholder: need.placeholder,
89
+ computed: need.computed,
90
+ customField: need.custom_field,
91
+ dependsOn: need.depends_on,
92
+ format: need.format,
93
+ inputFormat: need.input_format,
94
+ }));
95
+ }
@@ -0,0 +1,256 @@
1
+ import { getOrCreateApiClient, generateRequestId } from "../api";
2
+ import type { ActionExecutionResult, FunctionConfig } from "../types";
3
+ import { getAction } from "./getAction";
4
+ import { getApp } from "./getApp";
5
+
6
+ export interface RunActionOptions extends FunctionConfig {
7
+ app: string;
8
+ type: string;
9
+ action: string;
10
+ inputs?: Record<string, any>;
11
+ authId?: number;
12
+ }
13
+
14
+ /**
15
+ * Execute an action
16
+ *
17
+ * This function can be used standalone without instantiating a full SDK,
18
+ * which enables better tree-shaking in applications that only need this functionality.
19
+ *
20
+ * @param options - Action execution parameters and API configuration options
21
+ * @returns Promise<ActionExecutionResult>
22
+ */
23
+ export async function runAction(
24
+ options: RunActionOptions,
25
+ ): Promise<ActionExecutionResult> {
26
+ const { app, type, action, inputs, authId: providedAuthId, token } = options;
27
+
28
+ if (!token && !process.env.ZAPIER_TOKEN) {
29
+ throw new Error(
30
+ "Authentication token is required to run actions. Please provide token in options or set ZAPIER_TOKEN environment variable.",
31
+ );
32
+ }
33
+
34
+ const api = getOrCreateApiClient(options);
35
+
36
+ // Validate that the action exists
37
+ const actionData = await getAction({
38
+ ...options,
39
+ app: app,
40
+ action: action,
41
+ type: type,
42
+ });
43
+
44
+ // Validate action type matches
45
+ if (actionData.type !== type) {
46
+ throw new Error(
47
+ `Action type mismatch: expected ${type}, got ${actionData.type}`,
48
+ );
49
+ }
50
+
51
+ // Execute the action using the appropriate API based on action type
52
+ const startTime = Date.now();
53
+ const result = await executeActionWithStrategy({
54
+ api,
55
+ appSlug: app,
56
+ actionKey: action,
57
+ actionType: actionData.type,
58
+ executionOptions: { inputs: inputs || {} },
59
+ auth: token
60
+ ? { token: token, authentication_id: providedAuthId }
61
+ : undefined,
62
+ options,
63
+ });
64
+ const executionTime = Date.now() - startTime;
65
+
66
+ return {
67
+ success: true,
68
+ data: result,
69
+ metadata: {
70
+ executionTime,
71
+ requestId: generateRequestId(),
72
+ },
73
+ };
74
+ }
75
+
76
+ interface ExecuteActionStrategyOptions {
77
+ api: any;
78
+ appSlug: string;
79
+ actionKey: string;
80
+ actionType: string;
81
+ executionOptions: { inputs: Record<string, any> };
82
+ auth?: { token: string; authentication_id?: number };
83
+ options: RunActionOptions;
84
+ }
85
+
86
+ async function executeActionWithStrategy(
87
+ strategyOptions: ExecuteActionStrategyOptions,
88
+ ): Promise<any> {
89
+ const {
90
+ api,
91
+ appSlug,
92
+ actionKey,
93
+ actionType,
94
+ executionOptions,
95
+ auth,
96
+ options,
97
+ } = strategyOptions;
98
+
99
+ // Actions API supports: read, read_bulk, write
100
+ // Invoke API supports: search, read, write, read_bulk, and more
101
+
102
+ const actionsApiTypes = ["read", "read_bulk", "write"];
103
+ const useActionsApi = actionsApiTypes.includes(actionType);
104
+
105
+ if (useActionsApi) {
106
+ return executeActionViaActionsApi({
107
+ api,
108
+ appSlug,
109
+ actionKey,
110
+ actionType,
111
+ executionOptions,
112
+ auth,
113
+ options,
114
+ });
115
+ } else {
116
+ return executeActionViaInvokeApi({
117
+ api,
118
+ appSlug,
119
+ actionKey,
120
+ actionType,
121
+ executionOptions,
122
+ auth,
123
+ options,
124
+ });
125
+ }
126
+ }
127
+
128
+ interface ExecuteActionViaActionsApiOptions {
129
+ api: any;
130
+ appSlug: string;
131
+ actionKey: string;
132
+ actionType: string;
133
+ executionOptions: { inputs: Record<string, any> };
134
+ auth?: { token: string; authentication_id?: number };
135
+ options: RunActionOptions;
136
+ }
137
+
138
+ async function executeActionViaActionsApi(
139
+ apiOptions: ExecuteActionViaActionsApiOptions,
140
+ ): Promise<any> {
141
+ const {
142
+ api,
143
+ appSlug,
144
+ actionKey,
145
+ actionType,
146
+ executionOptions,
147
+ auth,
148
+ options,
149
+ } = apiOptions;
150
+
151
+ // Use the standalone getApp function
152
+ const appData = await getApp({
153
+ key: appSlug,
154
+ api,
155
+ token: options.token,
156
+ baseUrl: options.baseUrl,
157
+ debug: options.debug,
158
+ fetch: options.fetch,
159
+ });
160
+ const selectedApi = appData.current_implementation_id;
161
+
162
+ if (!selectedApi) {
163
+ throw new Error("No current_implementation_id found for app");
164
+ }
165
+
166
+ if (!auth?.token) {
167
+ throw new Error(
168
+ "Authentication token is required. Please provide token when creating the SDK.",
169
+ );
170
+ }
171
+
172
+ // Step 1: POST to /actions/v1/runs to start execution
173
+ const runRequest = {
174
+ data: {
175
+ authentication_id: auth.authentication_id || 1,
176
+ selected_api: selectedApi,
177
+ action_key: actionKey,
178
+ action_type: actionType,
179
+ inputs: executionOptions.inputs || {},
180
+ },
181
+ };
182
+
183
+ const runData = await api.post("/api/actions/v1/runs", runRequest);
184
+ const runId = runData.data.id;
185
+
186
+ // Step 2: Poll GET /actions/v1/runs/{run_id} for results
187
+ return await api.poll(`/api/actions/v1/runs/${runId}`, {
188
+ successStatus: 200,
189
+ pendingStatus: 202,
190
+ resultExtractor: (result: any) => result.data,
191
+ });
192
+ }
193
+
194
+ interface ExecuteActionViaInvokeApiOptions {
195
+ api: any;
196
+ appSlug: string;
197
+ actionKey: string;
198
+ actionType: string;
199
+ executionOptions: { inputs: Record<string, any> };
200
+ auth?: { token: string; authentication_id?: number };
201
+ options: RunActionOptions;
202
+ }
203
+
204
+ async function executeActionViaInvokeApi(
205
+ apiOptions: ExecuteActionViaInvokeApiOptions,
206
+ ): Promise<any> {
207
+ const {
208
+ api,
209
+ appSlug,
210
+ actionKey,
211
+ actionType,
212
+ executionOptions,
213
+ auth,
214
+ options,
215
+ } = apiOptions;
216
+
217
+ // Use the standalone getApp function
218
+ const appData = await getApp({
219
+ key: appSlug,
220
+ api,
221
+ token: options.token,
222
+ baseUrl: options.baseUrl,
223
+ debug: options.debug,
224
+ fetch: options.fetch,
225
+ });
226
+ const selectedApi = appData.current_implementation_id;
227
+
228
+ if (!selectedApi) {
229
+ throw new Error("No current_implementation_id found for app");
230
+ }
231
+
232
+ if (!auth?.token) {
233
+ throw new Error(
234
+ "Authentication token is required. Please provide token when creating the SDK.",
235
+ );
236
+ }
237
+
238
+ // Step 1: POST to /invoke/v1/invoke to start execution
239
+ const invokeRequest = {
240
+ selected_api: selectedApi,
241
+ action: actionKey,
242
+ type_of: actionType,
243
+ authentication_id: auth.authentication_id || 1,
244
+ params: executionOptions.inputs || {},
245
+ };
246
+
247
+ const invokeData = await api.post("/api/invoke/v1/invoke", invokeRequest);
248
+ const invocationId = invokeData.invocation_id;
249
+
250
+ // Step 2: Poll GET /invoke/v1/invoke/{invocation_id} for results
251
+ return await api.poll(`/api/invoke/v1/invoke/${invocationId}`, {
252
+ successStatus: 200,
253
+ pendingStatus: 202,
254
+ resultExtractor: (result: any) => result.results || result,
255
+ });
256
+ }
package/src/index.ts CHANGED
@@ -1,6 +1,17 @@
1
- // Export everything from shared and actions
2
- export * from "../../shared-sdk/dist";
3
- export * from "../../actions-sdk/dist";
1
+ // Export everything from types and actions-sdk
2
+ export * from "./types";
3
+ export * from "./actions-sdk";
4
+
5
+ // Export individual functions for tree-shaking
6
+ export { listAuths } from "./functions/listAuths";
7
+ export { listApps } from "./functions/listApps";
8
+ export { getApp } from "./functions/getApp";
9
+ export { listActions } from "./functions/listActions";
10
+ export { getAction } from "./functions/getAction";
11
+ export { runAction } from "./functions/runAction";
12
+ export { listFields } from "./functions/listFields";
13
+ export { generateTypes } from "./functions/generateTypes";
14
+ export { bundleCode } from "./functions/bundleCode";
4
15
 
5
16
  // Export the main combined SDK
6
- export { createZapierSDK, ZapierSDK, ZapierSDKOptions } from "./sdk";
17
+ export { createZapierSdk, ZapierSdk, ZapierSdkOptions } from "./sdk";