@zapier/zapier-sdk-cli 0.77.8 → 0.78.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
@@ -3,7 +3,7 @@ import { Command, CommanderError, Option, InvalidArgumentError } from 'commander
3
3
  import { getConnectionPlugin, defineMethod, apiPluginRef, resolveCredentialsPluginRef, eventEmissionPluginRef, sdkOptionsPluginRef, declareOptionalProperty, OutputPropertySchema, ZapierBundleError, isZapierBundleError, DEFAULT_CONFIG_PATH, declareMethod, ZapierValidationError, isZapierValidationError, ZapierUnknownError, manifestPluginRef, defineResolver, isPermanentHttpError, isZapierAuthenticationError, ZapierApiError, defineOverride, fetchPlugin, zapierCoreOptions, injectCliLogin, definePlugin, omitExports, zapierSdkPlugin, BaseSdkOptionsSchema, disposeSdk, invalidateCachedToken, batch, toSnakeCase, ZapierError, isZapierReleaseTriggerMessageSignal, createSdk as createSdk$1, CORE_OPTIONS_ID as CORE_OPTIONS_ID$1, SDK_OPTIONS_ID as SDK_OPTIONS_ID$1, addPlugin as addPlugin$1, getOrCreateApiClient, isCredentialsObject, getRegistryPlugin, createController, ZapierAbortDrainSignal, ZapierReleaseTriggerMessageSignal, buildApplicationLifecycleEvent, AuthMechanism, DEPRECATION_NOTICE_EVENT, runWithCallerContext, isCoreCancelledSignal, getNegatable, isPositional, resolvePlugin, isZapierError, formatErrorMessage, getOsInfo, getPlatformVersions, getAgent, getTtyContext, getCiPlatform, isCi, isZapierConflictError, getReleaseId, getCurrentTimestamp, generateEventId, isZapierApprovalError, ZapierAuthenticationError } from '@zapier/zapier-sdk';
4
4
  import { z } from 'zod';
5
5
  import inquirer from 'inquirer';
6
- import chalk8 from 'chalk';
6
+ import chalk9 from 'chalk';
7
7
  import { makeTheme, createPrompt, useState, usePrefix, useMemo, useEffect, useKeypress, isEnterKey, isTabKey, isUpKey, isDownKey, usePagination, Separator } from '@inquirer/core';
8
8
  import ora from 'ora';
9
9
  import * as fs from 'fs';
@@ -14,7 +14,7 @@ import isInstalledGlobally from 'is-installed-globally';
14
14
  import util, { stripVTControlCharacters } from 'util';
15
15
  import wrapAnsi4 from 'wrap-ansi';
16
16
  import * as jwt from 'jsonwebtoken';
17
- import { deletePassword, getKeyring, setPassword, getPassword } from 'cross-keychain';
17
+ import { deletePassword, getPassword, getKeyring, setPassword } from 'cross-keychain';
18
18
  import Conf from 'conf';
19
19
  import crypto, { createHash } from 'crypto';
20
20
  import * as lockfile from 'proper-lockfile';
@@ -60,9 +60,9 @@ function normalizeChoices(choices) {
60
60
  var theme = makeTheme({
61
61
  icon: { cursor: "\u276F" },
62
62
  style: {
63
- disabled: (text) => chalk8.dim(`- ${text}`),
64
- searchTerm: (text) => chalk8.cyan(text),
65
- keysHelpTip: (keys) => keys.map(([key, action]) => `${chalk8.bold(key)} ${chalk8.dim(action)}`).join(chalk8.dim(" \u2022 "))
63
+ disabled: (text) => chalk9.dim(`- ${text}`),
64
+ searchTerm: (text) => chalk9.cyan(text),
65
+ keysHelpTip: (keys) => keys.map(([key, action]) => `${chalk9.bold(key)} ${chalk9.dim(action)}`).join(chalk9.dim(" \u2022 "))
66
66
  }
67
67
  });
68
68
  var searchSelect = createPrompt(
@@ -87,8 +87,8 @@ var searchSelect = createPrompt(
87
87
  return { first, last };
88
88
  }, [searchResults]);
89
89
  const defaultActive = useMemo(() => {
90
- const requested = config2.initialActive;
91
- if (searchTerm === "" && requested !== void 0 && requested >= 0 && requested < searchResults.length && isSelectable(searchResults[requested])) {
90
+ const requested = searchTerm === "" ? config2.initialActive : config2.initialActiveForTerm?.({ term: searchTerm });
91
+ if (requested !== void 0 && requested >= 0 && requested < searchResults.length && isSelectable(searchResults[requested])) {
92
92
  return requested;
93
93
  }
94
94
  return bounds.first;
@@ -205,10 +205,10 @@ async function promptText({
205
205
  ]);
206
206
  return value;
207
207
  }
208
- var display = (c) => c.hint ? `${c.label} ${chalk8.dim(`(${c.hint})`)}` : c.label;
208
+ var display = (c) => c.hint ? `${c.label} ${chalk9.dim(`(${c.hint})`)}` : c.label;
209
209
  var HIGH_CONTRAST_PROMPT_THEME = {
210
210
  style: {
211
- answer: (text) => chalk8.inverse.bold(` ${text} `)
211
+ answer: (text) => chalk9.inverse.bold(` ${text} `)
212
212
  }
213
213
  };
214
214
  function buildSelectRows(question, term) {
@@ -224,8 +224,8 @@ function buildSelectRows(question, term) {
224
224
  name: display(c),
225
225
  value: c.value
226
226
  }));
227
- const skipRow = offers(question, "skip") ? [row(chalk8.dim("Skip (optional)"), "skip")] : [];
228
- const customRow = offers(question, "custom") ? [row(chalk8.dim("Enter a value manually\u2026"), "custom")] : [];
227
+ const skipRow = offers(question, "skip") ? [row(chalk9.dim("Skip (optional)"), "skip")] : [];
228
+ const customRow = offers(question, "custom") ? [row(chalk9.dim("Enter a value manually\u2026"), "custom")] : [];
229
229
  const committed = !!t || question.search !== void 0;
230
230
  let rows;
231
231
  if (!committed) {
@@ -236,13 +236,13 @@ function buildSelectRows(question, term) {
236
236
  rows = [...customRow, ...skipRow];
237
237
  }
238
238
  if (offers(question, "search"))
239
- rows.push(row(chalk8.cyan("Search again\u2026"), "search"));
239
+ rows.push(row(chalk9.cyan("Search again\u2026"), "search"));
240
240
  if (offers(question, "next_page"))
241
- rows.push(row(chalk8.dim("Load more\u2026"), "next_page"));
242
- if (offers(question, "retry")) rows.push(row(chalk8.yellow("Retry"), "retry"));
243
- if (offers(question, "cancel")) rows.push(row(chalk8.dim("Cancel"), "cancel"));
241
+ rows.push(row(chalk9.dim("Load more\u2026"), "next_page"));
242
+ if (offers(question, "retry")) rows.push(row(chalk9.yellow("Retry"), "retry"));
243
+ if (offers(question, "cancel")) rows.push(row(chalk9.dim("Cancel"), "cancel"));
244
244
  for (const note of question.notes ?? [])
245
- rows.push({ name: chalk8.dim(note), value: note, disabled: true });
245
+ rows.push({ name: chalk9.dim(note), value: note, disabled: true });
246
246
  return rows;
247
247
  }
248
248
  function foldPage(acc, question, field) {
@@ -322,12 +322,12 @@ async function answerSelect(question, field, box, failed, mode) {
322
322
  })),
323
323
  ...offers(question, "next_page") ? [
324
324
  {
325
- name: chalk8.dim("Load more\u2026"),
325
+ name: chalk9.dim("Load more\u2026"),
326
326
  value: { action: "next_page" }
327
327
  }
328
328
  ] : [],
329
329
  ...(question.notes ?? []).map((note) => ({
330
- name: chalk8.dim(note),
330
+ name: chalk9.dim(note),
331
331
  value: note,
332
332
  disabled: true
333
333
  }))
@@ -404,14 +404,14 @@ async function answerSelect(question, field, box, failed, mode) {
404
404
  case "retry":
405
405
  return { type: "retry" };
406
406
  case "skip":
407
- printAnswered(view.message, chalk8.dim("(skipped)"));
407
+ printAnswered(view.message, chalk9.dim("(skipped)"));
408
408
  return { type: "skip" };
409
409
  case "cancel":
410
410
  return { type: "cancel" };
411
411
  }
412
412
  }
413
413
  function printAnswered(message, label) {
414
- console.log(`${chalk8.green("\u2714")} ${message} ${chalk8.cyan(label)}`);
414
+ console.log(`${chalk9.green("\u2714")} ${message} ${chalk9.cyan(label)}`);
415
415
  }
