@go-to-k/cdkd 0.220.2 → 0.220.4

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-CcOt3mUO.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";
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.2";
1556
+ return "0.220.4";
1557
1557
  }
1558
1558
  /**
1559
1559
  * Generate a time-sortable unique run id, e.g.
@@ -1929,6 +1929,18 @@ function recordRunFailed(recorder, stackName, error) {
1929
1929
  * lock + bounded retry. After exhaustion, the writer logs warn and
1930
1930
  * continues; the index becomes stale until the next deploy/destroy
1931
1931
  * updates it.
1932
+ *
1933
+ * Cross-region state bucket: like `S3StateBackend` and `LockManager`, the
1934
+ * store tolerates a state bucket that lives in a different AWS region from
1935
+ * the CLI's base region. Before its first S3 operation it resolves the
1936
+ * bucket's actual region via `GetBucketLocation` and, if it differs from
1937
+ * the supplied client's region, builds a private replacement client for
1938
+ * that region (issue #819 — without this, every index write/remove against
1939
+ * a cross-region bucket failed with S3's 301 PermanentRedirect, surfacing
1940
+ * as `Exports index ... failed (non-retryable): ... must be addressed using
1941
+ * the specified endpoint`; the index was silently never maintained
1942
+ * cross-region, although the canonical state.json — written through the
1943
+ * already-region-corrected `S3StateBackend` — stayed correct).
1932
1944
  */
1933
1945
  /** Schema version for the exports index file. Separate from state.json's version. */
1934
1946
  const EXPORT_INDEX_VERSION = 1;
@@ -1977,6 +1989,9 @@ var ExportIndexStore = class {
1977
1989
  * where it actually matters. Reads (`lookup`) remain unsynchronized.
1978
1990
  */
1979
1991
  writeChain = Promise.resolve();
1992
+ /** Memoization for the one-time bucket-region resolution (issue #819). */
1993
+ clientResolved = false;
1994
+ resolveInFlight = null;
1980
1995
  constructor(s3Client, bucket, prefix, region, stateBackend, opts = {}) {
1981
1996
  this.s3Client = s3Client;
1982
1997
  this.bucket = bucket;
@@ -1993,6 +2008,72 @@ var ExportIndexStore = class {
1993
2008
  return `${this.prefix}/_index/${this.region}/exports.json`;
1994
2009
  }
1995
2010
  /**
2011
+ * Resolve the state bucket's actual region and, if it differs from the
2012
+ * supplied client's configured region, replace the client reference with
2013
+ * a new S3Client pointed at the bucket's region (issue #819).
2014
+ *
2015
+ * Mirrors `LockManager.ensureClientForBucket()` (issue #803) with the same
2016
+ * two deliberate differences from `S3StateBackend`:
2017
+ *
2018
+ * - The replacement client reuses the original client's resolved
2019
+ * credentials provider, so `--profile` / static credentials carry over
2020
+ * without the four `ExportIndexStore` call sites having to thread client
2021
+ * options.
2022
+ * - The original client is NOT destroyed. It is the shared `AwsClients.s3`
2023
+ * instance that other components (state backend, lock manager) still hold
2024
+ * a reference to.
2025
+ *
2026
+ * `resolveBucketRegion` caches per bucket name for the process lifetime, so
2027
+ * when the state backend / lock manager have already resolved the same
2028
+ * bucket this incurs no additional `GetBucketLocation` call.
2029
+ *
2030
+ * Best-effort: if the supplied client does not expose the SDK
2031
+ * `config.region()` shape (e.g. a hand-rolled test double) the resolution
2032
+ * is skipped and the original client is used unchanged.
2033
+ */
2034
+ async ensureClientForBucket() {
2035
+ if (this.clientResolved) return;
2036
+ if (this.resolveInFlight) return this.resolveInFlight;
2037
+ this.resolveInFlight = (async () => {
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 }
2055
+ });
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
+ }
2069
+ this.clientResolved = true;
2070
+ } finally {
2071
+ this.resolveInFlight = null;
2072
+ }
2073
+ })();
2074
+ return this.resolveInFlight;
2075
+ }
2076
+ /**
1996
2077
  * Look up an exported value by name. Returns the cached entry on hit,
1997
2078
  * or `undefined` on miss. The caller is responsible for falling back
1998
2079
  * to a state.json scan and (if found) patching the index via
@@ -2113,6 +2194,7 @@ var ExportIndexStore = class {
2113
2194
  }
2114
2195
  }
2115
2196
  async readIndexRaw() {
2197
+ await this.ensureClientForBucket();
2116
2198
  try {
2117
2199
  const response = await this.s3Client.send(new GetObjectCommand({
2118
2200
  Bucket: this.bucket,
@@ -2128,6 +2210,7 @@ var ExportIndexStore = class {
2128
2210
  }
2129
2211
  }
2130
2212
  async writeIndex(next, expectedEtag) {
2213
+ await this.ensureClientForBucket();
2131
2214
  const body = JSON.stringify(next, null, 2);
2132
2215
  return (await this.s3Client.send(new PutObjectCommand({
2133
2216
  Bucket: this.bucket,
@@ -53550,7 +53633,7 @@ function reorderArgs(argv) {
53550
53633
  async function main() {
53551
53634
  installPipeCloseHandler();
53552
53635
  const program = new Command();
53553
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.220.2");
53636
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.220.4");
53554
53637
  program.addCommand(createBootstrapCommand());
53555
53638
  program.addCommand(createSynthCommand());
53556
53639
  program.addCommand(createListCommand());