@go-to-k/cdkd 0.280.15 → 0.280.17

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,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
- import { $ as requireConfigString, $t as processStackMessages, A as red, At as runDockerStreaming, B as isTerminationProtectionPropagationError, Bt as resolveSkipPrefix, C as isStatefulRecreateTargetSync, Ct as parseBootstrapMarker, D as cyan, Dn as normalizeAwsError, Dt as formatDockerLoginError, E as bold, Et as buildDockerImage, F as ProviderRegistry, Ft as getDefaultStateBucketName, G as normalizeAwsTagsToCfn, Gt as warnDeprecatedNoPrefixCliFlag, H as cfnRefValueFromPhysicalId, Ht as resolveStateBucketWithDefaultAndSource, I as findActionableSilentDrops, It as getLegacyStateBucketName, J as configStringRefusal, Jt as MIGRATE_TMP_PREFIX, K as resolveExplicitPhysicalId, Kt as CFN_TEMPLATE_BODY_LIMIT, L as CloudControlProvider, Lt as resolveApp, M as IAMRoleProvider, Mt as getDockerImageBySourceHash, N as collectInlinePolicyNamesManagedBySiblings, Nt as Synthesizer, O as gray, On as withErrorHandling, Ot as getDockerCmd, P as clearOnUpdateRemoval, Pt as synthesisStatusMessage, Q as requireConfigObject, Qt as AssemblyReader, R as slowCcOperationTimeoutMs, Rt as resolveAutoAssetStorage, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, Sn as StackTerminationProtectionError, St as getBootstrapMarkerKey, T as formatResourceLine, Tt as validateContainerRepoName, U as refStateLookupFromResource, Ut as resolveUseCdkBootstrapAssets, V as IntrinsicFunctionResolver, Vt as resolveStateBucketWithDefault, W as WAFv2WebACLProvider, Wt as stateBucketExistenceConfirmed, X as replayWarn, Xt as uploadCfnTemplate, Y as readConfigString, Yt as findLargeInlineResources, Z as requireConfigArray, Zt as expectedOwnerParam, _ as createPreDeleteFinalSnapshot, _n as PartialFailureError, _t as loadPublishableAssetManifest, a as DeploymentEventsStore, an as setAwsClients, at as isThrottlingError, b as unsupportedFinalSnapshotError, bn as ResourceUpdateNotSupportedError, bt as BOOTSTRAP_MARKER_PREFIX, c as replayFailedOperations, ct as LockManager, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalInvokeBuildError$1, dt as shouldRetainResource, et as applyRoleArnIfSet, f as computeImplicitDeleteEdges, fn as LocalMigrateError, ft as AssetPublisher, g as ccRoutedFinalSnapshotError, gn as NestedStackChildDirectDestroyError, gt as createAssetRedirectResolver, h as buildFinalSnapshotIdentifier, hn as MissingCdkCliError, ht as buildAssetRedirectMap, i as DeploymentEventsReader, in as resetAwsClients, it as isRetryableTransientError, j as yellow, jt as AssetManifestLoader, k as green, kt as runDockerForeground, l as replayRollback, lt as S3StateBackend, m as PRE_DELETE_SNAPSHOT_TYPES, mt as WorkGraph, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as AwsClients, nt as describeTypeWithThrottleRetry, o as planFailedOps, ot as DagBuilder, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalStartServiceError, pt as stringifyValue, q as assertRegionMatch, qt as CFN_TEMPLATE_URL_LIMIT, r as DeployEngine, rn as getAwsClients, rt as withRetry, s as planRollback, sn as CdkdError, st as TemplateParser, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as resolveBucketRegion, tt as DiffCalculator, u as withResourceDeadline, un as DeployCancelledError, ut as rebuildClientForBucketRegion, v as isFinalSnapshotError, vn as ProvisioningError, vt as rewriteTemplateAssetReferences, w as renderStatefulReason, wt as validateAssetBucketName, x as extractDeploymentEventError, xn as StackHasActiveImportsError, xt as ensureAssetStorage, y as refusesFinalSnapshot, yn as ResourceTimeoutError, yt as AssetModeResolver, z as disableInstanceApiTermination, zt as resolveCaptureObservedState } from "./deploy-engine-CJPLgh5z.js";
2
+ import { $ as requireConfigString, $t as processStackMessages, A as red, At as runDockerStreaming, B as isTerminationProtectionPropagationError, Bt as resolveSkipPrefix, C as isStatefulRecreateTargetSync, Ct as parseBootstrapMarker, D as cyan, Dn as normalizeAwsError, Dt as formatDockerLoginError, E as bold, Et as buildDockerImage, F as ProviderRegistry, Ft as getDefaultStateBucketName, G as normalizeAwsTagsToCfn, Gt as warnDeprecatedNoPrefixCliFlag, H as cfnRefValueFromPhysicalId, Ht as resolveStateBucketWithDefaultAndSource, I as findActionableSilentDrops, It as getLegacyStateBucketName, J as configStringRefusal, Jt as MIGRATE_TMP_PREFIX, K as resolveExplicitPhysicalId, Kt as CFN_TEMPLATE_BODY_LIMIT, L as CloudControlProvider, Lt as resolveApp, M as IAMRoleProvider, Mt as getDockerImageBySourceHash, N as collectInlinePolicyNamesManagedBySiblings, Nt as Synthesizer, O as gray, On as withErrorHandling, Ot as getDockerCmd, P as clearOnUpdateRemoval, Pt as synthesisStatusMessage, Q as requireConfigObject, Qt as AssemblyReader, R as slowCcOperationTimeoutMs, Rt as resolveAutoAssetStorage, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, Sn as StackTerminationProtectionError, St as getBootstrapMarkerKey, T as formatResourceLine, Tt as validateContainerRepoName, U as refStateLookupFromResource, Ut as resolveUseCdkBootstrapAssets, V as IntrinsicFunctionResolver, Vt as resolveStateBucketWithDefault, W as WAFv2WebACLProvider, Wt as stateBucketExistenceConfirmed, X as replayWarn, Xt as uploadCfnTemplate, Y as readConfigString, Yt as findLargeInlineResources, Z as requireConfigArray, Zt as expectedOwnerParam, _ as createPreDeleteFinalSnapshot, _n as PartialFailureError, _t as loadPublishableAssetManifest, a as DeploymentEventsStore, an as setAwsClients, at as isThrottlingError, b as unsupportedFinalSnapshotError, bn as ResourceUpdateNotSupportedError, bt as BOOTSTRAP_MARKER_PREFIX, c as replayFailedOperations, ct as LockManager, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalInvokeBuildError$1, dt as shouldRetainResource, et as applyRoleArnIfSet, f as computeImplicitDeleteEdges, fn as LocalMigrateError, ft as AssetPublisher, g as ccRoutedFinalSnapshotError, gn as NestedStackChildDirectDestroyError, gt as createAssetRedirectResolver, h as buildFinalSnapshotIdentifier, hn as MissingCdkCliError, ht as buildAssetRedirectMap, i as DeploymentEventsReader, in as resetAwsClients, it as isRetryableTransientError, j as yellow, jt as AssetManifestLoader, k as green, kt as runDockerForeground, l as replayRollback, lt as S3StateBackend, m as PRE_DELETE_SNAPSHOT_TYPES, mt as WorkGraph, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as AwsClients, nt as describeTypeWithThrottleRetry, o as planFailedOps, ot as DagBuilder, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalStartServiceError, pt as stringifyValue, q as assertRegionMatch, qt as CFN_TEMPLATE_URL_LIMIT, r as DeployEngine, rn as getAwsClients, rt as withRetry, s as planRollback, sn as CdkdError, st as TemplateParser, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as resolveBucketRegion, tt as DiffCalculator, u as withResourceDeadline, un as DeployCancelledError, ut as rebuildClientForBucketRegion, v as isFinalSnapshotError, vn as ProvisioningError, vt as rewriteTemplateAssetReferences, w as renderStatefulReason, wt as validateAssetBucketName, x as extractDeploymentEventError, xn as StackHasActiveImportsError, xt as ensureAssetStorage, y as refusesFinalSnapshot, yn as ResourceTimeoutError, yt as AssetModeResolver, z as disableInstanceApiTermination, zt as resolveCaptureObservedState } from "./deploy-engine-tCcs8UGn.js";
3
3
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, f as withSkipPrefix, i as runStackBuffered, n as getLogger, o as PATTERN_B_NAME_OPTIONS, p as withStackName, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-BYMEE-BS.js";
4
- import { t as ASGProvider } from "./asg-provider-BRvHsDmu.js";
4
+ import { t as ASGProvider } from "./asg-provider-DQLjoTQ3.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";
8
8
  import { AddRoleToInstanceProfileCommand, AddUserToGroupCommand, AttachGroupPolicyCommand, AttachRolePolicyCommand, AttachUserPolicyCommand, CreateAccessKeyCommand, CreateGroupCommand, CreateInstanceProfileCommand, CreateLoginProfileCommand, CreatePolicyCommand, CreatePolicyVersionCommand, CreateUserCommand, DeleteAccessKeyCommand, DeleteGroupCommand, DeleteGroupPolicyCommand, DeleteInstanceProfileCommand, DeleteLoginProfileCommand, DeletePolicyCommand, DeletePolicyVersionCommand, DeleteRolePolicyCommand, DeleteUserCommand, DeleteUserPermissionsBoundaryCommand, DeleteUserPolicyCommand, DetachGroupPolicyCommand, DetachRolePolicyCommand, DetachUserPolicyCommand, GetAccessKeyLastUsedCommand, GetGroupCommand, GetGroupPolicyCommand, GetInstanceProfileCommand, GetPolicyCommand, GetPolicyVersionCommand, GetRoleCommand, GetRolePolicyCommand, GetUserCommand, GetUserPolicyCommand, IAMClient, ListAccessKeysCommand, ListAttachedGroupPoliciesCommand, ListAttachedUserPoliciesCommand, ListEntitiesForPolicyCommand, ListGroupPoliciesCommand, ListGroupsForUserCommand, ListPoliciesCommand, ListPolicyTagsCommand, ListPolicyVersionsCommand, ListUserPoliciesCommand, NoSuchEntityException, PutGroupPolicyCommand, PutRolePolicyCommand, PutUserPermissionsBoundaryCommand, PutUserPolicyCommand, RemoveRoleFromInstanceProfileCommand, RemoveUserFromGroupCommand, TagPolicyCommand, TagUserCommand, UntagPolicyCommand, UntagUserCommand, UpdateAccessKeyCommand, UpdateLoginProfileCommand } from "@aws-sdk/client-iam";
