@zapier/zapier-sdk-cli 0.34.11 → 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.11"};
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
  };
@@ -2002,9 +2184,10 @@ var loginPlugin = ({
2002
2184
  const user = await getLoggedInUser();
2003
2185
  context.eventEmission.emit(
2004
2186
  "platform.sdk.ApplicationLifecycleEvent",
2005
- buildApplicationLifecycleEvent({
2006
- lifecycle_event_type: "login_success"
2007
- })
2187
+ buildApplicationLifecycleEvent(
2188
+ { lifecycle_event_type: "login_success" },
2189
+ { customuser_id: user.customUserId, account_id: user.accountId }
2190
+ )
2008
2191
  );
2009
2192
  console.log(`\u2705 Successfully logged in as ${user.email}`);
2010
2193
  };
@@ -2014,7 +2197,8 @@ var loginPlugin = ({
2014
2197
  meta: {
2015
2198
  login: {
2016
2199
  categories: ["account"],
2017
- inputSchema: LoginSchema
2200
+ inputSchema: LoginSchema,
2201
+ supportsJsonOutput: false
2018
2202
  }
2019
2203
  }
2020
2204
  }
@@ -2033,7 +2217,8 @@ var logoutPlugin = () => ({
2033
2217
  meta: {
2034
2218
  logout: {
2035
2219
  categories: ["account"],
2036
- inputSchema: LogoutSchema
2220
+ inputSchema: LogoutSchema,
2221
+ supportsJsonOutput: false
2037
2222
  }
2038
2223
  }
2039
2224
  }
@@ -3804,7 +3989,7 @@ function buildTemplateVariables({
3804
3989
  };
3805
3990
  }
3806
3991
  function cleanupProject({ projectDir }) {
3807
- console.log("\n" + chalk3.yellow("!") + " Cleaning up...");
3992
+ console.log("\n" + chalk7.yellow("!") + " Cleaning up...");
3808
3993
  rmSync(projectDir, { recursive: true, force: true });
3809
3994
  }
3810
3995
  async function withInterruptCleanup(cleanup, fn) {
@@ -4014,8 +4199,8 @@ function buildNextSteps({
4014
4199
  }
4015
4200
  function createConsoleDisplayHooks() {
4016
4201
  return {
4017
- onItemComplete: (message) => console.log(" " + chalk3.green("\u2713") + " " + chalk3.dim(message)),
4018
- 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),
4019
4204
  onStepStart: ({
4020
4205
  description,
4021
4206
  stepNumber,
@@ -4024,31 +4209,31 @@ function createConsoleDisplayHooks() {
4024
4209
  skipPrompts
4025
4210
  }) => {
4026
4211
  const progressMessage = `${description}...`;
4027
- const stepCounter = chalk3.dim(`${stepNumber}/${totalSteps}`);
4212
+ const stepCounter = chalk7.dim(`${stepNumber}/${totalSteps}`);
4028
4213
  if (skipPrompts) {
4029
4214
  console.log(
4030
- "\n" + chalk3.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
4215
+ "\n" + chalk7.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
4031
4216
  );
4032
4217
  } else {
4033
4218
  console.log(
4034
- chalk3.dim("\u2192") + " " + progressMessage + " " + stepCounter
4219
+ chalk7.dim("\u2192") + " " + progressMessage + " " + stepCounter
4035
4220
  );
4036
4221
  }
4037
4222
  if (command) {
4038
- console.log(" " + chalk3.cyan(`$ ${command}`));
4223
+ console.log(" " + chalk7.cyan(`$ ${command}`));
4039
4224
  }
4040
4225
  },
4041
4226
  onStepSuccess: ({ stepNumber, totalSteps }) => console.log(
4042
- "\n" + chalk3.green("\u2713") + " " + chalk3.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
4227
+ "\n" + chalk7.green("\u2713") + " " + chalk7.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
4043
4228
  ),
4044
4229
  onStepError: ({ description, command, err }) => {
4045
4230
  const detail = err instanceof Error && err.message ? `
4046
- ${chalk3.dim(err.message)}` : "";
4231
+ ${chalk7.dim(err.message)}` : "";
4047
4232
  const hint = command ? `
4048
- ${chalk3.dim("run manually:")} ${chalk3.cyan(`$ ${command}`)}` : "";
4233
+ ${chalk7.dim("run manually:")} ${chalk7.cyan(`$ ${command}`)}` : "";
4049
4234
  console.error(
4050
4235
  `
4051
- ${chalk3.red("\u2716")} ${chalk3.bold(description)}${chalk3.dim(" failed")}${detail}${hint}`
4236
+ ${chalk7.red("\u2716")} ${chalk7.bold(description)}${chalk7.dim(" failed")}${detail}${hint}`
4052
4237
  );
4053
4238
  }
4054
4239
  };
@@ -4060,22 +4245,22 @@ function displaySummaryAndNextSteps({
4060
4245
  packageManager
4061
4246
  }) {
4062
4247
  const formatStatus = (complete) => ({
4063
- icon: complete ? chalk3.green("\u2713") : chalk3.yellow("!"),
4064
- 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")
4065
4250
  });
4066
- const formatNextStep = (step, i) => " " + chalk3.dim(`${i + 1}.`) + " " + chalk3.bold(step.description);
4067
- const formatCommand = (cmd) => " " + chalk3.cyan(`$ ${cmd}`);
4068
- 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;
4069
4254
  const { execCmd } = getPackageManagerCommands({ packageManager });
4070
4255
  const leftoverSteps = steps.filter(
4071
4256
  (s) => !completedSetupStepIds.includes(s.id)
4072
4257
  );
4073
4258
  const isComplete = leftoverSteps.length === 0;
4074
4259
  const status = formatStatus(isComplete);
4075
- console.log("\n" + chalk3.bold("\u276F Summary") + "\n");
4076
- 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));
4077
4262
  console.log(
4078
- " " + chalk3.dim("Status") + " " + status.icon + " " + status.text
4263
+ " " + chalk7.dim("Status") + " " + status.icon + " " + status.text
4079
4264
  );
4080
4265
  const completedSteps = steps.filter(
4081
4266
  (s) => completedSetupStepIds.includes(s.id)
@@ -4085,7 +4270,7 @@ function displaySummaryAndNextSteps({
4085
4270
  for (const step of completedSteps) console.log(formatCompletedStep(step));
4086
4271
  }
4087
4272
  const nextSteps = buildNextSteps({ projectName, leftoverSteps, execCmd });
4088
- console.log("\n" + chalk3.bold("\u276F Next Steps") + "\n");
4273
+ console.log("\n" + chalk7.bold("\u276F Next Steps") + "\n");
4089
4274
  nextSteps.forEach((step, i) => {
4090
4275
  console.log(formatNextStep(step, i));
4091
4276
  if (step.command) console.log(formatCommand(step.command));
@@ -4147,7 +4332,8 @@ var initPlugin = () => {
4147
4332
  meta: {
4148
4333
  init: {
4149
4334
  categories: ["utility"],
4150
- inputSchema: InitSchema
4335
+ inputSchema: InitSchema,
4336
+ supportsJsonOutput: false
4151
4337
  }
4152
4338
  }
4153
4339
  }
@@ -4166,7 +4352,7 @@ function createZapierCliSdk(options = {}) {
4166
4352
  // package.json with { type: 'json' }
4167
4353
  var package_default2 = {
4168
4354
  name: "@zapier/zapier-sdk-cli",
4169
- version: "0.34.11"};
4355
+ version: "0.35.0"};
4170
4356
  var ONE_DAY_MS = 24 * 60 * 60 * 1e3;
4171
4357
  var CACHE_RESET_INTERVAL_MS = (() => {
4172
4358
  const { ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS = `${ONE_DAY_MS}` } = process.env;
@@ -4276,26 +4462,26 @@ function displayUpdateNotification(versionInfo, packageName) {
4276
4462
  if (versionInfo.isDeprecated) {
4277
4463
  console.error();
4278
4464
  console.error(
4279
- chalk3.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk3.red(
4465
+ chalk7.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk7.red(
4280
4466
  ` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
4281
4467
  )
4282
4468
  );
4283
4469
  if (versionInfo.deprecationMessage) {
4284
- console.error(chalk3.red(` ${versionInfo.deprecationMessage}`));
4470
+ console.error(chalk7.red(` ${versionInfo.deprecationMessage}`));
4285
4471
  }
4286
- console.error(chalk3.red(` Please update to the latest version.`));
4472
+ console.error(chalk7.red(` Please update to the latest version.`));
4287
4473
  console.error();
4288
4474
  }
4289
4475
  if (versionInfo.hasUpdate) {
4290
4476
  console.error();
4291
4477
  console.error(
4292
- chalk3.yellow.bold("\u{1F4E6} Update available!") + chalk3.yellow(
4478
+ chalk7.yellow.bold("\u{1F4E6} Update available!") + chalk7.yellow(
4293
4479
  ` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
4294
4480
  )
4295
4481
  );
4296
4482
  console.error(
4297
- chalk3.yellow(
4298
- ` Run ${chalk3.bold(getUpdateCommand(packageName))} to update.`
4483
+ chalk7.yellow(
4484
+ ` Run ${chalk7.bold(getUpdateCommand(packageName))} to update.`
4299
4485
  )
4300
4486
  );
4301
4487
  console.error();