@go-to-k/cdkd 0.280.46 → 0.280.47

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-E_JV4UqE.js";
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-fs0W4o1b.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-DGHuyUA8.js";
4
+ import { t as ASGProvider } from "./asg-provider-CemPPnK2.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";
@@ -4875,6 +4875,20 @@ function s3BucketDestinationPath(dest, destinationPath) {
4875
4875
  return isPlainObject$1(dest) && isFlattenedDestination(dest) ? destinationPath : `${destinationPath}.S3BucketDestination`;
4876
4876
  }
4877
4877
  /**
4878
+ * The structural path segments — relative to the enclosing `Destination` block —
4879
+ * of the bag `resolveS3BucketDestination` PICKED, so a substituted value can be
4880
+ * written back at the key the template actually declared (issue #1670).
4881
+ *
4882
+ * The value-side twin of {@link s3BucketDestinationPath}, which names the same
4883
+ * branch for MESSAGES. Derived from the picked bag's IDENTITY rather than by
4884
+ * re-running {@link isFlattenedDestination}: a third copy of that branch
4885
+ * condition is exactly what the predicate's own header warns about, and identity
4886
+ * cannot drift from the resolver at all.
4887
+ */
4888
+ function s3BucketDestinationSegments(declared, picked) {
4889
+ return picked === declared ? [] : ["S3BucketDestination"];
4890
+ }
4891
+ /**
4878
4892
  * Name a malformed value in a refusal message, the way `config-shape.ts`'s
4879
4893
  * private `describe` does for the string-reading guards. Kept local rather than
4880
4894
  * exported from there because `resolveS3BucketDestination` is S3-specific
@@ -5129,6 +5143,35 @@ var S3BucketProvider = class S3BucketProvider {
5129
5143
  return true;
5130
5144
  }
5131
5145
  /**
5146
+ * A string read whose replay downgrade is a warn-and-SUBSTITUTE, reporting
5147
+ * the substitution so the caller can record what was SENT (issue #1670).
5148
+ *
5149
+ * The third shape beside {@link skipOnUnusableConfigString}'s SKIP and the
5150
+ * plain strict read, for the sites where the fallback IS the right value to
5151
+ * send. The deploy then succeeds with the default on the wire, so recording
5152
+ * the declared value describes a configuration AWS does not hold, and
5153
+ * `readCurrentState` reads all of these back — the permanent phantom drift
5154
+ * `.claude/rules/providers.md` records for the #1633 warn-and-default arm.
5155
+ * That file also carries the full rationale, including why these sites take
5156
+ * NO `canonicalizeDesiredProperties` twin; do not re-derive it here.
5157
+ *
5158
+ * Three details are load-bearing:
5159
+ *
5160
+ * - `onSubstituted` receives the value this call RETURNS, not the `fallback`
5161
+ * argument, so "what is recorded" and "what is sent" stay one expression.
5162
+ * - `options` is forwarded to BOTH the probe and the read, so a site that
5163
+ * ever needs `coerceNumber` cannot make the two disagree.
5164
+ * - Without `options.onUnusable` there is no probe: the read still THROWS,
5165
+ * and recording a value the provider merely failed to send is what the
5166
+ * "already ANNOUNCED" condition on `effectiveProperties` forbids.
5167
+ */
5168
+ readSubstitutedConfigString(container, key, fallback, containerPath, options, onSubstituted) {
5169
+ const refused = options.onUnusable !== void 0 && configStringRefusal(container, key, fallback, containerPath, options) !== void 0;
5170
+ const value = readConfigString(container, key, fallback, containerPath, options);
5171
+ if (refused) onSubstituted(value);
5172
+ return value;
5173
+ }
5174
+ /**
5132
5175
  * Apply lifecycle configuration
5133
5176
  *
5134
5177
  * CFn property: LifecycleConfiguration.Rules[]
@@ -5457,8 +5500,11 @@ var S3BucketProvider = class S3BucketProvider {
5457
5500
  * CFn property: MetricsConfigurations[] (array of configurations)
5458
5501
  * SDK: PutBucketMetricsConfiguration (one per configuration, keyed by Id)
5459
5502
  *
5460
- * @returns the indexes (into `configs`) of the items a replay downgrade
5461
- * SKIPPED — the per-item unit of `effectiveProperties` (issue #1612).
5503
+ * @returns what happened to each item, as {@link PerItemApplyOutcome} the
5504
+ * per-item unit of `effectiveProperties` (issue #1612). This applier has no
5505
+ * warn-and-SUBSTITUTE read, so its `substituted` map is always empty; the
5506
+ * shape is shared with its three siblings so the two call-site recorders
5507
+ * stay uniform and a future substitution here cannot go unrecorded.
5462
5508
  */
5463
5509
  async applyMetricsConfigurations(bucketName, configs, onUnusable) {
5464
5510
  const skipped = [];
@@ -5490,7 +5536,10 @@ var S3BucketProvider = class S3BucketProvider {
5490
5536
  }));
5491
5537
  }