9
9
  import { CreateQueueCommand, DeleteQueueCommand, GetQueueAttributesCommand, GetQueueUrlCommand, ListQueueTagsCommand, QueueDoesNotExist, SQSClient, SetQueueAttributesCommand, TagQueueCommand, UntagQueueCommand } from "@aws-sdk/client-sqs";
10
10
  import { CreateTopicCommand, DeleteTopicCommand, GetSubscriptionAttributesCommand, GetTopicAttributesCommand, InvalidParameterException, ListSubscriptionsByTopicCommand, ListTagsForResourceCommand, ListTopicsCommand, NotFoundException, SNSClient, SetTopicAttributesCommand, SubscribeCommand, TagResourceCommand, UnsubscribeCommand, UntagResourceCommand } from "@aws-sdk/client-sns";
11
- import { AddPermissionCommand, CreateEventSourceMappingCommand, CreateFunctionCommand, CreateFunctionUrlConfigCommand, DeleteEventSourceMappingCommand, DeleteFunctionCommand, DeleteFunctionConcurrencyCommand, DeleteFunctionEventInvokeConfigCommand, DeleteFunctionUrlConfigCommand, DeleteLayerVersionCommand, GetEventSourceMappingCommand, GetFunctionCommand, GetFunctionConcurrencyCommand, GetFunctionEventInvokeConfigCommand, GetFunctionRecursionConfigCommand, GetFunctionUrlConfigCommand, GetLayerVersionByArnCommand, GetPolicyCommand as GetPolicyCommand$1, LambdaClient, ListTagsCommand, PublishLayerVersionCommand, PutFunctionConcurrencyCommand, PutFunctionEventInvokeConfigCommand, PutFunctionRecursionConfigCommand, RemovePermissionCommand, ResourceNotFoundException, TagResourceCommand as TagResourceCommand$1, UntagResourceCommand as UntagResourceCommand$1, UpdateEventSourceMappingCommand, UpdateFunctionCodeCommand, UpdateFunctionConfigurationCommand, UpdateFunctionUrlConfigCommand, waitUntilFunctionUpdatedV2 } from "@aws-sdk/client-lambda";
11
+ import { AddPermissionCommand, CreateEventSourceMappingCommand, CreateFunctionCommand, CreateFunctionUrlConfigCommand, DeleteEventSourceMappingCommand, DeleteFunctionCodeSigningConfigCommand, DeleteFunctionCommand, DeleteFunctionConcurrencyCommand, DeleteFunctionEventInvokeConfigCommand, DeleteFunctionUrlConfigCommand, DeleteLayerVersionCommand, GetEventSourceMappingCommand, GetFunctionCodeSigningConfigCommand, GetFunctionCommand, GetFunctionConcurrencyCommand, GetFunctionEventInvokeConfigCommand, GetFunctionRecursionConfigCommand, GetFunctionUrlConfigCommand, GetLayerVersionByArnCommand, GetPolicyCommand as GetPolicyCommand$1, GetRuntimeManagementConfigCommand, LambdaClient, ListTagsCommand, PublishLayerVersionCommand, PutFunctionCodeSigningConfigCommand, PutFunctionConcurrencyCommand, PutFunctionEventInvokeConfigCommand, PutFunctionRecursionConfigCommand, PutRuntimeManagementConfigCommand, RemovePermissionCommand, ResourceNotFoundException, TagResourceCommand as TagResourceCommand$1, UntagResourceCommand as UntagResourceCommand$1, UpdateEventSourceMappingCommand, UpdateFunctionCodeCommand, UpdateFunctionConfigurationCommand, UpdateFunctionUrlConfigCommand, waitUntilFunctionActiveV2, waitUntilFunctionUpdatedV2 } from "@aws-sdk/client-lambda";
12
12
  import { AssumeRoleCommand, GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
13
13
  import { AllocateAddressCommand, AssociateAddressCommand, AssociateIamInstanceProfileCommand, AssociateRouteTableCommand, AttachInternetGatewayCommand, AuthorizeSecurityGroupEgressCommand, AuthorizeSecurityGroupIngressCommand, CreateInternetGatewayCommand, CreateNatGatewayCommand, CreateNetworkAclCommand, CreateNetworkAclEntryCommand, CreateRouteCommand, CreateRouteTableCommand, CreateSecurityGroupCommand, CreateSubnetCommand, CreateTagsCommand, CreateVpcCommand, DeleteInternetGatewayCommand, DeleteNatGatewayCommand, DeleteNetworkAclCommand, DeleteNetworkAclEntryCommand, DeleteNetworkInterfaceCommand, DeleteRouteCommand, DeleteRouteTableCommand, DeleteSecurityGroupCommand, DeleteSubnetCommand, DeleteTagsCommand, DeleteVpcCommand, DescribeAddressesCommand, DescribeAvailabilityZonesCommand, DescribeIamInstanceProfileAssociationsCommand, DescribeInstanceAttributeCommand, DescribeInstanceCreditSpecificationsCommand, DescribeInstancesCommand, DescribeInternetGatewaysCommand, DescribeNatGatewaysCommand, DescribeNetworkAclsCommand, DescribeNetworkInterfacesCommand, DescribeRouteTablesCommand, DescribeSecurityGroupsCommand, DescribeSubnetsCommand, DescribeVolumesCommand, DescribeVpcAttributeCommand, DescribeVpcsCommand, DetachInternetGatewayCommand, DisassociateAddressCommand, DisassociateRouteTableCommand, EC2Client, ModifyInstanceAttributeCommand, ModifyInstanceCreditSpecificationCommand, ModifyInstanceMetadataOptionsCommand, ModifySubnetAttributeCommand, ModifyVpcAttributeCommand, MonitorInstancesCommand, ReleaseAddressCommand, ReplaceNetworkAclAssociationCommand, RevokeSecurityGroupEgressCommand, RevokeSecurityGroupIngressCommand, RunInstancesCommand, TerminateInstancesCommand, UnmonitorInstancesCommand, waitUntilInstanceRunning, waitUntilInstanceTerminated, waitUntilNatGatewayAvailable, waitUntilNatGatewayDeleted } from "@aws-sdk/client-ec2";
14
14
  import { CreateTableCommand, DeleteResourcePolicyCommand, DeleteTableCommand, DescribeContinuousBackupsCommand, DescribeContributorInsightsCommand, DescribeKinesisStreamingDestinationCommand, DescribeTableCommand, DescribeTimeToLiveCommand, DisableKinesisStreamingDestinationCommand, DynamoDBClient, EnableKinesisStreamingDestinationCommand, GetResourcePolicyCommand, ListTagsOfResourceCommand, PutResourcePolicyCommand, ResourceNotFoundException as ResourceNotFoundException$1, TagResourceCommand as TagResourceCommand$2, UntagResourceCommand as UntagResourceCommand$2, UpdateContinuousBackupsCommand, UpdateContributorInsightsCommand, UpdateTableCommand, UpdateTimeToLiveCommand } from "@aws-sdk/client-dynamodb";
@@ -9028,6 +9028,13 @@ function isSnsTopicArnList(value) {
9028
9028
  //#endregion
9029
9029
  //#region src/provisioning/providers/lambda-function-provider.ts
9030
9030
  /**
9031
+ * Attempts the create path's atomicity cleanup makes when DeleteFunction is
9032
+ * refused because the function is still settling. Three attempts with the
9033
+ * linear backoff in `cleanupDeleteRetryDelayMs` covers the few seconds a
9034
+ * `Pending` -> terminal transition takes without stalling a failed deploy.
9035
+ */
9036
+ const LAMBDA_CLEANUP_DELETE_MAX_ATTEMPTS = 3;
9037
+ /**
9031
9038
  * Pick the inline-code filename for a Lambda runtime.
9032
9039
  *
9033
9040
  * CloudFormation's `Code.ZipFile` auto-zips inline code into a file named
@@ -9078,8 +9085,28 @@ var LambdaFunctionProvider = class {
9078
9085
  "SnapStart",
9079
9086
  "LoggingConfig",
9080
9087
  "RecursiveLoop",
9081
- "ReservedConcurrentExecutions"
9088
+ "ReservedConcurrentExecutions",
9089
+ "CodeSigningConfigArn",
9090
+ "RuntimeManagementConfig",
9091
+ "DurableConfig",
9092
+ "TenancyConfig"
9082
9093
  ])]]);
9094
+ /**
9095
+ * Properties the provider deliberately does NOT wire (issue #391 /
9096
+ * see `ResourceProvider.unhandledByDesign`).
9097
+ *
9098
+ * `CapacityProviderConfig` / `FunctionScalingConfig` are deliberately NOT
9099
+ * here — they stay in `silentDrop` (pre-flight rejection with the
9100
+ * `--allow-unsupported-properties` escape hatch) rather than being declared
9101
+ * un-wirable, because they ARE wirable once Lambda managed instances are
9102
+ * supported. They are one coupled feature: `PutFunctionScalingConfig` fails
9103
+ * with `AccessDeniedException: The function provided by the arn does not
9104
+ * contain a capacity provider configuration` unless the function already
9105
+ * carries a capacity provider (live-probed us-east-1, 2026-08-11). Tracked
9106
+ * in issue #1616.
9107
+ */
9108
+ unhandledByDesign = /* @__PURE__ */ new Map([["AWS::Lambda::Function", /* @__PURE__ */ new Map([["PublishToLatestPublished", "CloudFormation-only version-publishing directive with no AWS SDK equivalent"]])]]);
9109
+ cleanupDeleteRetryDelayMs = 2e3;
9083
9110
  eniWaitTimeoutMs = 600 * 1e3;
9084
9111
  eniWaitInitialDelayMs = 1e4;
9085
9112
  eniWaitMaxDelayMs = 1e4;
@@ -9131,39 +9158,50 @@ var LambdaFunctionProvider = class {
9131
9158
  ImageConfig: properties["ImageConfig"],
9132
9159
  SnapStart: properties["SnapStart"],
9133
9160
  LoggingConfig: properties["LoggingConfig"],
9161
+ DurableConfig: properties["DurableConfig"],
9162
+ TenancyConfig: properties["TenancyConfig"],
9163
+ CodeSigningConfigArn: properties["CodeSigningConfigArn"],
9134
9164
  Tags: tags
9135
9165
  };
9136
9166
  const response = await this.lambdaClient.send(new CreateFunctionCommand(createParams));
9137
9167
  const recursiveLoop = properties["RecursiveLoop"];
9138
- if (recursiveLoop !== void 0) try {
9139
- await this.lambdaClient.send(new PutFunctionRecursionConfigCommand({
9140
- FunctionName: functionName,
9141
- RecursiveLoop: recursiveLoop
9142
- }));
9143
- } catch (rlError) {
9144
- this.logger.warn(`PutFunctionRecursionConfig failed for ${logicalId}: ${rlError instanceof Error ? rlError.message : String(rlError)} — deleting partially-created function to maintain atomicity`);
9145
- try {
9146
- await this.lambdaClient.send(new DeleteFunctionCommand({ FunctionName: functionName }));
9147
- } catch (deleteError) {
9148
- this.logger.error(`Cleanup DeleteFunction failed for ${logicalId} after PutFunctionRecursionConfig failure — function may be orphaned: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}`);
9149
- }
9150
- throw new ProvisioningError(`Failed to set RecursiveLoop on Lambda function ${logicalId} (function was deleted to maintain atomicity): ${rlError instanceof Error ? rlError.message : String(rlError)}`, resourceType, logicalId, functionName, rlError instanceof Error ? rlError : void 0);
9151
- }
9168
+ if (recursiveLoop !== void 0) await this.applyPostCreateConfig(() => this.lambdaClient.send(new PutFunctionRecursionConfigCommand({
9169
+ FunctionName: functionName,
9170
+ RecursiveLoop: recursiveLoop
9171
+ })), {
9172
+ apiName: "PutFunctionRecursionConfig",
9173
+ propertyName: "RecursiveLoop",
9174
+ logicalId,
9175
+ resourceType,
9176
+ functionName
9177
+ });
9152
9178
  const reservedConcurrentExecutions = properties["ReservedConcurrentExecutions"];
9153
- if (reservedConcurrentExecutions !== void 0) try {
9154
- await this.lambdaClient.send(new PutFunctionConcurrencyCommand({
9155
- FunctionName: functionName,
9156
- ReservedConcurrentExecutions: reservedConcurrentExecutions
9157
- }));
9158
- } catch (pcError) {
9159
- this.logger.warn(`PutFunctionConcurrency failed for ${logicalId}: ${pcError instanceof Error ? pcError.message : String(pcError)} — deleting partially-created function to maintain atomicity`);
9160
- try {
9161
- await this.lambdaClient.send(new DeleteFunctionCommand({ FunctionName: functionName }));
9162
- } catch (deleteError) {
9163
- this.logger.error(`Cleanup DeleteFunction failed for ${logicalId} after PutFunctionConcurrency failure — function may be orphaned: ${deleteError instanceof Error ? deleteError.message : String(deleteError)}`);
9164
- }
9165
- throw new ProvisioningError(`Failed to set ReservedConcurrentExecutions on Lambda function ${logicalId} (function was deleted to maintain atomicity): ${pcError instanceof Error ? pcError.message : String(pcError)}`, resourceType, logicalId, functionName, pcError instanceof Error ? pcError : void 0);
9166
- }
9179
+ if (reservedConcurrentExecutions !== void 0) await this.applyPostCreateConfig(() => this.lambdaClient.send(new PutFunctionConcurrencyCommand({
9180
+ FunctionName: functionName,
9181
+ ReservedConcurrentExecutions: reservedConcurrentExecutions
9182
+ })), {
9183
+ apiName: "PutFunctionConcurrency",
9184
+ propertyName: "ReservedConcurrentExecutions",
9185
+ logicalId,
9186
+ resourceType,
9187
+ functionName
9188
+ });
9189
+ const runtimeManagementConfig = properties["RuntimeManagementConfig"];
9190
+ if (runtimeManagementConfig !== void 0) await this.applyPostCreateConfig(async () => {
9191
+ await waitUntilFunctionActiveV2({
9192
+ client: this.lambdaClient,
9193
+ maxWaitTime: this.functionUpdateMaxWaitSeconds,
9194
+ minDelay: 1,
9195
+ maxDelay: 5
9196
+ }, { FunctionName: functionName });
9197
+ await this.putRuntimeManagementConfig(functionName, runtimeManagementConfig);
9198
+ }, {
9199
+ apiName: "PutRuntimeManagementConfig",
9200
+ propertyName: "RuntimeManagementConfig",
9201
+ logicalId,
9202
+ resourceType,
9203
+ functionName
9204
+ });
9167
9205
  this.logger.debug(`Successfully created Lambda function ${logicalId}: ${functionName}`);
9168
9206
  return {
9169
9207
  physicalId: response.FunctionName || functionName,
@@ -9178,6 +9216,63 @@ var LambdaFunctionProvider = class {
9178
9216
  }
9179
9217
  }
9180
9218
  /**
9219
+ * Run a post-create control-plane call under the create path's atomicity
9220
+ * contract: on failure, DELETE the just-created function so the next deploy
9221
+ * retry sees a fresh slate instead of an orphan that already exists.
9222
+ *
9223
+ * Extracted from the (previously duplicated) `RecursiveLoop` /
9224
+ * `ReservedConcurrentExecutions` blocks when `RuntimeManagementConfig`
9225
+ * became the third caller — the wording of all three log lines and of the
9226
+ * thrown error is preserved verbatim, parameterized only by the API name
9227
+ * and the CFn property name.
9228
+ *
9229
+ * VPC-attached Lambda caveat (unchanged): the cleanup uses a bare
9230
+ * `DeleteFunction`, not the provider's own `delete()`, so hyperplane ENIs
9231
+ * are NOT pre-detached / awaited. For a VPC-attached function whose call
9232
+ * fails, the next deploy retry's downstream Subnet/SG creation can race the
9233
+ * asynchronous ENI release until AWS finishes the detach. The "concurrent
9234
+ * update operation" substring is preserved in the wrapped error message so
9235
+ * the outer `withRetry` classifier still retries cleanly.
9236
+ */
9237
+ async applyPostCreateConfig(send, ctx) {
9238
+ try {
9239
+ await send();
9240
+ } catch (error) {
9241
+ const message = error instanceof Error ? error.message : String(error);
9242
+ this.logger.warn(`${ctx.apiName} failed for ${ctx.logicalId}: ${message} — deleting partially-created function to maintain atomicity`);
9243
+ let cleanupFailure;
9244
+ for (let attempt = 0; attempt < LAMBDA_CLEANUP_DELETE_MAX_ATTEMPTS; attempt++) try {
9245
+ await this.lambdaClient.send(new DeleteFunctionCommand({ FunctionName: ctx.functionName }));
9246
+ cleanupFailure = void 0;
9247
+ break;
9248
+ } catch (deleteError) {
9249
+ const deleteMessage = deleteError instanceof Error ? deleteError.message : String(deleteError);
9250
+ cleanupFailure = deleteMessage;
9251
+ if (!/currently in the following state|ResourceConflict/i.test(deleteMessage)) break;
9252
+ if (attempt < LAMBDA_CLEANUP_DELETE_MAX_ATTEMPTS - 1) await new Promise((resolve) => setTimeout(resolve, this.cleanupDeleteRetryDelayMs * (attempt + 1)));
9253
+ }
9254
+ if (cleanupFailure !== void 0) this.logger.error(`Cleanup DeleteFunction failed for ${ctx.logicalId} after ${ctx.apiName} failure — function may be orphaned: ${cleanupFailure}`);
9255
+ throw new ProvisioningError(`Failed to set ${ctx.propertyName} on Lambda function ${ctx.logicalId} (function was deleted to maintain atomicity): ${message}`, ctx.resourceType, ctx.logicalId, ctx.functionName, error instanceof Error ? error : void 0);
9256
+ }
9257
+ }
9258
+ /**
9259
+ * Send the CFn `RuntimeManagementConfig` block to `PutRuntimeManagementConfig`.
9260
+ *
9261
+ * CFn spells the block `{ UpdateRuntimeOn, RuntimeVersionArn }` and the SDK
9262
+ * request carries the same two members flat on the request (plus the
9263
+ * function name), so this is a straight lift rather than a re-shape.
9264
+ * `UpdateRuntimeOn` is required by the API; a template that omits it is
9265
+ * refused by AWS with its own validation error, which is the behavior we
9266
+ * want to surface rather than paper over with a cdkd-invented default.
9267
+ */
9268
+ async putRuntimeManagementConfig(functionName, config) {
9269
+ await this.lambdaClient.send(new PutRuntimeManagementConfigCommand({
9270
+ FunctionName: functionName,
9271
+ UpdateRuntimeOn: config["UpdateRuntimeOn"],
9272
+ RuntimeVersionArn: config["RuntimeVersionArn"]
9273
+ }));
9274
+ }
9275
+ /**
9181
9276
  * Update a Lambda function
9182
9277
  */
9183
9278
  async update(logicalId, physicalId, resourceType, properties, previousProperties) {
@@ -9200,7 +9295,8 @@ var LambdaFunctionProvider = class {
9200
9295
  "FileSystemConfigs",
9201
9296
  "ImageConfig",
9202
9297
  "SnapStart",
9203
- "LoggingConfig"
9298
+ "LoggingConfig",
9299
+ "DurableConfig"
9204
9300
  ];
9205
9301
  let hasConfigChanges = false;
9206
9302
  for (const field of configFields) if (JSON.stringify(properties[field]) !== JSON.stringify(previousProperties[field])) {
@@ -9226,12 +9322,19 @@ var LambdaFunctionProvider = class {
9226
9322
  FileSystemConfigs: clearOnUpdateRemoval(properties["FileSystemConfigs"], previousProperties["FileSystemConfigs"], []),
9227
9323
  ImageConfig: clearOnUpdateRemoval(properties["ImageConfig"], previousProperties["ImageConfig"], {}),
9228
9324
  SnapStart: clearOnUpdateRemoval(properties["SnapStart"], previousProperties["SnapStart"], { ApplyOn: "None" }),
9229
- LoggingConfig: clearOnUpdateRemoval(properties["LoggingConfig"], previousProperties["LoggingConfig"], { LogFormat: "Text" })
9325
+ LoggingConfig: clearOnUpdateRemoval(properties["LoggingConfig"], previousProperties["LoggingConfig"], { LogFormat: "Text" }),
9326
+ DurableConfig: properties["DurableConfig"]
9230
9327
  };
9231
9328
  await this.lambdaClient.send(new UpdateFunctionConfigurationCommand(configParams));
9232
9329
  this.logger.debug(`Updated configuration for Lambda function ${physicalId}`);
9233
9330
  await this.waitForFunctionUpdated(logicalId, resourceType, physicalId);
9234
9331
  }
9332
+ const newCodeSigningConfigArn = properties["CodeSigningConfigArn"];
9333
+ const codeSigningChanged = newCodeSigningConfigArn !== previousProperties["CodeSigningConfigArn"];
9334
+ if (codeSigningChanged && newCodeSigningConfigArn === void 0) {
9335
+ await this.lambdaClient.send(new DeleteFunctionCodeSigningConfigCommand({ FunctionName: physicalId }));
9336
+ this.logger.debug(`Detached CodeSigningConfigArn from Lambda function ${physicalId} (template removed the property)`);
9337
+ }
9235
9338
  const newCode = properties["Code"];
9236
9339
  const oldCode = previousProperties["Code"];
9237
9340
  const normalizeArchitectures = (v) => Array.isArray(v) && v.length > 0 ? v : ["x86_64"];
@@ -9271,6 +9374,19 @@ var LambdaFunctionProvider = class {
9271
9374
  }));
9272
9375
  this.logger.debug(`Updated ReservedConcurrentExecutions for Lambda function ${physicalId} to ${newReservedConcurrentExecutions}`);
9273
9376
  }
