@go-to-k/cdkd 0.282.4 → 0.282.6

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
- import { $ as configStringRefusal, $t as resolveUseCdkBootstrapAssets, A as green, An as ProvisioningError, At as BOOTSTRAP_MARKER_PREFIX, B as slowCcOperationTimeoutMs, Bn as withErrorHandling, Bt as runDockerStreaming, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as LocalInvokeBuildError$1, Ct as stringifyValue, D as bold, Dn as MissingCdkCliError, Dt as loadPublishableAssetManifest, E as formatResourceLine, Et as createAssetRedirectResolver, F as clearOnUpdateRemoval, Ft as validateContainerRepoName, G as getAccountInfo, Gt as getDefaultStateBucketName, H as isTerminationProtectionPropagationError, Ht as getDockerImageBySourceHash, I as ProviderRegistry, It as buildDockerImage, J as normalizeAwsTagsToCfn, Jt as resolveAutoAssetStorage, K as refStateLookupFromResource, Kt as getLegacyStateBucketName, L as findActionableSilentDrops, Lt as formatDockerLoginError, M as yellow, Mn as ResourceUpdateNotSupportedError, Mt as getBootstrapMarkerKey, N as IAMRoleProvider, Nn as StackHasActiveImportsError, Nt as parseBootstrapMarker, O as cyan, On as NestedStackChildDirectDestroyError, Ot as rewriteTemplateAssetReferences, P as collectInlinePolicyNamesManagedBySiblings, Pn as StackTerminationProtectionError, Pt as validateAssetBucketName, Q as configBooleanRefusal, Qt as resolveStateBucketWithDefaultAndSource, R as findSilentDropProperties, Rt as getDockerCmd, S as extractDeploymentEventError, Sn as DeployCancelledError, St as AssetPublisher, T as renderStatefulReason, Tn as LocalStartServiceError, Tt as buildAssetRedirectMap, U as IntrinsicFunctionResolver, Ut as Synthesizer, V as disableInstanceApiTermination, Vt as AssetManifestLoader, W as cfnRefValueFromPhysicalId, Wt as synthesisStatusMessage, X as assertRegionMatch, Xt as resolveSkipPrefix, Y as resolveExplicitPhysicalId, Yt as resolveCaptureObservedState, Z as coerceCfnBoolean, Zt as resolveStateBucketWithDefault, _ as createPreDeleteFinalSnapshot, _n as setAwsClients, _t as TemplateParser, a as DeploymentEventsStore, an as findLargeInlineResources, at as s3BucketArn, b as unsupportedFinalSnapshotError, bt as rebuildClientForBucketRegion, c as replayFailedOperations, cn as PARTITION_TABLE, ct as s3BucketRegionalDomainName, d as IMPLICIT_DELETE_DEPENDENCIES, dn as processStackMessages, dt as DiffCalculator, en as stateBucketExistenceConfirmed, et as readConfigString, f as computeImplicitDeleteEdges, ft as describeTypeWithThrottleRetry, g as ccRoutedFinalSnapshotError, gn as resetAwsClients, gt as DagBuilder, h as buildFinalSnapshotIdentifier, hn as getAwsClients, ht as isThrottlingError, i as DeploymentEventsReader, in as MIGRATE_TMP_PREFIX, it as requireConfigString, j as red, jn as ResourceTimeoutError, jt as ensureAssetStorage, k as gray, kn as PartialFailureError, kt as AssetModeResolver, l as replayRollback, ln as derivePartitionAndUrlSuffix, lt as s3BucketWebsiteUrl, m as PRE_DELETE_SNAPSHOT_TYPES, mn as AwsClients, mt as isRetryableTransientError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as CFN_TEMPLATE_BODY_LIMIT, nt as requireConfigArray, o as planFailedOps, on as uploadCfnTemplate, ot as s3BucketDomainName, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as resolveBucketRegion, pt as withRetry, q as WAFv2WebACLProvider, qt as resolveApp, r as DeployEngine, rn as CFN_TEMPLATE_URL_LIMIT, rt as requireConfigObject, s as planRollback, sn as expectedOwnerParam, st as s3BucketDualStackDomainName, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as warnDeprecatedNoPrefixCliFlag, tt as replayWarn, u as withResourceDeadline, un as AssemblyReader, ut as applyRoleArnIfSet, v as isFinalSnapshotError, vt as LockManager, w as isStatefulRecreateTargetSync, wn as LocalMigrateError, wt as WorkGraph, x as makeCanonicalizePropertiesFn, xt as shouldRetainResource, y as refusesFinalSnapshot, yn as CdkdError, yt as S3StateBackend, z as CloudControlProvider, zn as normalizeAwsError, zt as runDockerForeground } from "./deploy-engine-CnxJLy3Y.js";
2
+ import { $ as configStringRefusal, $t as resolveStateBucketWithDefaultAndSource, A as green, An as NestedStackChildDirectDestroyError, At as BOOTSTRAP_MARKER_PREFIX, B as slowCcOperationTimeoutMs, Bt as runDockerForeground, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Ct as stringifyValue, D as bold, Dn as LocalStartServiceError, Dt as loadPublishableAssetManifest, E as formatResourceLine, En as LocalMigrateError, Et as createAssetRedirectResolver, F as clearOnUpdateRemoval, Fn as StackHasActiveImportsError, Ft as validateContainerRepoName, G as getAccountInfo, Gt as synthesisStatusMessage, H as isTerminationProtectionPropagationError, Hn as withErrorHandling, Ht as AssetManifestLoader, I as ProviderRegistry, In as StackTerminationProtectionError, It as buildDenyExternalAccessPolicy, J as normalizeAwsTagsToCfn, Jt as resolveApp, K as refStateLookupFromResource, Kt as getDefaultStateBucketName, L as findActionableSilentDrops, Lt as buildDockerImage, M as yellow, Mn as ProvisioningError, Mt as getBootstrapMarkerKey, N as IAMRoleProvider, Nn as ResourceTimeoutError, Nt as parseBootstrapMarker, O as cyan, Ot as rewriteTemplateAssetReferences, P as collectInlinePolicyNamesManagedBySiblings, Pn as ResourceUpdateNotSupportedError, Pt as validateAssetBucketName, Q as configBooleanRefusal, Qt as resolveStateBucketWithDefault, R as findSilentDropProperties, Rt as formatDockerLoginError, S as extractDeploymentEventError, St as AssetPublisher, T as renderStatefulReason, Tn as LocalInvokeBuildError$1, Tt as buildAssetRedirectMap, U as IntrinsicFunctionResolver, Ut as getDockerImageBySourceHash, V as disableInstanceApiTermination, Vn as normalizeAwsError, Vt as runDockerStreaming, W as cfnRefValueFromPhysicalId, Wt as Synthesizer, X as assertRegionMatch, Xt as resolveCaptureObservedState, Y as resolveExplicitPhysicalId, Yt as resolveAutoAssetStorage, Z as coerceCfnBoolean, Zt as resolveSkipPrefix, _ as createPreDeleteFinalSnapshot, _n as getAwsClients, _t as TemplateParser, a as DeploymentEventsStore, an as MIGRATE_TMP_PREFIX, at as s3BucketArn, b as unsupportedFinalSnapshotError, bt as rebuildClientForBucketRegion, c as replayFailedOperations, cn as expectedOwnerParam, ct as s3BucketRegionalDomainName, d as IMPLICIT_DELETE_DEPENDENCIES, dn as derivePartitionAndUrlSuffix, dt as DiffCalculator, en as resolveUseCdkBootstrapAssets, et as readConfigString, f as computeImplicitDeleteEdges, fn as AssemblyReader, ft as describeTypeWithThrottleRetry, g as ccRoutedFinalSnapshotError, gn as AwsClients, gt as DagBuilder, h as buildFinalSnapshotIdentifier, hn as resolveBucketRegion, ht as isThrottlingError, i as DeploymentEventsReader, in as CFN_TEMPLATE_URL_LIMIT, it as requireConfigString, j as red, jn as PartialFailureError, jt as ensureAssetStorage, k as gray, kn as MissingCdkCliError, kt as AssetModeResolver, l as replayRollback, ln as PARTITION_TABLE, lt as s3BucketWebsiteUrl, m as PRE_DELETE_SNAPSHOT_TYPES, mt as isRetryableTransientError, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as warnDeprecatedNoPrefixCliFlag, nt as requireConfigArray, o as planFailedOps, on as findLargeInlineResources, ot as s3BucketDomainName, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as processStackMessages, pt as withRetry, q as WAFv2WebACLProvider, qt as getLegacyStateBucketName, r as DeployEngine, rn as CFN_TEMPLATE_BODY_LIMIT, rt as requireConfigObject, s as planRollback, sn as uploadCfnTemplate, st as s3BucketDualStackDomainName, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as stateBucketExistenceConfirmed, tt as replayWarn, u as withResourceDeadline, un as canonicalizeRegion, ut as applyRoleArnIfSet, v as isFinalSnapshotError, vn as resetAwsClients, vt as LockManager, w as isStatefulRecreateTargetSync, wn as DeployCancelledError, wt as WorkGraph, x as makeCanonicalizePropertiesFn, xn as CdkdError, xt as shouldRetainResource, y as refusesFinalSnapshot, yn as setAwsClients, yt as S3StateBackend, z as CloudControlProvider, zt as getDockerCmd } from "./deploy-engine-4K_iJ2rV.js";
3
3
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
4
- import { t as ASGProvider } from "./asg-provider-D9VJTwn3.js";
4
+ import { t as ASGProvider } from "./asg-provider-Dm_dVhvQ.js";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { createHash, randomBytes, randomUUID } from "node:crypto";
7
7
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -1164,17 +1164,7 @@ async function bootstrapCommand(options) {
1164
1164
  }));
