@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/src/utils/log.ts CHANGED
@@ -1,16 +1,16 @@
1
1
  import chalk from "chalk";
2
2
 
3
3
  const log = {
4
- info: (message: string, ...args: any[]) => {
4
+ info: (message: string, ...args: unknown[]) => {
5
5
  console.log(chalk.blue("ℹ"), message, ...args);
6
6
  },
7
- error: (message: string, ...args: any[]) => {
7
+ error: (message: string, ...args: unknown[]) => {
8
8
  console.error(chalk.red("✖"), message, ...args);
9
9
  },
10
- success: (message: string, ...args: any[]) => {
10
+ success: (message: string, ...args: unknown[]) => {
11
11
  console.log(chalk.green("✓"), message, ...args);
12
12
  },
13
- warn: (message: string, ...args: any[]) => {
13
+ warn: (message: string, ...args: unknown[]) => {
14
14
  console.log(chalk.yellow("⚠"), message, ...args);
15
15
  },
16
16
  };
@@ -22,8 +22,8 @@ interface ResolvableParameter {
22
22
 
23
23
  interface ResolverContext {
24
24
  sdk: ZapierSdk;
25
- currentParams: any;
26
- resolvedParams: any;
25
+ currentParams: Record<string, unknown>;
26
+ resolvedParams: Record<string, unknown>;
27
27
  }
28
28
 
29
29
  // ============================================================================
@@ -33,9 +33,9 @@ interface ResolverContext {
33
33
  export class SchemaParameterResolver {
34
34
  async resolveParameters(
35
35
  schema: z.ZodSchema,
36
- providedParams: any,
36
+ providedParams: unknown,
37
37
  sdk: ZapierSdk,
38
- ): Promise<any> {
38
+ ): Promise<unknown> {
39
39
  // 1. Try to parse with current parameters
40
40
  const parseResult = schema.safeParse(providedParams);
41
41
 
@@ -102,11 +102,11 @@ export class SchemaParameterResolver {
102
102
  return parseResult.data;
103
103
  }
104
104
 
105
- // 2. Resolve functionally required parameters and their dependencies first
106
- const resolvedParams = { ...providedParams };
105
+ // 2. Resolve functionally required parameters first
106
+ const resolvedParams = { ...(providedParams as Record<string, unknown>) };
107
107
  const context: ResolverContext = {
108
108
  sdk,
109
- currentParams: providedParams,
109
+ currentParams: providedParams as Record<string, unknown>,
110
110
  resolvedParams,
111
111
  };
112
112
 
@@ -306,7 +306,7 @@ export class SchemaParameterResolver {
306
306
  private async resolveParameter(
307
307
  param: ResolvableParameter,
308
308
  context: ResolverContext,
309
- ): Promise<any> {
309
+ ): Promise<unknown> {
310
310
  const resolver = getResolver(param.name);
311
311
  if (!resolver) {
312
312
  throw new Error(`No resolver found for parameter: ${param.name}`);
@@ -314,39 +314,55 @@ export class SchemaParameterResolver {
314
314
 
315
315
  console.log(chalk.blue(`\n🔍 Resolving ${param.name}...`));
316
316
 
317
- if (resolver.type === "static") {
317
+ const typedResolver = resolver as {
318
+ type: string;
319
+ inputType?: string;
320
+ placeholder?: string;
321
+ fetch?: Function;
322
+ prompt?: Function;
323
+ };
324
+
325
+ if (typedResolver.type === "static") {
318
326
  // Static resolver - just prompt for input
319
327
  const promptConfig = {
320
- type: resolver.inputType === "password" ? "password" : "input",
328
+ type: typedResolver.inputType === "password" ? "password" : "input",
321
329
  name: param.name,
322
330
  message: `Enter ${param.name}:`,
323
- ...(resolver.placeholder && { default: resolver.placeholder }),
331
+ ...(typedResolver.placeholder && {
332
+ default: typedResolver.placeholder,
333
+ }),
324
334
  };
325
335
 
326
336
  const answers = await inquirer.prompt([promptConfig as any]);
327
337
  return answers[param.name];
328
- } else if (resolver.type === "dynamic") {
338
+ } else if (typedResolver.type === "dynamic") {
329
339
  // Dynamic resolver - fetch options and prompt for selection
330
340
  try {
331
341
  // Only show "Fetching..." for required parameters that typically have many options
332
342
  if (param.isRequired && param.name !== "authenticationId") {
333
343
  console.log(chalk.gray(`Fetching options for ${param.name}...`));
334
344
  }
335
- const items = await resolver.fetch(context.sdk, context.resolvedParams);
345
+ const items = await typedResolver.fetch!(
346
+ context.sdk,
347
+ context.resolvedParams,
348
+ );
336
349
 
337
350
  // Let the resolver's prompt handle empty lists (e.g., authenticationId can show "skip authentication")
338
351
  const safeItems = items || [];
339
- const promptConfig = resolver.prompt(safeItems, context.resolvedParams);
352
+ const promptConfig = typedResolver.prompt!(
353
+ safeItems,
354
+ context.resolvedParams,
355
+ );
340
356
  const answers = await inquirer.prompt([promptConfig as any]);
341
357
  return answers[param.name];
342
358
  } catch (error) {
343
359
  // Let the main CLI error handler display user-friendly errors
344
360
  throw error;
345
361
  }
346
- } else if ((resolver as any).type === "fields") {
362
+ } else if (typedResolver.type === "fields") {
347
363
  // Fields resolver - fetch field definitions and prompt for each input with recursive field resolution
348
364
  return await this.resolveFieldsRecursively(
349
- resolver as any,
365
+ resolver as unknown,
350
366
  context,
351
367
  param,
352
368
  );
@@ -356,11 +372,12 @@ export class SchemaParameterResolver {
356
372
  }
357
373
 
358
374
  private async resolveFieldsRecursively(
359
- resolver: any,
375
+ resolver: unknown,
360
376
  context: ResolverContext,
361
377
  param: ResolvableParameter,
362
- ): Promise<Record<string, any>> {
363
- const inputs: Record<string, any> = {};
378
+ ): Promise<Record<string, unknown>> {
379
+ const typedResolver = resolver as { fetch: Function };
380
+ const inputs: Record<string, unknown> = {};
364
381
  let processedFieldKeys = new Set<string>();
365
382
  let iteration = 0;
366
383
  const maxIterations = 5; // Prevent infinite loops
@@ -383,7 +400,7 @@ export class SchemaParameterResolver {
383
400
  ),
384
401
  );
385
402
 
386
- const fields = await resolver.fetch(
403
+ const fields = await typedResolver.fetch(
387
404
  updatedContext.sdk,
388
405
  updatedContext.resolvedParams,
389
406
  );
@@ -399,7 +416,11 @@ export class SchemaParameterResolver {
399
416
 
400
417
  // Find new fields that we haven't processed yet
401
418
  const newFields = fields.filter(
402
- (field: any) => !processedFieldKeys.has(field.key),
419
+ (field: unknown) =>
420
+ !(
421
+ (field as { key: string }).key &&
422
+ processedFieldKeys.has((field as { key: string }).key)
423
+ ),
403
424
  );
404
425
 
405
426
  if (newFields.length === 0) {
@@ -409,10 +430,10 @@ export class SchemaParameterResolver {
409
430
 
410
431
  // Separate new required and optional fields
411
432
  const newRequiredFields = newFields.filter(
412
- (field: any) => field.required,
433
+ (field: unknown) => (field as { required: boolean }).required,
413
434
  );
414
435
  const newOptionalFields = newFields.filter(
415
- (field: any) => !field.required,
436
+ (field: unknown) => !(field as { required: boolean }).required,
416
437
  );
417
438
 
418
439
  // Prompt for new required fields
@@ -424,7 +445,7 @@ export class SchemaParameterResolver {
424
445
  );
425
446
  for (const field of newRequiredFields) {
426
447
  await this.promptForField(field, inputs);
427
- processedFieldKeys.add(field.key);
448
+ processedFieldKeys.add((field as { key: string }).key);
428
449
  }
429
450
  }
430
451
 
@@ -458,12 +479,12 @@ export class SchemaParameterResolver {
458
479
  console.log(chalk.cyan(`\nOptional fields:`));
459
480
  for (const field of newOptionalFields) {
460
481
  await this.promptForField(field, inputs);
461
- processedFieldKeys.add(field.key);
482
+ processedFieldKeys.add((field as { key: string }).key);
462
483
  }
463
484
  } else {
464
485
  // Mark these fields as processed even if skipped to avoid re-asking
465
- newOptionalFields.forEach((field: any) =>
466
- processedFieldKeys.add(field.key),
486
+ newOptionalFields.forEach((field: unknown) =>
487
+ processedFieldKeys.add((field as { key: string }).key),
467
488
  );
468
489
  }
469
490
  }
@@ -488,48 +509,73 @@ export class SchemaParameterResolver {
488
509
  return inputs;
489
510
  }
490
511
 
491
- private getNestedValue(obj: any, path: string[]): any {
492
- return path.reduce((current, key) => current?.[key], obj);
512
+ private getNestedValue(obj: unknown, path: string[]): unknown {
513
+ return path.reduce(
514
+ (current, key) => (current as Record<string, unknown>)?.[key],
515
+ obj,
516
+ );
493
517
  }
494
518
 
495
- private setNestedValue(obj: any, path: string[], value: any): void {
519
+ private setNestedValue(obj: unknown, path: string[], value: unknown): void {
496
520
  const lastKey = path[path.length - 1];
497
521
  const parent = path.slice(0, -1).reduce((current, key) => {
498
- if (!(key in current)) {
499
- current[key] = {};
522
+ const currentObj = current as Record<string, unknown>;
523
+ if (!(key in currentObj)) {
524
+ currentObj[key] = {};
500
525
  }
501
- return current[key];
502
- }, obj);
526
+ return currentObj[key];
527
+ }, obj) as Record<string, unknown>;
503
528
  parent[lastKey] = value;
504
529
  }
505
530
 
506
531
  private async promptForField(
507
- field: any,
508
- inputs: Record<string, any>,
532
+ field: unknown,
533
+ inputs: Record<string, unknown>,
509
534
  ): Promise<void> {
510
- const fieldPrompt = {
511
- type: field.type === "boolean" ? "confirm" : "input",
512
- name: field.key,
513
- message: `${field.label || field.key}${field.required ? " (required)" : " (optional)"}:`,
514
- ...(field.helpText && { prefix: chalk.gray(`ℹ ${field.helpText}\n`) }),
515
- ...(field.default && { default: field.default }),
535
+ const fieldObj = field as {
536
+ type?: string;
537
+ key: string;
538
+ label?: string;
539
+ required?: boolean;
540
+ helpText?: string;
541
+ default?: unknown;
542
+ choices?: Array<{ label?: string; value: unknown }>;
543
+ };
544
+
545
+ const fieldPrompt: Record<string, unknown> = {
546
+ type: fieldObj.type === "boolean" ? "confirm" : "input",
547
+ name: fieldObj.key,
548
+ message: `${fieldObj.label || fieldObj.key}${fieldObj.required ? " (required)" : " (optional)"}:`,
516
549
  };
517
550
 
518
- if (field.choices && field.choices.length > 0) {
551
+ if (fieldObj.helpText) {
552
+ fieldPrompt.prefix = chalk.gray(`ℹ ${fieldObj.helpText}\n`);
553
+ }
554
+
555
+ if (fieldObj.default !== undefined) {
556
+ fieldPrompt.default = fieldObj.default;
557
+ }
558
+
559
+ if (fieldObj.choices && fieldObj.choices.length > 0) {
519
560
  fieldPrompt.type = "list";
520
- (fieldPrompt as any).choices = field.choices.map((choice: any) => ({
521
- name: choice.label || choice.value,
522
- value: choice.value,
523
- }));
561
+ (fieldPrompt as { choices: unknown[] }).choices = fieldObj.choices.map(
562
+ (choice: unknown) => {
563
+ const choiceObj = choice as { label?: unknown; value: unknown };
564
+ return {
565
+ name: choiceObj.label || choiceObj.value,
566
+ value: choiceObj.value,
567
+ };
568
+ },
569
+ );
524
570
  }
525
571
 
526
572
  try {
527
573
  const answer = await inquirer.prompt([fieldPrompt as any]);
528
574
 
529
- if (answer[field.key] !== undefined && answer[field.key] !== "") {
530
- inputs[field.key] = answer[field.key];
531
- } else if (field.required) {
532
- throw new Error(`Required field ${field.key} cannot be empty`);
575
+ if (answer[fieldObj.key] !== undefined && answer[fieldObj.key] !== "") {
576
+ inputs[fieldObj.key] = answer[fieldObj.key];
577
+ } else if (fieldObj.required) {
578
+ throw new Error(`Required field ${fieldObj.key} cannot be empty`);
533
579
  }
534
580
  } catch (error) {
535
581
  if (this.isUserCancellation(error)) {
@@ -540,11 +586,16 @@ export class SchemaParameterResolver {
540
586
  }
541
587
  }
542
588
 
543
- private isUserCancellation(error: any): boolean {
589
+ private isUserCancellation(error: unknown): boolean {
590
+ const errorObj = error as {
591
+ name?: string;
592
+ message?: string;
593
+ isTTYError?: boolean;
594
+ };
544
595
  return (
545
- error?.name === "ExitPromptError" ||
546
- error?.message?.includes("User force closed") ||
547
- error?.isTTYError
596
+ errorObj?.name === "ExitPromptError" ||
597
+ errorObj?.message?.includes("User force closed") ||
598
+ errorObj?.isTTYError === true
548
599
  );
549
600
  }
550
601
  }
@@ -13,15 +13,16 @@ interface FormattedItem {
13
13
  }
14
14
 
15
15
  interface FormatMetadata {
16
- format: (item: any) => FormattedItem;
16
+ format: (item: unknown) => FormattedItem;
17
17
  }
18
18
 
19
- function getFormatMetadata(schema: any): FormatMetadata | undefined {
20
- return schema?._def?.formatMeta;
19
+ function getFormatMetadata(schema: unknown): FormatMetadata | undefined {
20
+ return (schema as { _def?: { formatMeta?: FormatMetadata } })?._def
21
+ ?.formatMeta;
21
22
  }
22
23
 
23
- function getOutputSchema(schema: any): any {
24
- return schema?._def?.outputSchema;
24
+ function getOutputSchema(schema: unknown): unknown {
25
+ return (schema as { _def?: { outputSchema?: unknown } })?._def?.outputSchema;
25
26
  }
26
27
 
27
28
  // ============================================================================
@@ -30,7 +31,7 @@ function getOutputSchema(schema: any): any {
30
31
 
31
32
  export function formatItemsFromSchema(
32
33
  inputSchema: z.ZodType,
33
- items: any[],
34
+ items: unknown[],
34
35
  ): void {
35
36
  // Get the output schema and its format metadata
36
37
  const outputSchema = getOutputSchema(inputSchema);
@@ -54,7 +55,7 @@ export function formatItemsFromSchema(
54
55
  }
55
56
 
56
57
  function formatSingleItem(
57
- item: any,
58
+ item: unknown,
58
59
  index: number,
59
60
  formatMeta: FormatMetadata,
60
61
  ): void {
@@ -93,13 +94,21 @@ function applyStyle(value: string, style: string): string {
93
94
  }
94
95
  }
95
96
 
96
- function formatItemsGeneric(items: any[]): void {
97
+ function formatItemsGeneric(items: unknown[]): void {
97
98
  // Fallback formatting for items without schema metadata
98
99
  items.forEach((item, index) => {
99
- const name = item.title || item.name || item.key || item.id || "Item";
100
+ const itemObj = item as {
101
+ title?: string;
102
+ name?: string;
103
+ key?: string;
104
+ id?: string;
105
+ description?: string;
106
+ };
107
+ const name =
108
+ itemObj.title || itemObj.name || itemObj.key || itemObj.id || "Item";
100
109
  console.log(`${chalk.gray(`${index + 1}.`)} ${chalk.cyan(name)}`);
101
- if (item.description) {
102
- console.log(` ${chalk.dim(item.description)}`);
110
+ if (itemObj.description) {
111
+ console.log(` ${chalk.dim(itemObj.description)}`);
103
112
  }
104
113
  console.log();
105
114
  });