@zapier/zapier-sdk-cli 0.13.5 → 0.13.7
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 +21 -0
- package/README.md +39 -0
- package/dist/cli.cjs +360 -82
- package/dist/cli.mjs +356 -78
- package/dist/index.cjs +359 -81
- package/dist/index.d.mts +155 -3
- package/dist/index.d.ts +155 -3
- package/dist/index.mjs +355 -77
- package/dist/package.json +1 -1
- package/dist/src/plugins/add/index.d.ts +4 -2
- package/dist/src/plugins/add/index.js +89 -98
- package/dist/src/plugins/buildManifest/index.d.ts +13 -0
- package/dist/src/plugins/buildManifest/index.js +81 -0
- package/dist/src/plugins/buildManifest/schemas.d.ts +56 -0
- package/dist/src/plugins/buildManifest/schemas.js +17 -0
- package/dist/src/plugins/generateAppTypes/index.d.ts +13 -0
- package/dist/src/plugins/generateAppTypes/index.js +169 -0
- package/dist/src/plugins/generateAppTypes/schemas.d.ts +72 -0
- package/dist/src/plugins/generateAppTypes/schemas.js +21 -0
- package/dist/src/plugins/index.d.ts +2 -0
- package/dist/src/plugins/index.js +2 -0
- package/dist/src/sdk.d.ts +4 -3
- package/dist/src/sdk.js +16 -14
- package/dist/src/types/sdk.d.ts +5 -0
- package/dist/src/types/sdk.js +1 -0
- package/dist/src/utils/constants.d.ts +1 -3
- package/dist/src/utils/constants.js +3 -4
- package/dist/src/utils/directory-detection.d.ts +5 -0
- package/dist/src/utils/directory-detection.js +21 -0
- package/dist/src/utils/manifest-helpers.d.ts +10 -0
- package/dist/src/utils/manifest-helpers.js +19 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/plugins/add/index.ts +123 -125
- package/src/plugins/buildManifest/index.test.ts +612 -0
- package/src/plugins/buildManifest/index.ts +128 -0
- package/src/plugins/buildManifest/schemas.ts +59 -0
- package/src/plugins/generateAppTypes/index.ts +235 -0
- package/src/plugins/generateAppTypes/schemas.ts +65 -0
- package/src/plugins/index.ts +2 -0
- package/src/sdk.ts +25 -21
- package/src/types/sdk.ts +8 -0
- package/src/utils/constants.ts +7 -6
- package/src/utils/directory-detection.ts +23 -0
- package/src/utils/manifest-helpers.ts +25 -0
- /package/dist/src/{plugins/add → generators}/ast-generator.d.ts +0 -0
- /package/dist/src/{plugins/add → generators}/ast-generator.js +0 -0
- /package/src/{plugins/add → generators}/ast-generator.ts +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Plugin,
|
|
3
|
+
GetSdkType,
|
|
4
|
+
GetContextType,
|
|
5
|
+
ListAppsPluginProvides,
|
|
6
|
+
ManifestPluginProvides,
|
|
7
|
+
AppItem,
|
|
8
|
+
Manifest,
|
|
9
|
+
} from "@zapier/zapier-sdk";
|
|
10
|
+
import { createFunction } from "@zapier/zapier-sdk";
|
|
11
|
+
import {
|
|
12
|
+
BuildManifestSchema,
|
|
13
|
+
type BuildManifestOptions,
|
|
14
|
+
type BuildManifestResult,
|
|
15
|
+
} from "./schemas";
|
|
16
|
+
import { createManifestEntry } from "../../utils/manifest-helpers";
|
|
17
|
+
|
|
18
|
+
export interface BuildManifestPluginProvides {
|
|
19
|
+
buildManifest: (
|
|
20
|
+
options: BuildManifestOptions,
|
|
21
|
+
) => Promise<BuildManifestResult>;
|
|
22
|
+
context: {
|
|
23
|
+
meta: {
|
|
24
|
+
buildManifest: {
|
|
25
|
+
inputSchema: typeof BuildManifestSchema;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const buildManifestPlugin: Plugin<
|
|
32
|
+
GetSdkType<ListAppsPluginProvides>,
|
|
33
|
+
GetContextType<ManifestPluginProvides>,
|
|
34
|
+
BuildManifestPluginProvides
|
|
35
|
+
> = ({ sdk, context }) => {
|
|
36
|
+
const buildManifest = createFunction(async function buildManifest(
|
|
37
|
+
options: BuildManifestOptions,
|
|
38
|
+
): Promise<BuildManifestResult> {
|
|
39
|
+
const { appKeys, skipWrite = false, configPath, onProgress } = options;
|
|
40
|
+
|
|
41
|
+
const result: BuildManifestResult = {
|
|
42
|
+
errors: [],
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
// Get apps using listApps (which respects existing manifest for version locking)
|
|
46
|
+
onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
|
|
47
|
+
const appsIterator = sdk.listApps({ appKeys }).items();
|
|
48
|
+
const apps: AppItem[] = [];
|
|
49
|
+
for await (const app of appsIterator) {
|
|
50
|
+
apps.push(app);
|
|
51
|
+
onProgress?.({ type: "app_found", app });
|
|
52
|
+
}
|
|
53
|
+
onProgress?.({ type: "apps_lookup_complete", count: apps.length });
|
|
54
|
+
|
|
55
|
+
if (apps.length === 0) {
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
let updatedManifest: Manifest | undefined;
|
|
60
|
+
|
|
61
|
+
// Process each app
|
|
62
|
+
for (const app of apps) {
|
|
63
|
+
onProgress?.({
|
|
64
|
+
type: "app_processing_start",
|
|
65
|
+
appKey: app.key,
|
|
66
|
+
slug: app.slug,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const manifestEntry = createManifestEntry(app);
|
|
71
|
+
|
|
72
|
+
onProgress?.({
|
|
73
|
+
type: "manifest_entry_built",
|
|
74
|
+
appKey: app.key,
|
|
75
|
+
manifestKey: manifestEntry.implementationName,
|
|
76
|
+
version: manifestEntry.version || "",
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
const [updatedManifestKey, , manifest] =
|
|
80
|
+
await context.updateManifestEntry({
|
|
81
|
+
appKey: app.key,
|
|
82
|
+
entry: manifestEntry,
|
|
83
|
+
configPath,
|
|
84
|
+
skipWrite,
|
|
85
|
+
manifest: updatedManifest,
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
updatedManifest = manifest;
|
|
89
|
+
|
|
90
|
+
onProgress?.({
|
|
91
|
+
type: "manifest_updated",
|
|
92
|
+
appKey: app.key,
|
|
93
|
+
manifestKey: updatedManifestKey,
|
|
94
|
+
version: manifestEntry.version || "",
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
onProgress?.({ type: "app_processing_complete", appKey: app.key });
|
|
98
|
+
} catch (error) {
|
|
99
|
+
const errorMessage = `Failed to process app: ${error}`;
|
|
100
|
+
result.errors.push({
|
|
101
|
+
appKey: app.key,
|
|
102
|
+
error: errorMessage,
|
|
103
|
+
});
|
|
104
|
+
onProgress?.({
|
|
105
|
+
type: "app_processing_error",
|
|
106
|
+
appKey: app.key,
|
|
107
|
+
error: errorMessage,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
result.manifest = updatedManifest;
|
|
113
|
+
|
|
114
|
+
return result;
|
|
115
|
+
}, BuildManifestSchema);
|
|
116
|
+
|
|
117
|
+
return {
|
|
118
|
+
buildManifest,
|
|
119
|
+
context: {
|
|
120
|
+
meta: {
|
|
121
|
+
buildManifest: {
|
|
122
|
+
categories: ["utility"],
|
|
123
|
+
inputSchema: BuildManifestSchema,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
};
|
|
128
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { AppItem, Manifest } from "@zapier/zapier-sdk";
|
|
3
|
+
|
|
4
|
+
export const BuildManifestSchema = z
|
|
5
|
+
.object({
|
|
6
|
+
appKeys: z
|
|
7
|
+
.array(z.string().min(1, "App key cannot be empty"))
|
|
8
|
+
.min(1, "At least one app key is required")
|
|
9
|
+
.describe(
|
|
10
|
+
"One or more app keys to build manifest entries for (e.g., 'slack', 'github', 'trello')",
|
|
11
|
+
),
|
|
12
|
+
skipWrite: z
|
|
13
|
+
.boolean()
|
|
14
|
+
.optional()
|
|
15
|
+
.describe(
|
|
16
|
+
"If true, returns manifest entries without writing to disk. If false or omitted, writes to the manifest file.",
|
|
17
|
+
),
|
|
18
|
+
configPath: z
|
|
19
|
+
.string()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe(
|
|
22
|
+
"Path to the manifest file. Only used when skipWrite is false or omitted.",
|
|
23
|
+
),
|
|
24
|
+
})
|
|
25
|
+
.describe(
|
|
26
|
+
"Build manifest entries for apps - can optionally write to disk or just return JSON",
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
export type BuildManifestOptions = z.infer<typeof BuildManifestSchema> & {
|
|
30
|
+
onProgress?: (event: ManifestBuildProgressEvent) => void;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export type ManifestBuildProgressEvent =
|
|
34
|
+
| { type: "apps_lookup_start"; count: number }
|
|
35
|
+
| { type: "app_found"; app: AppItem }
|
|
36
|
+
| { type: "apps_lookup_complete"; count: number }
|
|
37
|
+
| { type: "app_processing_start"; appKey: string; slug?: string }
|
|
38
|
+
| {
|
|
39
|
+
type: "manifest_entry_built";
|
|
40
|
+
appKey: string;
|
|
41
|
+
manifestKey: string;
|
|
42
|
+
version: string;
|
|
43
|
+
}
|
|
44
|
+
| {
|
|
45
|
+
type: "manifest_updated";
|
|
46
|
+
appKey: string;
|
|
47
|
+
manifestKey: string;
|
|
48
|
+
version: string;
|
|
49
|
+
}
|
|
50
|
+
| { type: "app_processing_complete"; appKey: string }
|
|
51
|
+
| { type: "app_processing_error"; appKey: string; error: string };
|
|
52
|
+
|
|
53
|
+
export interface BuildManifestResult {
|
|
54
|
+
manifest?: Manifest;
|
|
55
|
+
errors: Array<{
|
|
56
|
+
appKey: string;
|
|
57
|
+
error: string;
|
|
58
|
+
}>;
|
|
59
|
+
}
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Plugin,
|
|
3
|
+
GetSdkType,
|
|
4
|
+
ListActionsPluginProvides,
|
|
5
|
+
ListAppsPluginProvides,
|
|
6
|
+
ListInputFieldsPluginProvides,
|
|
7
|
+
ListAuthenticationsPluginProvides,
|
|
8
|
+
ManifestPluginProvides,
|
|
9
|
+
AppItem,
|
|
10
|
+
} from "@zapier/zapier-sdk";
|
|
11
|
+
import { createFunction } from "@zapier/zapier-sdk";
|
|
12
|
+
import {
|
|
13
|
+
GenerateAppTypesSchema,
|
|
14
|
+
type GenerateAppTypesOptions,
|
|
15
|
+
type GenerateAppTypesResult,
|
|
16
|
+
} from "./schemas";
|
|
17
|
+
import { AstTypeGenerator } from "../../generators/ast-generator";
|
|
18
|
+
import { getManifestKey } from "../../utils/manifest-helpers";
|
|
19
|
+
import { mkdir, writeFile } from "fs/promises";
|
|
20
|
+
import { join } from "path";
|
|
21
|
+
|
|
22
|
+
export interface GenerateAppTypesPluginProvides {
|
|
23
|
+
generateAppTypes: (
|
|
24
|
+
options: GenerateAppTypesOptions,
|
|
25
|
+
) => Promise<GenerateAppTypesResult>;
|
|
26
|
+
context: {
|
|
27
|
+
meta: {
|
|
28
|
+
generateAppTypes: {
|
|
29
|
+
inputSchema: typeof GenerateAppTypesSchema;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const generateAppTypesPlugin: Plugin<
|
|
36
|
+
GetSdkType<
|
|
37
|
+
ListAppsPluginProvides &
|
|
38
|
+
ListActionsPluginProvides &
|
|
39
|
+
ListInputFieldsPluginProvides &
|
|
40
|
+
ListAuthenticationsPluginProvides &
|
|
41
|
+
ManifestPluginProvides
|
|
42
|
+
>,
|
|
43
|
+
{},
|
|
44
|
+
GenerateAppTypesPluginProvides
|
|
45
|
+
> = ({ sdk }) => {
|
|
46
|
+
const generateAppTypes = createFunction(async function generateAppTypes(
|
|
47
|
+
options: GenerateAppTypesOptions,
|
|
48
|
+
): Promise<GenerateAppTypesResult> {
|
|
49
|
+
const {
|
|
50
|
+
appKeys,
|
|
51
|
+
authenticationIds,
|
|
52
|
+
skipWrite = false,
|
|
53
|
+
typesOutputDirectory,
|
|
54
|
+
onProgress,
|
|
55
|
+
} = options;
|
|
56
|
+
|
|
57
|
+
// Validate that typesOutputDirectory is provided when skipWrite is false
|
|
58
|
+
if (!skipWrite && !typesOutputDirectory) {
|
|
59
|
+
throw new Error(
|
|
60
|
+
"typesOutputDirectory is required when skipWrite is false",
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const result: GenerateAppTypesResult = {
|
|
65
|
+
typeDefinitions: {},
|
|
66
|
+
errors: [],
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
// Get apps using listApps (which respects existing manifest for version locking)
|
|
70
|
+
onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
|
|
71
|
+
const appsIterator = sdk.listApps({ appKeys }).items();
|
|
72
|
+
const apps: AppItem[] = [];
|
|
73
|
+
for await (const app of appsIterator) {
|
|
74
|
+
apps.push(app);
|
|
75
|
+
onProgress?.({ type: "app_found", app });
|
|
76
|
+
}
|
|
77
|
+
onProgress?.({ type: "apps_lookup_complete", count: apps.length });
|
|
78
|
+
|
|
79
|
+
if (apps.length === 0) {
|
|
80
|
+
return result;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Fetch authentications if provided
|
|
84
|
+
const authentications = [];
|
|
85
|
+
if (authenticationIds && authenticationIds.length > 0) {
|
|
86
|
+
onProgress?.({
|
|
87
|
+
type: "authentications_lookup_start",
|
|
88
|
+
count: authenticationIds.length,
|
|
89
|
+
});
|
|
90
|
+
const authsIterator = sdk
|
|
91
|
+
.listAuthentications({ authenticationIds })
|
|
92
|
+
.items();
|
|
93
|
+
for await (const auth of authsIterator) {
|
|
94
|
+
authentications.push(auth);
|
|
95
|
+
}
|
|
96
|
+
onProgress?.({
|
|
97
|
+
type: "authentications_lookup_complete",
|
|
98
|
+
count: authentications.length,
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Ensure output directory exists if we're writing files
|
|
103
|
+
if (!skipWrite && typesOutputDirectory) {
|
|
104
|
+
await mkdir(typesOutputDirectory, { recursive: true });
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Initialize writtenFiles if we're writing to disk
|
|
108
|
+
if (!skipWrite) {
|
|
109
|
+
result.writtenFiles = {};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Process each app
|
|
113
|
+
for (const app of apps) {
|
|
114
|
+
onProgress?.({
|
|
115
|
+
type: "app_processing_start",
|
|
116
|
+
appKey: app.key,
|
|
117
|
+
slug: app.slug,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
if (!app.version) {
|
|
122
|
+
const error = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
|
|
123
|
+
result.errors.push({
|
|
124
|
+
appKey: app.key,
|
|
125
|
+
error,
|
|
126
|
+
});
|
|
127
|
+
onProgress?.({
|
|
128
|
+
type: "app_processing_error",
|
|
129
|
+
appKey: app.key,
|
|
130
|
+
error,
|
|
131
|
+
});
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Find matching authentication for this app if authentications were provided
|
|
136
|
+
let authenticationId: number | undefined;
|
|
137
|
+
if (authentications.length > 0) {
|
|
138
|
+
const matchingAuth = authentications.find((auth) => {
|
|
139
|
+
return auth.app_key === app.key;
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
if (matchingAuth) {
|
|
143
|
+
authenticationId = matchingAuth.id;
|
|
144
|
+
onProgress?.({
|
|
145
|
+
type: "authentication_matched",
|
|
146
|
+
appKey: app.key,
|
|
147
|
+
authenticationId: matchingAuth.id,
|
|
148
|
+
authenticationTitle: matchingAuth.title || "",
|
|
149
|
+
});
|
|
150
|
+
} else {
|
|
151
|
+
onProgress?.({
|
|
152
|
+
type: "authentication_not_matched",
|
|
153
|
+
appKey: app.key,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const manifestKey = getManifestKey(app);
|
|
159
|
+
|
|
160
|
+
// Generate type definitions
|
|
161
|
+
try {
|
|
162
|
+
const generator = new AstTypeGenerator();
|
|
163
|
+
const typeDefinitionString = await generator.generateTypes({
|
|
164
|
+
app,
|
|
165
|
+
authenticationId,
|
|
166
|
+
sdk,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
result.typeDefinitions[manifestKey] = typeDefinitionString;
|
|
170
|
+
|
|
171
|
+
onProgress?.({
|
|
172
|
+
type: "type_generated",
|
|
173
|
+
manifestKey,
|
|
174
|
+
sizeBytes: typeDefinitionString.length,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
// Write to file if skipWrite is false
|
|
178
|
+
if (!skipWrite && typesOutputDirectory && result.writtenFiles) {
|
|
179
|
+
const filePath = join(typesOutputDirectory, `${manifestKey}.d.ts`);
|
|
180
|
+
await writeFile(filePath, typeDefinitionString, "utf8");
|
|
181
|
+
|
|
182
|
+
result.writtenFiles[manifestKey] = filePath;
|
|
183
|
+
|
|
184
|
+
onProgress?.({
|
|
185
|
+
type: "file_written",
|
|
186
|
+
manifestKey,
|
|
187
|
+
filePath,
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
onProgress?.({
|
|
192
|
+
type: "app_processing_complete",
|
|
193
|
+
appKey: app.key,
|
|
194
|
+
});
|
|
195
|
+
} catch (error) {
|
|
196
|
+
const errorMessage = `Failed to generate types: ${error}`;
|
|
197
|
+
result.errors.push({
|
|
198
|
+
appKey: app.key,
|
|
199
|
+
error: errorMessage,
|
|
200
|
+
});
|
|
201
|
+
onProgress?.({
|
|
202
|
+
type: "app_processing_error",
|
|
203
|
+
appKey: app.key,
|
|
204
|
+
error: errorMessage,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
} catch (error) {
|
|
208
|
+
const errorMessage = `Failed to process app: ${error}`;
|
|
209
|
+
result.errors.push({
|
|
210
|
+
appKey: app.key,
|
|
211
|
+
error: errorMessage,
|
|
212
|
+
});
|
|
213
|
+
onProgress?.({
|
|
214
|
+
type: "app_processing_error",
|
|
215
|
+
appKey: app.key,
|
|
216
|
+
error: errorMessage,
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return result;
|
|
222
|
+
}, GenerateAppTypesSchema);
|
|
223
|
+
|
|
224
|
+
return {
|
|
225
|
+
generateAppTypes,
|
|
226
|
+
context: {
|
|
227
|
+
meta: {
|
|
228
|
+
generateAppTypes: {
|
|
229
|
+
categories: ["utility"],
|
|
230
|
+
inputSchema: GenerateAppTypesSchema,
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import type { AppItem } from "@zapier/zapier-sdk";
|
|
3
|
+
|
|
4
|
+
export const GenerateAppTypesSchema = z
|
|
5
|
+
.object({
|
|
6
|
+
appKeys: z
|
|
7
|
+
.array(z.string().min(1, "App key cannot be empty"))
|
|
8
|
+
.min(1, "At least one app key is required")
|
|
9
|
+
.describe(
|
|
10
|
+
"One or more app keys to generate types for (e.g., 'slack', 'github', 'trello')",
|
|
11
|
+
),
|
|
12
|
+
authenticationIds: z
|
|
13
|
+
.array(z.string())
|
|
14
|
+
.optional()
|
|
15
|
+
.describe(
|
|
16
|
+
"Authentication IDs to use for type generation (e.g., ['123', '456'])",
|
|
17
|
+
),
|
|
18
|
+
skipWrite: z
|
|
19
|
+
.boolean()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe(
|
|
22
|
+
"If true, returns type definitions without writing to disk. If false or omitted, writes type files.",
|
|
23
|
+
),
|
|
24
|
+
typesOutputDirectory: z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe(
|
|
28
|
+
"Directory for TypeScript type files. Required when skipWrite is false or omitted.",
|
|
29
|
+
),
|
|
30
|
+
})
|
|
31
|
+
.describe(
|
|
32
|
+
"Generate TypeScript type definitions for apps - can optionally write to disk or just return type strings",
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
export type GenerateAppTypesOptions = z.infer<typeof GenerateAppTypesSchema> & {
|
|
36
|
+
onProgress?: (event: AppTypesProgressEvent) => void;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type AppTypesProgressEvent =
|
|
40
|
+
| { type: "apps_lookup_start"; count: number }
|
|
41
|
+
| { type: "app_found"; app: AppItem }
|
|
42
|
+
| { type: "apps_lookup_complete"; count: number }
|
|
43
|
+
| { type: "authentications_lookup_start"; count: number }
|
|
44
|
+
| { type: "authentications_lookup_complete"; count: number }
|
|
45
|
+
| { type: "app_processing_start"; appKey: string; slug?: string }
|
|
46
|
+
| {
|
|
47
|
+
type: "authentication_matched";
|
|
48
|
+
appKey: string;
|
|
49
|
+
authenticationId: number;
|
|
50
|
+
authenticationTitle: string;
|
|
51
|
+
}
|
|
52
|
+
| { type: "authentication_not_matched"; appKey: string }
|
|
53
|
+
| { type: "type_generated"; manifestKey: string; sizeBytes: number }
|
|
54
|
+
| { type: "file_written"; manifestKey: string; filePath: string }
|
|
55
|
+
| { type: "app_processing_complete"; appKey: string }
|
|
56
|
+
| { type: "app_processing_error"; appKey: string; error: string };
|
|
57
|
+
|
|
58
|
+
export interface GenerateAppTypesResult {
|
|
59
|
+
typeDefinitions: Record<string, string>; // manifestKey -> type definition string
|
|
60
|
+
writtenFiles?: Record<string, string>; // manifestKey -> file path (only when skipWrite is false)
|
|
61
|
+
errors: Array<{
|
|
62
|
+
appKey: string;
|
|
63
|
+
error: string;
|
|
64
|
+
}>;
|
|
65
|
+
}
|
package/src/plugins/index.ts
CHANGED
|
@@ -4,3 +4,5 @@ export { mcpPlugin } from "./mcp";
|
|
|
4
4
|
export { bundleCodePlugin } from "./bundleCode";
|
|
5
5
|
export { getLoginConfigPathPlugin } from "./getLoginConfigPath";
|
|
6
6
|
export { addPlugin } from "./add";
|
|
7
|
+
export { generateAppTypesPlugin } from "./generateAppTypes";
|
|
8
|
+
export { buildManifestPlugin } from "./buildManifest";
|
package/src/sdk.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createZapierSdkWithoutRegistry,
|
|
3
3
|
registryPlugin,
|
|
4
|
-
type
|
|
4
|
+
type ZapierSdkOptions,
|
|
5
5
|
} from "@zapier/zapier-sdk";
|
|
6
6
|
import {
|
|
7
7
|
loginPlugin,
|
|
@@ -10,9 +10,12 @@ import {
|
|
|
10
10
|
bundleCodePlugin,
|
|
11
11
|
getLoginConfigPathPlugin,
|
|
12
12
|
addPlugin,
|
|
13
|
+
generateAppTypesPlugin,
|
|
14
|
+
buildManifestPlugin,
|
|
13
15
|
} from "./plugins/index";
|
|
16
|
+
import type { ZapierSdkCli } from "./types/sdk";
|
|
14
17
|
|
|
15
|
-
export interface ZapierCliSdkOptions {
|
|
18
|
+
export interface ZapierCliSdkOptions extends ZapierSdkOptions {
|
|
16
19
|
debug?: boolean;
|
|
17
20
|
eventEmission?: {
|
|
18
21
|
enabled?: boolean;
|
|
@@ -30,23 +33,24 @@ export interface ZapierCliSdkOptions {
|
|
|
30
33
|
*/
|
|
31
34
|
export function createZapierCliSdk(
|
|
32
35
|
options: ZapierCliSdkOptions = {},
|
|
33
|
-
):
|
|
34
|
-
// Create SDK instance
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
36
|
+
): ZapierSdkCli {
|
|
37
|
+
// Create SDK instance and chain all plugins
|
|
38
|
+
// Chaining prevents type widening that occurs with let reassignment
|
|
39
|
+
return (
|
|
40
|
+
createZapierSdkWithoutRegistry({
|
|
41
|
+
debug: options.debug,
|
|
42
|
+
eventEmission: options.eventEmission,
|
|
43
|
+
})
|
|
44
|
+
// Add CLI-specific plugins before registry
|
|
45
|
+
.addPlugin(generateAppTypesPlugin)
|
|
46
|
+
.addPlugin(buildManifestPlugin)
|
|
47
|
+
.addPlugin(bundleCodePlugin)
|
|
48
|
+
.addPlugin(getLoginConfigPathPlugin)
|
|
49
|
+
.addPlugin(addPlugin)
|
|
50
|
+
.addPlugin(mcpPlugin)
|
|
51
|
+
.addPlugin(loginPlugin)
|
|
52
|
+
.addPlugin(logoutPlugin)
|
|
53
|
+
// Add registry plugin to finalize SDK
|
|
54
|
+
.addPlugin(registryPlugin)
|
|
55
|
+
);
|
|
52
56
|
}
|
package/src/types/sdk.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { GetSdkType, ZapierSdk } from "@zapier/zapier-sdk";
|
|
2
|
+
import type { BuildManifestPluginProvides } from "../plugins/buildManifest";
|
|
3
|
+
import type { GenerateAppTypesPluginProvides } from "../plugins/generateAppTypes";
|
|
4
|
+
|
|
5
|
+
export interface ZapierSdkCli
|
|
6
|
+
extends GetSdkType<
|
|
7
|
+
ZapierSdk & BuildManifestPluginProvides & GenerateAppTypesPluginProvides
|
|
8
|
+
> {}
|
package/src/utils/constants.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
// Import shared OAuth constants from login package
|
|
2
|
+
export {
|
|
3
|
+
ZAPIER_BASE,
|
|
4
|
+
LOGIN_CLIENT_ID,
|
|
5
|
+
AUTH_MODE_HEADER,
|
|
6
|
+
} from "@zapier/zapier-sdk-cli-login";
|
|
5
7
|
|
|
8
|
+
// CLI-specific constants
|
|
6
9
|
export const LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
|
|
7
10
|
export const LOGIN_TIMEOUT_MS = 300000; // 5 minutes
|
|
8
|
-
|
|
9
|
-
export const AUTH_MODE_HEADER = "X-Auth";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { access } from "fs/promises";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Detect the best default directory for TypeScript types
|
|
6
|
+
* Looks for src or lib directories, falls back to current directory
|
|
7
|
+
*/
|
|
8
|
+
export async function detectTypesOutputDirectory(): Promise<string> {
|
|
9
|
+
// Check for common source directories in priority order
|
|
10
|
+
const candidates = ["src", "lib"];
|
|
11
|
+
|
|
12
|
+
for (const candidate of candidates) {
|
|
13
|
+
try {
|
|
14
|
+
await access(candidate);
|
|
15
|
+
return join(candidate, "zapier", "apps");
|
|
16
|
+
} catch {
|
|
17
|
+
// Directory doesn't exist, continue to next candidate
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// Fall back to current directory
|
|
22
|
+
return "./zapier/apps/";
|
|
23
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AppItem, ManifestEntry } from "@zapier/zapier-sdk";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get the preferred key for a manifest entry
|
|
5
|
+
* Prefers slug over implementation name
|
|
6
|
+
*/
|
|
7
|
+
export function getManifestKey(app: AppItem): string {
|
|
8
|
+
return app.slug || app.key;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Create a manifest entry from an app
|
|
13
|
+
*/
|
|
14
|
+
export function createManifestEntry(app: AppItem): ManifestEntry {
|
|
15
|
+
if (!app.version) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
`App ${app.key} does not have a version. Implementation ID: ${app.implementation_id}`,
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return {
|
|
22
|
+
implementationName: app.key,
|
|
23
|
+
version: app.version,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|