@hasna/connectors 0.0.2 → 0.0.4

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.
Files changed (3) hide show
  1. package/bin/index.js +513 -125
  2. package/dist/index.js +49 -22
  3. package/package.json +1 -1
package/bin/index.js CHANGED
@@ -3952,6 +3952,9 @@ function Header({ title = "Connectors", subtitle }) {
3952
3952
  import { Box as Box4, Text as Text4 } from "ink";
3953
3953
 
3954
3954
  // src/lib/registry.ts
3955
+ import { existsSync, readFileSync } from "fs";
3956
+ import { join, dirname } from "path";
3957
+ import { fileURLToPath } from "url";
3955
3958
  var CATEGORIES = [
3956
3959
  "AI & ML",
3957
3960
  "Developer Tools",
@@ -4415,6 +4418,32 @@ function searchConnectors(query) {
4415
4418
  const q = query.toLowerCase();
4416
4419
  return CONNECTORS.filter((c) => c.name.toLowerCase().includes(q) || c.displayName.toLowerCase().includes(q) || c.description.toLowerCase().includes(q) || c.tags.some((t) => t.includes(q)));
4417
4420
  }
4421
+ function getConnector(name) {
4422
+ return CONNECTORS.find((c) => c.name === name);
4423
+ }
4424
+ var versionsLoaded = false;
4425
+ function loadConnectorVersions() {
4426
+ if (versionsLoaded)
4427
+ return;
4428
+ versionsLoaded = true;
4429
+ const thisDir = dirname(fileURLToPath(import.meta.url));
4430
+ const candidates = [
4431
+ join(thisDir, "..", "connectors"),
4432
+ join(thisDir, "..", "..", "connectors")
4433
+ ];
4434
+ const connectorsDir = candidates.find((d) => existsSync(d));
4435
+ if (!connectorsDir)
4436
+ return;
4437
+ for (const connector of CONNECTORS) {
4438
+ try {
4439
+ const pkgPath = join(connectorsDir, `connect-${connector.name}`, "package.json");
4440
+ if (existsSync(pkgPath)) {
4441
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
4442
+ connector.version = pkg.version || "0.0.0";
4443
+ }
4444
+ } catch {}
4445
+ }
4446
+ }
4418
4447
 
4419
4448
  // src/cli/components/CategorySelect.tsx
4420
4449
  import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
@@ -4450,9 +4479,12 @@ function CategorySelect({ onSelect, onBack }) {
4450
4479
  }
4451
4480
 
4452
4481
  // src/cli/components/ConnectorSelect.tsx
4453
- import { useState as useState2 } from "react";
4454
- import { Box as Box5, Text as Text5 } from "ink";
4455
- import { jsxDEV as jsxDEV3, Fragment } from "react/jsx-dev-runtime";
4482
+ import { useState as useState2, useMemo } from "react";
4483
+ import { Box as Box5, Text as Text5, useInput as useInput2 } from "ink";
4484
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
4485
+ var COL_CHECK = 5;
4486
+ var COL_NAME = 20;
4487
+ var COL_VERSION = 10;
4456
4488
  function ConnectorSelect({
4457
4489
  connectors,
4458
4490
  selected,
@@ -4460,79 +4492,173 @@ function ConnectorSelect({
4460
4492
  onConfirm,
4461
4493
  onBack
4462
4494
  }) {
4463
- const items = [
4464
- { label: "\u2190 Back to categories", value: "__back__" },
4465
- ...connectors.map((c) => ({
4466
- label: `${selected.has(c.name) ? "[x]" : "[ ]"} ${c.displayName}`,
4467
- value: c.name
4468
- })),
4469
- { label: "", value: "__sep__" },
4470
- {
4471
- label: `\u2713 Install selected (${selected.size})`,
4472
- value: "__confirm__"
4473
- }
4474
- ];
4475
- const handleSelect = (item) => {
4476
- if (item.value === "__back__") {
4477
- onBack();
4478
- } else if (item.value === "__confirm__") {
4479
- if (selected.size > 0) {
4480
- onConfirm();
4495
+ const totalItems = connectors.length + 2;
4496
+ const [cursor, setCursor] = useState2(0);
4497
+ const maxVisible = 16;
4498
+ const scrollOffset = useMemo(() => {
4499
+ if (totalItems <= maxVisible)
4500
+ return 0;
4501
+ const half = Math.floor(maxVisible / 2);
4502
+ if (cursor < half)
4503
+ return 0;
4504
+ if (cursor > totalItems - maxVisible + half)
4505
+ return totalItems - maxVisible;
4506
+ return cursor - half;
4507
+ }, [cursor, totalItems]);
4508
+ useInput2((input, key) => {
4509
+ if (key.upArrow) {
4510
+ setCursor((c) => c > 0 ? c - 1 : totalItems - 1);
4511
+ } else if (key.downArrow) {
4512
+ setCursor((c) => c < totalItems - 1 ? c + 1 : 0);
4513
+ } else if (key.return) {
4514
+ if (cursor === 0) {
4515
+ onBack();
4516
+ } else if (cursor === totalItems - 1) {
4517
+ if (selected.size > 0)
4518
+ onConfirm();
4519
+ } else {
4520
+ onToggle(connectors[cursor - 1].name);
4481
4521
  }
4482
- } else if (item.value !== "__sep__") {
4483
- onToggle(item.value);
4522
+ } else if (input === " " && cursor > 0 && cursor < totalItems - 1) {
4523
+ onToggle(connectors[cursor - 1].name);
4484
4524
  }
4485
- };
4486
- const [highlightedIndex, setHighlightedIndex] = useState2(1);
4487
- const currentConnector = connectors[highlightedIndex - 1];
4525
+ });
4526
+ const visibleStart = scrollOffset;
4527
+ const visibleEnd = Math.min(scrollOffset + maxVisible, totalItems);
4488
4528
  return /* @__PURE__ */ jsxDEV3(Box5, {
4489
4529
  flexDirection: "column",
4490
4530
  children: [
4491
4531
  /* @__PURE__ */ jsxDEV3(Text5, {
4492
4532
  bold: true,
4493
4533
  marginBottom: 1,
4494
- children: "Select connectors (space to toggle, enter to confirm):"
4534
+ children: "Select connectors to install:"
4495
4535
  }, undefined, false, undefined, this),
4496
4536
  /* @__PURE__ */ jsxDEV3(Box5, {
4497
- flexDirection: "row",
4498
4537
  children: [
4499
4538
  /* @__PURE__ */ jsxDEV3(Box5, {
4500
- flexDirection: "column",
4501
- width: "50%",
4502
- children: /* @__PURE__ */ jsxDEV3(SelectInput_default, {
4503
- items,
4504
- onSelect: handleSelect,
4505
- onHighlight: (item) => {
4506
- const idx = connectors.findIndex((c) => c.name === item.value);
4507
- if (idx >= 0)
4508
- setHighlightedIndex(idx + 1);
4509
- }
4539
+ width: COL_CHECK,
4540
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4541
+ dimColor: true,
4542
+ children: " "
4510
4543
  }, undefined, false, undefined, this)
4511
4544
  }, undefined, false, undefined, this),
4512
4545
  /* @__PURE__ */ jsxDEV3(Box5, {
4513
- flexDirection: "column",
4514
- marginLeft: 2,
4515
- width: "50%",
4516
- children: currentConnector && /* @__PURE__ */ jsxDEV3(Fragment, {
4546
+ width: COL_NAME,
4547
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4548
+ bold: true,
4549
+ dimColor: true,
4550
+ children: "Connector"
4551
+ }, undefined, false, undefined, this)
4552
+ }, undefined, false, undefined, this),
4553
+ /* @__PURE__ */ jsxDEV3(Box5, {
4554
+ width: COL_VERSION,
4555
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4556
+ bold: true,
4557
+ dimColor: true,
4558
+ children: "Version"
4559
+ }, undefined, false, undefined, this)
4560
+ }, undefined, false, undefined, this),
4561
+ /* @__PURE__ */ jsxDEV3(Text5, {
4562
+ bold: true,
4563
+ dimColor: true,
4564
+ children: "Description"
4565
+ }, undefined, false, undefined, this)
4566
+ ]
4567
+ }, undefined, true, undefined, this),
4568
+ /* @__PURE__ */ jsxDEV3(Box5, {
4569
+ marginBottom: 0,
4570
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4571
+ dimColor: true,
4572
+ children: "\u2500".repeat(70)
4573
+ }, undefined, false, undefined, this)
4574
+ }, undefined, false, undefined, this),
4575
+ visibleStart > 0 && /* @__PURE__ */ jsxDEV3(Text5, {
4576
+ dimColor: true,
4577
+ children: [
4578
+ " \u2191 ",
4579
+ visibleStart,
4580
+ " more"
4581
+ ]
4582
+ }, undefined, true, undefined, this),
4583
+ Array.from({ length: visibleEnd - visibleStart }, (_, i) => {
4584
+ const idx = visibleStart + i;
4585
+ if (idx === 0) {
4586
+ const isActive2 = cursor === 0;
4587
+ return /* @__PURE__ */ jsxDEV3(Box5, {
4588
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4589
+ color: isActive2 ? "cyan" : undefined,
4590
+ bold: isActive2,
4517
4591
  children: [
4518
- /* @__PURE__ */ jsxDEV3(Text5, {
4519
- bold: true,
4520
- color: "cyan",
4521
- children: currentConnector.displayName
4522
- }, undefined, false, undefined, this),
4523
- /* @__PURE__ */ jsxDEV3(Text5, {
4524
- children: currentConnector.description
4525
- }, undefined, false, undefined, this),
4526
- /* @__PURE__ */ jsxDEV3(Text5, {
4527
- dimColor: true,
4528
- children: [
4529
- "Tags: ",
4530
- currentConnector.tags.join(", ")
4531
- ]
4532
- }, undefined, true, undefined, this)
4592
+ isActive2 ? "\u276F " : " ",
4593
+ "\u2190 Back to categories"
4533
4594
  ]
4534
4595
  }, undefined, true, undefined, this)
4535
- }, undefined, false, undefined, this)
4596
+ }, "__back__", false, undefined, this);
4597
+ }
4598
+ if (idx === totalItems - 1) {
4599
+ const isActive2 = cursor === totalItems - 1;
4600
+ const hasSelection = selected.size > 0;
4601
+ return /* @__PURE__ */ jsxDEV3(Box5, {
4602
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4603
+ color: isActive2 ? hasSelection ? "green" : "gray" : hasSelection ? "green" : "gray",
4604
+ bold: isActive2,
4605
+ dimColor: !hasSelection,
4606
+ children: [
4607
+ isActive2 ? "\u276F " : " ",
4608
+ "\u2713 Install selected (",
4609
+ selected.size,
4610
+ ")"
4611
+ ]
4612
+ }, undefined, true, undefined, this)
4613
+ }, "__confirm__", false, undefined, this);
4614
+ }
4615
+ const c = connectors[idx - 1];
4616
+ const isActive = cursor === idx;
4617
+ const isChecked = selected.has(c.name);
4618
+ return /* @__PURE__ */ jsxDEV3(Box5, {
4619
+ children: [
4620
+ /* @__PURE__ */ jsxDEV3(Box5, {
4621
+ width: 2,
4622
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4623
+ color: isActive ? "cyan" : undefined,
4624
+ children: isActive ? "\u276F" : " "
4625
+ }, undefined, false, undefined, this)
4626
+ }, undefined, false, undefined, this),
4627
+ /* @__PURE__ */ jsxDEV3(Box5, {
4628
+ width: COL_CHECK - 2,
4629
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4630
+ color: isChecked ? "green" : "gray",
4631
+ children: isChecked ? "[\u2713]" : "[ ]"
4632
+ }, undefined, false, undefined, this)
4633
+ }, undefined, false, undefined, this),
4634
+ /* @__PURE__ */ jsxDEV3(Box5, {
4635
+ width: COL_NAME,
4636
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4637
+ bold: isActive,
4638
+ color: isActive ? "cyan" : undefined,
4639
+ children: c.name
4640
+ }, undefined, false, undefined, this)
4641
+ }, undefined, false, undefined, this),
4642
+ /* @__PURE__ */ jsxDEV3(Box5, {
4643
+ width: COL_VERSION,
4644
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4645
+ dimColor: true,
4646
+ children: c.version || "-"
4647
+ }, undefined, false, undefined, this)
4648
+ }, undefined, false, undefined, this),
4649
+ /* @__PURE__ */ jsxDEV3(Text5, {
4650
+ wrap: "truncate",
4651
+ children: c.description
4652
+ }, undefined, false, undefined, this)
4653
+ ]
4654
+ }, c.name, true, undefined, this);
4655
+ }),
4656
+ visibleEnd < totalItems && /* @__PURE__ */ jsxDEV3(Text5, {
4657
+ dimColor: true,
4658
+ children: [
4659
+ " \u2193 ",
4660
+ totalItems - visibleEnd,
4661
+ " more"
4536
4662
  ]
4537
4663
  }, undefined, true, undefined, this),
