@go-to-k/cdkd 0.231.6 → 0.231.8

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
@@ -8,7 +8,7 @@ import { createHash, randomBytes, randomUUID } from "node:crypto";
8
8
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListBucketsCommand, ListDirectoryBucketsCommand, 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";
9
9
  import { AddRoleToInstanceProfileCommand, AddUserToGroupCommand, AttachGroupPolicyCommand, AttachRolePolicyCommand, AttachUserPolicyCommand, CreateGroupCommand, CreateInstanceProfileCommand, CreateLoginProfileCommand, CreatePolicyCommand, CreatePolicyVersionCommand, CreateUserCommand, DeleteAccessKeyCommand, DeleteGroupCommand, DeleteGroupPolicyCommand, DeleteInstanceProfileCommand, DeleteLoginProfileCommand, DeletePolicyCommand, DeletePolicyVersionCommand, DeleteRolePolicyCommand, DeleteUserCommand, DeleteUserPermissionsBoundaryCommand, DeleteUserPolicyCommand, DetachGroupPolicyCommand, DetachRolePolicyCommand, DetachUserPolicyCommand, GetGroupCommand, GetGroupPolicyCommand, GetInstanceProfileCommand, GetPolicyCommand, GetPolicyVersionCommand, GetRolePolicyCommand, GetUserCommand, GetUserPolicyCommand, IAMClient, ListAccessKeysCommand, ListAttachedGroupPoliciesCommand, ListAttachedUserPoliciesCommand, ListEntitiesForPolicyCommand, ListGroupPoliciesCommand, ListGroupsForUserCommand, ListInstanceProfilesCommand, ListPoliciesCommand, ListPolicyTagsCommand, ListPolicyVersionsCommand, ListUserPoliciesCommand, ListUserTagsCommand, ListUsersCommand, NoSuchEntityException, PutGroupPolicyCommand, PutRolePolicyCommand, PutUserPermissionsBoundaryCommand, PutUserPolicyCommand, RemoveRoleFromInstanceProfileCommand, RemoveUserFromGroupCommand, TagPolicyCommand, TagUserCommand, UntagPolicyCommand, UntagUserCommand, UpdateLoginProfileCommand } from "@aws-sdk/client-iam";
10
10
  import { CreateQueueCommand, DeleteQueueCommand, GetQueueAttributesCommand, GetQueueUrlCommand, ListQueueTagsCommand, ListQueuesCommand, QueueDoesNotExist, SQSClient, SetQueueAttributesCommand, TagQueueCommand, UntagQueueCommand } from "@aws-sdk/client-sqs";
