@zapier/zapier-sdk-cli 0.13.4 → 0.13.6

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 (45) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +39 -0
  3. package/dist/cli.cjs +354 -71
  4. package/dist/cli.mjs +355 -72
  5. package/dist/index.cjs +353 -70
  6. package/dist/index.d.mts +154 -2
  7. package/dist/index.d.ts +154 -2
  8. package/dist/index.mjs +354 -71
  9. package/dist/package.json +2 -2
  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 +57 -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 +2 -2
  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/directory-detection.d.ts +5 -0
  27. package/dist/src/utils/directory-detection.js +21 -0
  28. package/dist/src/utils/manifest-helpers.d.ts +13 -0
  29. package/dist/src/utils/manifest-helpers.js +19 -0
  30. package/dist/tsconfig.tsbuildinfo +1 -1
  31. package/package.json +5 -5
  32. package/src/plugins/add/index.ts +123 -125
  33. package/src/plugins/buildManifest/index.test.ts +612 -0
  34. package/src/plugins/buildManifest/index.ts +128 -0
  35. package/src/plugins/buildManifest/schemas.ts +61 -0
  36. package/src/plugins/generateAppTypes/index.ts +235 -0
  37. package/src/plugins/generateAppTypes/schemas.ts +65 -0
  38. package/src/plugins/index.ts +2 -0
  39. package/src/sdk.ts +23 -20
  40. package/src/types/sdk.ts +8 -0
  41. package/src/utils/directory-detection.ts +23 -0
  42. package/src/utils/manifest-helpers.ts +28 -0
  43. /package/dist/src/{plugins/add → generators}/ast-generator.d.ts +0 -0
  44. /package/dist/src/{plugins/add → generators}/ast-generator.js +0 -0
  45. /package/src/{plugins/add → generators}/ast-generator.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zapier/zapier-sdk-cli",
3
- "version": "0.13.4",
3
+ "version": "0.13.6",
4
4
  "description": "Command line interface for Zapier SDK",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.mjs",
@@ -41,10 +41,11 @@
41
41
  "open": "^10.2.0",
42
42
  "ora": "^8.2.0",
43
43
  "pkce-challenge": "^5.0.0",
44
+ "typescript": "^5.8.3",
44
45
  "zod": "^3.25.67",
45
- "@zapier/zapier-sdk": "0.13.4",
46
- "@zapier/zapier-sdk-mcp": "0.3.17",
47
- "@zapier/zapier-sdk-cli-login": "0.3.2"
46
+ "@zapier/zapier-sdk-cli-login": "0.3.2",
47
+ "@zapier/zapier-sdk": "0.13.5",
48
+ "@zapier/zapier-sdk-mcp": "0.3.18"
48
49
  },
49
50
  "devDependencies": {
50
51
  "@types/express": "^5.0.3",
@@ -52,7 +53,6 @@
52
53
  "@types/jsonwebtoken": "^9.0.10",
53
54
  "@types/node": "^24.0.1",
54
55
  "tsup": "^8.5.0",
55
- "typescript": "^5.8.3",
56
56
  "vitest": "^3.2.3"
57
57
  },
