@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.
- package/bin/index.js +513 -125
- package/dist/index.js +49 -22
- 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
|
|
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
|
|
4464
|
-
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
|
|
4480
|
-
|
|
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 (
|
|
4483
|
-
onToggle(
|
|
4522
|
+
} else if (input === " " && cursor > 0 && cursor < totalItems - 1) {
|
|
4523
|
+
onToggle(connectors[cursor - 1].name);
|
|
4484
4524
|
}
|
|
4485
|
-
};
|
|
4486
|
-
const
|
|
4487
|
-
const
|
|
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
|
|
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
|
-
|
|
4501
|
-
|
|
4502
|
-
|
|
4503
|
-
|
|
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
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
|
|
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
|
-
|
|
4519
|
-
|
|
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
|
-
},
|
|
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 (
|
|
4675
|
-
|
|
4826
|
+
if (mode === "search") {
|
|
4827
|
+
if (key.downArrow && results.length > 0) {
|
|
4828
|
+
setMode("select");
|
|
4829
|
+
setCursor(0);
|
|
4830
|
+
}
|
|
4831
|
+
return;
|
|
4676
4832
|
}
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
})
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4698
|
-
|
|
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(
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
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 =
|
|
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 =
|
|
4795
|
-
if (
|
|
5089
|
+
const fromBin = join2(__dirname2, "..", "connectors");
|
|
5090
|
+
if (existsSync2(fromBin))
|
|
4796
5091
|
return fromBin;
|
|
4797
|
-
const fromSrc =
|
|
4798
|
-
if (
|
|
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
|
|
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 =
|
|
4812
|
-
const destPath =
|
|
4813
|
-
if (!
|
|
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 (
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
4867
|
-
if (!
|
|
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 =
|
|
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 =
|
|
4880
|
-
const connectorPath =
|
|
4881
|
-
if (!
|
|
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.
|
|
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
|
|
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 ${
|
|
5528
|
+
console.log(chalk2.green(`\u2713 ${result.connector}`));
|
|
5209
5529
|
} else {
|
|
5210
|
-
console.log(chalk2.red(`\u2717 ${
|
|
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)} -
|
|
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)} -
|
|
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)}
|
|
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("
|
|
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 =
|
|
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 =
|
|
478
|
-
if (
|
|
503
|
+
const fromBin = join2(__dirname2, "..", "connectors");
|
|
504
|
+
if (existsSync2(fromBin))
|
|
479
505
|
return fromBin;
|
|
480
|
-
const fromSrc =
|
|
481
|
-
if (
|
|
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
|
|
514
|
+
return join2(CONNECTORS_DIR, connectorName);
|
|
489
515
|
}
|
|
490
516
|
function connectorExists(name) {
|
|
491
|
-
return
|
|
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 =
|
|
498
|
-
const destPath =
|
|
499
|
-
if (!
|
|
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 (
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
556
|
-
if (!
|
|
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 =
|
|
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 =
|
|
569
|
-
const connectorPath =
|
|
570
|
-
if (!
|
|
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,
|