1165
1165
  logger.info("✓ Enabled bucket encryption (AES-256)");
1166
1166
  logger.debug("Setting bucket policy...");
1167
- const bucketPolicy = {
1168
- Version: "2012-10-17",
1169
- Statement: [{
1170
- Sid: "DenyExternalAccess",
1171
- Effect: "Deny",
1172
- Principal: "*",
1173
- Action: "s3:*",
1174
- Resource: [`arn:aws:s3:::${bucketName}`, `arn:aws:s3:::${bucketName}/*`],
1175
- Condition: { StringNotEquals: { "aws:PrincipalAccount": accountId } }
1176
- }]
1177
- };
1167
+ const bucketPolicy = buildDenyExternalAccessPolicy(bucketName, accountId, await stateBucketS3.config.region());
1178
1168
  await stateBucketS3.send(new PutBucketPolicyCommand({
1179
1169
  Bucket: bucketName,
1180
1170
  ExpectedBucketOwner: accountId,
@@ -58779,17 +58769,7 @@ async function ensureDestinationBucket(bucketName, region, accountId, logger) {
58779
58769
  await s3.send(new PutBucketPolicyCommand({
58780
58770
  Bucket: bucketName,
58781
58771
  ...await expectedOwnerParam(s3),
58782
- Policy: JSON.stringify({
58783
- Version: "2012-10-17",
58784
- Statement: [{
58785
- Sid: "DenyExternalAccess",
58786
- Effect: "Deny",
58787
- Principal: "*",
58788
- Action: "s3:*",
58789
- Resource: [`arn:aws:s3:::${bucketName}`, `arn:aws:s3:::${bucketName}/*`],
58790
- Condition: { StringNotEquals: { "aws:PrincipalAccount": accountId } }
58791
- }]
58792
- })
58772
+ Policy: JSON.stringify(buildDenyExternalAccessPolicy(bucketName, accountId, await s3.config.region()))
58793
58773
  }));
58794
58774
  logger.info("✓ Applied versioning, encryption, and account-only access policy");
58795
58775
  return s3;
@@ -68399,20 +68379,64 @@ function ecrUrlSuffix(region) {
68399
68379
  return derivePartitionAndUrlSuffix(region).urlSuffix;
68400
68380
  }
68401
68381
  /**
68382
+ * Lower-case the REGISTRY HOST of an image reference and leave the repository
68383
+ * path and tag byte-identical.
68384
+ *
68385
+ * A registry host is a DNS name and therefore case-INSENSITIVE, but docker's
68386
+ * credential store is keyed on the hostname VERBATIM: measured against a real
68387
+ * daemon with a `DOCKER_CONFIG` holding auth for
68388
+ * `<acct>.dkr.ecr.us-east-1.amazonaws.com`, a pull of
68389
+ * `<acct>.dkr.ecr.US-EAST-1.amazonaws.com/...` sent NO credentials at all
68390
+ * (`no basic auth credentials`) while the lower-cased spelling authenticated
68391
+ * and failed with a token error instead. So cdkd logging in to one spelling
68392
+ * and pulling from another authenticates against neither.
68393
+ *
68394
+ * The repository path and tag are deliberately NOT folded: only the domain is
68395
+ * case-insensitive, docker already requires the path to be lower case, and
68396
+ * rewriting it would change WHICH image is pulled.
68397
+ *
68398
+ * "Everything before the first `/`" is NOT the same thing as "the host", which
68399
+ * is why the first component is tested rather than assumed. Docker treats it
68400
+ * as a registry only when it contains a `.` or a `:` or is exactly
68401
+ * `localhost`; otherwise it is the first segment of a Docker Hub repository
68402
+ * PATH (`MyOrg/MyRepo:tag` is `docker.io/MyOrg/MyRepo:tag`). Folding that
68403
+ * would name a DIFFERENT image. Today every caller is behind the strict ECR
68404
+ * host check so the distinction is inert, but this is exported under a generic
68405
+ * name and the contract has to be the real one.
68406
+ */
68407
+ function canonicalizeImageUriHost(imageUri) {
68408
+ const slash = imageUri.indexOf("/");
68409
+ if (slash < 0) return imageUri;
68410
+ const host = imageUri.slice(0, slash);
68411
+ if (!isRegistryHostComponent(host)) return imageUri;
68412
+ return host.toLowerCase() + imageUri.slice(slash);
68413
+ }
68414
+ /** Docker's rule for "component 1 is a registry, not a repository segment". */
68415
+ function isRegistryHostComponent(component) {
68416
+ return component.includes(".") || component.includes(":") || component === "localhost";
68417
+ }
68418
+ /**
68402
68419
  * Parse an ECR image URI. Returns `undefined` for non-ECR URIs (typically:
68403
68420
  * Docker Hub, public.ecr.aws, gcr.io, ...) — those are user-managed
68404
68421
  * images we don't try to authenticate against.
68422
+ *
68423
+ * The host is canonicalized BEFORE the registry-host match, so a mixed-case
68424
+ * genuine ECR host classifies as ECR (and its `region` comes back in the
68425
+ * spelling the ECR endpoint and the `docker login` both use) rather than
68426
+ * falling through to the anonymous-pull path.
68405
68427
  */
68406
68428
  function parseEcrUri(imageUri) {
68407
- const host = parseEcrRegistryHost(imageUri);
68429
+ const canonicalUri = canonicalizeImageUriHost(imageUri);
68430
+ const host = parseEcrRegistryHost(canonicalUri);
68408
68431
  if (!host) return void 0;
68409
- const m = /^([^:]+):(.+)$/.exec(imageUri.slice(imageUri.indexOf("/") + 1));
68432
+ const m = /^([^:]+):(.+)$/.exec(canonicalUri.slice(canonicalUri.indexOf("/") + 1));
68410
68433
  if (!m) return void 0;
68411
68434
  return {
68412
68435
  accountId: host.accountId,
68413
- region: host.region,
68436
+ region: canonicalizeRegion(host.region),
68414
68437
  repository: m[1],
68415
- tag: m[2]
68438
+ tag: m[2],
68439
+ canonicalUri
68416
68440
  };
68417
68441
  }
68418
68442
  /**
@@ -68452,17 +68476,24 @@ function isCredentialFresh(creds) {
68452
68476
  *
68453
68477
  * Auto-detects cross-account from `STS:GetCallerIdentity` and assumes
68454
68478
  * the supplied role when set. Returns the image URI the caller should
68455
- * pass to `docker run` (same as the input no rewriting).
68479
+ * pass to `docker run`: the input with its registry HOST lower-cased and
68480
+ * its repository path + tag untouched (issue #1801). That is the SAME
68481
+ * spelling `docker pull` / `docker image inspect` were handed here, and
68482
+ * the same one the DERIVED `docker login` endpoint names — an
68483
+ * AWS-reported `proxyEndpoint` still wins over that fallback (it can be
68484
+ * a VPC-endpoint host), which is correct: AWS names the endpoint its own
68485
+ * token authenticates, and it reports it lower-cased.
68456
68486
  */
68457
68487
  async function pullEcrImage(imageUri, options) {
68458
68488
  const logger = getLogger().child("ecr-puller");
68459
68489
  const parsed = parseEcrUri(imageUri);
68460
68490
  if (!parsed) throw new LocalInvokeBuildError$1(`Image URI '${imageUri}' is not an ECR URI. cdkd local invoke v1 only authenticates against ECR for the deployed-image fallback path.`);
68461
- const callerRegion = options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"];
68491
+ const canonicalUri = parsed.canonicalUri;
68492
+ const callerRegion = canonicalizeRegion(options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"]);
68462
68493
  if (options.skipPull) {
68463
- logger.info(`Skipping ECR pull (--no-pull). Verifying ${imageUri} is in local cache...`);
68464
- await verifyImageInLocalCache(imageUri);
68465
- return imageUri;
68494
+ logger.info(`Skipping ECR pull (--no-pull). Verifying ${canonicalUri} is in local cache...`);
68495
+ await verifyImageInLocalCache(canonicalUri);
68496
+ return canonicalUri;
68466
68497
  }
68467
68498
  const callerIdentityKey = callerRegion ?? "_unset";
68468
68499
  let callerAccount = CALLER_IDENTITY_CACHE.get(callerIdentityKey);
@@ -68502,13 +68533,13 @@ async function pullEcrImage(imageUri, options) {
68502
68533
  } finally {
68503
68534
  ecr.destroy();
68504
68535
  }
68505
- logger.info(`Pulling ${imageUri}...`);
68536
+ logger.info(`Pulling ${canonicalUri}...`);
68506
68537
  try {
68507
- await runDockerForeground(["pull", imageUri]);
68538
+ await runDockerForeground(["pull", canonicalUri]);
68508
68539
  } catch (err) {
68509
- throw new LocalInvokeBuildError$1(`docker pull ${imageUri} failed: ${err.message}`);
68540
+ throw new LocalInvokeBuildError$1(`docker pull ${canonicalUri} failed: ${err.message}`);
68510
68541
  }
68511
- return imageUri;
68542
+ return canonicalUri;
68512
68543
  }
68513
68544
  /**
68514
68545
  * Assume the supplied role via the SDK default credential chain and
@@ -69722,6 +69753,7 @@ function clampConcurrency(input) {
69722
69753
  async function localStartApiCommand(target, options) {
69723
69754
  const logger = getLogger();
69724
69755
  if (options.verbose) logger.setLevel("debug");
69756
+ if (options.region !== void 0) options.region = canonicalizeRegion(options.region);
69725
69757
  let apiFilter = target;
69726
69758
  if (options.api !== void 0) {
69727
69759
  if (target !== void 0) throw new Error(`Cannot specify both positional target ('${target}') and --api flag ('${options.api}'). Use one or the other. The positional form is preferred — '--api' is a deprecated alias.`);
@@ -71128,10 +71160,18 @@ async function loadStateForRoutedStacks(stacks, routes, routesWithAuth, options)
71128
71160
  *
71129
71161
  * Region precedence: `--region` > `AWS_REGION` > `AWS_DEFAULT_REGION` >
71130
71162
  * the state record's region (returned by the active `LocalStateProvider`).
71163
+ *
71164
+ * The resolved region is CANONICALIZED (issue #1795) before anything consumes
71165
+ * it. That covers all four sources — `--region`, both env vars, and the state
71166
+ * record's region — and all three consumers: the STS client built for
71167
+ * `${AWS::AccountId}`, the `${AWS::URLSuffix}` / `${AWS::Partition}`
71168
+ * derivation, and the `${AWS::Region}` value itself.
71169
+ *
71170
+ * @internal exported for unit tests.
71131
71171
  */
71132
71172
  async function resolvePseudoParametersForStartApi(stateRegion, options) {
71133
71173
  const logger = getLogger();
71134
- const region = options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"] ?? stateRegion;
71174
+ const region = canonicalizeRegion(options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"] ?? stateRegion);
71135
71175
  let accountId;
71136
71176
  try {
71137
71177
  const { STSClient, GetCallerIdentityCommand } = await import("@aws-sdk/client-sts");
@@ -72055,6 +72095,7 @@ async function localRunTaskCommand(target, options) {
72055
72095
  const logger = getLogger();
72056
72096
  if (options.verbose) logger.setLevel("debug");
72057
72097
  warnIfDeprecatedRegion(options);
72098
+ if (options.region !== void 0) options.region = canonicalizeRegion(options.region);
72058
72099
  const state = createEcsRunState();
72059
72100
  let sigintHandler;
72060
72101
  let sigintCount = 0;
@@ -72224,6 +72265,14 @@ async function assumeTaskRole(roleArn, region) {
72224
72265
  * load) routes through the active {@link LocalStateProvider} so both
72225
72266
  * `--from-state` and `--from-cfn-stack` produce the same downstream
72226
72267
  * context shape (issue #606).
72268
+ *
72269
+ * The resolved region is CANONICALIZED (issue #1795) before anything consumes
72270
+ * it. That covers all four sources — `--region`, both env vars, and the
72271
+ * synth-derived stack region — and all three consumers: the STS client built
72272
+ * for `${AWS::AccountId}`, the `${AWS::URLSuffix}` / `${AWS::Partition}`
72273
+ * derivation, and the `${AWS::Region}` value itself.
72274
+ *
72275
+ * @internal exported for unit tests.
72227
72276
  */
72228
72277
  async function buildEcsImageResolutionContext$1(candidate, stateProvider, options) {
72229
72278
  const logger = getLogger();
@@ -72233,7 +72282,7 @@ async function buildEcsImageResolutionContext$1(candidate, stateProvider, option
72233
72282
  const ctx = {};
72234
72283
  const wantsPseudoForEnvOrSecret = !!stateProvider && needs.needsEnvOrSecretSubstitution;
72235
72284
  if (needs.needsPseudoParameters || wantsPseudoForEnvOrSecret) {
72236
- const region = options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"] ?? candidate.region;
72285
+ const region = canonicalizeRegion(options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"] ?? candidate.region);
72237
72286
  if (!region) logger.warn("Resolver references ${AWS::Region} but cdkd could not determine the target region. Pass --region, set AWS_REGION, or declare env.region on the CDK stack.");
72238
72287
  let accountId;
72239
72288
  try {
@@ -73901,6 +73950,7 @@ async function localInvokeCommand(target, options) {
73901
73950
  const logger = getLogger();
73902
73951
  if (options.verbose) logger.setLevel("debug");
73903
73952
  warnIfDeprecatedRegion(options);
73953
+ if (options.region !== void 0) options.region = canonicalizeRegion(options.region);
73904
73954
  let imagePlan;
73905
73955
  let containerId;
73906
73956
  let stopLogs;
@@ -74381,10 +74431,18 @@ function envHasCrossStackIntrinsic(templateEnv) {
74381
74431
  *
74382
74432
  * Region precedence (mirrors `local-run-task`): `--region` > `AWS_REGION`
74383
74433
  * > `AWS_DEFAULT_REGION` > the synth-derived stack region.
74434
+ *
74435
+ * The resolved region is CANONICALIZED (issue #1795) before anything consumes
74436
+ * it. That covers all four sources — `--region`, both env vars, and the
74437
+ * synth-derived stack region — and all three consumers: the STS client built
74438
+ * for `${AWS::AccountId}`, the `${AWS::URLSuffix}` / `${AWS::Partition}`
74439
+ * derivation, and the `${AWS::Region}` value itself.
74440
+ *
74441
+ * @internal exported for unit tests.
74384
74442
  */
74385
74443
  async function resolvePseudoParametersForInvoke(stackRegion, options) {
74386
74444
  const logger = getLogger();
74387
- const region = options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"] ?? stackRegion;
74445
+ const region = canonicalizeRegion(options.region ?? process.env["AWS_REGION"] ?? process.env["AWS_DEFAULT_REGION"] ?? stackRegion);
74388
74446
  if (!region) logger.warn("--from-state: resolver references ${AWS::Region} but cdkd could not determine the target region. Pass --region, set AWS_REGION, or declare env.region on the CDK stack.");
74389
74447
  let accountId;
74390
74448
  try {
@@ -75763,7 +75821,7 @@ function createMigrateCommand() {
75763
75821
  */
75764
75822
  function buildProgram() {
75765
75823
  const program = new Command();
75766
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.282.4");
75824
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.282.6");
75767
75825
  program.hook("preAction", (_thisCommand, actionCommand) => {
75768
75826
  const { profile } = actionCommand.optsWithGlobals();
75769
75827
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;