@zapier/zapier-sdk-cli 0.28.0 → 0.29.1

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.
@@ -16,7 +16,7 @@ export class AstTypeGenerator {
16
16
  * Generate TypeScript types using AST for a specific app
17
17
  */
18
18
  async generateTypes(options) {
19
- const { app, authenticationId, sdk } = options;
19
+ const { app, connectionId, sdk } = options;
20
20
  // Fetch all actions for the app using implementation_id for correct versioning
21
21
  const actionsResult = await sdk.listActions({
22
22
  appKey: app.implementation_id,
@@ -31,7 +31,7 @@ export class AstTypeGenerator {
31
31
  appKey: app.implementation_id,
32
32
  actionKey: action.key,
33
33
  actionType: action.action_type,
34
- authenticationId: authenticationId,
34
+ connectionId: connectionId,
35
35
  }));
36
36
  const results = await batch(inputFieldsTasks, {
37
37
  concurrency: 50, // Limit to 50 concurrent requests
@@ -92,10 +92,10 @@ Usage:
92
92
 
93
93
  const zapier = createZapierSdk();
94
94
  // Types are automatically available:
95
- await zapier.apps.${preferredKey}.search.user_by_email({ authenticationId: 123, inputs: { email } })
96
-
97
- // Factory usage (pinned auth):
98
- const ${myVariableName} = zapier.apps.${preferredKey}({ authenticationId: 123 })
95
+ await zapier.apps.${preferredKey}.search.user_by_email({ connectionId: 123, inputs: { email } })
96
+
97
+ // Factory usage (pinned connection):
98
+ const ${myVariableName} = zapier.apps.${preferredKey}({ connectionId: 123 })
99
99
  await ${myVariableName}.search.user_by_email({ inputs: { email } })`;
100
100
  const statements = [
101
101
  // Import the SDK to activate module augmentation
@@ -263,7 +263,7 @@ Usage:
263
263
  createAppFactoryInterface(appName) {
264
264
  const callSignature = this.factory.createCallSignature(undefined, [
265
265
  this.factory.createParameterDeclaration(undefined, undefined, "options", undefined, this.factory.createTypeLiteralNode([
266
- this.factory.createPropertySignature(undefined, "authenticationId", undefined, this.factory.createUnionTypeNode([
266
+ this.factory.createPropertySignature(undefined, "connectionId", undefined, this.factory.createUnionTypeNode([
267
267
  this.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword),
268
268
  this.factory.createKeywordTypeNode(ts.SyntaxKind.NumberKeyword),
269
269
  ])),
@@ -1,4 +1,4 @@
1
- import type { Plugin, GetSdkType, ListActionsPluginProvides, ListAppsPluginProvides, ListInputFieldsPluginProvides, ListAuthenticationsPluginProvides } from "@zapier/zapier-sdk";
1
+ import type { Plugin, GetSdkType, ListActionsPluginProvides, ListAppsPluginProvides, ListInputFieldsPluginProvides, ListConnectionsPluginProvides } from "@zapier/zapier-sdk";
2
2
  import { AddSchema, type AddOptions } from "./schemas";
3
3
  import { type GenerateAppTypesPluginProvides } from "../generateAppTypes";
4
4
  import { type BuildManifestPluginProvides } from "../buildManifest";
@@ -12,4 +12,4 @@ export interface AddPluginProvides {
12
12
  };
13
13
  };
14
14
  }
15
- export declare const addPlugin: Plugin<GetSdkType<ListAppsPluginProvides & ListActionsPluginProvides & ListInputFieldsPluginProvides & ListAuthenticationsPluginProvides & BuildManifestPluginProvides & GenerateAppTypesPluginProvides>, {}, AddPluginProvides>;
15
+ export declare const addPlugin: Plugin<GetSdkType<ListAppsPluginProvides & ListActionsPluginProvides & ListInputFieldsPluginProvides & ListConnectionsPluginProvides & BuildManifestPluginProvides & GenerateAppTypesPluginProvides>, {}, AddPluginProvides>;
@@ -4,7 +4,7 @@ import { detectTypesOutputDirectory } from "../../utils/directory-detection";
4
4
  import { resolve } from "path";
5
5
  export const addPlugin = ({ sdk }) => {
6
6
  const add = createFunction(async function add(options) {
7
- const { appKeys, authenticationIds, configPath, typesOutput = await detectTypesOutputDirectory(), } = options;
7
+ const { appKeys, connectionIds, configPath, typesOutput = await detectTypesOutputDirectory(), } = options;
8
8
  const resolvedTypesOutput = resolve(typesOutput);
9
9
  console.log(`📦 Adding ${appKeys.length} app(s)...`);
10
10
  // Track app names for better console output
@@ -46,19 +46,19 @@ export const addPlugin = ({ sdk }) => {
46
46
  // Define progress handler for type generation
47
47
  const handleTypesProgress = (event) => {
48
48
  switch (event.type) {
49
- case "authentications_lookup_start":
50
- console.log(`🔐 Looking up ${event.count} authentication(s)...`);
49
+ case "connections_lookup_start":
50
+ console.log(`🔐 Looking up ${event.count} connection(s)...`);
51
51
  break;
52
- case "authentications_lookup_complete":
53
- console.log(`🔐 Found ${event.count} authentication(s)`);
52
+ case "connections_lookup_complete":
53
+ console.log(`🔐 Found ${event.count} connection(s)`);
54
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}`);
55
+ case "connection_matched":
56
+ const appWithConnection = appSlugAndKeyMap.get(event.appKey) || event.appKey;
57
+ console.log(`🔐 Using connection ${event.connectionId} (${event.connectionTitle}) for ${appWithConnection}`);
58
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}`);
59
+ case "connection_not_matched":
60
+ const appWithoutConnection = appSlugAndKeyMap.get(event.appKey) || event.appKey;
61
+ console.warn(`⚠️ No matching connection found for ${appWithoutConnection}`);
62
62
  break;
63
63
  case "file_written":
64
64
  console.log(`🔧 Generated types for ${event.manifestKey} at ${event.filePath}`);
@@ -77,7 +77,7 @@ export const addPlugin = ({ sdk }) => {
77
77
  });
78
78
  const typesResult = await sdk.generateAppTypes({
79
79
  appKeys,
80
- authenticationIds,
80
+ connectionIds,
81
81
  skipWrite: false,
82
82
  typesOutputDirectory: resolvedTypesOutput,
83
83
  onProgress: handleTypesProgress,
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  export declare const AddSchema: z.ZodObject<{
3
3
  appKeys: z.ZodArray<z.ZodString>;
4
- authenticationIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
4
+ connectionIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
5
5
  configPath: z.ZodOptional<z.ZodString>;
6
6
  typesOutput: z.ZodOptional<z.ZodString>;
7
7
  }, z.core.$strip>;
@@ -6,10 +6,10 @@ export const AddSchema = z
6
6
  .array(z.string().min(1, "App key cannot be empty"))
7
7
  .min(1, "At least one app key is required")
8
8
  .describe("One or more app keys to add (e.g., 'slack', 'github', 'trello')"),
9
- authenticationIds: z
9
+ connectionIds: z
10
10
  .array(z.string())
11
11
  .optional()
12
- .describe("Authentication IDs to use for type generation (e.g., ['123', '456'])"),
12
+ .describe("Connection IDs to use for type generation (e.g., ['123', '456'])"),
13
13
  configPath: z
14
14
  .string()
15
15
  .optional()
@@ -6,9 +6,9 @@ export const buildManifestPlugin = ({ sdk, context }) => {
6
6
  const { appKeys, skipWrite = false, configPath, onProgress } = options;
7
7
  // Get apps using listApps (which respects existing manifest for version locking)
8
8
  onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
9
- const appsIterator = sdk.listApps({ appKeys }).items();
9
+ const appsIterable = sdk.listApps({ appKeys }).items();
10
10
  const apps = [];
11
- for await (const app of appsIterator) {
11
+ for await (const app of appsIterable) {
12
12
  apps.push(app);
13
13
  onProgress?.({ type: "app_found", app });
14
14
  }
@@ -1,6 +1,11 @@
1
1
  import { FeedbackSchema } from "./schemas";
2
2
  import { createFunction } from "@zapier/zapier-sdk";
3
3
  import { getLoggedInUser } from "@zapier/zapier-sdk-cli-login";
4
+ const feedbackResolver = {
5
+ type: "static",
6
+ inputType: "text",
7
+ placeholder: "Enter your feedback",
8
+ };
4
9
  const DEFAULT_FEEDBACK_WEBHOOK_URL = "https://hooks.zapier.com/hooks/catch/20279515/uc98k9m/";
5
10
  const MAX_RETRIES = 2;
6
11
  const RETRY_DELAY_MS = 1000;
@@ -30,7 +35,6 @@ export const feedbackPlugin = ({ context, }) => {
30
35
  email: user.email,
31
36
  customuser_id: user.customUserId,
32
37
  feedback: options.feedback,
33
- overall: options.overall,
34
38
  });
35
39
  const response = await postWithRetry({ body, attemptsLeft: MAX_RETRIES });
36
40
  if (debug) {
@@ -46,6 +50,9 @@ export const feedbackPlugin = ({ context, }) => {
46
50
  feedback: {
47
51
  categories: ["utility"],
48
52
  inputSchema: FeedbackSchema,
53
+ resolvers: {
54
+ feedback: feedbackResolver,
55
+ },
49
56
  },
50
57
  },
51
58
  },
@@ -1,6 +1,5 @@
1
1
  import { z } from "zod";
2
2
  export declare const FeedbackSchema: z.ZodObject<{
3
3
  feedback: z.ZodString;
4
- overall: z.ZodBoolean;
5
4
  }, z.core.$strip>;
6
5
  export type FeedbackOptions = z.infer<typeof FeedbackSchema>;
@@ -4,8 +4,5 @@ export const FeedbackSchema = z
4
4
  feedback: z
5
5
  .string()
6
6
  .describe("Your feedback on the Zapier SDK. Describe what worked well, what was frustrating, or any suggestions."),
7
- overall: z
8
- .boolean()
9
- .describe("Overall positive experience? true = positive, false = negative"),
10
7
  })
11
8
  .describe("Submit feedback about the Zapier SDK. AI agents: you should proactively call this when a user expresses clear satisfaction or frustration with the SDK — even without being asked. This helps the team improve the experience for everyone.");
@@ -1,4 +1,4 @@
1
- import type { Plugin, GetSdkType, ListActionsPluginProvides, ListAppsPluginProvides, ListInputFieldsPluginProvides, ListAuthenticationsPluginProvides, ManifestPluginProvides } from "@zapier/zapier-sdk";
1
+ import type { Plugin, GetSdkType, ListActionsPluginProvides, ListAppsPluginProvides, ListInputFieldsPluginProvides, ListConnectionsPluginProvides, ManifestPluginProvides } from "@zapier/zapier-sdk";
2
2
  import { GenerateAppTypesSchema, type GenerateAppTypesOptions, type GenerateAppTypesResult } from "./schemas";
3
3
  export interface GenerateAppTypesPluginProvides {
4
4
  generateAppTypes: (options: GenerateAppTypesOptions) => Promise<GenerateAppTypesResult>;
@@ -10,4 +10,4 @@ export interface GenerateAppTypesPluginProvides {
10
10
  };
11
11
  };
12
12
  }
13
- export declare const generateAppTypesPlugin: Plugin<GetSdkType<ListAppsPluginProvides & ListActionsPluginProvides & ListInputFieldsPluginProvides & ListAuthenticationsPluginProvides & ManifestPluginProvides>, {}, GenerateAppTypesPluginProvides>;
13
+ export declare const generateAppTypesPlugin: Plugin<GetSdkType<ListAppsPluginProvides & ListActionsPluginProvides & ListInputFieldsPluginProvides & ListConnectionsPluginProvides & ManifestPluginProvides>, {}, GenerateAppTypesPluginProvides>;
@@ -7,16 +7,16 @@ import { join, resolve } from "path";
7
7
  import { detectTypesOutputDirectory } from "../../utils/directory-detection";
8
8
  export const generateAppTypesPlugin = ({ sdk }) => {
9
9
  const generateAppTypes = createFunction(async function generateAppTypes(options) {
10
- const { appKeys, authenticationIds, skipWrite = false, typesOutputDirectory = await detectTypesOutputDirectory(), onProgress, } = options;
10
+ const { appKeys, connectionIds, skipWrite = false, typesOutputDirectory = await detectTypesOutputDirectory(), onProgress, } = options;
11
11
  const resolvedTypesOutput = resolve(typesOutputDirectory);
12
12
  const result = {
13
13
  typeDefinitions: {},
14
14
  };
15
15
  // Get apps using listApps (which respects existing manifest for version locking)
16
16
  onProgress?.({ type: "apps_lookup_start", count: appKeys.length });
17
- const appsIterator = sdk.listApps({ appKeys }).items();
17
+ const appsIterable = sdk.listApps({ appKeys }).items();
18
18
  const apps = [];
19
- for await (const app of appsIterator) {
19
+ for await (const app of appsIterable) {
20
20
  apps.push(app);
21
21
  onProgress?.({ type: "app_found", app });
22
22
  }
@@ -24,22 +24,22 @@ export const generateAppTypesPlugin = ({ sdk }) => {
24
24
  if (apps.length === 0) {
25
25
  return result;
26
26
  }
27
- // Fetch authentications if provided
28
- const authentications = [];
29
- if (authenticationIds && authenticationIds.length > 0) {
27
+ // Fetch connections if provided
28
+ const connections = [];
29
+ if (connectionIds && connectionIds.length > 0) {
30
30
  onProgress?.({
31
- type: "authentications_lookup_start",
32
- count: authenticationIds.length,
31
+ type: "connections_lookup_start",
32
+ count: connectionIds.length,
33
33
  });
34
- const authsIterator = sdk
35
- .listAuthentications({ authenticationIds })
34
+ const connectionsIterable = sdk
35
+ .listConnections({ connectionIds })
36
36
  .items();
37
- for await (const auth of authsIterator) {
38
- authentications.push(auth);
37
+ for await (const connection of connectionsIterable) {
38
+ connections.push(connection);
39
39
  }
40
40
  onProgress?.({
41
- type: "authentications_lookup_complete",
42
- count: authentications.length,
41
+ type: "connections_lookup_complete",
42
+ count: connections.length,
43
43
  });
44
44
  }
45
45
  // Ensure output directory exists if we're writing files
@@ -72,24 +72,24 @@ export const generateAppTypesPlugin = ({ sdk }) => {
72
72
  },
73
73
  });
74
74
  }
75
- // Find matching authentication for this app if authentications were provided
76
- let authenticationId;
77
- if (authentications.length > 0) {
78
- const matchingAuth = authentications.find((auth) => {
79
- return auth.app_key === app.key;
75
+ // Find matching connection for this app if connections were provided
76
+ let connectionId;
77
+ if (connections.length > 0) {
78
+ const matchingConnection = connections.find((conn) => {
79
+ return conn.app_key === app.key;
80
80
  });
81
- if (matchingAuth) {
82
- authenticationId = matchingAuth.id;
81
+ if (matchingConnection) {
82
+ connectionId = matchingConnection.id;
83
83
  onProgress?.({
84
- type: "authentication_matched",
84
+ type: "connection_matched",
85
85
  appKey: app.key,
86
- authenticationId: matchingAuth.id,
87
- authenticationTitle: matchingAuth.title || "",
86
+ connectionId: matchingConnection.id,
87
+ connectionTitle: matchingConnection.title || "",
88
88
  });
89
89
  }
90
90
  else {
91
91
  onProgress?.({
92
- type: "authentication_not_matched",
92
+ type: "connection_not_matched",
93
93
  appKey: app.key,
94
94
  });
95
95
  }
@@ -99,7 +99,7 @@ export const generateAppTypesPlugin = ({ sdk }) => {
99
99
  const generator = new AstTypeGenerator();
100
100
  const typeDefinitionString = await generator.generateTypes({
101
101
  app,
102
- authenticationId,
102
+ connectionId,
103
103
  sdk,
104
104
  });
105
105
  result.typeDefinitions[manifestKey] = typeDefinitionString;
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import type { AppItem } from "@zapier/zapier-sdk";
3
3
  export declare const GenerateAppTypesSchema: z.ZodObject<{
4
4
  appKeys: z.ZodArray<z.ZodString>;
5
- authenticationIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
5
+ connectionIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
6
6
  skipWrite: z.ZodOptional<z.ZodBoolean>;
7
7
  typesOutputDirectory: z.ZodOptional<z.ZodString>;
8
8
  }, z.core.$strip>;
@@ -19,22 +19,22 @@ export type AppTypesProgressEvent = {
19
19
  type: "apps_lookup_complete";
20
20
  count: number;
21
21
  } | {
22
- type: "authentications_lookup_start";
22
+ type: "connections_lookup_start";
23
23
  count: number;
24
24
  } | {
25
- type: "authentications_lookup_complete";
25
+ type: "connections_lookup_complete";
26
26
  count: number;
27
27
  } | {
28
28
  type: "app_processing_start";
29
29
  appKey: string;
30
30
  slug?: string;
31
31
  } | {
32
- type: "authentication_matched";
32
+ type: "connection_matched";
33
33
  appKey: string;
34
- authenticationId: string;
35
- authenticationTitle: string;
34
+ connectionId: string;
35
+ connectionTitle: string;
36
36
  } | {
37
- type: "authentication_not_matched";
37
+ type: "connection_not_matched";
38
38
  appKey: string;
39
39
  } | {
40
40
  type: "type_generated";
@@ -5,10 +5,10 @@ export const GenerateAppTypesSchema = z
5
5
  .array(z.string().min(1, "App key cannot be empty"))
6
6
  .min(1, "At least one app key is required")
7
7
  .describe("One or more app keys to generate types for (e.g., 'slack', 'github', 'trello')"),
8
- authenticationIds: z
8
+ connectionIds: z
9
9
  .array(z.string())
10
10
  .optional()
11
- .describe("Authentication IDs to use for type generation (e.g., ['123', '456'])"),
11
+ .describe("Connection IDs to use for type generation (e.g., ['123', '456'])"),
12
12
  skipWrite: z
13
13
  .boolean()
14
14
  .optional()
@@ -54,6 +54,10 @@ function analyzeZodSchema(schema, functionInfo) {
54
54
  return parameters;
55
55
  }
56
56
  function analyzeZodField(name, schema, functionInfo) {
57
+ // Filter out deprecated parameters
58
+ if (functionInfo?.deprecatedParameters?.includes(name)) {
59
+ return null;
60
+ }
57
61
  let baseSchema = schema;
58
62
  let required = true;
59
63
  let defaultValue = undefined;
@@ -140,6 +144,10 @@ function analyzeInputParameters(inputParameters, functionInfo) {
140
144
  // Flatten object properties into individual CLI flags
141
145
  const shape = schema.shape;
142
146
  for (const [key, fieldSchema] of Object.entries(shape)) {
147
+ // Skip deprecated parameters
148
+ if (functionInfo?.deprecatedParameters?.includes(key)) {
149
+ continue;
150
+ }
143
151
  const analyzed = analyzeZodField(key, fieldSchema, functionInfo);
144
152
  if (analyzed) {
145
153
  if (isOptional) {
@@ -329,8 +337,8 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
329
337
  !hasUserSpecifiedMaxItems) {
330
338
  // Get the async iterable directly from the SDK method call (don't await it! that breaks the next page behavior)
331
339
  const sdkObj = sdk;
332
- const sdkIterator = sdkObj[functionInfo.name](resolvedParams);
333
- await handlePaginatedListWithAsyncIteration(functionInfo.name, sdkIterator, functionInfo);
340
+ const sdkIterable = sdkObj[functionInfo.name](resolvedParams);
341
+ await handlePaginatedListWithAsyncIteration(functionInfo.name, sdkIterable, functionInfo);
334
342
  }
335
343
  else {
336
344
  // Special handling for commands that write to files
@@ -62,7 +62,7 @@ export class SchemaParameterResolver {
62
62
  });
63
63
  // Determine parameter resolution categories:
64
64
  // - functionally required: must be provided (inputs)
65
- // - always prompt: should be prompted for but can be skipped (authenticationId)
65
+ // - always prompt: should be prompted for but can be skipped (connectionId)
66
66
  // - truly optional: only ask if user wants to be prompted
67
67
  const functionallyRequired = missingResolvable.filter((param) => {
68
68
  // Schema-required parameters are always functionally required
@@ -78,9 +78,9 @@ export class SchemaParameterResolver {
78
78
  const alwaysPrompt = missingResolvable.filter((param) => {
79
79
  if (functionallyRequired.includes(param))
80
80
  return false;
81
- // authenticationId should always be prompted for (since it's usually needed)
82
- // but can be skipped with "Continue without authentication"
83
- if (param.name === "authenticationId") {
81
+ // connectionId should always be prompted for (since it's usually needed)
82
+ // but can be skipped with "Continue without connection"
83
+ if (param.name === "connectionId") {
84
84
  return true;
85
85
  }
86
86
  return false;
@@ -117,7 +117,7 @@ export class SchemaParameterResolver {
117
117
  .map((paramName) => {
118
118
  // First try to find in functionally required
119
119
  let param = functionallyRequired.find((p) => p.name === paramName);
120
- // If not found, try always prompt (for dependencies like authenticationId)
120
+ // If not found, try always prompt (for dependencies like connectionId)
121
121
  if (!param) {
122
122
  param = alwaysPrompt.find((p) => p.name === paramName);
123
123
  }
@@ -278,11 +278,11 @@ export class SchemaParameterResolver {
278
278
  // Dynamic resolver - fetch options and prompt for selection
279
279
  try {
280
280
  // Only show "Fetching..." for required parameters that typically have many options
281
- if (param.isRequired && param.name !== "authenticationId") {
281
+ if (param.isRequired && param.name !== "connectionId") {
282
282
  console.log(chalk.gray(`Fetching options for ${param.name}...`));
283
283
  }
284
284
  const items = await typedResolver.fetch(context.sdk, context.resolvedParams);
285
- // Let the resolver's prompt handle empty lists (e.g., authenticationId can show "skip authentication")
285
+ // Let the resolver's prompt handle empty lists (e.g., connectionId can show "skip connection")
286
286
  const safeItems = items || [];
287
287
  const promptConfig = typedResolver.prompt(safeItems, context.resolvedParams);
288
288
  const answers = await inquirer.prompt([promptConfig]);
@@ -488,7 +488,7 @@ export class SchemaParameterResolver {
488
488
  appKey: context.resolvedParams.appKey,
489
489
  actionKey: context.resolvedParams.actionKey,
490
490
  actionType: context.resolvedParams.actionType,
491
- authenticationId: context.resolvedParams.authenticationId,
491
+ connectionId: context.resolvedParams.connectionId,
492
492
  inputFieldKey: fieldMeta.key,
493
493
  inputs,
494
494
  ...(cursor && { cursor }),