4538
4664
  selected.size > 0 && /* @__PURE__ */ jsxDEV3(Box5, {
@@ -4544,13 +4670,20 @@ function ConnectorSelect({
4544
4670
  Array.from(selected).join(", ")
4545
4671
  ]
4546
4672
  }, undefined, true, undefined, this)
4673
+ }, undefined, false, undefined, this),
4674
+ /* @__PURE__ */ jsxDEV3(Box5, {
4675
+ marginTop: 1,
4676
+ children: /* @__PURE__ */ jsxDEV3(Text5, {
4677
+ dimColor: true,
4678
+ children: "\u2191\u2193 navigate space toggle enter confirm esc back"
4679
+ }, undefined, false, undefined, this)
4547
4680
  }, undefined, false, undefined, this)
4548
4681
  ]
4549
4682
  }, undefined, true, undefined, this);
4550
4683
  }
4551
4684
 
4552
4685
  // src/cli/components/SearchView.tsx
4553
- import { useState as useState4, useEffect as useEffect3 } from "react";
4686
+ import { useState as useState4, useEffect as useEffect3, useMemo as useMemo2 } from "react";
4554
4687
  import { Box as Box6, Text as Text7, useInput as useInput4 } from "ink";
4555
4688
 
4556
4689
  // node_modules/ink-text-input/build/index.js