9377
+ if (codeSigningChanged && newCodeSigningConfigArn !== void 0) {
9378
+ await this.lambdaClient.send(new PutFunctionCodeSigningConfigCommand({
9379
+ FunctionName: physicalId,
9380
+ CodeSigningConfigArn: newCodeSigningConfigArn
9381
+ }));
9382
+ this.logger.debug(`Updated CodeSigningConfigArn for Lambda function ${physicalId} to ${newCodeSigningConfigArn}`);
9383
+ }
9384
+ const newRuntimeManagementConfig = properties["RuntimeManagementConfig"];
9385
+ const prevRuntimeManagementConfig = previousProperties["RuntimeManagementConfig"];
9386
+ if (newRuntimeManagementConfig?.["UpdateRuntimeOn"] !== prevRuntimeManagementConfig?.["UpdateRuntimeOn"] || newRuntimeManagementConfig?.["RuntimeVersionArn"] !== prevRuntimeManagementConfig?.["RuntimeVersionArn"]) {
9387
+ await this.putRuntimeManagementConfig(physicalId, newRuntimeManagementConfig ?? { UpdateRuntimeOn: "Auto" });
9388
+ this.logger.debug(`Updated RuntimeManagementConfig for Lambda function ${physicalId} to ${JSON.stringify(newRuntimeManagementConfig ?? { UpdateRuntimeOn: "Auto" })}`);
9389
+ }
9274
9390
  const getResponse = await this.lambdaClient.send(new GetFunctionCommand({ FunctionName: physicalId }));
