@go-to-k/cdkd 0.220.5 → 0.221.1

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/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { A as withErrorHandling, B as generateResourceNameWithFallback, C as StackHasActiveImportsError, F as getLiveRenderer, H as withStackName, I as PATTERN_B_NAME_PROPERTIES, L as PATTERN_B_RESOURCE_TYPES, M as getLogger, P as runStackBuffered, S as ResourceUpdateNotSupportedError, V as withSkipPrefix, _ as MissingCdkCliError, a as assertRegionMatch, b as ProvisioningError, f as LocalInvokeBuildError$1, i as resolveExplicitPhysicalId, k as normalizeAwsError, l as CdkdError, m as LocalStartServiceError, n as matchesCdkPath, o as disableInstanceApiTermination, p as LocalMigrateError, r as normalizeAwsTagsToCfn, s as isTerminationProtectionPropagationError, t as CDK_PATH_TAG, v as NestedStackChildDirectDestroyError, w as StackTerminationProtectionError, x as ResourceTimeoutError, y as PartialFailureError, z as generateResourceName } from "./import-helpers-wLipXr5g.js";
3
3
  import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-pjPwZz1r.js";
4
- import { $ as resolveBucketRegion, A as stringifyValue, B as resolveApp, C as DiffCalculator, D as S3StateBackend, E as LockManager, F as runDockerForeground, G as warnDeprecatedNoPrefixCliFlag, H as resolveSkipPrefix, I as runDockerStreaming, J as MIGRATE_TMP_PREFIX, K as CFN_TEMPLATE_BODY_LIMIT, L as Synthesizer, M as buildDockerImage, N as formatDockerLoginError, O as shouldRetainResource, P as getDockerCmd, R as getDefaultStateBucketName, S as applyRoleArnIfSet, T as TemplateParser, U as resolveStateBucketWithDefault, V as resolveCaptureObservedState, W as resolveStateBucketWithDefaultAndSource, X as uploadCfnTemplate, Y as findLargeInlineResources, Z as AssemblyReader, _ as collectInlinePolicyNamesManagedBySiblings, a as withRetry, b as CloudControlProvider, c as extractDeploymentEventError, d as cyan, f as gray, g as IAMRoleProvider, h as yellow, i as withResourceDeadline, j as WorkGraph, k as AssetPublisher, l as formatResourceLine, m as red, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as isRetryableTransientError, p as green, q as CFN_TEMPLATE_URL_LIMIT, r as DeployEngine, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as bold, v as ProviderRegistry, w as DagBuilder, x as IntrinsicFunctionResolver, y as findActionableSilentDrops, z as getLegacyStateBucketName } from "./deploy-engine-xlz3wc4W.js";
4
+ import { A as AssetPublisher, B as getLegacyStateBucketName, C as DiffCalculator, D as S3StateBackend, E as LockManager, F as getDockerCmd, G as resolveStateBucketWithDefaultAndSource, H as resolveCaptureObservedState, I as runDockerForeground, J as CFN_TEMPLATE_URL_LIMIT, K as warnDeprecatedNoPrefixCliFlag, L as runDockerStreaming, M as WorkGraph, N as buildDockerImage, O as rebuildClientForBucketRegion, P as formatDockerLoginError, Q as AssemblyReader, R as Synthesizer, S as applyRoleArnIfSet, T as TemplateParser, U as resolveSkipPrefix, V as resolveApp, W as resolveStateBucketWithDefault, X as findLargeInlineResources, Y as MIGRATE_TMP_PREFIX, Z as uploadCfnTemplate, _ as collectInlinePolicyNamesManagedBySiblings, a as withRetry, b as CloudControlProvider, c as extractDeploymentEventError, d as cyan, et as resolveBucketRegion, f as gray, g as IAMRoleProvider, h as yellow, i as withResourceDeadline, j as stringifyValue, k as shouldRetainResource, l as formatResourceLine, m as red, n as DEFAULT_RESOURCE_WARN_AFTER_MS, o as isRetryableTransientError, p as green, q as CFN_TEMPLATE_BODY_LIMIT, r as DeployEngine, s as IMPLICIT_DELETE_DEPENDENCIES, t as DEFAULT_RESOURCE_TIMEOUT_MS, u as bold, v as ProviderRegistry, w as DagBuilder, x as IntrinsicFunctionResolver, y as findActionableSilentDrops, z as getDefaultStateBucketName } from "./deploy-engine-OWyYqmlc.js";
5
5
  import { t as ASGProvider } from "./asg-provider-B_hrCxRx.js";