5492
5538
  this.logger.debug(`Applied ${configs.length - skipped.length} metrics configuration(s) to bucket ${bucketName}`);
5493
- return skipped;
5539
+ return {
5540
+ skipped,
5541
+ substituted: /* @__PURE__ */ new Map()
5542
+ };
5494
5543
  }
5495
5544
  /**
5496
5545
  * Pick the `S3BucketDestination` bag out of an analytics / inventory
@@ -5547,15 +5596,24 @@ var S3BucketProvider = class S3BucketProvider {
5547
5596
  * CFn property: AnalyticsConfigurations[] (array of configurations)
5548
5597
  * SDK: PutBucketAnalyticsConfiguration (one per configuration, keyed by Id)
5549
5598
  *
5550
- * @returns the indexes (into `configs`) of the items a replay downgrade
5551
- * SKIPPED — the per-item unit of `effectiveProperties` (issue #1612).
5599
+ * @returns what happened to each item, as {@link PerItemApplyOutcome} the
5600
+ * per-item unit of `effectiveProperties` (issues #1612 / #1670). Both arms
5601
+ * are reachable here: a container / destination guard SKIPS the item, while
5602
+ * the `OutputSchemaVersion` and destination `Format` reads warn and SEND a
5603
+ * substituted default, so the item is recorded as SENT rather than as
5604
+ * declared.
5552
5605
  */
5553
5606
  async applyAnalyticsConfigurations(bucketName, configs, onUnusable) {
5554
5607
  const skipped = [];
5608
+ const substituted = /* @__PURE__ */ new Map();
5555
5609
  let index = -1;
5556
5610
  for (const config of configs) {
5557
5611
  index += 1;
5558
5612
  const id = config["Id"];
5613
+ let sentItem;
5614
+ const recordSubstitution = (path, sent) => {
5615
+ sentItem = S3BucketProvider.withDeepValue(sentItem ?? config, path, sent);
5616
+ };
5559
5617
  const rawStorageClassAnalysis = config["StorageClassAnalysis"];
5560
5618
  if (rawStorageClassAnalysis != null && requireConfigObject(rawStorageClassAnalysis, "AWS::S3::Bucket AnalyticsConfigurations[].StorageClassAnalysis", { ...onUnusable ? { onUnusable } : {} }) === void 0) {
5561
5619
  skipped.push(index);
@@ -5594,12 +5652,23 @@ var S3BucketProvider = class S3BucketProvider {
5594
5652
  continue;
5595
5653
  }
5596
5654
  const destPath = s3BucketDestinationPath(rawDest, analyticsDestPath);
5655
+ const destSegments = s3Dest ? s3BucketDestinationSegments(rawDest, s3Dest) : [];
5597
5656
  analyticsConfig.StorageClassAnalysis = { DataExport: {
5598
- OutputSchemaVersion: readConfigString(dataExport, "OutputSchemaVersion", "V_1", "AWS::S3::Bucket AnalyticsConfigurations[].StorageClassAnalysis.DataExport", { ...onUnusable ? { onUnusable } : {} }),
5657
+ OutputSchemaVersion: this.readSubstitutedConfigString(dataExport, "OutputSchemaVersion", "V_1", "AWS::S3::Bucket AnalyticsConfigurations[].StorageClassAnalysis.DataExport", { ...onUnusable ? { onUnusable } : {} }, (sent) => recordSubstitution([
5658
+ "StorageClassAnalysis",
5659
+ "DataExport",
5660
+ "OutputSchemaVersion"
5661
+ ], sent)),
5599
5662
  Destination: s3Dest ? { S3BucketDestination: {
5600
5663
  Bucket: s3Dest["BucketArn"] ?? s3Dest["Bucket"],
5601
5664
  BucketAccountId: s3Dest["BucketAccountId"],
5602
- Format: readConfigString(s3Dest, "Format", "CSV", destPath, { ...onUnusable ? { onUnusable } : {} }),
5665
+ Format: this.readSubstitutedConfigString(s3Dest, "Format", "CSV", destPath, { ...onUnusable ? { onUnusable } : {} }, (sent) => recordSubstitution([
5666
+ "StorageClassAnalysis",
5667
+ "DataExport",
5668
+ "Destination",
5669
+ ...destSegments,
5670
+ "Format"
5671
+ ], sent)),
5603
5672
  Prefix: s3Dest["Prefix"]
5604
5673
  } } : void 0
5605
5674
  } };
@@ -5609,9 +5678,13 @@ var S3BucketProvider = class S3BucketProvider {
5609
5678
  Id: id,
5610
5679
  AnalyticsConfiguration: analyticsConfig
5611
5680
  }));
5681
+ if (sentItem !== void 0) substituted.set(index, sentItem);
5612
5682
  }
5613
5683
  this.logger.debug(`Applied ${configs.length - skipped.length} analytics configuration(s) to bucket ${bucketName}`);
5614
- return skipped;
5684
+ return {
5685
+ skipped,
5686
+ substituted
5687
+ };
5615
5688
  }
