@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.
- package/CHANGELOG.md +19 -0
- package/README.md +107 -83
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/schemas.d.ts +6 -6
- package/dist/api/types.d.ts +7 -7
- package/dist/api/types.d.ts.map +1 -1
- package/dist/index.cjs +343 -67
- package/dist/index.d.mts +416 -347
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.mjs +343 -67
- package/dist/plugins/api/index.js +1 -1
- package/dist/plugins/apps/types.d.ts +1 -1
- package/dist/plugins/apps/types.d.ts.map +1 -1
- package/dist/plugins/findFirstAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/findFirstAuthentication/index.js +1 -0
- package/dist/plugins/findUniqueAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/findUniqueAuthentication/index.js +1 -0
- package/dist/plugins/getAction/index.d.ts.map +1 -1
- package/dist/plugins/getAction/index.js +1 -0
- package/dist/plugins/getAction/index.test.js +1 -1
- package/dist/plugins/getApp/index.d.ts +6 -3
- package/dist/plugins/getApp/index.d.ts.map +1 -1
- package/dist/plugins/getApp/index.js +8 -18
- package/dist/plugins/getApp/index.test.js +2 -0
- package/dist/plugins/getAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/getAuthentication/index.js +1 -0
- package/dist/plugins/getAuthentication/index.test.js +12 -1
- package/dist/plugins/getProfile/index.d.ts.map +1 -1
- package/dist/plugins/getProfile/index.js +1 -0
- package/dist/plugins/listActions/index.d.ts +5 -3
- package/dist/plugins/listActions/index.d.ts.map +1 -1
- package/dist/plugins/listActions/index.js +6 -6
- package/dist/plugins/listActions/index.test.js +26 -74
- package/dist/plugins/listActions/schemas.d.ts +4 -4
- package/dist/plugins/listApps/index.d.ts.map +1 -1
- package/dist/plugins/listApps/index.js +1 -0
- package/dist/plugins/listApps/schemas.d.ts +2 -2
- package/dist/plugins/listAuthentications/index.d.ts +4 -2
- package/dist/plugins/listAuthentications/index.d.ts.map +1 -1
- package/dist/plugins/listAuthentications/index.js +9 -12
- package/dist/plugins/listAuthentications/index.test.js +33 -40
- package/dist/plugins/listAuthentications/schemas.d.ts +4 -4
- package/dist/plugins/listInputFields/index.d.ts +3 -1
- package/dist/plugins/listInputFields/index.d.ts.map +1 -1
- package/dist/plugins/listInputFields/index.js +5 -5
- package/dist/plugins/listInputFields/index.test.js +10 -8
- package/dist/plugins/listInputFields/schemas.d.ts +4 -4
- package/dist/plugins/lockVersion/index.d.ts +24 -0
- package/dist/plugins/lockVersion/index.d.ts.map +1 -0
- package/dist/plugins/lockVersion/index.js +72 -0
- package/dist/plugins/lockVersion/index.test.d.ts +2 -0
- package/dist/plugins/lockVersion/index.test.d.ts.map +1 -0
- package/dist/plugins/lockVersion/index.test.js +129 -0
- package/dist/plugins/lockVersion/schemas.d.ts +10 -0
- package/dist/plugins/lockVersion/schemas.d.ts.map +1 -0
- package/dist/plugins/lockVersion/schemas.js +6 -0
- package/dist/plugins/manifest/index.d.ts +24 -0
- package/dist/plugins/manifest/index.d.ts.map +1 -0
- package/dist/plugins/manifest/index.js +119 -0
- package/dist/plugins/manifest/index.test.d.ts +2 -0
- package/dist/plugins/manifest/index.test.d.ts.map +1 -0
- package/dist/plugins/manifest/index.test.js +331 -0
- package/dist/plugins/manifest/schemas.d.ts +64 -0
- package/dist/plugins/manifest/schemas.d.ts.map +1 -0
- package/dist/plugins/manifest/schemas.js +25 -0
- package/dist/plugins/registry/index.d.ts +9 -1
- package/dist/plugins/registry/index.d.ts.map +1 -1
- package/dist/plugins/registry/index.js +68 -3
- package/dist/plugins/request/index.d.ts.map +1 -1
- package/dist/plugins/request/index.js +1 -0
- package/dist/plugins/request/index.test.js +6 -1
- package/dist/plugins/request/schemas.d.ts +4 -4
- package/dist/plugins/runAction/index.d.ts +2 -0
- package/dist/plugins/runAction/index.d.ts.map +1 -1
- package/dist/plugins/runAction/index.js +5 -5
- package/dist/plugins/runAction/index.test.js +9 -8
- package/dist/plugins/runAction/schemas.d.ts +4 -4
- package/dist/schemas/Auth.d.ts +4 -4
- package/dist/schemas/Field.d.ts.map +1 -1
- package/dist/sdk.d.ts +3 -3
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +18 -7
- package/dist/sdk.test.js +1 -1
- package/dist/types/errors.d.ts +6 -6
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/events.d.ts +1 -1
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/plugin.d.ts +10 -2
- package/dist/types/plugin.d.ts.map +1 -1
- package/dist/types/sdk.d.ts +13 -2
- package/dist/types/sdk.d.ts.map +1 -1
- package/dist/utils/validation.test.js +2 -1
- package/package.json +2 -2
- package/src/api/client.ts +3 -3
- package/src/api/index.ts +2 -0
- package/src/api/types.ts +15 -7
- package/src/index.ts +0 -2
- package/src/plugins/api/index.ts +1 -1
- package/src/plugins/apps/types.ts +1 -1
- package/src/plugins/findFirstAuthentication/index.ts +1 -0
- package/src/plugins/findUniqueAuthentication/index.ts +1 -0
- package/src/plugins/getAction/index.test.ts +1 -1
- package/src/plugins/getAction/index.ts +1 -0
- package/src/plugins/getApp/index.test.ts +2 -0
- package/src/plugins/getApp/index.ts +12 -24
- package/src/plugins/getAuthentication/index.test.ts +13 -3
- package/src/plugins/getAuthentication/index.ts +1 -0
- package/src/plugins/getProfile/index.ts +1 -0
- package/src/plugins/listActions/index.test.ts +30 -89
- package/src/plugins/listActions/index.ts +34 -27
- package/src/plugins/listApps/index.ts +1 -0
- package/src/plugins/listAuthentications/index.test.ts +38 -47
- package/src/plugins/listAuthentications/index.ts +21 -18
- package/src/plugins/listInputFields/index.test.ts +12 -9
- package/src/plugins/listInputFields/index.ts +10 -6
- package/src/plugins/lockVersion/index.test.ts +176 -0
- package/src/plugins/lockVersion/index.ts +112 -0
- package/src/plugins/lockVersion/schemas.ts +9 -0
- package/src/plugins/manifest/index.test.ts +439 -0
- package/src/plugins/manifest/index.ts +171 -0
- package/src/plugins/manifest/schemas.ts +53 -0
- package/src/plugins/registry/index.ts +89 -8
- package/src/plugins/request/index.test.ts +8 -4
- package/src/plugins/request/index.ts +1 -0
- package/src/plugins/runAction/index.test.ts +9 -8
- package/src/plugins/runAction/index.ts +18 -9
- package/src/schemas/Field.ts +5 -2
- package/src/sdk.test.ts +1 -1
- package/src/sdk.ts +22 -7
- package/src/types/errors.ts +9 -6
- package/src/types/events.ts +1 -1
- package/src/types/plugin.ts +14 -2
- package/src/types/sdk.ts +15 -1
- package/src/utils/validation.test.ts +2 -1
- 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
|
-
|
|
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
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
implementation: sdk[key as keyof typeof sdk],
|
|
103
|
+
functions,
|
|
104
|
+
categories,
|
|
24
105
|
};
|
|
25
|
-
}
|
|
106
|
+
}
|
|
26
107
|
|
|
27
108
|
return {
|
|
28
|
-
|
|
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(
|
|
28
|
-
requestPlugin,
|
|
29
|
-
);
|
|
33
|
+
return createSdk().addPlugin(apiPlugin).addPlugin(requestPlugin);
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
describe("schema validation", () => {
|
|
@@ -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
|
-
{
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
57
|
-
const
|
|
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(
|
|
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 })
|
|
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
|
-
{
|
|
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
|
-
|
|
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
|
},
|
package/src/schemas/Field.ts
CHANGED
|
@@ -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:
|
|
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(
|
|
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,
|
|
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
|
-
|
|
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:
|
|
67
|
-
|
|
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
|
|
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)
|
package/src/types/errors.ts
CHANGED
|
@@ -6,8 +6,8 @@ export interface ApiError {
|
|
|
6
6
|
code: string;
|
|
7
7
|
title: string;
|
|
8
8
|
detail: string;
|
|
9
|
-
source?:
|
|
10
|
-
meta?:
|
|
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?:
|
|
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?:
|
|
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?:
|
|
77
|
+
public details?: unknown;
|
|
78
78
|
|
|
79
|
-
constructor(
|
|
79
|
+
constructor(
|
|
80
|
+
message: string,
|
|
81
|
+
options: ErrorOptions & { details?: unknown } = {},
|
|
82
|
+
) {
|
|
80
83
|
super(message, options);
|
|
81
84
|
this.details = options.details;
|
|
82
85
|
}
|
package/src/types/events.ts
CHANGED
package/src/types/plugin.ts
CHANGED
|
@@ -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 & {
|
|
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,
|
|
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
|
-
|
|
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
|
|
45
|
+
((error as ZapierValidationError).details as { zodErrors: unknown })
|
|
46
|
+
?.zodErrors,
|
|
46
47
|
).toBeDefined();
|
|
47
48
|
}
|
|
48
49
|
});
|