@hasna/connectors 1.1.12 → 1.1.13

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/mcp.js CHANGED
@@ -26,6 +26,7 @@ var __export = (target, all) => {
26
26
  set: (newValue) => all[name] = () => newValue
27
27
  });
28
28
  };
29
+ var __require = import.meta.require;
29
30
 
30
31
  // node_modules/ajv/dist/compile/codegen/code.js
31
32
  var require_code = __commonJS((exports) => {
@@ -25571,9 +25572,79 @@ function removeConnector(name, targetDir = process.cwd()) {
25571
25572
  }
25572
25573
 
25573
25574
  // src/server/auth.ts
25574
- import { existsSync as existsSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2 } from "fs";
25575
- import { homedir as homedir2 } from "os";
25575
+ import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync3, readdirSync as readdirSync2, rmSync as rmSync2, statSync as statSync2 } from "fs";
25576
+ import { homedir as homedir3 } from "os";
25577
+ import { join as join4 } from "path";
25578
+
25579
+ // src/lib/lock.ts
25580
+ import { openSync, closeSync, unlinkSync, existsSync as existsSync3 } from "fs";
25576
25581
  import { join as join3 } from "path";
25582
+ import { homedir as homedir2 } from "os";
25583
+ import { mkdirSync as mkdirSync2 } from "fs";
25584
+ var LOCK_TIMEOUT_MS = 5000;
25585
+ var LOCK_RETRY_MS = 100;
25586
+ var STALE_LOCK_MS = 30000;
25587
+
25588
+ class LockTimeoutError extends Error {
25589
+ connector;
25590
+ constructor(connector) {
25591
+ super(`Could not acquire write lock for connector "${connector}" within ${LOCK_TIMEOUT_MS}ms. Another agent may be writing. Try again shortly.`);
25592
+ this.connector = connector;
25593
+ this.name = "LockTimeoutError";
25594
+ }
25595
+ }
25596
+ function lockPath(connector) {
25597
+ const dir = join3(homedir2(), ".connectors", `connect-${connector}`);
25598
+ mkdirSync2(dir, { recursive: true });
25599
+ return join3(dir, ".write.lock");
25600
+ }
25601
+ function isStale(path) {
25602
+ try {
25603
+ const { statSync: statSync2 } = __require("fs");
25604
+ const stat = statSync2(path);
25605
+ return Date.now() - stat.mtimeMs > STALE_LOCK_MS;
25606
+ } catch {
25607
+ return false;
25608
+ }
25609
+ }
25610
+ function tryAcquire(path) {
25611
+ if (existsSync3(path) && isStale(path)) {
25612
+ try {
25613
+ unlinkSync(path);
25614
+ } catch {}
25615
+ }
25616
+ try {
25617
+ const fd = openSync(path, "wx");
25618
+ closeSync(fd);
25619
+ return true;
25620
+ } catch (e) {
25621
+ if (e.code === "EEXIST")
25622
+ return false;
25623
+ throw e;
25624
+ }
25625
+ }
25626
+ function release(path) {
25627
+ try {
25628
+ unlinkSync(path);
25629
+ } catch {}
25630
+ }
25631
+ async function withWriteLock(connector, fn) {
25632
+ const path = lockPath(connector);
25633
+ const deadline = Date.now() + LOCK_TIMEOUT_MS;
25634
+ while (Date.now() < deadline) {
25635
+ if (tryAcquire(path)) {
25636
+ try {
25637
+ return await fn();
25638
+ } finally {
25639
+ release(path);
25640
+ }
25641
+ }
25642
+ await new Promise((resolve) => setTimeout(resolve, LOCK_RETRY_MS));
25643
+ }
25644
+ throw new LockTimeoutError(connector);
25645
+ }
25646
+
25647
+ // src/server/auth.ts
25577
25648
  var oauthStateStore = new Map;
25578
25649
  var GOOGLE_SCOPES = {
25579
25650
  gmail: [
@@ -25626,12 +25697,12 @@ function getAuthType(name) {
25626
25697
  }
25627
25698
  function getConnectorConfigDir(name) {
25628
25699
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
25629
- return join3(homedir2(), ".connectors", connectorName);
25700
+ return join4(homedir3(), ".connectors", connectorName);
25630
25701
  }
25631
25702
  function getCurrentProfile(name) {
25632
25703
  const configDir = getConnectorConfigDir(name);
25633
- const currentProfileFile = join3(configDir, "current_profile");
25634
- if (existsSync3(currentProfileFile)) {
25704
+ const currentProfileFile = join4(configDir, "current_profile");
25705
+ if (existsSync4(currentProfileFile)) {
25635
25706
  try {
25636
25707
  return readFileSync3(currentProfileFile, "utf-8").trim() || "default";
25637
25708
  } catch {
@@ -25645,14 +25716,14 @@ function loadProfileConfig(name) {
25645
25716
  const profile = getCurrentProfile(name);
25646
25717
  let flatConfig = {};
25647
25718
  let dirConfig = {};
25648
- const profileFile = join3(configDir, "profiles", `${profile}.json`);
25649
- if (existsSync3(profileFile)) {
25719
+ const profileFile = join4(configDir, "profiles", `${profile}.json`);
25720
+ if (existsSync4(profileFile)) {
25650
25721
  try {
25651
25722
  flatConfig = JSON.parse(readFileSync3(profileFile, "utf-8"));
25652
25723
  } catch {}
25653
25724
  }
25654
- const profileDirConfig = join3(configDir, "profiles", profile, "config.json");
25655
- if (existsSync3(profileDirConfig)) {
25725
+ const profileDirConfig = join4(configDir, "profiles", profile, "config.json");
25726
+ if (existsSync4(profileDirConfig)) {
25656
25727
  try {
25657
25728
  dirConfig = JSON.parse(readFileSync3(profileDirConfig, "utf-8"));
25658
25729
  } catch {}
@@ -25665,8 +25736,8 @@ function loadProfileConfig(name) {
25665
25736
  function loadTokens(name) {
25666
25737
  const configDir = getConnectorConfigDir(name);
25667
25738
  const profile = getCurrentProfile(name);
25668
- const tokensFile = join3(configDir, "profiles", profile, "tokens.json");
25669
- if (existsSync3(tokensFile)) {
25739
+ const tokensFile = join4(configDir, "profiles", profile, "tokens.json");
25740
+ if (existsSync4(tokensFile)) {
25670
25741
  try {
25671
25742
  return JSON.parse(readFileSync3(tokensFile, "utf-8"));
25672
25743
  } catch {
@@ -25713,15 +25784,18 @@ function getAuthStatus(name) {
25713
25784
  envVarTotalCount
25714
25785
  };
25715
25786
  }
25716
- function saveApiKey(name, key, field) {
25787
+ async function saveApiKey(name, key, field) {
25788
+ return withWriteLock(name, () => _saveApiKey(name, key, field));
25789
+ }
25790
+ function _saveApiKey(name, key, field) {
25717
25791
  const configDir = getConnectorConfigDir(name);
25718
25792
  const profile = getCurrentProfile(name);
25719
25793
  const keyField = field || guessKeyField(name);
25720
25794
  if (keyField === "clientId" || keyField === "clientSecret") {
25721
- const credentialsFile = join3(configDir, "credentials.json");
25722
- mkdirSync2(configDir, { recursive: true });
25795
+ const credentialsFile = join4(configDir, "credentials.json");
25796
+ mkdirSync3(configDir, { recursive: true });
25723
25797
  let creds = {};
25724
- if (existsSync3(credentialsFile)) {
25798
+ if (existsSync4(credentialsFile)) {
25725
25799
  try {
25726
25800
  creds = JSON.parse(readFileSync3(credentialsFile, "utf-8"));
25727
25801
  } catch {}
@@ -25730,9 +25804,9 @@ function saveApiKey(name, key, field) {
25730
25804
  writeFileSync2(credentialsFile, JSON.stringify(creds, null, 2));
25731
25805
  return;
25732
25806
  }
25733
- const profileFile = join3(configDir, "profiles", `${profile}.json`);
25734
- const profileDir = join3(configDir, "profiles", profile);
25735
- if (existsSync3(profileFile)) {
25807
+ const profileFile = join4(configDir, "profiles", `${profile}.json`);
25808
+ const profileDir = join4(configDir, "profiles", profile);
25809
+ if (existsSync4(profileFile)) {
25736
25810
  let config2 = {};
25737
25811
  try {
25738
25812
  config2 = JSON.parse(readFileSync3(profileFile, "utf-8"));
@@ -25741,10 +25815,10 @@ function saveApiKey(name, key, field) {
25741
25815
  writeFileSync2(profileFile, JSON.stringify(config2, null, 2));
25742
25816
  return;
25743
25817
  }
25744
- if (existsSync3(profileDir)) {
25745
- const configFile = join3(profileDir, "config.json");
25818
+ if (existsSync4(profileDir)) {
25819
+ const configFile = join4(profileDir, "config.json");
25746
25820
  let config2 = {};
25747
- if (existsSync3(configFile)) {
25821
+ if (existsSync4(configFile)) {
25748
25822
  try {
25749
25823
  config2 = JSON.parse(readFileSync3(configFile, "utf-8"));
25750
25824
  } catch {}
@@ -25753,8 +25827,8 @@ function saveApiKey(name, key, field) {
25753
25827
  writeFileSync2(configFile, JSON.stringify(config2, null, 2));
25754
25828
  return;
25755
25829
  }
25756
- mkdirSync2(profileDir, { recursive: true });
25757
- writeFileSync2(join3(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
25830
+ mkdirSync3(profileDir, { recursive: true });
25831
+ writeFileSync2(join4(profileDir, "config.json"), JSON.stringify({ [keyField]: key }, null, 2));
25758
25832
  }
25759
25833
  function guessKeyField(name) {
25760
25834
  const docs = getConnectorDocs(name);
@@ -25772,17 +25846,17 @@ function guessKeyField(name) {
25772
25846
  }
25773
25847
 
25774
25848
  // src/lib/runner.ts
25775
- import { existsSync as existsSync4 } from "fs";
25776
- import { join as join4, dirname as dirname3 } from "path";
25849
+ import { existsSync as existsSync5 } from "fs";
25850
+ import { join as join5, dirname as dirname3 } from "path";
25777
25851
  import { fileURLToPath as fileURLToPath3 } from "url";
25778
25852
  import { spawn } from "child_process";
25779
25853
  var __dirname3 = dirname3(fileURLToPath3(import.meta.url));
25780
25854
  function resolveConnectorsDir2() {
25781
- const fromBin = join4(__dirname3, "..", "connectors");
25782
- if (existsSync4(fromBin))
25855
+ const fromBin = join5(__dirname3, "..", "connectors");
25856
+ if (existsSync5(fromBin))
25783
25857
  return fromBin;
25784
- const fromSrc = join4(__dirname3, "..", "..", "connectors");
25785
- if (existsSync4(fromSrc))
25858
+ const fromSrc = join5(__dirname3, "..", "..", "connectors");
25859
+ if (existsSync5(fromSrc))
25786
25860
  return fromSrc;
25787
25861
  return fromBin;
25788
25862
  }
@@ -25822,9 +25896,9 @@ function buildEnvWithCredentials(connectorName, baseEnv) {
25822
25896
  }
25823
25897
  function getConnectorCliPath(name) {
25824
25898
  const safeName = name.replace(/[^a-z0-9-]/g, "");
25825
- const connectorDir = join4(CONNECTORS_DIR2, `connect-${safeName}`);
25826
- const cliPath = join4(connectorDir, "src", "cli", "index.ts");
25827
- if (existsSync4(cliPath))
25899
+ const connectorDir = join5(CONNECTORS_DIR2, `connect-${safeName}`);
25900
+ const cliPath = join5(connectorDir, "src", "cli", "index.ts");
25901
+ if (existsSync5(cliPath))
25828
25902
  return cliPath;
25829
25903
  return null;
25830
25904
  }
@@ -25905,17 +25979,17 @@ async function getConnectorCommandHelp(name, command) {
25905
25979
 
25906
25980
  // src/db/database.ts
25907
25981
  import { Database } from "bun:sqlite";
25908
- import { join as join5 } from "path";
25909
- import { homedir as homedir3 } from "os";
25910
- import { mkdirSync as mkdirSync3 } from "fs";
25911
- var DB_DIR = join5(homedir3(), ".connectors");
25912
- var DB_PATH = join5(DB_DIR, "connectors.db");
25982
+ import { join as join6 } from "path";
25983
+ import { homedir as homedir4 } from "os";
25984
+ import { mkdirSync as mkdirSync4 } from "fs";
25985
+ var DB_DIR = join6(homedir4(), ".connectors");
25986
+ var DB_PATH = join6(DB_DIR, "connectors.db");
25913
25987
  var _db = null;
25914
25988
  function getDatabase(path) {
25915
25989
  if (_db)
25916
25990
  return _db;
25917
25991
  const dbPath = path ?? DB_PATH;
25918
- mkdirSync3(join5(dbPath, ".."), { recursive: true });
25992
+ mkdirSync4(join6(dbPath, ".."), { recursive: true });
25919
25993
  _db = new Database(dbPath);
25920
25994
  _db.run("PRAGMA journal_mode = WAL");
25921
25995
  migrate(_db);
@@ -25997,7 +26071,7 @@ function listAgents(db) {
25997
26071
  // package.json
25998
26072
  var package_default = {
25999
26073
  name: "@hasna/connectors",
26000
- version: "1.1.12",
26074
+ version: "1.1.13",
26001
26075
  description: "Open source connector library - Install API connectors with a single command",
26002
26076
  type: "module",
26003
26077
  bin: {
@@ -26295,7 +26369,7 @@ server.registerTool("configure_auth", {
26295
26369
  }
26296
26370
  }, async ({ name, key, field }) => {
26297
26371
  try {
26298
- saveApiKey(name, key, field);
26372
+ await saveApiKey(name, key, field);
26299
26373
  return {
26300
26374
  content: [
26301
26375
  {
@@ -26485,7 +26559,7 @@ server.registerTool("setup_connector", {
26485
26559
  }
26486
26560
  if (key) {
26487
26561
  try {
26488
- saveApiKey(name, key, field);
26562
+ await saveApiKey(name, key, field);
26489
26563
  } catch (error2) {
26490
26564
  return {
26491
26565
  content: [