ardent-cli 0.0.55 → 0.0.56
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 +101 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2658,8 +2658,9 @@ async function listAction2() {
|
|
|
2658
2658
|
if (render.kind === "engine_pending") enginePendingCount += 1;
|
|
2659
2659
|
const warnings = connector.warnings ?? [];
|
|
2660
2660
|
const warningSuffix = warnings.length > 0 ? ` ${yellow}\u26A0 ${warnings.length}${reset2}` : "";
|
|
2661
|
+
const lockSuffix = connector.deletion_locked ? ` ${yellow}[delete locked]${reset2}` : "";
|
|
2661
2662
|
const statusSuffix = render.kind === "ready" ? "" : ` ${render.color}[${connectorStatusDisplay(connector.status)}]${reset2}`;
|
|
2662
|
-
const nameLine = isCurrent ? `${green2}* ${render.color}${render.icon}${green2} ${connector.name}${reset2}${warningSuffix}${statusSuffix}` : ` ${render.color}${render.icon}${reset2} ${connector.name}${warningSuffix}${statusSuffix}`;
|
|
2663
|
+
const nameLine = isCurrent ? `${green2}* ${render.color}${render.icon}${green2} ${connector.name}${reset2}${warningSuffix}${lockSuffix}${statusSuffix}` : ` ${render.color}${render.icon}${reset2} ${connector.name}${warningSuffix}${lockSuffix}${statusSuffix}`;
|
|
2663
2664
|
console.log(nameLine);
|
|
2664
2665
|
if (isCurrent) {
|
|
2665
2666
|
console.log(`${green2} ${connector.service_name}${reset2}`);
|
|
@@ -2693,6 +2694,10 @@ async function listAction2() {
|
|
|
2693
2694
|
var CONNECTOR_DELETE_MAX_WAIT_MS = 60 * 60 * 1e3;
|
|
2694
2695
|
var CONNECTOR_DELETE_POLL_INTERVAL_MS = 5 * 1e3;
|
|
2695
2696
|
var CONNECTOR_DELETE_TRANSIENT_WARN_EVERY = 6;
|
|
2697
|
+
var CONNECTOR_DELETION_LOCKED_MESSAGE = "Connector deletion is locked. Unlock this connector, then retry.";
|
|
2698
|
+
function stripApiErrorPrefix(message) {
|
|
2699
|
+
return message.replace(/^API error \d{3}:\s*/, "");
|
|
2700
|
+
}
|
|
2696
2701
|
async function deleteAction2(name, options = {}) {
|
|
2697
2702
|
const cached = getCacheEntry("connectors");
|
|
2698
2703
|
let connector = cached?.data.find((c) => c.name === name);
|
|
@@ -2748,6 +2753,11 @@ async function deleteAction2(name, options = {}) {
|
|
|
2748
2753
|
process.exit(1);
|
|
2749
2754
|
}
|
|
2750
2755
|
const message = err instanceof Error ? err.message : String(err);
|
|
2756
|
+
if (message.includes(CONNECTOR_DELETION_LOCKED_MESSAGE)) {
|
|
2757
|
+
trackEvent("CLI: connector delete failed", { reason: "deletion_locked" });
|
|
2758
|
+
console.error(`\u2717 ${stripApiErrorPrefix(message)}`);
|
|
2759
|
+
process.exit(1);
|
|
2760
|
+
}
|
|
2751
2761
|
const isDrainRefusal = message.includes("Branch still has un-replicated changes") || typeof err === "object" && err !== null && "status" in err && err.status === 409;
|
|
2752
2762
|
if (isDrainRefusal) {
|
|
2753
2763
|
trackEvent("CLI: connector delete failed", { reason: "drain_refused" });
|
|
@@ -3253,6 +3263,94 @@ async function updateAction(name, options = {}) {
|
|
|
3253
3263
|
}
|
|
3254
3264
|
}
|
|
3255
3265
|
|
|
3266
|
+
// src/commands/connector/lock.ts
|
|
3267
|
+
async function resolveConnectorByName2(name) {
|
|
3268
|
+
const cached = getCacheEntry("connectors");
|
|
3269
|
+
let connector = cached?.data.find((candidate) => candidate.name === name);
|
|
3270
|
+
if (!connector) {
|
|
3271
|
+
try {
|
|
3272
|
+
const result = await api.get("/v1/cli/connectors");
|
|
3273
|
+
if (result.connectors) {
|
|
3274
|
+
setCacheEntry("connectors", result.connectors);
|
|
3275
|
+
connector = result.connectors.find((candidate) => candidate.name === name);
|
|
3276
|
+
}
|
|
3277
|
+
} catch (err) {
|
|
3278
|
+
if (isNetworkError(err)) {
|
|
3279
|
+
console.error("\u2717 Connector not found in cache and offline");
|
|
3280
|
+
process.exit(1);
|
|
3281
|
+
}
|
|
3282
|
+
throw err;
|
|
3283
|
+
}
|
|
3284
|
+
}
|
|
3285
|
+
if (!connector) {
|
|
3286
|
+
console.error(`\u2717 Connector "${name}" not found`);
|
|
3287
|
+
console.log(" Run: ardent connector list");
|
|
3288
|
+
process.exit(1);
|
|
3289
|
+
}
|
|
3290
|
+
return connector;
|
|
3291
|
+
}
|
|
3292
|
+
function refreshCachedConnector(updatedConnector) {
|
|
3293
|
+
const currentCache = getCacheEntry("connectors");
|
|
3294
|
+
if (!currentCache?.data) {
|
|
3295
|
+
return;
|
|
3296
|
+
}
|
|
3297
|
+
const updatedConnectors = currentCache.data.map(
|
|
3298
|
+
(connector) => connector.id === updatedConnector.id ? { ...connector, ...updatedConnector } : connector
|
|
3299
|
+
);
|
|
3300
|
+
setCacheEntry("connectors", updatedConnectors);
|
|
3301
|
+
}
|
|
3302
|
+
async function lockAction(name, options = {}) {
|
|
3303
|
+
const connector = await resolveConnectorByName2(name);
|
|
3304
|
+
try {
|
|
3305
|
+
const response = await api.post(
|
|
3306
|
+
`/v1/connectors/${connector.id}/deletion-lock`,
|
|
3307
|
+
{ reason: options.reason ?? null }
|
|
3308
|
+
);
|
|
3309
|
+
refreshCachedConnector({ ...response.connector, deletion_locked: true });
|
|
3310
|
+
trackEvent("CLI: connector deletion lock succeeded");
|
|
3311
|
+
console.log(`\u2713 Connector deletion locked for '${name}'`);
|
|
3312
|
+
} catch (err) {
|
|
3313
|
+
if (isPermissionError(err)) {
|
|
3314
|
+
trackEvent("CLI: connector deletion lock failed", { reason: "permission_denied" });
|
|
3315
|
+
console.error("\u2717 You don't have permission to update this connector.");
|
|
3316
|
+
process.exit(1);
|
|
3317
|
+
}
|
|
3318
|
+
if (isNetworkError(err)) {
|
|
3319
|
+
trackEvent("CLI: connector deletion lock failed", { reason: "offline" });
|
|
3320
|
+
console.error("\u2717 Cannot lock connector deletion while offline");
|
|
3321
|
+
process.exit(1);
|
|
3322
|
+
}
|
|
3323
|
+
trackEvent("CLI: connector deletion lock failed", { reason: "api_error" });
|
|
3324
|
+
console.error("\u2717 Failed:", err instanceof Error ? err.message : err);
|
|
3325
|
+
process.exit(1);
|
|
3326
|
+
}
|
|
3327
|
+
}
|
|
3328
|
+
async function unlockAction(name) {
|
|
3329
|
+
const connector = await resolveConnectorByName2(name);
|
|
3330
|
+
try {
|
|
3331
|
+
const response = await api.delete(
|
|
3332
|
+
`/v1/connectors/${connector.id}/deletion-lock`
|
|
3333
|
+
);
|
|
3334
|
+
refreshCachedConnector({ ...response.connector, deletion_locked: false });
|
|
3335
|
+
trackEvent("CLI: connector deletion unlock succeeded");
|
|
3336
|
+
console.log(`\u2713 Connector deletion unlocked for '${name}'`);
|
|
3337
|
+
} catch (err) {
|
|
3338
|
+
if (isPermissionError(err)) {
|
|
3339
|
+
trackEvent("CLI: connector deletion unlock failed", { reason: "permission_denied" });
|
|
3340
|
+
console.error("\u2717 You don't have permission to update this connector.");
|
|
3341
|
+
process.exit(1);
|
|
3342
|
+
}
|
|
3343
|
+
if (isNetworkError(err)) {
|
|
3344
|
+
trackEvent("CLI: connector deletion unlock failed", { reason: "offline" });
|
|
3345
|
+
console.error("\u2717 Cannot unlock connector deletion while offline");
|
|
3346
|
+
process.exit(1);
|
|
3347
|
+
}
|
|
3348
|
+
trackEvent("CLI: connector deletion unlock failed", { reason: "api_error" });
|
|
3349
|
+
console.error("\u2717 Failed:", err instanceof Error ? err.message : err);
|
|
3350
|
+
process.exit(1);
|
|
3351
|
+
}
|
|
3352
|
+
}
|
|
3353
|
+
|
|
3256
3354
|
// src/commands/connector/index.ts
|
|
3257
3355
|
var connectorCommand = new Command2("connector").description("Manage database connectors");
|
|
3258
3356
|
connectorCommand.command("preflight <type> [url]").description(
|
|
@@ -3305,6 +3403,8 @@ connectorCommand.command("delete <name>").description("Delete a connector by nam
|
|
|
3305
3403
|
"--force",
|
|
3306
3404
|
"Skip the wait for in-flight changes to finish replicating. Any un-replicated changes are abandoned."
|
|
3307
3405
|
).action(deleteAction2);
|
|
3406
|
+
connectorCommand.command("lock <name>").description("Lock connector deletion").option("--reason <text>", "Optional reason for the deletion lock").action(lockAction);
|
|
3407
|
+
connectorCommand.command("unlock <name>").description("Unlock connector deletion").action(unlockAction);
|
|
3308
3408
|
|
|
3309
3409
|
// src/commands/invite/index.ts
|
|
3310
3410
|
import { Command as Command3 } from "commander";
|