@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.
@@ -11,11 +11,12 @@ var zapierSdk = require('@zapier/zapier-sdk');
11
11
  var zod = require('zod');
12
12
  var experimental = require('@zapier/zapier-sdk/experimental');
13
13
  var os = require('os');
14
- var inquirer3 = require('inquirer');
14
+ var inquirer4 = require('inquirer');
15
+ var chalk5 = require('chalk');
16
+ var core = require('@inquirer/core');
15
17
  var express = require('express');
16
18
  var promises$1 = require('readline/promises');
17
19
  var open = require('open');
18
- var chalk3 = require('chalk');
19
20
  var ora = require('ora');
20
21
  var pkceChallenge = require('pkce-challenge');
21
22
  var zapierSdkMcp = require('@zapier/zapier-sdk-mcp');
@@ -26,7 +27,6 @@ require('is-installed-globally');
26
27
  var child_process = require('child_process');
27
28
  var Handlebars = require('handlebars');
28
29
  var url = require('url');
29
- var core = require('@inquirer/core');
30
30
  var packageJsonLib = require('package-json');
31
31
  var semver = require('semver');
32
32
  var crossSpawn = require('cross-spawn');
@@ -60,10 +60,10 @@ var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
60
60
  var crypto__default = /*#__PURE__*/_interopDefault(crypto);
61
61
  var path__namespace = /*#__PURE__*/_interopNamespace(path);
62
62
  var lockfile__namespace = /*#__PURE__*/_interopNamespace(lockfile);
63
- var inquirer3__default = /*#__PURE__*/_interopDefault(inquirer3);
63
+ var inquirer4__default = /*#__PURE__*/_interopDefault(inquirer4);
64
+ var chalk5__default = /*#__PURE__*/_interopDefault(chalk5);
64
65
  var express__default = /*#__PURE__*/_interopDefault(express);
65
66
  var open__default = /*#__PURE__*/_interopDefault(open);
66
- var chalk3__default = /*#__PURE__*/_interopDefault(chalk3);
67
67
  var ora__default = /*#__PURE__*/_interopDefault(ora);
68
68
  var pkceChallenge__default = /*#__PURE__*/_interopDefault(pkceChallenge);
69
69
  var ts__namespace = /*#__PURE__*/_interopNamespace(ts);
@@ -406,6 +406,10 @@ function getActiveCredentials(options) {
406
406
  if (!name) return void 0;
407
407
  return findEntry(readRegistry(), name, normalizeBaseUrl(options?.baseUrl));
408
408
  }
409
+ function listStoredCredentials(options) {
410
+ const baseUrl = normalizeBaseUrl(options?.baseUrl);
411
+ return readRegistry().filter((entry) => entry.baseUrl === baseUrl).sort((left, right) => right.createdAt - left.createdAt);
412
+ }
409
413
  var MAX_CREDENTIAL_NAME_ATTEMPTS = 500;
