ardent-cli 0.0.5 → 0.0.7
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 +84 -34
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -126,6 +126,14 @@ async function bootstrapCache() {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
// src/lib/api.ts
|
|
129
|
+
function parseApiError(status, text) {
|
|
130
|
+
try {
|
|
131
|
+
const json = JSON.parse(text);
|
|
132
|
+
if (json.detail) return `API error ${status}: ${json.detail}`;
|
|
133
|
+
} catch {
|
|
134
|
+
}
|
|
135
|
+
return `API error ${status}: ${text}`;
|
|
136
|
+
}
|
|
129
137
|
var ApiClient = class {
|
|
130
138
|
getHeaders() {
|
|
131
139
|
const token = getToken();
|
|
@@ -148,7 +156,7 @@ var ApiClient = class {
|
|
|
148
156
|
});
|
|
149
157
|
if (!response.ok) {
|
|
150
158
|
const text = await response.text();
|
|
151
|
-
throw new Error(
|
|
159
|
+
throw new Error(parseApiError(response.status, text));
|
|
152
160
|
}
|
|
153
161
|
return response.json();
|
|
154
162
|
}
|
|
@@ -161,7 +169,7 @@ var ApiClient = class {
|
|
|
161
169
|
});
|
|
162
170
|
if (!response.ok) {
|
|
163
171
|
const text = await response.text();
|
|
164
|
-
throw new Error(
|
|
172
|
+
throw new Error(parseApiError(response.status, text));
|
|
165
173
|
}
|
|
166
174
|
return response.json();
|
|
167
175
|
}
|
|
@@ -174,7 +182,7 @@ var ApiClient = class {
|
|
|
174
182
|
});
|
|
175
183
|
if (!response.ok) {
|
|
176
184
|
const text = await response.text();
|
|
177
|
-
throw new Error(
|
|
185
|
+
throw new Error(parseApiError(response.status, text));
|
|
178
186
|
}
|
|
179
187
|
return response.json();
|
|
180
188
|
}
|
|
@@ -187,7 +195,7 @@ var ApiClient = class {
|
|
|
187
195
|
});
|
|
188
196
|
if (!response.ok) {
|
|
189
197
|
const text = await response.text();
|
|
190
|
-
throw new Error(
|
|
198
|
+
throw new Error(parseApiError(response.status, text));
|
|
191
199
|
}
|
|
192
200
|
return response.json();
|
|
193
201
|
}
|
|
@@ -205,7 +213,8 @@ function isNetworkError(err) {
|
|
|
205
213
|
}
|
|
206
214
|
function isPermissionError(err) {
|
|
207
215
|
if (err instanceof Error) {
|
|
208
|
-
|
|
216
|
+
const msg = err.message.toLowerCase();
|
|
217
|
+
return msg.includes("api error 403") || msg.includes("api error 401") || msg.includes("not authorized") || msg.includes("forbidden");
|
|
209
218
|
}
|
|
210
219
|
return false;
|
|
211
220
|
}
|
|
@@ -766,43 +775,84 @@ async function createAction2(type, url, options) {
|
|
|
766
775
|
console.error(` Supported: ${supportedTypes.join(", ")}`);
|
|
767
776
|
process.exit(1);
|
|
768
777
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
if (!
|
|
772
|
-
console.error("\u2717
|
|
773
|
-
console.error(" Example: postgresql://user:password@host:5432/db");
|
|
778
|
+
const isByoc = Boolean(options.byoc);
|
|
779
|
+
if (isByoc) {
|
|
780
|
+
if (!options.apiKey || !options.projectId) {
|
|
781
|
+
console.error("\u2717 --api-key and --project-id are required when using --byoc");
|
|
774
782
|
process.exit(1);
|
|
775
783
|
}
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
console.
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
784
|
+
if (options.byoc !== "neon") {
|
|
785
|
+
console.error(`\u2717 Unsupported BYOC provider: ${options.byoc}`);
|
|
786
|
+
console.error(" Supported: neon");
|
|
787
|
+
process.exit(1);
|
|
788
|
+
}
|
|
789
|
+
} else if (!url) {
|
|
790
|
+
console.error("\u2717 Connection URL required");
|
|
791
|
+
console.error(" Example: ardent connector create postgresql postgresql://user:pass@host:5432/db");
|
|
792
|
+
process.exit(1);
|
|
793
|
+
}
|
|
794
|
+
try {
|
|
795
|
+
const connectorName = options.name || (isByoc ? "my-neon-connection" : "my-postgresql-connection");
|
|
796
|
+
let createPayload;
|
|
797
|
+
if (isByoc) {
|
|
798
|
+
console.log("Creating connector (BYOC Neon)...");
|
|
799
|
+
createPayload = {
|
|
800
|
+
name: connectorName,
|
|
801
|
+
service_name: "postgresql",
|
|
802
|
+
byoc: options.byoc,
|
|
803
|
+
neon_api_key: options.apiKey,
|
|
804
|
+
neon_project_id: options.projectId,
|
|
805
|
+
connection_details: {}
|
|
806
|
+
};
|
|
807
|
+
} else {
|
|
808
|
+
const parsed = parsePostgresUrl(url);
|
|
809
|
+
if (!parsed.password) {
|
|
810
|
+
console.error("\u2717 Password required in connection URL");
|
|
811
|
+
console.error(" Example: postgresql://user:password@host:5432/db");
|
|
812
|
+
process.exit(1);
|
|
813
|
+
}
|
|
814
|
+
console.log("Creating connector...");
|
|
815
|
+
createPayload = {
|
|
816
|
+
name: connectorName,
|
|
817
|
+
service_name: "postgresql",
|
|
818
|
+
connection_details: {
|
|
819
|
+
host: parsed.host,
|
|
820
|
+
port: parsed.port,
|
|
821
|
+
username: parsed.username,
|
|
822
|
+
password: parsed.password
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
const created = await api.post("/v1/connectors", createPayload);
|
|
789
827
|
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") {
|
|
828
|
+
if (isByoc) {
|
|
798
829
|
console.log("Setting up branching engine...");
|
|
799
|
-
|
|
830
|
+
try {
|
|
831
|
+
await api.post(`/v1/connectors/${connectorId}/engine-setup`, {});
|
|
832
|
+
} catch (setupErr) {
|
|
833
|
+
console.error("\u2717 Engine setup failed. To retry, delete and recreate:");
|
|
834
|
+
console.error(` ardent connector delete ${connectorName}`);
|
|
835
|
+
throw setupErr;
|
|
836
|
+
}
|
|
837
|
+
} else {
|
|
838
|
+
console.log("Discovering schema...");
|
|
839
|
+
await api.post(`/v1/connectors/${connectorId}/discover`, {});
|
|
840
|
+
console.log("Setting selection...");
|
|
841
|
+
await api.post(`/v1/connectors/${connectorId}/selection`, {
|
|
842
|
+
selected_paths: ["*"]
|
|
843
|
+
});
|
|
844
|
+
const connector = await api.get(`/v1/connectors/${connectorId}`);
|
|
845
|
+
if (connector.branching_engine_status === "configuration_verified") {
|
|
846
|
+
console.log("Setting up branching engine...");
|
|
847
|
+
await api.post(`/v1/connectors/${connectorId}/engine-setup`, {});
|
|
848
|
+
}
|
|
800
849
|
}
|
|
850
|
+
const finalConnector = await api.get(`/v1/connectors/${connectorId}`);
|
|
801
851
|
const newConnector = {
|
|
802
852
|
id: connectorId,
|
|
803
853
|
name: connectorName,
|
|
804
854
|
service_name: "postgresql",
|
|
805
|
-
status:
|
|
855
|
+
status: finalConnector.branching_engine_status ?? finalConnector.connection_status ?? "pending"
|
|
806
856
|
};
|
|
807
857
|
const cached = getCacheEntry("connectors");
|
|
808
858
|
const cachedConnectors = cached?.data || [];
|
|
@@ -924,7 +974,7 @@ async function deleteAction2(name) {
|
|
|
924
974
|
|
|
925
975
|
// src/commands/connector/index.ts
|
|
926
976
|
var connectorCommand = new Command2("connector").description("Manage database connectors");
|
|
927
|
-
connectorCommand.command("create <type>
|
|
977
|
+
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
978
|
connectorCommand.command("list").description("List your connectors").action(listAction2);
|
|
929
979
|
connectorCommand.command("delete <name>").description("Delete a connector by name").action(deleteAction2);
|
|
930
980
|
|