@zapier/zapier-sdk-cli 0.4.4 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zapier/zapier-sdk-cli",
3
- "version": "0.4.4",
3
+ "version": "0.6.0",
4
4
  "description": "Command line interface for Zapier SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -31,9 +31,9 @@
31
31
  "ora": "^8.2.0",
32
32
  "pkce-challenge": "^5.0.0",
33
33
  "zod": "^3.25.67",
34
- "@zapier/zapier-sdk": "0.5.1",
35
- "@zapier/zapier-sdk-mcp": "0.1.3",
36
- "@zapier/zapier-sdk-cli-login": "0.3.1"
34
+ "@zapier/zapier-sdk": "0.6.0",
35
+ "@zapier/zapier-sdk-cli-login": "0.3.2",
36
+ "@zapier/zapier-sdk-mcp": "0.2.0"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/express": "^5.0.3",
package/src/cli.test.ts CHANGED
@@ -8,8 +8,7 @@ describe("CLI", () => {
8
8
  cwd: __dirname + "/..",
9
9
  });
10
10
 
11
- expect(result).toContain("Usage:");
12
- expect(result).toContain("Commands:");
13
11
  expect(result).toContain("Options:");
12
+ expect(result).toContain("Commands:");
14
13
  });
15
14
  });
package/src/cli.ts CHANGED
@@ -16,7 +16,7 @@ const program = new Command();
16
16
 
17
17
  program
18
18
  .name("zapier-sdk")
19
- .description("CLI for Zapier SDK - Commands auto-generated from SDK schemas")
19
+ .description("CLI for Zapier SDK")
20
20
  .version("1.0.0")
21
21
  .option("--debug", "Enable debug logging");
22
22
 
@@ -46,7 +46,11 @@ export function createBundleCodeCommand(): Command {
46
46
  command.option(flags.join(", "), param.description);
47
47
  } else {
48
48
  const flagSignature = flags.join(", ") + ` <${param.type}>`;
49
- command.option(flagSignature, param.description, param.default);
49
+ command.option(
50
+ flagSignature,
51
+ param.description || "",
52
+ param.default as string | boolean | string[] | undefined,
53
+ );
50
54
  }
51
55
  }
52
56
  });
