@zapier/zapier-sdk-cli 0.34.12 → 0.35.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/dist/cli.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command, CommanderError } from 'commander';
3
3
  import { z } from 'zod';
4
- import { createFunction, OutputPropertySchema, DEFAULT_CONFIG_PATH, injectCliLogin, createZapierSdkWithoutRegistry, registryPlugin, ZapierError, ZapierValidationError, ZapierUnknownError, batch, toSnakeCase, buildApplicationLifecycleEvent, formatErrorMessage, isCredentialsObject, isPositional, runWithTelemetryContext, getOsInfo, getPlatformVersions, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId } from '@zapier/zapier-sdk';
4
+ import { createFunction, OutputPropertySchema, DEFAULT_CONFIG_PATH, injectCliLogin, createZapierSdkWithoutRegistry, registryPlugin, ZapierError, ZapierValidationError, ZapierUnknownError, batch, toSnakeCase, buildApplicationLifecycleEvent, isCredentialsObject, isPositional, runWithTelemetryContext, formatErrorMessage, getOsInfo, getPlatformVersions, getCiPlatform, isCi, getReleaseId, getCurrentTimestamp, generateEventId } from '@zapier/zapier-sdk';
5
5
  import inquirer from 'inquirer';
6
- import chalk3 from 'chalk';
6
+ import chalk7 from 'chalk';
7
7
  import util from 'util';
8
8
  import * as cliLogin from '@zapier/zapier-sdk-cli-login';
9
9
  import { logout, getConfigPath, getLoggedInUser, getPkceLoginConfig, AUTH_MODE_HEADER, getLoginStorageMode, updateLogin, getConfig } from '@zapier/zapier-sdk-cli-login';
@@ -45,8 +45,33 @@ var ZapierCliExitError = class extends ZapierCliError {
45
45
  this.exitCode = exitCode;
46
46
  }
47
47
  };
48
+ var ZapierCliValidationError = class extends ZapierCliError {
49
+ constructor(message) {
50
+ super(message);
51
+ this.name = "ZapierCliValidationError";
52
+ this.code = "ZAPIER_CLI_VALIDATION_ERROR";
53
+ this.exitCode = 1;
54
+ }
55
+ };
56
+ var ZapierCliMissingParametersError = class extends ZapierCliError {
57
+ constructor(params) {
58
+ super(
59
+ `Missing required parameters: ${params.map((p) => p.name).join(", ")}`
60
+ );
61
+ this.name = "ZapierCliMissingParametersError";
62
+ this.code = "ZAPIER_CLI_MISSING_PARAMETERS";
63
+ this.exitCode = 1;
64
+ this.params = params;
65
+ }
66
+ };
48
67
 
49
68
  // src/utils/parameter-resolver.ts