@@ -4647,6 +4780,9 @@ var build_default = TextInput;
4647
4780
 
4648
4781
  // src/cli/components/SearchView.tsx
4649
4782
  import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
4783
+ var COL_CHECK2 = 5;
4784
+ var COL_NAME2 = 20;
4785
+ var COL_VERSION2 = 10;
4650
4786
  function SearchView({
4651
4787
  selected,
4652
4788
  onToggle,
@@ -4656,13 +4792,28 @@ function SearchView({
4656
4792
  const [query, setQuery] = useState4("");
4657
4793
  const [results, setResults] = useState4([]);
4658
4794
  const [mode, setMode] = useState4("search");
4795
+ const [cursor, setCursor] = useState4(0);
4659
4796
  useEffect3(() => {
4660
4797
  if (query.length >= 2) {
4661
4798
  setResults(searchConnectors(query));
4799
+ setCursor(0);
4662
4800
  } else {
4663
4801
  setResults([]);
4664
4802
  }
4665
4803
  }, [query]);
4804
+ const hasConfirm = selected.size > 0;
4805
+ const totalItems = results.length + 1 + (hasConfirm ? 1 : 0);
4806
+ const maxVisible = 14;
4807
+ const scrollOffset = useMemo2(() => {
4808
+ if (totalItems <= maxVisible)
4809
+ return 0;
4810
+ const half = Math.floor(maxVisible / 2);
4811
+ if (cursor < half)
4812
+ return 0;
4813
+ if (cursor > totalItems - maxVisible + half)
4814
+ return totalItems - maxVisible;
4815
+ return cursor - half;
4816
+ }, [cursor, totalItems]);
4666
4817
  useInput4((input, key) => {
4667
4818
  if (key.escape) {
4668
4819
  if (mode === "select") {
@@ -4670,34 +4821,43 @@ function SearchView({
4670
4821
  } else {
4671
4822
  onBack();
4672
4823
  }
4824
+ return;
4673
4825
  }
4674
- if (key.downArrow && mode === "search" && results.length > 0) {
4675
- setMode("select");
4826
+ if (mode === "search") {
4827
+ if (key.downArrow && results.length > 0) {
4828
+ setMode("select");
4829
+ setCursor(0);
4830
+ }
4831
+ return;
4676
4832
  }
4677
- });
4678
- const items = [
4679
- { label: "\u2190 Back", value: "__back__" },
4680
- ...results.map((c) => ({
4681
- label: `${selected.has(c.name) ? "[x]" : "[ ]"} ${c.displayName} - ${c.description}`,
4682
- value: c.name
4683
- }))
4684
- ];
4685
- if (selected.size > 0) {
4686
- items.push({ label: "", value: "__sep__" });
4687
- items.push({
4688
- label: `\u2713 Install selected (${selected.size})`,
4689
- value: "__confirm__"
4690
- });
4691
- }
4692
- const handleSelect = (item) => {
4693
- if (item.value === "__back__") {
4694
- onBack();
4695
- } else if (item.value === "__confirm__") {
4696
- onConfirm();
4697
- } else if (item.value !== "__sep__") {
4698
- onToggle(item.value);
4833
+ if (key.upArrow) {
4834
+ if (cursor === 0) {
4835
+ setMode("search");
4836
+ } else {
4837
+ setCursor((c) => c - 1);
4838
+ }
4839
+ } else if (key.downArrow) {
4840
+ setCursor((c) => c < totalItems - 1 ? c + 1 : c);
4841
+ } else if (key.return) {
4842
+ if (cursor === 0) {
4843
+ onBack();
4844
+ } else if (hasConfirm && cursor === totalItems - 1) {
4845
+ onConfirm();
4846
+ } else {
4847
+ const connectorIdx = cursor - 1;
4848
+ if (connectorIdx < results.length) {
4849
+ onToggle(results[connectorIdx].name);
4850
+ }
4851
+ }
4852
+ } else if (input === " " && cursor > 0) {
4853
+ const connectorIdx = cursor - 1;
4854
+ if (connectorIdx < results.length) {
4855
+ onToggle(results[connectorIdx].name);
4856
+ }
4699
4857
  }
4700
- };
4858
+ });
4859
+ const visibleStart = scrollOffset;
4860
+ const visibleEnd = Math.min(scrollOffset + maxVisible, totalItems);
4701
4861
  return /* @__PURE__ */ jsxDEV4(Box6, {
4702
4862
  flexDirection: "column",
4703
4863
  children: [
@@ -4711,7 +4871,8 @@ function SearchView({
4711
4871
  /* @__PURE__ */ jsxDEV4(build_default, {
4712
4872
  value: query,
4713
4873
  onChange: setQuery,
4714
- placeholder: "Type to search connectors..."
4874
+ placeholder: "Type to search connectors...",
4875
+ focus: mode === "search"
4715
4876
  }, undefined, false, undefined, this)
4716
4877
  ]
4717
4878
  }, undefined, true, undefined, this),
@@ -4736,13 +4897,140 @@ function SearchView({
4736
4897
  children: [
4737
4898
  "Found ",
4738
4899
  results.length,
4739
- " connector(s):"
4900
+ " connector(s)",
4901
+ mode === "search" ? " \u2014 press \u2193 to select" : "",
4902
+ ":"
4740
4903
  ]
4741
4904
  }, undefined, true, undefined, this),
4742
- /* @__PURE__ */ jsxDEV4(SelectInput_default, {
4743
- items,
4744
- onSelect: handleSelect
4745
- }, undefined, false, undefined, this)
4905
+ /* @__PURE__ */ jsxDEV4(Box6, {
4906
+ children: [
4907
+ /* @__PURE__ */ jsxDEV4(Box6, {
4908
+ width: COL_CHECK2,
4909
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
4910
+ dimColor: true,
4911
+ children: " "
4912
+ }, undefined, false, undefined, this)
4913
+ }, undefined, false, undefined, this),
4914
+ /* @__PURE__ */ jsxDEV4(Box6, {
4915
+ width: COL_NAME2,
4916
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
4917
+ bold: true,
4918
+ dimColor: true,
4919
+ children: "Connector"
4920
+ }, undefined, false, undefined, this)
4921
+ }, undefined, false, undefined, this),
4922
+ /* @__PURE__ */ jsxDEV4(Box6, {
4923
+ width: COL_VERSION2,
4924
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
4925
+ bold: true,
4926
+ dimColor: true,
4927
+ children: "Version"
4928
+ }, undefined, false, undefined, this)
4929
+ }, undefined, false, undefined, this),
4930
+ /* @__PURE__ */ jsxDEV4(Text7, {
4931
+ bold: true,
4932
+ dimColor: true,
4933
+ children: "Description"
4934
+ }, undefined, false, undefined, this)
4935
+ ]
4936
+ }, undefined, true, undefined, this),
4937
+ /* @__PURE__ */ jsxDEV4(Box6, {
4938
+ marginBottom: 0,
4939
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
4940
+ dimColor: true,
4941
+ children: "\u2500".repeat(70)
4942
+ }, undefined, false, undefined, this)
4943
+ }, undefined, false, undefined, this),
4944
+ visibleStart > 0 && /* @__PURE__ */ jsxDEV4(Text7, {
4945
+ dimColor: true,
4946
+ children: [
4947
+ " \u2191 ",
4948
+ visibleStart,
4949
+ " more"
4950
+ ]
4951
+ }, undefined, true, undefined, this),
4952
+ Array.from({ length: visibleEnd - visibleStart }, (_, i) => {
4953
+ const idx = visibleStart + i;
4954
+ if (idx === 0) {
4955
+ const isActive2 = mode === "select" && cursor === 0;
4956
+ return /* @__PURE__ */ jsxDEV4(Box6, {
4957
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
4958
+ color: isActive2 ? "cyan" : undefined,
4959
+ bold: isActive2,
4960
+ children: [
4961
+ isActive2 ? "\u276F " : " ",
4962
+ "\u2190 Back"
4963
+ ]
4964
+ }, undefined, true, undefined, this)
4965
+ }, "__back__", false, undefined, this);
4966
+ }
4967
+ if (hasConfirm && idx === totalItems - 1) {
4968
+ const isActive2 = mode === "select" && cursor === totalItems - 1;
4969
+ return /* @__PURE__ */ jsxDEV4(Box6, {
4970
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
4971
+ color: isActive2 ? "green" : "green",
4972
+ bold: isActive2,
4973
+ dimColor: !isActive2,
4974
+ children: [
4975
+ isActive2 ? "\u276F " : " ",
4976
+ "\u2713 Install selected (",
4977
+ selected.size,
4978
+ ")"
4979
+ ]
4980
+ }, undefined, true, undefined, this)
4981
+ }, "__confirm__", false, undefined, this);
4982
+ }
4983
+ const c = results[idx - 1];
4984
+ if (!c)
4985
+ return null;
4986
+ const isActive = mode === "select" && cursor === idx;
4987
+ const isChecked = selected.has(c.name);
4988
+ return /* @__PURE__ */ jsxDEV4(Box6, {
4989
+ children: [
4990
+ /* @__PURE__ */ jsxDEV4(Box6, {
4991
+ width: 2,
4992
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
4993
+ color: isActive ? "cyan" : undefined,
4994
+ children: isActive ? "\u276F" : " "
4995
+ }, undefined, false, undefined, this)
4996
+ }, undefined, false, undefined, this),
4997
+ /* @__PURE__ */ jsxDEV4(Box6, {
4998
+ width: COL_CHECK2 - 2,
4999
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
5000
+ color: isChecked ? "green" : "gray",
5001
+ children: isChecked ? "[\u2713]" : "[ ]"
5002
+ }, undefined, false, undefined, this)
5003
+ }, undefined, false, undefined, this),
5004
+ /* @__PURE__ */ jsxDEV4(Box6, {
5005
+ width: COL_NAME2,
5006
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
5007
+ bold: isActive,
5008
+ color: isActive ? "cyan" : undefined,
5009
+ children: c.name
5010
+ }, undefined, false, undefined, this)
5011
+ }, undefined, false, undefined, this),
5012
+ /* @__PURE__ */ jsxDEV4(Box6, {
5013
+ width: COL_VERSION2,
5014
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
5015
+ dimColor: true,
5016
+ children: c.version || "-"
5017
+ }, undefined, false, undefined, this)
5018
+ }, undefined, false, undefined, this),
5019
+ /* @__PURE__ */ jsxDEV4(Text7, {
5020
+ wrap: "truncate",
5021
+ children: c.description
5022
+ }, undefined, false, undefined, this)
5023
+ ]
5024
+ }, c.name, true, undefined, this);
5025
+ }),
5026
+ visibleEnd < totalItems && /* @__PURE__ */ jsxDEV4(Text7, {
5027
+ dimColor: true,
5028
+ children: [
5029
+ " \u2193 ",
5030
+ totalItems - visibleEnd,
5031
+ " more"
5032
+ ]
5033
+ }, undefined, true, undefined, this)
4746
5034
  ]
