@go-to-k/cdkd 0.220.0 → 0.220.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-CFaK71E9.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-CcOt3mUO.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";
@@ -1543,7 +1543,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1543
1543
  const FLUSH_EVENT_THRESHOLD = 50;
1544
1544
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1545
1545
  function getCdkdVersion() {
1546
- return "0.220.0";
1546
+ return "0.220.1";
1547
1547
  }
1548
1548
  /**
1549
1549
  * Generate a time-sortable unique run id, e.g.
@@ -53540,7 +53540,7 @@ function reorderArgs(argv) {
53540
53540
  async function main() {
53541
53541
  installPipeCloseHandler();
53542
53542
  const program = new Command();
53543
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.220.0");
53543
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.220.1");
53544
53544
  program.addCommand(createBootstrapCommand());
53545
53545
  program.addCommand(createSynthCommand());
53546
53546
  program.addCommand(createListCommand());
@@ -3540,12 +3540,22 @@ function isNoSuchKey(error) {
3540
3540
  *
3541
3541
  * Locks have a TTL (time-to-live). Expired locks are automatically cleaned up
3542
3542
  * during acquisition attempts.
3543
+ *
3544
+ * Like `S3StateBackend`, the lock manager tolerates a state bucket that
3545
+ * lives in a different AWS region from the CLI's base region: before the
3546
+ * first S3 operation it resolves the bucket's actual region via
3547
+ * `GetBucketLocation` and, if it differs from the supplied client's region,
3548
+ * builds a private replacement client for that region (issue #803 — without
3549
+ * this, every lock acquisition against a cross-region bucket failed with
3550
+ * S3's 301 PermanentRedirect while state reads/writes succeeded).
3543
3551
  */