69
+ function formatZodError(error) {
70
+ return error.issues.map((issue) => {
71
+ const field = issue.path.length > 0 ? issue.path.join(".") : "input";
72
+ return `${field}: ${issue.message}`;
73
+ }).join(", ");
74
+ }
50
75
  function getLocalResolutionOrder(paramName, resolvers, resolved = /* @__PURE__ */ new Set()) {
51
76
  const resolver = resolvers[paramName];
52
77
  if (!resolver || resolver.type === "static") {
@@ -81,8 +106,9 @@ function getLocalResolutionOrderForParams(paramNames, resolvers) {
81
106
  return order;
82
107
  }
83
108
  var SchemaParameterResolver = class {
84
- async resolveParameters(schema, providedParams, sdk2, functionName) {
109
+ async resolveParameters(schema, providedParams, sdk2, functionName, options) {
85
110
  return runWithTelemetryContext(async () => {
111
+ const interactiveMode = options?.interactiveMode ?? true;
86
112
  const parseResult = schema.safeParse(providedParams);
87
113
  const allParams = this.extractParametersFromSchema(schema);
88
114
  const resolvableParams = allParams.filter(
@@ -95,7 +121,7 @@ var SchemaParameterResolver = class {
95
121
  const functionallyRequired = missingResolvable.filter((param) => {
96
122
  if (param.isRequired) return true;
97
123
  if (param.name === "inputs") {
98
- return true;
124
+ return interactiveMode;
99
125
  }
100
126
  return false;
101
127
  });
@@ -114,7 +140,7 @@ var SchemaParameterResolver = class {
114
140
  }
115
141
  if (functionallyRequired.length === 0 && alwaysPrompt.length === 0) {
116
142
  if (!parseResult.success) {
117
- throw parseResult.error;
143
+ throw new ZapierCliValidationError(formatZodError(parseResult.error));
118
144
  }
119
145
  return parseResult.data;
120
146
  }
@@ -142,21 +168,30 @@ var SchemaParameterResolver = class {
142
168
  }
143
169
  return param;
144
170
  }).filter((param) => param !== void 0);
145
- for (const param of orderedRequiredParams) {
146
- try {
147
- const value = await this.resolveParameter(
148
- param,
149
- context,
150
- functionName
151
- );
152
- this.setNestedValue(resolvedParams, param.path, value);
153
- context.resolvedParams = resolvedParams;
154
- } catch (error) {
155
- if (this.isUserCancellation(error)) {
156
- console.log(chalk3.yellow("\n\nOperation cancelled by user"));
157
- throw new ZapierCliUserCancellationError();
171
+ if (!interactiveMode) {
172
+ await this.resolveRequiredParamsNonInteractive(
173
+ orderedRequiredParams,
174
+ context,
175
+ resolvedParams,
176
+ functionName
177
+ );
178
+ } else {
179
+ for (const param of orderedRequiredParams) {
180
+ try {
181
+ const value = await this.resolveParameter(
182
+ param,
183
+ context,
184
+ functionName
185
+ );
186
+ this.setNestedValue(resolvedParams, param.path, value);
187
+ context.resolvedParams = resolvedParams;
188
+ } catch (error) {
189
+ if (this.isUserCancellation(error)) {
190
+ console.log(chalk7.yellow("\n\nOperation cancelled by user"));
191
+ throw new ZapierCliUserCancellationError();
192
+ }
193
+ throw error;
158
194
  }
159
- throw error;
160
195
  }
161
196
  }
162
197
  const resolvedParamNames = new Set(
@@ -173,7 +208,7 @@ var SchemaParameterResolver = class {
173
208
  ...trulyOptional.filter((p) => !resolvedParamNames.has(p.name))
174
209
  );
175
210
  }
176
- if (alwaysPrompt.length > 0) {
211
+ if (interactiveMode && alwaysPrompt.length > 0) {
177
212
  const alwaysPromptNames = alwaysPrompt.map((p) => p.name);
178
213
  const alwaysPromptResolutionOrder = getLocalResolutionOrderForParams(
179
214
  alwaysPromptNames,
@@ -191,14 +226,14 @@ var SchemaParameterResolver = class {
191
226
  context.resolvedParams = resolvedParams;
192
227
  } catch (error) {
193
228
  if (this.isUserCancellation(error)) {
194
- console.log(chalk3.yellow("\n\nOperation cancelled by user"));
229
+ console.log(chalk7.yellow("\n\nOperation cancelled by user"));
195
230
  throw new ZapierCliUserCancellationError();
196
231
  }
197
232
  throw error;
198
233
  }
199
234
  }
200
235
  }
201
- if (trulyOptional.length > 0) {
236
+ if (interactiveMode && trulyOptional.length > 0) {
202
237
  const optionalNames = trulyOptional.map((p) => p.name).join(", ");
203
238
  const shouldResolveOptional = await inquirer.prompt([
204
239
  {
@@ -228,7 +263,7 @@ var SchemaParameterResolver = class {
228
263
  context.resolvedParams = resolvedParams;
229
264
  } catch (error) {
230
265
  if (this.isUserCancellation(error)) {
231
- console.log(chalk3.yellow("\n\nOperation cancelled by user"));
266
+ console.log(chalk7.yellow("\n\nOperation cancelled by user"));
232
267
  throw new ZapierCliUserCancellationError();
233
268
  }
234
269
  throw error;
@@ -238,10 +273,9 @@ var SchemaParameterResolver = class {
238
273
  }
239
274
  const finalResult = schema.safeParse(resolvedParams);
240
275
  if (!finalResult.success) {
241
- console.error(
242
- chalk3.red("\u274C Parameter validation failed after resolution:")
276
+ throw new ZapierCliValidationError(
277
+ `Parameter validation failed: ${formatZodError(finalResult.error)}`
243
278
  );
244
- throw finalResult.error;
245
279
  }
246
280
  return finalResult.data;
247
281
  });
@@ -283,6 +317,54 @@ var SchemaParameterResolver = class {
283
317
  isRequired
284
318
  };
285
319
  }
320
+ /**
321
+ * Calls `tryResolveWithoutPrompt` on a dynamic resolver.
322
+ * Returns the resolution result object, or null if unresolvable / throws.
323
+ * Note: { resolvedValue: null } is a valid result (e.g. connectionId when app has no auth);
324
+ * only a null return from the resolver itself means "could not auto-resolve".
325
+ */
326
+ async tryAutoResolve(dynamicResolver, context) {
327
+ if (!dynamicResolver.tryResolveWithoutPrompt) return null;
328
+ try {
329
+ return await dynamicResolver.tryResolveWithoutPrompt(
330
+ context.sdk,
331
+ context.resolvedParams
332
+ );
333
+ } catch (err) {
334
+ console.warn(
335
+ `Auto-resolver threw unexpectedly; treating as unresolved. Error: ${err instanceof Error ? err.message : String(err)}`
336
+ );
337
+ return null;
338
+ }
339
+ }
340
+ /**
341
+ * Non-interactive resolution: auto-resolves what it can via tryAutoResolve,
342
+ * throws ZapierCliMissingParametersError for anything that requires user input.
343
+ */
344
+ async resolveRequiredParamsNonInteractive(params, context, resolvedParams, functionName) {
345
+ const missingParams = [];
346
+ for (const param of params) {
347
+ const resolver = this.getResolver(param.name, context.sdk, functionName);
348
+ const autoResolution = resolver?.type === "dynamic" ? await this.tryAutoResolve(resolver, context) : null;
349
+ if (autoResolution != null) {
350
+ this.setNestedValue(
351
+ resolvedParams,
352
+ param.path,
353
+ autoResolution.resolvedValue
354
+ );
355
+ context.resolvedParams = resolvedParams;
356
+ } else {
357
+ missingParams.push({
358
+ name: param.name,
359
+ // Required params render as positional CLI args (<name>); so do explicitly positional optional params.
360
+ isPositional: param.isRequired || isPositional(param.schema)
361
+ });
362
+ }
363
+ }
364
+ if (missingParams.length > 0) {
365
+ throw new ZapierCliMissingParametersError(missingParams);
366
+ }
367
+ }
286
368
  async resolveParameter(param, context, functionName) {
287
369
  const resolver = this.getResolver(
288
370
  param.name,
@@ -292,7 +374,7 @@ var SchemaParameterResolver = class {
292
374
  if (!resolver) {
293
375
  throw new Error(`No resolver found for parameter: ${param.name}`);
294
376
  }
295
- console.log(chalk3.blue(`
377
+ console.log(chalk7.blue(`
296
378
  \u{1F50D} Resolving ${param.name}...`));
297
379
  if (resolver.type === "static") {
298
380
  const staticResolver = resolver;
@@ -308,20 +390,15 @@ var SchemaParameterResolver = class {
308
390
  return answers[param.name];
309
391
  } else if (resolver.type === "dynamic") {
310
392
  const dynamicResolver = resolver;
311
- if (dynamicResolver.tryResolveWithoutPrompt) {
312
- try {
313
- const preResolvedValue = await dynamicResolver.tryResolveWithoutPrompt(
314
- context.sdk,
315
- context.resolvedParams
316
- );
317
- if (preResolvedValue != null) {
318
- return preResolvedValue.resolvedValue;
319
- }
320
- } catch {
321
- }
393
+ const autoResolution = await this.tryAutoResolve(
394
+ dynamicResolver,
395
+ context
396
+ );
397
+ if (autoResolution != null) {
398
+ return autoResolution.resolvedValue;
322
399
  }
323
400
  if (param.isRequired && param.name !== "connectionId") {
324
- console.log(chalk3.gray(`Fetching options for ${param.name}...`));
401
+ console.log(chalk7.gray(`Fetching options for ${param.name}...`));
325
402
  }
326
403
  const items = await dynamicResolver.fetch(
327
404
  context.sdk,
@@ -358,7 +435,7 @@ var SchemaParameterResolver = class {
358
435
  }
359
436
  };
360
437
  console.log(
361
- chalk3.gray(
438
+ chalk7.gray(
362
439
  `Fetching input fields for ${param.name}${iteration > 1 ? ` (iteration ${iteration})` : ""}...`
363
440
  )
364
441
  );
@@ -369,7 +446,7 @@ var SchemaParameterResolver = class {
369
446
  if (!rootFieldItems || rootFieldItems.length === 0) {
370
447
  if (iteration === 1) {
371
448
  console.log(
372
- chalk3.yellow(`No input fields required for this action.`)
449
+ chalk7.yellow(`No input fields required for this action.`)
373
450
  );
374
451
  }
375
452
  break;
@@ -391,7 +468,7 @@ var SchemaParameterResolver = class {
391
468
  }
392
469
  if (iteration >= maxIterations) {
393
470
  console.log(
394
- chalk3.yellow(
471
+ chalk7.yellow(
395
472
  `
396
473
  \u26A0\uFE0F Maximum field resolution iterations reached. Some dynamic fields may not have been discovered.`
397
474
  )
@@ -413,7 +490,7 @@ var SchemaParameterResolver = class {
413
490
  const fieldsetTitle = typedItem.title || typedItem.key;
414
491
  const pathDisplay = fieldsetPath.length > 0 ? ` (in ${fieldsetPath.join(" > ")})` : "";
415
492
  console.log(
416
- chalk3.cyan(
493
+ chalk7.cyan(
417
494
  `
418
495
  \u{1F4C1} Processing fieldset: ${fieldsetTitle}${pathDisplay}`
419
496
  )
@@ -445,7 +522,7 @@ var SchemaParameterResolver = class {
445
522
  newRequiredCount++;
446
523
  if (newRequiredCount === 1 && fieldsetPath.length === 0) {
447
524
  console.log(
448
- chalk3.blue(
525
+ chalk7.blue(
449
526
  `
450
527
  \u{1F4DD} Please provide values for the following ${iteration === 1 ? "" : "additional "}input fields:`
451
528
  )
@@ -466,7 +543,7 @@ var SchemaParameterResolver = class {
466
543
  if (optionalFields.length > 0) {
467
544
  const pathContext = fieldsetPath.length > 0 ? ` in ${fieldsetPath.join(" > ")}` : "";
468
545
  console.log(
469
- chalk3.gray(
546
+ chalk7.gray(
470
547
  `
471
548
  There are ${optionalFields.length} ${iteration === 1 ? "" : "additional "}optional field(s) available${pathContext}.`
472
549
  )
@@ -481,7 +558,7 @@ There are ${optionalFields.length} ${iteration === 1 ? "" : "additional "}option
481
558
  }
482
559
  ]);
483
560
  if (shouldConfigureOptional.configure) {
484
- console.log(chalk3.cyan(`
561
+ console.log(chalk7.cyan(`
485
562
  Optional fields${pathContext}:`));
486
563
  for (const field of optionalFields) {
487
564
  await this.promptForField(field, targetInputs, context);
@@ -497,7 +574,7 @@ Optional fields${pathContext}:`));
497
574
  }
498
575
  } catch (error) {
499
576
  if (this.isUserCancellation(error)) {
500
- console.log(chalk3.yellow("\n\nOperation cancelled by user"));
577
+ console.log(chalk7.yellow("\n\nOperation cancelled by user"));
501
578
  throw new ZapierCliUserCancellationError();
502
579
  }
503
580
  throw error;
@@ -552,7 +629,7 @@ Optional fields${pathContext}:`));
552
629
  async fetchChoices(fieldMeta, inputs, context, cursor) {
553
630
  try {
554
631
  console.log(
555
- chalk3.gray(
632
+ chalk7.gray(
556
633
  cursor ? ` Fetching more choices...` : ` Fetching choices for ${fieldMeta.title}...`
557
634
  )
558
635
  );
@@ -571,7 +648,7 @@ Optional fields${pathContext}:`));
571
648
  }));
572
649
  if (choices.length === 0 && !cursor) {
573
650
  console.log(
574
- chalk3.yellow(` No choices available for ${fieldMeta.title}`)
651
+ chalk7.yellow(` No choices available for ${fieldMeta.title}`)
575
652
  );
576
653
  }
577
654
  return {
@@ -580,7 +657,7 @@ Optional fields${pathContext}:`));
580
657
  };
581
658
  } catch (error) {
582
659
  console.warn(
583
- chalk3.yellow(` \u26A0\uFE0F Failed to fetch choices for ${fieldMeta.title}:`),
660
+ chalk7.yellow(` \u26A0\uFE0F Failed to fetch choices for ${fieldMeta.title}:`),
584
661
  error
585
662
  );
586
663
  return { choices: [] };
@@ -606,7 +683,7 @@ Optional fields${pathContext}:`));
606
683
  }));
607
684
  if (nextCursor) {
608
685
  promptChoices.push({
609
- name: chalk3.dim("(Load more...)"),
686
+ name: chalk7.dim("(Load more...)"),
610
687
  value: LOAD_MORE_SENTINEL
611
688
  });
612
689
  }
@@ -669,7 +746,7 @@ Optional fields${pathContext}:`));
669
746
  };
670
747
  }
671
748
  if (fieldMeta.description) {
672
- promptConfig.prefix = chalk3.gray(`\u2139 ${fieldMeta.description}
749
+ promptConfig.prefix = chalk7.gray(`\u2139 ${fieldMeta.description}
673
750
  `);
674
751
  }
675
752
  try {
@@ -677,7 +754,7 @@ Optional fields${pathContext}:`));
677
754
  return answer[fieldMeta.key];
678
755
  } catch (error) {
679
756
  if (this.isUserCancellation(error)) {
680
- console.log(chalk3.yellow("\n\nOperation cancelled by user"));
757
+ console.log(chalk7.yellow("\n\nOperation cancelled by user"));
681
758
  throw new ZapierCliUserCancellationError();
682
759
  }
683
760
  throw error;
@@ -695,7 +772,7 @@ Optional fields${pathContext}:`));
695
772
  }
696
773
  } catch (error) {
697
774
  if (this.isUserCancellation(error)) {
698
- console.log(chalk3.yellow("\n\nOperation cancelled by user"));
775
+ console.log(chalk7.yellow("\n\nOperation cancelled by user"));
699
776
  throw new ZapierCliUserCancellationError();
700
777
  }
701
778
  throw error;
@@ -768,6 +845,91 @@ Optional fields${pathContext}:`));
768
845
  return functionInfo?.resolvers || {};
769
846
  }
770
847
  };
848
+
849
+ // src/utils/cli-options.ts
850
+ var RESERVED_CLI_OPTIONS = [
851
+ {
852
+ name: "version" /* Version */,
853
+ flag: "--version",
854
+ short: "-V",
855
+ description: "Display version number"
856
+ },
857
+ {
858
+ name: "help" /* Help */,
859
+ flag: "--help",
860
+ short: "-h",
861
+ description: "Display help for command"
862
+ }
863
+ ];
864
+ function getReservedCliOption(name) {
865
+ const option = RESERVED_CLI_OPTIONS.find((opt) => opt.name === name);
866
+ if (!option) throw new Error(`Reserved CLI option not found: ${name}`);
867
+ return option;
868
+ }
869
+ var SHARED_COMMAND_CLI_OPTIONS = [
870
+ {
871
+ name: "json",
872
+ flag: "--json",
873
+ description: "Output raw JSON instead of formatted results"
874
+ }
875
+ ];
876
+
877
+ // package.json
878
+ var package_default = {
879
+ version: "0.35.0"};
880
+
881
+ // src/telemetry/builders.ts
882
+ function createCliBaseEvent(context = {}) {
883
+ return {
884
+ event_id: generateEventId(),
885
+ timestamp_ms: getCurrentTimestamp(),
886
+ release_id: getReleaseId(),
887
+ customuser_id: context.customuser_id ?? null,
888
+ account_id: context.account_id ?? null,
889
+ identity_id: context.identity_id ?? null,
890
+ visitor_id: context.visitor_id ?? null,
891
+ correlation_id: context.correlation_id ?? null
892
+ };
893
+ }
894
+ function buildCliCommandExecutedEvent({
895
+ data,
896
+ context = {},
897
+ cliVersion = package_default.version
898
+ }) {
899
+ const osInfo = getOsInfo();
900
+ const platformVersions = getPlatformVersions();
901
+ return {
902
+ ...createCliBaseEvent(context),
903
+ system_name: "zapier-sdk-cli",
904
+ session_id: context.session_id ?? null,
905
+ cli_version: data.cli_version ?? cliVersion,
906
+ cli_arguments: data.cli_arguments ?? null,
907
+ cli_primary_command: data.cli_primary_command,
908
+ os_platform: osInfo.platform,
909
+ os_release: osInfo.release,
910
+ os_architecture: osInfo.architecture,
911
+ platform_versions: platformVersions,
912
+ selected_api: context.selected_api ?? null,
913
+ app_id: context.app_id ?? null,
914
+ app_version_id: context.app_version_id ?? null,
915
+ execution_duration_ms: data.execution_duration_ms ?? null,
916
+ success_flag: data.success_flag,
917
+ exit_code: data.exit_code ?? (data.success_flag ? 0 : 1),
918
+ error_message: data.error_message ?? null,
919
+ command_category: data.command_category ?? null,
920
+ requires_auth: null,
921
+ is_ci_environment: isCi(),
922
+ ci_platform: getCiPlatform(),
923
+ package_manager: data.package_manager ?? "pnpm",
924
+ // Default based on project setup
925
+ made_network_requests: data.made_network_requests ?? null,
926
+ files_modified_count: data.files_modified_count ?? null,
927
+ files_created_count: data.files_created_count ?? null,
928
+ files_processed_size_bytes: data.files_processed_size_bytes ?? null,
929
+ cpu_time_ms: data.cpu_time_ms ?? null,
930
+ subprocess_count: data.subprocess_count ?? null
931
+ };
932
+ }
771
933
  function getFormatMetadata(schema) {
772
934
  return schema?._zod?.def?.formatMeta;
773
935
  }
@@ -799,7 +961,7 @@ function formatItemsFromSchema(functionInfo, items, startingNumber = 0) {
799
961
  });
800
962
  }
801
963
  function formatSingleItem(formatted, itemNumber) {
802
- let titleLine = `${chalk3.gray(`${itemNumber + 1}.`)} ${chalk3.cyan(formatted.title)}`;
964
+ let titleLine = `${chalk7.gray(`${itemNumber + 1}.`)} ${chalk7.cyan(formatted.title)}`;
803
965
  const subtitleParts = [];
804
966
  if (formatted.keys) {
805
967
  subtitleParts.push(...formatted.keys);
@@ -811,11 +973,11 @@ function formatSingleItem(formatted, itemNumber) {
811
973
  }
812
974
  const uniqueParts = [...new Set(subtitleParts)];
813
975
  if (uniqueParts.length > 0) {
814
- titleLine += ` ${chalk3.gray(`(${uniqueParts.join(", ")})`)}`;
976
+ titleLine += ` ${chalk7.gray(`(${uniqueParts.join(", ")})`)}`;
815
977
  }
816
978
  console.log(titleLine);
817
979
  if (formatted.description) {
818
- console.log(` ${chalk3.dim(formatted.description)}`);
980
+ console.log(` ${chalk7.dim(formatted.description)}`);
819
981
  }
820
982
  if (formatted.data !== void 0) {
821
983
  formatJsonOutput(formatted.data);
@@ -831,16 +993,16 @@ function formatSingleItem(formatted, itemNumber) {
831
993
  function applyStyle(value, style) {
832
994
  switch (style) {
833
995
  case "dim":
834
- return chalk3.dim(value);
996
+ return chalk7.dim(value);
835
997
  case "accent":
836
- return chalk3.magenta(value);
998
+ return chalk7.magenta(value);
837
999
  case "warning":
838
- return chalk3.red(value);
1000
+ return chalk7.red(value);
839
1001
  case "success":
840
- return chalk3.green(value);
1002
+ return chalk7.green(value);
841
1003
  case "normal":
842
1004
  default:
843
- return chalk3.blue(value);
1005
+ return chalk7.blue(value);
844
1006
  }
845
1007
  }
846
1008
  function convertGenericItemToFormattedItem(item) {
@@ -860,93 +1022,229 @@ function formatItemsGeneric(items, startingNumber = 0) {
860
1022
  });
861
1023
  }
862
1024
 
863
- // src/utils/cli-options.ts
864
- var RESERVED_CLI_OPTIONS = [
865
- {
866
- name: "version" /* Version */,
867
- flag: "--version",
868
- short: "-V",
869
- description: "Display version number"
870
- },
871
- {
872
- name: "help" /* Help */,
873
- flag: "--help",
874
- short: "-h",
875
- description: "Display help for command"
876
- }
877
- ];
878
- function getReservedCliOption(name) {
879
- const option = RESERVED_CLI_OPTIONS.find((opt) => opt.name === name);
880
- if (!option) throw new Error(`Reserved CLI option not found: ${name}`);
881
- return option;
1025
+ // src/utils/string-utils.ts
1026
+ function toKebabCase(str) {
1027
+ return str.replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").replace(/([a-z\d])([A-Z])/g, "$1-$2").toLowerCase();
882
1028
  }
883
- var SHARED_COMMAND_CLI_OPTIONS = [
884
- {
885
- name: "json",
886
- flag: "--json",
887
- description: "Output raw JSON instead of formatted results"
1029
+ function formatMissingParamsError(error) {
1030
+ return [
1031
+ "Missing required parameters:",
1032
+ ...error.params.map(
1033
+ ({ name, isPositional: isPositional3 }) => isPositional3 ? ` \u2022 <${toKebabCase(name)}>` : ` \u2022 --${toKebabCase(name)}`
1034
+ )
1035
+ ].join("\n");
1036
+ }
1037
+ function buildJsonErrors(error) {
1038
+ if (error instanceof ZapierCliMissingParametersError) {
1039
+ return error.params.map(({ name, isPositional: isPositional3 }) => ({
1040
+ code: error.code,
1041
+ message: isPositional3 ? `<${toKebabCase(name)}> is required in non-interactive mode` : `--${toKebabCase(name)} is required in non-interactive mode`
1042
+ }));
1043
+ }
1044
+ const code = error instanceof ZapierError ? error.code : "UNKNOWN_ERROR";
1045
+ const message = error instanceof Error ? error.message : String(error);
1046
+ return [{ code, message }];
1047
+ }
1048
+ async function unwrapHttpResponse(response) {
1049
+ const text = await response.text().catch(() => "[unable to read body]");
1050
+ try {
1051
+ return {
1052
+ statusCode: response.status,
1053
+ headers: Object.fromEntries(response.headers.entries()),
1054
+ body: JSON.parse(text)
1055
+ };
1056
+ } catch {
1057
+ throw new Error(
1058
+ `Failed to parse response as JSON (status: ${response.status}). Body: ${text.slice(0, 500)}`
1059
+ );
888
1060
  }
889
- ];
890
-
891
- // package.json
892
- var package_default = {
893
- version: "0.34.12"};
894
-
895
- // src/telemetry/builders.ts
896
- function createCliBaseEvent(context = {}) {
1061
+ }
1062
+ function outputJson(envelope) {
1063
+ console.log(JSON.stringify(envelope, null, 2));
1064
+ }
1065
+ function createJsonRenderer() {
897
1066
  return {
898
- event_id: generateEventId(),
899
- timestamp_ms: getCurrentTimestamp(),
900
- release_id: getReleaseId(),
901
- customuser_id: context.customuser_id ?? null,
902
- account_id: context.account_id ?? null,
903
- identity_id: context.identity_id ?? null,
904
- visitor_id: context.visitor_id ?? null,
905
- correlation_id: context.correlation_id ?? null
1067
+ async renderPaginatedList(source, _functionInfo) {
1068
+ let page;
1069
+ if (Symbol.asyncIterator in Object(source)) {
1070
+ const iter = source[Symbol.asyncIterator]();
1071
+ const result = await iter.next();
1072
+ page = result.done ? void 0 : result.value;
1073
+ } else {
1074
+ page = await source;
1075
+ }
1076
+ const data = Array.isArray(page?.data) ? page.data : [];
1077
+ outputJson({
1078
+ data,
1079
+ ...page?.nextCursor && { nextCursor: page.nextCursor },
1080
+ errors: []
1081
+ });
1082
+ },
1083
+ renderCollectedList(items, _options) {
1084
+ outputJson({ data: items, errors: [] });
1085
+ },
1086
+ renderItem(value, options) {
1087
+ outputJson({
1088
+ data: options?.outputFile ? { outputFile: options.outputFile } : value ?? null,
1089
+ errors: []
1090
+ });
1091
+ },
1092
+ async renderResponse(response) {
1093
+ console.log(JSON.stringify(await unwrapHttpResponse(response), null, 2));
1094
+ },
1095
+ renderError(error) {
1096
+ outputJson({ data: null, errors: buildJsonErrors(error) });
1097
+ throw new ZapierCliExitError(
1098
+ error instanceof Error ? error.message : String(error),
1099
+ 1
1100
+ );
1101
+ }
906
1102
  };
907
1103
  }
908
- function buildCliCommandExecutedEvent({
909
- data,
910
- context = {},
911
- cliVersion = package_default.version
912
- }) {
913
- const osInfo = getOsInfo();
914
- const platformVersions = getPlatformVersions();
1104
+ function getItemName(functionInfo) {
1105
+ if (functionInfo?.itemType) return `${functionInfo.itemType} items`;
1106
+ return "items";
1107
+ }
1108
+ function getListTitle(functionInfo) {
1109
+ if (functionInfo.itemType) return `Available ${functionInfo.itemType} items`;
1110
+ return "items";
1111
+ }
1112
+ function renderItemsForDisplay(items, functionInfo, startingNumber = 0) {
1113
+ if (functionInfo?.inputSchema) {
1114
+ formatItemsFromSchema(
1115
+ functionInfo,
1116
+ items,
1117
+ startingNumber
1118
+ );
1119
+ } else {
1120
+ items.forEach((item, index) => {
1121
+ const obj = item;
1122
+ const name = obj?.name || obj?.key || obj?.id || "Item";
1123
+ console.log(
1124
+ `${chalk7.gray(`${startingNumber + index + 1}.`)} ${chalk7.cyan(String(name))}`
1125
+ );
1126
+ if (obj?.description)
1127
+ console.log(` ${chalk7.dim(String(obj.description))}`);
1128
+ console.log();
1129
+ });
1130
+ }
1131
+ }
1132
+ function createInteractiveRenderer() {
915
1133
  return {
916
- ...createCliBaseEvent(context),
917
- system_name: "zapier-sdk-cli",
918
- session_id: context.session_id ?? null,
919
- cli_version: data.cli_version ?? cliVersion,
920
- cli_arguments: data.cli_arguments ?? null,
921
- cli_primary_command: data.cli_primary_command,
922
- os_platform: osInfo.platform,
923
- os_release: osInfo.release,
924
- os_architecture: osInfo.architecture,
925
- platform_versions: platformVersions,
926
- selected_api: context.selected_api ?? null,
927
- app_id: context.app_id ?? null,
928
- app_version_id: context.app_version_id ?? null,
929
- execution_duration_ms: data.execution_duration_ms ?? null,
930
- success_flag: data.success_flag,
931
- exit_code: data.exit_code ?? (data.success_flag ? 0 : 1),
932
- error_message: data.error_message ?? null,
933
- command_category: data.command_category ?? null,
934
- requires_auth: null,
935
- is_ci_environment: isCi(),
936
- ci_platform: getCiPlatform(),
937
- package_manager: data.package_manager ?? "pnpm",
938
- // Default based on project setup
939
- made_network_requests: data.made_network_requests ?? null,
940
- files_modified_count: data.files_modified_count ?? null,
941
- files_created_count: data.files_created_count ?? null,
942
- files_processed_size_bytes: data.files_processed_size_bytes ?? null,
943
- cpu_time_ms: data.cpu_time_ms ?? null,
944
- subprocess_count: data.subprocess_count ?? null
1134
+ async renderPaginatedList(source, functionInfo) {
1135
+ const itemName = getItemName(functionInfo);
1136
+ if (!(Symbol.asyncIterator in Object(source))) {
1137
+ const items = source?.data;
1138
+ if (!Array.isArray(items) || items.length === 0) {
1139
+ console.log(chalk7.yellow(`No ${itemName} found.`));
1140
+ return;
1141
+ }
1142
+ renderItemsForDisplay(items, functionInfo, 0);
1143
+ console.log(chalk7.green(`
1144
+ \u2705 Showing ${items.length} ${itemName}`));
1145
+ return;
1146
+ }
1147
+ let totalShown = 0;
1148
+ let pageCount = 0;
1149
+ console.log(chalk7.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
1150
+ `));
1151
+ for await (const page of source) {
1152
+ const items = page.data ?? [];
1153
+ pageCount++;
1154
+ if (items.length === 0 && pageCount === 1) {
1155
+ console.log(chalk7.yellow(`No ${itemName} found.`));
1156
+ return;
1157
+ }
1158
+ if (items.length === 0) break;
1159
+ if (pageCount > 1) {
1160
+ console.clear();
1161
+ console.log(chalk7.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
1162
+ `));
1163
+ }
1164
+ renderItemsForDisplay(items, functionInfo, totalShown);
1165
+ totalShown += items.length;
1166
+ console.log(
1167
+ chalk7.green(
1168
+ `
1169
+ \u2705 Showing ${totalShown} ${itemName} (page ${pageCount})`
1170
+ )
1171
+ );
1172
+ if (page.nextCursor) {
1173
+ const { continueReading } = await inquirer.prompt([
1174
+ {
1175
+ type: "confirm",
1176
+ name: "continueReading",
1177
+ message: "Load next page?",
1178
+ default: true
1179
+ }
1180
+ ]);
1181
+ if (!continueReading) break;
1182
+ } else {
1183
+ break;
1184
+ }
1185
+ }
1186
+ console.log(chalk7.gray(`
1187
+ \u{1F4C4} Finished browsing ${itemName}`));
1188
+ },
1189
+ renderCollectedList(items, { maxItems, userSpecifiedMaxItems, functionInfo } = {}) {
1190
+ if (!Array.isArray(items)) {
1191
+ formatJsonOutput(items);
1192
+ return;
1193
+ }
1194
+ const itemName = getItemName(functionInfo);
1195
+ if (items.length === 0) {
1196
+ console.log(chalk7.yellow(`No ${itemName} found.`));
1197
+ return;
1198
+ }
1199
+ console.log(chalk7.green(`
1200
+ \u2705 Found ${items.length} ${itemName}:
1201
+ `));
1202
+ renderItemsForDisplay(items, functionInfo);
1203
+ if (userSpecifiedMaxItems && maxItems) {
1204
+ console.log(
1205
+ chalk7.gray(
1206
+ `
1207
+ \u{1F4C4} Showing up to ${maxItems} ${itemName} (--max-items ${maxItems})`
1208
+ )
1209
+ );
1210
+ } else {
1211
+ console.log(chalk7.gray(`
1212
+ \u{1F4C4} All available ${itemName} shown`));
1213
+ }
1214
+ },
1215
+ renderItem(value, options) {
1216
+ if (options?.outputFile) {
1217
+ const label = options.commandName ? `\u2705 ${options.commandName} completed successfully!` : "\u2705 Done!";
1218
+ console.log(chalk7.green(label));
1219
+ console.log(chalk7.gray(`Output written to: ${options.outputFile}`));
1220
+ } else {
1221
+ formatJsonOutput(value);
1222
+ }
1223
+ },
1224
+ async renderResponse(response) {
1225
+ formatJsonOutput(await unwrapHttpResponse(response));
1226
+ },
1227
+ renderError(error) {
1228
+ if (error instanceof ZapierCliMissingParametersError) {
1229
+ console.error(chalk7.red("\u274C " + formatMissingParamsError(error)));
1230
+ console.error("\n" + chalk7.dim("Use --help to see available options"));
1231
+ throw new ZapierCliExitError(error.message, 1);
1232
+ }
1233
+ if (error instanceof ZapierError) {
1234
+ const formattedMessage = formatErrorMessage(error);
1235
+ console.error(chalk7.red("\u274C Error:"), formattedMessage);
1236
+ throw new ZapierCliExitError(formattedMessage, 1);
1237
+ }
1238
+ const msg = error instanceof Error ? error.message : "Unknown error";
1239
+ console.error(chalk7.red("\u274C Error:"), msg);
1240
+ throw new ZapierCliExitError(msg, 1);
1241
+ }
945
1242
  };
946
1243
  }
947
1244
 
948
1245
  // src/utils/cli-generator.ts
949
1246
  var CLI_COMMAND_EXECUTED_EVENT_SUBJECT = "platform.sdk.CliCommandExecutedEvent";
1247
+ var PAGINATION_PARAM_NAMES = /* @__PURE__ */ new Set(["maxItems", "pageSize", "cursor"]);
950
1248
  var SENSITIVE_FLAGS = [
951
1249
  "--credentials",
952
1250
  "--credentials-client-secret",
@@ -977,6 +1275,62 @@ function sanitizeCliArguments(args) {
977
1275
  }
978
1276
  return sanitized;
979
1277
  }
1278
+ function getNormalizedResult(result, { isListCommand }) {
1279
+ if (result instanceof Response) {
1280
+ return { kind: "response", value: result };
1281
+ }
1282
+ if (isListCommand) {
1283
+ const sdkResult2 = result;
1284
+ if (!Array.isArray(sdkResult2?.data)) {
1285
+ throw new Error(
1286
+ `List command returned unexpected shape (expected { data: [] }): ${JSON.stringify(result).slice(0, 200)}`
1287
+ );
1288
+ }
1289
+ return {
1290
+ kind: "list",
1291
+ data: sdkResult2.data,
1292
+ nextCursor: sdkResult2.nextCursor
1293
+ };
1294
+ }
1295
+ const sdkResult = result;
1296
+ return {
1297
+ kind: "item",
1298
+ value: result !== null && typeof result === "object" && "data" in result ? sdkResult.data : result
1299
+ };
1300
+ }
1301
+ function hasItems(sdkResult) {
1302
+ return sdkResult != null && typeof sdkResult.items === "function";
1303
+ }
1304
+ function hasPages(sdkResult) {
1305
+ return sdkResult != null && typeof sdkResult[Symbol.asyncIterator] === "function";
1306
+ }
1307
+ async function* toItemsStream(sdkResult) {
1308
+ if (hasItems(sdkResult)) {
1309
+ yield* sdkResult.items();
1310
+ return;
1311
+ }
1312
+ if (hasPages(sdkResult)) {
1313
+ for await (const page of sdkResult) {
1314
+ yield* page.data ?? [];
1315
+ }
1316
+ return;
1317
+ }
1318
+ throw new ZapierCliExitError(
1319
+ `SDK method returned a value that is not async-iterable. Got: ${typeof sdkResult}. List methods must return an AsyncIterable or an object with an items() method.`,
1320
+ 1
1321
+ );
1322
+ }
1323
+ async function collectItemsFromResult({
1324
+ sdkResult,
1325
+ maxItems
1326
+ }) {
1327
+ const items = [];
1328
+ for await (const item of toItemsStream(sdkResult)) {
1329
+ items.push(item);
1330
+ if (maxItems !== void 0 && items.length >= maxItems) break;
1331
+ }
1332
+ return maxItems !== void 0 ? items.slice(0, maxItems) : items;
1333
+ }
980
1334
  var CONFIRM_MESSAGES = {
981
1335
  "create-secret": {
982
1336
  messageBefore: "You are about to create a sensitive secret that will be displayed as plain text.\nOnce created, you cannot retrieve it again.",
@@ -991,7 +1345,7 @@ async function promptConfirm(confirmType) {
991
1345
  return { confirmed: true };
992
1346
  }
993
1347
  const { messageBefore, messageAfter } = CONFIRM_MESSAGES[confirmType];
994
- console.log(chalk3.yellow(`
1348
+ console.log(chalk7.yellow(`
995
1349
  ${messageBefore}
996
1350
  `));
997
1351
  const { confirmed } = await inquirer.prompt([
@@ -1013,11 +1367,20 @@ function emitDeprecationWarning({
1013
1367
  }
1014
1368
  console.warn();
1015
1369
  console.warn(
1016
- chalk3.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk3.yellow(` - \`${cliCommandName}\` is deprecated.`)
1370
+ chalk7.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk7.yellow(` - \`${cliCommandName}\` is deprecated.`)
1017
1371
  );
1018
- console.warn(chalk3.yellow(` ${deprecation.message}`));
1372
+ console.warn(chalk7.yellow(` ${deprecation.message}`));
1019
1373
  console.warn();
1020
1374
  }
1375
+ function resolveOutputMode({
1376
+ isListCommand,
1377
+ hasPaginationParams,
1378
+ hasUserSpecifiedMaxItems
1379
+ }) {
1380
+ if (!isListCommand || !hasPaginationParams) return "single";
1381
+ if (hasUserSpecifiedMaxItems) return "collect";
1382
+ return "paginate";
1383
+ }
1021
1384
  function analyzeZodSchema(schema, functionInfo) {
1022
1385
  const parameters = [];
1023
1386
  const schemaDef = schema._zod?.def;
@@ -1157,9 +1520,6 @@ function reconstructPositionalArgs(inputParameters, flatParams) {
1157
1520
  }
1158
1521
  return args;
1159
1522
  }
1160
- function toKebabCase(str) {
1161
- return str.replace(/([A-Z])/g, "-$1").toLowerCase();
1162
- }
1163
1523
  function methodNameToCliCommand(methodName) {
1164
1524
  return toKebabCase(methodName);
1165
1525
  }
@@ -1249,23 +1609,31 @@ function createCommandConfig(cliCommandName, functionInfo, sdk2) {
1249
1609
  let success = true;
1250
1610
  let errorMessage = null;
1251
1611
  let resolvedParams = {};
1612
+ const commandObj = args[args.length - 1];
1613
+ const options = commandObj.opts();
1614
+ const interactiveMode = !options.json;
1615
+ const renderer = interactiveMode ? createInteractiveRenderer() : createJsonRenderer();
1252
1616
  try {
1253
- const commandObj = args[args.length - 1];
1254
- const options = commandObj.opts();
1617
+ const commandObj2 = args[args.length - 1];
1618
+ const options2 = commandObj2.opts();
1255
1619
  emitDeprecationWarning({
1256
1620
  cliCommandName,
1257
1621
  deprecation: functionInfo.deprecation
1258
1622
  });
1259
1623
  const isListCommand = functionInfo.type === "list";
1260
1624
  const hasPaginationParams = parameters.some(
1261
- (p) => p.name === "maxItems" || p.name === "pageSize"
1625
+ (p) => PAGINATION_PARAM_NAMES.has(p.name)
1262
1626
  );
1263
- const hasUserSpecifiedMaxItems = "maxItems" in options && options.maxItems !== void 0;
1264
- const shouldUseJson = options.json;
1627
+ const hasUserSpecifiedMaxItems = "maxItems" in options2 && options2.maxItems !== void 0;
1628
+ const outputMode = resolveOutputMode({
1629
+ isListCommand,
1630
+ hasPaginationParams,
1631
+ hasUserSpecifiedMaxItems
1632
+ });
1265
1633
  const rawParams = convertCliArgsToSdkParams(
1266
1634
  parameters,
1267
1635
  args.slice(0, -1),
1268
- options
1636
+ options2
1269
1637
  );
1270
1638
  if (schema && !usesInputParameters) {
1271
1639
  const resolver = new SchemaParameterResolver();
@@ -1273,128 +1641,96 @@ function createCommandConfig(cliCommandName, functionInfo, sdk2) {
1273
1641
  schema,
1274
1642
  rawParams,
1275
1643
  sdk2,
1276
- functionInfo.name
1644
+ functionInfo.name,
1645
+ { interactiveMode }
1277
1646
  );
1278
1647
  } else {
1279
1648
  resolvedParams = rawParams;
1280
1649
  }
1281
1650
  const confirm = functionInfo.confirm;
1282
1651
  let confirmMessageAfter;
1283
- if (confirm && !shouldUseJson) {
1652
+ if (confirm && interactiveMode) {
1284
1653
  const confirmResult = await promptConfirm(confirm);
1285
1654
  if (!confirmResult.confirmed) {
1286
- console.log(chalk3.yellow("Operation cancelled."));
1655
+ console.log(chalk7.yellow("Operation cancelled."));
1287
1656
  return;
1288
1657
  }
1289
1658
  confirmMessageAfter = confirmResult.messageAfter;
1290
1659
  }
1291
- if (isListCommand && hasPaginationParams && !shouldUseJson && !hasUserSpecifiedMaxItems) {
1292
- const sdkObj = sdk2;
1293
- const sdkIterable = sdkObj[functionInfo.name](resolvedParams);
1294
- await handlePaginatedListWithAsyncIteration(
1295
- functionInfo.name,
1296
- sdkIterable,
1297
- functionInfo
1298
- );
1299
- } else {
1300
- const hasOutputFile = resolvedParams.output;
1301
- if (hasOutputFile) {
1302
- const sdkObj = sdk2;
1303
- await sdkObj[functionInfo.name](resolvedParams);
1304
- console.log(
1305
- chalk3.green(`\u2705 ${cliCommandName} completed successfully!`)
1306
- );
1307
- console.log(chalk3.gray(`Output written to: ${hasOutputFile}`));
1308
- return;
1309
- }
1310
- let result;
1311
- if (usesInputParameters) {
1312
- const positionalArgs = reconstructPositionalArgs(
1313
- functionInfo.inputParameters,
1314
- resolvedParams
1315
- );
1316
- const sdkObj = sdk2;
1317
- result = await sdkObj[functionInfo.name](...positionalArgs);
1318
- } else {
1319
- const sdkObj = sdk2;
1320
- result = await sdkObj[functionInfo.name](resolvedParams);
1321
- }
1322
- if (result instanceof Response) {
1323
- const response = result;
1324
- let body;
1325
- const text = await response.text().catch(() => "[unable to read body]");
1326
- try {
1327
- body = JSON.parse(text);
1328
- } catch {
1329
- throw new Error(
1330
- `Failed to parse response as JSON (status: ${response.status}). Body: ${text.slice(0, 500)}`
1331
- );
1332
- }
1333
- result = {
1334
- statusCode: response.status,
1335
- headers: Object.fromEntries(response.headers.entries()),
1336
- body
1337
- };
1660
+ const sdkMethod = sdk2[functionInfo.name];
1661
+ switch (outputMode) {
1662
+ case "paginate": {
1663
+ const source = sdkMethod(resolvedParams);
1664
+ await renderer.renderPaginatedList(source, functionInfo);
1665
+ break;
1338
1666
  }
1339
- const items = result?.data ? result.data : result;
1340
- if (shouldUseJson) {
1341
- console.log(JSON.stringify(items, null, 2));
1342
- } else if (isListCommand) {
1343
- formatNonPaginatedResults(
1344
- items,
1345
- resolvedParams.maxItems,
1346
- hasUserSpecifiedMaxItems,
1347
- shouldUseJson,
1667
+ case "collect": {
1668
+ const maxItems = resolvedParams.maxItems;
1669
+ const sdkResult = sdkMethod({ ...resolvedParams, maxItems });
1670
+ const allItems = await collectItemsFromResult({
1671
+ sdkResult,
1672
+ maxItems
1673
+ });
1674
+ renderer.renderCollectedList(allItems, {
1675
+ maxItems,
1676
+ userSpecifiedMaxItems: hasUserSpecifiedMaxItems,
1348
1677
  functionInfo
1349
- );
1350
- } else {
1351
- formatJsonOutput(items);
1678
+ });
1679
+ break;
1352
1680
  }
1353
- if (confirmMessageAfter) {
1354
- console.log(chalk3.yellow(`
1681
+ case "single": {
1682
+ const callSdkMethod = () => {
1683
+ if (usesInputParameters) {
1684
+ const positionalArgs = reconstructPositionalArgs(
1685
+ functionInfo.inputParameters,
1686
+ resolvedParams
1687
+ );
1688
+ return sdkMethod(...positionalArgs);
1689
+ }
1690
+ return sdkMethod(resolvedParams);
1691
+ };
1692
+ const outputFile = resolvedParams.output;
1693
+ if (outputFile) {
1694
+ await callSdkMethod();
1695
+ renderer.renderItem(null, {
1696
+ outputFile,
1697
+ commandName: cliCommandName
1698
+ });
1699
+ break;
1700
+ }
1701
+ const result = await callSdkMethod();
1702
+ const normalizedResult = getNormalizedResult(result, {
1703
+ isListCommand
1704
+ });
1705
+ if (normalizedResult.kind === "response") {
1706
+ await renderer.renderResponse(normalizedResult.value);
1707
+ } else if (normalizedResult.kind === "list") {
1708
+ renderer.renderCollectedList(normalizedResult.data, {
1709
+ maxItems: resolvedParams.maxItems,
1710
+ userSpecifiedMaxItems: hasUserSpecifiedMaxItems,
1711
+ functionInfo
1712
+ });
1713
+ } else {
1714
+ renderer.renderItem(normalizedResult.value);
1715
+ }
1716
+ if (confirmMessageAfter) {
1717
+ console.log(chalk7.yellow(`
1355
1718
  ${confirmMessageAfter}`));
1719
+ }
1720
+ break;
1356
1721
  }
1357
1722
  }
1358
1723
  } catch (error) {
1359
1724
  success = false;
1360
1725
  errorMessage = error instanceof Error ? error.message : String(error);
1361
- if (error instanceof Error && error.message.includes('"code"')) {
1362
- try {
1363
- const validationErrors = JSON.parse(error.message);
1364
- console.error(chalk3.red("\u274C Validation Error:"));
1365
- validationErrors.forEach((err) => {
1366
- const errorObj = err;
1367
- const field = errorObj?.path?.join(".") || "unknown";
1368
- console.error(
1369
- chalk3.yellow(
1370
- ` \u2022 ${field}: ${errorObj?.message || "Unknown error"}`
1371
- )
1372
- );
1373
- });
1374
- console.error(
1375
- "\n" + chalk3.dim(`Use --help to see available options`)
1376
- );
1377
- throw new ZapierCliExitError("Validation failed", 1);
1378
- } catch {
1379
- console.error(
1380
- chalk3.red("Error:"),
1381
- error instanceof Error ? error.message : String(error)
1382
- );
1383
- throw new ZapierCliExitError(
1384
- error instanceof Error ? error.message : String(error),
1385
- 1
1386
- );
1387
- }
1726
+ if (error instanceof ZapierCliMissingParametersError) {
1727
+ renderer.renderError(error);
1728
+ } else if (error instanceof ZapierCliValidationError) {
1729
+ renderer.renderError(error);
1388
1730
  } else if (error instanceof ZapierCliError) {
1389
1731
  throw error;
1390
- } else if (error instanceof ZapierError) {
1391
- const formattedMessage = formatErrorMessage(error);
1392
- console.error(chalk3.red("\u274C Error:"), formattedMessage);
1393
- throw new ZapierCliExitError(formattedMessage, 1);
1394
1732
  } else {
1395
- const msg = error instanceof Error ? error.message : "Unknown error";
1396
- console.error(chalk3.red("\u274C Error:"), msg);
1397
- throw new ZapierCliExitError(msg, 1);
1733
+ renderer.renderError(error);
1398
1734
  }
1399
1735
  } finally {
1400
1736
  try {
@@ -1423,7 +1759,8 @@ ${confirmMessageAfter}`));
1423
1759
  parameters,
1424
1760
  handler,
1425
1761
  hidden: functionInfo.categories?.includes("deprecated") ?? false,
1426
- aliases: functionInfo.aliases
1762
+ aliases: functionInfo.aliases,
1763
+ supportsJsonOutput: functionInfo.supportsJsonOutput
1427
1764
  };
1428
1765
  }
1429
1766
  function collect(value, previous = []) {
@@ -1434,7 +1771,7 @@ function addCommand(program2, commandName, config) {
1434
1771
  const command = program2.command(commandName, { hidden: config.hidden ?? false }).description(config.description);
1435
1772
  let hasPositionalArray = false;
1436
1773
  config.parameters.forEach((param) => {
1437
- const kebabName = param.name.replace(/([A-Z])/g, "-$1").toLowerCase();
1774
+ const kebabName = toKebabCase(param.name);
1438
1775
  if (param.hasResolver && param.required) {
1439
1776
  command.argument(
1440
1777
  `[${kebabName}]`,
@@ -1489,9 +1826,9 @@ function addCommand(program2, commandName, config) {
1489
1826
  });
1490
1827
  const paramNames = new Set(config.parameters.map((p) => p.name));
1491
1828
  SHARED_COMMAND_CLI_OPTIONS.forEach((opt) => {
1492
- if (!paramNames.has(opt.name)) {
1493
- command.option(opt.flag, opt.description);
1494
- }
1829
+ if (paramNames.has(opt.name)) return;
1830
+ if (config.supportsJsonOutput === false && opt.name === "json") return;
1831
+ command.option(opt.flag, opt.description);
1495
1832
  });
1496
1833
  command.action(config.handler);
1497
1834
  }
@@ -1552,161 +1889,6 @@ function convertValue(value, type) {
1552
1889
  return value;
1553
1890
  }
1554
1891
  }
1555
- async function handlePaginatedListWithAsyncIteration(sdkMethodName, sdkResult, functionInfo) {
1556
- const itemName = getItemNameFromMethod(functionInfo);
1557
- let totalShown = 0;
1558
- let pageCount = 0;
1559
- console.log(
1560
- chalk3.blue(`\u{1F4CB} ${getListTitleFromMethod(sdkMethodName, functionInfo)}
1561
- `)
1562
- );
1563
- try {
1564
- for await (const page of sdkResult) {
1565
- const items = page.data || page;
1566
- pageCount++;
1567
- if (!Array.isArray(items)) {
1568
- console.log(chalk3.yellow(`No ${itemName} found.`));
1569
- return;
1570
- }
1571
- if (items.length === 0 && pageCount === 1) {
1572
- console.log(chalk3.yellow(`No ${itemName} found.`));
1573
- return;
1574
- }
1575
- if (items.length === 0) {
1576
- break;
1577
- }
1578
- if (pageCount > 1) {
1579
- console.clear();
1580
- console.log(
1581
- chalk3.blue(
1582
- `\u{1F4CB} ${getListTitleFromMethod(sdkMethodName, functionInfo)}
1583
- `
1584
- )
1585
- );
1586
- }
1587
- if (functionInfo && functionInfo.inputSchema) {
1588
- formatItemsFromSchema(
1589
- functionInfo,
1590
- items,
1591
- totalShown
1592
- );
1593
- } else {
1594
- formatItemsGeneric2(items, totalShown);
1595
- }
1596
- totalShown += items.length;
1597
- console.log(
1598
- chalk3.green(
1599
- `
1600
- \u2705 Showing ${totalShown} ${itemName} (page ${pageCount})`
1601
- )
1602
- );
1603
- if (page.nextCursor) {
1604
- const { continueReading } = await inquirer.prompt([
1605
- {
1606
- type: "confirm",
1607
- name: "continueReading",
1608
- message: `Load next page?`,
1609
- default: true
1610
- }
1611
- ]);
1612
- if (!continueReading) {
1613
- break;
1614
- }
1615
- } else {
1616
- break;
1617
- }
1618
- }
1619
- console.log(chalk3.gray(`
1620
- \u{1F4C4} Finished browsing ${itemName}`));
1621
- } catch (error) {
1622
- const items = sdkResult?.data || sdkResult;
1623
- if (Array.isArray(items)) {
1624
- if (items.length === 0) {
1625
- console.log(chalk3.yellow(`No ${itemName} found.`));
1626
- return;
1627
- }
1628
- if (functionInfo && functionInfo.inputSchema) {
1629
- formatItemsFromSchema(
1630
- functionInfo,
1631
- items,
1632
- 0
1633
- );
1634
- } else {
1635
- formatItemsGeneric2(items, 0);
1636
- }
1637
- console.log(chalk3.green(`
1638
- \u2705 Showing ${items.length} ${itemName}`));
1639
- } else {
1640
- throw error;
1641
- }
1642
- }
1643
- }
1644
- function formatNonPaginatedResults(result, requestedMaxItems, userSpecifiedMaxItems, useRawJson, functionInfo) {
1645
- if (!Array.isArray(result)) {
1646
- if (useRawJson) {
1647
- console.log(JSON.stringify(result, null, 2));
1648
- } else {
1649
- formatJsonOutput(result);
1650
- }
1651
- return;
1652
- }
1653
- if (useRawJson) {
1654
- console.log(JSON.stringify(result, null, 2));
1655
- return;
1656
- }
1657
- const itemName = functionInfo ? getItemNameFromMethod(functionInfo) : "items";
1658
- if (result.length === 0) {
1659
- console.log(chalk3.yellow(`No ${itemName} found.`));
1660
- return;
1661
- }
1662
- console.log(chalk3.green(`
1663
- \u2705 Found ${result.length} ${itemName}:
1664
- `));
1665
- if (functionInfo && functionInfo.inputSchema) {
1666
- formatItemsFromSchema(
1667
- functionInfo,
1668
- result
1669
- );
1670
- } else {
1671
- formatItemsGeneric2(result);
1672
- }
1673
- if (userSpecifiedMaxItems && requestedMaxItems) {
1674
- console.log(
1675
- chalk3.gray(
1676
- `
1677
- \u{1F4C4} Showing up to ${requestedMaxItems} ${itemName} (--max-items ${requestedMaxItems})`
1678
- )
1679
- );
1680
- } else {
1681
- console.log(chalk3.gray(`
1682
- \u{1F4C4} All available ${itemName} shown`));
1683
- }
1684
- }
1685
- function formatItemsGeneric2(items, startingNumber = 0) {
1686
- items.forEach((item, index) => {
1687
- const itemObj = item;
1688
- const name = itemObj?.name || itemObj?.key || itemObj?.id || "Item";
1689
- console.log(
1690
- `${chalk3.gray(`${startingNumber + index + 1}.`)} ${chalk3.cyan(String(name))}`
1691
- );
1692
- if (itemObj?.description) {
1693
- console.log(` ${chalk3.dim(String(itemObj.description))}`);
1694
- }
1695
- console.log();
1696
- });
1697
- }
1698
- function getItemNameFromMethod(functionInfo) {
1699
- if (functionInfo.itemType) {
1700
- return `${functionInfo.itemType} items`;
1701
- }
1702
- return "items";
1703
- }
1704
- function getListTitleFromMethod(methodName, functionInfo) {
1705
- if (functionInfo.itemType) {
1706
- return `Available ${functionInfo.itemType} items`;
1707
- }
1708
- return `${methodName} items`;
1709
- }
1710
1892
  var LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
1711
1893
  var LOGIN_TIMEOUT_MS = 3e5;
1712
1894
  var spinPromise = async (promise, text) => {
@@ -1726,20 +1908,20 @@ var spinPromise = async (promise, text) => {
1726
1908
  };
1727
1909
  var log = {
1728
1910
  info: (message, ...args) => {
1729
- console.log(chalk3.blue("\u2139"), message, ...args);
1911
+ console.log(chalk7.blue("\u2139"), message, ...args);
1730
1912
  },
1731
1913
  error: (message, ...args) => {
1732
- console.error(chalk3.red("\u2716"), message, ...args);
1914
+ console.error(chalk7.red("\u2716"), message, ...args);
1733
1915
  },
1734
1916
  success: (message, ...args) => {
1735
- console.log(chalk3.green("\u2713"), message, ...args);
1917
+ console.log(chalk7.green("\u2713"), message, ...args);
1736
1918
  },
1737
1919
  warn: (message, ...args) => {
1738
- console.log(chalk3.yellow("\u26A0"), message, ...args);
1920
+ console.log(chalk7.yellow("\u26A0"), message, ...args);
1739
1921
  },
1740
1922
  debug: (message, ...args) => {
1741
1923
  if (process.env.DEBUG === "true" || process.argv.includes("--debug")) {
1742
- console.log(chalk3.gray("\u{1F41B}"), message, ...args);
1924
+ console.log(chalk7.gray("\u{1F41B}"), message, ...args);
1743
1925
  }
1744
1926
  }
1745
1927
  };
@@ -2015,7 +2197,8 @@ var loginPlugin = ({
2015
2197
  meta: {
2016
2198
  login: {
2017
2199
  categories: ["account"],
2018
- inputSchema: LoginSchema
2200
+ inputSchema: LoginSchema,
2201
+ supportsJsonOutput: false
2019
2202
  }
2020
2203
  }
2021
2204
  }
@@ -2034,7 +2217,8 @@ var logoutPlugin = () => ({
2034
2217
  meta: {
2035
2218
  logout: {
2036
2219
  categories: ["account"],
2037
- inputSchema: LogoutSchema
2220
+ inputSchema: LogoutSchema,
2221
+ supportsJsonOutput: false
2038
2222
  }
2039
2223
  }
2040
2224
  }
@@ -3805,7 +3989,7 @@ function buildTemplateVariables({
3805
3989
  };
3806
3990
  }
3807
3991
  function cleanupProject({ projectDir }) {
3808
- console.log("\n" + chalk3.yellow("!") + " Cleaning up...");
3992
+ console.log("\n" + chalk7.yellow("!") + " Cleaning up...");
3809
3993
  rmSync(projectDir, { recursive: true, force: true });
3810
3994
  }
3811
3995
  async function withInterruptCleanup(cleanup, fn) {
@@ -4015,8 +4199,8 @@ function buildNextSteps({
4015
4199
  }
4016
4200
  function createConsoleDisplayHooks() {
4017
4201
  return {
4018
- onItemComplete: (message) => console.log(" " + chalk3.green("\u2713") + " " + chalk3.dim(message)),
4019
- onWarn: (message) => console.warn(chalk3.yellow("!") + " " + message),
4202
+ onItemComplete: (message) => console.log(" " + chalk7.green("\u2713") + " " + chalk7.dim(message)),
4203
+ onWarn: (message) => console.warn(chalk7.yellow("!") + " " + message),
4020
4204
  onStepStart: ({
4021
4205
  description,
4022
4206
  stepNumber,
@@ -4025,31 +4209,31 @@ function createConsoleDisplayHooks() {
4025
4209
  skipPrompts
4026
4210
  }) => {
4027
4211
  const progressMessage = `${description}...`;
4028
- const stepCounter = chalk3.dim(`${stepNumber}/${totalSteps}`);
4212
+ const stepCounter = chalk7.dim(`${stepNumber}/${totalSteps}`);
4029
4213
  if (skipPrompts) {
4030
4214
  console.log(
4031
- "\n" + chalk3.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
4215
+ "\n" + chalk7.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
4032
4216
  );
4033
4217
  } else {
4034
4218
  console.log(
4035
- chalk3.dim("\u2192") + " " + progressMessage + " " + stepCounter
4219
+ chalk7.dim("\u2192") + " " + progressMessage + " " + stepCounter
4036
4220
  );
4037
4221
  }
4038
4222
  if (command) {
4039
- console.log(" " + chalk3.cyan(`$ ${command}`));
4223
+ console.log(" " + chalk7.cyan(`$ ${command}`));
4040
4224
  }
4041
4225
  },
4042
4226
  onStepSuccess: ({ stepNumber, totalSteps }) => console.log(
4043
- "\n" + chalk3.green("\u2713") + " " + chalk3.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
4227
+ "\n" + chalk7.green("\u2713") + " " + chalk7.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
4044
4228
  ),
4045
4229
  onStepError: ({ description, command, err }) => {
4046
4230
  const detail = err instanceof Error && err.message ? `
4047
- ${chalk3.dim(err.message)}` : "";
4231
+ ${chalk7.dim(err.message)}` : "";
4048
4232
  const hint = command ? `
4049
- ${chalk3.dim("run manually:")} ${chalk3.cyan(`$ ${command}`)}` : "";
4233
+ ${chalk7.dim("run manually:")} ${chalk7.cyan(`$ ${command}`)}` : "";
4050
4234
  console.error(
4051
4235
  `
4052
- ${chalk3.red("\u2716")} ${chalk3.bold(description)}${chalk3.dim(" failed")}${detail}${hint}`
4236
+ ${chalk7.red("\u2716")} ${chalk7.bold(description)}${chalk7.dim(" failed")}${detail}${hint}`
4053
4237
  );
4054
4238
  }
4055
4239
  };
@@ -4061,22 +4245,22 @@ function displaySummaryAndNextSteps({
4061
4245
  packageManager
4062
4246
  }) {
4063
4247
  const formatStatus = (complete) => ({
4064
- icon: complete ? chalk3.green("\u2713") : chalk3.yellow("!"),
4065
- text: complete ? chalk3.green("Setup complete") : chalk3.yellow("Setup interrupted")
4248
+ icon: complete ? chalk7.green("\u2713") : chalk7.yellow("!"),
4249
+ text: complete ? chalk7.green("Setup complete") : chalk7.yellow("Setup interrupted")
4066
4250
  });
4067
- const formatNextStep = (step, i) => " " + chalk3.dim(`${i + 1}.`) + " " + chalk3.bold(step.description);
4068
- const formatCommand = (cmd) => " " + chalk3.cyan(`$ ${cmd}`);
4069
- const formatCompletedStep = (step) => " " + chalk3.green("\u2713") + " " + step.description;
4251
+ const formatNextStep = (step, i) => " " + chalk7.dim(`${i + 1}.`) + " " + chalk7.bold(step.description);
4252
+ const formatCommand = (cmd) => " " + chalk7.cyan(`$ ${cmd}`);
4253
+ const formatCompletedStep = (step) => " " + chalk7.green("\u2713") + " " + step.description;
4070
4254
  const { execCmd } = getPackageManagerCommands({ packageManager });
4071
4255
  const leftoverSteps = steps.filter(
4072
4256
  (s) => !completedSetupStepIds.includes(s.id)
4073
4257
  );
4074
4258
  const isComplete = leftoverSteps.length === 0;
4075
4259
  const status = formatStatus(isComplete);
4076
- console.log("\n" + chalk3.bold("\u276F Summary") + "\n");
4077
- console.log(" " + chalk3.dim("Project") + " " + chalk3.bold(projectName));
4260
+ console.log("\n" + chalk7.bold("\u276F Summary") + "\n");
4261
+ console.log(" " + chalk7.dim("Project") + " " + chalk7.bold(projectName));
4078
4262
  console.log(
4079
- " " + chalk3.dim("Status") + " " + status.icon + " " + status.text
4263
+ " " + chalk7.dim("Status") + " " + status.icon + " " + status.text
4080
4264
  );
4081
4265
  const completedSteps = steps.filter(
4082
4266
  (s) => completedSetupStepIds.includes(s.id)
@@ -4086,7 +4270,7 @@ function displaySummaryAndNextSteps({
4086
4270
  for (const step of completedSteps) console.log(formatCompletedStep(step));
4087
4271
  }
4088
4272
  const nextSteps = buildNextSteps({ projectName, leftoverSteps, execCmd });
4089
- console.log("\n" + chalk3.bold("\u276F Next Steps") + "\n");
4273
+ console.log("\n" + chalk7.bold("\u276F Next Steps") + "\n");
4090
4274
  nextSteps.forEach((step, i) => {
4091
4275
  console.log(formatNextStep(step, i));
4092
4276
  if (step.command) console.log(formatCommand(step.command));
@@ -4148,7 +4332,8 @@ var initPlugin = () => {
4148
4332
  meta: {
4149
4333
  init: {
4150
4334
  categories: ["utility"],
4151
- inputSchema: InitSchema
4335
+ inputSchema: InitSchema,
4336
+ supportsJsonOutput: false
4152
4337
  }
4153
4338
  }
4154
4339
  }
@@ -4167,7 +4352,7 @@ function createZapierCliSdk(options = {}) {
4167
4352
  // package.json with { type: 'json' }
4168
4353
  var package_default2 = {
4169
4354
  name: "@zapier/zapier-sdk-cli",
4170
- version: "0.34.12"};
4355
+ version: "0.35.0"};
4171
4356
  var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
4172
4357
  var CACHE_RESET_INTERVAL_MS = (() => {
4173
4358
  const { ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS = `${ONE_DAY_MS}` } = process.env;
@@ -4277,26 +4462,26 @@ function displayUpdateNotification(versionInfo, packageName) {
4277
4462
  if (versionInfo.isDeprecated) {
4278
4463
  console.error();
4279
4464
  console.error(
4280
- chalk3.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk3.red(
4465
+ chalk7.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk7.red(
4281
4466
  ` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
4282
4467
  )
4283
4468
  );
4284
4469
  if (versionInfo.deprecationMessage) {
4285
- console.error(chalk3.red(` ${versionInfo.deprecationMessage}`));
4470
+ console.error(chalk7.red(` ${versionInfo.deprecationMessage}`));
4286
4471
  }
4287
- console.error(chalk3.red(` Please update to the latest version.`));
4472
+ console.error(chalk7.red(` Please update to the latest version.`));
4288
4473
  console.error();
4289
4474
  }
4290
4475
  if (versionInfo.hasUpdate) {
4291
4476
  console.error();
4292
4477
  console.error(
4293
- chalk3.yellow.bold("\u{1F4E6} Update available!") + chalk3.yellow(
4478
+ chalk7.yellow.bold("\u{1F4E6} Update available!") + chalk7.yellow(
4294
4479
  ` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
4295
4480
  )
4296
4481
  );
4297
4482
  console.error(
4298
- chalk3.yellow(
4299
- ` Run ${chalk3.bold(getUpdateCommand(packageName))} to update.`
4483
+ chalk7.yellow(
4484
+ ` Run ${chalk7.bold(getUpdateCommand(packageName))} to update.`
4300
4485
  )
4301
4486
  );
4302
4487
  console.error();