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.
Files changed (2) hide show
  1. package/dist/index.js +101 -1
  2. 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";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ardent-cli",
3
- "version": "0.0.55",
3
+ "version": "0.0.56",
4
4
  "description": "Git for Data infrastructure",
5
5
  "type": "module",
6
6
  "bin": {