3544
3552
  var LockManager = class {
3545
3553
  logger = getLogger().child("LockManager");
3546
3554
  s3Client;
3547
3555
  config;
3548
3556
  ttlMs;
3557
+ clientResolved = false;
3558
+ resolveInFlight = null;
3549
3559
  constructor(s3Client, config, options) {
3550
3560
  this.s3Client = s3Client;
3551
3561
  this.config = config;
@@ -3553,6 +3563,62 @@ var LockManager = class {
3553
3563
  this.ttlMs = ttlMinutes * 60 * 1e3;
3554
3564
  }
3555
3565
  /**
3566
+ * Resolve the state bucket's actual region and, if it differs from the
3567
+ * supplied client's configured region, replace the client reference with
3568
+ * a new S3Client pointed at the bucket's region.
3569
+ *
3570
+ * Mirrors `S3StateBackend.ensureClientForBucket()` (PR #60) with two
3571
+ * deliberate differences:
3572
+ *
3573
+ * - The replacement client reuses the original client's resolved
3574
+ * credentials provider, so `--profile` / static credentials carry over
3575
+ * without the 8 LockManager call sites having to thread client options.
3576
+ * - The original client is NOT destroyed. It is the shared `AwsClients.s3`
3577
+ * instance that other components (state backend, exports index) still
3578
+ * hold a reference to.
3579
+ *
3580
+ * `resolveBucketRegion` caches per bucket name for the process lifetime,
3581
+ * so when the state backend has already resolved the same bucket this
3582
+ * incurs no additional `GetBucketLocation` call.
3583
+ */
3584
+ async ensureClientForBucket() {
3585
+ if (this.clientResolved) return;
3586
+ if (this.resolveInFlight) return this.resolveInFlight;
3587
+ this.resolveInFlight = (async () => {
3588
+ try {
3589
+ const currentRegion = await this.s3Client.config.region();
3590
+ const fallbackRegion = typeof currentRegion === "string" ? currentRegion : void 0;
3591
+ let probeCredentials;
3592
+ try {
3593
+ probeCredentials = await this.s3Client.config.credentials();
3594
+ } catch {
3595
+ probeCredentials = void 0;
3596
+ }
3597
+ const bucketRegion = await resolveBucketRegion(this.config.bucket, {
3598
+ ...probeCredentials && { credentials: probeCredentials },
3599
+ ...fallbackRegion && { fallbackRegion }
3600
+ });
3601
+ if (bucketRegion !== currentRegion) {
3602
+ this.logger.debug(`State bucket '${this.config.bucket}' is in '${bucketRegion}' (lock client was '${currentRegion}'); building a region-corrected S3 client for lock operations.`);
3603
+ this.s3Client = new S3Client({
3604
+ region: bucketRegion,
3605
+ credentials: this.s3Client.config.credentials,
3606
+ logger: {
3607
+ debug: () => {},
3608
+ info: () => {},
3609
+ warn: () => {},
3610
+ error: () => {}
3611
+ }
3612
+ });
3613
+ }
3614
+ this.clientResolved = true;
3615
+ } finally {
3616
+ this.resolveInFlight = null;
3617
+ }
3618
+ })();
3619
+ return this.resolveInFlight;
3620
+ }
3621
+ /**
3556
3622
  * Get the S3 key for a stack's lock file.
3557
3623
  *
3558
3624
  * Locks are region-scoped, mirroring the state key layout
@@ -3607,6 +3673,7 @@ var LockManager = class {
3607
3673
  * @param operation Operation being performed (e.g., "deploy", "destroy")
3608
3674
  */
3609
3675
  async acquireLock(stackName, region, owner, operation) {
3676
+ await this.ensureClientForBucket();
3610
3677
  const key = this.getLockKey(stackName, region);
3611
3678
  const lockOwner = owner || this.getDefaultOwner();
3612
3679
  const now = Date.now();
@@ -3669,6 +3736,7 @@ var LockManager = class {
3669
3736
  * file (e.g. for state-listing tools that don't yet know the region).
3670
3737
  */
3671
3738
  async getLockInfo(stackName, region) {
3739
+ await this.ensureClientForBucket();
3672
3740
  const key = this.getLockKey(stackName, region);
3673
3741
  try {
3674
3742
  this.logger.debug(`Getting lock info for stack: ${stackName}`);
@@ -3705,6 +3773,7 @@ var LockManager = class {
3705
3773
  * Release a lock for a stack
3706
3774
  */
3707
3775
  async releaseLock(stackName, region) {
3776
+ await this.ensureClientForBucket();
3708
3777
  const key = this.getLockKey(stackName, region);
3709
3778
  try {
3710
3779
  this.logger.debug(`Releasing lock for stack: ${stackName} (${region})`);
@@ -3739,6 +3808,7 @@ var LockManager = class {
3739
3808
  * Internal method to delete the lock file from S3
3740
3809
  */
3741
3810
  async deleteLock(stackName, region) {
3811
+ await this.ensureClientForBucket();
3742
3812
  const key = this.getLockKey(stackName, region);
3743
3813
  await this.s3Client.send(new DeleteObjectCommand({
3744
3814
  Bucket: this.config.bucket,
@@ -12673,4 +12743,4 @@ var DeployEngine = class {
12673
12743
 
12674
12744
  //#endregion
12675
12745
  export { resolveBucketRegion as $, stringifyValue as A, resolveApp as B, DiffCalculator as C, S3StateBackend as D, LockManager as E, runDockerForeground as F, warnDeprecatedNoPrefixCliFlag as G, resolveSkipPrefix as H, runDockerStreaming as I, MIGRATE_TMP_PREFIX as J, CFN_TEMPLATE_BODY_LIMIT as K, Synthesizer as L, buildDockerImage as M, formatDockerLoginError as N, shouldRetainResource as O, getDockerCmd as P, clearBucketRegionCache as Q, getDefaultStateBucketName as R, applyRoleArnIfSet as S, TemplateParser as T, resolveStateBucketWithDefault as U, resolveCaptureObservedState as V, resolveStateBucketWithDefaultAndSource as W, uploadCfnTemplate as X, findLargeInlineResources as Y, AssemblyReader as Z, collectInlinePolicyNamesManagedBySiblings as _, withRetry as a, CloudControlProvider as b, extractDeploymentEventError as c, cyan as d, gray as f, IAMRoleProvider as g, yellow as h, withResourceDeadline as i, WorkGraph as j, AssetPublisher as k, formatResourceLine as l, red as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, isRetryableTransientError as o, green as p, CFN_TEMPLATE_URL_LIMIT as q, DeployEngine as r, IMPLICIT_DELETE_DEPENDENCIES as s, DEFAULT_RESOURCE_TIMEOUT_MS as t, bold as u, ProviderRegistry as v, DagBuilder as w, IntrinsicFunctionResolver as x, findActionableSilentDrops as y, getLegacyStateBucketName as z };
12676
- //# sourceMappingURL=deploy-engine-CFaK71E9.js.map
12746
+ //# sourceMappingURL=deploy-engine-CcOt3mUO.js.map