@@ -54,10 +58,12 @@ export function createBundleCodeCommand(): Command {
54
58
  // Add formatting options like other commands
55
59
  command.option("--json", "Output raw JSON instead of formatted results");
56
60
 
57
- command.action(async (...args: any[]) => {
61
+ command.action(async (...args: unknown[]) => {
58
62
  try {
59
63
  // The last argument is always the command object with parsed options
60
- const commandObj = args[args.length - 1];
64
+ const commandObj = args[args.length - 1] as {
65
+ opts(): Record<string, unknown>;
66
+ };
61
67
  const options = commandObj.opts();
62
68
 
63
69
  // Convert CLI args to SDK method parameters
@@ -76,7 +82,16 @@ export function createBundleCodeCommand(): Command {
76
82
  console.log(chalk.blue(`šŸ“¦ Bundling ${rawParams.input}...`));
77
83
 
78
84
  // Call our implementation
79
- const result = await bundleCode(rawParams as any);
85
+ const result = await bundleCode(
86
+ rawParams as {
87
+ string: boolean;
88
+ input: string;
89
+ minify: boolean;
90
+ target: string;
91
+ cjs: boolean;
92
+ output?: string | undefined;
93
+ },
94
+ );
80
95
 
81
96
  if (options.json) {
82
97
  console.log(JSON.stringify({ result }, null, 2));
@@ -48,7 +48,11 @@ export function createGenerateTypesCommand(): Command {
48
48
  command.option(flags.join(", "), param.description);
49
49
  } else {
50
50
  const flagSignature = flags.join(", ") + ` <${param.type}>`;
51
- command.option(flagSignature, param.description, param.default);
51
+ command.option(
52
+ flagSignature,
53
+ param.description || "",
54
+ param.default as string | boolean | string[] | undefined,
55
+ );
52
56
  }
53
57
  }
54
58
  });
@@ -56,10 +60,12 @@ export function createGenerateTypesCommand(): Command {
56
60
  // Add formatting options like other commands
57
61
  command.option("--json", "Output raw JSON instead of formatted results");
58
62
 
59
- command.action(async (...args: any[]) => {
63
+ command.action(async (...args: unknown[]) => {
60
64
  try {
61
65
  // The last argument is always the command object with parsed options
62
- const commandObj = args[args.length - 1];
66
+ const commandObj = args[args.length - 1] as {
67
+ opts(): Record<string, unknown>;
68
+ };
63
69
  const options = commandObj.opts();
64
70
 
65
71
  // Convert CLI args to SDK method parameters
@@ -69,9 +75,10 @@ export function createGenerateTypesCommand(): Command {
69
75
  options,
70
76
  );
71
77
 
72
- // Create SDK instance
73
- const sdk = createZapierSdk();
74
-
78
+ // Create SDK instance with manifest path if provided
79
+ const sdk = createZapierSdk({
80
+ manifestPath: rawParams.lockFilePath as string | undefined,
81
+ });
75
82
  // Resolve missing parameters interactively using schema metadata
76
83
  const resolver = new SchemaParameterResolver();
77
84
  const resolvedParams = await resolver.resolveParameters(
@@ -80,20 +87,29 @@ export function createGenerateTypesCommand(): Command {
80
87
  sdk,
81
88
  );
82
89
 
90
+ const params = resolvedParams as Record<string, unknown>;
83
91
  console.log(
84
92
  chalk.blue(
85
- `šŸ”§ Generating TypeScript types for ${resolvedParams.appKey}...`,
93
+ `šŸ”§ Generating TypeScript types for ${params.appKey as string}...`,
86
94
  ),
87
95
  );
88
96
 
89
97
  // Call our implementation
90
- const result = await generateTypes({ ...resolvedParams, sdk });
98
+ const generateTypesParams = {
99
+ appKey: params.appKey as string,
100
+ debug: (params.debug as boolean) ?? false,
101
+ authenticationId: params.authenticationId as number | undefined,
102
+ output: params.output as string | undefined,
103
+ sdk,
104
+ };
105
+ const result = await generateTypes(generateTypesParams);
91
106
 
92
107
  if (options.json) {
93
108
  console.log(JSON.stringify({ result }, null, 2));
94
109
  } else {
95
110
  const output =
96
- resolvedParams.output || `./types/${resolvedParams.appKey}.d.ts`;
111
+ (params.output as string) ||
112
+ `./types/${params.appKey as string}.d.ts`;
97
113
  console.log(chalk.green("āœ… TypeScript types generated successfully!"));
98
114
  console.log(chalk.gray(`Output written to: ${output}`));
99
115
  }
@@ -64,24 +64,50 @@ export async function generateTypes(
64
64
  if (authenticationId) {
65
65
  for (const action of actions) {
66
66
  try {
67
+ // Check to see if the appKey is in the manifest
68
+ const manifestEntry = sdk.getContext().getManifestEntry(appKey);
69
+
67
70
  const fieldsResult = await sdk.listInputFields({
68
- appKey: action.app_key,
71
+ // If the appKey is in the manifest, use the appKey so that the types are consistent with the manifest's version, otherwise use the action.app_key
72
+ appKey: manifestEntry ? appKey : action.app_key,
69
73
  actionKey: action.key,
70
- actionType: action.action_type as any,
74
+ actionType: action.action_type,
71
75
  authenticationId: authenticationId,
72
76
  });
73
77
 
74
- const fields = fieldsResult.data; // Direct array result
75
- actionsWithFields.push({ ...action, inputFields: fields } as any);
78
+ const fields = fieldsResult.data.map((field: unknown): ActionField => {
79
+ const fieldObj = field as {
80
+ is_required?: boolean;
81
+ required?: boolean;
82
+ [key: string]: unknown;
83
+ };
84
+ return {
85
+ ...fieldObj,
86
+ required: fieldObj.is_required || fieldObj.required || false,
87
+ } as ActionField;
88
+ });
89
+ actionsWithFields.push({
90
+ ...action,
91
+ inputFields: fields,
92
+ name: action.title || action.key,
93
+ });
76
94
  } catch {
77
95
  // If we can't get fields for an action, include it without fields
78
- actionsWithFields.push({ ...action, inputFields: [] } as any);
96
+ actionsWithFields.push({
97
+ ...action,
98
+ inputFields: [],
99
+ name: action.title || action.key,
100
+ });
79
101
  }
80
102
  }
81
103
  } else {
82
104
  // Convert actions to have empty input fields (will generate generic types)
83
105
  actions.forEach((action: ActionItem) => {
84
- actionsWithFields.push({ ...action, inputFields: [] } as any);
106
+ actionsWithFields.push({
107
+ ...action,
108
+ inputFields: [],
109
+ name: action.title || action.key,
110
+ });
85
111
  });
86
112
  }
87
113
 
@@ -17,6 +17,10 @@ export const GenerateTypesSchema = z
17
17
  debug: DebugPropertySchema.describe(
18
18
  "Enable debug logging during generation",
19
19
  ),
20
+ lockFilePath: z
21
+ .string()
22
+ .optional()
23
+ .describe("Path to the .zapierrc lock file (defaults to .zapierrc)"),
20
24
  })
21
25
  .describe("Generate TypeScript SDK code for a specific app");
22
26
 
@@ -1,13 +1,13 @@
1
1
  // Simple HTTP client for OAuth authentication
2
- export interface ApiResponse<T = any> {
2
+ export interface ApiResponse<T = unknown> {
3
3
  data: T;
4
4
  status: number;
5
5
  }
6
6
 
7
7
  export const createApiClient = () => {
8
- const post = async <T = any>(
8
+ const post = async <T = unknown>(
9
9
  url: string,
10
- data: any,
10
+ data: Record<string, string>,
11
11
  options: {
12
12
  headers?: Record<string, string>;
13
13
  } = {},
@@ -2,6 +2,7 @@ import open from "open";
2
2
  import crypto from "node:crypto";
3
3
  import express from "express";
4
4
  import pkceChallenge from "pkce-challenge";
5
+ import type { Socket } from "net";
5
6
 
6
7
  import {
7
8
  AUTH_MODE_HEADER,
@@ -86,7 +87,7 @@ const login = async (timeoutMs: number = LOGIN_TIMEOUT_MS): Promise<string> => {
86
87
  const server = app.listen(availablePort);
87
88
 
88
89
  // Track connections to force close them if needed
89
- const connections = new Set<any>();
90
+ const connections = new Set<Socket>();
90
91
  server.on("connection", (conn) => {
91
92
  connections.add(conn);
92
93
  conn.on("close", () => connections.delete(conn));
@@ -10,7 +10,7 @@ export interface CliParameter {
10
10
  type: "string" | "number" | "boolean" | "array";
11
11
  required: boolean;
12
12
  description?: string;
13
- default?: any;
13
+ default?: unknown;
14
14
  choices?: string[];
15
15
  hasResolver?: boolean;
16
16
  isPositional?: boolean;
@@ -43,7 +43,7 @@ function analyzeZodField(
43
43
  ): CliParameter | null {
44
44
  let baseSchema = schema;
45
45
  let required = true;
46
- let defaultValue: any = undefined;
46
+ let defaultValue: unknown = undefined;
47
47
 
48
48
  // Unwrap optional and default wrappers
49
49
  if (baseSchema instanceof z.ZodOptional) {
@@ -96,10 +96,10 @@ function analyzeZodField(
96
96
 
97
97
  export function convertCliArgsToSdkParams(
98
98
  parameters: CliParameter[],
99
- positionalArgs: any[],
100
- options: Record<string, any>,
101
- ): Record<string, any> {
102
- const sdkParams: Record<string, any> = {};
99
+ positionalArgs: unknown[],
100
+ options: Record<string, unknown>,
101
+ ): Record<string, unknown> {
102
+ const sdkParams: Record<string, unknown> = {};
103
103
 
104
104
  // Handle positional arguments (required parameters or optional positional parameters)
105
105
  let argIndex = 0;
@@ -131,7 +131,7 @@ export function convertCliArgsToSdkParams(
131
131
  return sdkParams;
132
132
  }
133
133
 
134
- function convertValue(value: any, type: CliParameter["type"]): any {
134
+ function convertValue(value: unknown, type: CliParameter["type"]): unknown {
135
135
  switch (type) {
136
136
  case "number":
137
137
  return Number(value);
@@ -17,13 +17,15 @@ import inquirer from "inquirer";
17
17
  // JSON Formatting
18
18
  // ============================================================================
19
19
 
20
- function formatJsonOutput(data: any): void {
20
+ function formatJsonOutput(data: unknown): void {
21
21
  // Show success message for action results
22
22
  if (
23
23
  data &&
24
24
  typeof data === "object" &&
25
25
  !Array.isArray(data) &&
26
- (data.success !== undefined || data.id || data.status)
26
+ ((data as Record<string, unknown>).success !== undefined ||
27
+ (data as Record<string, unknown>).id ||
28
+ (data as Record<string, unknown>).status)
27
29
  ) {
28
30
  console.log(chalk.green("āœ… Action completed successfully!\n"));
29
31
  }
@@ -41,7 +43,7 @@ function formatJsonOutput(data: any): void {
41
43
  interface CliCommandConfig {
42
44
  description: string;
43
45
  parameters: CliParameter[];
44
- handler: (...args: any[]) => Promise<void>;
46
+ handler: (...args: unknown[]) => Promise<void>;
45
47
  }
46
48
 
47
49
  interface CliParameter {
@@ -49,7 +51,7 @@ interface CliParameter {
49
51
  type: "string" | "number" | "boolean" | "array";
50
52
  required: boolean;
51
53
  description?: string;
52
- default?: any;
54
+ default?: unknown;
53
55
  choices?: string[];
54
56
  hasResolver?: boolean;
55
57
  isPositional?: boolean;
@@ -82,7 +84,7 @@ function analyzeZodField(
82
84
  ): CliParameter | null {
83
85
  let baseSchema = schema;
84
86
  let required = true;
85
- let defaultValue: any = undefined;
87
+ let defaultValue: unknown = undefined;
86
88
 
87
89
  // Unwrap optional and default wrappers
88
90
  if (baseSchema instanceof z.ZodOptional) {
@@ -155,13 +157,15 @@ function methodNameToCliCommand(methodName: string): string {
155
157
 
156
158
  export function generateCliCommands(program: Command, sdk: ZapierSdk): void {
157
159
  // Check if SDK has registry
158
- if (!sdk.__registry) {
160
+ if (typeof sdk.getRegistry !== "function") {
159
161
  console.error("SDK registry not available");
160
162
  return;
161
163
  }
162
164
 
163
- // Generate one flat command for each function in the registry
164
- sdk.__registry.forEach((fnInfo) => {
165
+ const registry = sdk.getRegistry();
166
+
167
+ // Create all commands first
168
+ registry.functions.forEach((fnInfo) => {
165
169
  if (!fnInfo.inputSchema) {
166
170
  console.warn(`Schema not found for ${fnInfo.name}`);
167
171
  return;
@@ -179,6 +183,75 @@ export function generateCliCommands(program: Command, sdk: ZapierSdk): void {
179
183
 
180
184
  addCommand(program, cliCommandName, config);
181
185
  });
186
+
187
+ // Override the help display to show commands grouped by category
188
+ program.configureHelp({
189
+ formatHelp: (cmd, helper) => {
190
+ const helpWidth = helper.helpWidth || 80;
191
+
192
+ let output = helper.commandUsage(cmd) + "\n";
193
+
194
+ if (cmd.description()) {
195
+ output += helper.wrap(cmd.description(), helpWidth, 0) + "\n";
196
+ }
197
+
198
+ // Add options section
199
+ const options = helper.visibleOptions(cmd);
200
+ if (options.length > 0) {
201
+ output += "\nOptions:\n";
202
+ const longestOptionLength = Math.max(
203
+ ...options.map((opt) => helper.optionTerm(opt).length),
204
+ );
205
+ options.forEach((option) => {
206
+ const term = helper.optionTerm(option);
207
+ const padding = " ".repeat(
208
+ Math.max(2, longestOptionLength - term.length + 4),
209
+ );
210
+ output += ` ${term}${padding}${helper.optionDescription(option)}\n`;
211
+ });
212
+ }
213
+
214
+ // Add categorized commands section
215
+ const commands = helper.visibleCommands(cmd);
216
+ if (commands.length > 0) {
217
+ output += "\nCommands:\n";
218
+
219
+ // Collect all SDK commands that belong to categories
220
+ const categorizedCommands = new Set<string>();
221
+
222
+ // Group SDK commands by categories
223
+ registry.categories.forEach((category) => {
224
+ const categoryCommands = commands.filter((command) =>
225
+ category.functions.some((functionName) => {
226
+ const cliCommandName = methodNameToCliCommand(functionName);
227
+ return command.name() === cliCommandName;
228
+ }),
229
+ );
230
+
231
+ if (categoryCommands.length > 0) {
232
+ output += `\n ${category.titlePlural}:\n`;
233
+ categoryCommands.forEach((command) => {
234
+ output += ` ${helper.subcommandTerm(command)}\n`;
235
+ categorizedCommands.add(command.name());
236
+ });
237
+ }
238
+ });
239
+
240
+ // Add any remaining commands that aren't part of SDK categories
241
+ const otherCommands = commands.filter(
242
+ (command) => !categorizedCommands.has(command.name()),
243
+ );
244
+ if (otherCommands.length > 0) {
245
+ output += `\n Other:\n`;
246
+ otherCommands.forEach((command) => {
247
+ output += ` ${helper.subcommandTerm(command)}\n`;
248
+ });
249
+ }
250
+ }
251
+
252
+ return output;
253
+ },
254
+ });
182
255
  }
183
256
 
184
257
  function createCommandConfig(
@@ -190,10 +263,12 @@ function createCommandConfig(
190
263
  const parameters = analyzeZodSchema(schema);
191
264
  const description = schema.description || `${cliCommandName} command`;
192
265
 
193
- const handler = async (...args: any[]) => {
266
+ const handler = async (...args: unknown[]) => {
194
267
  try {
195
268
  // The last argument is always the command object with parsed options
196
- const commandObj = args[args.length - 1];
269
+ const commandObj = args[args.length - 1] as {
270
+ opts(): Record<string, unknown>;
271
+ };
197
272
  const options = commandObj.opts();
198
273
 
199
274
  // Check if this is a list command for pagination
@@ -201,7 +276,7 @@ function createCommandConfig(
201
276
  const hasPaginationParams = parameters.some(
202
277
  (p) => p.name === "maxItems" || p.name === "pageSize",
203
278
  );
204
- const hasUserSpecifiedMaxItems =
279
+ const hasUserSpecifiedMaxItems: boolean =
205
280
  "maxItems" in options && options.maxItems !== undefined;
206
281
  const shouldUseJson = options.json;
207
282
 
@@ -220,18 +295,6 @@ function createCommandConfig(
220
295
  sdk,
221
296
  );
222
297
 
223
- // Special handling for commands that write to files
224
- const hasOutputFile = resolvedParams.output;
225
- if (hasOutputFile) {
226
- // Call the SDK method for file output commands
227
- await (sdk as any)[sdkMethodName](resolvedParams);
228
- console.log(
229
- chalk.green(`āœ… ${cliCommandName} completed successfully!`),
230
- );
231
- console.log(chalk.gray(`Output written to: ${resolvedParams.output}`));
232
- return;
233
- }
234
-
235
298
  // Handle paginated list commands with async iteration
236
299
  if (
237
300
  isListCommand &&
@@ -240,25 +303,51 @@ function createCommandConfig(
240
303
  !hasUserSpecifiedMaxItems
241
304
  ) {
242
305
  // Get the async iterator directly from the SDK method call
243
- const sdkIterator = (sdk as any)[sdkMethodName](resolvedParams);
306
+ const sdkObj = sdk as unknown as Record<
307
+ string,
308
+ (params: unknown) => Promise<unknown>
309
+ >;
310
+ const sdkIterator = await sdkObj[sdkMethodName](resolvedParams);
244
311
  await handlePaginatedListWithAsyncIteration(
245
312
  sdkMethodName,
246
313
  sdkIterator,
247
314
  schema,
248
315
  );
249
316
  } else {
317
+ // Special handling for commands that write to files
318
+ const hasOutputFile = (resolvedParams as { output?: unknown }).output;
319
+ if (hasOutputFile) {
320
+ // Call the SDK method for file output commands
321
+ const sdkObj = sdk as unknown as Record<
322
+ string,
323
+ (params: unknown) => Promise<unknown>
324
+ >;
325
+ await sdkObj[sdkMethodName](resolvedParams);
326
+ console.log(
327
+ chalk.green(`āœ… ${cliCommandName} completed successfully!`),
328
+ );
329
+ console.log(chalk.gray(`Output written to: ${hasOutputFile}`));
330
+ return;
331
+ }
332
+
250
333
  // Call the SDK method and handle non-paginated results
251
- const result = await (sdk as any)[sdkMethodName](resolvedParams);
252
- const items = result?.data ? result.data : result;
334
+ const sdkObj = sdk as unknown as Record<
335
+ string,
336
+ (params: unknown) => Promise<unknown>
337
+ >;
338
+ const result: unknown = await sdkObj[sdkMethodName](resolvedParams);
339
+ const items = (result as { data?: unknown })?.data
340
+ ? (result as { data: unknown }).data
341
+ : result;
253
342
 
254
343
  if (shouldUseJson) {
255
344
  console.log(JSON.stringify(items, null, 2));
256
345
  } else if (isListCommand) {
257
346
  formatNonPaginatedResults(
258
- items,
259
- resolvedParams.maxItems,
347
+ items as unknown[],
348
+ (resolvedParams as { maxItems?: number }).maxItems,
260
349
  hasUserSpecifiedMaxItems,
261
- shouldUseJson,
350
+ shouldUseJson as boolean,
262
351
  schema,
263
352
  sdkMethodName,
264
353
  );
@@ -272,9 +361,14 @@ function createCommandConfig(
272
361
  try {
273
362
  const validationErrors = JSON.parse(error.message);
274
363
  console.error(chalk.red("āŒ Validation Error:"));
275
- validationErrors.forEach((err: any) => {
276
- const field = err.path?.join(".") || "unknown";
277
- console.error(chalk.yellow(` • ${field}: ${err.message}`));
364
+ validationErrors.forEach((err: unknown) => {
365
+ const errorObj = err as { path?: string[]; message?: string };
366
+ const field = errorObj?.path?.join(".") || "unknown";
367
+ console.error(
368
+ chalk.yellow(
369
+ ` • ${field}: ${errorObj?.message || "Unknown error"}`,
370
+ ),
371
+ );
278
372
  });
279
373
  console.error(
280
374
  "\n" + chalk.dim(`Use --help to see available options`),
@@ -342,10 +436,18 @@ function addCommand(
342
436
  } else if (param.type === "array") {
343
437
  // For arrays, use variadic syntax to collect multiple values
344
438
  const flagSignature = flags.join(", ") + ` <values...>`;
345
- command.option(flagSignature, param.description, param.default);
439
+ command.option(
440
+ flagSignature,
441
+ param.description,
442
+ param.default as string[] | undefined,
443
+ );
346
444
  } else {
347
445
  const flagSignature = flags.join(", ") + ` <${param.type}>`;
348
- command.option(flagSignature, param.description, param.default);
446
+ command.option(
447
+ flagSignature,
448
+ param.description || "",
449
+ param.default as string | boolean | string[] | undefined,
450
+ );
349
451
  }
350
452
  }
351
453
  });
@@ -362,10 +464,10 @@ function addCommand(
362
464
 
363
465
  function convertCliArgsToSdkParams(
364
466
  parameters: CliParameter[],
365
- positionalArgs: any[],
366
- options: Record<string, any>,
367
- ): Record<string, any> {
368
- const sdkParams: Record<string, any> = {};
467
+ positionalArgs: unknown[],
468
+ options: Record<string, unknown>,
469
+ ): Record<string, unknown> {
470
+ const sdkParams: Record<string, unknown> = {};
369
471
 
370
472
  // Handle positional arguments (required parameters or optional positional parameters)
371
473
  let argIndex = 0;
@@ -397,7 +499,7 @@ function convertCliArgsToSdkParams(
397
499
  return sdkParams;
398
500
  }
399
501
 
400
- function convertValue(value: any, type: CliParameter["type"]): any {
502
+ function convertValue(value: unknown, type: CliParameter["type"]): unknown {
401
503
  switch (type) {
402
504
  case "number":
403
505
  return Number(value);
@@ -428,7 +530,7 @@ function convertValue(value: any, type: CliParameter["type"]): any {
428
530
 
429
531
  async function handlePaginatedListWithAsyncIteration(
430
532
  sdkMethodName: string,
431
- sdkResult: any,
533
+ sdkResult: unknown,
432
534
  schema: z.ZodSchema,
433
535
  ): Promise<void> {
434
536
  const itemName = getItemNameFromMethod(sdkMethodName);
@@ -439,7 +541,10 @@ async function handlePaginatedListWithAsyncIteration(
439
541
 
440
542
  try {
441
543
  // Use async iteration to go through pages
442
- for await (const page of sdkResult) {
544
+ for await (const page of sdkResult as AsyncIterable<{
545
+ data?: unknown[];
546
+ nextCursor?: string;
547
+ }>) {
443
548
  const items = page.data || page;
444
549
  pageCount++;
445
550
 
@@ -502,7 +607,7 @@ async function handlePaginatedListWithAsyncIteration(
502
607
  console.log(chalk.gray(`\nšŸ“„ Finished browsing ${itemName}`));
503
608
  } catch (error) {
504
609
  // If the result is not async iterable, fall back to showing the first page
505
- const items = sdkResult?.data || sdkResult;
610
+ const items = (sdkResult as { data?: unknown[] })?.data || sdkResult;
506
611
  if (Array.isArray(items)) {
507
612
  if (items.length === 0) {
508
613
  console.log(chalk.yellow(`No ${itemName} found.`));
@@ -523,7 +628,7 @@ async function handlePaginatedListWithAsyncIteration(
523
628
  }
524
629
 
525
630
  function formatNonPaginatedResults(
526
- result: any[],
631
+ result: unknown[],
527
632
  requestedMaxItems?: number,
528
633
  userSpecifiedMaxItems?: boolean,
529
634
  useRawJson?: boolean,
@@ -573,13 +678,14 @@ function formatNonPaginatedResults(
573
678
  }
574
679
  }
575
680
 
576
- function formatItemsGeneric(items: any[]): void {
681
+ function formatItemsGeneric(items: unknown[]): void {
577
682
  // Fallback formatting for items without schema metadata
578
683
  items.forEach((item, index) => {
579
- const name = item.title || item.name || item.key || item.id || "Item";
580
- console.log(`${chalk.gray(`${index + 1}.`)} ${chalk.cyan(name)}`);
581
- if (item.description) {
582
- console.log(` ${chalk.dim(item.description)}`);
684
+ const itemObj = item as Record<string, unknown>;
685
+ const name = itemObj?.name || itemObj?.key || itemObj?.id || "Item";
686
+ console.log(`${chalk.gray(`${index + 1}.`)} ${chalk.cyan(String(name))}`);
687
+ if (itemObj?.description) {
688
+ console.log(` ${chalk.dim(String(itemObj.description))}`);
583
689
  }
584
690
  console.log();
585
691
  });