5616
5689
  /**
5617
5690
  * Apply intelligent tiering configurations
@@ -5619,8 +5692,11 @@ var S3BucketProvider = class S3BucketProvider {
5619
5692
  * CFn property: IntelligentTieringConfigurations[]
5620
5693
  * SDK: PutBucketIntelligentTieringConfiguration (one per configuration, keyed by Id)
5621
5694
  *
5622
- * @returns the indexes (into `configs`) of the items a replay downgrade
5623
- * SKIPPED — the per-item unit of `effectiveProperties` (issue #1612).
5695
+ * @returns what happened to each item, as {@link PerItemApplyOutcome} the
5696
+ * per-item unit of `effectiveProperties` (issue #1612). Its per-item
5697
+ * `Status` read takes the SKIP downgrade rather than a substitution (issue
5698
+ * #1595 — defaulting to `Enabled` would start archiving objects), so the
5699
+ * `substituted` map is always empty here.
5624
5700
  */
5625
5701
  async applyIntelligentTieringConfigurations(bucketName, configs, onUnusable) {
5626
5702
  const skipped = [];
@@ -5661,7 +5737,10 @@ var S3BucketProvider = class S3BucketProvider {
5661
5737
  }));
5662
5738
  }
5663
5739
  this.logger.debug(`Applied ${configs.length - skipped.length} intelligent tiering configuration(s) to bucket ${bucketName}`);
5664
- return skipped;
5740
+ return {
5741
+ skipped,
5742
+ substituted: /* @__PURE__ */ new Map()
5743
+ };
5665
5744
  }
5666
5745
  /**
5667
5746
  * Apply inventory configurations
@@ -5669,11 +5748,15 @@ var S3BucketProvider = class S3BucketProvider {
5669
5748
  * CFn property: InventoryConfigurations[]
5670
5749
  * SDK: PutBucketInventoryConfiguration (one per configuration, keyed by Id)
5671
5750
  *
5672
- * @returns the indexes (into `configs`) of the items a replay downgrade
5673
- * SKIPPED — the per-item unit of `effectiveProperties` (issue #1612).
5751
+ * @returns what happened to each item, as {@link PerItemApplyOutcome} the
5752
+ * per-item unit of `effectiveProperties` (issues #1612 / #1670). Both arms
5753
+ * are reachable here: `IncludedObjectVersions` / the schedule frequency pair
5754
+ * / the destination guard SKIP the item, while the destination `Format` read
5755
+ * warns and SENDS a substituted default.
5674
5756
  */