416
416
  async function answerInput(question) {
417
417
  const message = question.placeholder ? question.message.replace(/:?\s*$/, ` (${question.placeholder}):`) : question.message;
@@ -458,7 +458,7 @@ function createCliAnswer({
458
458
  try {
459
459
  if (result.error !== void 0) {
460
460
  const message = typeof result.error === "string" ? result.error : result.error.message;
461
- console.log(chalk8.yellow(`! ${message}`));
461
+ console.log(chalk9.yellow(`! ${message}`));
462
462
  }
463
463
  const question = result.question;
464
464
  const field = question.path.length ? question.path.join(".") : "value";
@@ -558,7 +558,7 @@ var SHARED_COMMAND_CLI_OPTIONS = [
558
558
 
559
559
  // package.json
560
560
  var package_default = {
561
- version: "0.77.8"};
561
+ version: "0.78.0"};
562
562
  var PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
563
563
  var LOCKFILES = [
564
564
  ["pnpm-lock.yaml", "pnpm"],
@@ -723,7 +723,7 @@ async function formatItemsFromSchema(_functionInfo, items, startingNumber = 0, o
723
723
  formatItemsGeneric(items, startingNumber);
724
724
  }
725
725
  function formatSingleItem(formatted, itemNumber) {
726
- let titleLine = `${chalk8.gray(`${itemNumber + 1}.`)} ${chalk8.cyan(formatted.title)}`;
726
+ let titleLine = `${chalk9.gray(`${itemNumber + 1}.`)} ${chalk9.cyan(formatted.title)}`;
727
727
  const subtitleParts = [];
728
728
  if (formatted.hint !== void 0) {
729
729
  subtitleParts.push(
@@ -741,11 +741,11 @@ function formatSingleItem(formatted, itemNumber) {
741
741
  }
742
742
  const uniqueParts = [...new Set(subtitleParts)];
743
743
  if (uniqueParts.length > 0) {
744
- titleLine += ` ${chalk8.gray(`(${uniqueParts.join(", ")})`)}`;
744
+ titleLine += ` ${chalk9.gray(`(${uniqueParts.join(", ")})`)}`;
745
745
  }
746
746
  console.log(titleLine);
747
747
  if (formatted.description) {
748
- console.log(` ${chalk8.dim(formatted.description)}`);
748
+ console.log(` ${chalk9.dim(formatted.description)}`);
749
749
  }
750
750
  if (formatted.raw !== void 0) {
751
751
  formatJsonOutput(formatted.raw);
@@ -756,7 +756,7 @@ function formatSingleItem(formatted, itemNumber) {
756
756
  if (detail.label) {
757
757
  const isMultiline = detail.text.includes("\n");
758
758
  if (isMultiline) {
759
- console.log(` ${chalk8.gray(detail.label + ":")}`);
759
+ console.log(` ${chalk9.gray(detail.label + ":")}`);
760
760
  const displayText = formatDetailText(
761
761
  detail.text,
762
762
  DETAIL_INDENT + " "
@@ -765,7 +765,7 @@ function formatSingleItem(formatted, itemNumber) {
765
765
  console.log(`${DETAIL_INDENT} ${styledText}`);
766
766
  } else {
767
767
  const styledValue = applyStyle(detail.text, detail.style);
768
- console.log(` ${chalk8.gray(detail.label + ":")} ${styledValue}`);
768
+ console.log(` ${chalk9.gray(detail.label + ":")} ${styledValue}`);
769
769
  }
770
770
  } else {
771
771
  const displayText = formatDetailText(detail.text, DETAIL_INDENT);
@@ -789,16 +789,16 @@ function formatDetailText(text, indent = DETAIL_INDENT) {
789
789
  function applyStyle(value, style) {
790
790
  switch (style) {
791
791
  case "dim":
792
- return chalk8.dim(value);
792
+ return chalk9.dim(value);
793
793
  case "accent":
794
- return chalk8.magenta(value);
794
+ return chalk9.magenta(value);
795
795
  case "warning":
796
- return chalk8.red(value);
796
+ return chalk9.red(value);
797
797
  case "success":
798
- return chalk8.green(value);
798
+ return chalk9.green(value);
799
799
  case "normal":
800
800
  default:
801
- return chalk8.blue(value);
801
+ return chalk9.blue(value);
802
802
  }
803
803
  }
804
804
  function convertGenericItemToFormattedItem(item) {
@@ -947,10 +947,10 @@ function createInteractiveRenderer(context = {}) {
947
947
  const obj = item;
948
948
  const name = obj?.name || obj?.key || obj?.id || "Item";
949
949
  console.log(
950
- `${chalk8.gray(`${startingNumber + index + 1}.`)} ${chalk8.cyan(String(name))}`
950
+ `${chalk9.gray(`${startingNumber + index + 1}.`)} ${chalk9.cyan(String(name))}`
951
951
  );
952
952
  if (obj?.description)
953
- console.log(` ${chalk8.dim(String(obj.description))}`);
953
+ console.log(` ${chalk9.dim(String(obj.description))}`);
954
954
  console.log();
955
955
  });
956
956
  }
@@ -961,35 +961,35 @@ function createInteractiveRenderer(context = {}) {
961
961
  if (!(Symbol.asyncIterator in Object(source))) {
962
962
  const items = source?.data;
963
963
  if (!Array.isArray(items) || items.length === 0) {
964
- console.log(chalk8.yellow(`No ${itemName} found.`));
964
+ console.log(chalk9.yellow(`No ${itemName} found.`));
965
965
  return;
966
966
  }
967
967
  await renderItemsForDisplay(items, functionInfo, 0);
968
- console.log(chalk8.green(`
968
+ console.log(chalk9.green(`
969
969
  \u2705 Showing ${items.length} ${itemName}`));
970
970
  return;
971
971
  }
972
972
  let totalShown = 0;
973
973
  let pageCount = 0;
974
- console.log(chalk8.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
974
+ console.log(chalk9.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
975
975
  `));
976
976
  for await (const page of source) {
977
977
  const items = page.data ?? [];
978
978
  pageCount++;
979
979
  if (items.length === 0 && pageCount === 1) {
980
- console.log(chalk8.yellow(`No ${itemName} found.`));
980
+ console.log(chalk9.yellow(`No ${itemName} found.`));
981
981
  return;
982
982
  }
983
983
  if (items.length === 0) break;
984
984
  if (pageCount > 1) {
985
985
  console.clear();
986
- console.log(chalk8.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
986
+ console.log(chalk9.blue(`\u{1F4CB} ${getListTitle(functionInfo)}
987
987
  `));
988
988
  }
989
989
  await renderItemsForDisplay(items, functionInfo, totalShown);
990
990
  totalShown += items.length;
991
991
  console.log(
992
- chalk8.green(
992
+ chalk9.green(
993
993
  `
994
994
  \u2705 Showing ${totalShown} ${itemName} (page ${pageCount})`
995
995
  )
@@ -1008,7 +1008,7 @@ function createInteractiveRenderer(context = {}) {
1008
1008
  break;
1009
1009
  }
1010
1010
  }
1011
- console.log(chalk8.gray(`
1011
+ console.log(chalk9.gray(`
1012
1012
  \u{1F4C4} Finished browsing ${itemName}`));
1013
1013
  },
1014
1014
  async renderCollectedList(items, { maxItems, userSpecifiedMaxItems, functionInfo } = {}) {
@@ -1018,30 +1018,30 @@ function createInteractiveRenderer(context = {}) {
1018
1018
  }
1019
1019
  const itemName = getItemName(functionInfo);
1020
1020
  if (items.length === 0) {
1021
- console.log(chalk8.yellow(`No ${itemName} found.`));
1021
+ console.log(chalk9.yellow(`No ${itemName} found.`));
1022
1022
  return;
1023
1023
  }
1024
- console.log(chalk8.green(`
1024
+ console.log(chalk9.green(`
1025
1025
  \u2705 Found ${items.length} ${itemName}:
1026
1026
  `));
1027
1027
  await renderItemsForDisplay(items, functionInfo);
1028
1028
  if (userSpecifiedMaxItems && maxItems) {
1029
1029
  console.log(
1030
- chalk8.gray(
1030
+ chalk9.gray(
1031
1031
  `
1032
1032
  \u{1F4C4} Showing up to ${maxItems} ${itemName} (--max-items ${maxItems})`
1033
1033
  )
1034
1034
  );
1035
1035
  } else {
1036
- console.log(chalk8.gray(`
1036
+ console.log(chalk9.gray(`
1037
1037
  \u{1F4C4} All available ${itemName} shown`));
1038
1038
  }
1039
1039
  },
1040
1040
  renderItem(value, options) {
1041
1041
  if (options?.outputFile) {
1042
1042
  const label = options.commandName ? `\u2705 ${options.commandName} completed successfully!` : "\u2705 Done!";
1043
- console.log(chalk8.green(label));
1044
- console.log(chalk8.gray(`Output written to: ${options.outputFile}`));
1043
+ console.log(chalk9.green(label));
1044
+ console.log(chalk9.gray(`Output written to: ${options.outputFile}`));
1045
1045
  } else {
1046
1046
  formatJsonOutput(value);
1047
1047
  }
@@ -1051,17 +1051,17 @@ function createInteractiveRenderer(context = {}) {
1051
1051
  },
1052
1052
  renderError(error) {
1053
1053
  if (error instanceof ZapierCliMissingParametersError) {
1054
- console.error(chalk8.red("\u274C " + formatMissingParamsError(error)));
1055
- console.error("\n" + chalk8.dim("Use --help to see available options"));
1054
+ console.error(chalk9.red("\u274C " + formatMissingParamsError(error)));
1055
+ console.error("\n" + chalk9.dim("Use --help to see available options"));
1056
1056
  throw new ZapierCliExitError(error.message, 1);
1057
1057
  }
1058
1058
  if (isZapierError(error)) {
1059
1059
  const formattedMessage = formatErrorMessage(error);
1060
- console.error(chalk8.red("\u274C Error:"), formattedMessage);
1060
+ console.error(chalk9.red("\u274C Error:"), formattedMessage);
1061
1061
  throw new ZapierCliExitError(formattedMessage, 1);
1062
1062
  }
1063
1063
  const msg = error instanceof Error ? error.message : "Unknown error";
1064
- console.error(chalk8.red("\u274C Error:"), msg);
1064
+ console.error(chalk9.red("\u274C Error:"), msg);
1065
1065
  throw new ZapierCliExitError(msg, 1);
1066
1066
  }
1067
1067
  };
@@ -1177,7 +1177,7 @@ async function promptConfirm(confirmType, itemType) {
1177
1177
  }
1178
1178
  const configOrFn = CONFIRM_MESSAGES[confirmType];
1179
1179
  const { messageBefore, messageAfter } = typeof configOrFn === "function" ? configOrFn(itemType) : configOrFn;
1180
- console.log(chalk8.yellow(`
1180
+ console.log(chalk9.yellow(`
1181
1181
  ${messageBefore}
1182
1182
  `));
1183
1183
  const { confirmed } = await inquirer.prompt([
@@ -1201,12 +1201,12 @@ function emitParamDeprecationWarnings({
1201
1201
  if (Array.isArray(value) && value.length === 0) continue;
1202
1202
  console.warn();
1203
1203
  console.warn(
1204
- chalk8.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8.yellow(
1204
+ chalk9.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk9.yellow(
1205
1205
  ` - \`${toKebabCase(param.name)}\` is deprecated and may be removed in a future release.`
1206
1206
  )
1207
1207
  );
1208
1208
  if (param.deprecationMessage) {
1209
- console.warn(chalk8.yellow(` ${param.deprecationMessage}`));
1209
+ console.warn(chalk9.yellow(` ${param.deprecationMessage}`));
1210
1210
  }
1211
1211
  console.warn();
1212
1212
  }
@@ -1599,7 +1599,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
1599
1599
  functionInfo.itemType
1600
1600
  );
1601
1601
  if (!confirmResult.confirmed) {
1602
- console.log(chalk8.yellow("Operation cancelled."));
1602
+ console.log(chalk9.yellow("Operation cancelled."));
1603
1603
  return;
1604
1604
  }
1605
1605
  confirmMessageAfter = confirmResult.messageAfter;
@@ -1660,7 +1660,7 @@ function createCommandConfig(cliCommandName, functionInfo, sdk) {
1660
1660
  renderer.renderItem(normalizedResult.value);
1661
1661
  }
1662
1662
  if (confirmMessageAfter) {
1663
- console.log(chalk8.yellow(`
1663
+ console.log(chalk9.yellow(`
1664
1664
  ${confirmMessageAfter}`));
1665
1665
  }
1666
1666
  break;
@@ -2341,6 +2341,10 @@ function getActiveCredentials(options) {
2341
2341
  if (!name) return void 0;
2342
2342
  return findEntry(readRegistry(), name, normalizeBaseUrl(options?.baseUrl));
2343
2343
  }
2344
+ function listStoredCredentials(options) {
2345
+ const baseUrl2 = normalizeBaseUrl(options?.baseUrl);
2346
+ return readRegistry().filter((entry) => entry.baseUrl === baseUrl2).sort((left, right) => right.createdAt - left.createdAt);
2347
+ }
2344
2348
  var MAX_CREDENTIAL_NAME_ATTEMPTS = 500;
2345
2349
  function firstAvailableCredentialName({
2346
2350
  baseName,
@@ -2445,6 +2449,29 @@ async function getStoredClientCredentials(options) {
2445
2449
  scope: [...entry.scopes].sort().join(" ")
2446
2450
  };
2447
2451
  }
2452
+ async function activateStoredCredentials({
2453
+ name,
2454
+ baseUrl: baseUrl2
2455
+ }) {
2456
+ const resolvedBaseUrl = normalizeBaseUrl(baseUrl2);
2457
+ const entry = findEntry(readRegistry(), name, resolvedBaseUrl);
2458
+ if (!entry) {
2459
+ throw new ZapierCliValidationError(
2460
+ `No stored credentials named "${name}" were found.`
2461
+ );
2462
+ }
2463
+ const credentials2 = await getStoredClientCredentials({
2464
+ name,
2465
+ baseUrl: resolvedBaseUrl
2466
+ });
2467
+ if (!credentials2) {
2468
+ throw new ZapierCliValidationError(
2469
+ `Stored credentials "${name}" are missing from the system keychain. Add a new account to recreate them.`
2470
+ );
2471
+ }
2472
+ getConfig().set(CREDENTIALS_KEY, name);
2473
+ return entry;
2474
+ }
2448
2475
  function deleteRegistryEntry(registry, name, baseUrl2) {
2449
2476
  const idx = registry.findIndex(
2450
2477
  (e) => e.name === name && e.baseUrl === baseUrl2
@@ -2998,6 +3025,219 @@ async function setupClientCredentials({
2998
3025
  }
2999
3026
  return { clientId };
3000
3027
  }
3028
+ function isSameCredentials(left, right) {
3029
+ return left.name === right.name && left.baseUrl === right.baseUrl;
3030
+ }
3031
+ function createdAtIso(credentials2) {
3032
+ return new Date(credentials2.createdAt).toISOString();
3033
+ }
3034
+ function searchableFields(credentials2) {
3035
+ return [
3036
+ { text: credentials2.name.toLowerCase(), weight: 0 },
3037
+ { text: credentials2.clientId.toLowerCase(), weight: 1e3 },
3038
+ ...credentials2.scopes.map((scope) => ({
3039
+ text: scope.toLowerCase(),
3040
+ weight: 2e3
3041
+ })),
3042
+ {
3043
+ text: createdAtIso(credentials2).slice(0, 10).toLowerCase(),
3044
+ weight: 3e3
3045
+ }
3046
+ ];
3047
+ }
3048
+ function textMatchScore(text, query) {
3049
+ if (text === query) return 0;
3050
+ if (text.startsWith(query)) return 100 + text.length - query.length;
3051
+ const index = text.indexOf(query);
3052
+ if (index === -1) return void 0;
3053
+ return 200 + text.length - query.length;
3054
+ }
3055
+ function closestFieldScore(fields, query) {
3056
+ let closest;
3057
+ for (const field of fields) {
3058
+ const textScore = textMatchScore(field.text, query);
3059
+ if (textScore === void 0) continue;
3060
+ const score = field.weight + textScore;
3061
+ closest = closest === void 0 ? score : Math.min(closest, score);
3062
+ }
3063
+ return closest;
3064
+ }
3065
+ function searchScore(credentials2, term) {
3066
+ const query = term.trim().toLowerCase();
3067
+ const tokens = query.split(/\s+/).filter(Boolean);
3068
+ const fields = searchableFields(credentials2);
3069
+ let tokenScore = 0;
3070
+ for (const token of tokens) {
3071
+ const score = closestFieldScore(fields, token);
3072
+ if (score === void 0) return void 0;
3073
+ tokenScore += score;
3074
+ }
3075
+ const phraseScore = closestFieldScore(fields, query);
3076
+ return phraseScore === void 0 ? 1e4 + tokenScore : phraseScore;
3077
+ }
3078
+ function formatCredentialsChoice({
3079
+ credentials: credentials2,
3080
+ current
3081
+ }) {
3082
+ const currentLabel = current ? chalk9.cyan(" (current)") : "";
3083
+ const details = [
3084
+ credentials2.clientId,
3085
+ credentials2.scopes.join(", "),
3086
+ `created ${createdAtIso(credentials2).slice(0, 10)}`
3087
+ ].join(" \xB7 ");
3088
+ return {
3089
+ name: `${credentials2.name}${currentLabel} ${chalk9.dim(`\xB7 ${details}`)}`,
3090
+ short: credentials2.name,
3091
+ value: { action: "switch", credentials: credentials2 }
3092
+ };
3093
+ }
3094
+ function buildCredentialsChoices({
3095
+ credentials: credentials2,
3096
+ activeCredentials,
3097
+ term = ""
3098
+ }) {
3099
+ const sortedCredentials = [...credentials2].sort(
3100
+ (left, right) => right.createdAt - left.createdAt
3101
+ );
3102
+ const current = activeCredentials ? sortedCredentials.find(
3103
+ (entry) => isSameCredentials(entry, activeCredentials)
3104
+ ) : void 0;
3105
+ const rankedCredentials = term ? sortedCredentials.map((credentials3) => ({
3106
+ credentials: credentials3,
3107
+ score: searchScore(credentials3, term)
3108
+ })).filter(
3109
+ (result) => result.score !== void 0
3110
+ ).sort((left, right) => left.score - right.score).map(({ credentials: credentials3 }) => credentials3) : [
3111
+ ...current ? [current] : [],
3112
+ ...sortedCredentials.filter((credentials3) => credentials3 !== current)
3113
+ ];
3114
+ return [
3115
+ {
3116
+ name: "+ Add a new account",
3117
+ short: "Add a new account",
3118
+ value: { action: "create" }
3119
+ },
3120
+ ...rankedCredentials.map(
3121
+ (credentials3) => formatCredentialsChoice({
3122
+ credentials: credentials3,
3123
+ current: credentials3 === current
3124
+ })
3125
+ )
3126
+ ];
3127
+ }
3128
+ async function promptForCredentials({
3129
+ credentials: credentials2,
3130
+ activeCredentials
3131
+ }) {
3132
+ return searchSelect({
3133
+ message: "Select credentials or add a new account:",
3134
+ source: (term) => buildCredentialsChoices({
3135
+ credentials: credentials2,
3136
+ activeCredentials,
3137
+ term
3138
+ }),
3139
+ initialActive: credentials2.length > 0 ? 1 : 0,
3140
+ initialActiveForTerm: () => 1
3141
+ });
3142
+ }
3143
+
3144
+ // src/utils/auth/stored-login-credentials.ts
3145
+ function authFlowOnlyOptions(options) {
3146
+ return [
3147
+ ...options.timeout === void 0 ? [] : ["--timeout"],
3148
+ ...options.useApprovals === true ? ["--use-approvals"] : [],
3149
+ ...options.headless === true ? ["--headless"] : []
3150
+ ];
3151
+ }
3152
+ function assertCanSwitchCredentials({
3153
+ credentials: credentials2,
3154
+ options,
3155
+ resolvedCredentials
3156
+ }) {
3157
+ if (resolvedCredentials !== void 0) {
3158
+ throw new ZapierCliValidationError(
3159
+ "Cannot switch stored credentials while credentials are configured through SDK options or environment variables. Remove those credentials before switching accounts."
3160
+ );
3161
+ }
3162
+ const incompatibleOptions = authFlowOnlyOptions(options);
3163
+ if (incompatibleOptions.length === 0) return;
3164
+ throw new ZapierCliValidationError(
3165
+ `Cannot switch to stored credentials "${credentials2.name}" while using ${incompatibleOptions.join(
3166
+ ", "
3167
+ )}. These options only apply when logging in to a new account.`
3168
+ );
3169
+ }
3170
+ function findStoredCredentialsByName({
3171
+ name,
3172
+ baseUrl: baseUrl2
3173
+ }) {
3174
+ return listStoredCredentials({ baseUrl: baseUrl2 }).find(
3175
+ (credentials2) => credentials2.name === name
3176
+ );
3177
+ }
3178
+ async function switchCredentials({
3179
+ credentials: credentials2,
3180
+ options,
3181
+ resolvedCredentials
3182
+ }) {
3183
+ assertCanSwitchCredentials({ credentials: credentials2, options, resolvedCredentials });
3184
+ await activateStoredCredentials({
3185
+ name: credentials2.name,
3186
+ baseUrl: credentials2.baseUrl
3187
+ });
3188
+ process.stderr.write(
3189
+ `\u2705 Credentials "${credentials2.name}" are now active.
3190
+ `
3191
+ );
3192
+ }
3193
+ async function chooseStoredLoginCredentialsAtBaseUrl({
3194
+ baseUrl: baseUrl2,
3195
+ options,
3196
+ resolvedCredentials
3197
+ }) {
3198
+ if (resolvedCredentials !== void 0 || authFlowOnlyOptions(options).length > 0) {
3199
+ return "none";
3200
+ }
3201
+ const storedCredentials = listStoredCredentials({ baseUrl: baseUrl2 });
3202
+ if (storedCredentials.length === 0) return "none";
3203
+ const selection = await promptForCredentials({
3204
+ credentials: storedCredentials,
3205
+ activeCredentials: getActiveCredentials({ baseUrl: baseUrl2 })
3206
+ });
3207
+ if (selection.action === "create") return "create";
3208
+ await switchCredentials({
3209
+ credentials: selection.credentials,
3210
+ options,
3211
+ resolvedCredentials
3212
+ });
3213
+ return "switch";
3214
+ }
3215
+ async function chooseStoredLoginCredentials({
3216
+ imports,
3217
+ options
3218
+ }) {
3219
+ const resolvedCredentials = await imports.resolveCredentials();
3220
+ const credentialsBaseUrl2 = await resolveCredentialsBaseUrl({
3221
+ options: imports.sdkOptions,
3222
+ resolvedCredentials
3223
+ });
3224
+ return chooseStoredLoginCredentialsAtBaseUrl({
3225
+ baseUrl: credentialsBaseUrl2,
3226
+ options,
3227
+ resolvedCredentials
3228
+ });
3229
+ }
3230
+ async function confirmNewCredentialsName(name) {
3231
+ const { confirmed } = await inquirer.prompt([
3232
+ {
3233
+ type: "confirm",
3234
+ name: "confirmed",
3235
+ default: false,
3236
+ message: `No stored credentials named "${name}" were found. Continue with a new account and save it as "${name}"?`
3237
+ }
3238
+ ]);
3239
+ return confirmed;
3240
+ }
3001
3241
 
3002
3242
  // src/utils/constants.ts
3003
3243
  var LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
@@ -3022,20 +3262,20 @@ var getCallablePromise = () => {
3022
3262
  var getCallablePromise_default = getCallablePromise;
3023
3263
  var log = {
3024
3264
  info: (message, ...args) => {
3025
- console.error(chalk8.blue("\u2139"), message, ...args);
3265
+ console.error(chalk9.blue("\u2139"), message, ...args);
3026
3266
  },
3027
3267
  error: (message, ...args) => {
3028
- console.error(chalk8.red("\u2716"), message, ...args);
3268
+ console.error(chalk9.red("\u2716"), message, ...args);
3029
3269
  },
3030
3270
  success: (message, ...args) => {
3031
- console.error(chalk8.green("\u2713"), message, ...args);
3271
+ console.error(chalk9.green("\u2713"), message, ...args);
3032
3272
  },
3033
3273
  warn: (message, ...args) => {
3034
- console.error(chalk8.yellow("\u26A0"), message, ...args);
3274
+ console.error(chalk9.yellow("\u26A0"), message, ...args);
3035
3275
  },
3036
3276
  debug: (message, ...args) => {
3037
3277
  if (process.env.DEBUG === "true" || process.argv.includes("--debug")) {
3038
- console.error(chalk8.gray("\u{1F41B}"), message, ...args);
3278
+ console.error(chalk9.gray("\u{1F41B}"), message, ...args);
3039
3279
  }
3040
3280
  }
3041
3281
  };
@@ -3882,9 +4122,6 @@ var HEADLESS_SIGNUP_RECOVERY_MESSAGE = "Restart `zapier-sdk signup --headless` t
3882
4122
  function getEntryPointLabel(entryPoint) {
3883
4123
  return entryPoint === "signup" ? "Signup" : "Login";
3884
4124
  }
3885
- function getActiveCredentialsAction(entryPoint) {
3886
- return entryPoint === "signup" ? "continue signup" : "log in again";
3887
- }
3888
4125
  function getCredentialsPromptMessage(entryPoint) {
3889
4126
  return entryPoint === "signup" ? "Enter a name to identify these credentials:" : "Enter a name to identify them:";
3890
4127
  }
@@ -3899,9 +4136,22 @@ function validateCredentialsName(name) {
3899
4136
  if (!trimmedName) throw new ZapierCliValidationError("Name cannot be empty");
3900
4137
  return trimmedName;
3901
4138
  }
4139
+ function validateNewCredentialsName({
4140
+ name,
4141
+ baseUrl: baseUrl2
4142
+ }) {
4143
+ const validatedName = validateCredentialsName(name);
4144
+ if (credentialNameExists({ name: validatedName, baseUrl: baseUrl2 })) {
4145
+ throw new ZapierCliValidationError(
4146
+ `Credentials named "${validatedName}" already exist. Choose a different name.`
4147
+ );
4148
+ }
4149
+ return validatedName;
4150
+ }
3902
4151
  async function promptCredentialsName({
3903
4152
  email,
3904
- promptMessage
4153
+ promptMessage,
4154
+ baseUrl: baseUrl2
3905
4155
  }) {
3906
4156
  const { credentialName } = await inquirer.prompt([
3907
4157
  {
@@ -3911,7 +4161,7 @@ async function promptCredentialsName({
3911
4161
  default: defaultCredentialsName(email),
3912
4162
  validate: (input) => {
3913
4163
  try {
3914
- validateCredentialsName(input);
4164
+ validateNewCredentialsName({ name: input, baseUrl: baseUrl2 });
3915
4165
  return true;
3916
4166
  } catch (err) {
3917
4167
  return err instanceof Error ? err.message : String(err);
@@ -3919,7 +4169,7 @@ async function promptCredentialsName({
3919
4169
  }
3920
4170
  }
3921
4171
  ]);
3922
- return validateCredentialsName(credentialName);
4172
+ return validateNewCredentialsName({ name: credentialName, baseUrl: baseUrl2 });
3923
4173
  }
3924
4174
  function resolveDefaultCredentialsName({
3925
4175
  email
@@ -3935,7 +4185,8 @@ async function resolveCredentialName({
3935
4185
  if (interactive) {
3936
4186
  return promptCredentialsName({
3937
4187
  email,
3938
- promptMessage: getCredentialsPromptMessage(entryPoint)
4188
+ promptMessage: getCredentialsPromptMessage(entryPoint),
4189
+ baseUrl: baseUrl2
3939
4190
  });
3940
4191
  }
3941
4192
  const baseName = resolveDefaultCredentialsName({ email });
@@ -3976,6 +4227,11 @@ function promptlessCredentialResetError(credentials2) {
3976
4227
  `Already logged in as "${credentials2.name}". Run \`logout\` first or use an interactive terminal to re-authenticate.`
3977
4228
  );
3978
4229
  }
4230
+ function unnamedNonInteractiveLoginError(credentials2) {
4231
+ throw new ZapierCliValidationError(
4232
+ `Already logged in as "${credentials2.name}". Provide \`--name\` to activate or create named credentials, or run \`logout\` first.`
4233
+ );
4234
+ }
3979
4235
  function promptlessLegacyJwtUpgradeError() {
3980
4236
  throw new ZapierCliValidationError(
3981
4237
  "Legacy JWT login detected. Run `logout` first or use an interactive terminal to migrate to client credentials."
@@ -3985,16 +4241,20 @@ async function clearExistingAuthState({
3985
4241
  imports,
3986
4242
  baseUrl: baseUrl2,
3987
4243
  interactive,
3988
- entryPoint
4244
+ entryPoint,
4245
+ preserveExistingCredentials = false
3989
4246
  }) {
3990
4247
  const activeCredentials = getActiveCredentials({ baseUrl: baseUrl2 });
3991
4248
  const flowLabel = getEntryPointLabel(entryPoint);
4249
+ if (activeCredentials && (entryPoint === "login" || preserveExistingCredentials)) {
4250
+ return true;
4251
+ }
3992
4252
  if (activeCredentials) {
3993
4253
  const confirmed = interactive ? await promptConfirm2({
3994
4254
  defaultValue: false,
3995
4255
  message: `You are already logged in as "${activeCredentials.name}".
3996
4256
  Logging out will delete these credentials and may interrupt other Zapier SDK or CLI sessions using them.
3997
- Log out and ${getActiveCredentialsAction(entryPoint)}?`
4257
+ Log out and continue signup?`
3998
4258
  }) : promptlessCredentialResetError(activeCredentials);
3999
4259
  if (!confirmed) {
4000
4260
  process.stderr.write(`${flowLabel} cancelled.
@@ -4209,12 +4469,14 @@ async function provisionAccountCredentials({
4209
4469
  async function runAccountAuth({
4210
4470
  imports,
4211
4471
  options,
4212
- entryPoint
4472
+ entryPoint,
4473
+ storedCredentialsMode = "choose",
4474
+ preserveExistingCredentials = false
4213
4475
  }) {
4214
4476
  if (options.callbackUrl !== void 0) {
4215
4477
  const { callbackUrl } = options;
4216
4478
  const pending = getPendingOauthFlow({ entryPoint });
4217
- const finishName = options.name !== void 0 ? validateCredentialsName(options.name) : void 0;
4479
+ const finishName = options.name === void 0 ? void 0 : validateCredentialsName(options.name);
4218
4480
  if (finishName !== void 0 && finishName !== pending.credentialName) {
4219
4481
  throw new ZapierCliValidationError(
4220
4482
  "Cannot change --name while completing a pending OAuth flow. Start a new non-interactive login with the desired --name."
@@ -4274,7 +4536,6 @@ async function runAccountAuth({
4274
4536
  });
4275
4537
  return;
4276
4538
  }
4277
- const timeoutSeconds = parseTimeoutSeconds(options.timeout);
4278
4539
  const interactive = !resolveNonInteractive(options);
4279
4540
  const resolvedCredentials = await imports.resolveCredentials();
4280
4541
  const pkceCredentials = toPkceCredentials(resolvedCredentials);
@@ -4283,8 +4544,34 @@ async function runAccountAuth({
4283
4544
  options: imports.sdkOptions,
4284
4545
  resolvedCredentials
4285
4546
  });
4286
- const providedName = options.name !== void 0 ? validateCredentialsName(options.name) : void 0;
4287
- if (providedName !== void 0) {
4547
+ const providedName = options.name === void 0 ? void 0 : validateCredentialsName(options.name);
4548
+ if (entryPoint === "login") {
4549
+ if (providedName !== void 0) {
4550
+ const matchingCredentials = findStoredCredentialsByName({
4551
+ name: providedName,
4552
+ baseUrl: credentialsBaseUrl2
4553
+ });
4554
+ if (matchingCredentials) {
4555
+ await switchCredentials({
4556
+ credentials: matchingCredentials,
4557
+ options,
4558
+ resolvedCredentials
4559
+ });
4560
+ return;
4561
+ }
4562
+ if (interactive && !await confirmNewCredentialsName(providedName)) {
4563
+ process.stderr.write("Login cancelled.\n");
4564
+ return;
4565
+ }
4566
+ } else if (interactive && storedCredentialsMode === "choose") {
4567
+ const selection = await chooseStoredLoginCredentialsAtBaseUrl({
4568
+ baseUrl: credentialsBaseUrl2,
4569
+ options,
4570
+ resolvedCredentials
4571
+ });
4572
+ if (selection === "switch") return;
4573
+ }
4574
+ } else if (providedName !== void 0) {
4288
4575
  const activeCredentials = getActiveCredentials({
4289
4576
  baseUrl: credentialsBaseUrl2
4290
4577
  });
@@ -4294,14 +4581,22 @@ async function runAccountAuth({
4294
4581
  );
4295
4582
  }
4296
4583
  }
4584
+ if (entryPoint === "login" && !interactive && providedName === void 0) {
4585
+ const activeCredentials = getActiveCredentials({
4586
+ baseUrl: credentialsBaseUrl2
4587
+ });
4588
+ if (activeCredentials) unnamedNonInteractiveLoginError(activeCredentials);
4589
+ }
4297
4590
  if (!await clearExistingAuthState({
4298
4591
  imports,
4299
4592
  baseUrl: credentialsBaseUrl2,
4300
4593
  interactive,
4301
- entryPoint
4594
+ entryPoint,
4595
+ preserveExistingCredentials
4302
4596
  })) {
4303
4597
  return;
4304
4598
  }
4599
+ const timeoutSeconds = parseTimeoutSeconds(options.timeout);
4305
4600
  const useApprovals = options.useApprovals === true;
4306
4601
  if (!interactive) {
4307
4602
  await startPendingOauthFlow({
@@ -4338,7 +4633,7 @@ async function runAccountAuth({
4338
4633
  }
4339
4634
  var LoginSchema = z.object({
4340
4635
  name: z.string().optional().describe(
4341
- "Name to identify these credentials (defaults to <email>@<hostname>). Provide this to set a custom name without the interactive prompt."
4636
+ "Activate stored credentials with this name. If none exist, create new credentials with this name; interactive login asks for confirmation first."
4342
4637
  ),
4343
4638
  timeout: z.string().optional().describe("Login timeout in seconds (default: 300)"),
4344
4639
  useApprovals: z.boolean().optional().describe(
@@ -6134,7 +6429,7 @@ function buildTemplateVariables({
6134
6429
  };
6135
6430
  }
6136
6431
  function cleanupProject({ projectDir }) {
6137
- console.log("\n" + chalk8.yellow("!") + " Cleaning up...");
6432
+ console.log("\n" + chalk9.yellow("!") + " Cleaning up...");
6138
6433
  rmSync(projectDir, { recursive: true, force: true });
6139
6434
  }
6140
6435
  async function withInterruptCleanup(cleanup, fn) {
@@ -6344,8 +6639,8 @@ function buildNextSteps({
6344
6639
  }
6345
6640
  function createConsoleDisplayHooks() {
6346
6641
  return {
6347
- onItemComplete: (message) => console.log(" " + chalk8.green("\u2713") + " " + chalk8.dim(message)),
6348
- onWarn: (message) => console.warn(chalk8.yellow("!") + " " + message),
6642
+ onItemComplete: (message) => console.log(" " + chalk9.green("\u2713") + " " + chalk9.dim(message)),
6643
+ onWarn: (message) => console.warn(chalk9.yellow("!") + " " + message),
6349
6644
  onStepStart: ({
6350
6645
  description,
6351
6646
  stepNumber,
@@ -6354,31 +6649,31 @@ function createConsoleDisplayHooks() {
6354
6649
  nonInteractive
6355
6650
  }) => {
6356
6651
  const progressMessage = `${description}...`;
6357
- const stepCounter = chalk8.dim(`${stepNumber}/${totalSteps}`);
6652
+ const stepCounter = chalk9.dim(`${stepNumber}/${totalSteps}`);
6358
6653
  if (nonInteractive) {
6359
6654
  console.log(
6360
- "\n" + chalk8.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
6655
+ "\n" + chalk9.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
6361
6656
  );
6362
6657
  } else {
6363
6658
  console.log(
6364
- chalk8.dim("\u2192") + " " + progressMessage + " " + stepCounter
6659
+ chalk9.dim("\u2192") + " " + progressMessage + " " + stepCounter
6365
6660
  );
6366
6661
  }
6367
6662
  if (command) {
6368
- console.log(" " + chalk8.cyan(`$ ${command}`));
6663
+ console.log(" " + chalk9.cyan(`$ ${command}`));
6369
6664
  }
6370
6665
  },
6371
6666
  onStepSuccess: ({ stepNumber, totalSteps }) => console.log(
6372
- "\n" + chalk8.green("\u2713") + " " + chalk8.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
6667
+ "\n" + chalk9.green("\u2713") + " " + chalk9.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
6373
6668
  ),
6374
6669
  onStepError: ({ description, command, err }) => {
6375
6670
  const detail = err instanceof Error && err.message ? `
6376
- ${chalk8.dim(err.message)}` : "";
6671
+ ${chalk9.dim(err.message)}` : "";
6377
6672
  const hint = command ? `
6378
- ${chalk8.dim("run manually:")} ${chalk8.cyan(`$ ${command}`)}` : "";
6673
+ ${chalk9.dim("run manually:")} ${chalk9.cyan(`$ ${command}`)}` : "";
6379
6674
  console.error(
6380
6675
  `
6381
- ${chalk8.red("\u2716")} ${chalk8.bold(description)}${chalk8.dim(" failed")}${detail}${hint}`
6676
+ ${chalk9.red("\u2716")} ${chalk9.bold(description)}${chalk9.dim(" failed")}${detail}${hint}`
6382
6677
  );
6383
6678
  }
6384
6679
  };
@@ -6390,22 +6685,22 @@ function displaySummaryAndNextSteps({
6390
6685
  packageManager
6391
6686
  }) {
6392
6687
  const formatStatus = (complete) => ({
6393
- icon: complete ? chalk8.green("\u2713") : chalk8.yellow("!"),
6394
- text: complete ? chalk8.green("Setup complete") : chalk8.yellow("Setup interrupted")
6688
+ icon: complete ? chalk9.green("\u2713") : chalk9.yellow("!"),
6689
+ text: complete ? chalk9.green("Setup complete") : chalk9.yellow("Setup interrupted")
6395
6690
  });
6396
- const formatNextStep = (step, i) => " " + chalk8.dim(`${i + 1}.`) + " " + chalk8.bold(step.description);
6397
- const formatCommand = (cmd) => " " + chalk8.cyan(`$ ${cmd}`);
6398
- const formatCompletedStep = (step) => " " + chalk8.green("\u2713") + " " + step.description;
6691
+ const formatNextStep = (step, i) => " " + chalk9.dim(`${i + 1}.`) + " " + chalk9.bold(step.description);
6692
+ const formatCommand = (cmd) => " " + chalk9.cyan(`$ ${cmd}`);
6693
+ const formatCompletedStep = (step) => " " + chalk9.green("\u2713") + " " + step.description;
6399
6694
  const { execCmd } = getPackageManagerCommands({ packageManager });
6400
6695
  const leftoverSteps = steps.filter(
6401
6696
  (s) => !completedSetupStepIds.includes(s.id)
6402
6697
  );
6403
6698
  const isComplete = leftoverSteps.length === 0;
6404
6699
  const status = formatStatus(isComplete);
6405
- console.log("\n" + chalk8.bold("\u276F Summary") + "\n");
6406
- console.log(" " + chalk8.dim("Project") + " " + chalk8.bold(projectName));
6700
+ console.log("\n" + chalk9.bold("\u276F Summary") + "\n");
6701
+ console.log(" " + chalk9.dim("Project") + " " + chalk9.bold(projectName));
6407
6702
  console.log(
6408
- " " + chalk8.dim("Status") + " " + status.icon + " " + status.text
6703
+ " " + chalk9.dim("Status") + " " + status.icon + " " + status.text
6409
6704
  );
6410
6705
  const completedSteps = steps.filter(
6411
6706
  (s) => completedSetupStepIds.includes(s.id)
@@ -6415,7 +6710,7 @@ function displaySummaryAndNextSteps({
6415
6710
  for (const step of completedSteps) console.log(formatCompletedStep(step));
6416
6711
  }
6417
6712
  const nextSteps = buildNextSteps({ projectName, leftoverSteps, execCmd });
6418
- console.log("\n" + chalk8.bold("\u276F Next Steps") + "\n");
6713
+ console.log("\n" + chalk9.bold("\u276F Next Steps") + "\n");
6419
6714
  nextSteps.forEach((step, i) => {
6420
6715
  console.log(formatNextStep(step, i));
6421
6716
  if (step.command) console.log(formatCommand(step.command));
@@ -6600,26 +6895,26 @@ function displayUpdateNotification(versionInfo, packageName) {
6600
6895
  if (versionInfo.isDeprecated) {
6601
6896
  console.error();
6602
6897
  console.error(
6603
- chalk8.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8.red(
6898
+ chalk9.red.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk9.red(
6604
6899
  ` - ${packageName} v${versionInfo.currentVersion} is deprecated.`
6605
6900
  )
6606
6901
  );
6607
6902
  if (versionInfo.deprecationMessage) {
6608
- console.error(chalk8.red(` ${versionInfo.deprecationMessage}`));
6903
+ console.error(chalk9.red(` ${versionInfo.deprecationMessage}`));
6609
6904
  }
6610
- console.error(chalk8.red(` Please update to the latest version.`));
6905
+ console.error(chalk9.red(` Please update to the latest version.`));
6611
6906
  console.error();
6612
6907
  }
6613
6908
  if (versionInfo.hasUpdate) {
6614
6909
  console.error();
6615
6910
  console.error(
6616
- chalk8.yellow.bold("\u{1F4E6} Update available!") + chalk8.yellow(
6911
+ chalk9.yellow.bold("\u{1F4E6} Update available!") + chalk9.yellow(
6617
6912
  ` ${packageName} v${versionInfo.currentVersion} \u2192 v${versionInfo.latestVersion}`
6618
6913
  )
6619
6914
  );
6620
6915
  console.error(
6621
- chalk8.yellow(
6622
- ` Run ${chalk8.bold(getUpdateCommand(packageName))} to update.`
6916
+ chalk9.yellow(
6917
+ ` Run ${chalk9.bold(getUpdateCommand(packageName))} to update.`
6623
6918
  )
6624
6919
  );
6625
6920
  console.error();
@@ -6660,7 +6955,7 @@ var boltFillRanks = new Map(
6660
6955
  );
6661
6956
  var STATUS_ROW_INDEX = Math.floor(boltRows.length / 2);
6662
6957
  function formatPhase({ label, detail }) {
6663
- return detail ? `${chalk8.bold(label)} ${chalk8.dim(detail)}` : chalk8.bold(label);
6958
+ return detail ? `${chalk9.bold(label)} ${chalk9.dim(detail)}` : chalk9.bold(label);
6664
6959
  }
6665
6960
  function formatLoaderFrame({
6666
6961
  phase,
@@ -6672,7 +6967,7 @@ function formatLoaderFrame({
6672
6967
  const cellIndex = rowIndex * row.length + columnIndex;
6673
6968
  const fillRank = boltFillRanks.get(cellIndex);
6674
6969
  const isFilled = fillRank !== void 0 && fillRank < fillStage;
6675
- return isFilled ? chalk8.bold.yellow(cell) : chalk8.dim.yellow(cell);
6970
+ return isFilled ? chalk9.bold.yellow(cell) : chalk9.dim.yellow(cell);
6676
6971
  }).join("");
6677
6972
  const status = rowIndex === STATUS_ROW_INDEX ? ` ${formatPhase(phase)}` : "";
6678
6973
  return `${bolt}${status}`;
@@ -6704,12 +6999,12 @@ async function runWithSetupLoader({
6704
6999
  const result = await promise;
6705
7000
  clearInterval(animationTimer);
6706
7001
  const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
6707
- loader.succeed(`${formatPhase(phase)} ${chalk8.dim(`${elapsedSeconds}s`)}`);
7002
+ loader.succeed(`${formatPhase(phase)} ${chalk9.dim(`${elapsedSeconds}s`)}`);
6708
7003
  return result;
6709
7004
  } catch (error) {
6710
7005
  clearInterval(animationTimer);
6711
7006
  const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
6712
- loader.fail(`${formatPhase(phase)} ${chalk8.dim(`${elapsedSeconds}s`)}`);
7007
+ loader.fail(`${formatPhase(phase)} ${chalk9.dim(`${elapsedSeconds}s`)}`);
6713
7008
  throw error;
6714
7009
  }
6715
7010
  }
@@ -7200,7 +7495,7 @@ async function runCommand({
7200
7495
  detail: commandLabel
7201
7496
  });
7202
7497
  }
7203
- console.log(chalk8.dim(commandLabel));
7498
+ console.log(chalk9.dim(commandLabel));
7204
7499
  return await execute;
7205
7500
  } catch (error) {
7206
7501
  const message = error instanceof Error ? error.message : String(error);
@@ -7306,6 +7601,14 @@ function createWizardContext({
7306
7601
  imports,
7307
7602
  createAnswer: () => createCliAnswer({ mode: "closed-list" }),
7308
7603
  setupController: createSetupController(),
7604
+ selectStoredLoginCredentials: () => chooseStoredLoginCredentials({ imports, options: {} }),
7605
+ authenticateNewAccount: ({ entryPoint, headless }) => runAccountAuth({
7606
+ imports,
7607
+ options: { headless },
7608
+ entryPoint,
7609
+ storedCredentialsMode: "fresh",
7610
+ preserveExistingCredentials: true
7611
+ }),
7309
7612
  checkForUpdates,
7310
7613
  openUrl: async (url) => {
7311
7614
  await open(url);
@@ -7339,6 +7642,14 @@ function isCredentialWriteError(error) {
7339
7642
  const message = error instanceof Error ? error.message : String(error);
7340
7643
  return /permission|sandbox|eacces|eperm/i.test(message);
7341
7644
  }
7645
+ async function confirmAuthentication(context) {
7646
+ const { data: profile } = await runWithSetupLoader({
7647
+ promise: context.imports.getProfile({}),
7648
+ label: "Confirming Zapier account"
7649
+ });
7650
+ context.accountEmail = profile.email;
7651
+ console.log(`Authenticated as ${profile.email}.`);
7652
+ }
7342
7653
  async function authenticate(context) {
7343
7654
  const activeProfile = await runWithSetupLoader({
7344
7655
  promise: context.imports.getProfile({}).then(({ data }) => data).catch((error) => {
@@ -7347,7 +7658,12 @@ async function authenticate(context) {
7347
7658
  }),
7348
7659
  label: "Checking Zapier authentication"
7349
7660
  });
7350
- if (activeProfile) {
7661
+ const storedCredentialsSelection = await context.selectStoredLoginCredentials();
7662
+ if (storedCredentialsSelection === "switch") {
7663
+ await confirmAuthentication(context);
7664
+ return;
7665
+ }
7666
+ if (storedCredentialsSelection === "none" && activeProfile) {
7351
7667
  const shouldLogout = await resolveSetupConfirm({
7352
7668
  answer: context.createAnswer(),
7353
7669
  controller: context.setupController,
@@ -7388,10 +7704,14 @@ Log out and use a different account?`,
7388
7704
  ]
7389
7705
  });
7390
7706
  const headless = environment === "headless";
7391
- const runAuth = flow === "login" ? context.imports.login : context.imports.signup;
7392
7707
  printAuthCommand({ context, flow, headless });
7393
7708
  try {
7394
- await runAuth({ headless });
7709
+ if (storedCredentialsSelection === "create") {
7710
+ await context.authenticateNewAccount({ entryPoint: flow, headless });
7711
+ } else {
7712
+ const runAuth = flow === "login" ? context.imports.login : context.imports.signup;
7713
+ await runAuth({ headless });
7714
+ }
7395
7715
  } catch (error) {
7396
7716
  if (isCredentialWriteError(error)) {
7397
7717
  console.error(
@@ -7400,12 +7720,7 @@ Log out and use a different account?`,
7400
7720
  }
7401
7721
  throw error;
7402
7722
  }
7403
- const { data: profile } = await runWithSetupLoader({
7404
- promise: context.imports.getProfile({}),
7405
- label: "Confirming Zapier account"
7406
- });
7407
- context.accountEmail = profile.email;
7408
- console.log(`Authenticated as ${profile.email}.`);
7723
+ await confirmAuthentication(context);
7409
7724
  }
7410
7725
  var agentLabels = {
7411
7726
  claude: "Claude Code",
@@ -7447,7 +7762,7 @@ function printAgentPrompt({
7447
7762
  message
7448
7763
  }) {
7449
7764
  console.log();
7450
- console.log(chalk8.bgYellow.black.bold(message));
7765
+ console.log(chalk9.bgYellow.black.bold(message));
7451
7766
  console.log();
7452
7767
  console.log(buildAgentPrompt({ context }));
7453
7768
  }
@@ -7732,7 +8047,7 @@ var MINIMUM_MESSAGE_WIDTH = 20;
7732
8047
  var MAXIMUM_MESSAGE_WIDTH = 88;
7733
8048
  function showPhase({ number, title }) {
7734
8049
  console.log();
7735
- console.log(chalk8.bgCyan.black.bold(` ${number}/${PHASE_COUNT} ${title} `));
8050
+ console.log(chalk9.bgCyan.black.bold(` ${number}/${PHASE_COUNT} ${title} `));
7736
8051
  }
7737
8052
  function printWrapped(text) {
7738
8053
  const width = Math.max(
@@ -7746,7 +8061,7 @@ function printWrapped(text) {
7746
8061
  }
7747
8062
  function showReadyMessage() {
7748
8063
  console.log();
7749
- console.log(chalk8.bgGreen.black.bold(" \u2713 Zapier SDK setup complete "));
8064
+ console.log(chalk9.bgGreen.black.bold(" \u2713 Zapier SDK setup complete "));
7750
8065
  console.log();
7751
8066
  printWrapped(
7752
8067
  "Use active Zapier connections to access 9,000+ app connectors without managing each app's OAuth, token refresh, or retries."
@@ -7758,7 +8073,7 @@ function showReadyMessage() {
7758
8073
  console.log();
7759
8074
  }
7760
8075
  async function runWizard(context) {
7761
- console.log(chalk8.bold("Zapier SDK setup"));
8076
+ console.log(chalk9.bold("Zapier SDK setup"));
7762
8077
  showPhase({ number: 1, title: "Project directory" });
7763
8078
  await chooseDirectory(context);
7764
8079
  showPhase({ number: 2, title: "Node.js" });
@@ -7773,7 +8088,7 @@ async function runWizard(context) {
7773
8088
  showPhase({ number: 6, title: "Slack demo" });
7774
8089
  await offerSlackTest(context);
7775
8090
  showReadyMessage();
7776
- console.log(chalk8.bgCyan.black.bold(" Next steps "));
8091
+ console.log(chalk9.bgCyan.black.bold(" Next steps "));
7777
8092
  await openAgentHandoff(context);
7778
8093
  }
7779
8094
 
@@ -7788,7 +8103,11 @@ var setupImports = [
7788
8103
  listConnectionsRef2,
7789
8104
  loginRef,
7790
8105
  logoutRef,
7791
- signupRef
8106
+ signupRef,
8107
+ apiPluginRef,
8108
+ resolveCredentialsPluginRef,
8109
+ eventEmissionPluginRef,
8110
+ sdkOptionsPluginRef
7792
8111
  ];
7793
8112
  var setupPlugin = defineMethod({
7794
8113
  name: "setup",
@@ -7819,13 +8138,13 @@ function createInteractiveCallback() {
7819
8138
  const attrs = message.message_attributes;
7820
8139
  console.log(
7821
8140
  `
7822
- ${chalk8.bold(`Message #${messageNumber}`)} ${chalk8.dim(message.id)} ${chalk8.dim(`(lease #${attrs.lease_count})`)}`
8141
+ ${chalk9.bold(`Message #${messageNumber}`)} ${chalk9.dim(message.id)} ${chalk9.dim(`(lease #${attrs.lease_count})`)}`
7823
8142
  );
7824
8143
  if (attrs.error_message) {
7825
- console.log(chalk8.yellow(` upstream error: ${attrs.error_message}`));
8144
+ console.log(chalk9.yellow(` upstream error: ${attrs.error_message}`));
7826
8145
  }
7827
8146
  if (attrs.possible_duplicate_data) {
7828
- console.log(chalk8.yellow(" possible duplicate data"));
8147
+ console.log(chalk9.yellow(" possible duplicate data"));
7829
8148
  }
7830
8149
  while (true) {
7831
8150
  let action;
@@ -7855,7 +8174,7 @@ ${chalk8.bold(`Message #${messageNumber}`)} ${chalk8.dim(message.id)} ${chalk8.d
7855
8174
  throw error;
7856
8175
  }
7857
8176
  if (action === "view") {
7858
- console.log(chalk8.dim(JSON.stringify(message.payload, null, 2)));
8177
+ console.log(chalk9.dim(JSON.stringify(message.payload, null, 2)));
7859
8178
  continue;
7860
8179
  }
7861
8180
  if (action === "ack") {
@@ -7958,7 +8277,7 @@ function describeReason(reason) {
7958
8277
  }
7959
8278
  function printDrainError(reason, message) {
7960
8279
  console.error(
7961
- chalk8.red(`Error processing ${message.id}: ${describeReason(reason)}`)
8280
+ chalk9.red(`Error processing ${message.id}: ${describeReason(reason)}`)
7962
8281
  );
7963
8282
  }
7964
8283
  function printDrainSummary(counts) {
@@ -7968,7 +8287,7 @@ function printDrainSummary(counts) {
7968
8287
  if (skipped > 0) parts.push(`${skipped} skipped`);
7969
8288
  parts.push(`${counts.rejected} rejected`);
7970
8289
  console.log(
7971
- chalk8.dim(
8290
+ chalk9.dim(
7972
8291
  `
7973
8292
  Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
7974
8293
  )
@@ -7976,7 +8295,7 @@ Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
7976
8295
  }
7977
8296
  function warnInteractiveContinueOnErrorOverride() {
7978
8297
  console.warn(
7979
- chalk8.yellow(
8298
+ chalk9.yellow(
7980
8299
  'Note: continueOnError=false is overridden to true in interactive mode (the "Skip (let lease expire)" choice would otherwise terminate the drain).'
7981
8300
  )
7982
8301
  );
@@ -8302,7 +8621,7 @@ function renderDeprecationNotices() {
8302
8621
  console.error();
8303
8622
  for (const message of messages) {
8304
8623
  for (const line of buildBoxLines(message)) {
8305
- console.error(chalk8.red.bold(line));
8624
+ console.error(chalk9.red.bold(line));
8306
8625
  }
8307
8626
  console.error();
8308
8627
  }
@@ -8323,7 +8642,7 @@ function buildBoxLines(message) {
8323
8642
  // package.json with { type: 'json' }
8324
8643
  var package_default2 = {
8325
8644
  name: "@zapier/zapier-sdk-cli",
8326
- version: "0.77.8"};
8645
+ version: "0.78.0"};
8327
8646
 
8328
8647
  // src/sdk.ts
8329
8648
  var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
@@ -8334,9 +8653,9 @@ var cliCoreOptions = {
8334
8653
  warnedDeprecatedMethods.add(methodName);
8335
8654
  console.warn();
8336
8655
  console.warn(
8337
- chalk8.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk8.yellow(` - \`${toKebabCase(methodName)}\` is deprecated.`)
8656
+ chalk9.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk9.yellow(` - \`${toKebabCase(methodName)}\` is deprecated.`)
8338
8657
  );
8339
- console.warn(chalk8.yellow(` ${deprecation.message}`));
8658
+ console.warn(chalk9.yellow(` ${deprecation.message}`));
8340
8659
  console.warn();
8341
8660
  }
8342
8661
  };
@@ -8609,11 +8928,11 @@ function buildFrameLines(state, frameIndex) {
8609
8928
  const bodyWidth = width - 2;
8610
8929
  const bodyTextWidth = innerWidth - 2;
8611
8930
  const content = [];
8612
- content.push(chalk8.bold.cyan("Approval review"));
8931
+ content.push(chalk9.bold.cyan("Approval review"));
8613
8932
  content.push("");
8614
8933
  if (!state.verdict) {
8615
8934
  content.push(
8616
- chalk8.yellow(`${SPINNER_FRAMES[frameIndex]} Checking approval...`)
8935
+ chalk9.yellow(`${SPINNER_FRAMES[frameIndex]} Checking approval...`)
8617
8936
  );
8618
8937
  }
8619
8938
  const recentMessages = state.messages.slice(-5);
@@ -8624,13 +8943,13 @@ function buildFrameLines(state, frameIndex) {
8624
8943
  "\n"
8625
8944
  );
8626
8945
  segments.forEach((segment, segmentIndex) => {
8627
- const prefix = segmentIndex === 0 ? chalk8.cyan("> ") : " ";
8628
- content.push(`${prefix}${dimmed ? chalk8.dim(segment) : segment}`);
8946
+ const prefix = segmentIndex === 0 ? chalk9.cyan("> ") : " ";
8947
+ content.push(`${prefix}${dimmed ? chalk9.dim(segment) : segment}`);
8629
8948
  });
8630
8949
  });
8631
8950
  if (state.streamError) {
8632
8951
  if (hasMessages || !state.verdict) content.push("");
8633
- content.push(chalk8.bold.red("Approval stream error"));
8952
+ content.push(chalk9.bold.red("Approval stream error"));
8634
8953
  for (const segment of wrapAnsi4(state.streamError, bodyTextWidth, {
8635
8954
  hard: true
8636
8955
  }).split("\n")) {
@@ -8640,7 +8959,7 @@ function buildFrameLines(state, frameIndex) {
8640
8959
  if (state.verdict) {
8641
8960
  if (hasMessages || state.streamError) content.push("");
8642
8961
  content.push(
8643
- chalk8.bold.green(`${state.verdict.icon} ${state.verdict.label}`)
8962
+ chalk9.bold.green(`${state.verdict.icon} ${state.verdict.label}`)
8644
8963
  );
8645
8964
  if (state.verdict.reason) {
8646
8965
  for (const segment of wrapAnsi4(state.verdict.reason, bodyTextWidth, {
@@ -8652,12 +8971,12 @@ function buildFrameLines(state, frameIndex) {
8652
8971
  }
8653
8972
  const pad = (line) => {
8654
8973
  const padding = " ".repeat(Math.max(0, innerWidth - displayWidth(line)));
8655
- return `${chalk8.cyan("\u2502")} ${line}${padding} ${chalk8.cyan("\u2502")}`;
8974
+ return `${chalk9.cyan("\u2502")} ${line}${padding} ${chalk9.cyan("\u2502")}`;
8656
8975
  };
8657
8976
  return [
8658
- chalk8.cyan(`\u256D${"\u2500".repeat(bodyWidth)}\u256E`),
8977
+ chalk9.cyan(`\u256D${"\u2500".repeat(bodyWidth)}\u256E`),
8659
8978
  ...content.map(pad),
8660
- chalk8.cyan(`\u2570${"\u2500".repeat(bodyWidth)}\u256F`)
8979
+ chalk9.cyan(`\u2570${"\u2500".repeat(bodyWidth)}\u256F`)
8661
8980
  ];
8662
8981
  }
8663
8982
  function createApprovalProgressRenderer({