@go-to-k/cdkd 0.221.0 → 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.
@@ -3017,6 +3017,75 @@ function shouldRetainResource(deletionPolicy) {
3017
3017
  return deletionPolicy === "Retain" || deletionPolicy === "RetainExceptOnCreate";
3018
3018
  }
3019
3019
 
3020
+ //#endregion
3021
+ //#region src/utils/bucket-region-client.ts
3022
+ /**
3023
+ * Resolve a state bucket's actual region and, if it differs from the supplied
3024
+ * client's configured region, return a fresh `S3Client` pointed at the bucket's
3025
+ * region (reusing the caller's credentials). Returns `null` when no rebuild is
3026
+ * needed — the bucket is already in the client's region — so the caller keeps
3027
+ * using the original client.
3028
+ *
3029
+ * This is the shared core of the (previously triplicated) `ensureClientForBucket`
3030
+ * pattern in `S3StateBackend` (PR #60), `LockManager` (#803), and
3031
+ * `ExportIndexStore` (#819). Each store keeps its own per-instance memoization
3032
+ * (`clientResolved` flag / single-flight `resolveInFlight` promise) and just
3033
+ * delegates the probe + short-circuit + rebuild here.
3034
+ *
3035
+ * The probe goes through the cached `resolveBucketRegion`, so when several
3036
+ * stores resolve the same bucket only the FIRST issues a `GetBucketLocation`.
3037
+ * `resolveBucketRegion` never throws — on any error it returns the supplied
3038
+ * `fallbackRegion` (the client's current region), so a missing / forbidden
3039
+ * bucket degrades to "no rebuild" rather than blocking the caller.
3040
+ *
3041
+ * Credential / ownership / test-double behavior is controlled by
3042
+ * {@link RebuildClientForBucketRegionOptions} — see each field for the per-store
3043
+ * rationale.
3044
+ *
3045
+ * @returns A region-corrected `S3Client` to swap in, or `null` to signal
3046
+ * "no rebuild needed; keep the original client".
3047
+ */
3048
+ async function rebuildClientForBucketRegion(client, bucket, opts = {}) {
3049
+ const config = client.config;
3050
+ if (!config || typeof config.region !== "function") {
3051
+ if (opts.tolerateNonStandardClient) return null;
3052
+ }
3053
+ const currentRegion = await config.region();
3054
+ const fallbackRegion = typeof currentRegion === "string" ? currentRegion : void 0;
3055
+ let probeCredentials;
3056
+ if (opts.credentials) probeCredentials = opts.credentials;
3057
+ else if (opts.reuseClientCredentials && typeof config.credentials === "function") try {
3058
+ probeCredentials = await config.credentials();
3059
+ } catch {
3060
+ probeCredentials = void 0;
3061
+ }
3062
+ const bucketRegion = await resolveBucketRegion(bucket, {
3063
+ ...opts.profile && { profile: opts.profile },
3064
+ ...probeCredentials && { credentials: probeCredentials },
3065
+ ...fallbackRegion && { fallbackRegion }
3066
+ });
3067
+ if (bucketRegion === currentRegion) return null;
3068
+ opts.onRebuild?.({
3069
+ bucket,
3070
+ bucketRegion,
3071
+ currentRegion
3072
+ });
3073
+ const rebuiltCredentials = opts.credentials ? opts.credentials : opts.reuseClientCredentials ? client.config.credentials : void 0;
3074
+ const replacement = new S3Client({
3075
+ region: bucketRegion,
3076
+ ...opts.profile && { profile: opts.profile },
3077
+ ...rebuiltCredentials !== void 0 && { credentials: rebuiltCredentials },
3078
+ logger: {
3079
+ debug: () => {},
3080
+ info: () => {},
3081
+ warn: () => {},
3082
+ error: () => {}
3083
+ }
3084
+ });
3085
+ if (opts.destroyOldClient) client.destroy();
3086
+ return replacement;
3087
+ }
3088
+
3020
3089
  //#endregion
3021
3090
  //#region src/state/s3-state-backend.ts