11
- import { CreateTopicCommand, DeleteTopicCommand, GetSubscriptionAttributesCommand, GetTopicAttributesCommand, ListTagsForResourceCommand, ListTopicsCommand, NotFoundException, SNSClient, SetTopicAttributesCommand, SubscribeCommand, TagResourceCommand, UnsubscribeCommand, UntagResourceCommand } from "@aws-sdk/client-sns";
11
+ import { CreateTopicCommand, DeleteTopicCommand, GetSubscriptionAttributesCommand, GetTopicAttributesCommand, ListSubscriptionsByTopicCommand, ListTagsForResourceCommand, ListTopicsCommand, NotFoundException, SNSClient, SetTopicAttributesCommand, SubscribeCommand, TagResourceCommand, UnsubscribeCommand, UntagResourceCommand } from "@aws-sdk/client-sns";
12
12
  import { AddPermissionCommand, CreateEventSourceMappingCommand, CreateFunctionCommand, CreateFunctionUrlConfigCommand, DeleteEventSourceMappingCommand, DeleteFunctionCommand, DeleteFunctionConcurrencyCommand, DeleteFunctionEventInvokeConfigCommand, DeleteFunctionUrlConfigCommand, DeleteLayerVersionCommand, GetEventSourceMappingCommand, GetFunctionCommand, GetFunctionConcurrencyCommand, GetFunctionEventInvokeConfigCommand, GetFunctionRecursionConfigCommand, GetFunctionUrlConfigCommand, GetLayerVersionByArnCommand, GetPolicyCommand as GetPolicyCommand$1, LambdaClient, ListFunctionsCommand, ListLayersCommand, 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";
13
13
  import { AssumeRoleCommand, GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
14
14
  import { 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, DescribeAvailabilityZonesCommand, DescribeIamInstanceProfileAssociationsCommand, DescribeInstanceAttributeCommand, DescribeInstanceCreditSpecificationsCommand, DescribeInstancesCommand, DescribeInternetGatewaysCommand, DescribeNatGatewaysCommand, DescribeNetworkAclsCommand, DescribeNetworkInterfacesCommand, DescribeRouteTablesCommand, DescribeSecurityGroupsCommand, DescribeSubnetsCommand, DescribeVolumesCommand, DescribeVpcAttributeCommand, DescribeVpcsCommand, DetachInternetGatewayCommand, DisassociateRouteTableCommand, EC2Client, ModifyInstanceAttributeCommand, ModifyInstanceCreditSpecificationCommand, ModifyInstanceMetadataOptionsCommand, ModifySubnetAttributeCommand, ModifyVpcAttributeCommand, MonitorInstancesCommand, ReplaceNetworkAclAssociationCommand, RevokeSecurityGroupEgressCommand, RevokeSecurityGroupIngressCommand, RunInstancesCommand, TerminateInstancesCommand, UnmonitorInstancesCommand, waitUntilInstanceRunning, waitUntilInstanceTerminated, waitUntilNatGatewayAvailable, waitUntilNatGatewayDeleted } from "@aws-sdk/client-ec2";
@@ -1445,7 +1445,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1445
1445
  const FLUSH_EVENT_THRESHOLD = 50;
1446
1446
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1447
1447
  function getCdkdVersion() {
1448
- return "0.231.6";
1448
+ return "0.231.8";
1449
1449
  }
1450
1450
  /**
1451
1451
  * Generate a time-sortable unique run id, e.g.
@@ -7021,6 +7021,10 @@ var SNSTopicProvider = class {
7021
7021
  }));
7022
7022
  }
7023
7023
  }
7024
+ if (Array.isArray(properties["Subscription"])) {
7025
+ const subscriptions = properties["Subscription"];
7026
+ for (const sub of subscriptions) await this.subscribeInline(topicArn, sub, logicalId);
7027
+ }
7024
7028
  } catch (innerError) {
7025
7029
  try {
7026
7030
  await this.snsClient.send(new DeleteTopicCommand({ TopicArn: topicArn }));
@@ -7123,6 +7127,7 @@ var SNSTopicProvider = class {
7123
7127
  }));
7124
7128
  }
7125
7129
  }
7130
+ if (JSON.stringify(properties["Subscription"]) !== JSON.stringify(previousProperties["Subscription"])) await this.reconcileInlineSubscriptions(physicalId, previousProperties["Subscription"] || [], properties["Subscription"] || [], logicalId);
7126
7131
  const newTags = properties["Tags"];
7127
7132
  const oldTags = previousProperties["Tags"];
7128
7133
  if (JSON.stringify(newTags) !== JSON.stringify(oldTags)) {
@@ -7149,6 +7154,81 @@ var SNSTopicProvider = class {
7149
7154
  };
7150
7155
  }
7151
7156
  /**
7157
+ * Subscribe a single inline `Subscription` entry to the topic.
7158
+ *
7159
+ * Each entry carries at least `Protocol` + `Endpoint` (the two required CFn
7160
+ * fields). Documented optional subscription attributes that are settable at
7161
+ * subscribe time are passed through the `Subscribe` `Attributes` map
7162
+ * (`RawMessageDelivery`, `FilterPolicy`, `FilterPolicyScope`, `RedrivePolicy`,
7163
+ * `DeliveryPolicy`, `ReplayPolicy`, `SubscriptionRoleArn`). Object-valued
7164
+ * attributes (policies) are JSON-stringified; everything else is stringified
7165
+ * verbatim — AWS's `SubscribeCommand` accepts `Attributes` as a
7166
+ * `Record<string,string>`.
7167
+ */
7168
+ async subscribeInline(topicArn, sub, logicalId) {
7169
+ const protocol = sub["Protocol"];
7170
+ const endpoint = sub["Endpoint"];
7171
+ if (typeof protocol !== "string" || typeof endpoint !== "string") throw new Error(`SNS topic ${logicalId}: inline Subscription entry requires string Protocol and Endpoint, got ${JSON.stringify(sub)}`);
7172
+ const attributes = buildSubscriptionAttributes(sub);
7173
+ const input = {
7174
+ TopicArn: topicArn,
7175
+ Protocol: protocol,
7176
+ Endpoint: endpoint,
7177
+ ReturnSubscriptionArn: true,
7178
+ ...Object.keys(attributes).length > 0 && { Attributes: attributes }
7179
+ };
7180
+ await this.snsClient.send(new SubscribeCommand(input));
7181
+ this.logger.debug(`Subscribed ${protocol}:${endpoint} to topic ${topicArn} for ${logicalId}`);
7182
+ }
7183
+ /**
7184
+ * Reconcile the inline `Subscription` list on an UPDATE: add entries present
7185
+ * in the new list but not the old, and unsubscribe entries present in the
7186
+ * old list but not the new. Identity is `(Protocol, Endpoint)`.
7187
+ *
7188
+ * Removals need the live `SubscriptionArn`, which the template does not
7189
+ * carry — resolve it via `ListSubscriptionsByTopic` (paginated). A removed
7190
+ * entry whose subscription is still `PendingConfirmation` (never confirmed)
7191
+ * has no ARN to unsubscribe and is skipped with a debug log.
7192
+ *
7193
+ * KNOWN LIMITATION: identity is `(Protocol, Endpoint)` only, so an
7194
+ * attribute-only change on an UNCHANGED endpoint (e.g. editing `FilterPolicy`
7195
+ * / `RawMessageDelivery` while keeping the same protocol+endpoint) is neither
7196
+ * an add nor a remove and is therefore NOT re-applied here — it would need a
7197
+ * `SetSubscriptionAttributes` pass. CloudFormation updates those in place.
7198
+ * The primary #980 silent-drop (create / add / remove / drift) is fixed; the
7199
+ * attribute-only in-place update is a deliberately-scoped follow-up.
7200
+ */
7201
+ async reconcileInlineSubscriptions(topicArn, oldSubs, newSubs, logicalId) {
7202
+ const key = (protocol, endpoint) => `${String(protocol)}${String(endpoint)}`;
7203
+ const oldKeys = new Set(oldSubs.map((s) => key(s["Protocol"], s["Endpoint"])));
7204
+ const newKeys = new Set(newSubs.map((s) => key(s["Protocol"], s["Endpoint"])));
7205
+ for (const sub of newSubs) if (!oldKeys.has(key(sub["Protocol"], sub["Endpoint"]))) await this.subscribeInline(topicArn, sub, logicalId);
7206
+ const removed = oldSubs.filter((s) => !newKeys.has(key(s["Protocol"], s["Endpoint"])));
7207
+ if (removed.length === 0) return;
7208
+ const arnByKey = /* @__PURE__ */ new Map();
7209
+ let nextToken;
7210
+ do {
7211
+ const resp = await this.snsClient.send(new ListSubscriptionsByTopicCommand({
7212
+ TopicArn: topicArn,
7213
+ ...nextToken && { NextToken: nextToken }
7214
+ }));
7215
+ for (const s of resp.Subscriptions ?? []) {
7216
+ if (!s.SubscriptionArn || s.SubscriptionArn === "PendingConfirmation") continue;
7217
+ arnByKey.set(key(s.Protocol, s.Endpoint), s.SubscriptionArn);
7218
+ }
7219
+ nextToken = resp.NextToken;
7220
+ } while (nextToken);
7221
+ for (const sub of removed) {
7222
+ const arn = arnByKey.get(key(sub["Protocol"], sub["Endpoint"]));
7223
+ if (!arn) {
7224
+ this.logger.debug(`No confirmed SubscriptionArn for ${String(sub["Protocol"])}:${String(sub["Endpoint"])} on topic ${topicArn} — skipping unsubscribe`);
7225
+ continue;
7226
+ }
7227
+ await this.snsClient.send(new UnsubscribeCommand({ SubscriptionArn: arn }));
7228
+ this.logger.debug(`Unsubscribed ${arn} from topic ${topicArn} for ${logicalId}`);
7229
+ }
7230
+ }
7231
+ /**
7152
7232
  * Delete an SNS topic
7153
7233
  */
7154
7234
  async delete(logicalId, physicalId, resourceType, _properties, context) {
@@ -7217,8 +7297,12 @@ var SNSTopicProvider = class {
7217
7297
  * comparator would fire false drift on every clean run for any
7218
7298
  * lowercase-`Protocol` template.
7219
7299
  *
7220
- * `Subscription` is omitted because CDK manages it via separate
7221
- * `AWS::SNS::Subscription` resources, not as a Topic property.
7300
+ * `Subscription` is reverse-mapped from `ListSubscriptionsByTopic` ONLY
7301
+ * when the passed-in `properties` recorded an inline `Subscription` list
7302
+ * (issue #980) — L1 `CfnTopic` / migrated CloudFormation. A Topic whose
7303
+ * subscriptions are separate `AWS::SNS::Subscription` resources (CDK L2
7304
+ * `addSubscription()`) has no inline list in state, so its subscriptions
7305
+ * are not surfaced here (they belong to sibling resources).
7222
7306
  *
7223
7307
  * Returns `undefined` when the topic is gone (`NotFoundException`).
7224
7308
  */
@@ -7260,16 +7344,38 @@ var SNSTopicProvider = class {
7260
7344
  if (err instanceof NotFoundException) return void 0;
7261
7345
  throw err;
7262
7346
  }
7347
+ if (Array.isArray(properties?.["Subscription"])) {
7348
+ const subs = [];
7349
+ let nextToken;
7350
+ do {
7351
+ const resp = await this.snsClient.send(new ListSubscriptionsByTopicCommand({
7352
+ TopicArn: physicalId,
7353
+ ...nextToken && { NextToken: nextToken }
7354
+ }));
7355
+ for (const s of resp.Subscriptions ?? []) {
7356
+ if (!s.Protocol || !s.Endpoint) continue;
7357
+ subs.push({
7358
+ Protocol: s.Protocol,
7359
+ Endpoint: s.Endpoint
7360
+ });
7361
+ }
7362
+ nextToken = resp.NextToken;
7363
+ } while (nextToken);
7364
+ subs.sort((a, b) => `${String(a["Protocol"])} ${String(a["Endpoint"])}`.localeCompare(`${String(b["Protocol"])} ${String(b["Endpoint"])}`));
7365
+ result["Subscription"] = subs;
7366
+ }
7263
7367
  return result;
7264
7368
  }
7265
7369
  /**
7266
- * Only `Subscription` remains drift-unknown CDK manages topic
7267
- * subscriptions via separate `AWS::SNS::Subscription` resources, so the
7268
- * inline `Topic.Subscription` property is intentionally not surfaced.
7269
- * `DeliveryStatusLogging` is now reverse-mapped (see `readCurrentState`).
7370
+ * No drift-unknown paths remain. `DeliveryStatusLogging` is reverse-mapped
7371
+ * (see `readCurrentState`), and the inline `Subscription` list is now
7372
+ * reverse-mapped too (issue #980) but only when state actually recorded
7373
+ * inline subscriptions, so a Topic whose subscriptions are managed as
7374
+ * separate `AWS::SNS::Subscription` resources (CDK L2 `addSubscription()`)
7375
+ * does not surface them here.
7270
7376
  */
7271
7377
  getDriftUnknownPaths() {
7272
- return ["Subscription"];
7378
+ return [];
7273
7379
  }
7274
7380
  /**
7275
7381
  * Adopt an existing SNS topic into cdkd state.
@@ -7320,6 +7426,30 @@ var SNSTopicProvider = class {
7320
7426
  return null;
7321
7427
  }
7322
7428
  };
7429
+ const SNS_SUBSCRIPTION_ATTRIBUTE_KEYS = [
7430
+ "RawMessageDelivery",
7431
+ "FilterPolicy",
7432
+ "FilterPolicyScope",
7433
+ "RedrivePolicy",
7434
+ "DeliveryPolicy",
7435
+ "ReplayPolicy",
7436
+ "SubscriptionRoleArn"
7437
+ ];
7438
+ /**
7439
+ * Build the SNS `Subscribe` `Attributes` map from an inline `Subscription`
7440
+ * entry, skipping the required `Protocol` / `Endpoint` fields. Undefined /
7441
+ * null values are omitted; object values (policy documents) are
7442
+ * JSON-stringified; scalars are `String()`-coerced.
7443
+ */
7444
+ function buildSubscriptionAttributes(sub) {
7445
+ const attributes = {};
7446
+ for (const key of SNS_SUBSCRIPTION_ATTRIBUTE_KEYS) {
7447
+ const value = sub[key];
7448
+ if (value === void 0 || value === null) continue;
7449
+ attributes[key] = typeof value === "object" ? JSON.stringify(value) : String(value);
7450
+ }
7451
+ return attributes;
7452
+ }
7323
7453
  const SNS_DELIVERY_STATUS_PROTOCOLS = [
7324
7454
  "Application",
7325
7455
  "Firehose",
@@ -20131,9 +20261,9 @@ var StepFunctionsProvider = class {
20131
20261
  this.logger.debug(`Updating Step Functions state machine ${logicalId}: ${physicalId}`);
20132
20262
  try {
20133
20263
  const definitionString = await this.buildDefinitionString(properties);
20134
- const encryptionConfiguration = mapEncryptionConfiguration(properties["EncryptionConfiguration"]);
20135
- const loggingConfiguration = mapLoggingConfiguration(properties["LoggingConfiguration"]);
20136
- const tracingConfiguration = mapTracingConfiguration(properties["TracingConfiguration"]);
20264
+ const encryptionConfiguration = mapEncryptionConfiguration(properties["EncryptionConfiguration"]) ?? disabledEncryptionConfigurationOnRemoval(previousProperties["EncryptionConfiguration"], properties["EncryptionConfiguration"]);
20265
+ const loggingConfiguration = mapLoggingConfiguration(properties["LoggingConfiguration"]) ?? disabledLoggingConfigurationOnRemoval(previousProperties["LoggingConfiguration"], properties["LoggingConfiguration"]);
20266
+ const tracingConfiguration = mapTracingConfiguration(properties["TracingConfiguration"]) ?? disabledTracingConfigurationOnRemoval(previousProperties["TracingConfiguration"], properties["TracingConfiguration"]);
20137
20267
  await this.getClient().send(new UpdateStateMachineCommand({
20138
20268
  stateMachineArn: physicalId,
20139
20269
  definition: definitionString,
@@ -20457,6 +20587,59 @@ function mapTracingConfiguration(value) {
20457
20587
  if (cfg["Enabled"] === void 0) return void 0;
20458
20588
  return { enabled: cfg["Enabled"] };
20459
20589
  }
20590
+ /**
20591
+ * Return the SDK disable payload for `EncryptionConfiguration` when it was
20592
+ * present+configured in the previous properties but is absent/placeholder in
20593
+ * the new ones; otherwise `undefined` (no clear needed). `AWS_OWNED_KEY` is
20594
+ * the AWS default, so this resets a customer-managed-key config back to default.
20595
+ */
20596
+ function disabledEncryptionConfigurationOnRemoval(previous, next) {
20597
+ if (!wasMeaningfullyConfigured(previous, "Type")) return void 0;
20598
+ if (mapEncryptionConfiguration(next) !== void 0) return void 0;
20599
+ return { type: "AWS_OWNED_KEY" };
20600
+ }
20601
+ /**
20602
+ * Return the SDK disable payload for `LoggingConfiguration` when it was
20603
+ * present+configured in the previous properties but is absent/placeholder in
20604
+ * the new ones; otherwise `undefined`. `level: OFF` disables logging;
20605
+ * `destinations: []` clears the log destinations (only required when level is
20606
+ * not OFF, so an empty list is accepted alongside OFF).
20607
+ */
20608
+ function disabledLoggingConfigurationOnRemoval(previous, next) {
20609
+ if (!wasMeaningfullyConfigured(previous, "Level")) return void 0;
20610
+ if (mapLoggingConfiguration(next) !== void 0) return void 0;
20611
+ return {
20612
+ level: "OFF",
20613
+ includeExecutionData: false,
20614
+ destinations: []
20615
+ };
20616
+ }
20617
+ /**
20618
+ * Return the SDK disable payload for `TracingConfiguration` when it was
20619
+ * present+enabled in the previous properties but is absent/placeholder in the
20620
+ * new ones; otherwise `undefined`. `enabled: false` turns X-Ray tracing off.
20621
+ *
20622
+ * Unlike logging/encryption, the "meaningful" signal here is `Enabled === true`
20623
+ * (a previous `{ Enabled: false }` is already the AWS default, so there is
20624
+ * nothing to clear).
20625
+ */
20626
+ function disabledTracingConfigurationOnRemoval(previous, next) {
20627
+ if (previous === null || typeof previous !== "object") return void 0;
20628
+ if (previous["Enabled"] !== true) return void 0;
20629
+ if (mapTracingConfiguration(next) !== void 0) return void 0;
20630
+ return { enabled: false };
20631
+ }
20632
+ /**
20633
+ * True when `value` is an object that carries a defined `discriminatorKey`
20634
+ * field (`Level` for logging, `Type` for encryption) — i.e. it was a real,
20635
+ * non-placeholder config in the previous properties. The empty-placeholder
20636
+ * shape `{}` that `readCurrentState` emits has no discriminator, so it returns
20637
+ * false and no clear is emitted.
20638
+ */
20639
+ function wasMeaningfullyConfigured(value, discriminatorKey) {
20640
+ if (value === null || typeof value !== "object") return false;
20641
+ return value[discriminatorKey] !== void 0;
20642
+ }
20460
20643
 
20461
20644
  //#endregion
20462
20645
  //#region src/provisioning/providers/ecs-provider.ts
@@ -55594,7 +55777,7 @@ function reorderArgs(argv) {
55594
55777
  async function main() {
55595
55778
  installPipeCloseHandler();
55596
55779
  const program = new Command();
55597
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.231.6");
55780
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.231.8");
55598
55781
  program.addCommand(createBootstrapCommand());
55599
55782
  program.addCommand(createSynthCommand());
55600
55783
  program.addCommand(createListCommand());