6
6
  import { AsyncLocalStorage } from "node:async_hooks";
7
7
  import { randomBytes, randomUUID } from "node:crypto";
@@ -1553,7 +1553,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1553
1553
  const FLUSH_EVENT_THRESHOLD = 50;
1554
1554
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1555
1555
  function getCdkdVersion() {
1556
- return "0.220.5";
1556
+ return "0.221.1";
1557
1557
  }
1558
1558
  /**
1559
1559
  * Generate a time-sortable unique run id, e.g.
@@ -2036,36 +2036,14 @@ var ExportIndexStore = class {
2036
2036
  if (this.resolveInFlight) return this.resolveInFlight;
2037
2037
  this.resolveInFlight = (async () => {
2038
2038
  try {
2039
- const config = this.s3Client.config;
2040
- if (!config || typeof config.region !== "function") {
2041
- this.clientResolved = true;
2042
- return;
2043
- }
2044
- const currentRegion = await config.region();
2045
- const fallbackRegion = typeof currentRegion === "string" ? currentRegion : void 0;
2046
- let probeCredentials;
2047
- try {
2048
- if (typeof config.credentials === "function") probeCredentials = await config.credentials();
2049
- } catch {
2050
- probeCredentials = void 0;
2051
- }
2052
- const bucketRegion = await resolveBucketRegion(this.bucket, {
2053
- ...probeCredentials && { credentials: probeCredentials },
2054
- ...fallbackRegion && { fallbackRegion }
2039
+ const replacement = await rebuildClientForBucketRegion(this.s3Client, this.bucket, {
2040
+ reuseClientCredentials: true,
2041
+ tolerateNonStandardClient: true,
2042
+ onRebuild: ({ bucketRegion, currentRegion }) => {
2043
+ this.logger.debug(`State bucket '${this.bucket}' is in '${bucketRegion}' (exports-index client was '${String(currentRegion)}'); building a region-corrected S3 client for index operations.`);
2044
+ }
2055
2045
  });
2056
- if (bucketRegion !== currentRegion) {
2057
- this.logger.debug(`State bucket '${this.bucket}' is in '${bucketRegion}' (exports-index client was '${String(currentRegion)}'); building a region-corrected S3 client for index operations.`);
2058
- this.s3Client = new S3Client({
2059
- region: bucketRegion,
2060
- credentials: this.s3Client.config.credentials,
2061
- logger: {
2062
- debug: () => {},
2063
- info: () => {},
2064
- warn: () => {},
2065
- error: () => {}
2066
- }
2067
- });
2068
- }
2046
+ if (replacement) this.s3Client = replacement;
2069
2047
  this.clientResolved = true;
2070
2048
  } finally {
2071
2049
  this.resolveInFlight = null;
@@ -34416,7 +34394,8 @@ async function runDestroyForStack(stackName, state, ctx) {
34416
34394
  skippedEmpty: false,
34417
34395
  deletedCount: 0,
34418
34396
  retainedCount: 0,
34419
- errorCount: 0
34397
+ errorCount: 0,
34398
+ interrupted: false
34420
34399
  };
34421
34400
  const resourceCount = Object.keys(state.resources).length;
34422
34401
  const regionForState = state.region ?? ctx.baseRegion;
@@ -34509,6 +34488,20 @@ async function runDestroyForStack(stackName, state, ctx) {
34509
34488
  };
34510
34489
  const renderer = getLiveRenderer();
34511
34490
  renderer.start();
34491
+ let draining = false;
34492
+ const sigintHandler = () => {
34493
+ if (draining) {
34494
+ ctx.lockManager.releaseLock(stackName, regionForState).catch(() => {});
34495
+ process.stderr.write(`\nForce-quit: stack lock may not be released. If the next run reports a lock, run: cdkd force-unlock ${stackName}\n`);
34496
+ process.exit(130);
34497
+ }
34498
+ draining = true;
34499
+ renderer.printAbove(() => {
34500
+ process.stderr.write("\nInterrupted — finishing in-flight deletes, then flushing state and releasing the lock (press Ctrl-C again to force-quit)...\n");
34501
+ });
34502
+ };
34503
+ process.setMaxListeners(Math.max(process.getMaxListeners(), 100));
34504
+ process.on("SIGINT", sigintHandler);
34512
34505
  try {
34513
34506
  logger.info("Building dependency graph...");
34514
34507
  const template = {
@@ -34550,11 +34543,16 @@ async function runDestroyForStack(stackName, state, ctx) {
34550
34543
  const executionLevels = dagBuilder.getExecutionLevels(graph);
34551
34544
  logger.debug(`Dependency graph: ${executionLevels.length} level(s)`);
34552
34545
  for (let levelIndex = executionLevels.length - 1; levelIndex >= 0; levelIndex--) {
34546
+ if (draining) {
34547
+ logger.debug("Interrupted (draining) — not scheduling further deletion levels");
34548
+ break;
34549
+ }
34553
34550
  const level = executionLevels[levelIndex];
34554
34551
  if (!level) continue;
34555
34552
  logger.debug(`Deletion level ${executionLevels.length - levelIndex}/${executionLevels.length} (${level.length} resources)`);
34556
34553
  const stackRegion = state.region ?? ctx.baseRegion;
34557
34554
  const deletePromises = level.map(async (logicalId) => {
34555
+ if (draining) return;
34558
34556
  const resource = state.resources[logicalId];
34559
34557
  if (!resource) {
34560
34558
  logger.warn(`Resource ${logicalId} not found in state, skipping`);
@@ -34691,8 +34689,10 @@ async function runDestroyForStack(stackName, state, ctx) {
34691
34689
  });
34692
34690
  await Promise.all(deletePromises);
34693
34691
  }
34692
+ result.interrupted = draining;
34694
34693
  await saveChain;
34695
- if (result.errorCount === 0) {
34694
+ const preserveState = result.errorCount > 0 || result.interrupted;
34695
+ if (!preserveState) {
34696
34696
  await ctx.stateBackend.deleteState(stackName, regionForState);
34697
34697
  logger.debug("State deleted");
34698
34698
  if (ctx.exportIndexStore) await ctx.exportIndexStore.removeStack(stackName, regionForState);
@@ -34702,12 +34702,15 @@ async function runDestroyForStack(stackName, state, ctx) {
34702
34702
  } catch (error) {
34703
34703
  logger.warn(`Failed to persist remaining state after partial destroy: ${error instanceof Error ? error.message : String(error)}. The state file may still list already-deleted resources; a re-run resolves them idempotently.`);
34704
34704
  }
34705
- logger.warn(`${result.errorCount} resource(s) failed to delete. State preserved.`);
34705
+ if (result.interrupted) logger.warn(`Destroy interrupted — ${Object.keys(remainingResources).length} resource(s) not deleted. State preserved.`);
34706
+ else logger.warn(`${result.errorCount} resource(s) failed to delete. State preserved.`);
34706
34707
  }
34707
34708
  const retainedSuffix = result.retainedCount > 0 ? `, ${result.retainedCount} retained` : "";
34708
- if (result.errorCount === 0) logger.info(`\n${green("✓")} ${bold(`Stack ${stackName} destroyed`)} (${green(result.deletedCount)} deleted${retainedSuffix}, ${result.errorCount} errors)`);
34709
+ if (!preserveState) logger.info(`\n${green("✓")} ${bold(`Stack ${stackName} destroyed`)} (${green(result.deletedCount)} deleted${retainedSuffix}, ${result.errorCount} errors)`);
34710
+ else if (result.interrupted && result.errorCount === 0) logger.warn(`\n${yellow("⚠")} ${bold(`Stack ${stackName} destroy interrupted`)} (${green(result.deletedCount)} deleted${retainedSuffix}, ${result.errorCount} errors). State preserved — re-run 'cdkd destroy' / 'cdkd state destroy' to finish.`);
34709
34711
  else logger.warn(`\n${yellow("⚠")} ${bold(`Stack ${stackName} partially destroyed`)} (${green(result.deletedCount)} deleted${retainedSuffix}, ${red(result.errorCount)} errors). State preserved — re-run 'cdkd destroy' / 'cdkd state destroy' to clean up.`);
34710
34712
  } finally {
34713
+ process.removeListener("SIGINT", sigintHandler);
34711
34714
  renderer.stop();
34712
34715
  await saveChain;
34713
34716
  logger.debug("Releasing lock...");
@@ -38322,6 +38325,7 @@ async function destroyCommand(stackArgs, options) {
38322
38325
  } else throw new Error("Could not determine which stacks belong to this app. Specify stack names explicitly, use --all, or ensure --app / cdk.json is configured.");
38323
38326
  const stackPatterns = stackArgs.length > 0 ? stackArgs : options.stack ? [options.stack] : [];
38324
38327
  let totalErrors = 0;
38328
+ let interrupted = false;
38325
38329
  let stackNames;
38326
38330
  if (options.all) stackNames = candidateStacks.map((s) => s.stackName);
38327
38331
  else if (stackPatterns.length > 0) stackNames = matchStacks(candidateStacks, stackPatterns).map((s) => s.stackName);
@@ -38443,6 +38447,7 @@ async function destroyCommand(stackArgs, options) {
38443
38447
  eventRecorder
38444
38448
  }));
38445
38449
  totalErrors += result.errorCount;
38450
+ if (result.interrupted) interrupted = true;
38446
38451
  destroyRunResult = result.errorCount > 0 ? "FAILED" : "SUCCEEDED";
38447
38452
  eventRecorder.record({
38448
38453
  eventType: "RUN_FINISHED",
@@ -38462,8 +38467,10 @@ async function destroyCommand(stackArgs, options) {
38462
38467
  } finally {
38463
38468
  await eventRecorder.finalize(destroyRunResult);
38464
38469
  }
38470
+ if (interrupted) break;
38465
38471
  }
38466
38472
  if (totalErrors > 0) throw new PartialFailureError(`Destroy completed with ${totalErrors} resource error(s). State preserved — inspect 'cdkd state show <stack>' and re-run 'cdkd destroy' to retry.`);
38473
+ if (interrupted) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd destroy' to finish.`);
38467
38474
  } finally {
38468
38475
  awsClients.destroy();
38469
38476
  }
@@ -42900,6 +42907,7 @@ async function stateDestroyCommand(stackArgs, options) {
42900
42907
  }
42901
42908
  logger.info(`Found ${stackNames.length} stack(s) to destroy: ${stackNames.join(", ")}`);
42902
42909
  let totalErrors = 0;
42910
+ let interrupted = false;
42903
42911
  for (const stackName of stackNames) {
42904
42912
  const refs = stateRefs.filter((r) => r.stackName === stackName);
42905
42913
  let targets;
@@ -42957,9 +42965,13 @@ async function stateDestroyCommand(stackArgs, options) {
42957
42965
  ...options.resourceTimeout?.perTypeMs && { resourceTimeoutByType: options.resourceTimeout.perTypeMs }
42958
42966
  }));
42959
42967
  totalErrors += result.errorCount;
42968
+ if (result.interrupted) interrupted = true;
42969
+ if (interrupted) break;
42960
42970
  }
42971
+ if (interrupted) break;
42961
42972
  }
42962
42973
  if (totalErrors > 0) throw new PartialFailureError(`Destroy completed with ${totalErrors} resource error(s). State preserved — inspect 'cdkd state show <stack>' and re-run 'cdkd state destroy' to retry.`);
42974
+ if (interrupted) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd state destroy' to finish.`);
42963
42975
  } finally {
42964
42976
  setup.dispose();
42965
42977
  }
@@ -53790,7 +53802,7 @@ function reorderArgs(argv) {
53790
53802
  async function main() {
53791
53803
  installPipeCloseHandler();
53792
53804
  const program = new Command();
53793
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.220.5");
53805
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.221.1");
53794
53806
  program.addCommand(createBootstrapCommand());
53795
53807
  program.addCommand(createSynthCommand());
53796
53808
  program.addCommand(createListCommand());