9275
9391
  const functionArn = getResponse.Configuration?.FunctionArn;
9276
9392
  await this.applyTagDiff(functionArn, previousProperties["Tags"], properties["Tags"]);
@@ -9795,6 +9911,13 @@ var LambdaFunctionProvider = class {
9795
9911
  if (cfg.LoggingConfig.LogGroup !== void 0) lc["LogGroup"] = cfg.LoggingConfig.LogGroup;
9796
9912
  result["LoggingConfig"] = lc;
9797
9913
  }
9914
+ if (cfg.DurableConfig !== void 0) {
9915
+ const dc = {};
9916
+ if (cfg.DurableConfig.ExecutionTimeout !== void 0) dc["ExecutionTimeout"] = cfg.DurableConfig.ExecutionTimeout;
9917
+ if (cfg.DurableConfig.RetentionPeriodInDays !== void 0) dc["RetentionPeriodInDays"] = cfg.DurableConfig.RetentionPeriodInDays;
9918
+ if (Object.keys(dc).length > 0) result["DurableConfig"] = dc;
9919
+ }
9920
+ if (cfg.TenancyConfig?.TenantIsolationMode !== void 0) result["TenancyConfig"] = { TenantIsolationMode: cfg.TenancyConfig.TenantIsolationMode };
9798
9921
  result["Tags"] = normalizeAwsTagsToCfn(resp.Tags);
