@hasna/connectors 1.1.12 → 1.1.14

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/bin/index.js CHANGED
@@ -9631,11 +9631,78 @@ var init_installer = __esm(() => {
9631
9631
  CONNECTORS_DIR = resolveConnectorsDir();
9632
9632
  });
9633
9633
 
9634
+ // src/lib/lock.ts
9635
+ import { openSync, closeSync, unlinkSync, existsSync as existsSync3 } from "fs";
9636
+ import { join as join3 } from "path";
9637
+ import { homedir as homedir2 } from "os";
9638
+ import { mkdirSync as mkdirSync2 } from "fs";
9639
+ function lockPath(connector) {
9640
+ const dir = join3(homedir2(), ".connectors", `connect-${connector}`);
9641
+ mkdirSync2(dir, { recursive: true });
9642
+ return join3(dir, ".write.lock");
9643
+ }
9644
+ function isStale(path) {
9645
+ try {
9646
+ const { statSync: statSync2 } = __require("fs");
9647
+ const stat = statSync2(path);
9648
+ return Date.now() - stat.mtimeMs > STALE_LOCK_MS;
9649
+ } catch {
9650
+ return false;
9651
+ }
9652
+ }
9653
+ function tryAcquire(path) {
9654
+ if (existsSync3(path) && isStale(path)) {
9655
+ try {
9656
+ unlinkSync(path);
9657
+ } catch {}
9658
+ }
9659
+ try {
9660
+ const fd = openSync(path, "wx");
9661
+ closeSync(fd);
9662
+ return true;
9663
+ } catch (e) {
9664
+ if (e.code === "EEXIST")
9665
+ return false;
9666
+ throw e;
9667
+ }
9668
+ }
9669
+ function release(path) {
9670
+ try {
9671
+ unlinkSync(path);
9672
+ } catch {}
9673
+ }
9674
+ async function withWriteLock(connector, fn) {
9675
+ const path = lockPath(connector);
9676
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
9677
+ while (Date.now() < deadline) {
9678
+ if (tryAcquire(path)) {
9679
+ try {
9680
+ return await fn();
9681
+ } finally {
9682
+ release(path);
9683
+ }
9684
+ }
9685
+ await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_MS));
9686
+ }
9687
+ throw new LockTimeoutError(connector);
9688
+ }
9689
+ var LOCK_TIMEOUT_MS = 5000, LOCK_RETRY_MS = 100, STALE_LOCK_MS = 30000, LockTimeoutError;
9690
+ var init_lock = __esm(() => {
9691
+ LockTimeoutError = class LockTimeoutError extends Error {
9692
+ connector;
9693
+ constructor(connector) {
9694
+ super(`Could not acquire write lock for connector "${connector}" within ${LOCK_TIMEOUT_MS}ms. Another agent may be writing. Try again shortly.`);
9695
+ this.connector = connector;
9696
+ this.name = "LockTimeoutError";
9697
+ }
9698
+ };
9699
+ });
9700
+
9634
9701
  // src/server/auth.ts
9635
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2 } from "fs";
9702
+ import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2 } from "fs";
9636
9703
  import { randomBytes } from "crypto";