4747
5035
  }, undefined, true, undefined, this),
4748
5036
  selected.size > 0 && /* @__PURE__ */ jsxDEV4(Box6, {
@@ -4754,6 +5042,13 @@ function SearchView({
4754
5042
  Array.from(selected).join(", ")
4755
5043
  ]
4756
5044
  }, undefined, true, undefined, this)
5045
+ }, undefined, false, undefined, this),
5046
+ /* @__PURE__ */ jsxDEV4(Box6, {
5047
+ marginTop: 1,
5048
+ children: /* @__PURE__ */ jsxDEV4(Text7, {
5049
+ dimColor: true,
5050
+ children: mode === "search" ? "type to search \u2193 select results esc back" : "\u2191\u2193 navigate space toggle enter confirm esc search"
5051
+ }, undefined, false, undefined, this)
4757
5052
  }, undefined, false, undefined, this)
4758
5053
  ]
4759
5054
  }, undefined, true, undefined, this);
@@ -4786,38 +5081,38 @@ function Spinner({ type = "dots" }) {
4786
5081
  var build_default2 = Spinner;
4787
5082
 
4788
5083
  // src/lib/installer.ts
4789
- import { existsSync, cpSync, mkdirSync, writeFileSync } from "fs";
4790
- import { join, dirname } from "path";
4791
- import { fileURLToPath } from "url";
4792
- var __dirname2 = dirname(fileURLToPath(import.meta.url));
5084
+ import { existsSync as existsSync2, cpSync, mkdirSync, writeFileSync } from "fs";
5085
+ import { join as join2, dirname as dirname2 } from "path";
5086
+ import { fileURLToPath as fileURLToPath2 } from "url";
5087
+ var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
4793
5088
  function resolveConnectorsDir() {
4794
- const fromBin = join(__dirname2, "..", "connectors");
4795
- if (existsSync(fromBin))
5089
+ const fromBin = join2(__dirname2, "..", "connectors");
5090
+ if (existsSync2(fromBin))
4796
5091
  return fromBin;
4797
- const fromSrc = join(__dirname2, "..", "..", "connectors");
4798
- if (existsSync(fromSrc))
5092
+ const fromSrc = join2(__dirname2, "..", "..", "connectors");
5093
+ if (existsSync2(fromSrc))
4799
5094
  return fromSrc;
4800
5095
  return fromBin;
4801
5096
  }
4802
5097
  var CONNECTORS_DIR = resolveConnectorsDir();
4803
5098
  function getConnectorPath(name) {
4804
5099
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
4805
- return join(CONNECTORS_DIR, connectorName);
5100
+ return join2(CONNECTORS_DIR, connectorName);
4806
5101
  }
4807
5102
  function installConnector(name, options = {}) {
4808
5103
  const { targetDir = process.cwd(), overwrite = false } = options;
4809
5104
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
4810
5105
  const sourcePath = getConnectorPath(name);
4811
- const destDir = join(targetDir, ".connectors");
4812
- const destPath = join(destDir, connectorName);
4813
- if (!existsSync(sourcePath)) {
5106
+ const destDir = join2(targetDir, ".connectors");
5107
+ const destPath = join2(destDir, connectorName);
5108
+ if (!existsSync2(sourcePath)) {
4814
5109
  return {
4815
5110
  connector: name,
4816
5111
  success: false,
4817
5112
  error: `Connector '${name}' not found`
4818
5113
  };
4819
5114
  }
4820
- if (existsSync(destPath) && !overwrite) {
5115
+ if (existsSync2(destPath) && !overwrite) {
4821
5116
  return {
4822
5117
  connector: name,
4823
5118
  success: false,
@@ -4826,7 +5121,7 @@ function installConnector(name, options = {}) {
4826
5121
  };
4827
5122
  }
4828
5123
  try {
4829
- if (!existsSync(destDir)) {
5124
+ if (!existsSync2(destDir)) {
4830
5125
  mkdirSync(destDir, { recursive: true });
4831
5126
  }
4832
5127
  cpSync(sourcePath, destPath, { recursive: true });
@@ -4845,7 +5140,7 @@ function installConnector(name, options = {}) {
4845
5140
  }
4846
5141
  }
4847
5142
  function updateConnectorsIndex(connectorsDir) {
4848
- const indexPath = join(connectorsDir, "index.ts");
5143
+ const indexPath = join2(connectorsDir, "index.ts");
4849
5144
  const { readdirSync } = __require("fs");
4850
5145
  const connectors = readdirSync(connectorsDir).filter((f) => f.startsWith("connect-") && !f.includes("."));
4851
5146
  const exports = connectors.map((c) => {
@@ -4863,22 +5158,22 @@ ${exports}
4863
5158
  writeFileSync(indexPath, content);
4864
5159
  }
4865
5160
  function getInstalledConnectors(targetDir = process.cwd()) {
4866
- const connectorsDir = join(targetDir, ".connectors");
4867
- if (!existsSync(connectorsDir)) {
5161
+ const connectorsDir = join2(targetDir, ".connectors");
5162
+ if (!existsSync2(connectorsDir)) {
4868
5163
  return [];
4869
5164
  }
4870
5165
  const { readdirSync, statSync } = __require("fs");
4871
5166
  return readdirSync(connectorsDir).filter((f) => {
4872
- const fullPath = join(connectorsDir, f);
5167
+ const fullPath = join2(connectorsDir, f);
4873
5168
  return f.startsWith("connect-") && statSync(fullPath).isDirectory();
4874
5169
  }).map((f) => f.replace("connect-", ""));
4875
5170
  }
4876
5171
  function removeConnector(name, targetDir = process.cwd()) {
4877
5172
  const { rmSync } = __require("fs");
4878
5173
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
4879
- const connectorsDir = join(targetDir, ".connectors");
4880
- const connectorPath = join(connectorsDir, connectorName);
4881
- if (!existsSync(connectorPath)) {
5174
+ const connectorsDir = join2(targetDir, ".connectors");
5175
+ const connectorPath = join2(connectorsDir, connectorName);
5176
+ if (!existsSync2(connectorPath)) {
4882
5177
  return false;
4883
5178
  }
4884
5179
  rmSync(connectorPath, { recursive: true });
@@ -5189,33 +5484,63 @@ function App({ initialConnectors, overwrite = false }) {
5189
5484
 
5190
5485
  // src/cli/index.tsx
5191
5486
  import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
5487
+ loadConnectorVersions();
5488
+ var isTTY = process.stdout.isTTY ?? false;
5192
5489
  var program2 = new Command;
5193
- program2.name("connectors").description("Install API connectors for your project").version("0.0.1");
5490
+ program2.name("connectors").description("Install API connectors for your project").version("0.0.4");
5194
5491
  program2.command("interactive", { isDefault: true }).alias("i").description("Interactive connector browser").action(() => {
5492
+ if (!isTTY) {
5493
+ console.log(`Non-interactive environment detected. Use a subcommand:
5494
+ `);
5495
+ console.log(" connectors list List all available connectors");
5496
+ console.log(" connectors list --json List as JSON (for AI agents)");
5497
+ console.log(" connectors search <query> Search connectors");
5498
+ console.log(" connectors install <names...> Install connectors");
5499
+ console.log(" connectors remove <name> Remove a connector");
5500
+ console.log(" connectors info <name> Show connector details");
5501
+ console.log(" connectors categories List categories");
5502
+ console.log(`
5503
+ Run 'connectors --help' for full usage.`);
5504
+ process.exit(0);
5505
+ }
5195
5506
  render(/* @__PURE__ */ jsxDEV7(App, {}, undefined, false, undefined, this));
5196
5507
  });
5197
- program2.command("install").alias("add").argument("[connectors...]", "Connectors to install").option("-o, --overwrite", "Overwrite existing connectors", false).description("Install one or more connectors").action((connectors, options) => {
5508
+ program2.command("install").alias("add").argument("[connectors...]", "Connectors to install").option("-o, --overwrite", "Overwrite existing connectors", false).option("--json", "Output results as JSON", false).description("Install one or more connectors").action((connectors, options) => {
5198
5509
  if (connectors.length === 0) {
5510
+ if (!isTTY) {
5511
+ console.error("Error: specify connectors to install. Example: connectors install figma stripe");
5512
+ process.exit(1);
5513
+ }
5199
5514
  render(/* @__PURE__ */ jsxDEV7(App, {}, undefined, false, undefined, this));
5200
5515
  return;
5201
5516
  }
5517
+ const results = connectors.map((name) => installConnector(name, { overwrite: options.overwrite }));
5518
+ if (options.json) {
5519
+ console.log(JSON.stringify(results, null, 2));
5520
+ process.exit(results.every((r) => r.success) ? 0 : 1);
5521
+ return;
5522
+ }
5202
5523
  console.log(chalk2.bold(`
5203
5524
  Installing connectors...
5204
5525
  `));
5205
- for (const name of connectors) {
5206
- const result = installConnector(name, { overwrite: options.overwrite });
5526
+ for (const result of results) {
5207
5527
  if (result.success) {
5208
- console.log(chalk2.green(`\u2713 ${name}`));
5528
+ console.log(chalk2.green(`\u2713 ${result.connector}`));
5209
5529
  } else {
5210
- console.log(chalk2.red(`\u2717 ${name}: ${result.error}`));
5530
+ console.log(chalk2.red(`\u2717 ${result.connector}: ${result.error}`));
5211
5531
  }
5212
5532
  }
5213
5533
  console.log(chalk2.dim(`
5214
5534
  Connectors installed to .connectors/`));
5535
+ process.exit(results.every((r) => r.success) ? 0 : 1);
5215
5536
  });
5216
- program2.command("list").alias("ls").option("-c, --category <category>", "Filter by category").option("-a, --all", "Show all available connectors", false).option("-i, --installed", "Show only installed connectors", false).description("List available or installed connectors").action((options) => {
5537
+ program2.command("list").alias("ls").option("-c, --category <category>", "Filter by category").option("-a, --all", "Show all available connectors", false).option("-i, --installed", "Show only installed connectors", false).option("--json", "Output as JSON", false).description("List available or installed connectors").action((options) => {
5217
5538
  if (options.installed) {
5218
5539
  const installed = getInstalledConnectors();
5540
+ if (options.json) {
5541
+ console.log(JSON.stringify(installed));
5542
+ return;
5543
+ }
5219
5544
  if (installed.length === 0) {
5220
5545
  console.log(chalk2.dim("No connectors installed"));
5221
5546
  return;
@@ -5231,33 +5556,53 @@ Installed connectors (${installed.length}):
5231
5556
  if (options.category) {
5232
5557
  const category = CATEGORIES.find((c) => c.toLowerCase() === options.category.toLowerCase());
5233
5558
  if (!category) {
5559
+ if (options.json) {
5560
+ console.log(JSON.stringify({ error: `Unknown category: ${options.category}` }));
5561
+ process.exit(1);
5562
+ }
5234
5563
  console.log(chalk2.red(`Unknown category: ${options.category}`));
5235
5564
  console.log(chalk2.dim(`Available: ${CATEGORIES.join(", ")}`));
5236
5565
  return;
5237
5566
  }
5238
5567
  const connectors = getConnectorsByCategory(category);
5568
+ if (options.json) {
5569
+ console.log(JSON.stringify(connectors));
5570
+ return;
5571
+ }
5239
5572
  console.log(chalk2.bold(`
5240
5573
  ${category} (${connectors.length}):
5241
5574
  `));
5575
+ console.log(` ${chalk2.dim("Name".padEnd(20))}${chalk2.dim("Version".padEnd(10))}${chalk2.dim("Description")}`);
5576
+ console.log(chalk2.dim(` ${"\u2500".repeat(60)}`));
5242
5577
  for (const c of connectors) {
5243
- console.log(` ${chalk2.cyan(c.name)} - ${c.description}`);
5578
+ console.log(` ${chalk2.cyan(c.name.padEnd(20))}${chalk2.dim((c.version || "-").padEnd(10))}${c.description}`);
5244
5579
  }
5245
5580
  return;
5246
5581
  }
5582
+ if (options.json) {
5583
+ console.log(JSON.stringify(CONNECTORS));
5584
+ return;
5585
+ }
5247
5586
  console.log(chalk2.bold(`
5248
5587
  Available connectors (${CONNECTORS.length}):
5249
5588
  `));
5250
5589
  for (const category of CATEGORIES) {
5251
5590
  const connectors = getConnectorsByCategory(category);
5252
5591
  console.log(chalk2.bold(`${category} (${connectors.length}):`));
5592
+ console.log(` ${chalk2.dim("Name".padEnd(20))}${chalk2.dim("Version".padEnd(10))}${chalk2.dim("Description")}`);
5593
+ console.log(chalk2.dim(` ${"\u2500".repeat(60)}`));
5253
5594
  for (const c of connectors) {
5254
- console.log(` ${chalk2.cyan(c.name)} - ${c.description}`);
5595
+ console.log(` ${chalk2.cyan(c.name.padEnd(20))}${chalk2.dim((c.version || "-").padEnd(10))}${c.description}`);
5255
5596
  }
5256
5597
  console.log();
5257
5598
  }
5258
5599
  });
5259
- program2.command("search").argument("<query>", "Search term").description("Search for connectors").action((query) => {
5600
+ program2.command("search").argument("<query>", "Search term").option("--json", "Output as JSON", false).description("Search for connectors").action((query, options) => {
5260
5601
  const results = searchConnectors(query);
5602
+ if (options.json) {
5603
+ console.log(JSON.stringify(results));
5604
+ return;
5605
+ }
5261
5606
  if (results.length === 0) {
5262
5607
  console.log(chalk2.dim(`No connectors found for "${query}"`));
5263
5608
  return;
@@ -5265,20 +5610,63 @@ program2.command("search").argument("<query>", "Search term").description("Searc
5265
5610
  console.log(chalk2.bold(`
5266
5611
  Found ${results.length} connector(s):
5267
5612
  `));
5613
+ console.log(` ${chalk2.dim("Name".padEnd(20))}${chalk2.dim("Version".padEnd(10))}${chalk2.dim("Category".padEnd(20))}${chalk2.dim("Description")}`);
5614
+ console.log(chalk2.dim(` ${"\u2500".repeat(70)}`));
5268
5615
  for (const c of results) {
5269
- console.log(` ${chalk2.cyan(c.name)} ${chalk2.dim(`[${c.category}]`)}`);
5270
- console.log(` ${c.description}`);
5616
+ console.log(` ${chalk2.cyan(c.name.padEnd(20))}${chalk2.dim((c.version || "-").padEnd(10))}${chalk2.dim(c.category.padEnd(20))}${c.description}`);
5271
5617
  }
5272
5618
  });
5273
- program2.command("remove").alias("rm").argument("<connector>", "Connector to remove").description("Remove an installed connector").action((connector) => {
5619
+ program2.command("info").argument("<connector>", "Connector name").option("--json", "Output as JSON", false).description("Show detailed info about a connector").action((connector, options) => {
5620
+ const meta = getConnector(connector);
5621
+ if (!meta) {
5622
+ if (options.json) {
5623
+ console.log(JSON.stringify({ error: `Connector '${connector}' not found` }));
5624
+ process.exit(1);
5625
+ }
5626
+ console.log(chalk2.red(`Connector '${connector}' not found`));
5627
+ process.exit(1);
5628
+ return;
5629
+ }
5630
+ const installed = getInstalledConnectors();
5631
+ const isInstalled = installed.includes(meta.name);
5632
+ if (options.json) {
5633
+ console.log(JSON.stringify({ ...meta, installed: isInstalled }));
5634
+ return;
5635
+ }
5636
+ console.log(chalk2.bold(`
5637
+ ${meta.displayName}`));
5638
+ console.log(chalk2.dim(`${"\u2500".repeat(40)}`));
5639
+ console.log(` Name: ${chalk2.cyan(meta.name)}`);
5640
+ console.log(` Version: ${meta.version || "-"}`);
5641
+ console.log(` Category: ${meta.category}`);
5642
+ console.log(` Description: ${meta.description}`);
5643
+ console.log(` Tags: ${meta.tags.join(", ")}`);
5644
+ console.log(` Installed: ${isInstalled ? chalk2.green("yes") : "no"}`);
5645
+ console.log(` Package: @hasna/connect-${meta.name}`);
5646
+ });
5647
+ program2.command("remove").alias("rm").argument("<connector>", "Connector to remove").option("--json", "Output as JSON", false).description("Remove an installed connector").action((connector, options) => {
5274
5648
  const removed = removeConnector(connector);
5649
+ if (options.json) {
5650
+ console.log(JSON.stringify({ connector, removed }));
5651
+ process.exit(removed ? 0 : 1);
5652
+ return;
5653
+ }
5275
5654
  if (removed) {
5276
5655
  console.log(chalk2.green(`\u2713 Removed ${connector}`));
5277
5656
  } else {
5278
5657
  console.log(chalk2.red(`\u2717 ${connector} is not installed`));
5658
+ process.exit(1);
5279
5659
  }
5280
5660
  });
5281
- program2.command("categories").description("List all categories").action(() => {
5661
+ program2.command("categories").option("--json", "Output as JSON", false).description("List all categories").action((options) => {
5662
+ if (options.json) {
5663
+ const data = CATEGORIES.map((category) => ({
5664
+ name: category,
5665
+ count: getConnectorsByCategory(category).length
5666
+ }));
5667
+ console.log(JSON.stringify(data));
5668
+ return;
5669
+ }
5282
5670
  console.log(chalk2.bold(`
5283
5671
  Categories:
5284
5672
  `));
package/dist/index.js CHANGED
@@ -2,6 +2,9 @@
2
2
  var __require = import.meta.require;
3
3
 
4
4
  // src/lib/registry.ts
5
+ import { existsSync, readFileSync } from "fs";
6
+ import { join, dirname } from "path";
7
+ import { fileURLToPath } from "url";
5
8
  var CATEGORIES = [
6
9
  "AI & ML",
7
10
  "Developer Tools",
@@ -468,42 +471,65 @@ function searchConnectors(query) {
468
471
  function getConnector(name) {
469
472
  return CONNECTORS.find((c) => c.name === name);
470
473
  }
474
+ var versionsLoaded = false;
475
+ function loadConnectorVersions() {
476
+ if (versionsLoaded)
477
+ return;
478
+ versionsLoaded = true;
479
+ const thisDir = dirname(fileURLToPath(import.meta.url));
480
+ const candidates = [
481
+ join(thisDir, "..", "connectors"),
482
+ join(thisDir, "..", "..", "connectors")
483
+ ];
484
+ const connectorsDir = candidates.find((d) => existsSync(d));
485
+ if (!connectorsDir)
486
+ return;
487
+ for (const connector of CONNECTORS) {
488
+ try {
489
+ const pkgPath = join(connectorsDir, `connect-${connector.name}`, "package.json");
490
+ if (existsSync(pkgPath)) {
491
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
492
+ connector.version = pkg.version || "0.0.0";
493
+ }
494
+ } catch {}
495
+ }
496
+ }
471
497
  // src/lib/installer.ts
472
- import { existsSync, cpSync, mkdirSync, writeFileSync } from "fs";
473
- import { join, dirname } from "path";
474
- import { fileURLToPath } from "url";
475
- var __dirname2 = dirname(fileURLToPath(import.meta.url));
498
+ import { existsSync as existsSync2, cpSync, mkdirSync, writeFileSync } from "fs";
499
+ import { join as join2, dirname as dirname2 } from "path";
500
+ import { fileURLToPath as fileURLToPath2 } from "url";
501
+ var __dirname2 = dirname2(fileURLToPath2(import.meta.url));
476
502
  function resolveConnectorsDir() {
477
- const fromBin = join(__dirname2, "..", "connectors");
478
- if (existsSync(fromBin))
503
+ const fromBin = join2(__dirname2, "..", "connectors");
504
+ if (existsSync2(fromBin))
479
505
  return fromBin;
480
- const fromSrc = join(__dirname2, "..", "..", "connectors");
481
- if (existsSync(fromSrc))
506
+ const fromSrc = join2(__dirname2, "..", "..", "connectors");
507
+ if (existsSync2(fromSrc))
482
508
  return fromSrc;
483
509
  return fromBin;
484
510
  }
485
511
  var CONNECTORS_DIR = resolveConnectorsDir();
486
512
  function getConnectorPath(name) {
487
513
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
488
- return join(CONNECTORS_DIR, connectorName);
514
+ return join2(CONNECTORS_DIR, connectorName);
489
515
  }
490
516
  function connectorExists(name) {
491
- return existsSync(getConnectorPath(name));
517
+ return existsSync2(getConnectorPath(name));
492
518
  }
493
519
  function installConnector(name, options = {}) {
494
520
  const { targetDir = process.cwd(), overwrite = false } = options;
495
521
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
496
522
  const sourcePath = getConnectorPath(name);
497
- const destDir = join(targetDir, ".connectors");
498
- const destPath = join(destDir, connectorName);
499
- if (!existsSync(sourcePath)) {
523
+ const destDir = join2(targetDir, ".connectors");
524
+ const destPath = join2(destDir, connectorName);
525
+ if (!existsSync2(sourcePath)) {
500
526
  return {
501
527
  connector: name,
502
528
  success: false,
503
529
  error: `Connector '${name}' not found`
504
530
  };
505
531
  }
506
- if (existsSync(destPath) && !overwrite) {
532
+ if (existsSync2(destPath) && !overwrite) {
507
533
  return {
508
534
  connector: name,
509
535
  success: false,
@@ -512,7 +538,7 @@ function installConnector(name, options = {}) {
512
538
  };
513
539
  }
514
540
  try {
515
- if (!existsSync(destDir)) {
541
+ if (!existsSync2(destDir)) {
516
542
  mkdirSync(destDir, { recursive: true });
517
543
  }
518
544
  cpSync(sourcePath, destPath, { recursive: true });
@@ -534,7 +560,7 @@ function installConnectors(names, options = {}) {
534
560
  return names.map((name) => installConnector(name, options));
535
561
  }
536
562
  function updateConnectorsIndex(connectorsDir) {
537
- const indexPath = join(connectorsDir, "index.ts");
563
+ const indexPath = join2(connectorsDir, "index.ts");
538
564
  const { readdirSync } = __require("fs");
539
565
  const connectors = readdirSync(connectorsDir).filter((f) => f.startsWith("connect-") && !f.includes("."));
540
566
  const exports = connectors.map((c) => {
@@ -552,22 +578,22 @@ ${exports}
552
578
  writeFileSync(indexPath, content);
553
579
  }
554
580
  function getInstalledConnectors(targetDir = process.cwd()) {
555
- const connectorsDir = join(targetDir, ".connectors");
556
- if (!existsSync(connectorsDir)) {
581
+ const connectorsDir = join2(targetDir, ".connectors");
582
+ if (!existsSync2(connectorsDir)) {
557
583
  return [];
558
584
  }
559
585
  const { readdirSync, statSync } = __require("fs");
560
586
  return readdirSync(connectorsDir).filter((f) => {
561
- const fullPath = join(connectorsDir, f);
587
+ const fullPath = join2(connectorsDir, f);
562
588
  return f.startsWith("connect-") && statSync(fullPath).isDirectory();
563
589
  }).map((f) => f.replace("connect-", ""));
564
590
  }
565
591
  function removeConnector(name, targetDir = process.cwd()) {
566
592
  const { rmSync } = __require("fs");
567
593
  const connectorName = name.startsWith("connect-") ? name : `connect-${name}`;
568
- const connectorsDir = join(targetDir, ".connectors");
569
- const connectorPath = join(connectorsDir, connectorName);
570
- if (!existsSync(connectorPath)) {
594
+ const connectorsDir = join2(targetDir, ".connectors");
595
+ const connectorPath = join2(connectorsDir, connectorName);
596
+ if (!existsSync2(connectorPath)) {
571
597
  return false;
572
598
  }
573
599
  rmSync(connectorPath, { recursive: true });
@@ -577,6 +603,7 @@ function removeConnector(name, targetDir = process.cwd()) {
577
603
  export {
578
604
  searchConnectors,
579
605
  removeConnector,
606
+ loadConnectorVersions,
580
607
  installConnectors,
581
608
  installConnector,
582
609
  getInstalledConnectors,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/connectors",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Open source connector library - Install API connectors with a single command",
5
5
  "type": "module",
6
6
  "bin": {