9799
9922
  try {
9800
9923
  const rlResp = await this.lambdaClient.send(new GetFunctionRecursionConfigCommand({ FunctionName: physicalId }));
@@ -9808,6 +9931,22 @@ var LambdaFunctionProvider = class {
9808
9931
  } catch (pcErr) {
9809
9932
  if (!(pcErr instanceof ResourceNotFoundException)) this.logger.debug(`GetFunctionConcurrency failed for ${physicalId}: ${pcErr instanceof Error ? pcErr.message : String(pcErr)}`);
9810
9933
  }
9934
+ try {
9935
+ const rmResp = await this.lambdaClient.send(new GetRuntimeManagementConfigCommand({ FunctionName: physicalId }));
9936
+ if (rmResp.UpdateRuntimeOn !== void 0) {
9937
+ const rm = { UpdateRuntimeOn: rmResp.UpdateRuntimeOn };
9938
+ if (rmResp.RuntimeVersionArn !== void 0) rm["RuntimeVersionArn"] = rmResp.RuntimeVersionArn;
9939
+ result["RuntimeManagementConfig"] = rm;
9940
+ }
9941
+ } catch (rmErr) {
9942
+ if (!(rmErr instanceof ResourceNotFoundException)) this.logger.warn(`GetRuntimeManagementConfig failed for ${physicalId} — RuntimeManagementConfig omitted from the drift snapshot (may surface as a false removal): ${rmErr instanceof Error ? rmErr.message : String(rmErr)}`);
9943
+ }
9944
+ try {
9945
+ const csResp = await this.lambdaClient.send(new GetFunctionCodeSigningConfigCommand({ FunctionName: physicalId }));
9946
+ if (csResp.CodeSigningConfigArn !== void 0) result["CodeSigningConfigArn"] = csResp.CodeSigningConfigArn;
9947
+ } catch (csErr) {
9948
+ if (!(csErr instanceof ResourceNotFoundException)) this.logger.warn(`GetFunctionCodeSigningConfig failed for ${physicalId} — CodeSigningConfigArn omitted from the drift snapshot (may surface as a false removal): ${csErr instanceof Error ? csErr.message : String(csErr)}`);
9949
+ }
9811
9950
  return result;
9812
9951
  } catch (err) {
9813
9952
  if (err instanceof ResourceNotFoundException) return void 0;
@@ -22323,6 +22462,7 @@ var ApiGatewayV2Provider = class {
22323
22462
  const apiId = properties["ApiId"];
22324
22463
  const integrationType = properties["IntegrationType"];
22325
22464
  if (!apiId || !integrationType) throw new ProvisioningError(`ApiId and IntegrationType are required for API Gateway V2 Integration ${logicalId}`, resourceType, logicalId);
22465
+ this.warnTlsConfigIgnoredIfPublic(logicalId, properties);
22326
22466
  try {
22327
22467
  const integrationId = (await this.getClient().send(new CreateIntegrationCommand({
22328
22468
  ApiId: apiId,
@@ -22491,6 +22631,30 @@ var ApiGatewayV2Provider = class {
22491
22631
  * each uses `properties.ApiId` (passed through PR G's signature
22492
22632
  * extension) to issue the appropriate `Get*` call.
22493
22633
  */
22634
+ /**
22635
+ * `TlsConfig` is meaningful ONLY for a private (VPC-Link) integration.
22636
+ * On a public one (`ConnectionType` absent or `INTERNET`) AWS SILENTLY
22637
+ * IGNORES the field — it is absent from both the `CreateIntegration`
22638
+ * echo and the `GetIntegration` read-back (direct A/B, 2026-08-11
22639
+ * us-east-1) — so the provider can never read it back and a template
22640
+ * that declares it would report permanent phantom drift on the
22641
+ * `properties`-fallback baseline, with `--revert` re-sending a value AWS
22642
+ * discards on every run (issue #1602). The path is scoped by the
22643
+ * resource's own `ConnectionType` via the optional `properties` bag: a
22644
+ * VPC_LINK integration keeps full `TlsConfig` drift coverage (AWS
22645
+ * returns the field there). Without a USABLE properties bag the answer
22646
+ * stays empty — comparing is the safe default, since hiding a private
22647
+ * integration's real `TlsConfig` drift is worse than a false positive on
22648
+ * a caller that could not supply the bag. An EMPTY bag counts as unusable
22649
+ * for the same reason: the caller passes `resource.properties ?? {}`, so
22650
+ * `{}` means "nothing recorded", not "ConnectionType is absent, therefore
22651
+ * public" (an empty bag also has no `TlsConfig` key for the comparator to
22652
+ * walk, so refusing to declare costs nothing).
22653
+ */
22654
+ getDriftUnknownPaths(resourceType, properties) {
22655
+ if (resourceType === "AWS::ApiGatewayV2::Integration" && properties !== void 0 && Object.keys(properties).length > 0 && properties["ConnectionType"] !== "VPC_LINK") return ["TlsConfig"];
22656
+ return [];
22657
+ }
22494
22658
  async readCurrentState(physicalId, _logicalId, resourceType, properties) {
22495
22659
  switch (resourceType) {
22496
22660
  case "AWS::ApiGatewayV2::Api": return this.readApi(physicalId);
@@ -22568,7 +22732,7 @@ var ApiGatewayV2Provider = class {
22568
22732
  if (resp.IntegrationSubtype !== void 0) result["IntegrationSubtype"] = resp.IntegrationSubtype;
22569
22733
  if (resp.PassthroughBehavior !== void 0) result["PassthroughBehavior"] = resp.PassthroughBehavior;
22570
22734
  if (resp.RequestTemplates !== void 0) result["RequestTemplates"] = resp.RequestTemplates;
22571
- if (resp.ResponseParameters !== void 0) result["ResponseParameters"] = this.toCfnResponseParameters(resp.ResponseParameters);
22735
+ if (resp.ResponseParameters !== void 0) result["ResponseParameters"] = this.toCfnResponseParameters(resp.ResponseParameters, properties?.["ResponseParameters"]);
22572
22736
  if (resp.TemplateSelectionExpression !== void 0) result["TemplateSelectionExpression"] = resp.TemplateSelectionExpression;
22573
22737
  if (resp.TlsConfig !== void 0) result["TlsConfig"] = resp.TlsConfig;
22574
22738
  return result;
@@ -22943,6 +23107,7 @@ var ApiGatewayV2Provider = class {
22943
23107
  changed = true;
22944
23108
  }
22945
23109
  if (properties["TlsConfig"] != null && !this.deepEqual(properties["TlsConfig"], previousProperties["TlsConfig"])) {
23110
+ this.warnTlsConfigIgnoredIfPublic(logicalId, properties);
22946
23111
  input.TlsConfig = properties["TlsConfig"];
22947
23112
  changed = true;
22948
23113
  }
@@ -23296,6 +23461,22 @@ var ApiGatewayV2Provider = class {
23296
23461
  return merged;
23297
23462
  }
23298
23463
  /**
23464
+ * Announce a `TlsConfig` that AWS will silently discard (issue #1602):
23465
+ * the field is only honored on a private (VPC-Link) integration, and on a
23466
+ * public one (`ConnectionType` absent or `INTERNET`) AWS accepts the value
23467
+ * and drops it — it never appears on the `GetIntegration` read-back
23468
+ * (direct A/B, 2026-08-11 us-east-1). cdkd still sends the field (parity:
23469
+ * CloudFormation forwards it too and AWS accepts it), but the never-silent
23470
+ * policy requires saying so. The matching drift false positive is closed
23471
+ * by {@link getDriftUnknownPaths}. A WARN on both create and update, never
23472
+ * a throw — the update path can be a state-record replay
23473
+ * (`rollback-executor.ts` / `drift --revert`) where a refusal would leave
23474
+ * the resource un-revertable.
23475
+ */
23476
+ warnTlsConfigIgnoredIfPublic(logicalId, properties) {
23477
+ if (properties["TlsConfig"] != null && properties["ConnectionType"] !== "VPC_LINK") this.logger.warn(`AWS::ApiGatewayV2::Integration ${logicalId}: TlsConfig is only honored on a VPC_LINK (private) integration — AWS silently ignores it on a public one, and the value will never be readable back from AWS (issue #1602).`);
23478
+ }
23479
+ /**
23299
23480
  * `ResponseParameters` is the one `AWS::ApiGatewayV2::Integration` property
23300
23481
  * whose CFn shape does NOT match the SDK's, so forwarding it verbatim is not
23301
23482
  * an option (issue #609). CloudFormation models it as
@@ -23354,26 +23535,87 @@ var ApiGatewayV2Provider = class {
23354
23535
  * baseline carries the CFn list-of-pairs, and every `cdkd drift` run would
23355
23536
  * report permanent phantom drift on a resource nobody touched.
23356
23537
  *
23357
- * The pairs are sorted by `Destination` because this turns an UNORDERED SDK
23358
- * map into an ARRAY, and `calculateResourceDrift` compares arrays
23359
- * POSITIONALLY — AWS does not guarantee map readback order, so an unsorted
23360
- * rebuild would trade the shape-mismatch phantom drift for an ordering one
23361
- * (and `--revert` would re-push an identical value forever). Same reasoning
23362
- * as `src/analyzer/drift-normalize.ts`, applied at the source instead.
23363
- */
23364
- toCfnResponseParameters(value) {
23538
+ * Order matters because this turns an UNORDERED SDK map into an ARRAY, and
23539
+ * `calculateResourceDrift` compares arrays POSITIONALLY AWS does not
23540
+ * guarantee map readback order, so an arbitrary rebuild would trade the
23541
+ * shape-mismatch phantom drift for an ordering one (and `--revert` would
23542
+ * re-push an identical value forever). Declared destinations therefore keep
23543
+ * their DECLARED position and anything else is sorted; both are stable
23544
+ * across reads. Same reasoning as `src/analyzer/drift-normalize.ts`,
23545
+ * applied at the source instead.
23546
+ *
23547
+ * `declared` (the state-recorded desired `ResponseParameters` block, when
23548
+ * the caller has it) makes the inverse MIRROR the template's spelling per
23549
+ * status code (issue #1602): {@link toSdkResponseParameters} accepts an
23550
+ * ALREADY-FLAT block (`{ "<status>": { "<Destination>": "<Source>" } }` —
23551
+ * the SDK spelling a hand-written template may use) and passes it through,
23552
+ * which made the pair non-injective — this method always rebuilt the CFn
23553
+ * list shape, so a flat-spelled baseline could never compare equal to the
23554
+ * read-back and reported permanent phantom drift. For a status code whose
23555
+ * DECLARED block matches the flat-passthrough branch of
23556
+ * {@link toSdkResponseParameters} (an object without an array
23557
+ * `ResponseParameters` member), the read-back now stays flat too; every
23558
+ * other status code (declared CFn shape, declared absent, no `declared` at
23559
+ * all) keeps the CFn list shape. Object comparison is key-based, so the
23560
+ * flat map round-trips without the sort the list shape needs.
23561
+ *
23562
+ * The CFn arm mirrors the declared block too, in the two ways the
23563
+ * `properties`-fallback baseline is compared on: ENTRY ORDER (the
23564
+ * comparator walks arrays positionally, and the template's order is
23565
+ * whatever the author wrote — sorting only the read side is the mistake
23566
+ * `drift-normalize.ts`'s header records) and SCALAR TYPE (CFn types
23567
+ * `Source` as free-form and cdkd coerces a number to a string on the way
23568
+ * out, so re-emitting AWS's string against a numeric declaration is
23569
+ * permanent phantom drift). Declared destinations keep their declared
23570
+ * position and their declared scalar whenever the value still agrees with
23571
+ * AWS; a destination AWS returns that the template never declared is
23572
+ * appended in sorted order, so the result stays deterministic across reads.
23573
+ */
23574
+ toCfnResponseParameters(value, declared) {
23365
23575
  if (value == null) return void 0;
23576
+ const declaredBlocks = declared != null && typeof declared === "object" && !Array.isArray(declared) ? declared : void 0;
23366
23577
  const out = {};
23367
23578
  for (const [statusCode, flat] of Object.entries(value)) {
23368
23579
  if (flat == null || typeof flat !== "object" || Array.isArray(flat)) continue;
23369
- out[statusCode] = { ResponseParameters: Object.entries(flat).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([destination, source]) => ({
23370
- Destination: destination,
23371
- Source: source
23372
- })) };
23580
+ const declaredBlock = declaredBlocks?.[statusCode];
23581
+ const declaredIsBlock = declaredBlock != null && typeof declaredBlock === "object" && !Array.isArray(declaredBlock);
23582
+ const declaredEntries = declaredIsBlock ? declaredBlock["ResponseParameters"] : void 0;
23583
+ if (declaredIsBlock && !Array.isArray(declaredEntries)) {
23584
+ out[statusCode] = flat;
23585
+ continue;
23586
+ }
23587
+ out[statusCode] = { ResponseParameters: this.mirrorDeclaredResponsePairs(flat, declaredEntries) };
23373
23588
  }
23374
23589
  return out;
23375
23590
  }
23376
23591
  /**
23592
+ * Rebuild one status code's CFn list-of-pairs from AWS's flat map, keeping
23593
+ * the DECLARED entries' order and scalar types where they still agree with
23594
+ * AWS. See {@link toCfnResponseParameters} for why both matter.
23595
+ */
23596
+ mirrorDeclaredResponsePairs(flat, declaredEntries) {
23597
+ const remaining = new Map(Object.entries(flat));
23598
+ const pairs = [];
23599
+ if (Array.isArray(declaredEntries)) for (const entry of declaredEntries) {
23600
+ if (entry == null || typeof entry !== "object" || Array.isArray(entry)) continue;
23601
+ const destination = entry["Destination"];
23602
+ if (typeof destination !== "string" || !remaining.has(destination)) continue;
23603
+ const awsSource = remaining.get(destination);
23604
+ remaining.delete(destination);
23605
+ const declaredSource = entry["Source"];
23606
+ const declaredDenotesSame = (typeof declaredSource === "number" || typeof declaredSource === "boolean") && String(declaredSource) === awsSource;
23607
+ pairs.push({
23608
+ Destination: destination,
23609
+ Source: declaredDenotesSame ? declaredSource : awsSource
23610
+ });
23611
+ }
23612
+ for (const [destination, source] of [...remaining.entries()].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) pairs.push({
23613
+ Destination: destination,
23614
+ Source: source
23615
+ });
23616
+ return pairs;
23617
+ }
23618
+ /**
23377
23619
  * Convert CloudFormation Tags (Array<{Key, Value}>) to SDK Tags (Record<string, string>).
23378
23620
  */
23379
23621
  cfnTagsToRecord(tags) {
@@ -51798,7 +52040,7 @@ async function runDriftForStack(stackName, region, stateBackend, providerRegistr
51798
52040
  });
51799
52041
  continue;
51800
52042
  }
51801
- const ignorePaths = provider.getDriftUnknownPaths ? provider.getDriftUnknownPaths(resource.resourceType) : [];
52043
+ const ignorePaths = provider.getDriftUnknownPaths ? provider.getDriftUnknownPaths(resource.resourceType, resource.properties ?? {}) : [];
51802
52044
  const unorderedPaths = provider.getDriftUnorderedPaths ? provider.getDriftUnorderedPaths(resource.resourceType) : [];
51803
52045
  const useObserved = resource.observedProperties !== void 0;
51804
52046
  const baseline = useObserved ? resource.observedProperties : resource.properties ?? {};
@@ -69280,7 +69522,7 @@ function createMigrateCommand() {
69280
69522
  */
69281
69523
  function buildProgram() {
69282
69524
  const program = new Command();
69283
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.15");
69525
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.17");
69284
69526
  program.hook("preAction", (_thisCommand, actionCommand) => {
69285
69527
  const { profile } = actionCommand.optsWithGlobals();
69286
69528
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;