@go-to-k/cdkd 0.281.8 → 0.281.10

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 requireConfigArray, $t as expectedOwnerParam, A as green, An as withErrorHandling, At as getDockerCmd, B as slowCcOperationTimeoutMs, Bt as resolveAutoAssetStorage, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackHasActiveImportsError, Ct as ensureAssetStorage, D as bold, Dt as validateContainerRepoName, E as formatResourceLine, Et as validateAssetBucketName, F as clearOnUpdateRemoval, Ft as Synthesizer, G as refStateLookupFromResource, Gt as resolveUseCdkBootstrapAssets, H as isTerminationProtectionPropagationError, Ht as resolveSkipPrefix, I as ProviderRegistry, It as synthesisStatusMessage, J as resolveExplicitPhysicalId, Jt as CFN_TEMPLATE_BODY_LIMIT, K as WAFv2WebACLProvider, Kt as stateBucketExistenceConfirmed, L as findActionableSilentDrops, Lt as getDefaultStateBucketName, M as yellow, Mt as runDockerStreaming, N as IAMRoleProvider, Nt as AssetManifestLoader, O as cyan, Ot as buildDockerImage, P as collectInlinePolicyNamesManagedBySiblings, Pt as getDockerImageBySourceHash, Q as replayWarn, Qt as uploadCfnTemplate, R as findSilentDropProperties, Rt as getLegacyStateBucketName, S as extractDeploymentEventError, Sn as ResourceUpdateNotSupportedError, St as BOOTSTRAP_MARKER_PREFIX, T as renderStatefulReason, Tt as parseBootstrapMarker, U as IntrinsicFunctionResolver, Ut as resolveStateBucketWithDefault, V as disableInstanceApiTermination, Vt as resolveCaptureObservedState, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefaultAndSource, X as configStringRefusal, Xt as MIGRATE_TMP_PREFIX, Y as assertRegionMatch, Yt as CFN_TEMPLATE_URL_LIMIT, Z as readConfigString, Zt as findLargeInlineResources, _ as createPreDeleteFinalSnapshot, _n as MissingCdkCliError, _t as buildAssetRedirectMap, a as DeploymentEventsStore, an as getAwsClients, at as withRetry, b as unsupportedFinalSnapshotError, bn as ProvisioningError, bt as rewriteTemplateAssetReferences, c as replayFailedOperations, ct as DagBuilder, d as IMPLICIT_DELETE_DEPENDENCIES, dt as S3StateBackend, en as AssemblyReader, et as requireConfigObject, f as computeImplicitDeleteEdges, fn as DeployCancelledError, ft as rebuildClientForBucketRegion, g as ccRoutedFinalSnapshotError, gt as WorkGraph, h as buildFinalSnapshotIdentifier, hn as LocalStartServiceError, ht as stringifyValue, i as DeploymentEventsReader, in as AwsClients, it as describeTypeWithThrottleRetry, j as red, jt as runDockerForeground, k as gray, kn as normalizeAwsError, kt as formatDockerLoginError, l as replayRollback, ln as CdkdError, lt as TemplateParser, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalMigrateError, mt as AssetPublisher, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as applyRoleArnIfSet, o as planFailedOps, on as resetAwsClients, ot as isRetryableTransientError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalInvokeBuildError$1, pt as shouldRetainResource, q as normalizeAwsTagsToCfn, qt as warnDeprecatedNoPrefixCliFlag, r as DeployEngine, rn as resolveBucketRegion, rt as DiffCalculator, s as planRollback, sn as setAwsClients, st as isThrottlingError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as processStackMessages, tt as requireConfigString, u as withResourceDeadline, ut as LockManager, v as isFinalSnapshotError, vn as NestedStackChildDirectDestroyError, vt as createAssetRedirectResolver, w as isStatefulRecreateTargetSync, wn as StackTerminationProtectionError, wt as getBootstrapMarkerKey, x as makeCanonicalizePropertiesFn, xn as ResourceTimeoutError, xt as AssetModeResolver, y as refusesFinalSnapshot, yn as PartialFailureError, yt as loadPublishableAssetManifest, z as CloudControlProvider, zt as resolveApp } from "./deploy-engine-OafbuSbc.js";
2
+ import { $ as replayWarn, $t as uploadCfnTemplate, A as green, An as normalizeAwsError, At as formatDockerLoginError, B as slowCcOperationTimeoutMs, Bt as resolveApp, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as ResourceUpdateNotSupportedError, Ct as BOOTSTRAP_MARKER_PREFIX, D as bold, Dt as validateAssetBucketName, E as formatResourceLine, Et as parseBootstrapMarker, F as clearOnUpdateRemoval, Ft as getDockerImageBySourceHash, G as getAccountInfo, Gt as resolveStateBucketWithDefaultAndSource, H as isTerminationProtectionPropagationError, Ht as resolveCaptureObservedState, I as ProviderRegistry, It as Synthesizer, J as normalizeAwsTagsToCfn, Jt as warnDeprecatedNoPrefixCliFlag, K as refStateLookupFromResource, Kt as resolveUseCdkBootstrapAssets, L as findActionableSilentDrops, Lt as synthesisStatusMessage, M as yellow, Mt as runDockerForeground, N as IAMRoleProvider, Nt as runDockerStreaming, O as cyan, Ot as validateContainerRepoName, P as collectInlinePolicyNamesManagedBySiblings, Pt as AssetManifestLoader, Q as readConfigString, Qt as findLargeInlineResources, R as findSilentDropProperties, Rt as getDefaultStateBucketName, S as extractDeploymentEventError, Sn as ResourceTimeoutError, St as AssetModeResolver, T as renderStatefulReason, Tn as StackTerminationProtectionError, Tt as getBootstrapMarkerKey, U as IntrinsicFunctionResolver, Ut as resolveSkipPrefix, V as disableInstanceApiTermination, Vt as resolveAutoAssetStorage, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefault, X as assertRegionMatch, Xt as CFN_TEMPLATE_URL_LIMIT, Y as resolveExplicitPhysicalId, Yt as CFN_TEMPLATE_BODY_LIMIT, Z as configStringRefusal, Zt as MIGRATE_TMP_PREFIX, _ as createPreDeleteFinalSnapshot, _t as WorkGraph, a as DeploymentEventsStore, an as AwsClients, at as describeTypeWithThrottleRetry, b as unsupportedFinalSnapshotError, bn as PartialFailureError, bt as loadPublishableAssetManifest, c as replayFailedOperations, cn as setAwsClients, ct as isThrottlingError, d as IMPLICIT_DELETE_DEPENDENCIES, dt as LockManager, en as expectedOwnerParam, et as requireConfigArray, f as computeImplicitDeleteEdges, ft as S3StateBackend, g as ccRoutedFinalSnapshotError, gn as LocalStartServiceError, gt as stringifyValue, h as buildFinalSnapshotIdentifier, hn as LocalMigrateError, ht as AssetPublisher, i as DeploymentEventsReader, in as resolveBucketRegion, it as DiffCalculator, j as red, jn as withErrorHandling, jt as getDockerCmd, k as gray, kt as buildDockerImage, l as replayRollback, lt as DagBuilder, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalInvokeBuildError$1, mt as shouldRetainResource, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as processStackMessages, nt as requireConfigString, o as planFailedOps, on as getAwsClients, ot as withRetry, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as DeployCancelledError, pt as rebuildClientForBucketRegion, q as WAFv2WebACLProvider, qt as stateBucketExistenceConfirmed, r as DeployEngine, rt as applyRoleArnIfSet, s as planRollback, sn as resetAwsClients, st as isRetryableTransientError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as AssemblyReader, tt as requireConfigObject, u as withResourceDeadline, un as CdkdError, ut as TemplateParser, v as isFinalSnapshotError, vn as MissingCdkCliError, vt as buildAssetRedirectMap, w as isStatefulRecreateTargetSync, wn as StackHasActiveImportsError, wt as ensureAssetStorage, x as makeCanonicalizePropertiesFn, xn as ProvisioningError, xt as rewriteTemplateAssetReferences, y as refusesFinalSnapshot, yn as NestedStackChildDirectDestroyError, yt as createAssetRedirectResolver, z as CloudControlProvider, zt as getLegacyStateBucketName } from "./deploy-engine-DMY-UXvg.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-BhomRJhR.js";
4
+ import { t as ASGProvider } from "./asg-provider-mWcJAGAu.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";
@@ -13829,8 +13829,14 @@ var DynamoDBGlobalTableProvider = class {
13829
13829
  if (!keySchema) throw new ProvisioningError(`KeySchema is required for DynamoDB GlobalTable ${logicalId}`, resourceType, logicalId);
13830
13830
  if (!attributeDefinitions) throw new ProvisioningError(`AttributeDefinitions is required for DynamoDB GlobalTable ${logicalId}`, resourceType, logicalId);
13831
13831
  let billingMode;
13832
- try {
13833
- billingMode = requireConfigString(properties["BillingMode"], "PAY_PER_REQUEST", "AWS::DynamoDB::GlobalTable BillingMode", replayWarn(this.logger, context));
13832
+ let billingModeSubstituted = false;
13833
+ try {
13834
+ const billingReplayWarn = replayWarn(this.logger, context).onUnusable;
13835
+ billingMode = requireConfigString(properties["BillingMode"], "PAY_PER_REQUEST", "AWS::DynamoDB::GlobalTable BillingMode", billingReplayWarn ? { onUnusable: (message) => {
13836
+ billingModeSubstituted = true;
13837
+ billingReplayWarn(message);
13838
+ } } : {});
13839
+ if (billingReplayWarn && properties["BillingMode"] === void 0) this.logger.warn(`AWS::DynamoDB::GlobalTable ${logicalId}: the state record declares no BillingMode, so this replay creates the table PAY_PER_REQUEST. If it was PROVISIONED, set the mode in the template and redeploy.`);
13834
13840
  } catch (error) {
13835
13841
  throw new ProvisioningError(error instanceof Error ? error.message : String(error), resourceType, logicalId, void 0, error instanceof Error ? error : void 0);
13836
13842
  }
@@ -13845,6 +13851,10 @@ var DynamoDBGlobalTableProvider = class {
13845
13851
  const diagnostics = [];
13846
13852
  if (billingMode === "PROVISIONED") createParams.ProvisionedThroughput = derivePerCallProvisionedThroughput(properties, currentRegion, "min", diagnostics);
13847
13853
  let effectiveProperties;
13854
+ if (billingModeSubstituted) effectiveProperties = {
13855
+ ...properties,
13856
+ BillingMode: billingMode
13857
+ };
13848
13858
  const streamSpecInput = properties["StreamSpecification"];
13849
13859
  const needsStream = replicas.some((r) => r["Region"] !== currentRegion) || replicas.length > 1;
13850
13860
  if (streamSpecInput != null) {
@@ -13864,7 +13874,7 @@ var DynamoDBGlobalTableProvider = class {
13864
13874
  StreamViewType: streamViewType
13865
13875
  };
13866
13876
  if (streamSpecSubstituted) effectiveProperties = {
13867
- ...properties,
13877
+ ...effectiveProperties ?? properties,
13868
13878
  StreamSpecification: { StreamViewType: streamViewType }
13869
13879
  };
13870
13880
  } else if (needsStream) {
@@ -14095,7 +14105,7 @@ var DynamoDBGlobalTableProvider = class {
14095
14105
  let billingUnusable = false;
14096
14106
  const requestedBilling = requireConfigString(properties["BillingMode"], "PAY_PER_REQUEST", "AWS::DynamoDB::GlobalTable BillingMode", { onUnusable: (message) => {
14097
14107
  billingUnusable = true;
14098
- this.logger.warn(`${message} The table's current billing mode (${oldBilling}) is kept for this update rather than flipped to the default.`);
14108
+ this.logger.warn(`AWS::DynamoDB::GlobalTable ${logicalId}: ${message} The mode this update compared against (${oldBilling}) is kept for this update rather than flipped to the default.`);
14099
14109
  } });
14100
14110
  const newBilling = billingUnusable ? oldBilling : requestedBilling;
14101
14111
  const onDemandCeilingLive = oldBilling === "PAY_PER_REQUEST" && newBilling === "PAY_PER_REQUEST";
@@ -14160,11 +14170,26 @@ var DynamoDBGlobalTableProvider = class {
14160
14170
  } else {
14161
14171
  const previousStreamSpec = previousProperties["StreamSpecification"];
14162
14172
  const previousStreamSpecUsable = previousStreamSpec !== void 0 && previousStreamSpec !== null && configStringRefusal(previousStreamSpec, "StreamViewType", "NEW_AND_OLD_IMAGES", "AWS::DynamoDB::GlobalTable StreamSpecification") === void 0;
14163
- effectiveProperties = { ...properties };
14173
+ effectiveProperties = { ...effectiveProperties ?? properties };
14164
14174
  if (previousStreamSpecUsable) effectiveProperties["StreamSpecification"] = { ...previousStreamSpec };
14165
14175
  else delete effectiveProperties["StreamSpecification"];
14166
14176
  }
14167
14177
  }
14178
+ if (desiredGsiUnusable) {
14179
+ let previousGsiProbeUnusable = false;
14180
+ toSdkGlobalSecondaryIndexes(previousProperties, currentRegion, oldBilling, "min", void 0, () => {
14181
+ previousGsiProbeUnusable = true;
14182
+ });
14183
+ const previousIndexes = previousProperties["GlobalSecondaryIndexes"];
14184
+ effectiveProperties = { ...effectiveProperties ?? properties };
14185
+ if (!previousGsiProbeUnusable && previousIndexes !== void 0) effectiveProperties["GlobalSecondaryIndexes"] = [...previousIndexes];
14186
+ else delete effectiveProperties["GlobalSecondaryIndexes"];
14187
+ }
14188
+ if (billingUnusable) {
14189
+ effectiveProperties = { ...effectiveProperties ?? properties };
14190
+ if (recordedOldBilling === void 0) delete effectiveProperties["BillingMode"];
14191
+ else effectiveProperties["BillingMode"] = oldBilling;
14192
+ }
14168
14193
  const awsOnDemand = describeResp.Table?.OnDemandThroughput;
14169
14194
  const onDemandPayload = {};
14170
14195
  const resolveCeiling = (desired, live) => {
@@ -36765,6 +36790,51 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
36765
36790
  }
36766
36791
  };
36767
36792
 
36793
+ //#endregion
36794
+ //#region src/utils/aws-partition.ts
36795
+ /**
36796
+ * AWS partition / URL-suffix derivation, shared across layers.
36797
+ *
36798
+ * Lives in `src/utils/` because it has consumers in two different layers: the
36799
+ * `cdkd local *` command family (which passes a region in once to keep the STS
36800
+ * hop minimal) and the provisioning layer's `AppSyncProvider`, which rebuilds a
36801
+ * child resource's ARN when AWS did not report one.
36802
+ *
36803
+ * It was originally defined in `src/local/ecs-task-resolver.ts`, which
36804
+ * re-exports it so every existing call site is unchanged; a provisioning
36805
+ * provider importing from `src/local/**` would invert the layering.
36806
+ *
36807
+ * NOTE this is the mapping to prefer over `getAccountInfo().partition`
36808
+ * (`src/deployment/intrinsic-function-resolver.ts`), which is hardcoded to
36809
+ * `'aws'` and says so in its own comment.
36810
+ */
36811
+ /**
36812
+ * Derive the AWS partition / URL suffix for an AWS region. Same mapping
36813
+ * CloudFormation applies to `${AWS::Partition}` / `${AWS::URLSuffix}`.
36814
+ */
36815
+ function derivePartitionAndUrlSuffix(region) {
36816
+ if (region.startsWith("cn-")) return {
36817
+ partition: "aws-cn",
36818
+ urlSuffix: "amazonaws.com.cn"
36819
+ };
36820
+ if (region.startsWith("us-gov-")) return {
36821
+ partition: "aws-us-gov",
36822
+ urlSuffix: "amazonaws.com"
36823
+ };
36824
+ if (region.startsWith("us-iso-")) return {
36825
+ partition: "aws-iso",
36826
+ urlSuffix: "c2s.ic.gov"
36827
+ };
36828
+ if (region.startsWith("us-isob-")) return {
36829
+ partition: "aws-iso-b",
36830
+ urlSuffix: "sc2s.sgov.gov"
36831
+ };
36832
+ return {
36833
+ partition: "aws",
36834
+ urlSuffix: "amazonaws.com"
36835
+ };
36836
+ }
36837
+
36768
36838
  //#endregion
36769
36839
  //#region src/provisioning/providers/appsync-provider.ts
36770
36840
  const MUTABLE_GRAPHQL_API_CONFIG_PROPERTIES = [
@@ -36882,6 +36952,111 @@ var AppSyncProvider = class {
36882
36952
  return this.client;
36883
36953
  }
36884
36954
  /**
36955
+ * Build a child-resource ARN from the deploy's REAL partition / region /
36956
+ * account (issue #1681).
36957
+ *
36958
+ * The three child types record an ARN attribute because CloudFormation's
36959
+ * `Ref` for each of them returns the resource ARN (docs-verified 2026-08-12)
36960
+ * and `Fn::GetAtt` serves the same value from the same cached map — this
36961
+ * provider's `getAttribute` always resolves `undefined`, so the recorded
36962
+ * attribute is the ONLY source for both intrinsics.
36963
+ *
36964
+ * Until #1681 those attributes were string-built as
36965
+ * `arn:aws:appsync:*:*:...`, i.e. with literal `*` in the region and account
36966
+ * positions, so every consumer received an ARN AWS cannot resolve. Prefer the
36967
+ * ARN the create response reports (`dataSourceArn` / `resolverArn`); this
36968
+ * helper is for `AWS::AppSync::ApiKey`, whose `CreateApiKey` response carries
36969
+ * no ARN field at all, and as the fallback for the other two when a response
36970
+ * comes back without one.
36971
+ *
36972
+ * `getAccountInfo` is the same STS-backed, process-cached resolver
36973
+ * `CloudControlProvider` uses for its own ARN reconstruction, so this costs
36974
+ * at most one `GetCallerIdentity` per deploy.
36975
+ */
36976
+ async buildAppSyncArn(suffix) {
36977
+ const accountInfo = await getAccountInfo(this.providerRegion ?? await this.getClient().config.region());
36978
+ const { partition } = derivePartitionAndUrlSuffix(accountInfo.region);
36979
+ return `arn:${partition}:appsync:${accountInfo.region}:${accountInfo.accountId}:${suffix}`;
36980
+ }
36981
+ /**
36982
+ * {@link buildAppSyncArn} for the POST-CREATE sites, where throwing is not an
36983
+ * option (issue #1681 PR review).
36984
+ *
36985
+ * Moving the ARN build outside the create `try` stops a failure being
36986
+ * re-labelled as a creation failure — but on its own it does NOT stop the
36987
+ * resource being orphaned: `create()` still throws, the engine still journals
36988
+ * no physicalId for a failed CREATE, and the resource still sits in AWS
36989
+ * untracked (the issue #1710 class). Since the ARN is bookkeeping and the
36990
+ * resource already exists, the honest answer is to never fail the create for
36991
+ * it: warn, omit the attribute, and let `Ref` fall back to the compound id
36992
+ * exactly as it does for an imported child. The resource's next update heals
36993
+ * the record via `childRefAttributes`.
36994
+ */
36995
+ async buildAppSyncArnOrWarn(suffix, logicalId, physicalId) {
36996
+ try {
36997
+ return await this.buildAppSyncArn(suffix);
36998
+ } catch (error) {
36999
+ this.logger.warn(`Created ${logicalId} (${physicalId}) but could not build its ARN attribute: ${error instanceof Error ? error.message : String(error)}. Ref will resolve to the compound physical id until the next update.`);
37000
+ return;
37001
+ }
37002
+ }
37003
+ /**
37004
+ * Rebuild a child type's COMPLETE attribute set from its compound physical id
37005
+ * (issue #1681), for the update path to return.
37006
+ *
37007
+ * This is what heals a record written by a pre-#1681 binary. `update()`
37008
+ * previously returned no attributes, and the deploy engine carries the
37009
+ * existing ones forward when a provider reports none — so without this a
37010
+ * resource created before the fix would keep its `arn:aws:appsync:*:*:...`
37011
+ * placeholder for the rest of its life, since only a REPLACEMENT re-runs
37012
+ * `create()`. `Fn::GetAtt` reads the same cached map, so the placeholder was
37013
+ * breaking that intrinsic too, independently of the `Ref` defect #1681 is
37014
+ * about.
37015
+ *
37016
+ * It must return EVERY key the create path records, not just the ARN: an
37017
+ * `attributes` map returned from `update()` REPLACES the record's map
37018
+ * wholesale rather than merging into it (`deploy-engine.ts`), so a partial
37019
+ * answer would silently drop `Name` / `ApiKey`.
37020
+ *
37021
+ * Returns `undefined` for an id whose arity does not match the type — a
37022
+ * record that malformed cannot be healed by guessing, and carrying the
37023
+ * existing attributes forward is the safe answer.
37024
+ */
37025
+ async childRefAttributes(resourceType, physicalId) {
37026
+ const parts = physicalId.split("|");
37027
+ if (resourceType === "AWS::AppSync::DataSource" && parts.length === 2) {
37028
+ const [apiId, name] = parts;
37029
+ return {
37030
+ DataSourceArn: await this.buildAppSyncArn(`apis/${apiId}/datasources/${name}`),
37031
+ Name: name
37032
+ };
37033
+ }
37034
+ if (resourceType === "AWS::AppSync::Resolver" && parts.length === 3) {
37035
+ const [apiId, typeName, fieldName] = parts;
37036
+ return { ResolverArn: await this.buildAppSyncArn(`apis/${apiId}/types/${typeName}/resolvers/${fieldName}`) };
37037
+ }
37038
+ if (resourceType === "AWS::AppSync::ApiKey" && parts.length === 2) {
37039
+ const [apiId, apiKeyId] = parts;
37040
+ return {
37041
+ ApiKey: apiKeyId,
37042
+ Arn: await this.buildAppSyncArn(`apis/${apiId}/apikey/${apiKeyId}`)
37043
+ };
37044
+ }
37045
+ }
37046
+ /**
37047
+ * The no-replacement update result for a child type, carrying the healed
37048
+ * attribute set (issue #1681). Reporting none is still the correct answer for
37049
+ * an unhealable id — the engine then carries the existing attributes forward.
37050
+ */
37051
+ async childUpdateResult(resourceType, physicalId) {
37052
+ const attributes = await this.childRefAttributes(resourceType, physicalId);
37053
+ return {
37054
+ physicalId,
37055
+ wasReplaced: false,
37056
+ ...attributes && { attributes }
37057
+ };
37058
+ }
37059
+ /**
36885
37060
  * Lazy S3 client for the `*S3Location` properties (Resolver
36886
37061
  * `CodeS3Location` / `RequestMappingTemplateS3Location` /
36887
37062
  * `ResponseMappingTemplateS3Location`, GraphQLSchema
@@ -37071,10 +37246,7 @@ var AppSyncProvider = class {
37071
37246
  "EventBridgeConfig",
37072
37247
  "RelationalDatabaseConfig",
37073
37248
  "MetricsConfig"
37074
- ].some((key) => (key in properties || key in previousProperties) && !this.deepEqual(properties[key], previousProperties[key]))) return {
37075
- physicalId,
37076
- wasReplaced: false
37077
- };
37249
+ ].some((key) => (key in properties || key in previousProperties) && !this.deepEqual(properties[key], previousProperties[key]))) return this.childUpdateResult(resourceType, physicalId);
37078
37250
  const input = {
37079
37251
  apiId,
37080
37252
  name,
@@ -37086,10 +37258,7 @@ var AppSyncProvider = class {
37086
37258
  } catch (error) {
37087
37259
  throw this.wrapUpdateError(error, resourceType, logicalId, physicalId, "DataSource");
37088
37260
  }
37089
- return {
37090
- physicalId,
37091
- wasReplaced: false
37092
- };
37261
+ return this.childUpdateResult(resourceType, physicalId);
37093
37262
  }
37094
37263
  async updateResolver(logicalId, physicalId, resourceType, properties, previousProperties) {
37095
37264
  for (const field of [
@@ -37119,10 +37288,7 @@ var AppSyncProvider = class {
37119
37288
  "CodeS3Location",
37120
37289
  "RequestMappingTemplateS3Location",
37121
37290
  "ResponseMappingTemplateS3Location"
37122
- ].some((key) => (key in properties || key in previousProperties) && !this.deepEqual(properties[key], previousProperties[key]))) return {
37123
- physicalId,
37124
- wasReplaced: false
37125
- };
37291
+ ].some((key) => (key in properties || key in previousProperties) && !this.deepEqual(properties[key], previousProperties[key]))) return this.childUpdateResult(resourceType, physicalId);
37126
37292
  const input = {
37127
37293
  apiId,
37128
37294
  typeName,
@@ -37134,10 +37300,7 @@ var AppSyncProvider = class {
37134
37300
  } catch (error) {
37135
37301
  throw this.wrapUpdateError(error, resourceType, logicalId, physicalId, "Resolver");
37136
37302
  }
37137
- return {
37138
- physicalId,
37139
- wasReplaced: false
37140
- };
37303
+ return this.childUpdateResult(resourceType, physicalId);
37141
37304
  }
37142
37305
  async updateApiKey(logicalId, physicalId, resourceType, properties, previousProperties) {
37143
37306
  if (properties["ApiId"] !== void 0 && previousProperties["ApiId"] !== void 0 && properties["ApiId"] !== previousProperties["ApiId"]) throw new ResourceUpdateNotSupportedError(resourceType, logicalId, "AWS AppSync ApiKey.ApiId is immutable — destroy + redeploy to change");
@@ -37147,10 +37310,7 @@ var AppSyncProvider = class {
37147
37310
  const oldDesc = previousProperties["Description"];
37148
37311
  const newExp = properties["Expires"];
37149
37312
  const oldExp = previousProperties["Expires"];
37150
- if (newDesc === oldDesc && newExp === oldExp) return {
37151
- physicalId,
37152
- wasReplaced: false
37153
- };
37313
+ if (newDesc === oldDesc && newExp === oldExp) return this.childUpdateResult(resourceType, physicalId);
37154
37314
  const input = {
37155
37315
  apiId,
37156
37316
  id: apiKeyId
@@ -37162,10 +37322,7 @@ var AppSyncProvider = class {
37162
37322
  } catch (error) {
37163
37323
  throw this.wrapUpdateError(error, resourceType, logicalId, physicalId, "ApiKey");
37164
37324
  }
37165
- return {
37166
- physicalId,
37167
- wasReplaced: false
37168
- };
37325
+ return this.childUpdateResult(resourceType, physicalId);
37169
37326
  }
37170
37327
  /**
37171
37328
  * Apply a Tags diff to a GraphqlApi via TagResource / UntagResource.
@@ -37827,6 +37984,7 @@ var AppSyncProvider = class {
37827
37984
  name: "name",
37828
37985
  value: name
37829
37986
  }], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
37987
+ let reportedArn;
37830
37988
  try {
37831
37989
  const input = {
37832
37990
  apiId,
@@ -37834,19 +37992,20 @@ var AppSyncProvider = class {
37834
37992
  type
37835
37993
  };
37836
37994
  this.applyDataSourceConfig(input, resourceType, logicalId, properties);
37837
- await this.getClient().send(new CreateDataSourceCommand(input));
37995
+ reportedArn = (await this.getClient().send(new CreateDataSourceCommand(input))).dataSource?.dataSourceArn;
37838
37996
  this.logger.debug(`Successfully created DataSource ${logicalId}: ${physicalId}`);
37839
- return {
37840
- physicalId,
37841
- attributes: {
37842
- DataSourceArn: `arn:aws:appsync:*:*:apis/${apiId}/datasources/${name}`,
37843
- Name: name
37844
- }
37845
- };
37846
37997
  } catch (error) {
37847
37998
  const cause = error instanceof Error ? error : void 0;
37848
37999
  throw new ProvisioningError(`Failed to create DataSource ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
37849
38000
  }
38001
+ const dataSourceArn = reportedArn ?? await this.buildAppSyncArnOrWarn(`apis/${apiId}/datasources/${name}`, logicalId, physicalId);
38002
+ return {
38003
+ physicalId,
38004
+ attributes: {
38005
+ ...dataSourceArn !== void 0 && { DataSourceArn: dataSourceArn },
38006
+ Name: name
38007
+ }
38008
+ };
37850
38009
  }
37851
38010
  async deleteDataSource(logicalId, physicalId, resourceType, context) {
37852
38011
  this.logger.debug(`Deleting DataSource ${logicalId}: ${physicalId}`);
@@ -37891,6 +38050,7 @@ var AppSyncProvider = class {
37891
38050
  value: fieldName
37892
38051
  }
37893
38052
  ], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
38053
+ let reportedArn;
37894
38054
  try {
37895
38055
  const input = {
37896
38056
  apiId,
@@ -37898,16 +38058,17 @@ var AppSyncProvider = class {
37898
38058
  fieldName
37899
38059
  };
37900
38060
  await this.applyResolverConfig(input, resourceType, logicalId, properties);
37901
- await this.getClient().send(new CreateResolverCommand(input));
38061
+ reportedArn = (await this.getClient().send(new CreateResolverCommand(input))).resolver?.resolverArn;
37902
38062
  this.logger.debug(`Successfully created Resolver ${logicalId}: ${physicalId}`);
37903
- return {
37904
- physicalId,
37905
- attributes: { ResolverArn: `arn:aws:appsync:*:*:apis/${apiId}/types/${typeName}/resolvers/${fieldName}` }
37906
- };
37907
38063
  } catch (error) {
37908
38064
  const cause = error instanceof Error ? error : void 0;
37909
38065
  throw new ProvisioningError(`Failed to create Resolver ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
37910
38066
  }
38067
+ const resolverArn = reportedArn ?? await this.buildAppSyncArnOrWarn(`apis/${apiId}/types/${typeName}/resolvers/${fieldName}`, logicalId, physicalId);
38068
+ return {
38069
+ physicalId,
38070
+ attributes: { ...resolverArn !== void 0 && { ResolverArn: resolverArn } }
38071
+ };
37911
38072
  }
37912
38073
  async deleteResolver(logicalId, physicalId, resourceType, context) {
37913
38074
  this.logger.debug(`Deleting Resolver ${logicalId}: ${physicalId}`);
@@ -37949,17 +38110,19 @@ var AppSyncProvider = class {
37949
38110
  const cause = error instanceof Error ? error : void 0;
37950
38111
  throw new ProvisioningError(`Failed to create ApiKey ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
37951
38112
  }
38113
+ const physicalId = packCompositeId(resourceType, logicalId, [{
38114
+ name: "apiId",
38115
+ value: apiId
38116
+ }, {
38117
+ name: "apiKeyId",
38118
+ value: apiKeyId
38119
+ }], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0);
38120
+ const apiKeyArn = await this.buildAppSyncArnOrWarn(`apis/${apiId}/apikey/${apiKeyId}`, logicalId, physicalId);
37952
38121
  return {
37953
- physicalId: packCompositeId(resourceType, logicalId, [{
37954
- name: "apiId",
37955
- value: apiId
37956
- }, {
37957
- name: "apiKeyId",
37958
- value: apiKeyId
37959
- }], context?.replayingState === true ? { onRefusal: (message) => this.logger.warn(message) } : void 0),
38122
+ physicalId,
37960
38123
  attributes: {
37961
38124
  ApiKey: apiKeyId,
37962
- Arn: `arn:aws:appsync:*:*:apis/${apiId}/apikeys/${apiKeyId}`
38125
+ ...apiKeyArn !== void 0 && { Arn: apiKeyArn }
37963
38126
  }
37964
38127
  };
37965
38128
  }
@@ -64628,34 +64791,6 @@ function notFoundError$1(target, stack, resources) {
64628
64791
 
64629
64792
  //#endregion
64630
64793
  //#region src/local/ecs-task-resolver.ts
64631
- /**
64632
- * Derive the AWS partition / URL suffix for an AWS region. Same mapping
64633
- * CloudFormation applies to `${AWS::Partition}` / `${AWS::URLSuffix}`.
64634
- * Exported so the CLI can keep the STS hop minimal — caller passes the
64635
- * region in once, this returns the matching partition + suffix.
64636
- */
64637
- function derivePartitionAndUrlSuffix(region) {
64638
- if (region.startsWith("cn-")) return {
64639
- partition: "aws-cn",
64640
- urlSuffix: "amazonaws.com.cn"
64641
- };
64642
- if (region.startsWith("us-gov-")) return {
64643
- partition: "aws-us-gov",
64644
- urlSuffix: "amazonaws.com"
64645
- };
64646
- if (region.startsWith("us-iso-")) return {
64647
- partition: "aws-iso",
64648
- urlSuffix: "c2s.ic.gov"
64649
- };
64650
- if (region.startsWith("us-isob-")) return {
64651
- partition: "aws-iso-b",
64652
- urlSuffix: "sc2s.sgov.gov"
64653
- };
64654
- return {
64655
- partition: "aws",
64656
- urlSuffix: "amazonaws.com"
64657
- };
64658
- }
64659
64794
  function detectEcsImageResolutionNeeds(stack) {
64660
64795
  const resources = stack.template.Resources ?? {};
64661
64796
  let needsPseudoParameters = false;
@@ -73301,7 +73436,7 @@ function createMigrateCommand() {
73301
73436
  */
73302
73437
  function buildProgram() {
73303
73438
  const program = new Command();
73304
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.8");
73439
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.10");
73305
73440
  program.hook("preAction", (_thisCommand, actionCommand) => {
73306
73441
  const { profile } = actionCommand.optsWithGlobals();
73307
73442
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;