9637
- import { homedir as homedir2 } from "os";
9638
- import { join as join3 } from "path";
9704
+ import { homedir as homedir3 } from "os";
9705
+ import { join as join4 } from "path";
9639
9706
  function getAuthType(name) {
9640
9707
  const docs = getConnectorDocs(name);
9641
9708
  if (!docs?.auth)
@@ -9649,12 +9716,12 @@ function getAuthType(name) {
9649
9716
  }
9650
9717
  function getConnectorConfigDir(name) {
9651
9718
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
9652
- return join3(homedir2(), ".connectors", connectorName);
9719
+ return join4(homedir3(), ".connectors", connectorName);
9653
9720
  }
9654
9721
  function getCurrentProfile(name) {
9655
9722
  const configDir = getConnectorConfigDir(name);
9656
- const currentProfileFile = join3(configDir, "current_profile");
9657
- if (existsSync3(currentProfileFile)) {
9723
+ const currentProfileFile = join4(configDir, "current_profile");
9724
+ if (existsSync4(currentProfileFile)) {
9658
9725
  try {
9659
9726
  return readFileSync3(currentProfileFile, "utf-8").trim() || "default";
9660
9727
  } catch {
@@ -9668,14 +9735,14 @@ function loadProfileConfig(name) {
9668
9735
  const profile = getCurrentProfile(name);
9669
9736
  let flatConfig = {};
9670
9737
  let dirConfig = {};
9671
- const profileFile = join3(configDir, "profiles", `${profile}.json`);
9672
- if (existsSync3(profileFile)) {
9738
+ const profileFile = join4(configDir, "profiles", `${profile}.json`);
9739
+ if (existsSync4(profileFile)) {
9673
9740
  try {
9674
9741
  flatConfig = JSON.parse(readFileSync3(profileFile, "utf-8"));
9675
9742
  } catch {}
9676
9743
  }
9677
- const profileDirConfig = join3(configDir, "profiles", profile, "config.json");
9678
- if (existsSync3(profileDirConfig)) {
9744
+ const profileDirConfig = join4(configDir, "profiles", profile, "config.json");
9745
+ if (existsSync4(profileDirConfig)) {
9679
9746
  try {
9680
9747
  dirConfig = JSON.parse(readFileSync3(profileDirConfig, "utf-8"));
9681
9748
  } catch {}
@@ -9688,8 +9755,8 @@ function loadProfileConfig(name) {
9688
9755
  function loadTokens(name) {
9689
9756
  const configDir = getConnectorConfigDir(name);
9690
9757
  const profile = getCurrentProfile(name);
9691
- const tokensFile = join3(configDir, "profiles", profile, "tokens.json");
9692
- if (existsSync3(tokensFile)) {
9758
+ const tokensFile = join4(configDir, "profiles", profile, "tokens.json");
9759
+ if (existsSync4(tokensFile)) {
9693
9760
  try {
9694
9761
  return JSON.parse(readFileSync3(tokensFile, "utf-8"));
9695
9762
  } catch {
@@ -9740,15 +9807,18 @@ function getEnvVars(name) {
9740
9807
  const docs = getConnectorDocs(name);
9741
9808
  return docs?.envVars || [];
9742
9809
  }
9743
- function saveApiKey(name, key, field) {
9810
+ async function saveApiKey(name, key, field) {
9811
+ return withWriteLock(name, () => _saveApiKey(name, key, field));
9812
+ }
9813
+ function _saveApiKey(name, key, field) {
9744
9814
  const configDir = getConnectorConfigDir(name);
9745
9815
  const profile = getCurrentProfile(name);
9746
9816
  const keyField = field || guessKeyField(name);
9747
9817
  if (keyField === "clientId" || keyField === "clientSecret") {
9748
- const credentialsFile = join3(configDir, "credentials.json");
9749
- mkdirSync2(configDir, { recursive: true });
9818
+ const credentialsFile = join4(configDir, "credentials.json");
9819
+ mkdirSync3(configDir, { recursive: true });
9750
9820
  let creds = {};
9751
- if (existsSync3(credentialsFile)) {
9821
+ if (existsSync4(credentialsFile)) {
9752
9822
  try {
9753
9823
  creds = JSON.parse(readFileSync3(credentialsFile, "utf-8"));
9754
9824
  } catch {}
@@ -9757,9 +9827,9 @@ function saveApiKey(name, key, field) {
9757
9827
  writeFileSync2(credentialsFile, JSON.stringify(creds, null, 2));
9758
9828
  return;
9759
9829
  }
9760
- const profileFile = join3(configDir, "profiles", `${profile}.json`);
9761
- const profileDir = join3(configDir, "profiles", profile);
9762
- if (existsSync3(profileFile)) {
9830
+ const profileFile = join4(configDir, "profiles", `${profile}.json`);
9831
+ const profileDir = join4(configDir, "profiles", profile);
9832
+ if (existsSync4(profileFile)) {
9763
9833
  let config = {};
9764
9834
  try {
9765
9835
  config = JSON.parse(readFileSync3(profileFile, "utf-8"));
@@ -9768,10 +9838,10 @@ function saveApiKey(name, key, field) {
9768
9838
  writeFileSync2(profileFile, JSON.stringify(config, null, 2));
9769
9839
  return;
9770
9840
  }
9771
- if (existsSync3(profileDir)) {
9772
- const configFile = join3(profileDir, "config.json");
9841
+ if (existsSync4(profileDir)) {
9842
+ const configFile = join4(profileDir, "config.json");
9773
9843
  let config = {};
9774
- if (existsSync3(configFile)) {
9844
+ if (existsSync4(configFile)) {
9775
9845
  try {
9776
9846
  config = JSON.parse(readFileSync3(configFile, "utf-8"));
9777
9847
  } catch {}
@@ -9780,8 +9850,8 @@ function saveApiKey(name, key, field) {
9780
9850
  writeFileSync2(configFile, JSON.stringify(config, null, 2));
9781
9851
  return;
9782
9852
  }
9783
- mkdirSync2(profileDir, { recursive: true });
9784
- writeFileSync2(join3(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
9853
+ mkdirSync3(profileDir, { recursive: true });
9854
+ writeFileSync2(join4(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
9785
9855
  }
9786
9856
  function guessKeyField(name) {
9787
9857
  const docs = getConnectorDocs(name);
@@ -9799,8 +9869,8 @@ function guessKeyField(name) {
9799
9869
  }
9800
9870
  function getOAuthConfig(name) {
9801
9871
  const configDir = getConnectorConfigDir(name);
9802
- const credentialsFile = join3(configDir, "credentials.json");
9803
- if (existsSync3(credentialsFile)) {
9872
+ const credentialsFile = join4(configDir, "credentials.json");
9873
+ if (existsSync4(credentialsFile)) {
9804
9874
  try {
9805
9875
  const creds = JSON.parse(readFileSync3(credentialsFile, "utf-8"));
9806
9876
  return { clientId: creds.clientId, clientSecret: creds.clientSecret };
@@ -9881,12 +9951,15 @@ async function exchangeOAuthCode(name, code, redirectUri) {
9881
9951
  function saveOAuthTokens(name, tokens) {
9882
9952
  const configDir = getConnectorConfigDir(name);
9883
9953
  const profile = getCurrentProfile(name);
9884
- const profileDir = join3(configDir, "profiles", profile);
9885
- mkdirSync2(profileDir, { recursive: true });
9886
- const tokensFile = join3(profileDir, "tokens.json");
9954
+ const profileDir = join4(configDir, "profiles", profile);
9955
+ mkdirSync3(profileDir, { recursive: true });
9956
+ const tokensFile = join4(profileDir, "tokens.json");
9887
9957
  writeFileSync2(tokensFile, JSON.stringify(tokens, null, 2), { mode: 384 });
9888
9958
  }
9889
9959
  async function refreshOAuthToken(name) {
9960
+ return withWriteLock(name, () => _refreshOAuthToken(name));
9961
+ }
9962
+ async function _refreshOAuthToken(name) {
9890
9963
  const oauthConfig = getOAuthConfig(name);
9891
9964
  const currentTokens = loadTokens(name);
9892
9965
  if (!oauthConfig.clientId || !oauthConfig.clientSecret) {
@@ -9923,14 +9996,14 @@ async function refreshOAuthToken(name) {
9923
9996
  }
9924
9997
  function listProfiles(name) {
9925
9998
  const configDir = getConnectorConfigDir(name);
9926
- const profilesDir = join3(configDir, "profiles");
9927
- if (!existsSync3(profilesDir))
9999
+ const profilesDir = join4(configDir, "profiles");
10000
+ if (!existsSync4(profilesDir))
9928
10001
  return ["default"];
9929
10002
  const seen = new Set;
9930
10003
  try {
9931
10004
  const entries = readdirSync2(profilesDir);
9932
10005
  for (const entry of entries) {
9933
- const fullPath = join3(profilesDir, entry);
10006
+ const fullPath = join4(profilesDir, entry);
9934
10007
  const stat = statSync2(fullPath);
9935
10008
  if (stat.isDirectory()) {
9936
10009
  seen.add(entry);
@@ -9944,24 +10017,24 @@ function listProfiles(name) {
9944
10017
  }
9945
10018
  function switchProfile(name, profile) {
9946
10019
  const configDir = getConnectorConfigDir(name);
9947
- mkdirSync2(configDir, { recursive: true });
9948
- writeFileSync2(join3(configDir, "current_profile"), profile);
10020
+ mkdirSync3(configDir, { recursive: true });
10021
+ writeFileSync2(join4(configDir, "current_profile"), profile);
9949
10022
  }
9950
10023
  function deleteProfile(name, profile) {
9951
10024
  if (profile === "default")
9952
10025
  return false;
9953
10026
  const configDir = getConnectorConfigDir(name);
9954
- const profilesDir = join3(configDir, "profiles");
9955
- const profileFile = join3(profilesDir, `${profile}.json`);
9956
- if (existsSync3(profileFile)) {
10027
+ const profilesDir = join4(configDir, "profiles");
10028
+ const profileFile = join4(profilesDir, `${profile}.json`);
10029
+ if (existsSync4(profileFile)) {
9957
10030
  rmSync2(profileFile);
9958
10031
  if (getCurrentProfile(name) === profile) {
9959
10032
  switchProfile(name, "default");
9960
10033
  }
9961
10034
  return true;
9962
10035
  }
9963
- const profileDir = join3(profilesDir, profile);
9964
- if (existsSync3(profileDir)) {
10036
+ const profileDir = join4(profilesDir, profile);
10037
+ if (existsSync4(profileDir)) {
9965
10038
  rmSync2(profileDir, { recursive: true });
9966
10039
  if (getCurrentProfile(name) === profile) {
9967
10040
  switchProfile(name, "default");
@@ -9973,6 +10046,7 @@ function deleteProfile(name, profile) {
9973
10046
  var FETCH_TIMEOUT = 1e4, oauthStateStore, GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth", GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token", GOOGLE_SCOPES;
9974
10047
  var init_auth = __esm(() => {
9975
10048
  init_installer();
10049
+ init_lock();
9976
10050
  oauthStateStore = new Map;
9977
10051
  GOOGLE_SCOPES = {
9978
10052
  gmail: [
@@ -10016,14 +10090,14 @@ var init_auth = __esm(() => {
10016
10090
 
10017
10091
  // src/db/database.ts
10018
10092
  import { Database } from "bun:sqlite";
10019
- import { join as join5 } from "path";
10020
- import { homedir as homedir3 } from "os";
10021
- import { mkdirSync as mkdirSync3 } from "fs";
10093
+ import { join as join6 } from "path";
10094
+ import { homedir as homedir4 } from "os";
10095
+ import { mkdirSync as mkdirSync4 } from "fs";
10022
10096
  function getDatabase(path) {
10023
10097
  if (_db)
10024
10098
  return _db;
10025
10099
  const dbPath = path ?? DB_PATH;
10026
- mkdirSync3(join5(dbPath, ".."), { recursive: true });
10100
+ mkdirSync4(join6(dbPath, ".."), { recursive: true });
10027
10101
  _db = new Database(dbPath);
10028
10102
  _db.run("PRAGMA journal_mode = WAL");
10029
10103
  migrate(_db);
@@ -10046,8 +10120,8 @@ function migrate(db) {
10046
10120
  }
10047
10121
  var DB_DIR, DB_PATH, _db = null;
10048
10122
  var init_database = __esm(() => {
10049
- DB_DIR = join5(homedir3(), ".connectors");
10050
- DB_PATH = join5(DB_DIR, "connectors.db");
10123
+ DB_DIR = join6(homedir4(), ".connectors");
10124
+ DB_PATH = join6(DB_DIR, "connectors.db");
10051
10125
  });
10052
10126
 
10053
10127
  // src/db/agents.ts
@@ -10121,10 +10195,10 @@ var exports_serve = {};
10121
10195
  __export(exports_serve, {
10122
10196
  startServer: () => startServer
10123
10197
  });
10124
- import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync4 } from "fs";
10125
- import { join as join6, dirname as dirname4, extname, basename } from "path";
10198
+ import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync5 } from "fs";
10199
+ import { join as join7, dirname as dirname4, extname, basename } from "path";
10126
10200
  import { fileURLToPath as fileURLToPath4 } from "url";
10127
- import { homedir as homedir4 } from "os";
10201
+ import { homedir as homedir5 } from "os";
10128
10202
  function logActivity(action, connector, detail) {
10129
10203
  activityLog.unshift({ action, connector, timestamp: Date.now(), detail });
10130
10204
  if (activityLog.length > MAX_ACTIVITY_LOG) {
@@ -10135,20 +10209,20 @@ function resolveDashboardDir() {
10135
10209
  const candidates = [];
10136
10210
  try {
10137
10211
  const scriptDir = dirname4(fileURLToPath4(import.meta.url));
10138
- candidates.push(join6(scriptDir, "..", "dashboard", "dist"));
10139
- candidates.push(join6(scriptDir, "..", "..", "dashboard", "dist"));
10212
+ candidates.push(join7(scriptDir, "..", "dashboard", "dist"));
10213
+ candidates.push(join7(scriptDir, "..", "..", "dashboard", "dist"));
10140
10214
  } catch {}
10141
10215
  if (process.argv[1]) {
10142
10216
  const mainDir = dirname4(process.argv[1]);
10143
- candidates.push(join6(mainDir, "..", "dashboard", "dist"));
10144
- candidates.push(join6(mainDir, "..", "..", "dashboard", "dist"));
10217
+ candidates.push(join7(mainDir, "..", "dashboard", "dist"));
10218
+ candidates.push(join7(mainDir, "..", "..", "dashboard", "dist"));
10145
10219
  }
10146
- candidates.push(join6(process.cwd(), "dashboard", "dist"));
10220
+ candidates.push(join7(process.cwd(), "dashboard", "dist"));
10147
10221
  for (const candidate of candidates) {
10148
- if (existsSync5(candidate))
10222
+ if (existsSync6(candidate))
10149
10223
  return candidate;
10150
10224
  }
10151
- return join6(process.cwd(), "dashboard", "dist");
10225
+ return join7(process.cwd(), "dashboard", "dist");
10152
10226
  }
10153
10227
  function json(data, status = 200, port) {
10154
10228
  return new Response(JSON.stringify(data), {
@@ -10221,7 +10295,7 @@ function oauthPage(type, title, message, hint, extra) {
10221
10295
  </body></html>`;
10222
10296
  }
10223
10297
  function serveStaticFile(filePath) {
10224
- if (!existsSync5(filePath))
10298
+ if (!existsSync6(filePath))
10225
10299
  return null;
10226
10300
  const ext = extname(filePath);
10227
10301
  const contentType = MIME_TYPES[ext] || "application/octet-stream";
@@ -10245,7 +10319,7 @@ async function startServer(requestedPort, options) {
10245
10319
  const shouldOpen = options?.open ?? true;
10246
10320
  loadConnectorVersions();
10247
10321
  const dashboardDir = resolveDashboardDir();
10248
- const dashboardExists = existsSync5(dashboardDir);
10322
+ const dashboardExists = existsSync6(dashboardDir);
10249
10323
  if (!dashboardExists) {
10250
10324
  console.error(`
10251
10325
  Dashboard not found at: ${dashboardDir}`);
@@ -10320,7 +10394,7 @@ Dashboard not found at: ${dashboardDir}`);
10320
10394
  const body = await req.json();
10321
10395
  if (!body.key)
10322
10396
  return json({ error: "Missing 'key' in request body" }, 400, port);
10323
- saveApiKey(name, body.key, body.field);
10397
+ await saveApiKey(name, body.key, body.field);
10324
10398
  logActivity("key_saved", name, body.field ? `Field: ${body.field}` : undefined);
10325
10399
  return json({ success: true }, 200, port);
10326
10400
  } catch (e) {
@@ -10426,10 +10500,10 @@ Dashboard not found at: ${dashboardDir}`);
10426
10500
  return json({ error: "Invalid connector name" }, 400, port);
10427
10501
  try {
10428
10502
  const profiles = listProfiles(name);
10429
- const configDir = join6(homedir4(), ".connectors", name.startsWith("connect-") ? name : `connect-${name}`);
10430
- const currentProfileFile = join6(configDir, "current_profile");
10503
+ const configDir = join7(homedir5(), ".connectors", name.startsWith("connect-") ? name : `connect-${name}`);
10504
+ const currentProfileFile = join7(configDir, "current_profile");
10431
10505
  let current = "default";
10432
- if (existsSync5(currentProfileFile)) {
10506
+ if (existsSync6(currentProfileFile)) {
10433
10507
  try {
10434
10508
  current = readFileSync4(currentProfileFile, "utf-8").trim() || "default";
10435
10509
  } catch {}
@@ -10478,16 +10552,16 @@ Dashboard not found at: ${dashboardDir}`);
10478
10552
  }
10479
10553
  if (path === "/api/export" && method === "GET") {
10480
10554
  try {
10481
- const connectDir = join6(homedir4(), ".connectors");
10555
+ const connectDir = join7(homedir5(), ".connectors");
10482
10556
  const result = {};
10483
- if (existsSync5(connectDir)) {
10557
+ if (existsSync6(connectDir)) {
10484
10558
  const entries = readdirSync3(connectDir, { withFileTypes: true });
10485
10559
  for (const entry of entries) {
10486
10560
  if (!entry.isDirectory() || !entry.name.startsWith("connect-"))
10487
10561
  continue;
10488
10562
  const connectorName = entry.name.replace(/^connect-/, "");
10489
- const profilesDir = join6(connectDir, entry.name, "profiles");
10490
- if (!existsSync5(profilesDir))
10563
+ const profilesDir = join7(connectDir, entry.name, "profiles");
10564
+ if (!existsSync6(profilesDir))
10491
10565
  continue;
10492
10566
  const profiles = {};
10493
10567
  const profileEntries = readdirSync3(profilesDir, { withFileTypes: true });
@@ -10495,13 +10569,13 @@ Dashboard not found at: ${dashboardDir}`);
10495
10569
  if (pEntry.isFile() && pEntry.name.endsWith(".json")) {
10496
10570
  const profileName = basename(pEntry.name, ".json");
10497
10571
  try {
10498
- const config = JSON.parse(readFileSync4(join6(profilesDir, pEntry.name), "utf-8"));
10572
+ const config = JSON.parse(readFileSync4(join7(profilesDir, pEntry.name), "utf-8"));
10499
10573
  profiles[profileName] = config;
10500
10574
  } catch {}
10501
10575
  }
10502
10576
  if (pEntry.isDirectory()) {
10503
- const configPath = join6(profilesDir, pEntry.name, "config.json");
10504
- if (existsSync5(configPath)) {
10577
+ const configPath = join7(profilesDir, pEntry.name, "config.json");
10578
+ if (existsSync6(configPath)) {
10505
10579
  try {
10506
10580
  const config = JSON.parse(readFileSync4(configPath, "utf-8"));
10507
10581
  profiles[pEntry.name] = config;
@@ -10538,19 +10612,19 @@ Dashboard not found at: ${dashboardDir}`);
10538
10612
  return json({ error: "Invalid import format: missing 'connectors' object" }, 400, port);
10539
10613
  }
10540
10614
  let imported = 0;
10541
- const connectDir = join6(homedir4(), ".connectors");
10615
+ const connectDir = join7(homedir5(), ".connectors");
10542
10616
  for (const [connectorName, data] of Object.entries(body.connectors)) {
10543
10617
  if (!isValidConnectorName(connectorName))
10544
10618
  continue;
10545
10619
  if (!data.profiles || typeof data.profiles !== "object")
10546
10620
  continue;
10547
- const connectorDir = join6(connectDir, `connect-${connectorName}`);
10548
- const profilesDir = join6(connectorDir, "profiles");
10621
+ const connectorDir = join7(connectDir, `connect-${connectorName}`);
10622
+ const profilesDir = join7(connectorDir, "profiles");
10549
10623
  for (const [profileName, config] of Object.entries(data.profiles)) {
10550
10624
  if (!config || typeof config !== "object")
10551
10625
  continue;
10552
- mkdirSync4(profilesDir, { recursive: true });
10553
- const profileFile = join6(profilesDir, `${profileName}.json`);
10626
+ mkdirSync5(profilesDir, { recursive: true });
10627
+ const profileFile = join7(profilesDir, `${profileName}.json`);
10554
10628
  writeFileSync3(profileFile, JSON.stringify(config, null, 2));
10555
10629
  imported++;
10556
10630
  }
@@ -10606,12 +10680,12 @@ Dashboard not found at: ${dashboardDir}`);
10606
10680
  }
10607
10681
  if (dashboardExists && (method === "GET" || method === "HEAD")) {
10608
10682
  if (path !== "/") {
10609
- const filePath = join6(dashboardDir, path);
10683
+ const filePath = join7(dashboardDir, path);
10610
10684
  const res2 = serveStaticFile(filePath);
10611
10685
  if (res2)
10612
10686
  return res2;
10613
10687
  }
10614
- const indexPath = join6(dashboardDir, "index.html");
10688
+ const indexPath = join7(dashboardDir, "index.html");
10615
10689
  const res = serveStaticFile(indexPath);
10616
10690
  if (res)
10617
10691
  return res;
@@ -12155,9 +12229,9 @@ function App({ initialConnectors, overwrite = false }) {
12155
12229
  init_registry();
12156
12230
  init_installer();
12157
12231
  init_auth();
12158
- import { readdirSync as readdirSync4, existsSync as existsSync6, statSync as statSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync5 } from "fs";
12159
- import { homedir as homedir5 } from "os";
12160
- import { join as join7, relative } from "path";
12232
+ import { readdirSync as readdirSync4, existsSync as existsSync7, statSync as statSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync6 } from "fs";
12233
+ import { homedir as homedir6 } from "os";
12234
+ import { join as join8, relative } from "path";
12161
12235
 
12162
12236
  // src/lib/test-endpoints.ts
12163
12237
  var TEST_ENDPOINTS = {
@@ -12358,17 +12432,17 @@ var TEST_ENDPOINTS = {
12358
12432
  import { createInterface } from "readline";
12359
12433
 
12360
12434
  // src/lib/runner.ts
12361
- import { existsSync as existsSync4 } from "fs";
12362
- import { join as join4, dirname as dirname3 } from "path";
12435
+ import { existsSync as existsSync5 } from "fs";
12436
+ import { join as join5, dirname as dirname3 } from "path";
12363
12437
  import { fileURLToPath as fileURLToPath3 } from "url";
12364
12438
  import { spawn } from "child_process";
12365
12439
  var __dirname3 = dirname3(fileURLToPath3(import.meta.url));
12366
12440
  function resolveConnectorsDir2() {
12367
- const fromBin = join4(__dirname3, "..", "connectors");
12368
- if (existsSync4(fromBin))
12441
+ const fromBin = join5(__dirname3, "..", "connectors");
12442
+ if (existsSync5(fromBin))
12369
12443
  return fromBin;
12370
- const fromSrc = join4(__dirname3, "..", "..", "connectors");
12371
- if (existsSync4(fromSrc))
12444
+ const fromSrc = join5(__dirname3, "..", "..", "connectors");
12445
+ if (existsSync5(fromSrc))
12372
12446
  return fromSrc;
12373
12447
  return fromBin;
12374
12448
  }
@@ -12408,9 +12482,9 @@ function buildEnvWithCredentials(connectorName, baseEnv) {
12408
12482
  }
12409
12483
  function getConnectorCliPath(name) {
12410
12484
  const safeName = name.replace(/[^a-z0-9-]/g, "");
12411
- const connectorDir = join4(CONNECTORS_DIR2, `connect-${safeName}`);
12412
- const cliPath = join4(connectorDir, "src", "cli", "index.ts");
12413
- if (existsSync4(cliPath))
12485
+ const connectorDir = join5(CONNECTORS_DIR2, `connect-${safeName}`);
12486
+ const cliPath = join5(connectorDir, "src", "cli", "index.ts");
12487
+ if (existsSync5(cliPath))
12414
12488
  return cliPath;
12415
12489
  return null;
12416
12490
  }
@@ -12523,7 +12597,7 @@ Run 'connectors --help' for full usage.`);
12523
12597
  function listFilesRecursive(dir, base = dir) {
12524
12598
  const files = [];
12525
12599
  for (const entry of readdirSync4(dir)) {
12526
- const fullPath = join7(dir, entry);
12600
+ const fullPath = join8(dir, entry);
12527
12601
  if (statSync3(fullPath).isDirectory()) {
12528
12602
  files.push(...listFilesRecursive(fullPath, base));
12529
12603
  } else {
@@ -12572,7 +12646,7 @@ program2.command("install").alias("add").argument("[connectors...]", "Connectors
12572
12646
  }
12573
12647
  if (options.dryRun) {
12574
12648
  const installed = getInstalledConnectors();
12575
- const destDir = join7(process.cwd(), ".connectors");
12649
+ const destDir = join8(process.cwd(), ".connectors");
12576
12650
  const actions = [];
12577
12651
  for (const name of connectors) {
12578
12652
  if (!/^[a-z0-9-]+$/.test(name)) {
@@ -12590,7 +12664,7 @@ program2.command("install").alias("add").argument("[connectors...]", "Connectors
12590
12664
  }
12591
12665
  const connectorDirName = name.startsWith("connect-") ? name : `connect-${name}`;
12592
12666
  const sourcePath = getConnectorPath(name);
12593
- const destPath = join7(destDir, connectorDirName);
12667
+ const destPath = join8(destDir, connectorDirName);
12594
12668
  const alreadyInstalled = installed.includes(name);
12595
12669
  const files = listFilesRecursive(sourcePath);
12596
12670
  const importLine = `export * as ${name} from './${connectorDirName}/src/index.js';`;
@@ -13094,15 +13168,15 @@ Updating ${toUpdate.length} connector(s)...
13094
13168
  });
13095
13169
  program2.command("status").option("--json", "Output as JSON", false).description("Show auth status of all configured connectors (project + global)").action((options) => {
13096
13170
  const installed = getInstalledConnectors();
13097
- const configDir = join7(homedir5(), ".connectors");
13171
+ const configDir = join8(homedir6(), ".connectors");
13098
13172
  const seen = new Set;
13099
13173
  const allStatuses = [];
13100
13174
  function buildStatusEntry(name, source) {
13101
13175
  const auth = getAuthStatus(name);
13102
13176
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
13103
- const currentProfileFile = join7(configDir, connectorName, "current_profile");
13177
+ const currentProfileFile = join8(configDir, connectorName, "current_profile");
13104
13178
  let profile = "default";
13105
- if (existsSync6(currentProfileFile)) {
13179
+ if (existsSync7(currentProfileFile)) {
13106
13180
  try {
13107
13181
  profile = readFileSync5(currentProfileFile, "utf-8").trim() || "default";
13108
13182
  } catch {}
@@ -13140,13 +13214,13 @@ program2.command("status").option("--json", "Output as JSON", false).description
13140
13214
  seen.add(name);
13141
13215
  allStatuses.push(buildStatusEntry(name, "project"));
13142
13216
  }
13143
- if (existsSync6(configDir)) {
13217
+ if (existsSync7(configDir)) {
13144
13218
  try {
13145
13219
  const globalDirs = readdirSync4(configDir).filter((f) => {
13146
13220
  if (!f.startsWith("connect-"))
13147
13221
  return false;
13148
13222
  try {
13149
- return statSync3(join7(configDir, f)).isDirectory();
13223
+ return statSync3(join8(configDir, f)).isDirectory();
13150
13224
  } catch {
13151
13225
  return false;
13152
13226
  }
@@ -13420,7 +13494,7 @@ Open this URL to authenticate:
13420
13494
  return;
13421
13495
  }
13422
13496
  if (options.key) {
13423
- saveApiKey(connector, options.key, options.field || undefined);
13497
+ await saveApiKey(connector, options.key, options.field || undefined);
13424
13498
  const statusAfter2 = getAuthStatus(connector);
13425
13499
  if (options.json) {
13426
13500
  console.log(JSON.stringify({
@@ -13494,7 +13568,7 @@ Open this URL to authenticate:
13494
13568
  process.exit(1);
13495
13569
  return;
13496
13570
  }
13497
- saveApiKey(connector, key.trim(), options.field || undefined);
13571
+ await saveApiKey(connector, key.trim(), options.field || undefined);
13498
13572
  const statusAfter = getAuthStatus(connector);
13499
13573
  console.log(chalk2.green(`
13500
13574
  \u2713 API key saved for ${meta.displayName}`));
@@ -13511,15 +13585,15 @@ program2.command("init").option("--json", "Output presets and suggestions as JSO
13511
13585
  { key: "commerce", emoji: "\uD83D\uDCB3", label: "Commerce", connectors: ["stripe", "shopify", "paypal", "revolut", "mercury"], description: "Commerce and finance" },
13512
13586
  { key: "google", emoji: "\uD83D\uDCC1", label: "Google Workspace", connectors: ["gmail", "googledrive", "googlecalendar", "googledocs", "googlesheets"], description: "Google Workspace suite" }
13513
13587
  ];
13514
- const connectorsHome = join7(homedir5(), ".connectors");
13588
+ const connectorsHome = join8(homedir6(), ".connectors");
13515
13589
  let configuredCount = 0;
13516
13590
  const configuredNames = [];
13517
13591
  try {
13518
- if (existsSync6(connectorsHome)) {
13519
- const entries = readdirSync4(connectorsHome).filter((e) => e.startsWith("connect-") && statSync3(join7(connectorsHome, e)).isDirectory());
13592
+ if (existsSync7(connectorsHome)) {
13593
+ const entries = readdirSync4(connectorsHome).filter((e) => e.startsWith("connect-") && statSync3(join8(connectorsHome, e)).isDirectory());
13520
13594
  for (const entry of entries) {
13521
- const profilesDir = join7(connectorsHome, entry, "profiles");
13522
- if (existsSync6(profilesDir)) {
13595
+ const profilesDir = join8(connectorsHome, entry, "profiles");
13596
+ if (existsSync7(profilesDir)) {
13523
13597
  configuredCount++;
13524
13598
  configuredNames.push(entry.replace(/^connect-/, ""));
13525
13599
  }
@@ -13617,42 +13691,42 @@ function redactSecrets(obj) {
13617
13691
  return obj;
13618
13692
  }
13619
13693
  program2.command("export").option("-o, --output <file>", "Write to file instead of stdout").option("--include-secrets", "Include secrets in plaintext (dangerous \u2014 use only for backup/restore)").description("Export all connector credentials as JSON backup").action((options) => {
13620
- const connectDir = join7(homedir5(), ".connectors");
13694
+ const connectDir = join8(homedir6(), ".connectors");
13621
13695
  const result = {};
13622
- if (existsSync6(connectDir)) {
13696
+ if (existsSync7(connectDir)) {
13623
13697
  for (const entry of readdirSync4(connectDir)) {
13624
- const entryPath = join7(connectDir, entry);
13698
+ const entryPath = join8(connectDir, entry);
13625
13699
  if (!statSync3(entryPath).isDirectory() || !entry.startsWith("connect-"))
13626
13700
  continue;
13627
13701
  const connectorName = entry.replace(/^connect-/, "");
13628
13702
  let credentials = undefined;
13629
- const credentialsPath = join7(entryPath, "credentials.json");
13630
- if (existsSync6(credentialsPath)) {
13703
+ const credentialsPath = join8(entryPath, "credentials.json");
13704
+ if (existsSync7(credentialsPath)) {
13631
13705
  try {
13632
13706
  credentials = JSON.parse(readFileSync5(credentialsPath, "utf-8"));
13633
13707
  } catch {}
13634
13708
  }
13635
- const profilesDir = join7(entryPath, "profiles");
13636
- if (!existsSync6(profilesDir) && !credentials)
13709
+ const profilesDir = join8(entryPath, "profiles");
13710
+ if (!existsSync7(profilesDir) && !credentials)
13637
13711
  continue;
13638
13712
  const profiles = {};
13639
- if (existsSync6(profilesDir)) {
13713
+ if (existsSync7(profilesDir)) {
13640
13714
  for (const pEntry of readdirSync4(profilesDir)) {
13641
- const pPath = join7(profilesDir, pEntry);
13715
+ const pPath = join8(profilesDir, pEntry);
13642
13716
  if (statSync3(pPath).isFile() && pEntry.endsWith(".json")) {
13643
13717
  try {
13644
13718
  profiles[pEntry.replace(/\.json$/, "")] = JSON.parse(readFileSync5(pPath, "utf-8"));
13645
13719
  } catch {}
13646
13720
  } else if (statSync3(pPath).isDirectory()) {
13647
- const configPath = join7(pPath, "config.json");
13648
- const tokensPath = join7(pPath, "tokens.json");
13721
+ const configPath = join8(pPath, "config.json");
13722
+ const tokensPath = join8(pPath, "tokens.json");
13649
13723
  let merged = {};
13650
- if (existsSync6(configPath)) {
13724
+ if (existsSync7(configPath)) {
13651
13725
  try {
13652
13726
  merged = { ...merged, ...JSON.parse(readFileSync5(configPath, "utf-8")) };
13653
13727
  } catch {}
13654
13728
  }
13655
- if (existsSync6(tokensPath)) {
13729
+ if (existsSync7(tokensPath)) {
13656
13730
  try {
13657
13731
  merged = { ...merged, ...JSON.parse(readFileSync5(tokensPath, "utf-8")) };
13658
13732
  } catch {}
@@ -13689,7 +13763,7 @@ program2.command("import").argument("<file>", "JSON backup file to import (use -
13689
13763
  chunks.push(chunk.toString());
13690
13764
  raw = chunks.join("");
13691
13765
  } else {
13692
- if (!existsSync6(file)) {
13766
+ if (!existsSync7(file)) {
13693
13767
  if (options.json) {
13694
13768
  console.log(JSON.stringify({ error: `File not found: ${file}` }));
13695
13769
  } else {
@@ -13721,25 +13795,25 @@ program2.command("import").argument("<file>", "JSON backup file to import (use -
13721
13795
  process.exit(1);
13722
13796
  return;
13723
13797
  }
13724
- const connectDir = join7(homedir5(), ".connectors");
13798
+ const connectDir = join8(homedir6(), ".connectors");
13725
13799
  let imported = 0;
13726
13800
  for (const [connectorName, connData] of Object.entries(data.connectors)) {
13727
13801
  if (!/^[a-z0-9-]+$/.test(connectorName))
13728
13802
  continue;
13729
- const connectorDir = join7(connectDir, `connect-${connectorName}`);
13803
+ const connectorDir = join8(connectDir, `connect-${connectorName}`);
13730
13804
  if (connData.credentials && typeof connData.credentials === "object") {
13731
- mkdirSync5(connectorDir, { recursive: true });
13732
- writeFileSync4(join7(connectorDir, "credentials.json"), JSON.stringify(connData.credentials, null, 2));
13805
+ mkdirSync6(connectorDir, { recursive: true });
13806
+ writeFileSync4(join8(connectorDir, "credentials.json"), JSON.stringify(connData.credentials, null, 2));
13733
13807
  imported++;
13734
13808
  }
13735
13809
  if (!connData.profiles || typeof connData.profiles !== "object")
13736
13810
  continue;
13737
- const profilesDir = join7(connectorDir, "profiles");
13811
+ const profilesDir = join8(connectorDir, "profiles");
13738
13812
  for (const [profileName, config] of Object.entries(connData.profiles)) {
13739
13813
  if (!config || typeof config !== "object")
13740
13814
  continue;
13741
- mkdirSync5(profilesDir, { recursive: true });
13742
- writeFileSync4(join7(profilesDir, `${profileName}.json`), JSON.stringify(config, null, 2));
13815
+ mkdirSync6(profilesDir, { recursive: true });
13816
+ writeFileSync4(join8(profilesDir, `${profileName}.json`), JSON.stringify(config, null, 2));
13743
13817
  imported++;
13744
13818
  }
13745
13819
  }
@@ -13750,9 +13824,9 @@ program2.command("import").argument("<file>", "JSON backup file to import (use -
13750
13824
  }
13751
13825
  });
13752
13826
  program2.command("auth-import").option("--json", "Output as JSON", false).option("-d, --dry-run", "Preview what would be imported without copying", false).option("--force", "Overwrite existing files in ~/.connectors/", false).description("Migrate auth tokens from ~/.connect/ to ~/.connectors/").action((options) => {
13753
- const oldBase = join7(homedir5(), ".connect");
13754
- const newBase = join7(homedir5(), ".connectors");
13755
- if (!existsSync6(oldBase)) {
13827
+ const oldBase = join8(homedir6(), ".connect");
13828
+ const newBase = join8(homedir6(), ".connectors");
13829
+ if (!existsSync7(oldBase)) {
13756
13830
  if (options.json) {
13757
13831
  console.log(JSON.stringify({ imported: [], skipped: [], error: null, message: "No ~/.connect/ directory found" }));
13758
13832
  } else {
@@ -13764,7 +13838,7 @@ program2.command("auth-import").option("--json", "Output as JSON", false).option
13764
13838
  if (!name.startsWith("connect-"))
13765
13839
  return false;
13766
13840
  try {
13767
- return statSync3(join7(oldBase, name)).isDirectory();
13841
+ return statSync3(join8(oldBase, name)).isDirectory();
13768
13842
  } catch {
13769
13843
  return false;
13770
13844
  }
@@ -13780,8 +13854,8 @@ program2.command("auth-import").option("--json", "Output as JSON", false).option
13780
13854
  const imported = [];
13781
13855
  const skipped = [];
13782
13856
  for (const dirName of entries) {
13783
- const oldDir = join7(oldBase, dirName);
13784
- const newDir = join7(newBase, dirName);
13857
+ const oldDir = join8(oldBase, dirName);
13858
+ const newDir = join8(newBase, dirName);
13785
13859
  const connectorName = dirName.replace(/^connect-/, "");
13786
13860
  const allFiles = listFilesRecursive(oldDir);
13787
13861
  const authFiles = allFiles.filter((f) => {
@@ -13792,15 +13866,15 @@ program2.command("auth-import").option("--json", "Output as JSON", false).option
13792
13866
  const copiedFiles = [];
13793
13867
  const skippedFiles = [];
13794
13868
  for (const relFile of authFiles) {
13795
- const srcPath = join7(oldDir, relFile);
13796
- const destPath = join7(newDir, relFile);
13797
- if (existsSync6(destPath) && !options.force) {
13869
+ const srcPath = join8(oldDir, relFile);
13870
+ const destPath = join8(newDir, relFile);
13871
+ if (existsSync7(destPath) && !options.force) {
13798
13872
  skippedFiles.push(relFile);
13799
13873
  continue;
13800
13874
  }
13801
13875
  if (!options.dryRun) {
13802
- const parentDir = join7(destPath, "..");
13803
- mkdirSync5(parentDir, { recursive: true });
13876
+ const parentDir = join8(destPath, "..");
13877
+ mkdirSync6(parentDir, { recursive: true });
13804
13878
  const content = readFileSync5(srcPath);
13805
13879
  writeFileSync4(destPath, content);
13806
13880
  }
@@ -14075,7 +14149,7 @@ Available presets:
14075
14149
  `));
14076
14150
  });
14077
14151
  program2.command("whoami").option("--json", "Output as JSON", false).description("Show current setup: config dir, installed connectors, auth status").action((options) => {
14078
- const configDir = join7(homedir5(), ".connectors");
14152
+ const configDir = join8(homedir6(), ".connectors");
14079
14153
  const installed = getInstalledConnectors();
14080
14154
  const version = "0.3.1";
14081
14155
  let configured = 0;
@@ -14089,23 +14163,23 @@ program2.command("whoami").option("--json", "Output as JSON", false).description
14089
14163
  configured++;
14090
14164
  else
14091
14165
  unconfigured++;
14092
- const connectorConfigDir = join7(configDir, name.startsWith("connect-") ? name : `connect-${name}`);
14093
- const currentProfileFile = join7(connectorConfigDir, "current_profile");
14166
+ const connectorConfigDir = join8(configDir, name.startsWith("connect-") ? name : `connect-${name}`);
14167
+ const currentProfileFile = join8(connectorConfigDir, "current_profile");
14094
14168
  let profile = "default";
14095
- if (existsSync6(currentProfileFile)) {
14169
+ if (existsSync7(currentProfileFile)) {
14096
14170
  try {
14097
14171
  profile = readFileSync5(currentProfileFile, "utf-8").trim() || "default";
14098
14172
  } catch {}
14099
14173
  }
14100
14174
  connectorDetails.push({ name, configured: auth.configured, authType: auth.type, profile, source: "project" });
14101
14175
  }
14102
- if (existsSync6(configDir)) {
14176
+ if (existsSync7(configDir)) {
14103
14177
  try {
14104
14178
  const globalDirs = readdirSync4(configDir).filter((f) => {
14105
14179
  if (!f.startsWith("connect-"))
14106
14180
  return false;
14107
14181
  try {
14108
- return statSync3(join7(configDir, f)).isDirectory();
14182
+ return statSync3(join8(configDir, f)).isDirectory();
14109
14183
  } catch {
14110
14184
  return false;
14111
14185
  }
@@ -14119,9 +14193,9 @@ program2.command("whoami").option("--json", "Output as JSON", false).description
14119
14193
  continue;
14120
14194
  seen.add(name);
14121
14195
  configured++;
14122
- const currentProfileFile = join7(configDir, dir, "current_profile");
14196
+ const currentProfileFile = join8(configDir, dir, "current_profile");
14123
14197
  let profile = "default";
14124
- if (existsSync6(currentProfileFile)) {
14198
+ if (existsSync7(currentProfileFile)) {
14125
14199
  try {
14126
14200
  profile = readFileSync5(currentProfileFile, "utf-8").trim() || "default";
14127
14201
  } catch {}
@@ -14134,7 +14208,7 @@ program2.command("whoami").option("--json", "Output as JSON", false).description
14134
14208
  console.log(JSON.stringify({
14135
14209
  version,
14136
14210
  configDir,
14137
- configDirExists: existsSync6(configDir),
14211
+ configDirExists: existsSync7(configDir),
14138
14212
  installed: installed.length,
14139
14213
  configured,
14140
14214
  unconfigured,
@@ -14146,7 +14220,7 @@ program2.command("whoami").option("--json", "Output as JSON", false).description
14146
14220
  Connectors Setup
14147
14221
  `));
14148
14222
  console.log(` Version: ${chalk2.cyan(version)}`);
14149
- console.log(` Config: ${configDir}${existsSync6(configDir) ? "" : chalk2.dim(" (not created yet)")}`);
14223
+ console.log(` Config: ${configDir}${existsSync7(configDir) ? "" : chalk2.dim(" (not created yet)")}`);
14150
14224
  console.log(` Installed: ${installed.length} connector${installed.length !== 1 ? "s" : ""}`);
14151
14225
  console.log(` Configured: ${chalk2.green(String(configured))} ready, ${unconfigured > 0 ? chalk2.red(String(unconfigured)) : chalk2.dim("0")} need auth`);
14152
14226
  const projectConnectors = connectorDetails.filter((c) => c.source === "project");
@@ -14236,16 +14310,16 @@ Testing connector credentials...
14236
14310
  }
14237
14311
  }
14238
14312
  if (!apiKey) {
14239
- const connectorConfigDir = join7(homedir5(), ".connectors", name.startsWith("connect-") ? name : `connect-${name}`);
14313
+ const connectorConfigDir = join8(homedir6(), ".connectors", name.startsWith("connect-") ? name : `connect-${name}`);
14240
14314
  let currentProfile = "default";
14241
- const currentProfileFile = join7(connectorConfigDir, "current_profile");
14242
- if (existsSync6(currentProfileFile)) {
14315
+ const currentProfileFile = join8(connectorConfigDir, "current_profile");
14316
+ if (existsSync7(currentProfileFile)) {
14243
14317
  try {
14244
14318
  currentProfile = readFileSync5(currentProfileFile, "utf-8").trim() || "default";
14245
14319
  } catch {}
14246
14320
  }
14247
- const tokensFile = join7(connectorConfigDir, "profiles", currentProfile, "tokens.json");
14248
- if (existsSync6(tokensFile)) {
14321
+ const tokensFile = join8(connectorConfigDir, "profiles", currentProfile, "tokens.json");
14322
+ if (existsSync7(tokensFile)) {
14249
14323
  try {
14250
14324
  const tokens = JSON.parse(readFileSync5(tokensFile, "utf-8"));
14251
14325
  const isExpired = tokens.expiresAt && Date.now() >= tokens.expiresAt - 60000;
@@ -14265,8 +14339,8 @@ Testing connector credentials...
14265
14339
  } catch {}
14266
14340
  }
14267
14341
  if (!apiKey) {
14268
- const profileFile = join7(connectorConfigDir, "profiles", `${currentProfile}.json`);
14269
- if (existsSync6(profileFile)) {
14342
+ const profileFile = join8(connectorConfigDir, "profiles", `${currentProfile}.json`);
14343
+ if (existsSync7(profileFile)) {
14270
14344
  try {
14271
14345
  const config = JSON.parse(readFileSync5(profileFile, "utf-8"));
14272
14346
  apiKey = Object.values(config).find((v) => typeof v === "string" && v.length > 0);
@@ -14274,8 +14348,8 @@ Testing connector credentials...
14274
14348
  }
14275
14349
  }
14276
14350
  if (!apiKey) {
14277
- const profileDirConfig = join7(connectorConfigDir, "profiles", currentProfile, "config.json");
14278
- if (existsSync6(profileDirConfig)) {
14351
+ const profileDirConfig = join8(connectorConfigDir, "profiles", currentProfile, "config.json");
14352
+ if (existsSync7(profileDirConfig)) {
14279
14353
  try {
14280
14354
  const config = JSON.parse(readFileSync5(profileDirConfig, "utf-8"));
14281
14355
  apiKey = Object.values(config).find((v) => typeof v === "string" && v.length > 0);
@@ -14444,7 +14518,7 @@ Setting up ${meta.displayName}...
14444
14518
  const alreadyInstalled = installed.includes(meta.name);
14445
14519
  let installResult;
14446
14520
  if (alreadyInstalled && !options.overwrite) {
14447
- installResult = { success: true, path: join7(process.cwd(), ".connectors", `connect-${meta.name}`) };
14521
+ installResult = { success: true, path: join8(process.cwd(), ".connectors", `connect-${meta.name}`) };
14448
14522
  if (!options.json) {
14449
14523
  console.log(` ${chalk2.green("\u2713")} Already installed`);
14450
14524
  }
@@ -14469,7 +14543,7 @@ Setting up ${meta.displayName}...
14469
14543
  let authConfigured = false;
14470
14544
  if (authType === "oauth") {
14471
14545
  if (options.key) {
14472
- saveApiKey(name, options.key, options.field || undefined);
14546
+ await saveApiKey(name, options.key, options.field || undefined);
14473
14547
  authConfigured = true;
14474
14548
  if (!options.json) {
14475
14549
  console.log(` ${chalk2.green("\u2713")} Token saved`);
@@ -14527,7 +14601,7 @@ Setting up ${meta.displayName}...
14527
14601
  }
14528
14602
  } else {
14529
14603
  if (options.key) {
14530
- saveApiKey(name, options.key, options.field || undefined);
14604
+ await saveApiKey(name, options.key, options.field || undefined);
14531
14605
  authConfigured = true;
14532
14606
  if (!options.json) {
14533
14607
  console.log(` ${chalk2.green("\u2713")} ${authType === "bearer" ? "Bearer token" : "API key"} saved`);