3022
3091
  /**
@@ -3100,29 +3169,15 @@ var S3StateBackend = class {
3100
3169
  if (this.resolveInFlight) return this.resolveInFlight;
3101
3170
  this.resolveInFlight = (async () => {
3102
3171
  try {
3103
- const currentRegion = await this.s3Client.config.region();
3104
- const fallbackRegion = typeof currentRegion === "string" ? currentRegion : void 0;
3105
- const bucketRegion = await resolveBucketRegion(this.config.bucket, {
3172
+ const replacement = await rebuildClientForBucketRegion(this.s3Client, this.config.bucket, {
3106
3173
  ...this.clientOpts.profile && { profile: this.clientOpts.profile },
3107
3174
  ...this.clientOpts.credentials && { credentials: this.clientOpts.credentials },
3108
- ...fallbackRegion && { fallbackRegion }
3175
+ destroyOldClient: true,
3176
+ onRebuild: ({ bucketRegion, currentRegion }) => {
3177
+ this.logger.debug(`State bucket '${this.config.bucket}' is in '${bucketRegion}' (client was '${String(currentRegion)}'); rebuilding S3 client.`);
3178
+ }
3109
3179
  });
3110
- if (bucketRegion !== currentRegion) {
3111
- this.logger.debug(`State bucket '${this.config.bucket}' is in '${bucketRegion}' (client was '${currentRegion}'); rebuilding S3 client.`);
3112
- const oldClient = this.s3Client;
3113
- this.s3Client = new S3Client({
3114
- region: bucketRegion,
3115
- ...this.clientOpts.profile && { profile: this.clientOpts.profile },
3116
- ...this.clientOpts.credentials && { credentials: this.clientOpts.credentials },
3117
- logger: {
3118
- debug: () => {},
3119
- info: () => {},
3120
- warn: () => {},
3121
- error: () => {}
3122
- }
3123
- });
3124
- oldClient.destroy();
3125
- }
3180
+ if (replacement) this.s3Client = replacement;
3126
3181
  this.clientResolved = true;
3127
3182
  } finally {
3128
3183
  this.resolveInFlight = null;
@@ -3586,31 +3641,13 @@ var LockManager = class {
3586
3641
  if (this.resolveInFlight) return this.resolveInFlight;
3587
3642
  this.resolveInFlight = (async () => {
3588
3643
  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 }
3644
+ const replacement = await rebuildClientForBucketRegion(this.s3Client, this.config.bucket, {
3645
+ reuseClientCredentials: true,
3646
+ onRebuild: ({ bucketRegion, currentRegion }) => {
3647
+ this.logger.debug(`State bucket '${this.config.bucket}' is in '${bucketRegion}' (lock client was '${String(currentRegion)}'); building a region-corrected S3 client for lock operations.`);
3648
+ }
3600
3649
  });
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
- }
3650
+ if (replacement) this.s3Client = replacement;
3614
3651
  this.clientResolved = true;
3615
3652
  } finally {
3616
3653
  this.resolveInFlight = null;
@@ -11277,6 +11314,8 @@ const RETRYABLE_ERROR_MESSAGE_PATTERNS = [
11277
11314
  "does not exist",
11278
11315
  "Schema is currently being altered",
11279
11316
  "Invalid principal in policy",
11317
+ "Policy Error: PrincipalNotFound",
11318
+ "Invalid value for the parameter Policy",
11280
11319
  "required permissions for: ENHANCED_MONITORING",
11281
11320
  "Caught ServiceAccessDeniedException",
11282
11321
  "conflicting conditional operation",
@@ -12743,5 +12782,5 @@ var DeployEngine = class {
12743
12782
  };
12744
12783
 
12745
12784
  //#endregion
12746
- 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 };
12747
- //# sourceMappingURL=deploy-engine-xlz3wc4W.js.map
12785
+ export { clearBucketRegionCache as $, AssetPublisher as A, getLegacyStateBucketName as B, DiffCalculator as C, S3StateBackend as D, LockManager as E, getDockerCmd as F, resolveStateBucketWithDefaultAndSource as G, resolveCaptureObservedState as H, runDockerForeground as I, CFN_TEMPLATE_URL_LIMIT as J, warnDeprecatedNoPrefixCliFlag as K, runDockerStreaming as L, WorkGraph as M, buildDockerImage as N, rebuildClientForBucketRegion as O, formatDockerLoginError as P, AssemblyReader as Q, Synthesizer as R, applyRoleArnIfSet as S, TemplateParser as T, resolveSkipPrefix as U, resolveApp as V, resolveStateBucketWithDefault as W, findLargeInlineResources as X, MIGRATE_TMP_PREFIX as Y, uploadCfnTemplate as Z, collectInlinePolicyNamesManagedBySiblings as _, withRetry as a, CloudControlProvider as b, extractDeploymentEventError as c, cyan as d, resolveBucketRegion as et, gray as f, IAMRoleProvider as g, yellow as h, withResourceDeadline as i, stringifyValue as j, shouldRetainResource as k, formatResourceLine as l, red as m, DEFAULT_RESOURCE_WARN_AFTER_MS as n, isRetryableTransientError as o, green as p, CFN_TEMPLATE_BODY_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, getDefaultStateBucketName as z };
12786
+ //# sourceMappingURL=deploy-engine-OWyYqmlc.js.map