410
414
  function firstAvailableCredentialName({
411
415
  baseName,
@@ -510,6 +514,29 @@ async function getStoredClientCredentials(options) {
510
514
  scope: [...entry.scopes].sort().join(" ")
511
515
  };
512
516
  }
517
+ async function activateStoredCredentials({
518
+ name,
519
+ baseUrl
520
+ }) {
521
+ const resolvedBaseUrl = normalizeBaseUrl(baseUrl);
522
+ const entry = findEntry(readRegistry(), name, resolvedBaseUrl);
523
+ if (!entry) {
524
+ throw new ZapierCliValidationError(
525
+ `No stored credentials named "${name}" were found.`
526
+ );
527
+ }
528
+ const credentials = await getStoredClientCredentials({
529
+ name,
530
+ baseUrl: resolvedBaseUrl
531
+ });
532
+ if (!credentials) {
533
+ throw new ZapierCliValidationError(
534
+ `Stored credentials "${name}" are missing from the system keychain. Add a new account to recreate them.`
535
+ );
536
+ }
537
+ getConfig().set(CREDENTIALS_KEY, name);
538
+ return entry;
539
+ }
513
540
  function deleteRegistryEntry(registry, name, baseUrl) {
514
541
  const idx = registry.findIndex(
515
542
  (e) => e.name === name && e.baseUrl === baseUrl
@@ -1101,6 +1128,362 @@ async function setupClientCredentials({
1101
1128
  }
1102
1129
  return { clientId };
1103
1130
  }
1131
+ function isSelectable(item) {
1132
+ return !core.Separator.isSeparator(item) && !item.disabled;
1133
+ }
1134
+ function normalizeChoices(choices) {
1135
+ return choices.map((choice) => {
1136
+ if (core.Separator.isSeparator(choice)) return choice;
1137
+ const name = choice.name ?? String(choice.value);
1138
+ return {
1139
+ value: choice.value,
1140
+ name,
1141
+ short: choice.short ?? name,
1142
+ disabled: choice.disabled ?? false
1143
+ };
1144
+ });
1145
+ }
1146
+ var theme = core.makeTheme({
1147
+ icon: { cursor: "\u276F" },
1148
+ style: {
1149
+ disabled: (text) => chalk5__default.default.dim(`- ${text}`),
1150
+ searchTerm: (text) => chalk5__default.default.cyan(text),
1151
+ keysHelpTip: (keys) => keys.map(([key, action]) => `${chalk5__default.default.bold(key)} ${chalk5__default.default.dim(action)}`).join(chalk5__default.default.dim(" \u2022 "))
1152
+ }
1153
+ });
1154
+ var searchSelect = core.createPrompt(
1155
+ (config2, done) => {
1156
+ const { pageSize = 7 } = config2;
1157
+ const [status, setStatus] = core.useState(
1158
+ "loading"
1159
+ );
1160
+ const [searchTerm, setSearchTerm] = core.useState("");
1161
+ const [searchResults, setSearchResults] = core.useState([]);
1162
+ const [searchError, setSearchError] = core.useState();
1163
+ const prefix = core.usePrefix({ status, theme });
1164
+ const bounds = core.useMemo(() => {
1165
+ const first = searchResults.findIndex(isSelectable);
1166
+ let last = -1;
1167
+ for (let i = searchResults.length - 1; i >= 0; i--) {
1168
+ if (isSelectable(searchResults[i])) {
1169
+ last = i;
1170
+ break;
1171
+ }
1172
+ }
1173
+ return { first, last };
1174
+ }, [searchResults]);
1175
+ const defaultActive = core.useMemo(() => {
1176
+ const requested = searchTerm === "" ? config2.initialActive : config2.initialActiveForTerm?.({ term: searchTerm });
1177
+ if (requested !== void 0 && requested >= 0 && requested < searchResults.length && isSelectable(searchResults[requested])) {
1178
+ return requested;
1179
+ }
1180
+ return bounds.first;
1181
+ }, [searchResults, searchTerm, bounds.first]);
1182
+ const [active = defaultActive, setActive] = core.useState();
1183
+ core.useEffect(() => {
1184
+ const controller = new AbortController();
1185
+ setStatus("loading");
1186
+ setSearchError(void 0);
1187
+ const fetchResults = async () => {
1188
+ try {
1189
+ const results = await config2.source(searchTerm || void 0);
1190
+ if (!controller.signal.aborted) {
1191
+ setActive(void 0);
1192
+ setSearchError(void 0);
1193
+ setSearchResults(normalizeChoices(results));
1194
+ setStatus("idle");
1195
+ }
1196
+ } catch (error2) {
1197
+ if (!controller.signal.aborted && error2 instanceof Error) {
1198
+ setSearchError(error2.message);
1199
+ }
1200
+ }
1201
+ };
1202
+ void fetchResults();
1203
+ return () => {
1204
+ controller.abort();
1205
+ };
1206
+ }, [searchTerm]);
1207
+ const selectedChoice = searchResults[active];
1208
+ core.useKeypress((key, rl) => {
1209
+ if (core.isEnterKey(key)) {
1210
+ if (selectedChoice && isSelectable(selectedChoice)) {
1211
+ setStatus("done");
1212
+ done(selectedChoice.value);
1213
+ } else {
1214
+ rl.write(searchTerm);
1215
+ }
1216
+ } else if (core.isTabKey(key) && selectedChoice && isSelectable(selectedChoice)) {
1217
+ rl.clearLine(0);
1218
+ rl.write(selectedChoice.name);
1219
+ setSearchTerm(selectedChoice.name);
1220
+ } else if (status !== "loading" && (core.isUpKey(key) || core.isDownKey(key))) {
1221
+ rl.clearLine(0);
1222
+ if (core.isUpKey(key) && active !== bounds.first || core.isDownKey(key) && active !== bounds.last) {
1223
+ const offset = core.isUpKey(key) ? -1 : 1;
1224
+ let next = active;
1225
+ do {
1226
+ next = (next + offset + searchResults.length) % searchResults.length;
1227
+ } while (!isSelectable(searchResults[next]));
1228
+ setActive(next);
1229
+ }
1230
+ } else {
1231
+ setSearchTerm(rl.line);
1232
+ }
1233
+ });
1234
+ const page = core.usePagination({
1235
+ items: searchResults,
1236
+ active,
1237
+ renderItem({ item, isActive }) {
1238
+ if (core.Separator.isSeparator(item)) {
1239
+ return ` ${item.separator}`;
1240
+ }
1241
+ if (item.disabled) {
1242
+ const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
1243
+ return theme.style.disabled(`${item.name} ${disabledLabel}`);
1244
+ }
1245
+ const color = isActive ? theme.style.highlight : (x) => x;
1246
+ const cursor = isActive ? theme.icon.cursor : ` `;
1247
+ return color(`${cursor} ${item.name}`);
1248
+ },
1249
+ pageSize,
1250
+ loop: false
1251
+ });
1252
+ const message = theme.style.message(config2.message, status);
1253
+ if (status === "done" && selectedChoice && isSelectable(selectedChoice)) {
1254
+ return [prefix, message, theme.style.answer(selectedChoice.short)].filter(Boolean).join(" ").trimEnd();
1255
+ }
1256
+ const searchStr = theme.style.searchTerm(searchTerm);
1257
+ const helpTip = theme.style.keysHelpTip([
1258
+ ["\u2191\u2193", "navigate"],
1259
+ ["\u23CE", "select"]
1260
+ ]);
1261
+ let error;
1262
+ if (searchError) {
1263
+ error = theme.style.error(searchError);
1264
+ } else if (searchResults.length === 0 && searchTerm !== "" && status === "idle") {
1265
+ error = theme.style.error("No results found");
1266
+ }
1267
+ const header = [prefix, message, searchStr].filter(Boolean).join(" ").trimEnd();
1268
+ const body = [error ?? page, " ", helpTip].filter(Boolean).join("\n").trimEnd();
1269
+ return [header, body];
1270
+ }
1271
+ );
1272
+
1273
+ // src/utils/auth/credentials-picker.ts
1274
+ function isSameCredentials(left, right) {
1275
+ return left.name === right.name && left.baseUrl === right.baseUrl;
1276
+ }
1277
+ function createdAtIso(credentials) {
1278
+ return new Date(credentials.createdAt).toISOString();
1279
+ }
1280
+ function searchableFields(credentials) {
1281
+ return [
1282
+ { text: credentials.name.toLowerCase(), weight: 0 },
1283
+ { text: credentials.clientId.toLowerCase(), weight: 1e3 },
1284
+ ...credentials.scopes.map((scope) => ({
1285
+ text: scope.toLowerCase(),
1286
+ weight: 2e3
1287
+ })),
1288
+ {
1289
+ text: createdAtIso(credentials).slice(0, 10).toLowerCase(),
1290
+ weight: 3e3
1291
+ }
1292
+ ];
1293
+ }
1294
+ function textMatchScore(text, query) {
1295
+ if (text === query) return 0;
1296
+ if (text.startsWith(query)) return 100 + text.length - query.length;
1297
+ const index = text.indexOf(query);
1298
+ if (index === -1) return void 0;
1299
+ return 200 + text.length - query.length;
1300
+ }
1301
+ function closestFieldScore(fields, query) {
1302
+ let closest;
1303
+ for (const field of fields) {
1304
+ const textScore = textMatchScore(field.text, query);
1305
+ if (textScore === void 0) continue;
1306
+ const score = field.weight + textScore;
1307
+ closest = closest === void 0 ? score : Math.min(closest, score);
1308
+ }
1309
+ return closest;
1310
+ }
1311
+ function searchScore(credentials, term) {
1312
+ const query = term.trim().toLowerCase();
1313
+ const tokens = query.split(/\s+/).filter(Boolean);
1314
+ const fields = searchableFields(credentials);
1315
+ let tokenScore = 0;
1316
+ for (const token of tokens) {
1317
+ const score = closestFieldScore(fields, token);
1318
+ if (score === void 0) return void 0;
1319
+ tokenScore += score;
1320
+ }
1321
+ const phraseScore = closestFieldScore(fields, query);
1322
+ return phraseScore === void 0 ? 1e4 + tokenScore : phraseScore;
1323
+ }
1324
+ function formatCredentialsChoice({
1325
+ credentials,
1326
+ current
1327
+ }) {
1328
+ const currentLabel = current ? chalk5__default.default.cyan(" (current)") : "";
1329
+ const details = [
1330
+ credentials.clientId,
1331
+ credentials.scopes.join(", "),
1332
+ `created ${createdAtIso(credentials).slice(0, 10)}`
1333
+ ].join(" \xB7 ");
1334
+ return {
1335
+ name: `${credentials.name}${currentLabel} ${chalk5__default.default.dim(`\xB7 ${details}`)}`,
1336
+ short: credentials.name,
1337
+ value: { action: "switch", credentials }
1338
+ };
1339
+ }
1340
+ function buildCredentialsChoices({
1341
+ credentials,
1342
+ activeCredentials,
1343
+ term = ""
1344
+ }) {
1345
+ const sortedCredentials = [...credentials].sort(
1346
+ (left, right) => right.createdAt - left.createdAt
1347
+ );
1348
+ const current = activeCredentials ? sortedCredentials.find(
1349
+ (entry) => isSameCredentials(entry, activeCredentials)
1350
+ ) : void 0;
1351
+ const rankedCredentials = term ? sortedCredentials.map((credentials2) => ({
1352
+ credentials: credentials2,
1353
+ score: searchScore(credentials2, term)
1354
+ })).filter(
1355
+ (result) => result.score !== void 0
1356
+ ).sort((left, right) => left.score - right.score).map(({ credentials: credentials2 }) => credentials2) : [
1357
+ ...current ? [current] : [],
1358
+ ...sortedCredentials.filter((credentials2) => credentials2 !== current)
1359
+ ];
1360
+ return [
1361
+ {
1362
+ name: "+ Add a new account",
1363
+ short: "Add a new account",
1364
+ value: { action: "create" }
1365
+ },
1366
+ ...rankedCredentials.map(
1367
+ (credentials2) => formatCredentialsChoice({
1368
+ credentials: credentials2,
1369
+ current: credentials2 === current
1370
+ })
1371
+ )
1372
+ ];
1373
+ }
1374
+ async function promptForCredentials({
1375
+ credentials,
1376
+ activeCredentials
1377
+ }) {
1378
+ return searchSelect({
1379
+ message: "Select credentials or add a new account:",
1380
+ source: (term) => buildCredentialsChoices({
1381
+ credentials,
1382
+ activeCredentials,
1383
+ term
1384
+ }),
1385
+ initialActive: credentials.length > 0 ? 1 : 0,
1386
+ initialActiveForTerm: () => 1
1387
+ });
1388
+ }
1389
+
1390
+ // src/utils/auth/stored-login-credentials.ts
1391
+ function authFlowOnlyOptions(options) {
1392
+ return [
1393
+ ...options.timeout === void 0 ? [] : ["--timeout"],
1394
+ ...options.useApprovals === true ? ["--use-approvals"] : [],
1395
+ ...options.headless === true ? ["--headless"] : []
1396
+ ];
1397
+ }
1398
+ function assertCanSwitchCredentials({
1399
+ credentials,
1400
+ options,
1401
+ resolvedCredentials
1402
+ }) {
1403
+ if (resolvedCredentials !== void 0) {
1404
+ throw new ZapierCliValidationError(
1405
+ "Cannot switch stored credentials while credentials are configured through SDK options or environment variables. Remove those credentials before switching accounts."
1406
+ );
1407
+ }
1408
+ const incompatibleOptions = authFlowOnlyOptions(options);
1409
+ if (incompatibleOptions.length === 0) return;
1410
+ throw new ZapierCliValidationError(
1411
+ `Cannot switch to stored credentials "${credentials.name}" while using ${incompatibleOptions.join(
1412
+ ", "
1413
+ )}. These options only apply when logging in to a new account.`
1414
+ );
1415
+ }
1416
+ function findStoredCredentialsByName({
1417
+ name,
1418
+ baseUrl
1419
+ }) {
1420
+ return listStoredCredentials({ baseUrl }).find(
1421
+ (credentials) => credentials.name === name
1422
+ );
1423
+ }
1424
+ async function switchCredentials({
1425
+ credentials,
1426
+ options,
1427
+ resolvedCredentials
1428
+ }) {
1429
+ assertCanSwitchCredentials({ credentials, options, resolvedCredentials });
1430
+ await activateStoredCredentials({
1431
+ name: credentials.name,
1432
+ baseUrl: credentials.baseUrl
1433
+ });
1434
+ process.stderr.write(
1435
+ `\u2705 Credentials "${credentials.name}" are now active.
1436
+ `
1437
+ );
1438
+ }
1439
+ async function chooseStoredLoginCredentialsAtBaseUrl({
1440
+ baseUrl,
1441
+ options,
1442
+ resolvedCredentials
1443
+ }) {
1444
+ if (resolvedCredentials !== void 0 || authFlowOnlyOptions(options).length > 0) {
1445
+ return "none";
1446
+ }
1447
+ const storedCredentials = listStoredCredentials({ baseUrl });
1448
+ if (storedCredentials.length === 0) return "none";
1449
+ const selection = await promptForCredentials({
1450
+ credentials: storedCredentials,
1451
+ activeCredentials: getActiveCredentials({ baseUrl })
1452
+ });
1453
+ if (selection.action === "create") return "create";
1454
+ await switchCredentials({
1455
+ credentials: selection.credentials,
1456
+ options,
1457
+ resolvedCredentials
1458
+ });
1459
+ return "switch";
1460
+ }
1461
+ async function chooseStoredLoginCredentials({
1462
+ imports,
1463
+ options
1464
+ }) {
1465
+ const resolvedCredentials = await imports.resolveCredentials();
1466
+ const credentialsBaseUrl = await resolveCredentialsBaseUrl({
1467
+ options: imports.sdkOptions,
1468
+ resolvedCredentials
1469
+ });
1470
+ return chooseStoredLoginCredentialsAtBaseUrl({
1471
+ baseUrl: credentialsBaseUrl,
1472
+ options,
1473
+ resolvedCredentials
1474
+ });
1475
+ }
1476
+ async function confirmNewCredentialsName(name) {
1477
+ const { confirmed } = await inquirer4__default.default.prompt([
1478
+ {
1479
+ type: "confirm",
1480
+ name: "confirmed",
1481
+ default: false,
1482
+ message: `No stored credentials named "${name}" were found. Continue with a new account and save it as "${name}"?`
1483
+ }
1484
+ ]);
1485
+ return confirmed;
1486
+ }
1104
1487
 
1105
1488
  // src/utils/constants.ts
1106
1489
  var LOGIN_PORTS = [49505, 50575, 52804, 55981, 61010, 63851];
@@ -1125,20 +1508,20 @@ var getCallablePromise = () => {
1125
1508
  var getCallablePromise_default = getCallablePromise;
1126
1509
  var log = {
1127
1510
  info: (message, ...args) => {
1128
- console.error(chalk3__default.default.blue("\u2139"), message, ...args);
1511
+ console.error(chalk5__default.default.blue("\u2139"), message, ...args);
1129
1512
  },
1130
1513
  error: (message, ...args) => {
1131
- console.error(chalk3__default.default.red("\u2716"), message, ...args);
1514
+ console.error(chalk5__default.default.red("\u2716"), message, ...args);
1132
1515
  },
1133
1516
  success: (message, ...args) => {
1134
- console.error(chalk3__default.default.green("\u2713"), message, ...args);
1517
+ console.error(chalk5__default.default.green("\u2713"), message, ...args);
1135
1518
  },
1136
1519
  warn: (message, ...args) => {
1137
- console.error(chalk3__default.default.yellow("\u26A0"), message, ...args);
1520
+ console.error(chalk5__default.default.yellow("\u26A0"), message, ...args);
1138
1521
  },
1139
1522
  debug: (message, ...args) => {
1140
1523
  if (process.env.DEBUG === "true" || process.argv.includes("--debug")) {
1141
- console.error(chalk3__default.default.gray("\u{1F41B}"), message, ...args);
1524
+ console.error(chalk5__default.default.gray("\u{1F41B}"), message, ...args);
1142
1525
  }
1143
1526
  }
1144
1527
  };
@@ -1985,9 +2368,6 @@ var HEADLESS_SIGNUP_RECOVERY_MESSAGE = "Restart `zapier-sdk signup --headless` t
1985
2368
  function getEntryPointLabel(entryPoint) {
1986
2369
  return entryPoint === "signup" ? "Signup" : "Login";
1987
2370
  }
1988
- function getActiveCredentialsAction(entryPoint) {
1989
- return entryPoint === "signup" ? "continue signup" : "log in again";
1990
- }
1991
2371
  function getCredentialsPromptMessage(entryPoint) {
1992
2372
  return entryPoint === "signup" ? "Enter a name to identify these credentials:" : "Enter a name to identify them:";
1993
2373
  }
@@ -2002,11 +2382,24 @@ function validateCredentialsName(name) {
2002
2382
  if (!trimmedName) throw new ZapierCliValidationError("Name cannot be empty");
2003
2383
  return trimmedName;
2004
2384
  }
2385
+ function validateNewCredentialsName({
2386
+ name,
2387
+ baseUrl
2388
+ }) {
2389
+ const validatedName = validateCredentialsName(name);
2390
+ if (credentialNameExists({ name: validatedName, baseUrl })) {
2391
+ throw new ZapierCliValidationError(
2392
+ `Credentials named "${validatedName}" already exist. Choose a different name.`
2393
+ );
2394
+ }
2395
+ return validatedName;
2396
+ }
2005
2397
  async function promptCredentialsName({
2006
2398
  email,
2007
- promptMessage
2399
+ promptMessage,
2400
+ baseUrl
2008
2401
  }) {
2009
- const { credentialName } = await inquirer3__default.default.prompt([
2402
+ const { credentialName } = await inquirer4__default.default.prompt([
2010
2403
  {
2011
2404
  type: "input",
2012
2405
  name: "credentialName",
@@ -2014,7 +2407,7 @@ async function promptCredentialsName({
2014
2407
  default: defaultCredentialsName(email),
2015
2408
  validate: (input) => {
2016
2409
  try {
2017
- validateCredentialsName(input);
2410
+ validateNewCredentialsName({ name: input, baseUrl });
2018
2411
  return true;
2019
2412
  } catch (err) {
2020
2413
  return err instanceof Error ? err.message : String(err);
@@ -2022,7 +2415,7 @@ async function promptCredentialsName({
2022
2415
  }
2023
2416
  }
2024
2417
  ]);
2025
- return validateCredentialsName(credentialName);
2418
+ return validateNewCredentialsName({ name: credentialName, baseUrl });
2026
2419
  }
2027
2420
  function resolveDefaultCredentialsName({
2028
2421
  email
@@ -2038,7 +2431,8 @@ async function resolveCredentialName({
2038
2431
  if (interactive) {
2039
2432
  return promptCredentialsName({
2040
2433
  email,
2041
- promptMessage: getCredentialsPromptMessage(entryPoint)
2434
+ promptMessage: getCredentialsPromptMessage(entryPoint),
2435
+ baseUrl
2042
2436
  });
2043
2437
  }
2044
2438
  const baseName = resolveDefaultCredentialsName({ email });
@@ -2069,7 +2463,7 @@ async function promptConfirm({
2069
2463
  message,
2070
2464
  defaultValue
2071
2465
  }) {
2072
- const { confirmed } = await inquirer3__default.default.prompt([
2466
+ const { confirmed } = await inquirer4__default.default.prompt([
2073
2467
  { type: "confirm", name: "confirmed", message, default: defaultValue }
2074
2468
  ]);
2075
2469
  return confirmed;
@@ -2079,6 +2473,11 @@ function promptlessCredentialResetError(credentials) {
2079
2473
  `Already logged in as "${credentials.name}". Run \`logout\` first or use an interactive terminal to re-authenticate.`
2080
2474
  );
2081
2475
  }
2476
+ function unnamedNonInteractiveLoginError(credentials) {
2477
+ throw new ZapierCliValidationError(
2478
+ `Already logged in as "${credentials.name}". Provide \`--name\` to activate or create named credentials, or run \`logout\` first.`
2479
+ );
2480
+ }
2082
2481
  function promptlessLegacyJwtUpgradeError() {
2083
2482
  throw new ZapierCliValidationError(
2084
2483
  "Legacy JWT login detected. Run `logout` first or use an interactive terminal to migrate to client credentials."
@@ -2088,16 +2487,20 @@ async function clearExistingAuthState({
2088
2487
  imports,
2089
2488
  baseUrl,
2090
2489
  interactive,
2091
- entryPoint
2490
+ entryPoint,
2491
+ preserveExistingCredentials = false
2092
2492
  }) {
2093
2493
  const activeCredentials = getActiveCredentials({ baseUrl });
2094
2494
  const flowLabel = getEntryPointLabel(entryPoint);
2495
+ if (activeCredentials && (entryPoint === "login" || preserveExistingCredentials)) {
2496
+ return true;
2497
+ }
2095
2498
  if (activeCredentials) {
2096
2499
  const confirmed = interactive ? await promptConfirm({
2097
2500
  defaultValue: false,
2098
2501
  message: `You are already logged in as "${activeCredentials.name}".
2099
2502
  Logging out will delete these credentials and may interrupt other Zapier SDK or CLI sessions using them.
2100
- Log out and ${getActiveCredentialsAction(entryPoint)}?`
2503
+ Log out and continue signup?`
2101
2504
  }) : promptlessCredentialResetError(activeCredentials);
2102
2505
  if (!confirmed) {
2103
2506
  process.stderr.write(`${flowLabel} cancelled.
@@ -2312,12 +2715,14 @@ async function provisionAccountCredentials({
2312
2715
  async function runAccountAuth({
2313
2716
  imports,
2314
2717
  options,
2315
- entryPoint
2718
+ entryPoint,
2719
+ storedCredentialsMode = "choose",
2720
+ preserveExistingCredentials = false
2316
2721
  }) {
2317
2722
  if (options.callbackUrl !== void 0) {
2318
2723
  const { callbackUrl } = options;
2319
2724
  const pending = getPendingOauthFlow({ entryPoint });
2320
- const finishName = options.name !== void 0 ? validateCredentialsName(options.name) : void 0;
2725
+ const finishName = options.name === void 0 ? void 0 : validateCredentialsName(options.name);
2321
2726
  if (finishName !== void 0 && finishName !== pending.credentialName) {
2322
2727
  throw new ZapierCliValidationError(
2323
2728
  "Cannot change --name while completing a pending OAuth flow. Start a new non-interactive login with the desired --name."
@@ -2377,7 +2782,6 @@ async function runAccountAuth({
2377
2782
  });
2378
2783
  return;
2379
2784
  }
2380
- const timeoutSeconds = parseTimeoutSeconds(options.timeout);
2381
2785
  const interactive = !resolveNonInteractive(options);
2382
2786
  const resolvedCredentials = await imports.resolveCredentials();
2383
2787
  const pkceCredentials = toPkceCredentials(resolvedCredentials);
@@ -2386,8 +2790,34 @@ async function runAccountAuth({
2386
2790
  options: imports.sdkOptions,
2387
2791
  resolvedCredentials
2388
2792
  });
2389
- const providedName = options.name !== void 0 ? validateCredentialsName(options.name) : void 0;
2390
- if (providedName !== void 0) {
2793
+ const providedName = options.name === void 0 ? void 0 : validateCredentialsName(options.name);
2794
+ if (entryPoint === "login") {
2795
+ if (providedName !== void 0) {
2796
+ const matchingCredentials = findStoredCredentialsByName({
2797
+ name: providedName,
2798
+ baseUrl: credentialsBaseUrl
2799
+ });
2800
+ if (matchingCredentials) {
2801
+ await switchCredentials({
2802
+ credentials: matchingCredentials,
2803
+ options,
2804
+ resolvedCredentials
2805
+ });
2806
+ return;
2807
+ }
2808
+ if (interactive && !await confirmNewCredentialsName(providedName)) {
2809
+ process.stderr.write("Login cancelled.\n");
2810
+ return;
2811
+ }
2812
+ } else if (interactive && storedCredentialsMode === "choose") {
2813
+ const selection = await chooseStoredLoginCredentialsAtBaseUrl({
2814
+ baseUrl: credentialsBaseUrl,
2815
+ options,
2816
+ resolvedCredentials
2817
+ });
2818
+ if (selection === "switch") return;
2819
+ }
2820
+ } else if (providedName !== void 0) {
2391
2821
  const activeCredentials = getActiveCredentials({
2392
2822
  baseUrl: credentialsBaseUrl
2393
2823
  });
@@ -2397,14 +2827,22 @@ async function runAccountAuth({
2397
2827
  );
2398
2828
  }
2399
2829
  }
2830
+ if (entryPoint === "login" && !interactive && providedName === void 0) {
2831
+ const activeCredentials = getActiveCredentials({
2832
+ baseUrl: credentialsBaseUrl
2833
+ });
2834
+ if (activeCredentials) unnamedNonInteractiveLoginError(activeCredentials);
2835
+ }
2400
2836
  if (!await clearExistingAuthState({
2401
2837
  imports,
2402
2838
  baseUrl: credentialsBaseUrl,
2403
2839
  interactive,
2404
- entryPoint
2840
+ entryPoint,
2841
+ preserveExistingCredentials
2405
2842
  })) {
2406
2843
  return;
2407
2844
  }
2845
+ const timeoutSeconds = parseTimeoutSeconds(options.timeout);
2408
2846
  const useApprovals = options.useApprovals === true;
2409
2847
  if (!interactive) {
2410
2848
  await startPendingOauthFlow({
@@ -2441,7 +2879,7 @@ async function runAccountAuth({
2441
2879
  }
2442
2880
  var LoginSchema = zod.z.object({
2443
2881
  name: zod.z.string().optional().describe(
2444
- "Name to identify these credentials (defaults to <email>@<hostname>). Provide this to set a custom name without the interactive prompt."
2882
+ "Activate stored credentials with this name. If none exist, create new credentials with this name; interactive login asks for confirmation first."
2445
2883
  ),
2446
2884
  timeout: zod.z.string().optional().describe("Login timeout in seconds (default: 300)"),
2447
2885
  useApprovals: zod.z.boolean().optional().describe(
@@ -4242,7 +4680,7 @@ async function promptYesNo({
4242
4680
  nonInteractive
4243
4681
  }) {
4244
4682
  if (nonInteractive) return defaultValue;
4245
- const { answer } = await inquirer3__default.default.prompt([
4683
+ const { answer } = await inquirer4__default.default.prompt([
4246
4684
  { type: "confirm", name: "answer", message, default: defaultValue }
4247
4685
  ]);
4248
4686
  return answer;
@@ -4289,7 +4727,7 @@ function buildTemplateVariables({
4289
4727
  };
4290
4728
  }
4291
4729
  function cleanupProject({ projectDir }) {
4292
- console.log("\n" + chalk3__default.default.yellow("!") + " Cleaning up...");
4730
+ console.log("\n" + chalk5__default.default.yellow("!") + " Cleaning up...");
4293
4731
  fs.rmSync(projectDir, { recursive: true, force: true });
4294
4732
  }
4295
4733
  async function withInterruptCleanup(cleanup, fn) {
@@ -4499,8 +4937,8 @@ function buildNextSteps({
4499
4937
  }
4500
4938
  function createConsoleDisplayHooks() {
4501
4939
  return {
4502
- onItemComplete: (message) => console.log(" " + chalk3__default.default.green("\u2713") + " " + chalk3__default.default.dim(message)),
4503
- onWarn: (message) => console.warn(chalk3__default.default.yellow("!") + " " + message),
4940
+ onItemComplete: (message) => console.log(" " + chalk5__default.default.green("\u2713") + " " + chalk5__default.default.dim(message)),
4941
+ onWarn: (message) => console.warn(chalk5__default.default.yellow("!") + " " + message),
4504
4942
  onStepStart: ({
4505
4943
  description,
4506
4944
  stepNumber,
@@ -4509,31 +4947,31 @@ function createConsoleDisplayHooks() {
4509
4947
  nonInteractive
4510
4948
  }) => {
4511
4949
  const progressMessage = `${description}...`;
4512
- const stepCounter = chalk3__default.default.dim(`${stepNumber}/${totalSteps}`);
4950
+ const stepCounter = chalk5__default.default.dim(`${stepNumber}/${totalSteps}`);
4513
4951
  if (nonInteractive) {
4514
4952
  console.log(
4515
- "\n" + chalk3__default.default.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
4953
+ "\n" + chalk5__default.default.bold(`\u276F ${progressMessage}`) + " " + stepCounter + "\n"
4516
4954
  );
4517
4955
  } else {
4518
4956
  console.log(
4519
- chalk3__default.default.dim("\u2192") + " " + progressMessage + " " + stepCounter
4957
+ chalk5__default.default.dim("\u2192") + " " + progressMessage + " " + stepCounter
4520
4958
  );
4521
4959
  }
4522
4960
  if (command) {
4523
- console.log(" " + chalk3__default.default.cyan(`$ ${command}`));
4961
+ console.log(" " + chalk5__default.default.cyan(`$ ${command}`));
4524
4962
  }
4525
4963
  },
4526
4964
  onStepSuccess: ({ stepNumber, totalSteps }) => console.log(
4527
- "\n" + chalk3__default.default.green("\u2713") + " " + chalk3__default.default.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
4965
+ "\n" + chalk5__default.default.green("\u2713") + " " + chalk5__default.default.dim(`Step ${stepNumber}/${totalSteps} complete`) + "\n"
4528
4966
  ),
4529
4967
  onStepError: ({ description, command, err }) => {
4530
4968
  const detail = err instanceof Error && err.message ? `
4531
- ${chalk3__default.default.dim(err.message)}` : "";
4969
+ ${chalk5__default.default.dim(err.message)}` : "";
4532
4970
  const hint = command ? `
4533
- ${chalk3__default.default.dim("run manually:")} ${chalk3__default.default.cyan(`$ ${command}`)}` : "";
4971
+ ${chalk5__default.default.dim("run manually:")} ${chalk5__default.default.cyan(`$ ${command}`)}` : "";
4534
4972
  console.error(
4535
4973
  `
4536
- ${chalk3__default.default.red("\u2716")} ${chalk3__default.default.bold(description)}${chalk3__default.default.dim(" failed")}${detail}${hint}`
4974
+ ${chalk5__default.default.red("\u2716")} ${chalk5__default.default.bold(description)}${chalk5__default.default.dim(" failed")}${detail}${hint}`
4537
4975
  );
4538
4976
  }
4539
4977
  };
@@ -4545,22 +4983,22 @@ function displaySummaryAndNextSteps({
4545
4983
  packageManager
4546
4984
  }) {
4547
4985
  const formatStatus = (complete) => ({
4548
- icon: complete ? chalk3__default.default.green("\u2713") : chalk3__default.default.yellow("!"),
4549
- text: complete ? chalk3__default.default.green("Setup complete") : chalk3__default.default.yellow("Setup interrupted")
4986
+ icon: complete ? chalk5__default.default.green("\u2713") : chalk5__default.default.yellow("!"),
4987
+ text: complete ? chalk5__default.default.green("Setup complete") : chalk5__default.default.yellow("Setup interrupted")
4550
4988
  });
4551
- const formatNextStep = (step, i) => " " + chalk3__default.default.dim(`${i + 1}.`) + " " + chalk3__default.default.bold(step.description);
4552
- const formatCommand = (cmd) => " " + chalk3__default.default.cyan(`$ ${cmd}`);
4553
- const formatCompletedStep = (step) => " " + chalk3__default.default.green("\u2713") + " " + step.description;
4989
+ const formatNextStep = (step, i) => " " + chalk5__default.default.dim(`${i + 1}.`) + " " + chalk5__default.default.bold(step.description);
4990
+ const formatCommand = (cmd) => " " + chalk5__default.default.cyan(`$ ${cmd}`);
4991
+ const formatCompletedStep = (step) => " " + chalk5__default.default.green("\u2713") + " " + step.description;
4554
4992
  const { execCmd } = getPackageManagerCommands({ packageManager });
4555
4993
  const leftoverSteps = steps.filter(
4556
4994
  (s) => !completedSetupStepIds.includes(s.id)
4557
4995
  );
4558
4996
  const isComplete = leftoverSteps.length === 0;
4559
4997
  const status = formatStatus(isComplete);
4560
- console.log("\n" + chalk3__default.default.bold("\u276F Summary") + "\n");
4561
- console.log(" " + chalk3__default.default.dim("Project") + " " + chalk3__default.default.bold(projectName));
4998
+ console.log("\n" + chalk5__default.default.bold("\u276F Summary") + "\n");
4999
+ console.log(" " + chalk5__default.default.dim("Project") + " " + chalk5__default.default.bold(projectName));
4562
5000
  console.log(
4563
- " " + chalk3__default.default.dim("Status") + " " + status.icon + " " + status.text
5001
+ " " + chalk5__default.default.dim("Status") + " " + status.icon + " " + status.text
4564
5002
  );
4565
5003
  const completedSteps = steps.filter(
4566
5004
  (s) => completedSetupStepIds.includes(s.id)
@@ -4570,7 +5008,7 @@ function displaySummaryAndNextSteps({
4570
5008
  for (const step of completedSteps) console.log(formatCompletedStep(step));
4571
5009
  }
4572
5010
  const nextSteps = buildNextSteps({ projectName, leftoverSteps, execCmd });
4573
- console.log("\n" + chalk3__default.default.bold("\u276F Next Steps") + "\n");
5011
+ console.log("\n" + chalk5__default.default.bold("\u276F Next Steps") + "\n");
4574
5012
  nextSteps.forEach((step, i) => {
4575
5013
  console.log(formatNextStep(step, i));
4576
5014
  if (step.command) console.log(formatCommand(step.command));
@@ -4633,149 +5071,6 @@ var initPlugin = zapierSdk.defineMethod({
4633
5071
  });
4634
5072
  }
4635
5073
  });
4636
- function isSelectable(item) {
4637
- return !core.Separator.isSeparator(item) && !item.disabled;
4638
- }
4639
- function normalizeChoices(choices) {
4640
- return choices.map((choice) => {
4641
- if (core.Separator.isSeparator(choice)) return choice;
4642
- const name = choice.name ?? String(choice.value);
4643
- return {
4644
- value: choice.value,
4645
- name,
4646
- short: choice.short ?? name,
4647
- disabled: choice.disabled ?? false
4648
- };
4649
- });
4650
- }
4651
- var theme = core.makeTheme({
4652
- icon: { cursor: "\u276F" },
4653
- style: {
4654
- disabled: (text) => chalk3__default.default.dim(`- ${text}`),
4655
- searchTerm: (text) => chalk3__default.default.cyan(text),
4656
- keysHelpTip: (keys) => keys.map(([key, action]) => `${chalk3__default.default.bold(key)} ${chalk3__default.default.dim(action)}`).join(chalk3__default.default.dim(" \u2022 "))
4657
- }
4658
- });
4659
- var searchSelect = core.createPrompt(
4660
- (config2, done) => {
4661
- const { pageSize = 7 } = config2;
4662
- const [status, setStatus] = core.useState(
4663
- "loading"
4664
- );
4665
- const [searchTerm, setSearchTerm] = core.useState("");
4666
- const [searchResults, setSearchResults] = core.useState([]);
4667
- const [searchError, setSearchError] = core.useState();
4668
- const prefix = core.usePrefix({ status, theme });
4669
- const bounds = core.useMemo(() => {
4670
- const first = searchResults.findIndex(isSelectable);
4671
- let last = -1;
4672
- for (let i = searchResults.length - 1; i >= 0; i--) {
4673
- if (isSelectable(searchResults[i])) {
4674
- last = i;
4675
- break;
4676
- }
4677
- }
4678
- return { first, last };
4679
- }, [searchResults]);
4680
- const defaultActive = core.useMemo(() => {
4681
- const requested = config2.initialActive;
4682
- if (searchTerm === "" && requested !== void 0 && requested >= 0 && requested < searchResults.length && isSelectable(searchResults[requested])) {
4683
- return requested;
4684
- }
4685
- return bounds.first;
4686
- }, [searchResults, searchTerm, bounds.first]);
4687
- const [active = defaultActive, setActive] = core.useState();
4688
- core.useEffect(() => {
4689
- const controller = new AbortController();
4690
- setStatus("loading");
4691
- setSearchError(void 0);
4692
- const fetchResults = async () => {
4693
- try {
4694
- const results = await config2.source(searchTerm || void 0);
4695
- if (!controller.signal.aborted) {
4696
- setActive(void 0);
4697
- setSearchError(void 0);
4698
- setSearchResults(normalizeChoices(results));
4699
- setStatus("idle");
4700
- }
4701
- } catch (error2) {
4702
- if (!controller.signal.aborted && error2 instanceof Error) {
4703
- setSearchError(error2.message);
4704
- }
4705
- }
4706
- };
4707
- void fetchResults();
4708
- return () => {
4709
- controller.abort();
4710
- };
4711
- }, [searchTerm]);
4712
- const selectedChoice = searchResults[active];
4713
- core.useKeypress((key, rl) => {
4714
- if (core.isEnterKey(key)) {
4715
- if (selectedChoice && isSelectable(selectedChoice)) {
4716
- setStatus("done");
4717
- done(selectedChoice.value);
4718
- } else {
4719
- rl.write(searchTerm);
4720
- }
4721
- } else if (core.isTabKey(key) && selectedChoice && isSelectable(selectedChoice)) {
4722
- rl.clearLine(0);
4723
- rl.write(selectedChoice.name);
4724
- setSearchTerm(selectedChoice.name);
4725
- } else if (status !== "loading" && (core.isUpKey(key) || core.isDownKey(key))) {
4726
- rl.clearLine(0);
4727
- if (core.isUpKey(key) && active !== bounds.first || core.isDownKey(key) && active !== bounds.last) {
4728
- const offset = core.isUpKey(key) ? -1 : 1;
4729
- let next = active;
4730
- do {
4731
- next = (next + offset + searchResults.length) % searchResults.length;
4732
- } while (!isSelectable(searchResults[next]));
4733
- setActive(next);
4734
- }
4735
- } else {
4736
- setSearchTerm(rl.line);
4737
- }
4738
- });
4739
- const page = core.usePagination({
4740
- items: searchResults,
4741
- active,
4742
- renderItem({ item, isActive }) {
4743
- if (core.Separator.isSeparator(item)) {
4744
- return ` ${item.separator}`;
4745
- }
4746
- if (item.disabled) {
4747
- const disabledLabel = typeof item.disabled === "string" ? item.disabled : "(disabled)";
4748
- return theme.style.disabled(`${item.name} ${disabledLabel}`);
4749
- }
4750
- const color = isActive ? theme.style.highlight : (x) => x;
4751
- const cursor = isActive ? theme.icon.cursor : ` `;
4752
- return color(`${cursor} ${item.name}`);
4753
- },
4754
- pageSize,
4755
- loop: false
4756
- });
4757
- const message = theme.style.message(config2.message, status);
4758
- if (status === "done" && selectedChoice && isSelectable(selectedChoice)) {
4759
- return [prefix, message, theme.style.answer(selectedChoice.short)].filter(Boolean).join(" ").trimEnd();
4760
- }
4761
- const searchStr = theme.style.searchTerm(searchTerm);
4762
- const helpTip = theme.style.keysHelpTip([
4763
- ["\u2191\u2193", "navigate"],
4764
- ["\u23CE", "select"]
4765
- ]);
4766
- let error;
4767
- if (searchError) {
4768
- error = theme.style.error(searchError);
4769
- } else if (searchResults.length === 0 && searchTerm !== "" && status === "idle") {
4770
- error = theme.style.error("No results found");
4771
- }
4772
- const header = [prefix, message, searchStr].filter(Boolean).join(" ").trimEnd();
4773
- const body = [error ?? page, " ", helpTip].filter(Boolean).join("\n").trimEnd();
4774
- return [header, body];
4775
- }
4776
- );
4777
-
4778
- // src/utils/controller-answer.ts
4779
5074
  function offers(question, action) {
4780
5075
  return question.actions.some((a) => a.action === action);
4781
5076
  }
@@ -4786,7 +5081,7 @@ async function promptText({
4786
5081
  message,
4787
5082
  password
4788
5083
  }) {
4789
- const { value } = await inquirer3__default.default.prompt([
5084
+ const { value } = await inquirer4__default.default.prompt([
4790
5085
  {
4791
5086
  type: password ? "password" : "input",
4792
5087
  name: "value",
@@ -4796,10 +5091,10 @@ async function promptText({
4796
5091
  ]);
4797
5092
  return value;
4798
5093
  }
4799
- var display = (c) => c.hint ? `${c.label} ${chalk3__default.default.dim(`(${c.hint})`)}` : c.label;
5094
+ var display = (c) => c.hint ? `${c.label} ${chalk5__default.default.dim(`(${c.hint})`)}` : c.label;
4800
5095
  var HIGH_CONTRAST_PROMPT_THEME = {
4801
5096
  style: {
4802
- answer: (text) => chalk3__default.default.inverse.bold(` ${text} `)
5097
+ answer: (text) => chalk5__default.default.inverse.bold(` ${text} `)
4803
5098
  }
4804
5099
  };
4805
5100
  function buildSelectRows(question, term) {
@@ -4815,8 +5110,8 @@ function buildSelectRows(question, term) {
4815
5110
  name: display(c),
4816
5111
  value: c.value
4817
5112
  }));
4818
- const skipRow = offers(question, "skip") ? [row(chalk3__default.default.dim("Skip (optional)"), "skip")] : [];
4819
- const customRow = offers(question, "custom") ? [row(chalk3__default.default.dim("Enter a value manually\u2026"), "custom")] : [];
5113
+ const skipRow = offers(question, "skip") ? [row(chalk5__default.default.dim("Skip (optional)"), "skip")] : [];
5114
+ const customRow = offers(question, "custom") ? [row(chalk5__default.default.dim("Enter a value manually\u2026"), "custom")] : [];
4820
5115
  const committed = !!t || question.search !== void 0;
4821
5116
  let rows;
4822
5117
  if (!committed) {
@@ -4827,13 +5122,13 @@ function buildSelectRows(question, term) {
4827
5122
  rows = [...customRow, ...skipRow];
4828
5123
  }
4829
5124
  if (offers(question, "search"))
4830
- rows.push(row(chalk3__default.default.cyan("Search again\u2026"), "search"));
5125
+ rows.push(row(chalk5__default.default.cyan("Search again\u2026"), "search"));
4831
5126
  if (offers(question, "next_page"))
4832
- rows.push(row(chalk3__default.default.dim("Load more\u2026"), "next_page"));
4833
- if (offers(question, "retry")) rows.push(row(chalk3__default.default.yellow("Retry"), "retry"));
4834
- if (offers(question, "cancel")) rows.push(row(chalk3__default.default.dim("Cancel"), "cancel"));
5127
+ rows.push(row(chalk5__default.default.dim("Load more\u2026"), "next_page"));
5128
+ if (offers(question, "retry")) rows.push(row(chalk5__default.default.yellow("Retry"), "retry"));
5129
+ if (offers(question, "cancel")) rows.push(row(chalk5__default.default.dim("Cancel"), "cancel"));
4835
5130
  for (const note of question.notes ?? [])
4836
- rows.push({ name: chalk3__default.default.dim(note), value: note, disabled: true });
5131
+ rows.push({ name: chalk5__default.default.dim(note), value: note, disabled: true });
4837
5132
  return rows;
4838
5133
  }
4839
5134
  function foldPage(acc, question, field) {
@@ -4874,7 +5169,7 @@ async function answerSelect(question, field, box, failed, mode) {
4874
5169
  const isClosedListPrompt = mode === "closed-list" && !failed && !view.multiple;
4875
5170
  const booleanValues = view.choices.map(({ value: value2 }) => value2);
4876
5171
  if (isClosedListPrompt && booleanValues.length === 2 && booleanValues.includes("true") && booleanValues.includes("false")) {
4877
- const { value: value2 } = await inquirer3__default.default.prompt([
5172
+ const { value: value2 } = await inquirer4__default.default.prompt([
4878
5173
  {
4879
5174
  type: "confirm",
4880
5175
  name: "value",
@@ -4890,7 +5185,7 @@ async function answerSelect(question, field, box, failed, mode) {
4890
5185
  name: display(choice),
4891
5186
  value: choice.value
4892
5187
  }));
4893
- const { value: value2 } = await inquirer3__default.default.prompt([
5188
+ const { value: value2 } = await inquirer4__default.default.prompt([
4894
5189
  {
4895
5190
  type: "list",
4896
5191
  name: "value",
@@ -4913,17 +5208,17 @@ async function answerSelect(question, field, box, failed, mode) {
4913
5208
  })),
4914
5209
  ...offers(question, "next_page") ? [
4915
5210
  {
4916
- name: chalk3__default.default.dim("Load more\u2026"),
5211
+ name: chalk5__default.default.dim("Load more\u2026"),
4917
5212
  value: { action: "next_page" }
4918
5213
  }
4919
5214
  ] : [],
4920
5215
  ...(question.notes ?? []).map((note) => ({
4921
- name: chalk3__default.default.dim(note),
5216
+ name: chalk5__default.default.dim(note),
4922
5217
  value: note,
4923
5218
  disabled: true
4924
5219
  }))
4925
5220
  ];
4926
- const { values } = await inquirer3__default.default.prompt([
5221
+ const { values } = await inquirer4__default.default.prompt([
4927
5222
  {
4928
5223
  type: "checkbox",
4929
5224
  name: "values",
@@ -4995,14 +5290,14 @@ async function answerSelect(question, field, box, failed, mode) {
4995
5290
  case "retry":
4996
5291
  return { type: "retry" };
4997
5292
  case "skip":
4998
- printAnswered(view.message, chalk3__default.default.dim("(skipped)"));
5293
+ printAnswered(view.message, chalk5__default.default.dim("(skipped)"));
4999
5294
  return { type: "skip" };
5000
5295
  case "cancel":
5001
5296
  return { type: "cancel" };
5002
5297
  }
5003
5298
  }
5004
5299
  function printAnswered(message, label) {
5005
- console.log(`${chalk3__default.default.green("\u2714")} ${message} ${chalk3__default.default.cyan(label)}`);
5300
+ console.log(`${chalk5__default.default.green("\u2714")} ${message} ${chalk5__default.default.cyan(label)}`);
5006
5301
  }
5007
5302
  async function answerInput(question) {
5008
5303
  const message = question.placeholder ? question.message.replace(/:?\s*$/, ` (${question.placeholder}):`) : question.message;
@@ -5020,7 +5315,7 @@ async function answerCollection(question) {
5020
5315
  return { type: "add" };
5021
5316
  }
5022
5317
  if (question.description) console.log(question.description);
5023
- const { again } = await inquirer3__default.default.prompt([
5318
+ const { again } = await inquirer4__default.default.prompt([
5024
5319
  {
5025
5320
  type: "confirm",
5026
5321
  name: "again",
@@ -5039,7 +5334,7 @@ function createCliAnswer({
5039
5334
  try {
5040
5335
  if (result.error !== void 0) {
5041
5336
  const message = typeof result.error === "string" ? result.error : result.error.message;
5042
- console.log(chalk3__default.default.yellow(`! ${message}`));
5337
+ console.log(chalk5__default.default.yellow(`! ${message}`));
5043
5338
  }
5044
5339
  const question = result.question;
5045
5340
  const field = question.path.length ? question.path.join(".") : "value";
@@ -5208,7 +5503,7 @@ var boltFillRanks = new Map(
5208
5503
  );
5209
5504
  var STATUS_ROW_INDEX = Math.floor(boltRows.length / 2);
5210
5505
  function formatPhase({ label, detail }) {
5211
- return detail ? `${chalk3__default.default.bold(label)} ${chalk3__default.default.dim(detail)}` : chalk3__default.default.bold(label);
5506
+ return detail ? `${chalk5__default.default.bold(label)} ${chalk5__default.default.dim(detail)}` : chalk5__default.default.bold(label);
5212
5507
  }
5213
5508
  function formatLoaderFrame({
5214
5509
  phase,
@@ -5220,7 +5515,7 @@ function formatLoaderFrame({
5220
5515
  const cellIndex = rowIndex * row.length + columnIndex;
5221
5516
  const fillRank = boltFillRanks.get(cellIndex);
5222
5517
  const isFilled = fillRank !== void 0 && fillRank < fillStage;
5223
- return isFilled ? chalk3__default.default.bold.yellow(cell) : chalk3__default.default.dim.yellow(cell);
5518
+ return isFilled ? chalk5__default.default.bold.yellow(cell) : chalk5__default.default.dim.yellow(cell);
5224
5519
  }).join("");
5225
5520
  const status = rowIndex === STATUS_ROW_INDEX ? ` ${formatPhase(phase)}` : "";
5226
5521
  return `${bolt}${status}`;
@@ -5252,12 +5547,12 @@ async function runWithSetupLoader({
5252
5547
  const result = await promise;
5253
5548
  clearInterval(animationTimer);
5254
5549
  const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
5255
- loader.succeed(`${formatPhase(phase)} ${chalk3__default.default.dim(`${elapsedSeconds}s`)}`);
5550
+ loader.succeed(`${formatPhase(phase)} ${chalk5__default.default.dim(`${elapsedSeconds}s`)}`);
5256
5551
  return result;
5257
5552
  } catch (error) {
5258
5553
  clearInterval(animationTimer);
5259
5554
  const elapsedSeconds = ((Date.now() - startedAt) / 1e3).toFixed(1);
5260
- loader.fail(`${formatPhase(phase)} ${chalk3__default.default.dim(`${elapsedSeconds}s`)}`);
5555
+ loader.fail(`${formatPhase(phase)} ${chalk5__default.default.dim(`${elapsedSeconds}s`)}`);
5261
5556
  throw error;
5262
5557
  }
5263
5558
  }
@@ -5748,7 +6043,7 @@ async function runCommand({
5748
6043
  detail: commandLabel
5749
6044
  });
5750
6045
  }
5751
- console.log(chalk3__default.default.dim(commandLabel));
6046
+ console.log(chalk5__default.default.dim(commandLabel));
5752
6047
  return await execute;
5753
6048
  } catch (error) {
5754
6049
  const message = error instanceof Error ? error.message : String(error);
@@ -5854,6 +6149,14 @@ function createWizardContext({
5854
6149
  imports,
5855
6150
  createAnswer: () => createCliAnswer({ mode: "closed-list" }),
5856
6151
  setupController: createSetupController(),
6152
+ selectStoredLoginCredentials: () => chooseStoredLoginCredentials({ imports, options: {} }),
6153
+ authenticateNewAccount: ({ entryPoint, headless }) => runAccountAuth({
6154
+ imports,
6155
+ options: { headless },
6156
+ entryPoint,
6157
+ storedCredentialsMode: "fresh",
6158
+ preserveExistingCredentials: true
6159
+ }),
5857
6160
  checkForUpdates,
5858
6161
  openUrl: async (url) => {
5859
6162
  await open__default.default(url);
@@ -5887,6 +6190,14 @@ function isCredentialWriteError(error) {
5887
6190
  const message = error instanceof Error ? error.message : String(error);
5888
6191
  return /permission|sandbox|eacces|eperm/i.test(message);
5889
6192
  }
6193
+ async function confirmAuthentication(context) {
6194
+ const { data: profile } = await runWithSetupLoader({
6195
+ promise: context.imports.getProfile({}),
6196
+ label: "Confirming Zapier account"
6197
+ });
6198
+ context.accountEmail = profile.email;
6199
+ console.log(`Authenticated as ${profile.email}.`);
6200
+ }
5890
6201
  async function authenticate(context) {
5891
6202
  const activeProfile = await runWithSetupLoader({
5892
6203
  promise: context.imports.getProfile({}).then(({ data }) => data).catch((error) => {
@@ -5895,7 +6206,12 @@ async function authenticate(context) {
5895
6206
  }),
5896
6207
  label: "Checking Zapier authentication"
5897
6208
  });
5898
- if (activeProfile) {
6209
+ const storedCredentialsSelection = await context.selectStoredLoginCredentials();
6210
+ if (storedCredentialsSelection === "switch") {
6211
+ await confirmAuthentication(context);
6212
+ return;
6213
+ }
6214
+ if (storedCredentialsSelection === "none" && activeProfile) {
5899
6215
  const shouldLogout = await resolveSetupConfirm({
5900
6216
  answer: context.createAnswer(),
5901
6217
  controller: context.setupController,
@@ -5936,10 +6252,14 @@ Log out and use a different account?`,
5936
6252
  ]
5937
6253
  });
5938
6254
  const headless = environment === "headless";
5939
- const runAuth = flow === "login" ? context.imports.login : context.imports.signup;
5940
6255
  printAuthCommand({ context, flow, headless });
5941
6256
  try {
5942
- await runAuth({ headless });
6257
+ if (storedCredentialsSelection === "create") {
6258
+ await context.authenticateNewAccount({ entryPoint: flow, headless });
6259
+ } else {
6260
+ const runAuth = flow === "login" ? context.imports.login : context.imports.signup;
6261
+ await runAuth({ headless });
6262
+ }
5943
6263
  } catch (error) {
5944
6264
  if (isCredentialWriteError(error)) {
5945
6265
  console.error(
@@ -5948,12 +6268,7 @@ Log out and use a different account?`,
5948
6268
  }
5949
6269
  throw error;
5950
6270
  }
5951
- const { data: profile } = await runWithSetupLoader({
5952
- promise: context.imports.getProfile({}),
5953
- label: "Confirming Zapier account"
5954
- });
5955
- context.accountEmail = profile.email;
5956
- console.log(`Authenticated as ${profile.email}.`);
6271
+ await confirmAuthentication(context);
5957
6272
  }
5958
6273
  var agentLabels = {
5959
6274
  claude: "Claude Code",
@@ -5995,7 +6310,7 @@ function printAgentPrompt({
5995
6310
  message
5996
6311
  }) {
5997
6312
  console.log();
5998
- console.log(chalk3__default.default.bgYellow.black.bold(message));
6313
+ console.log(chalk5__default.default.bgYellow.black.bold(message));
5999
6314
  console.log();
6000
6315
  console.log(buildAgentPrompt({ context }));
6001
6316
  }
@@ -6280,7 +6595,7 @@ var MINIMUM_MESSAGE_WIDTH = 20;
6280
6595
  var MAXIMUM_MESSAGE_WIDTH = 88;
6281
6596
  function showPhase({ number, title }) {
6282
6597
  console.log();
6283
- console.log(chalk3__default.default.bgCyan.black.bold(` ${number}/${PHASE_COUNT} ${title} `));
6598
+ console.log(chalk5__default.default.bgCyan.black.bold(` ${number}/${PHASE_COUNT} ${title} `));
6284
6599
  }
6285
6600
  function printWrapped(text) {
6286
6601
  const width = Math.max(
@@ -6294,7 +6609,7 @@ function printWrapped(text) {
6294
6609
  }
6295
6610
  function showReadyMessage() {
6296
6611
  console.log();
6297
- console.log(chalk3__default.default.bgGreen.black.bold(" \u2713 Zapier SDK setup complete "));
6612
+ console.log(chalk5__default.default.bgGreen.black.bold(" \u2713 Zapier SDK setup complete "));
6298
6613
  console.log();
6299
6614
  printWrapped(
6300
6615
  "Use active Zapier connections to access 9,000+ app connectors without managing each app's OAuth, token refresh, or retries."
@@ -6306,7 +6621,7 @@ function showReadyMessage() {
6306
6621
  console.log();
6307
6622
  }
6308
6623
  async function runWizard(context) {
6309
- console.log(chalk3__default.default.bold("Zapier SDK setup"));
6624
+ console.log(chalk5__default.default.bold("Zapier SDK setup"));
6310
6625
  showPhase({ number: 1, title: "Project directory" });
6311
6626
  await chooseDirectory(context);
6312
6627
  showPhase({ number: 2, title: "Node.js" });
@@ -6321,7 +6636,7 @@ async function runWizard(context) {
6321
6636
  showPhase({ number: 6, title: "Slack demo" });
6322
6637
  await offerSlackTest(context);
6323
6638
  showReadyMessage();
6324
- console.log(chalk3__default.default.bgCyan.black.bold(" Next steps "));
6639
+ console.log(chalk5__default.default.bgCyan.black.bold(" Next steps "));
6325
6640
  await openAgentHandoff(context);
6326
6641
  }
6327
6642
 
@@ -6336,7 +6651,11 @@ var setupImports = [
6336
6651
  listConnectionsRef2,
6337
6652
  loginRef,
6338
6653
  logoutRef,
6339
- signupRef
6654
+ signupRef,
6655
+ zapierSdk.apiPluginRef,
6656
+ zapierSdk.resolveCredentialsPluginRef,
6657
+ zapierSdk.eventEmissionPluginRef,
6658
+ zapierSdk.sdkOptionsPluginRef
6340
6659
  ];
6341
6660
  var setupPlugin = zapierSdk.defineMethod({
6342
6661
  name: "setup",
@@ -6382,18 +6701,18 @@ function createInteractiveCallback() {
6382
6701
  const attrs = message.message_attributes;
6383
6702
  console.log(
6384
6703
  `
6385
- ${chalk3__default.default.bold(`Message #${messageNumber}`)} ${chalk3__default.default.dim(message.id)} ${chalk3__default.default.dim(`(lease #${attrs.lease_count})`)}`
6704
+ ${chalk5__default.default.bold(`Message #${messageNumber}`)} ${chalk5__default.default.dim(message.id)} ${chalk5__default.default.dim(`(lease #${attrs.lease_count})`)}`
6386
6705
  );
6387
6706
  if (attrs.error_message) {
6388
- console.log(chalk3__default.default.yellow(` upstream error: ${attrs.error_message}`));
6707
+ console.log(chalk5__default.default.yellow(` upstream error: ${attrs.error_message}`));
6389
6708
  }
6390
6709
  if (attrs.possible_duplicate_data) {
6391
- console.log(chalk3__default.default.yellow(" possible duplicate data"));
6710
+ console.log(chalk5__default.default.yellow(" possible duplicate data"));
6392
6711
  }
6393
6712
  while (true) {
6394
6713
  let action;
6395
6714
  try {
6396
- const answer = await inquirer3__default.default.prompt([
6715
+ const answer = await inquirer4__default.default.prompt([
6397
6716
  {
6398
6717
  type: "list",
6399
6718
  name: "action",
@@ -6418,7 +6737,7 @@ ${chalk3__default.default.bold(`Message #${messageNumber}`)} ${chalk3__default.d
6418
6737
  throw error;
6419
6738
  }
6420
6739
  if (action === "view") {
6421
- console.log(chalk3__default.default.dim(JSON.stringify(message.payload, null, 2)));
6740
+ console.log(chalk5__default.default.dim(JSON.stringify(message.payload, null, 2)));
6422
6741
  continue;
6423
6742
  }
6424
6743
  if (action === "ack") {
@@ -6521,7 +6840,7 @@ function describeReason(reason) {
6521
6840
  }
6522
6841
  function printDrainError(reason, message) {
6523
6842
  console.error(
6524
- chalk3__default.default.red(`Error processing ${message.id}: ${describeReason(reason)}`)
6843
+ chalk5__default.default.red(`Error processing ${message.id}: ${describeReason(reason)}`)
6525
6844
  );
6526
6845
  }
6527
6846
  function printDrainSummary(counts) {
@@ -6531,7 +6850,7 @@ function printDrainSummary(counts) {
6531
6850
  if (skipped > 0) parts.push(`${skipped} skipped`);
6532
6851
  parts.push(`${counts.rejected} rejected`);
6533
6852
  console.log(
6534
- chalk3__default.default.dim(
6853
+ chalk5__default.default.dim(
6535
6854
  `
6536
6855
  Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
6537
6856
  )
@@ -6539,7 +6858,7 @@ Processed ${total} message${total === 1 ? "" : "s"} (${parts.join(", ")}).`
6539
6858
  }
6540
6859
  function warnInteractiveContinueOnErrorOverride() {
6541
6860
  console.warn(
6542
- chalk3__default.default.yellow(
6861
+ chalk5__default.default.yellow(
6543
6862
  'Note: continueOnError=false is overridden to true in interactive mode (the "Skip (let lease expire)" choice would otherwise terminate the drain).'
6544
6863
  )
6545
6864
  );
@@ -6860,7 +7179,7 @@ function collectDeprecationNoticeAndForward(event, onEvent) {
6860
7179
  // package.json with { type: 'json' }
6861
7180
  var package_default = {
6862
7181
  name: "@zapier/zapier-sdk-cli",
6863
- version: "0.77.8"};
7182
+ version: "0.78.0"};
6864
7183
 
6865
7184
  // src/sdk.ts
6866
7185
  var warnedDeprecatedMethods = /* @__PURE__ */ new Set();
@@ -6871,9 +7190,9 @@ var cliCoreOptions = {
6871
7190
  warnedDeprecatedMethods.add(methodName);
6872
7191
  console.warn();
6873
7192
  console.warn(
6874
- chalk3__default.default.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk3__default.default.yellow(` - \`${toKebabCase(methodName)}\` is deprecated.`)
7193
+ chalk5__default.default.yellow.bold("\u26A0\uFE0F DEPRECATION WARNING") + chalk5__default.default.yellow(` - \`${toKebabCase(methodName)}\` is deprecated.`)
6875
7194
  );
6876
- console.warn(chalk3__default.default.yellow(` ${deprecation.message}`));
7195
+ console.warn(chalk5__default.default.yellow(` ${deprecation.message}`));
6877
7196
  console.warn();
6878
7197
  }
6879
7198
  };