ardent-cli 0.0.15 → 0.0.17
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/dist/index.js +124 -278
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -57,13 +57,6 @@ function getApiUrl() {
|
|
|
57
57
|
function getToken() {
|
|
58
58
|
return getConfig("token") || process.env.ARDENT_TOKEN;
|
|
59
59
|
}
|
|
60
|
-
function getBranches() {
|
|
61
|
-
const cached = getCacheEntry("branches");
|
|
62
|
-
return cached?.data || [];
|
|
63
|
-
}
|
|
64
|
-
function getBranchByName(name) {
|
|
65
|
-
return getBranches().find((branch) => branch.name === name);
|
|
66
|
-
}
|
|
67
60
|
function setCacheEntry(key, data) {
|
|
68
61
|
const config = loadConfig();
|
|
69
62
|
if (!config.cache) config.cache = {};
|
|
@@ -188,9 +181,9 @@ var ApiClient = class {
|
|
|
188
181
|
getHeaders() {
|
|
189
182
|
const token = getToken();
|
|
190
183
|
if (!token) {
|
|
191
|
-
const
|
|
192
|
-
const
|
|
193
|
-
console.error(`\u2717 Not authenticated. Run: ${
|
|
184
|
+
const green2 = "\x1B[32m";
|
|
185
|
+
const reset2 = "\x1B[0m";
|
|
186
|
+
console.error(`\u2717 Not authenticated. Run: ${green2}ardent login${reset2}`);
|
|
194
187
|
process.exit(1);
|
|
195
188
|
}
|
|
196
189
|
return {
|
|
@@ -421,22 +414,22 @@ async function listAction() {
|
|
|
421
414
|
return;
|
|
422
415
|
}
|
|
423
416
|
const current = getCurrentBranch();
|
|
424
|
-
const
|
|
425
|
-
const
|
|
426
|
-
const
|
|
417
|
+
const green2 = "\x1B[32m";
|
|
418
|
+
const dim2 = "\x1B[2m";
|
|
419
|
+
const reset2 = "\x1B[0m";
|
|
427
420
|
console.log("Branches:\n");
|
|
428
421
|
for (const branch of branches) {
|
|
429
422
|
const isCurrent = branch.name === current;
|
|
430
|
-
const icon = branch.status === "active"
|
|
423
|
+
const icon = branch.status === "active" ? "\u25CF" : "\u25CB";
|
|
431
424
|
if (isCurrent) {
|
|
432
|
-
console.log(`${
|
|
425
|
+
console.log(`${green2}* ${icon} ${branch.name}${reset2}`);
|
|
433
426
|
if (branch.branch_url) {
|
|
434
|
-
console.log(`${
|
|
427
|
+
console.log(`${green2} ${branch.branch_url}${reset2}`);
|
|
435
428
|
}
|
|
436
429
|
} else {
|
|
437
430
|
console.log(` ${icon} ${branch.name}`);
|
|
438
431
|
if (branch.branch_url) {
|
|
439
|
-
console.log(`${
|
|
432
|
+
console.log(`${dim2} ${branch.branch_url}${reset2}`);
|
|
440
433
|
}
|
|
441
434
|
}
|
|
442
435
|
console.log();
|
|
@@ -547,219 +540,21 @@ ${branch.branch_url}`);
|
|
|
547
540
|
}
|
|
548
541
|
|
|
549
542
|
// src/commands/branch/diff.ts
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
schema_name: raw.schema_name,
|
|
566
|
-
table_name: raw.table_name,
|
|
567
|
-
primary_key: raw.primary_key,
|
|
568
|
-
first_op: raw.first_op,
|
|
569
|
-
last_op: raw.last_op,
|
|
570
|
-
first_data: raw.original_values ? JSON.parse(raw.original_values) : null,
|
|
571
|
-
last_data: raw.final_values ? JSON.parse(raw.final_values) : null
|
|
572
|
-
};
|
|
573
|
-
}
|
|
574
|
-
async function diffAction(options) {
|
|
575
|
-
let branch;
|
|
576
|
-
if (options.branch) {
|
|
577
|
-
branch = getBranchByName(options.branch);
|
|
578
|
-
} else {
|
|
579
|
-
const currentName = getCurrentBranch();
|
|
580
|
-
if (currentName) {
|
|
581
|
-
branch = getBranchByName(currentName);
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
if (!branch) {
|
|
585
|
-
const current = getCurrentBranch();
|
|
586
|
-
if (current) {
|
|
587
|
-
console.error(`\u2717 Branch "${current}" not found in cache`);
|
|
588
|
-
console.log(" Run: ardent branch list");
|
|
589
|
-
} else {
|
|
590
|
-
console.error("\u2717 No current branch set");
|
|
591
|
-
console.log(" Run: ardent branch switch <name> or ardent branch create <name>");
|
|
592
|
-
}
|
|
593
|
-
return;
|
|
594
|
-
}
|
|
595
|
-
try {
|
|
596
|
-
const stateRaw = await api.get(`/v1/branches/${branch.id}/state`);
|
|
597
|
-
if (!stateRaw || Object.keys(stateRaw).length === 0) {
|
|
598
|
-
console.log("No changes captured");
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
|
-
for (const [_branchId, branchStateRaw] of Object.entries(stateRaw)) {
|
|
602
|
-
const ddl = branchStateRaw.ddl;
|
|
603
|
-
const replay_sql = branchStateRaw.replay_sql;
|
|
604
|
-
const diff = (branchStateRaw.diff || []).map(parseDiffRow);
|
|
605
|
-
if (options.sql) {
|
|
606
|
-
if (replay_sql) {
|
|
607
|
-
console.log(replay_sql);
|
|
608
|
-
} else {
|
|
609
|
-
console.log("-- No replay SQL generated");
|
|
610
|
-
}
|
|
611
|
-
continue;
|
|
612
|
-
}
|
|
613
|
-
if (ddl && ddl.length > 0) {
|
|
614
|
-
console.log(`${bold}Schema Changes${reset} ${dim}(${ddl.length} DDL)${reset}
|
|
615
|
-
`);
|
|
616
|
-
for (const change of ddl) {
|
|
617
|
-
const color = change.command_tag.includes("DROP") ? red : change.command_tag.includes("CREATE") ? green : yellow;
|
|
618
|
-
console.log(` ${color}${change.command_tag}${reset} ${change.object_name}`);
|
|
619
|
-
if (change.ddl_command && change.ddl_command.length < 100) {
|
|
620
|
-
console.log(` ${dim}${change.ddl_command}${reset}`);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
console.log();
|
|
624
|
-
}
|
|
625
|
-
if (diff && diff.length > 0) {
|
|
626
|
-
const byTable = /* @__PURE__ */ new Map();
|
|
627
|
-
for (const row of diff) {
|
|
628
|
-
const tableName = row.table_name || `${row.schema_name}.unknown`;
|
|
629
|
-
if (!byTable.has(tableName)) {
|
|
630
|
-
byTable.set(tableName, []);
|
|
631
|
-
}
|
|
632
|
-
byTable.get(tableName).push(row);
|
|
633
|
-
}
|
|
634
|
-
const inserts = diff.filter((r) => r.last_op === "INSERT").length;
|
|
635
|
-
const updates = diff.filter((r) => r.last_op === "UPDATE").length;
|
|
636
|
-
const deletes = diff.filter((r) => r.last_op === "DELETE").length;
|
|
637
|
-
const summary = [
|
|
638
|
-
inserts > 0 ? `${green}+${inserts} added${reset}` : "",
|
|
639
|
-
updates > 0 ? `${yellow}~${updates} modified${reset}` : "",
|
|
640
|
-
deletes > 0 ? `${red}-${deletes} deleted${reset}` : ""
|
|
641
|
-
].filter(Boolean).join(" ");
|
|
642
|
-
console.log(`${bold}Data Changes${reset} ${dim}(${byTable.size} table${byTable.size > 1 ? "s" : ""})${reset} ${summary}
|
|
643
|
-
`);
|
|
644
|
-
for (const [tableName, rows] of byTable) {
|
|
645
|
-
const tableInserts = rows.filter((r) => r.last_op === "INSERT").length;
|
|
646
|
-
const tableUpdates = rows.filter((r) => r.last_op === "UPDATE").length;
|
|
647
|
-
const tableDeletes = rows.filter((r) => r.last_op === "DELETE").length;
|
|
648
|
-
const tableSummary = [
|
|
649
|
-
tableInserts > 0 ? `${green}+${tableInserts}${reset}` : "",
|
|
650
|
-
tableUpdates > 0 ? `${yellow}~${tableUpdates}${reset}` : "",
|
|
651
|
-
tableDeletes > 0 ? `${red}-${tableDeletes}${reset}` : ""
|
|
652
|
-
].filter(Boolean).join(" ");
|
|
653
|
-
console.log(`${cyan}${tableName}${reset} ${tableSummary}`);
|
|
654
|
-
console.log();
|
|
655
|
-
const allColumns = /* @__PURE__ */ new Set();
|
|
656
|
-
for (const row of rows) {
|
|
657
|
-
const data = row.last_data || row.first_data || {};
|
|
658
|
-
Object.keys(data).forEach((k) => allColumns.add(k));
|
|
659
|
-
if (row.first_data) {
|
|
660
|
-
Object.keys(row.first_data).forEach((k) => allColumns.add(k));
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
let columns = Array.from(allColumns);
|
|
664
|
-
let hiddenColumns = 0;
|
|
665
|
-
if (columns.length > MAX_COLUMNS) {
|
|
666
|
-
const changedCols = /* @__PURE__ */ new Set();
|
|
667
|
-
for (const row of rows) {
|
|
668
|
-
if (row.last_op === "UPDATE" && row.first_data && row.last_data) {
|
|
669
|
-
for (const col of columns) {
|
|
670
|
-
if (row.first_data[col] !== row.last_data[col]) {
|
|
671
|
-
changedCols.add(col);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
const prioritized = [
|
|
677
|
-
...columns.filter((c) => changedCols.has(c)),
|
|
678
|
-
...columns.filter((c) => !changedCols.has(c))
|
|
679
|
-
];
|
|
680
|
-
hiddenColumns = prioritized.length - MAX_COLUMNS;
|
|
681
|
-
columns = prioritized.slice(0, MAX_COLUMNS);
|
|
682
|
-
}
|
|
683
|
-
const colWidths = { Op: 2 };
|
|
684
|
-
for (const col of columns) {
|
|
685
|
-
colWidths[col] = Math.min(col.length, MAX_COL_WIDTH);
|
|
686
|
-
}
|
|
687
|
-
for (const row of rows) {
|
|
688
|
-
const data = row.last_data || row.first_data || {};
|
|
689
|
-
for (const col of columns) {
|
|
690
|
-
const val = data[col];
|
|
691
|
-
const valStr = val === void 0 ? "" : typeof val === "string" ? val : String(val);
|
|
692
|
-
colWidths[col] = Math.min(MAX_COL_WIDTH, Math.max(colWidths[col], valStr.length));
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
const vLine = `${dim}\u2502${reset}`;
|
|
696
|
-
const topParts = [
|
|
697
|
-
"\u2500".repeat(colWidths["Op"]),
|
|
698
|
-
...columns.map((col) => "\u2500".repeat(colWidths[col]))
|
|
699
|
-
];
|
|
700
|
-
const hiddenNote = hiddenColumns > 0 ? ` ${dim}+${hiddenColumns} more${reset}` : "";
|
|
701
|
-
console.log(` ${dim}\u250C\u2500${topParts.join("\u2500\u252C\u2500")}\u2500\u2510${reset}${hiddenNote}`);
|
|
702
|
-
const headerParts = [
|
|
703
|
-
`${"Op".padEnd(colWidths["Op"])}`,
|
|
704
|
-
...columns.map((col) => truncate(col, colWidths[col]).padEnd(colWidths[col]))
|
|
705
|
-
];
|
|
706
|
-
console.log(` ${dim}\u2502 ${headerParts.join(" \u2502 ")} \u2502${reset}`);
|
|
707
|
-
const sepParts = [
|
|
708
|
-
"\u2500".repeat(colWidths["Op"]),
|
|
709
|
-
...columns.map((col) => "\u2500".repeat(colWidths[col]))
|
|
710
|
-
];
|
|
711
|
-
console.log(` ${dim}\u251C\u2500${sepParts.join("\u2500\u253C\u2500")}\u2500\u2524${reset}`);
|
|
712
|
-
for (const row of rows) {
|
|
713
|
-
const op = row.last_op;
|
|
714
|
-
const opColor = op === "INSERT" ? green : op === "DELETE" ? red : yellow;
|
|
715
|
-
const opSymbol = op === "INSERT" ? "+" : op === "DELETE" ? "-" : "~";
|
|
716
|
-
const cellParts = [];
|
|
717
|
-
cellParts.push(`${opColor}${opSymbol.padEnd(colWidths["Op"])}${reset}`);
|
|
718
|
-
for (const col of columns) {
|
|
719
|
-
const width = colWidths[col];
|
|
720
|
-
if (op === "UPDATE" && row.first_data && row.last_data) {
|
|
721
|
-
const oldVal = row.first_data[col];
|
|
722
|
-
const newVal = row.last_data[col];
|
|
723
|
-
if (oldVal !== newVal) {
|
|
724
|
-
const halfWidth = Math.floor((width - 1) / 2);
|
|
725
|
-
const oldStr = truncate(oldVal === void 0 ? "" : typeof oldVal === "string" ? oldVal : String(oldVal), halfWidth);
|
|
726
|
-
const newStr = truncate(newVal === void 0 ? "" : typeof newVal === "string" ? newVal : String(newVal), halfWidth);
|
|
727
|
-
cellParts.push(`${red}${oldStr.padEnd(halfWidth)}${reset}\u2192${green}${newStr.padEnd(width - halfWidth - 1)}${reset}`);
|
|
728
|
-
} else {
|
|
729
|
-
const valStr = newVal === void 0 ? "" : typeof newVal === "string" ? newVal : String(newVal);
|
|
730
|
-
cellParts.push(`${dim}${truncate(valStr, width).padEnd(width)}${reset}`);
|
|
731
|
-
}
|
|
732
|
-
} else {
|
|
733
|
-
const data = row.last_data || row.first_data || {};
|
|
734
|
-
const val = data[col];
|
|
735
|
-
const valStr = val === void 0 ? "" : typeof val === "string" ? val : String(val);
|
|
736
|
-
cellParts.push(`${opColor}${truncate(valStr, width).padEnd(width)}${reset}`);
|
|
737
|
-
}
|
|
738
|
-
}
|
|
739
|
-
console.log(` ${vLine} ${cellParts.join(` ${vLine} `)} ${vLine}`);
|
|
740
|
-
}
|
|
741
|
-
const bottomParts = [
|
|
742
|
-
"\u2500".repeat(colWidths["Op"]),
|
|
743
|
-
...columns.map((col) => "\u2500".repeat(colWidths[col]))
|
|
744
|
-
];
|
|
745
|
-
console.log(` ${dim}\u2514\u2500${bottomParts.join("\u2500\u2534\u2500")}\u2500\u2518${reset}`);
|
|
746
|
-
console.log();
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
if ((!ddl || ddl.length === 0) && (!diff || diff.length === 0)) {
|
|
750
|
-
console.log("No changes");
|
|
751
|
-
}
|
|
752
|
-
trackEvent("CLI: branch diff succeeded", {
|
|
753
|
-
sql_mode: Boolean(options.sql),
|
|
754
|
-
ddl_count: ddl?.length ?? 0,
|
|
755
|
-
data_change_count: diff?.length ?? 0
|
|
756
|
-
});
|
|
757
|
-
}
|
|
758
|
-
} catch (err) {
|
|
759
|
-
trackEvent("CLI: branch diff failed", { reason: "api_error" });
|
|
760
|
-
console.error("\u2717 Failed:", err instanceof Error ? err.message : err);
|
|
761
|
-
process.exit(1);
|
|
762
|
-
}
|
|
543
|
+
function diffAction() {
|
|
544
|
+
const red = "\x1B[31m";
|
|
545
|
+
const yellow = "\x1B[33m";
|
|
546
|
+
const reset2 = "\x1B[0m";
|
|
547
|
+
console.error(
|
|
548
|
+
`${red}error:${reset2} \`ardent branch diff\` has been removed.
|
|
549
|
+
|
|
550
|
+
The underlying CDC service (branching-replay-service + StarRocks) was
|
|
551
|
+
deprecated in favour of pgstream. A pgstream-backed diff view is on the
|
|
552
|
+
roadmap but not yet shipped.
|
|
553
|
+
|
|
554
|
+
${yellow}If you need the current state of a branch:${reset2} \`ardent branch info <name>\`
|
|
555
|
+
`
|
|
556
|
+
);
|
|
557
|
+
process.exit(2);
|
|
763
558
|
}
|
|
764
559
|
|
|
765
560
|
// src/commands/branch/index.ts
|
|
@@ -769,7 +564,7 @@ branchCommand.command("list").description("List your branches").action(listActio
|
|
|
769
564
|
branchCommand.command("info [name]").description("Show branch details (defaults to current branch)").action(infoAction);
|
|
770
565
|
branchCommand.command("delete <name>").description("Delete a branch").action(deleteAction);
|
|
771
566
|
branchCommand.command("switch <name>").description("Switch to a different branch").action(switchAction);
|
|
772
|
-
branchCommand.command("diff
|
|
567
|
+
branchCommand.command("diff [name]", { hidden: true }).description("(removed) Show changes on a branch").action(diffAction);
|
|
773
568
|
|
|
774
569
|
// src/commands/connector/index.ts
|
|
775
570
|
import { Command as Command2 } from "commander";
|
|
@@ -807,9 +602,9 @@ function getOnboardingState() {
|
|
|
807
602
|
}
|
|
808
603
|
return { state: "ready", connectorCount, branchCount, currentBranch };
|
|
809
604
|
}
|
|
810
|
-
var
|
|
811
|
-
var
|
|
812
|
-
var
|
|
605
|
+
var dim = "\x1B[2m";
|
|
606
|
+
var reset = "\x1B[0m";
|
|
607
|
+
var green = "\x1B[32m";
|
|
813
608
|
function showOnboarding() {
|
|
814
609
|
const { state, connectorCount, branchCount, currentBranch } = getOnboardingState();
|
|
815
610
|
switch (state) {
|
|
@@ -817,37 +612,37 @@ function showOnboarding() {
|
|
|
817
612
|
console.log(BANNER);
|
|
818
613
|
console.log(`To get started, log in with your GitHub account:
|
|
819
614
|
|
|
820
|
-
${
|
|
615
|
+
${green}ardent login${reset}
|
|
821
616
|
|
|
822
|
-
Run ${
|
|
617
|
+
Run ${dim}ardent --help${reset} to see all commands.
|
|
823
618
|
`);
|
|
824
619
|
break;
|
|
825
620
|
case "no_connectors":
|
|
826
621
|
console.log(`
|
|
827
|
-
${
|
|
622
|
+
${green}\u2713${reset} Logged in
|
|
828
623
|
|
|
829
624
|
Next step \u2014 connect your first database:
|
|
830
625
|
|
|
831
|
-
${
|
|
626
|
+
${green}ardent connector create <type> <connection-url>${reset}
|
|
832
627
|
|
|
833
628
|
Example:
|
|
834
|
-
${
|
|
629
|
+
${dim}ardent connector create postgresql postgresql://user:password@host:5432/database${reset}
|
|
835
630
|
|
|
836
|
-
Run ${
|
|
631
|
+
Run ${dim}ardent --help${reset} to see all commands.
|
|
837
632
|
`);
|
|
838
633
|
break;
|
|
839
634
|
case "no_branches":
|
|
840
635
|
console.log(`
|
|
841
|
-
${
|
|
636
|
+
${green}\u2713${reset} Logged in ${green}\u2713${reset} ${connectorCount} connector${connectorCount !== 1 ? "s" : ""}
|
|
842
637
|
|
|
843
638
|
You're all set! Create your first branch:
|
|
844
639
|
|
|
845
|
-
${
|
|
640
|
+
${green}ardent branch create <name>${reset}
|
|
846
641
|
|
|
847
642
|
Example:
|
|
848
|
-
${
|
|
643
|
+
${dim}ardent branch create my-feature${reset}
|
|
849
644
|
|
|
850
|
-
Run ${
|
|
645
|
+
Run ${dim}ardent --help${reset} to see all commands.
|
|
851
646
|
`);
|
|
852
647
|
return true;
|
|
853
648
|
case "ready":
|
|
@@ -862,20 +657,20 @@ function showNextStep() {
|
|
|
862
657
|
console.log(`
|
|
863
658
|
Next step \u2014 connect your first database:
|
|
864
659
|
|
|
865
|
-
${
|
|
660
|
+
${green}ardent connector create <type> <connection-url>${reset}
|
|
866
661
|
|
|
867
662
|
Example:
|
|
868
|
-
${
|
|
663
|
+
${dim}ardent connector create postgresql postgresql://user:password@host:5432/database${reset}
|
|
869
664
|
`);
|
|
870
665
|
break;
|
|
871
666
|
case "no_branches":
|
|
872
667
|
console.log(`
|
|
873
668
|
Next step \u2014 create your first branch:
|
|
874
669
|
|
|
875
|
-
${
|
|
670
|
+
${green}ardent branch create <name>${reset}
|
|
876
671
|
|
|
877
672
|
Example:
|
|
878
|
-
${
|
|
673
|
+
${dim}ardent branch create my-feature${reset}
|
|
879
674
|
`);
|
|
880
675
|
break;
|
|
881
676
|
case "ready":
|
|
@@ -905,6 +700,33 @@ async function createAction2(type, url, options) {
|
|
|
905
700
|
console.error(` Supported: ${supportedTypes.join(", ")}`);
|
|
906
701
|
process.exit(1);
|
|
907
702
|
}
|
|
703
|
+
const deploymentModel = options.deploymentModel ?? "ardent-cloud";
|
|
704
|
+
if (deploymentModel !== "ardent-cloud" && deploymentModel !== "customer-cloud") {
|
|
705
|
+
console.error(`\u2717 Invalid --deployment-model: ${deploymentModel}`);
|
|
706
|
+
console.error(" Supported: ardent-cloud, customer-cloud");
|
|
707
|
+
process.exit(1);
|
|
708
|
+
}
|
|
709
|
+
const isCustomerCloud = deploymentModel === "customer-cloud";
|
|
710
|
+
if (isCustomerCloud) {
|
|
711
|
+
const missing = [];
|
|
712
|
+
if (!options.awsRoleArn) missing.push("--aws-role-arn");
|
|
713
|
+
if (!options.awsExternalId) missing.push("--aws-external-id");
|
|
714
|
+
if (!options.awsRegion) missing.push("--aws-region");
|
|
715
|
+
if (missing.length > 0) {
|
|
716
|
+
console.error(
|
|
717
|
+
`\u2717 ${missing.join(", ")} required when --deployment-model=customer-cloud`
|
|
718
|
+
);
|
|
719
|
+
process.exit(1);
|
|
720
|
+
}
|
|
721
|
+
} else {
|
|
722
|
+
const stray = options.awsRoleArn || options.awsExternalId || options.awsRegion;
|
|
723
|
+
if (stray) {
|
|
724
|
+
console.error(
|
|
725
|
+
"\u2717 --aws-role-arn / --aws-external-id / --aws-region require --deployment-model=customer-cloud"
|
|
726
|
+
);
|
|
727
|
+
process.exit(1);
|
|
728
|
+
}
|
|
729
|
+
}
|
|
908
730
|
const isByoc = Boolean(options.byoc);
|
|
909
731
|
if (isByoc) {
|
|
910
732
|
if (!options.apiKey || !options.projectId) {
|
|
@@ -932,7 +754,9 @@ async function createAction2(type, url, options) {
|
|
|
932
754
|
}
|
|
933
755
|
let createPayload;
|
|
934
756
|
if (isByoc) {
|
|
935
|
-
console.log(
|
|
757
|
+
console.log(
|
|
758
|
+
`Creating connector (BYOC Neon${isCustomerCloud ? ", customer-cloud data plane" : ""})...`
|
|
759
|
+
);
|
|
936
760
|
createPayload = {
|
|
937
761
|
name: connectorName,
|
|
938
762
|
service_name: "postgresql",
|
|
@@ -949,7 +773,9 @@ async function createAction2(type, url, options) {
|
|
|
949
773
|
console.error(" Example: postgresql://user:password@host:5432/db");
|
|
950
774
|
process.exit(1);
|
|
951
775
|
}
|
|
952
|
-
console.log(
|
|
776
|
+
console.log(
|
|
777
|
+
`Creating connector${isCustomerCloud ? " (customer-cloud data plane)" : ""}...`
|
|
778
|
+
);
|
|
953
779
|
createPayload = {
|
|
954
780
|
name: connectorName,
|
|
955
781
|
service_name: "postgresql",
|
|
@@ -962,6 +788,14 @@ async function createAction2(type, url, options) {
|
|
|
962
788
|
}
|
|
963
789
|
};
|
|
964
790
|
}
|
|
791
|
+
if (isCustomerCloud) {
|
|
792
|
+
createPayload.deployment_model = "customer-cloud";
|
|
793
|
+
createPayload.byoc_access_credentials = {
|
|
794
|
+
role_arn: options.awsRoleArn,
|
|
795
|
+
external_id: options.awsExternalId,
|
|
796
|
+
region: options.awsRegion
|
|
797
|
+
};
|
|
798
|
+
}
|
|
965
799
|
const created = await api.post("/v1/connectors", createPayload);
|
|
966
800
|
const connectorId = created.id;
|
|
967
801
|
if (isByoc) {
|
|
@@ -981,11 +815,11 @@ async function createAction2(type, url, options) {
|
|
|
981
815
|
);
|
|
982
816
|
const discoveryWarnings = discoverResult?.source_metadata?.warnings ?? [];
|
|
983
817
|
if (discoveryWarnings.length > 0) {
|
|
984
|
-
const
|
|
985
|
-
const
|
|
818
|
+
const yellow = "\x1B[33m";
|
|
819
|
+
const reset2 = "\x1B[0m";
|
|
986
820
|
console.log("");
|
|
987
821
|
for (const warning of discoveryWarnings) {
|
|
988
|
-
console.log(`${
|
|
822
|
+
console.log(`${yellow}\u26A0 ${warning}${reset2}`);
|
|
989
823
|
}
|
|
990
824
|
console.log("");
|
|
991
825
|
}
|
|
@@ -1012,7 +846,11 @@ async function createAction2(type, url, options) {
|
|
|
1012
846
|
setCacheEntry("connectors", cachedConnectors);
|
|
1013
847
|
setConfig("currentConnectorId", connectorId);
|
|
1014
848
|
setConfig("currentConnectorName", connectorName);
|
|
1015
|
-
trackEvent("CLI: connector create succeeded", {
|
|
849
|
+
trackEvent("CLI: connector create succeeded", {
|
|
850
|
+
db_type: type,
|
|
851
|
+
byoc: isByoc,
|
|
852
|
+
deployment_model: deploymentModel
|
|
853
|
+
});
|
|
1016
854
|
console.log("\u2713 Connector created and ready");
|
|
1017
855
|
console.log(` ID: ${connectorId}`);
|
|
1018
856
|
showNextStep();
|
|
@@ -1080,25 +918,25 @@ async function listAction2() {
|
|
|
1080
918
|
return;
|
|
1081
919
|
}
|
|
1082
920
|
const currentConnectorId = getConfig("currentConnectorId");
|
|
1083
|
-
const
|
|
1084
|
-
const
|
|
1085
|
-
const
|
|
1086
|
-
const
|
|
921
|
+
const green2 = "\x1B[32m";
|
|
922
|
+
const dim2 = "\x1B[2m";
|
|
923
|
+
const yellow = "\x1B[33m";
|
|
924
|
+
const reset2 = "\x1B[0m";
|
|
1087
925
|
console.log("Connectors:\n");
|
|
1088
926
|
for (const connector of connectors) {
|
|
1089
927
|
const isCurrent = connector.id === currentConnectorId;
|
|
1090
928
|
const icon = connector.status === "healthy" ? "\u25CF" : "\u25CB";
|
|
1091
929
|
const warnings = connector.warnings ?? [];
|
|
1092
|
-
const warningSuffix = warnings.length > 0 ? ` ${
|
|
930
|
+
const warningSuffix = warnings.length > 0 ? ` ${yellow}\u26A0 ${warnings.length}${reset2}` : "";
|
|
1093
931
|
if (isCurrent) {
|
|
1094
|
-
console.log(`${
|
|
1095
|
-
console.log(`${
|
|
932
|
+
console.log(`${green2}* ${icon} ${connector.name}${reset2}${warningSuffix}`);
|
|
933
|
+
console.log(`${green2} ${connector.service_name}${reset2}`);
|
|
1096
934
|
} else {
|
|
1097
935
|
console.log(` ${icon} ${connector.name}${warningSuffix}`);
|
|
1098
|
-
console.log(`${
|
|
936
|
+
console.log(`${dim2} ${connector.service_name}${reset2}`);
|
|
1099
937
|
}
|
|
1100
938
|
for (const warning of warnings) {
|
|
1101
|
-
console.log(`${
|
|
939
|
+
console.log(`${yellow} \u26A0 ${warning}${reset2}`);
|
|
1102
940
|
}
|
|
1103
941
|
console.log();
|
|
1104
942
|
}
|
|
@@ -1214,7 +1052,19 @@ async function switchAction2(name) {
|
|
|
1214
1052
|
|
|
1215
1053
|
// src/commands/connector/index.ts
|
|
1216
1054
|
var connectorCommand = new Command2("connector").description("Manage database connectors");
|
|
1217
|
-
connectorCommand.command("create <type> [url]").description("Create a new connector").option("-n, --name <name>", "Connector name").option("--byoc <provider>", "Bring your own Neon project (e.g. neon)").option("--api-key <key>", "Neon API key (required with --byoc)").option("--project-id <id>", "Neon project ID (required with --byoc)").
|
|
1055
|
+
connectorCommand.command("create <type> [url]").description("Create a new connector").option("-n, --name <name>", "Connector name").option("--byoc <provider>", "Bring your own Neon project (e.g. neon)").option("--api-key <key>", "Neon API key (required with --byoc)").option("--project-id <id>", "Neon project ID (required with --byoc)").option(
|
|
1056
|
+
"--deployment-model <model>",
|
|
1057
|
+
"'ardent-cloud' (default) or 'customer-cloud' to route CDC through the customer's AWS account"
|
|
1058
|
+
).option(
|
|
1059
|
+
"--aws-role-arn <arn>",
|
|
1060
|
+
"ArdentDeployer role ARN in the customer account (required with --deployment-model=customer-cloud)"
|
|
1061
|
+
).option(
|
|
1062
|
+
"--aws-external-id <id>",
|
|
1063
|
+
"External ID for sts:AssumeRole (required with --deployment-model=customer-cloud)"
|
|
1064
|
+
).option(
|
|
1065
|
+
"--aws-region <region>",
|
|
1066
|
+
"AWS region of the customer data plane (required with --deployment-model=customer-cloud)"
|
|
1067
|
+
).action(createAction2);
|
|
1218
1068
|
connectorCommand.command("list").description("List your connectors").action(listAction2);
|
|
1219
1069
|
connectorCommand.command("switch <name>").description("Switch to a different connector").action(switchAction2);
|
|
1220
1070
|
connectorCommand.command("delete <name>").description("Delete a connector by name").action(deleteAction2);
|
|
@@ -1505,18 +1355,18 @@ async function listAction4() {
|
|
|
1505
1355
|
return;
|
|
1506
1356
|
}
|
|
1507
1357
|
const currentProjectId = getConfig("currentProjectId");
|
|
1508
|
-
const
|
|
1509
|
-
const
|
|
1510
|
-
const
|
|
1358
|
+
const green2 = "\x1B[32m";
|
|
1359
|
+
const dim2 = "\x1B[2m";
|
|
1360
|
+
const reset2 = "\x1B[0m";
|
|
1511
1361
|
console.log("Projects:\n");
|
|
1512
1362
|
for (const project of projects) {
|
|
1513
1363
|
const isCurrent = project.id === currentProjectId;
|
|
1514
1364
|
if (isCurrent) {
|
|
1515
|
-
console.log(`${
|
|
1516
|
-
console.log(`${
|
|
1365
|
+
console.log(`${green2}* ${project.name}${reset2}`);
|
|
1366
|
+
console.log(`${green2} ${project.id}${reset2}`);
|
|
1517
1367
|
} else {
|
|
1518
1368
|
console.log(` ${project.name}`);
|
|
1519
|
-
console.log(`${
|
|
1369
|
+
console.log(`${dim2} ${project.id}${reset2}`);
|
|
1520
1370
|
}
|
|
1521
1371
|
console.log();
|
|
1522
1372
|
}
|
|
@@ -1793,11 +1643,11 @@ async function checkForUpdate(currentVersion) {
|
|
|
1793
1643
|
}
|
|
1794
1644
|
}
|
|
1795
1645
|
function printUpdateNotice(current, latest) {
|
|
1796
|
-
const
|
|
1797
|
-
const
|
|
1798
|
-
const
|
|
1646
|
+
const yellow = "\x1B[33m";
|
|
1647
|
+
const green2 = "\x1B[32m";
|
|
1648
|
+
const reset2 = "\x1B[0m";
|
|
1799
1649
|
console.error(
|
|
1800
|
-
`${
|
|
1650
|
+
`${yellow}Update available: ${current} \u2192 ${latest}${reset2} \u2014 run ${green2}npm install -g ardent-cli@latest${reset2}`
|
|
1801
1651
|
);
|
|
1802
1652
|
}
|
|
1803
1653
|
|
|
@@ -1828,7 +1678,6 @@ BRANCHES
|
|
|
1828
1678
|
branch info Show branch details (URL, status, etc.)
|
|
1829
1679
|
branch delete Delete a branch
|
|
1830
1680
|
branch switch Switch to a different branch
|
|
1831
|
-
branch diff Show all changes since branch creation
|
|
1832
1681
|
|
|
1833
1682
|
TEAM
|
|
1834
1683
|
invite <email> Invite a user to your organization
|
|
@@ -1878,9 +1727,6 @@ program.on("command:*", (operands) => {
|
|
|
1878
1727
|
`);
|
|
1879
1728
|
if (unknown === "switch") {
|
|
1880
1729
|
console.error(` Did you mean: ardent branch switch <name>
|
|
1881
|
-
`);
|
|
1882
|
-
} else if (unknown === "diff") {
|
|
1883
|
-
console.error(` Did you mean: ardent branch diff
|
|
1884
1730
|
`);
|
|
1885
1731
|
}
|
|
1886
1732
|
console.error(`Run ardent --help for available commands.`);
|