58
58
  "scripts": {
@@ -1,40 +1,22 @@
1
1
  import type {
2
2
  Plugin,
3
3
  GetSdkType,
4
- GetContextType,
5
4
  ListActionsPluginProvides,
6
5
  ListAppsPluginProvides,
7
6
  ListInputFieldsPluginProvides,
8
7
  ListAuthenticationsPluginProvides,
9
- ManifestPluginProvides,
10
- AppItem,
11
8
  } from "@zapier/zapier-sdk";
12
9
  import { createFunction } from "@zapier/zapier-sdk";
13
10
  import { AddSchema, type AddOptions } from "./schemas";
14
- import { AstTypeGenerator } from "./ast-generator";
15
- import { mkdir, access, writeFile } from "fs/promises";
16
- import { resolve, join } from "path";
17
-
18
- /**
19
- * Detect the best default directory for TypeScript types
20
- * Looks for src or lib directories, falls back to current directory
21
- */
22
- async function detectTypesOutputDirectory(): Promise<string> {
23
- // Check for common source directories in priority order
24
- const candidates = ["src", "lib"];
25
-
26
- for (const candidate of candidates) {
27
- try {
28
- await access(candidate);
29
- return join(candidate, "zapier", "apps");
30
- } catch {
31
- // Directory doesn't exist, continue to next candidate
32
- }
33
- }
34
11
 
35
- // Fall back to current directory
36
- return "./zapier/apps/";
37
- }
12
+ import { type GenerateAppTypesPluginProvides } from "../generateAppTypes";
13
+ import { type AppTypesProgressEvent } from "../generateAppTypes/schemas";
14
+ import { type BuildManifestPluginProvides } from "../buildManifest";
15
+ import { type ManifestBuildProgressEvent } from "../buildManifest/schemas";
16
+
17
+ import { detectTypesOutputDirectory } from "../../utils/directory-detection";
18
+
19
+ import { resolve } from "path";
38
20
  export interface AddPluginProvides {
39
21
  add: (options: AddOptions) => Promise<void>;
40
22
  context: {
@@ -52,11 +34,12 @@ export const addPlugin: Plugin<
52
34
  ListActionsPluginProvides &
53
35
  ListInputFieldsPluginProvides &
54
36
  ListAuthenticationsPluginProvides &
55
- ManifestPluginProvides
37
+ BuildManifestPluginProvides &
38
+ GenerateAppTypesPluginProvides
56
39
  >,
57
- GetContextType<ManifestPluginProvides>,
40
+ {},
58
41
  AddPluginProvides
59
- > = ({ sdk, context }) => {
42
+ > = ({ sdk }) => {
60
43
  const add = createFunction(async function add(options: AddOptions) {
61
44
  const {
62
45
  appKeys,
@@ -64,114 +47,129 @@ export const addPlugin: Plugin<
64
47
  configPath,
65
48
  typesOutput = await detectTypesOutputDirectory(),
66
49
  } = options;
67
-
68
50
  const resolvedTypesOutput = resolve(typesOutput);
69
51
 
70
- // Ensure types output directory exists
71
- await mkdir(resolvedTypesOutput, { recursive: true });
72
-
73
- // Get apps using listApps (which respects existing manifest for version locking)
74
- console.log(`📦 Looking up ${appKeys.length} app(s)...`);
75
- const appsIterator = sdk.listApps({ appKeys }).items();
76
- const apps: AppItem[] = [];
77
- for await (const app of appsIterator) {
78
- apps.push(app);
79
- }
80
-
81
- if (apps.length === 0) {
82
- console.warn("⚠️ No apps found");
83
- return;
84
- }
52
+ console.log(`📦 Adding ${appKeys.length} app(s)...`);
53
+
54
+ // Track app names for better console output
55
+ const appSlugAndKeyMap = new Map<string, string>();
56
+
57
+ // Define progress handler for manifest building
58
+ const handleManifestProgress = (event: ManifestBuildProgressEvent) => {
59
+ switch (event.type) {
60
+ case "apps_lookup_start":
61
+ console.log(`📦 Looking up ${event.count} app(s)...`);
62
+ break;
63
+
64
+ case "app_found":
65
+ // Store the app display name for later use
66
+ const displayName = event.app.slug
67
+ ? `${event.app.slug} (${event.app.key})`
68
+ : event.app.key;
69
+ appSlugAndKeyMap.set(event.app.key, displayName);
70
+ break;
71
+
72
+ case "apps_lookup_complete":
73
+ if (event.count === 0) {
74
+ console.warn("⚠️ No apps found");
75
+ }
76
+ break;
77
+
78
+ case "app_processing_start":
79
+ const appName = event.slug
80
+ ? `${event.slug} (${event.appKey})`
81
+ : event.appKey;
82
+ console.log(`📦 Adding ${appName}...`);
83
+ break;
84
+
85
+ case "manifest_updated":
86
+ const appDisplay = appSlugAndKeyMap.get(event.appKey) || event.appKey;
87
+ console.log(
88
+ `📝 Locked ${appDisplay} to ${event.appKey}@${event.version} using key '${event.manifestKey}'`,
89
+ );
90
+ break;
85
91
 
86
- // Fetch authentications if provided
87
- let authentications = [];
88
- if (authenticationIds && authenticationIds.length > 0) {
89
- console.log(
90
- `🔐 Looking up ${authenticationIds.length} authentication(s)...`,
91
- );
92
- const authsIterator = sdk
93
- .listAuthentications({ authenticationIds })
94
- .items();
95
- for await (const auth of authsIterator) {
96
- authentications.push(auth);
92
+ case "app_processing_error":
93
+ const errorApp = appSlugAndKeyMap.get(event.appKey) || event.appKey;
94
+ console.warn(`⚠️ ${event.error} for ${errorApp}`);
95
+ break;
97
96
  }
98
- console.log(`🔐 Found ${authentications.length} authentication(s)`);
99
- }
97
+ };
100
98
 
101
- // Process each app
102
- for (const app of apps) {
103
- const appSlugAndKey = app.slug ? `${app.slug} (${app.key})` : app.key;
104
- console.log(`📦 Adding ${appSlugAndKey}...`);
99
+ // Define progress handler for type generation
100
+ const handleTypesProgress = (event: AppTypesProgressEvent) => {
101
+ switch (event.type) {
102
+ case "authentications_lookup_start":
103
+ console.log(`🔐 Looking up ${event.count} authentication(s)...`);
104
+ break;
105
+
106
+ case "authentications_lookup_complete":
107
+ console.log(`🔐 Found ${event.count} authentication(s)`);
108
+ break;
109
+
110
+ case "authentication_matched":
111
+ const appWithAuth =
112
+ appSlugAndKeyMap.get(event.appKey) || event.appKey;
113
+ console.log(
114
+ `🔐 Using authentication ${event.authenticationId} (${event.authenticationTitle}) for ${appWithAuth}`,
115
+ );
116
+ break;
105
117
 
106
- try {
107
- if (!app.version) {
118
+ case "authentication_not_matched":
119
+ const appWithoutAuth =
120
+ appSlugAndKeyMap.get(event.appKey) || event.appKey;
108
121
  console.warn(
109
- `⚠️ Invalid implementation ID format for '${appSlugAndKey}': ${app.implementation_id}. Expected format: <implementationName>@<version>. Skipping...`,
122
+ `⚠️ No matching authentication found for ${appWithoutAuth}`,
110
123
  );
111
- continue;
112
- }
113
-
114
- // Update manifest using manifest plugin's function
115
- const [manifestKey] = await context.updateManifestEntry(
116
- app.key,
117
- {
118
- implementationName: app.key,
119
- version: app.version,
120
- },
121
- configPath,
122
- );
123
-
124
- console.log(
125
- `📝 Locked ${appSlugAndKey} to ${app.key}@${app.version} using key '${manifestKey}'`,
126
- );
127
-
128
- // Find matching authentication for this app if authentications were provided
129
- let authenticationId: number | undefined;
130
- if (authentications.length > 0) {
131
- // Match authentication by app_key
132
- const matchingAuth = authentications.find((auth) => {
133
- return auth.app_key === app.key;
134
- });
135
-
136
- if (matchingAuth) {
137
- authenticationId = matchingAuth.id;
138
- console.log(
139
- `🔐 Using authentication ${authenticationId} (${matchingAuth.title}) for ${appSlugAndKey}`,
140
- );
141
- } else {
142
- console.warn(
143
- `⚠️ No matching authentication found for ${appSlugAndKey}`,
144
- );
145
- }
146
- }
147
-
148
- // Generate types using the manifest key for consistency
149
- const typesPath = join(resolvedTypesOutput, `${manifestKey}.d.ts`);
150
-
151
- try {
152
- // Use AST-based generator directly
153
- const generator = new AstTypeGenerator();
154
- const typeDefinitions = await generator.generateTypes({
155
- app,
156
- authenticationId,
157
- sdk,
158
- });
159
-
160
- // Write to file
161
- await writeFile(typesPath, typeDefinitions, "utf8");
162
- console.log(`🔧 Generated types for ${manifestKey} at ${typesPath}`);
163
- } catch (error) {
164
- console.warn(
165
- `⚠️ Failed to generate types for ${appSlugAndKey}: ${error}`,
124
+ break;
125
+
126
+ case "file_written":
127
+ console.log(
128
+ `🔧 Generated types for ${event.manifestKey} at ${event.filePath}`,
166
129
  );
167
- // Continue even if type generation fails
168
- }
169
- } catch (error) {
170
- console.warn(`⚠️ Failed to process ${appSlugAndKey}: ${error}`);
130
+ break;
131
+
132
+ case "app_processing_error":
133
+ const errorApp = appSlugAndKeyMap.get(event.appKey) || event.appKey;
134
+ console.warn(`⚠️ ${event.error} for ${errorApp}`);
135
+ break;
171
136
  }
137
+ };
138
+
139
+ const manifestResult = await sdk.buildManifest({
140
+ appKeys,
141
+ skipWrite: false,
142
+ configPath,
143
+ onProgress: handleManifestProgress,
144
+ });
145
+
146
+ const typesResult = await sdk.generateAppTypes({
147
+ appKeys,
148
+ authenticationIds,
149
+ skipWrite: false,
150
+ typesOutputDirectory: resolvedTypesOutput,
151
+ onProgress: handleTypesProgress,
152
+ });
153
+
154
+ const results = manifestResult.manifest?.apps || {};
155
+
156
+ // Final summary
157
+ const successfulApps = Object.keys(results).filter(
158
+ (manifestKey) => typesResult.writtenFiles?.[manifestKey],
159
+ );
160
+
161
+ if (successfulApps.length > 0) {
162
+ console.log(`✅ Added ${successfulApps.length} app(s) to manifest`);
172
163
  }
173
164
 
174
- console.log(`✅ Added ${apps.length} app(s) to manifest`);
165
+ // Report any errors
166
+ const allErrors = [...manifestResult.errors, ...typesResult.errors];
167
+ if (allErrors.length > 0) {
168
+ console.warn(`\n⚠️ ${allErrors.length} error(s) occurred:`);
169
+ allErrors.forEach(({ appKey, error }) => {
170
+ console.warn(` - ${appKey}: ${error}`);
171
+ });
172
+ }
175
173
  }, AddSchema);
176
174
 
177
175
  return {