ardent-cli 0.0.5 → 0.0.8
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 +108 -40
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -104,9 +104,10 @@ async function bootstrapCache() {
|
|
|
104
104
|
"Content-Type": "application/json",
|
|
105
105
|
"Authorization": `Bearer ${token}`
|
|
106
106
|
};
|
|
107
|
-
const [connectorsRes, branchesRes] = await Promise.all([
|
|
107
|
+
const [connectorsRes, branchesRes, meRes] = await Promise.all([
|
|
108
108
|
fetch(`${apiUrl}/v1/cli/connectors`, { headers }),
|
|
109
|
-
fetch(`${apiUrl}/v1/cli/branches`, { headers })
|
|
109
|
+
fetch(`${apiUrl}/v1/cli/branches`, { headers }),
|
|
110
|
+
fetch(`${apiUrl}/v1/cli/me`, { headers })
|
|
110
111
|
]);
|
|
111
112
|
let connectorCount = 0;
|
|
112
113
|
let branchCount = 0;
|
|
@@ -122,10 +123,22 @@ async function bootstrapCache() {
|
|
|
122
123
|
setCacheEntry("branches", branches);
|
|
123
124
|
branchCount = branches.length;
|
|
124
125
|
}
|
|
126
|
+
if (meRes.ok) {
|
|
127
|
+
const user = await meRes.json();
|
|
128
|
+
setConfig("user", user);
|
|
129
|
+
}
|
|
125
130
|
return { connectors: connectorCount, branches: branchCount };
|
|
126
131
|
}
|
|
127
132
|
|
|
128
133
|
// src/lib/api.ts
|
|
134
|
+
function parseApiError(status, text) {
|
|
135
|
+
try {
|
|
136
|
+
const json = JSON.parse(text);
|
|
137
|
+
if (json.detail) return `API error ${status}: ${json.detail}`;
|
|
138
|
+
} catch {
|
|
139
|
+
}
|
|
140
|
+
return `API error ${status}: ${text}`;
|
|
141
|
+
}
|
|
129
142
|
var ApiClient = class {
|
|
130
143
|
getHeaders() {
|
|
131
144
|
const token = getToken();
|
|
@@ -148,7 +161,7 @@ var ApiClient = class {
|
|
|
148
161
|
});
|
|
149
162
|
if (!response.ok) {
|
|
150
163
|
const text = await response.text();
|
|
151
|
-
throw new Error(
|
|
164
|
+
throw new Error(parseApiError(response.status, text));
|
|
152
165
|
}
|
|
153
166
|
return response.json();
|
|
154
167
|
}
|
|
@@ -161,7 +174,7 @@ var ApiClient = class {
|
|
|
161
174
|
});
|
|
162
175
|
if (!response.ok) {
|
|
163
176
|
const text = await response.text();
|
|
164
|
-
throw new Error(
|
|
177
|
+
throw new Error(parseApiError(response.status, text));
|
|
165
178
|
}
|
|
166
179
|
return response.json();
|
|
167
180
|
}
|
|
@@ -174,7 +187,7 @@ var ApiClient = class {
|
|
|
174
187
|
});
|
|
175
188
|
if (!response.ok) {
|
|
176
189
|
const text = await response.text();
|
|
177
|
-
throw new Error(
|
|
190
|
+
throw new Error(parseApiError(response.status, text));
|
|
178
191
|
}
|
|
179
192
|
return response.json();
|
|
180
193
|
}
|
|
@@ -187,7 +200,7 @@ var ApiClient = class {
|
|
|
187
200
|
});
|
|
188
201
|
if (!response.ok) {
|
|
189
202
|
const text = await response.text();
|
|
190
|
-
throw new Error(
|
|
203
|
+
throw new Error(parseApiError(response.status, text));
|
|
191
204
|
}
|
|
192
205
|
return response.json();
|
|
193
206
|
}
|
|
@@ -205,7 +218,8 @@ function isNetworkError(err) {
|
|
|
205
218
|
}
|
|
206
219
|
function isPermissionError(err) {
|
|
207
220
|
if (err instanceof Error) {
|
|
208
|
-
|
|
221
|
+
const msg = err.message.toLowerCase();
|
|
222
|
+
return msg.includes("api error 403") || msg.includes("api error 401") || msg.includes("not authorized") || msg.includes("forbidden");
|
|
209
223
|
}
|
|
210
224
|
return false;
|
|
211
225
|
}
|
|
@@ -766,43 +780,84 @@ async function createAction2(type, url, options) {
|
|
|
766
780
|
console.error(` Supported: ${supportedTypes.join(", ")}`);
|
|
767
781
|
process.exit(1);
|
|
768
782
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
if (!
|
|
772
|
-
console.error("\u2717
|
|
773
|
-
console.error(" Example: postgresql://user:password@host:5432/db");
|
|
783
|
+
const isByoc = Boolean(options.byoc);
|
|
784
|
+
if (isByoc) {
|
|
785
|
+
if (!options.apiKey || !options.projectId) {
|
|
786
|
+
console.error("\u2717 --api-key and --project-id are required when using --byoc");
|
|
774
787
|
process.exit(1);
|
|
775
788
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
console.
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
+
if (options.byoc !== "neon") {
|
|
790
|
+
console.error(`\u2717 Unsupported BYOC provider: ${options.byoc}`);
|
|
791
|
+
console.error(" Supported: neon");
|
|
792
|
+
process.exit(1);
|
|
793
|
+
}
|
|
794
|
+
} else if (!url) {
|
|
795
|
+
console.error("\u2717 Connection URL required");
|
|
796
|
+
console.error(" Example: ardent connector create postgresql postgresql://user:pass@host:5432/db");
|
|
797
|
+
process.exit(1);
|
|
798
|
+
}
|
|
799
|
+
try {
|
|
800
|
+
const connectorName = options.name || (isByoc ? "my-neon-connection" : "my-postgresql-connection");
|
|
801
|
+
let createPayload;
|
|
802
|
+
if (isByoc) {
|
|
803
|
+
console.log("Creating connector (BYOC Neon)...");
|
|
804
|
+
createPayload = {
|
|
805
|
+
name: connectorName,
|
|
806
|
+
service_name: "postgresql",
|
|
807
|
+
byoc: options.byoc,
|
|
808
|
+
neon_api_key: options.apiKey,
|
|
809
|
+
neon_project_id: options.projectId,
|
|
810
|
+
connection_details: {}
|
|
811
|
+
};
|
|
812
|
+
} else {
|
|
813
|
+
const parsed = parsePostgresUrl(url);
|
|
814
|
+
if (!parsed.password) {
|
|
815
|
+
console.error("\u2717 Password required in connection URL");
|
|
816
|
+
console.error(" Example: postgresql://user:password@host:5432/db");
|
|
817
|
+
process.exit(1);
|
|
818
|
+
}
|
|
819
|
+
console.log("Creating connector...");
|
|
820
|
+
createPayload = {
|
|
821
|
+
name: connectorName,
|
|
822
|
+
service_name: "postgresql",
|
|
823
|
+
connection_details: {
|
|
824
|
+
host: parsed.host,
|
|
825
|
+
port: parsed.port,
|
|
826
|
+
username: parsed.username,
|
|
827
|
+
password: parsed.password
|
|
828
|
+
}
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
const created = await api.post("/v1/connectors", createPayload);
|
|
789
832
|
const connectorId = created.id;
|
|
790
|
-
|
|
791
|
-
await api.post(`/v1/connectors/${connectorId}/discover`, {});
|
|
792
|
-
console.log("Setting selection...");
|
|
793
|
-
await api.post(`/v1/connectors/${connectorId}/selection`, {
|
|
794
|
-
selected_paths: ["*"]
|
|
795
|
-
});
|
|
796
|
-
const connector = await api.get(`/v1/connectors/${connectorId}`);
|
|
797
|
-
if (connector.branching_engine_status === "configuration_verified") {
|
|
833
|
+
if (isByoc) {
|
|
798
834
|
console.log("Setting up branching engine...");
|
|
799
|
-
|
|
835
|
+
try {
|
|
836
|
+
await api.post(`/v1/connectors/${connectorId}/engine-setup`, {});
|
|
837
|
+
} catch (setupErr) {
|
|
838
|
+
console.error("\u2717 Engine setup failed. To retry, delete and recreate:");
|
|
839
|
+
console.error(` ardent connector delete ${connectorName}`);
|
|
840
|
+
throw setupErr;
|
|
841
|
+
}
|
|
842
|
+
} else {
|
|
843
|
+
console.log("Discovering schema...");
|
|
844
|
+
await api.post(`/v1/connectors/${connectorId}/discover`, {});
|
|
845
|
+
console.log("Setting selection...");
|
|
846
|
+
await api.post(`/v1/connectors/${connectorId}/selection`, {
|
|
847
|
+
selected_paths: ["*"]
|
|
848
|
+
});
|
|
849
|
+
const connector = await api.get(`/v1/connectors/${connectorId}`);
|
|
850
|
+
if (connector.branching_engine_status === "configuration_verified") {
|
|
851
|
+
console.log("Setting up branching engine...");
|
|
852
|
+
await api.post(`/v1/connectors/${connectorId}/engine-setup`, {});
|
|
853
|
+
}
|
|
800
854
|
}
|
|
855
|
+
const finalConnector = await api.get(`/v1/connectors/${connectorId}`);
|
|
801
856
|
const newConnector = {
|
|
802
857
|
id: connectorId,
|
|
803
858
|
name: connectorName,
|
|
804
859
|
service_name: "postgresql",
|
|
805
|
-
status:
|
|
860
|
+
status: finalConnector.branching_engine_status ?? finalConnector.connection_status ?? "pending"
|
|
806
861
|
};
|
|
807
862
|
const cached = getCacheEntry("connectors");
|
|
808
863
|
const cachedConnectors = cached?.data || [];
|
|
@@ -924,7 +979,7 @@ async function deleteAction2(name) {
|
|
|
924
979
|
|
|
925
980
|
// src/commands/connector/index.ts
|
|
926
981
|
var connectorCommand = new Command2("connector").description("Manage database connectors");
|
|
927
|
-
connectorCommand.command("create <type>
|
|
982
|
+
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)").action(createAction2);
|
|
928
983
|
connectorCommand.command("list").description("List your connectors").action(listAction2);
|
|
929
984
|
connectorCommand.command("delete <name>").description("Delete a connector by name").action(deleteAction2);
|
|
930
985
|
|
|
@@ -1182,12 +1237,25 @@ function logoutAction() {
|
|
|
1182
1237
|
// src/commands/auth/status.ts
|
|
1183
1238
|
function statusAction() {
|
|
1184
1239
|
const token = getConfig("token");
|
|
1185
|
-
if (token) {
|
|
1186
|
-
console.log("\u2713 Authenticated");
|
|
1187
|
-
console.log(` Token: ${token.slice(0, 8)}...${token.slice(-4)}`);
|
|
1188
|
-
} else {
|
|
1240
|
+
if (!token) {
|
|
1189
1241
|
console.log("\u2717 Not authenticated");
|
|
1190
1242
|
console.log(" Run: ardent login");
|
|
1243
|
+
return;
|
|
1244
|
+
}
|
|
1245
|
+
const user = getConfig("user");
|
|
1246
|
+
console.log("\u2713 Authenticated");
|
|
1247
|
+
if (user?.full_name) {
|
|
1248
|
+
console.log(` Account: ${user.full_name}`);
|
|
1249
|
+
}
|
|
1250
|
+
if (user?.email) {
|
|
1251
|
+
console.log(` Email: ${user.email}`);
|
|
1252
|
+
}
|
|
1253
|
+
if (user?.org_name) {
|
|
1254
|
+
console.log(` Org: ${user.org_name}`);
|
|
1255
|
+
}
|
|
1256
|
+
if (!user) {
|
|
1257
|
+
console.log(` Token: ${token.slice(0, 8)}...${token.slice(-4)}`);
|
|
1258
|
+
console.log(" Run: ardent login to refresh profile info");
|
|
1191
1259
|
}
|
|
1192
1260
|
}
|
|
1193
1261
|
|