5675
5757
  async applyInventoryConfigurations(bucketName, configs, onUnusable) {
5676
5758
  const skipped = [];
5759
+ const substituted = /* @__PURE__ */ new Map();
5677
5760
  let index = -1;
5678
5761
  for (const config of configs) {
5679
5762
  index += 1;
@@ -5690,6 +5773,11 @@ var S3BucketProvider = class S3BucketProvider {
5690
5773
  continue;
5691
5774
  }
5692
5775
  const destPath = s3BucketDestinationPath(rawDest, inventoryDestPath);
5776
+ const destSegments = s3Dest ? s3BucketDestinationSegments(rawDest, s3Dest) : [];
5777
+ let sentItem;
5778
+ const recordSubstitution = (path, sent) => {
5779
+ sentItem = S3BucketProvider.withDeepValue(sentItem ?? config, path, sent);
5780
+ };
5693
5781
  const scheduleFrequencyRefusal = onUnusable ? configStringRefusal(config, "ScheduleFrequency", "Weekly", "AWS::S3::Bucket InventoryConfigurations[]") : void 0;
5694
5782
  if (scheduleFrequencyRefusal !== void 0 && config["Schedule"] == null) {
5695
5783
  onUnusable?.(`${scheduleFrequencyRefusal}. Skipping this inventory configuration: there is no Schedule.Frequency to fall back to, and defaulting to Weekly would silently re-cadence a live inventory report; the same value is REFUSED on a template-path create`);
@@ -5703,6 +5791,7 @@ var S3BucketProvider = class S3BucketProvider {
5703
5791
  continue;
5704
5792
  }
5705
5793
  const frequency = useScheduleFrequency ? requireConfigString(config["ScheduleFrequency"], "Weekly", "AWS::S3::Bucket InventoryConfigurations[].ScheduleFrequency") : readConfigString(config["Schedule"], "Frequency", "Weekly", "AWS::S3::Bucket InventoryConfigurations[].Schedule");
5794
+ if (scheduleFrequencyRefusal !== void 0) recordSubstitution(["ScheduleFrequency"], frequency);
5706
5795
  const inventoryConfig = {
5707
5796
  Id: id,
5708
5797
  IsEnabled: config["Enabled"] ?? true,
@@ -5711,7 +5800,11 @@ var S3BucketProvider = class S3BucketProvider {
5711
5800
  Destination: { S3BucketDestination: s3Dest ? {
5712
5801
  Bucket: s3Dest["BucketArn"] ?? s3Dest["Bucket"],
5713
5802
  AccountId: s3Dest["BucketAccountId"],
5714
- Format: readConfigString(s3Dest, "Format", "CSV", destPath, { ...onUnusable ? { onUnusable } : {} }),
5803
+ Format: this.readSubstitutedConfigString(s3Dest, "Format", "CSV", destPath, { ...onUnusable ? { onUnusable } : {} }, (sent) => recordSubstitution([
5804
+ "Destination",
5805
+ ...destSegments,
5806
+ "Format"
5807
+ ], sent)),
5715
5808
  Prefix: s3Dest["Prefix"]
5716
5809
  } : void 0 },
5717
5810
  OptionalFields: config["OptionalFields"],
@@ -5722,9 +5815,13 @@ var S3BucketProvider = class S3BucketProvider {
5722
5815
  Id: id,
5723
5816
  InventoryConfiguration: inventoryConfig
5724
5817
  }));
5818
+ if (sentItem !== void 0) substituted.set(index, sentItem);
5725
5819
  }
5726
5820
  this.logger.debug(`Applied ${configs.length - skipped.length} inventory configuration(s) to bucket ${bucketName}`);
5727
- return skipped;
5821
+ return {
5822
+ skipped,
5823
+ substituted
5824
+ };
5728
5825
  }
5729
5826
  /**
5730
5827
  * Apply replication configuration
@@ -5958,24 +6055,26 @@ var S3BucketProvider = class S3BucketProvider {
5958
6055
  return config;
5959
6056
  }
5960
6057
  /**
5961
- * Turn a set of skipped-property overrides into the `effectiveProperties`
5962
- * bag the deploy engine records in place of the desired one (issue #1612).
6058
+ * Turn a set of per-property overrides into the `effectiveProperties` bag the
6059
+ * deploy engine records in place of the desired one (issues #1612 / #1670).
5963
6060
  *
5964
- * A warn-and-skip arm makes the deploy SUCCEED while a declared
5965
- * configuration never reaches AWS, so recording the desired bag verbatim
5966
- * writes a value AWS does not hold: `readCurrentState` can never match it,
5967
- * every later `cdkd drift` re-reports the difference, and `drift --revert`
5968
- * re-issues the same skipped call the permanent phantom drift
5969
- * `.claude/rules/providers.md` records for the EC2 Route warn arm (#1591),
5970
- * reached here through a skip instead of a narrowing.
6061
+ * A warn-and-SKIP arm makes the deploy SUCCEED while a declared configuration
6062
+ * never reaches AWS, and a warn-and-SUBSTITUTE read makes it succeed while a
6063
+ * DIFFERENT value than the declared one reaches AWS. Either way, recording
6064
+ * the desired bag verbatim writes something AWS does not hold:
6065
+ * `readCurrentState` can never match it, every later `cdkd drift` re-reports
6066
+ * the difference, and `drift --revert` re-issues the same call the
6067
+ * permanent phantom drift `.claude/rules/providers.md` records for the EC2
6068
+ * Route warn arm (#1591), reached here through a skip or a substitution
6069
+ * instead of a narrowing.
5971
6070
  *
5972
6071
  * A `undefined` override value means the key is ABSENT from the effective
5973
6072
  * bag, which is why this walks the map rather than spreading it: spreading
5974
6073
  * would leave an explicit `undefined` that `JSON.stringify` drops on one
5975
6074
  * side of the next diff but not the other.
5976
6075
  *
5977
- * @returns the complete replacement bag, or `undefined` when nothing was
5978
- * skipped — the engine then records the desired properties unchanged.
6076
+ * @returns the complete replacement bag, or `undefined` when there is nothing
6077
+ * to override — the engine then records the desired properties unchanged.
5979
6078
  */
5980
6079
  static applyEffectiveOverrides(properties, overrides) {
5981
6080
  if (overrides.size === 0) return void 0;
@@ -5999,14 +6098,22 @@ var S3BucketProvider = class S3BucketProvider {
5999
6098
  * items would manufacture a fresh phantom drift while removing the one this
6000
6099
  * exists to fix.
6001
6100
  *
6101
+ * An item that WAS applied but with a value a warn-and-SUBSTITUTE read
6102
+ * replaced is the third arm (issue #1670): it keeps its position and its
6103
+ * declared shape, and only the substituted field differs — `sentItem` is the
6104
+ * item AS SENT, which is what AWS holds and therefore what state must
6105
+ * describe.
6106
+ *
6002
6107
  * @param previous the previously-recorded array, or `undefined` on the
6003
6108
  * replay-CREATE path, where nothing was ever applied and there is no
6004
6109
  * previous item to substitute.
6110
+ * @param sentItemOf the item as SENT for an APPLIED item whose declared value
6111
+ * was substituted, or `undefined` when declared == sent (the ordinary case).
6005
6112
  * @returns the effective array, or `undefined` when the key should be ABSENT
6006
6113
  * from the effective bag (nothing survived AND the previous side declared
6007
6114
  * nothing, so the property was never applied at all).
6008
6115
  */
6009
- static buildEffectiveItemArray(desired, previous, isSkipped) {
6116
+ static buildEffectiveItemArray(desired, previous, isSkipped, sentItemOf) {
6010
6117
  const previousById = /* @__PURE__ */ new Map();
6011
6118
  for (const item of previous ?? []) {
6012
6119
  const id = configItemId(item);
@@ -6015,7 +6122,7 @@ var S3BucketProvider = class S3BucketProvider {
6015
6122
  const effective = [];
6016
6123
  desired.forEach((item, index) => {
6017
6124
  if (!isSkipped(item, index)) {
6018
- effective.push(item);
6125
+ effective.push(sentItemOf?.(item, index) ?? item);
6019
6126
  return;
6020
6127
  }
6021
6128
  const id = configItemId(item);
@@ -6026,6 +6133,34 @@ var S3BucketProvider = class S3BucketProvider {
6026
6133
  return effective;
6027
6134
  }
6028
6135
  /**
6136
+ * A COPY of `container` with `path` set to `value` (issue #1670).
6137
+ *
6138
+ * Copying rather than mutating is load-bearing, not hygiene: the container is
6139
+ * an item of the caller's DESIRED property bag, which `DiffCalculator` and the
6140
+ * engine still read afterwards — writing the substituted value into it would
6141
+ * silently rewrite the template side of the next comparison, which is exactly
6142
+ * the `canonicalizeDesiredProperties` behavior this fix must NOT have. Only
6143
+ * the objects ALONG the path are cloned; every sibling subtree is shared,
6144
+ * which is safe because nothing here mutates them.
6145
+ *
6146
+ * A non-object intermediate is rebuilt as an EMPTY block, which is not a
6147
+ * defensive shrug but the accurate record: it is what `readConfigString`
6148
+ * itself did on the way in — its container arm says "Treating the block as
6149
+ * empty, so <path>.<key> takes its default" — so `{}` plus the substituted
6150
+ * leaf IS what was sent. No call site can reach it today (every intermediate
6151
+ * has already been validated by `requireConfigObject` /
6152
+ * `resolveS3BucketDestination`, which SKIP the item on a malformed one).
6153
+ */
6154
+ static withDeepValue(container, path, value) {
6155
+ const [head, ...rest] = path;
6156
+ if (head === void 0) return container;
6157
+ const child = container[head];
6158
+ return {
6159
+ ...container,
6160
+ [head]: rest.length === 0 ? value : S3BucketProvider.withDeepValue(isPlainObject$1(child) ? child : {}, rest, value)
6161
+ };
6162
+ }
6163
+ /**
6029
6164
  * Diff CFn-shape sub-config values between previous and new state.
6030
6165
  *
6031
6166
  * Four transitions:
@@ -6100,18 +6235,42 @@ var S3BucketProvider = class S3BucketProvider {
6100
6235
  const retainPrevious = (key) => {
6101
6236
  overrides.set(key, previousProperties[key]);
6102
6237
  };
6103
- /** Record a PER-ITEM skip set against the desired / previous arrays. */
6104
- const retainPreviousItems = (key, skippedIds) => {
6105
- if (skippedIds.size === 0) return;
6238
+ /**
6239
+ * Per-property accumulator for one of the four `Id`-keyed appliers.
6240
+ *
6241
+ * Keyed by `Id` rather than by index because on THIS path the diff loop
6242
+ * hands the applier exactly one item per call (so every outcome index is
6243
+ * 0) and the id is all the loop knows about it.
6244
+ */
6245
+ const itemOutcomes = () => {
6246
+ const skipped = /* @__PURE__ */ new Set();
6247
+ const sentItems = /* @__PURE__ */ new Map();
6248
+ return {
6249
+ skipped,
6250
+ sentItems,
6251
+ record: (id, outcome) => {
6252
+ if (outcome.skipped.length > 0) skipped.add(id);
6253
+ const sent = outcome.substituted.get(0);
6254
+ if (sent !== void 0) sentItems.set(id, sent);
6255
+ }
6256
+ };
6257
+ };
6258
+ /** Record a PER-ITEM skip / substitution set against the desired / previous arrays. */
6259
+ const retainPreviousItems = (key, collected) => {
6260
+ const { skipped: skippedIds, sentItems } = collected;
6261
+ if (skippedIds.size === 0 && sentItems.size === 0) return;
6106
6262
  const desired = properties[key];
6107
6263
  if (!Array.isArray(desired)) {
6108
- this.logger.debug(`Bucket ${bucketName}: ${skippedIds.size} skipped ${key} item(s) could not be recorded — the desired value is not an array`);
6264
+ this.logger.debug(`Bucket ${bucketName}: ${skippedIds.size + sentItems.size} skipped or substituted ${key} item(s) could not be recorded — the desired value is not an array`);
6109
6265
  return;
6110
6266
  }
6111
6267
  const previous = previousProperties[key];
6112
6268
  overrides.set(key, S3BucketProvider.buildEffectiveItemArray(desired, Array.isArray(previous) ? previous : void 0, (item) => {
6113
6269
  const id = configItemId(item);
6114
6270
  return id !== void 0 && skippedIds.has(id);
6271
+ }, (item) => {
6272
+ const id = configItemId(item);
6273
+ return id !== void 0 ? sentItems.get(id) : void 0;
6115
6274
  }));
6116
6275
  };
6117
6276
  const previousVersioning = previousProperties["VersioningConfiguration"];
@@ -6172,9 +6331,10 @@ var S3BucketProvider = class S3BucketProvider {
6172
6331
  this.logger.debug(`Cleared object lock rule on bucket ${bucketName}`);
6173
6332
  });
6174
6333
  await this.diffSubConfig(bucketName, previousProperties["AccelerateConfiguration"], properties["AccelerateConfiguration"], async (cfg) => this.applyAccelerateConfiguration(bucketName, cfg), async () => this.applyAccelerateConfiguration(bucketName, { AccelerationStatus: "Suspended" }));
6175
- const skippedMetricsIds = /* @__PURE__ */ new Set();
6334
+ const metricsOutcomes = itemOutcomes();
6176
6335
  await this.diffArrayConfigById(bucketName, previousProperties["MetricsConfigurations"], properties["MetricsConfigurations"], async (id, cfg) => {
6177
- if ((await this.applyMetricsConfigurations(bucketName, [cfg], (m) => this.logger.warn(m))).length > 0) skippedMetricsIds.add(String(id));
6336
+ const outcome = await this.applyMetricsConfigurations(bucketName, [cfg], (m) => this.logger.warn(m));
6337
+ metricsOutcomes.record(String(id), outcome);
6178
6338
  }, async (id) => {
6179
6339
  await this.s3Client.send(new DeleteBucketMetricsConfigurationCommand({
6180
6340
  Bucket: bucketName,
@@ -6182,10 +6342,11 @@ var S3BucketProvider = class S3BucketProvider {
6182
6342
  }));
6183
6343
  this.logger.debug(`Deleted metrics configuration ${id} on bucket ${bucketName}`);
6184
6344
  });
6185
- retainPreviousItems("MetricsConfigurations", skippedMetricsIds);
6186
- const skippedAnalyticsIds = /* @__PURE__ */ new Set();
6345
+ retainPreviousItems("MetricsConfigurations", metricsOutcomes);
6346
+ const analyticsOutcomes = itemOutcomes();
6187
6347
  await this.diffArrayConfigById(bucketName, previousProperties["AnalyticsConfigurations"], properties["AnalyticsConfigurations"], async (id, cfg) => {
6188
- if ((await this.applyAnalyticsConfigurations(bucketName, [cfg], (m) => this.logger.warn(m))).length > 0) skippedAnalyticsIds.add(String(id));
6348
+ const outcome = await this.applyAnalyticsConfigurations(bucketName, [cfg], (m) => this.logger.warn(m));
6349
+ analyticsOutcomes.record(String(id), outcome);
6189
6350
  }, async (id) => {
6190
6351
  await this.s3Client.send(new DeleteBucketAnalyticsConfigurationCommand({
6191
6352
  Bucket: bucketName,
@@ -6193,10 +6354,11 @@ var S3BucketProvider = class S3BucketProvider {
6193
6354
  }));
6194
6355
  this.logger.debug(`Deleted analytics configuration ${id} on bucket ${bucketName}`);
6195
6356
  });
6196
- retainPreviousItems("AnalyticsConfigurations", skippedAnalyticsIds);
6197
- const skippedIntelligentTieringIds = /* @__PURE__ */ new Set();
6357
+ retainPreviousItems("AnalyticsConfigurations", analyticsOutcomes);
6358
+ const intelligentTieringOutcomes = itemOutcomes();
6198
6359
  await this.diffArrayConfigById(bucketName, previousProperties["IntelligentTieringConfigurations"], properties["IntelligentTieringConfigurations"], async (id, cfg) => {
6199
- if ((await this.applyIntelligentTieringConfigurations(bucketName, [cfg], (m) => this.logger.warn(m))).length > 0) skippedIntelligentTieringIds.add(String(id));
6360
+ const outcome = await this.applyIntelligentTieringConfigurations(bucketName, [cfg], (m) => this.logger.warn(m));
6361
+ intelligentTieringOutcomes.record(String(id), outcome);
6200
6362
  }, async (id) => {
6201
6363
  await this.s3Client.send(new DeleteBucketIntelligentTieringConfigurationCommand({
6202
6364
  Bucket: bucketName,
@@ -6204,10 +6366,11 @@ var S3BucketProvider = class S3BucketProvider {
6204
6366
  }));
6205
6367
  this.logger.debug(`Deleted intelligent tiering configuration ${id} on bucket ${bucketName}`);
6206
6368
  });
6207
- retainPreviousItems("IntelligentTieringConfigurations", skippedIntelligentTieringIds);
6208
- const skippedInventoryIds = /* @__PURE__ */ new Set();
6369
+ retainPreviousItems("IntelligentTieringConfigurations", intelligentTieringOutcomes);
6370
+ const inventoryOutcomes = itemOutcomes();
6209
6371
  await this.diffArrayConfigById(bucketName, previousProperties["InventoryConfigurations"], properties["InventoryConfigurations"], async (id, cfg) => {
6210
- if ((await this.applyInventoryConfigurations(bucketName, [cfg], (m) => this.logger.warn(m))).length > 0) skippedInventoryIds.add(String(id));
6372
+ const outcome = await this.applyInventoryConfigurations(bucketName, [cfg], (m) => this.logger.warn(m));
6373
+ inventoryOutcomes.record(String(id), outcome);
6211
6374
  }, async (id) => {
6212
6375
  await this.s3Client.send(new DeleteBucketInventoryConfigurationCommand({
6213
6376
  Bucket: bucketName,
@@ -6215,7 +6378,7 @@ var S3BucketProvider = class S3BucketProvider {
6215
6378
  }));
6216
6379
  this.logger.debug(`Deleted inventory configuration ${id} on bucket ${bucketName}`);
6217
6380
  });
6218
- retainPreviousItems("InventoryConfigurations", skippedInventoryIds);
6381
+ retainPreviousItems("InventoryConfigurations", inventoryOutcomes);
6219
6382
  if (versioningChanged && desiredVersioningStatus === "Suspended") {
6220
6383
  const hasObjectLock = (p) => {
6221
6384
  if (p["ObjectLockEnabled"] === true || p["ObjectLockEnabled"] === "true") return true;
@@ -6232,20 +6395,29 @@ var S3BucketProvider = class S3BucketProvider {
6232
6395
  * Apply ALL sub-configs unconditionally on initial create. Used by
6233
6396
  * `create()` so the bucket starts out matching the template.
6234
6397
  *
6235
- * @returns the per-property overrides for `effectiveProperties` (issue
6236
- * #1612). Every skip reachable here is on the REPLAY-create path (the
6237
- * rollback executor's reverse-replacement arm), where the bucket is brand
6238
- * new and nothing was applied — so the override DROPS the key rather than
6239
- * retaining a previous value, because there is no previous value to keep.
6240
- * The per-item arrays keep the items that DID apply.
6398
+ * @returns the per-property overrides for `effectiveProperties` (issues
6399
+ * #1612 / #1670). Every downgrade reachable here is on the REPLAY-create
6400
+ * path (the rollback executor's reverse-replacement arm), where the bucket
6401
+ * is brand new and nothing was applied — so a SKIP drops the key rather
6402
+ * than retaining a previous value, because there is no previous value to
6403
+ * keep. The per-item arrays keep the items that DID apply, including an
6404
+ * item applied with a SUBSTITUTED value, recorded as it was sent.
6241
6405
  */
6242
6406
  async applyAllSubConfigsForCreate(bucketName, properties, context) {
6243
6407
  const overrides = /* @__PURE__ */ new Map();
6244
- /** Record a per-ITEM skip set: nothing to substitute on a fresh bucket. */
6245
- const dropSkippedItems = (key, configs, skippedIndexes) => {
6246
- if (skippedIndexes.length === 0) return;
6247
- const skipped = new Set(skippedIndexes);
6248
- overrides.set(key, S3BucketProvider.buildEffectiveItemArray(configs, void 0, (_item, index) => skipped.has(index)));
6408
+ /**
6409
+ * Record a per-ITEM applier outcome.
6410
+ *
6411
+ * A SKIPPED item is DROPPED — there is no previously-applied item to
6412
+ * substitute on a fresh bucket. An item applied with a SUBSTITUTED value
6413
+ * (issue #1670) is kept in place as SENT, which is a decision the create
6414
+ * path makes for the same reason the update path does: the Put SUCCEEDED,
6415
+ * so AWS holds the substituted value and state must say so.
6416
+ */
6417
+ const recordItemOutcome = (key, configs, outcome) => {
6418
+ if (outcome.skipped.length === 0 && outcome.substituted.size === 0) return;
6419
+ const skipped = new Set(outcome.skipped);
6420
+ overrides.set(key, S3BucketProvider.buildEffectiveItemArray(configs, void 0, (_item, index) => skipped.has(index), (_item, index) => outcome.substituted.get(index)));
6249
6421
  };
6250
6422
  const replayOnUnusable = replayWarn(this.logger, context).onUnusable;
6251
6423
  const notifConfig = properties["NotificationConfiguration"];
@@ -6269,13 +6441,13 @@ var S3BucketProvider = class S3BucketProvider {
6269
6441
  const accelerateConfig = properties["AccelerateConfiguration"];
6270
6442
  if (accelerateConfig) await this.applyAccelerateConfiguration(bucketName, accelerateConfig);
6271
6443
  const metricsConfigs = properties["MetricsConfigurations"];
6272
- if (metricsConfigs && Array.isArray(metricsConfigs) && metricsConfigs.length > 0) dropSkippedItems("MetricsConfigurations", metricsConfigs, await this.applyMetricsConfigurations(bucketName, metricsConfigs, replayOnUnusable));
6444
+ if (metricsConfigs && Array.isArray(metricsConfigs) && metricsConfigs.length > 0) recordItemOutcome("MetricsConfigurations", metricsConfigs, await this.applyMetricsConfigurations(bucketName, metricsConfigs, replayOnUnusable));
6273
6445
  const analyticsConfigs = properties["AnalyticsConfigurations"];
6274
- if (analyticsConfigs && Array.isArray(analyticsConfigs) && analyticsConfigs.length > 0) dropSkippedItems("AnalyticsConfigurations", analyticsConfigs, await this.applyAnalyticsConfigurations(bucketName, analyticsConfigs, replayOnUnusable));
6446
+ if (analyticsConfigs && Array.isArray(analyticsConfigs) && analyticsConfigs.length > 0) recordItemOutcome("AnalyticsConfigurations", analyticsConfigs, await this.applyAnalyticsConfigurations(bucketName, analyticsConfigs, replayOnUnusable));
6275
6447
  const itConfigs = properties["IntelligentTieringConfigurations"];
6276
- if (itConfigs && Array.isArray(itConfigs) && itConfigs.length > 0) dropSkippedItems("IntelligentTieringConfigurations", itConfigs, await this.applyIntelligentTieringConfigurations(bucketName, itConfigs, replayOnUnusable));
6448
+ if (itConfigs && Array.isArray(itConfigs) && itConfigs.length > 0) recordItemOutcome("IntelligentTieringConfigurations", itConfigs, await this.applyIntelligentTieringConfigurations(bucketName, itConfigs, replayOnUnusable));
6277
6449
  const inventoryConfigs = properties["InventoryConfigurations"];
6278
- if (inventoryConfigs && Array.isArray(inventoryConfigs) && inventoryConfigs.length > 0) dropSkippedItems("InventoryConfigurations", inventoryConfigs, await this.applyInventoryConfigurations(bucketName, inventoryConfigs, replayOnUnusable));
6450
+ if (inventoryConfigs && Array.isArray(inventoryConfigs) && inventoryConfigs.length > 0) recordItemOutcome("InventoryConfigurations", inventoryConfigs, await this.applyInventoryConfigurations(bucketName, inventoryConfigs, replayOnUnusable));
6279
6451
  const replConfig = properties["ReplicationConfiguration"];
6280
6452
  if (replConfig) {
6281
6453
  if (!await this.applyReplicationConfiguration(bucketName, replConfig, replayOnUnusable)) overrides.set("ReplicationConfiguration", void 0);
@@ -6866,15 +7038,17 @@ var S3BucketProvider = class S3BucketProvider {
6866
7038
  if (sca?.["DataExport"]) {
6867
7039
  const dataExport = sca["DataExport"];
6868
7040
  const s3Dest = dataExport["Destination"]?.["S3BucketDestination"];
6869
- out["StorageClassAnalysis"] = { DataExport: {
6870
- OutputSchemaVersion: dataExport["OutputSchemaVersion"],
6871
- Destination: s3Dest ? { S3BucketDestination: {
6872
- BucketArn: s3Dest["Bucket"],
6873
- BucketAccountId: s3Dest["BucketAccountId"],
6874
- Format: s3Dest["Format"],
6875
- Prefix: s3Dest["Prefix"]
6876
- } } : void 0
6877
- } };
7041
+ const dataExportCfn = {};
7042
+ if (dataExport["OutputSchemaVersion"] !== void 0) dataExportCfn["OutputSchemaVersion"] = dataExport["OutputSchemaVersion"];
7043
+ if (s3Dest) {
7044
+ const cfnDest = {};
7045
+ if (s3Dest["Bucket"] !== void 0) cfnDest["BucketArn"] = s3Dest["Bucket"];
7046
+ if (s3Dest["BucketAccountId"] !== void 0) cfnDest["BucketAccountId"] = s3Dest["BucketAccountId"];
7047
+ if (s3Dest["Format"] !== void 0) cfnDest["Format"] = s3Dest["Format"];
7048
+ if (s3Dest["Prefix"] !== void 0) cfnDest["Prefix"] = s3Dest["Prefix"];
7049
+ dataExportCfn["Destination"] = cfnDest;
7050
+ }
7051
+ out["StorageClassAnalysis"] = { DataExport: dataExportCfn };
6878
7052
  }
6879
7053
  return out;
6880
7054
  }
@@ -72155,7 +72329,7 @@ function createMigrateCommand() {
72155
72329
  */
72156
72330
  function buildProgram() {
72157
72331
  const program = new Command();
72158
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.46");
72332
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.47");
72159
72333
  program.hook("preAction", (_thisCommand, actionCommand) => {
72160
72334
  const { profile } = actionCommand.optsWithGlobals();
72161
72335
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;