@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.
Files changed (48) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +39 -0
  3. package/dist/cli.cjs +360 -82
  4. package/dist/cli.mjs +356 -78
  5. package/dist/index.cjs +359 -81
  6. package/dist/index.d.mts +155 -3
  7. package/dist/index.d.ts +155 -3
  8. package/dist/index.mjs +355 -77
  9. package/dist/package.json +1 -1
  10. package/dist/src/plugins/add/index.d.ts +4 -2
  11. package/dist/src/plugins/add/index.js +89 -98
  12. package/dist/src/plugins/buildManifest/index.d.ts +13 -0
  13. package/dist/src/plugins/buildManifest/index.js +81 -0
  14. package/dist/src/plugins/buildManifest/schemas.d.ts +56 -0
  15. package/dist/src/plugins/buildManifest/schemas.js +17 -0
  16. package/dist/src/plugins/generateAppTypes/index.d.ts +13 -0
  17. package/dist/src/plugins/generateAppTypes/index.js +169 -0
  18. package/dist/src/plugins/generateAppTypes/schemas.d.ts +72 -0
  19. package/dist/src/plugins/generateAppTypes/schemas.js +21 -0
  20. package/dist/src/plugins/index.d.ts +2 -0
  21. package/dist/src/plugins/index.js +2 -0
  22. package/dist/src/sdk.d.ts +4 -3
  23. package/dist/src/sdk.js +16 -14
  24. package/dist/src/types/sdk.d.ts +5 -0
  25. package/dist/src/types/sdk.js +1 -0
  26. package/dist/src/utils/constants.d.ts +1 -3
  27. package/dist/src/utils/constants.js +3 -4
  28. package/dist/src/utils/directory-detection.d.ts +5 -0
  29. package/dist/src/utils/directory-detection.js +21 -0
  30. package/dist/src/utils/manifest-helpers.d.ts +10 -0
  31. package/dist/src/utils/manifest-helpers.js +19 -0
  32. package/dist/tsconfig.tsbuildinfo +1 -1
  33. package/package.json +4 -4
  34. package/src/plugins/add/index.ts +123 -125
  35. package/src/plugins/buildManifest/index.test.ts +612 -0
  36. package/src/plugins/buildManifest/index.ts +128 -0
  37. package/src/plugins/buildManifest/schemas.ts +59 -0
  38. package/src/plugins/generateAppTypes/index.ts +235 -0
  39. package/src/plugins/generateAppTypes/schemas.ts +65 -0
  40. package/src/plugins/index.ts +2 -0
  41. package/src/sdk.ts +25 -21
  42. package/src/types/sdk.ts +8 -0
  43. package/src/utils/constants.ts +7 -6
  44. package/src/utils/directory-detection.ts +23 -0
  45. package/src/utils/manifest-helpers.ts +25 -0
  46. /package/dist/src/{plugins/add → generators}/ast-generator.d.ts +0 -0
  47. /package/dist/src/{plugins/add → generators}/ast-generator.js +0 -0
  48. /package/src/{plugins/add → generators}/ast-generator.ts +0 -0
@@ -1,110 +1,101 @@
1
1
  import { createFunction } from "@zapier/zapier-sdk";
2
2
  import { AddSchema } from "./schemas";
3
- import { AstTypeGenerator } from "./ast-generator";
4
- import { mkdir, access, writeFile } from "fs/promises";
5
- import { resolve, join } from "path";
6
- /**
7
- * Detect the best default directory for TypeScript types
8
- * Looks for src or lib directories, falls back to current directory
9
- */
10
- async function detectTypesOutputDirectory() {
11
- // Check for common source directories in priority order
12
- const candidates = ["src", "lib"];
13
- for (const candidate of candidates) {
14
- try {
15
- await access(candidate);
16
- return join(candidate, "zapier", "apps");
17
- }
18
- catch {
19
- // Directory doesn't exist, continue to next candidate
20
- }
21
- }
22
- // Fall back to current directory
23
- return "./zapier/apps/";
24
- }
25
- export const addPlugin = ({ sdk, context }) => {
3
+ import { detectTypesOutputDirectory } from "../../utils/directory-detection";
4
+ import { resolve } from "path";
5
+ export const addPlugin = ({ sdk }) => {
26
6
  const add = createFunction(async function add(options) {
27
7
  const { appKeys, authenticationIds, configPath, typesOutput = await detectTypesOutputDirectory(), } = options;
28
8
  const resolvedTypesOutput = resolve(typesOutput);
29
- // Ensure types output directory exists
30
- await mkdir(resolvedTypesOutput, { recursive: true });
31
- // Get apps using listApps (which respects existing manifest for version locking)
32
- console.log(`📦 Looking up ${appKeys.length} app(s)...`);
33
- const appsIterator = sdk.listApps({ appKeys }).items();
34
- const apps = [];
35
- for await (const app of appsIterator) {
36
- apps.push(app);
37
- }
38
- if (apps.length === 0) {
39
- console.warn("⚠️ No apps found");
40
- return;
41
- }
42
- // Fetch authentications if provided
43
- let authentications = [];
44
- if (authenticationIds && authenticationIds.length > 0) {
45
- console.log(`🔐 Looking up ${authenticationIds.length} authentication(s)...`);
46
- const authsIterator = sdk
47
- .listAuthentications({ authenticationIds })
48
- .items();
49
- for await (const auth of authsIterator) {
50
- authentications.push(auth);
51
- }
52
- console.log(`🔐 Found ${authentications.length} authentication(s)`);
53
- }
54
- // Process each app
55
- for (const app of apps) {
56
- const appSlugAndKey = app.slug ? `${app.slug} (${app.key})` : app.key;
57
- console.log(`📦 Adding ${appSlugAndKey}...`);
58
- try {
59
- if (!app.version) {
60
- console.warn(`⚠️ Invalid implementation ID format for '${appSlugAndKey}': ${app.implementation_id}. Expected format: <implementationName>@<version>. Skipping...`);
61
- continue;
62
- }
63
- // Update manifest using manifest plugin's function
64
- const [manifestKey] = await context.updateManifestEntry(app.key, {
65
- implementationName: app.key,
66
- version: app.version,
67
- }, configPath);
68
- console.log(`📝 Locked ${appSlugAndKey} to ${app.key}@${app.version} using key '${manifestKey}'`);
69
- // Find matching authentication for this app if authentications were provided
70
- let authenticationId;
71
- if (authentications.length > 0) {
72
- // Match authentication by app_key
73
- const matchingAuth = authentications.find((auth) => {
74
- return auth.app_key === app.key;
75
- });
76
- if (matchingAuth) {
77
- authenticationId = matchingAuth.id;
78
- console.log(`🔐 Using authentication ${authenticationId} (${matchingAuth.title}) for ${appSlugAndKey}`);
9
+ console.log(`📦 Adding ${appKeys.length} app(s)...`);
10
+ // Track app names for better console output
11
+ const appSlugAndKeyMap = new Map();
12
+ // Define progress handler for manifest building
13
+ const handleManifestProgress = (event) => {
14
+ switch (event.type) {
15
+ case "apps_lookup_start":
16
+ console.log(`📦 Looking up ${event.count} app(s)...`);
17
+ break;
18
+ case "app_found":
19
+ // Store the app display name for later use
20
+ const displayName = event.app.slug
21
+ ? `${event.app.slug} (${event.app.key})`
22
+ : event.app.key;
23
+ appSlugAndKeyMap.set(event.app.key, displayName);
24
+ break;
25
+ case "apps_lookup_complete":
26
+ if (event.count === 0) {
27
+ console.warn("⚠️ No apps found");
79
28
  }
80
- else {
81
- console.warn(`⚠️ No matching authentication found for ${appSlugAndKey}`);
82
- }
83
- }
84
- // Generate types using the manifest key for consistency
85
- const typesPath = join(resolvedTypesOutput, `${manifestKey}.d.ts`);
86
- try {
87
- // Use AST-based generator directly
88
- const generator = new AstTypeGenerator();
89
- const typeDefinitions = await generator.generateTypes({
90
- app,
91
- authenticationId,
92
- sdk,
93
- });
94
- // Write to file
95
- await writeFile(typesPath, typeDefinitions, "utf8");
96
- console.log(`🔧 Generated types for ${manifestKey} at ${typesPath}`);
97
- }
98
- catch (error) {
99
- console.warn(`⚠️ Failed to generate types for ${appSlugAndKey}: ${error}`);
100
- // Continue even if type generation fails
101
- }
29
+ break;
30
+ case "app_processing_start":
31
+ const appName = event.slug
32
+ ? `${event.slug} (${event.appKey})`
33
+ : event.appKey;
34
+ console.log(`📦 Adding ${appName}...`);
35
+ break;
36
+ case "manifest_updated":
37
+ const appDisplay = appSlugAndKeyMap.get(event.appKey) || event.appKey;
38
+ console.log(`📝 Locked ${appDisplay} to ${event.appKey}@${event.version} using key '${event.manifestKey}'`);
39
+ break;
40
+ case "app_processing_error":
41
+ const errorApp = appSlugAndKeyMap.get(event.appKey) || event.appKey;
42
+ console.warn(`⚠️ ${event.error} for ${errorApp}`);
43
+ break;
102
44
  }
103
- catch (error) {
104
- console.warn(`⚠️ Failed to process ${appSlugAndKey}: ${error}`);
45
+ };
46
+ // Define progress handler for type generation
47
+ const handleTypesProgress = (event) => {
48
+ switch (event.type) {
49
+ case "authentications_lookup_start":
50
+ console.log(`🔐 Looking up ${event.count} authentication(s)...`);
51
+ break;
52
+ case "authentications_lookup_complete":
53
+ console.log(`🔐 Found ${event.count} authentication(s)`);
54
+ break;
55
+ case "authentication_matched":
56
+ const appWithAuth = appSlugAndKeyMap.get(event.appKey) || event.appKey;
57
+ console.log(`🔐 Using authentication ${event.authenticationId} (${event.authenticationTitle}) for ${appWithAuth}`);
58
+ break;
59
+ case "authentication_not_matched":
60
+ const appWithoutAuth = appSlugAndKeyMap.get(event.appKey) || event.appKey;
61
+ console.warn(`⚠️ No matching authentication found for ${appWithoutAuth}`);
62
+ break;
63
+ case "file_written":
64
+ console.log(`🔧 Generated types for ${event.manifestKey} at ${event.filePath}`);
65
+ break;
66
+ case "app_processing_error":
67
+ const errorApp = appSlugAndKeyMap.get(event.appKey) || event.appKey;
68
+ console.warn(`⚠️ ${event.error} for ${errorApp}`);
69
+ break;
105
70
  }
71
+ };
72
+ const manifestResult = await sdk.buildManifest({
73
+ appKeys,
74
+ skipWrite: false,
75
+ configPath,
76
+ onProgress: handleManifestProgress,
77
+ });
78
+ const typesResult = await sdk.generateAppTypes({
79
+ appKeys,
80
+ authenticationIds,
81
+ skipWrite: false,
82
+ typesOutputDirectory: resolvedTypesOutput,
83
+ onProgress: handleTypesProgress,
84
+ });
85
+ const results = manifestResult.manifest?.apps || {};
86
+ // Final summary
87
+ const successfulApps = Object.keys(results).filter((manifestKey) => typesResult.writtenFiles?.[manifestKey]);
88
+ if (successfulApps.length > 0) {
89
+ console.log(`✅ Added ${successfulApps.length} app(s) to manifest`);
90
+ }
91
+ // Report any errors
92
+ const allErrors = [...manifestResult.errors, ...typesResult.errors];
93
+ if (allErrors.length > 0) {
94
+ console.warn(`\n⚠️ ${allErrors.length} error(s) occurred:`);
95
+ allErrors.forEach(({ appKey, error }) => {
96
+ console.warn(` - ${appKey}: ${error}`);
97
+ });
106
98
  }
107
- console.log(`✅ Added ${apps.length} app(s) to manifest`);
108
99
  }, AddSchema);
109
100
  return {
110
101
  add,
@@ -0,0 +1,13 @@
1
+ import type { Plugin, GetSdkType, GetContextType, ListAppsPluginProvides, ManifestPluginProvides } from "@zapier/zapier-sdk";
2
+ import { BuildManifestSchema, type BuildManifestOptions, type BuildManifestResult } from "./schemas";
3
+ export interface BuildManifestPluginProvides {
4
+ buildManifest: (options: BuildManifestOptions) => Promise<BuildManifestResult>;
5
+ context: {
6
+ meta: {
7
+ buildManifest: {
8
+ inputSchema: typeof BuildManifestSchema;
9
+ };
10
+ };
11
+ };
12
+ }
13
+ export declare const buildManifestPlugin: Plugin<GetSdkType<ListAppsPluginProvides>, GetContextType<ManifestPluginProvides>, BuildManifestPluginProvides>;
@@ -0,0 +1,81 @@
1
+ import { createFunction } from "@zapier/zapier-sdk";
2
+ import { BuildManifestSchema, } from "./schemas";
3
+ import { createManifestEntry } from "../../utils/manifest-helpers";
4
+ export const buildManifestPlugin = ({ sdk, context }) => {
5
+ const buildManifest = createFunction(async function buildManifest(options) {
6
+ const { appKeys, skipWrite = false, configPath, onProgress } = options;
7
+ const result = {
8
+ errors: [],
9
+ };
10
+ // Get apps using listApps (which respects existing manifest for version locking)
11
+ onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
12
+ const appsIterator = sdk.listApps({ appKeys }).items();
13
+ const apps = [];
14
+ for await (const app of appsIterator) {
15
+ apps.push(app);
16
+ onProgress?.({ type: "app_found", app });
17
+ }
18
+ onProgress?.({ type: "apps_lookup_complete", count: apps.length });
19
+ if (apps.length === 0) {
20
+ return result;
21
+ }
22
+ let updatedManifest;
23
+ // Process each app
24
+ for (const app of apps) {
25
+ onProgress?.({
26
+ type: "app_processing_start",
27
+ appKey: app.key,
28
+ slug: app.slug,
29
+ });
30
+ try {
31
+ const manifestEntry = createManifestEntry(app);
32
+ onProgress?.({
33
+ type: "manifest_entry_built",
34
+ appKey: app.key,
35
+ manifestKey: manifestEntry.implementationName,
36
+ version: manifestEntry.version || "",
37
+ });
38
+ const [updatedManifestKey, , manifest] = await context.updateManifestEntry({
39
+ appKey: app.key,
40
+ entry: manifestEntry,
41
+ configPath,
42
+ skipWrite,
43
+ manifest: updatedManifest,
44
+ });
45
+ updatedManifest = manifest;
46
+ onProgress?.({
47
+ type: "manifest_updated",
48
+ appKey: app.key,
49
+ manifestKey: updatedManifestKey,
50
+ version: manifestEntry.version || "",
51
+ });
52
+ onProgress?.({ type: "app_processing_complete", appKey: app.key });
53
+ }
54
+ catch (error) {
55
+ const errorMessage = `Failed to process app: ${error}`;
56
+ result.errors.push({
57
+ appKey: app.key,
58
+ error: errorMessage,
59
+ });
60
+ onProgress?.({
61
+ type: "app_processing_error",
62
+ appKey: app.key,
63
+ error: errorMessage,
64
+ });
65
+ }
66
+ }
67
+ result.manifest = updatedManifest;
68
+ return result;
69
+ }, BuildManifestSchema);
70
+ return {
71
+ buildManifest,
72
+ context: {
73
+ meta: {
74
+ buildManifest: {
75
+ categories: ["utility"],
76
+ inputSchema: BuildManifestSchema,
77
+ },
78
+ },
79
+ },
80
+ };
81
+ };
@@ -0,0 +1,56 @@
1
+ import { z } from "zod";
2
+ import type { AppItem, Manifest } from "@zapier/zapier-sdk";
3
+ export declare const BuildManifestSchema: z.ZodObject<{
4
+ appKeys: z.ZodArray<z.ZodString, "many">;
5
+ skipWrite: z.ZodOptional<z.ZodBoolean>;
6
+ configPath: z.ZodOptional<z.ZodString>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ appKeys: string[];
9
+ configPath?: string | undefined;
10
+ skipWrite?: boolean | undefined;
11
+ }, {
12
+ appKeys: string[];
13
+ configPath?: string | undefined;
14
+ skipWrite?: boolean | undefined;
15
+ }>;
16
+ export type BuildManifestOptions = z.infer<typeof BuildManifestSchema> & {
17
+ onProgress?: (event: ManifestBuildProgressEvent) => void;
18
+ };
19
+ export type ManifestBuildProgressEvent = {
20
+ type: "apps_lookup_start";
21
+ count: number;
22
+ } | {
23
+ type: "app_found";
24
+ app: AppItem;
25
+ } | {
26
+ type: "apps_lookup_complete";
27
+ count: number;
28
+ } | {
29
+ type: "app_processing_start";
30
+ appKey: string;
31
+ slug?: string;
32
+ } | {
33
+ type: "manifest_entry_built";
34
+ appKey: string;
35
+ manifestKey: string;
36
+ version: string;
37
+ } | {
38
+ type: "manifest_updated";
39
+ appKey: string;
40
+ manifestKey: string;
41
+ version: string;
42
+ } | {
43
+ type: "app_processing_complete";
44
+ appKey: string;
45
+ } | {
46
+ type: "app_processing_error";
47
+ appKey: string;
48
+ error: string;
49
+ };
50
+ export interface BuildManifestResult {
51
+ manifest?: Manifest;
52
+ errors: Array<{
53
+ appKey: string;
54
+ error: string;
55
+ }>;
56
+ }
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ export const BuildManifestSchema = z
3
+ .object({
4
+ appKeys: z
5
+ .array(z.string().min(1, "App key cannot be empty"))
6
+ .min(1, "At least one app key is required")
7
+ .describe("One or more app keys to build manifest entries for (e.g., 'slack', 'github', 'trello')"),
8
+ skipWrite: z
9
+ .boolean()
10
+ .optional()
11
+ .describe("If true, returns manifest entries without writing to disk. If false or omitted, writes to the manifest file."),
12
+ configPath: z
13
+ .string()
14
+ .optional()
15
+ .describe("Path to the manifest file. Only used when skipWrite is false or omitted."),
16
+ })
17
+ .describe("Build manifest entries for apps - can optionally write to disk or just return JSON");
@@ -0,0 +1,13 @@
1
+ import type { Plugin, GetSdkType, ListActionsPluginProvides, ListAppsPluginProvides, ListInputFieldsPluginProvides, ListAuthenticationsPluginProvides, ManifestPluginProvides } from "@zapier/zapier-sdk";
2
+ import { GenerateAppTypesSchema, type GenerateAppTypesOptions, type GenerateAppTypesResult } from "./schemas";
3
+ export interface GenerateAppTypesPluginProvides {
4
+ generateAppTypes: (options: GenerateAppTypesOptions) => Promise<GenerateAppTypesResult>;
5
+ context: {
6
+ meta: {
7
+ generateAppTypes: {
8
+ inputSchema: typeof GenerateAppTypesSchema;
9
+ };
10
+ };
11
+ };
12
+ }
13
+ export declare const generateAppTypesPlugin: Plugin<GetSdkType<ListAppsPluginProvides & ListActionsPluginProvides & ListInputFieldsPluginProvides & ListAuthenticationsPluginProvides & ManifestPluginProvides>, {}, GenerateAppTypesPluginProvides>;
@@ -0,0 +1,169 @@
1
+ import { createFunction } from "@zapier/zapier-sdk";
2
+ import { GenerateAppTypesSchema, } from "./schemas";
3
+ import { AstTypeGenerator } from "../../generators/ast-generator";
4
+ import { getManifestKey } from "../../utils/manifest-helpers";
5
+ import { mkdir, writeFile } from "fs/promises";
6
+ import { join } from "path";
7
+ export const generateAppTypesPlugin = ({ sdk }) => {
8
+ const generateAppTypes = createFunction(async function generateAppTypes(options) {
9
+ const { appKeys, authenticationIds, skipWrite = false, typesOutputDirectory, onProgress, } = options;
10
+ // Validate that typesOutputDirectory is provided when skipWrite is false
11
+ if (!skipWrite && !typesOutputDirectory) {
12
+ throw new Error("typesOutputDirectory is required when skipWrite is false");
13
+ }
14
+ const result = {
15
+ typeDefinitions: {},
16
+ errors: [],
17
+ };
18
+ // Get apps using listApps (which respects existing manifest for version locking)
19
+ onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
20
+ const appsIterator = sdk.listApps({ appKeys }).items();
21
+ const apps = [];
22
+ for await (const app of appsIterator) {
23
+ apps.push(app);
24
+ onProgress?.({ type: "app_found", app });
25
+ }
26
+ onProgress?.({ type: "apps_lookup_complete", count: apps.length });
27
+ if (apps.length === 0) {
28
+ return result;
29
+ }
30
+ // Fetch authentications if provided
31
+ const authentications = [];
32
+ if (authenticationIds && authenticationIds.length > 0) {
33
+ onProgress?.({
34
+ type: "authentications_lookup_start",
35
+ count: authenticationIds.length,
36
+ });
37
+ const authsIterator = sdk
38
+ .listAuthentications({ authenticationIds })
39
+ .items();
40
+ for await (const auth of authsIterator) {
41
+ authentications.push(auth);
42
+ }
43
+ onProgress?.({
44
+ type: "authentications_lookup_complete",
45
+ count: authentications.length,
46
+ });
47
+ }
48
+ // Ensure output directory exists if we're writing files
49
+ if (!skipWrite && typesOutputDirectory) {
50
+ await mkdir(typesOutputDirectory, { recursive: true });
51
+ }
52
+ // Initialize writtenFiles if we're writing to disk
53
+ if (!skipWrite) {
54
+ result.writtenFiles = {};
55
+ }
56
+ // Process each app
57
+ for (const app of apps) {
58
+ onProgress?.({
59
+ type: "app_processing_start",
60
+ appKey: app.key,
61
+ slug: app.slug,
62
+ });
63
+ try {
64
+ if (!app.version) {
65
+ const error = `Invalid implementation ID format: ${app.implementation_id}. Expected format: <implementationName>@<version>`;
66
+ result.errors.push({
67
+ appKey: app.key,
68
+ error,
69
+ });
70
+ onProgress?.({
71
+ type: "app_processing_error",
72
+ appKey: app.key,
73
+ error,
74
+ });
75
+ continue;
76
+ }
77
+ // Find matching authentication for this app if authentications were provided
78
+ let authenticationId;
79
+ if (authentications.length > 0) {
80
+ const matchingAuth = authentications.find((auth) => {
81
+ return auth.app_key === app.key;
82
+ });
83
+ if (matchingAuth) {
84
+ authenticationId = matchingAuth.id;
85
+ onProgress?.({
86
+ type: "authentication_matched",
87
+ appKey: app.key,
88
+ authenticationId: matchingAuth.id,
89
+ authenticationTitle: matchingAuth.title || "",
90
+ });
91
+ }
92
+ else {
93
+ onProgress?.({
94
+ type: "authentication_not_matched",
95
+ appKey: app.key,
96
+ });
97
+ }
98
+ }
99
+ const manifestKey = getManifestKey(app);
100
+ // Generate type definitions
101
+ try {
102
+ const generator = new AstTypeGenerator();
103
+ const typeDefinitionString = await generator.generateTypes({
104
+ app,
105
+ authenticationId,
106
+ sdk,
107
+ });
108
+ result.typeDefinitions[manifestKey] = typeDefinitionString;
109
+ onProgress?.({
110
+ type: "type_generated",
111
+ manifestKey,
112
+ sizeBytes: typeDefinitionString.length,
113
+ });
114
+ // Write to file if skipWrite is false
115
+ if (!skipWrite && typesOutputDirectory && result.writtenFiles) {
116
+ const filePath = join(typesOutputDirectory, `${manifestKey}.d.ts`);
117
+ await writeFile(filePath, typeDefinitionString, "utf8");
118
+ result.writtenFiles[manifestKey] = filePath;
119
+ onProgress?.({
120
+ type: "file_written",
121
+ manifestKey,
122
+ filePath,
123
+ });
124
+ }
125
+ onProgress?.({
126
+ type: "app_processing_complete",
127
+ appKey: app.key,
128
+ });
129
+ }
130
+ catch (error) {
131
+ const errorMessage = `Failed to generate types: ${error}`;
132
+ result.errors.push({
133
+ appKey: app.key,
134
+ error: errorMessage,
135
+ });
136
+ onProgress?.({
137
+ type: "app_processing_error",
138
+ appKey: app.key,
139
+ error: errorMessage,
140
+ });
141
+ }
142
+ }
143
+ catch (error) {
144
+ const errorMessage = `Failed to process app: ${error}`;
145
+ result.errors.push({
146
+ appKey: app.key,
147
+ error: errorMessage,
148
+ });
149
+ onProgress?.({
150
+ type: "app_processing_error",
151
+ appKey: app.key,
152
+ error: errorMessage,
153
+ });
154
+ }
155
+ }
156
+ return result;
157
+ }, GenerateAppTypesSchema);
158
+ return {
159
+ generateAppTypes,
160
+ context: {
161
+ meta: {
162
+ generateAppTypes: {
163
+ categories: ["utility"],
164
+ inputSchema: GenerateAppTypesSchema,
165
+ },
166
+ },
167
+ },
168
+ };
169
+ };
@@ -0,0 +1,72 @@
1
+ import { z } from "zod";
2
+ import type { AppItem } from "@zapier/zapier-sdk";
3
+ export declare const GenerateAppTypesSchema: z.ZodObject<{
4
+ appKeys: z.ZodArray<z.ZodString, "many">;
5
+ authenticationIds: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
6
+ skipWrite: z.ZodOptional<z.ZodBoolean>;
7
+ typesOutputDirectory: z.ZodOptional<z.ZodString>;
8
+ }, "strip", z.ZodTypeAny, {
9
+ appKeys: string[];
10
+ authenticationIds?: string[] | undefined;
11
+ skipWrite?: boolean | undefined;
12
+ typesOutputDirectory?: string | undefined;
13
+ }, {
14
+ appKeys: string[];
15
+ authenticationIds?: string[] | undefined;
16
+ skipWrite?: boolean | undefined;
17
+ typesOutputDirectory?: string | undefined;
18
+ }>;
19
+ export type GenerateAppTypesOptions = z.infer<typeof GenerateAppTypesSchema> & {
20
+ onProgress?: (event: AppTypesProgressEvent) => void;
21
+ };
22
+ export type AppTypesProgressEvent = {
23
+ type: "apps_lookup_start";
24
+ count: number;
25
+ } | {
26
+ type: "app_found";
27
+ app: AppItem;
28
+ } | {
29
+ type: "apps_lookup_complete";
30
+ count: number;
31
+ } | {
32
+ type: "authentications_lookup_start";
33
+ count: number;
34
+ } | {
35
+ type: "authentications_lookup_complete";
36
+ count: number;
37
+ } | {
38
+ type: "app_processing_start";
39
+ appKey: string;
40
+ slug?: string;
41
+ } | {
42
+ type: "authentication_matched";
43
+ appKey: string;
44
+ authenticationId: number;
45
+ authenticationTitle: string;
46
+ } | {
47
+ type: "authentication_not_matched";
48
+ appKey: string;
49
+ } | {
50
+ type: "type_generated";
51
+ manifestKey: string;
52
+ sizeBytes: number;
53
+ } | {
54
+ type: "file_written";
55
+ manifestKey: string;
56
+ filePath: string;
57
+ } | {
58
+ type: "app_processing_complete";
59
+ appKey: string;
60
+ } | {
61
+ type: "app_processing_error";
62
+ appKey: string;
63
+ error: string;
64
+ };
65
+ export interface GenerateAppTypesResult {
66
+ typeDefinitions: Record<string, string>;
67
+ writtenFiles?: Record<string, string>;
68
+ errors: Array<{
69
+ appKey: string;
70
+ error: string;
71
+ }>;
72
+ }
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ export const GenerateAppTypesSchema = z
3
+ .object({
4
+ appKeys: z
5
+ .array(z.string().min(1, "App key cannot be empty"))
6
+ .min(1, "At least one app key is required")
7
+ .describe("One or more app keys to generate types for (e.g., 'slack', 'github', 'trello')"),
8
+ authenticationIds: z
9
+ .array(z.string())
10
+ .optional()
11
+ .describe("Authentication IDs to use for type generation (e.g., ['123', '456'])"),
12
+ skipWrite: z
13
+ .boolean()
14
+ .optional()
15
+ .describe("If true, returns type definitions without writing to disk. If false or omitted, writes type files."),
16
+ typesOutputDirectory: z
17
+ .string()
18
+ .optional()
19
+ .describe("Directory for TypeScript type files. Required when skipWrite is false or omitted."),
20
+ })
21
+ .describe("Generate TypeScript type definitions for apps - can optionally write to disk or just return type strings");
@@ -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";
@@ -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";