@go-to-k/cdkd 0.278.50 → 0.278.52

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 DiffCalculator, $t as resolveBucketRegion, A as red, At as getDockerImageBySourceHash, B as isTerminationProtectionPropagationError, Bt as resolveStateBucketWithDefaultAndSource, C as isStatefulRecreateTargetSync, Ct as validateContainerRepoName, D as cyan, Dt as runDockerForeground, E as bold, En as withErrorHandling, Et as getDockerCmd, F as ProviderRegistry, Ft as resolveApp, G as normalizeAwsTagsToCfn, Gt as CFN_TEMPLATE_URL_LIMIT, H as cfnRefValueFromPhysicalId, Ht as stateBucketExistenceConfirmed, I as findActionableSilentDrops, It as resolveAutoAssetStorage, J as readConfigString, Jt as uploadCfnTemplate, K as resolveExplicitPhysicalId, Kt as MIGRATE_TMP_PREFIX, L as CloudControlProvider, Lt as resolveCaptureObservedState, M as IAMRoleProvider, Mt as synthesisStatusMessage, N as collectInlinePolicyNamesManagedBySiblings, Nt as getDefaultStateBucketName, O as gray, Ot as runDockerStreaming, P as clearOnUpdateRemoval, Pt as getLegacyStateBucketName, Q as applyRoleArnIfSet, R as slowCcOperationTimeoutMs, Rt as resolveSkipPrefix, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, St as validateAssetBucketName, T as formatResourceLine, Tn as normalizeAwsError, Tt as formatDockerLoginError, U as refStateLookupFromResource, Ut as warnDeprecatedNoPrefixCliFlag, V as IntrinsicFunctionResolver, Vt as resolveUseCdkBootstrapAssets, W as WAFv2WebACLProvider, Wt as CFN_TEMPLATE_BODY_LIMIT, X as requireConfigArray, Xt as AssemblyReader, Y as replayWarn, Yt as expectedOwnerParam, Z as requireConfigString, Zt as processStackMessages, _ as createPreDeleteFinalSnapshot, _n as ResourceTimeoutError, _t as AssetModeResolver, a as DeploymentEventsStore, an as CdkdError, at as TemplateParser, b as unsupportedFinalSnapshotError, bn as StackTerminationProtectionError, bt as getBootstrapMarkerKey, c as replayFailedOperations, cn as DeployCancelledError, ct as rebuildClientForBucketRegion, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalStartServiceError, dt as stringifyValue, en as AwsClients, et as describeTypeWithThrottleRetry, f as computeImplicitDeleteEdges, ft as WorkGraph, g as ccRoutedFinalSnapshotError, gn as ProvisioningError, gt as rewriteTemplateAssetReferences, h as buildFinalSnapshotIdentifier, hn as PartialFailureError, ht as loadPublishableAssetManifest, i as DeploymentEventsReader, it as DagBuilder, j as yellow, jt as Synthesizer, k as green, kt as AssetManifestLoader, l as replayRollback, ln as LocalInvokeBuildError$1, lt as shouldRetainResource, m as PRE_DELETE_SNAPSHOT_TYPES, mn as NestedStackChildDirectDestroyError, mt as createAssetRedirectResolver, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resetAwsClients, nt as isRetryableTransientError, o as planFailedOps, ot as LockManager, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as MissingCdkCliError, pt as buildAssetRedirectMap, q as assertRegionMatch, qt as findLargeInlineResources, r as DeployEngine, rn as setAwsClients, rt as isThrottlingError, s as planRollback, st as S3StateBackend, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as getAwsClients, tt as withRetry, u as withResourceDeadline, un as LocalMigrateError, ut as AssetPublisher, v as isFinalSnapshotError, vn as ResourceUpdateNotSupportedError, vt as BOOTSTRAP_MARKER_PREFIX, w as renderStatefulReason, wt as buildDockerImage, x as extractDeploymentEventError, xt as parseBootstrapMarker, y as refusesFinalSnapshot, yn as StackHasActiveImportsError, yt as ensureAssetStorage, z as disableInstanceApiTermination, zt as resolveStateBucketWithDefault } from "./deploy-engine-D2mbS9va.js";
2
+ import { $ as DiffCalculator, $t as resolveBucketRegion, A as red, At as getDockerImageBySourceHash, B as isTerminationProtectionPropagationError, Bt as resolveStateBucketWithDefaultAndSource, C as isStatefulRecreateTargetSync, Ct as validateContainerRepoName, D as cyan, Dt as runDockerForeground, E as bold, En as withErrorHandling, Et as getDockerCmd, F as ProviderRegistry, Ft as resolveApp, G as normalizeAwsTagsToCfn, Gt as CFN_TEMPLATE_URL_LIMIT, H as cfnRefValueFromPhysicalId, Ht as stateBucketExistenceConfirmed, I as findActionableSilentDrops, It as resolveAutoAssetStorage, J as readConfigString, Jt as uploadCfnTemplate, K as resolveExplicitPhysicalId, Kt as MIGRATE_TMP_PREFIX, L as CloudControlProvider, Lt as resolveCaptureObservedState, M as IAMRoleProvider, Mt as synthesisStatusMessage, N as collectInlinePolicyNamesManagedBySiblings, Nt as getDefaultStateBucketName, O as gray, Ot as runDockerStreaming, P as clearOnUpdateRemoval, Pt as getLegacyStateBucketName, Q as applyRoleArnIfSet, R as slowCcOperationTimeoutMs, Rt as resolveSkipPrefix, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, St as validateAssetBucketName, T as formatResourceLine, Tn as normalizeAwsError, Tt as formatDockerLoginError, U as refStateLookupFromResource, Ut as warnDeprecatedNoPrefixCliFlag, V as IntrinsicFunctionResolver, Vt as resolveUseCdkBootstrapAssets, W as WAFv2WebACLProvider, Wt as CFN_TEMPLATE_BODY_LIMIT, X as requireConfigArray, Xt as AssemblyReader, Y as replayWarn, Yt as expectedOwnerParam, Z as requireConfigString, Zt as processStackMessages, _ as createPreDeleteFinalSnapshot, _n as ResourceTimeoutError, _t as AssetModeResolver, a as DeploymentEventsStore, an as CdkdError, at as TemplateParser, b as unsupportedFinalSnapshotError, bn as StackTerminationProtectionError, bt as getBootstrapMarkerKey, c as replayFailedOperations, cn as DeployCancelledError, ct as rebuildClientForBucketRegion, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalStartServiceError, dt as stringifyValue, en as AwsClients, et as describeTypeWithThrottleRetry, f as computeImplicitDeleteEdges, ft as WorkGraph, g as ccRoutedFinalSnapshotError, gn as ProvisioningError, gt as rewriteTemplateAssetReferences, h as buildFinalSnapshotIdentifier, hn as PartialFailureError, ht as loadPublishableAssetManifest, i as DeploymentEventsReader, it as DagBuilder, j as yellow, jt as Synthesizer, k as green, kt as AssetManifestLoader, l as replayRollback, ln as LocalInvokeBuildError$1, lt as shouldRetainResource, m as PRE_DELETE_SNAPSHOT_TYPES, mn as NestedStackChildDirectDestroyError, mt as createAssetRedirectResolver, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resetAwsClients, nt as isRetryableTransientError, o as planFailedOps, ot as LockManager, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as MissingCdkCliError, pt as buildAssetRedirectMap, q as assertRegionMatch, qt as findLargeInlineResources, r as DeployEngine, rn as setAwsClients, rt as isThrottlingError, s as planRollback, st as S3StateBackend, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as getAwsClients, tt as withRetry, u as withResourceDeadline, un as LocalMigrateError, ut as AssetPublisher, v as isFinalSnapshotError, vn as ResourceUpdateNotSupportedError, vt as BOOTSTRAP_MARKER_PREFIX, w as renderStatefulReason, wt as buildDockerImage, x as extractDeploymentEventError, xt as parseBootstrapMarker, y as refusesFinalSnapshot, yn as StackHasActiveImportsError, yt as ensureAssetStorage, z as disableInstanceApiTermination, zt as resolveStateBucketWithDefault } from "./deploy-engine-64dVN8O1.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-C217C6UE.js";
4
+ import { t as ASGProvider } from "./asg-provider-CjVpdcoW.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";
@@ -4824,6 +4824,53 @@ function isPlainObject$1(value) {
4824
4824
  return typeof value === "object" && value !== null && !Array.isArray(value);
4825
4825
  }
4826
4826
  /**
4827
+ * Is this `Destination` block written in the CFn FLATTENED form
4828
+ * (`{ BucketArn, Format, ... }`) rather than the SDK NESTED one
4829
+ * (`{ S3BucketDestination: { ... } }`)?
4830
+ *
4831
+ * ONE predicate, called from both `resolveS3BucketDestination` (which picks the
4832
+ * bag) and `s3BucketDestinationPath` (which names it). They were written out
4833
+ * twice and a reviewer rightly pointed out that two copies of a branch
4834
+ * condition must be edited together or a refusal starts naming the wrong key.
4835
+ *
4836
+ * `Bucket` is probed alongside `BucketArn` because the readers accept it
4837
+ * (`s3Dest['BucketArn'] ?? s3Dest['Bucket']`); omitting it made a
4838
+ * `{ Bucket }`-only block take the nested branch, find nothing, and drop — the
4839
+ * same silent drop one shape over.
4840
+ */
4841
+ function isFlattenedDestination(dest) {
4842
+ return Boolean(dest["BucketArn"] || dest["Bucket"] || dest["BucketAccountId"] || dest["Format"]);
4843
+ }
4844
+ /**
4845
+ * The CFn path of the destination bag `resolveS3BucketDestination` will pick —
4846
+ * issue #1493 item 3, which is a MESSAGE concern, not a value one.
4847
+ *
4848
+ * Kept separate from the resolver rather than returned alongside the bag:
4849
+ * `gen-nested-key-coverage`'s write-evidence walk follows a plain
4850
+ * `const x = this.helper(...)` binding to the members written beneath it, and
4851
+ * a DESTRUCTURED `const { bag, path } = ...` is a shape it cannot follow — so
4852
+ * pairing the two silently withdrew the write evidence for
4853
+ * `Destination.BucketArn` / `.BucketAccountId` and turned an opted-in target
4854
+ * red with no behavior change at all. Measured against the pre-change provider
4855
+ * via the critic's `--providers-dir=` seam.
4856
+ */
4857
+ function s3BucketDestinationPath(dest, destinationPath) {
4858
+ return isPlainObject$1(dest) && isFlattenedDestination(dest) ? destinationPath : `${destinationPath}.S3BucketDestination`;
4859
+ }
4860
+ /**
4861
+ * Name a malformed value in a refusal message, the way `config-shape.ts`'s
4862
+ * private `describe` does for the string-reading guards. Kept local rather than
4863
+ * exported from there because `resolveS3BucketDestination` is S3-specific
4864
+ * branch selection, not a shared shape guard — the two only share the wording.
4865
+ */
4866
+ function describeValue(value) {
4867
+ if (value === null) return "null";
4868
+ if (Array.isArray(value)) return "an array";
4869
+ if (typeof value === "string") return `a string ${JSON.stringify(value)}`;
4870
+ if (isPlainObject$1(value)) return `an object with keys [${Object.keys(value).join(", ")}]`;
4871
+ return `a ${typeof value} (${String(value)})`;
4872
+ }
4873
+ /**
4827
4874
  * Coerce a CFn numeric to a finite number. CloudFormation is stringly typed —
4828
4875
  * a hand-written or imported template (the audience the legacy lifecycle
4829
4876
  * branches exist for) can carry `"365"` where the schema says number.
@@ -5345,12 +5392,61 @@ var S3BucketProvider = class S3BucketProvider {
5345
5392
  this.logger.debug(`Applied ${configs.length} metrics configuration(s) to bucket ${bucketName}`);
5346
5393
  }
5347
5394
  /**
5395
+ * Pick the `S3BucketDestination` bag out of an analytics / inventory
5396
+ * `Destination` block, refusing a shape that would otherwise be dropped.
5397
+ *
5398
+ * Two shapes are legitimate and both must keep working: the CFn FLATTENED
5399
+ * form (`Destination: { BucketArn, Format, ... }`, what the schema declares)
5400
+ * and the SDK NESTED form (`Destination: { S3BucketDestination: { ... } }`,
5401
+ * accepted because state records and hand-written templates carry it).
5402
+ *
5403
+ * Issue #1493 item 2: the branch was picked by probing member presence
5404
+ * (`dest?.['BucketAccountId'] || dest?.['BucketArn'] || dest?.['Format']`),
5405
+ * so a `Destination` that is a STRING / array / unresolved intrinsic indexed
5406
+ * every probe to `undefined`, fell through to an equally-`undefined`
5407
+ * `S3BucketDestination`, and the caller's `s3Dest ? … : undefined` omitted
5408
+ * the whole block from the Put — a configuration silently deployed without
5409
+ * the destination it declared. Unlike the sibling defaulting class this is a
5410
+ * DROP, not a substituted default, so `readConfigString` does not cover it:
5411
+ * it needs its own decision, and per issue #1513's precedent that decision is
5412
+ * REFUSE on the template-borne create path, WARN on the replay-reachable
5413
+ * update path (`onUnusable`), where the desired bag can be a historical cdkd
5414
+ * state record with no template-side remedy.
5415
+ *
5416
+ * Also returns the CFn path of the bag it picked (issue #1493 item 3): the
5417
+ * callers used to hardcode `…Destination.S3BucketDestination` in the
5418
+ * `containerPath` they pass to `readConfigString`, so a refusal on the
5419
+ * FLATTENED branch — where the bag IS `dest` itself — named a key the user's
5420
+ * template does not contain.
5421
+ *
5422
+ * @returns the picked bag, or `undefined` when the block was ABSENT or was
5423
+ * refused on a warn-only path. The caller distinguishes the two by testing
5424
+ * its own `Destination` value — see the `continue` at each call site.
5425
+ */
5426
+ resolveS3BucketDestination(dest, destinationPath, onUnusable) {
5427
+ const nestedPath = `${destinationPath}.S3BucketDestination`;
5428
+ const drop = (message) => {
5429
+ if (onUnusable) {
5430
+ onUnusable(`${message}. Leaving this configuration unchanged; the same value is REFUSED on a template-path create`);
5431
+ return;
5432
+ }
5433
+ throw new Error(message);
5434
+ };
5435
+ if (dest === void 0 || dest === null) return;
5436
+ if (!isPlainObject$1(dest)) return drop(`${destinationPath} must be an object (got ${describeValue(dest)}) — check for an unresolved intrinsic or a mis-nested template value; the destination would otherwise be dropped from the request with no error`);
5437
+ const bag = isFlattenedDestination(dest) ? dest : dest["S3BucketDestination"];
5438
+ if (bag === void 0 || bag === null) return drop(`${destinationPath} carries neither a bucket (BucketArn / Bucket) nor a nested S3BucketDestination object (got ${describeValue(dest)}) — the destination would otherwise be dropped from the request with no error`);
5439
+ if (!isPlainObject$1(bag)) return drop(`${nestedPath} must be an object (got ${describeValue(bag)}) — check for an unresolved intrinsic or a mis-nested template value; the destination would otherwise be dropped from the request with no error`);
5440
+ if (!bag["BucketArn"] && !bag["Bucket"]) return drop(`${bag === dest ? destinationPath : nestedPath} has no destination bucket (BucketArn / Bucket) (got ${describeValue(bag)}) — the request would be rejected by S3, or silently carry no destination`);
5441
+ return bag;
5442
+ }
5443
+ /**
5348
5444
  * Apply analytics configurations
5349
5445
  *
5350
5446
  * CFn property: AnalyticsConfigurations[] (array of configurations)
5351
5447
  * SDK: PutBucketAnalyticsConfiguration (one per configuration, keyed by Id)
5352
5448
  */
5353
- async applyAnalyticsConfigurations(bucketName, configs) {
5449
+ async applyAnalyticsConfigurations(bucketName, configs, onUnusable) {
5354
5450
  for (const config of configs) {
5355
5451
  const id = config["Id"];
5356
5452
  const storageClassAnalysis = config["StorageClassAnalysis"];
@@ -5368,16 +5464,19 @@ var S3BucketProvider = class S3BucketProvider {
5368
5464
  else if (prefix) analyticsConfig.Filter = { Prefix: prefix };
5369
5465
  else if (tagFilters && tagFilters.length > 0) analyticsConfig.Filter = { Tag: tagFilters[0] };
5370
5466
  }
5371
- if (storageClassAnalysis?.["DataExport"]) {
5467
+ if (storageClassAnalysis?.["DataExport"] != null) {
5372
5468
  const dataExport = storageClassAnalysis["DataExport"];
5373
- const dest = dataExport["Destination"];
5374
- const s3Dest = dest?.["BucketAccountId"] || dest?.["BucketArn"] || dest?.["Format"] ? dest : dest?.["S3BucketDestination"];
5469
+ const analyticsDestPath = "AWS::S3::Bucket AnalyticsConfigurations[].StorageClassAnalysis.DataExport.Destination";
5470
+ const rawDest = dataExport["Destination"];
5471
+ const s3Dest = this.resolveS3BucketDestination(rawDest, analyticsDestPath, onUnusable);
5472
+ if (s3Dest === void 0 && rawDest != null) continue;
5473
+ const destPath = s3BucketDestinationPath(rawDest, analyticsDestPath);
5375
5474
  analyticsConfig.StorageClassAnalysis = { DataExport: {
5376
5475
  OutputSchemaVersion: readConfigString(dataExport, "OutputSchemaVersion", "V_1", "AWS::S3::Bucket AnalyticsConfigurations[].StorageClassAnalysis.DataExport"),
5377
5476
  Destination: s3Dest ? { S3BucketDestination: {
5378
5477
  Bucket: s3Dest["BucketArn"] ?? s3Dest["Bucket"],
5379
5478
  BucketAccountId: s3Dest["BucketAccountId"],
5380
- Format: readConfigString(s3Dest, "Format", "CSV", "AWS::S3::Bucket AnalyticsConfigurations[].StorageClassAnalysis.DataExport.Destination.S3BucketDestination"),
5479
+ Format: readConfigString(s3Dest, "Format", "CSV", destPath, { ...onUnusable ? { onUnusable } : {} }),
5381
5480
  Prefix: s3Dest["Prefix"]
5382
5481
  } } : void 0
5383
5482
  } };
@@ -5432,11 +5531,14 @@ var S3BucketProvider = class S3BucketProvider {
5432
5531
  * CFn property: InventoryConfigurations[]
5433
5532
  * SDK: PutBucketInventoryConfiguration (one per configuration, keyed by Id)
5434
5533
  */
5435
- async applyInventoryConfigurations(bucketName, configs) {
5534
+ async applyInventoryConfigurations(bucketName, configs, onUnusable) {
5436
5535
  for (const config of configs) {
5437
5536
  const id = config["Id"];
5438
- const dest = config["Destination"];
5439
- const s3Dest = dest?.["BucketArn"] || dest?.["Format"] ? dest : dest?.["S3BucketDestination"];
5537
+ const inventoryDestPath = "AWS::S3::Bucket InventoryConfigurations[].Destination";
5538
+ const rawDest = config["Destination"];
5539
+ const s3Dest = this.resolveS3BucketDestination(rawDest, inventoryDestPath, onUnusable);
5540
+ if (s3Dest === void 0 && rawDest != null) continue;
5541
+ const destPath = s3BucketDestinationPath(rawDest, inventoryDestPath);
5440
5542
  const inventoryConfig = {
5441
5543
  Id: id,
5442
5544
  IsEnabled: config["Enabled"] ?? true,
@@ -5445,7 +5547,7 @@ var S3BucketProvider = class S3BucketProvider {
5445
5547
  Destination: { S3BucketDestination: s3Dest ? {
5446
5548
  Bucket: s3Dest["BucketArn"] ?? s3Dest["Bucket"],
5447
5549
  AccountId: s3Dest["BucketAccountId"],
5448
- Format: readConfigString(s3Dest, "Format", "CSV", "AWS::S3::Bucket InventoryConfigurations[].Destination.S3BucketDestination"),
5550
+ Format: readConfigString(s3Dest, "Format", "CSV", destPath, { ...onUnusable ? { onUnusable } : {} }),
5449
5551
  Prefix: s3Dest["Prefix"]
5450
5552
  } : void 0 },
5451
5553
  OptionalFields: config["OptionalFields"],
@@ -5789,7 +5891,7 @@ var S3BucketProvider = class S3BucketProvider {
5789
5891
  }));
5790
5892
  this.logger.debug(`Deleted metrics configuration ${id} on bucket ${bucketName}`);
5791
5893
  });
5792
- await this.diffArrayConfigById(bucketName, previousProperties["AnalyticsConfigurations"], properties["AnalyticsConfigurations"], async (_id, cfg) => this.applyAnalyticsConfigurations(bucketName, [cfg]), async (id) => {
5894
+ await this.diffArrayConfigById(bucketName, previousProperties["AnalyticsConfigurations"], properties["AnalyticsConfigurations"], async (_id, cfg) => this.applyAnalyticsConfigurations(bucketName, [cfg], (m) => this.logger.warn(m)), async (id) => {
5793
5895
  await this.s3Client.send(new DeleteBucketAnalyticsConfigurationCommand({
5794
5896
  Bucket: bucketName,
5795
5897
  Id: id
@@ -5803,7 +5905,7 @@ var S3BucketProvider = class S3BucketProvider {
5803
5905
  }));
5804
5906
  this.logger.debug(`Deleted intelligent tiering configuration ${id} on bucket ${bucketName}`);
5805
5907
  });
5806
- await this.diffArrayConfigById(bucketName, previousProperties["InventoryConfigurations"], properties["InventoryConfigurations"], async (_id, cfg) => this.applyInventoryConfigurations(bucketName, [cfg]), async (id) => {
5908
+ await this.diffArrayConfigById(bucketName, previousProperties["InventoryConfigurations"], properties["InventoryConfigurations"], async (_id, cfg) => this.applyInventoryConfigurations(bucketName, [cfg], (m) => this.logger.warn(m)), async (id) => {
5807
5909
  await this.s3Client.send(new DeleteBucketInventoryConfigurationCommand({
5808
5910
  Bucket: bucketName,
5809
5911
  Id: id
@@ -5823,7 +5925,8 @@ var S3BucketProvider = class S3BucketProvider {
5823
5925
  * Apply ALL sub-configs unconditionally on initial create. Used by
5824
5926
  * `create()` so the bucket starts out matching the template.
5825
5927
  */
5826
- async applyAllSubConfigsForCreate(bucketName, properties) {
5928
+ async applyAllSubConfigsForCreate(bucketName, properties, context) {
5929
+ const replayOnUnusable = replayWarn(this.logger, context).onUnusable;
5827
5930
  const notifConfig = properties["NotificationConfiguration"];
5828
5931
  if (notifConfig) await this.applyNotificationConfiguration(bucketName, notifConfig);
5829
5932
  const corsConfig = properties["CorsConfiguration"];
@@ -5839,11 +5942,11 @@ var S3BucketProvider = class S3BucketProvider {
5839
5942
  const metricsConfigs = properties["MetricsConfigurations"];
5840
5943
  if (metricsConfigs && Array.isArray(metricsConfigs) && metricsConfigs.length > 0) await this.applyMetricsConfigurations(bucketName, metricsConfigs);
5841
5944
  const analyticsConfigs = properties["AnalyticsConfigurations"];
5842
- if (analyticsConfigs && Array.isArray(analyticsConfigs) && analyticsConfigs.length > 0) await this.applyAnalyticsConfigurations(bucketName, analyticsConfigs);
5945
+ if (analyticsConfigs && Array.isArray(analyticsConfigs) && analyticsConfigs.length > 0) await this.applyAnalyticsConfigurations(bucketName, analyticsConfigs, replayOnUnusable);
5843
5946
  const itConfigs = properties["IntelligentTieringConfigurations"];
5844
5947
  if (itConfigs && Array.isArray(itConfigs) && itConfigs.length > 0) await this.applyIntelligentTieringConfigurations(bucketName, itConfigs);
5845
5948
  const inventoryConfigs = properties["InventoryConfigurations"];
5846
- if (inventoryConfigs && Array.isArray(inventoryConfigs) && inventoryConfigs.length > 0) await this.applyInventoryConfigurations(bucketName, inventoryConfigs);
5949
+ if (inventoryConfigs && Array.isArray(inventoryConfigs) && inventoryConfigs.length > 0) await this.applyInventoryConfigurations(bucketName, inventoryConfigs, replayOnUnusable);
5847
5950
  const replConfig = properties["ReplicationConfiguration"];
5848
5951
  if (replConfig) await this.applyReplicationConfiguration(bucketName, replConfig);
5849
5952
  const objectLockConfig = properties["ObjectLockConfiguration"];
@@ -5852,7 +5955,7 @@ var S3BucketProvider = class S3BucketProvider {
5852
5955
  /**
5853
5956
  * Create an S3 bucket
5854
5957
  */
5855
- async create(logicalId, resourceType, properties) {
5958
+ async create(logicalId, resourceType, properties, context) {
5856
5959
  this.logger.debug(`Creating S3 bucket ${logicalId}`);
5857
5960
  const bucketName = properties["BucketName"] || generateResourceName(logicalId, {
5858
5961
  maxLength: 63,
@@ -5875,7 +5978,7 @@ var S3BucketProvider = class S3BucketProvider {
5875
5978
  }
5876
5979
  try {
5877
5980
  await this.applyConfiguration(bucketName, properties);
5878
- await this.applyAllSubConfigsForCreate(bucketName, properties);
5981
+ await this.applyAllSubConfigsForCreate(bucketName, properties, context);
5879
5982
  } catch (innerError) {
5880
5983
  if (createdNewBucket) try {
5881
5984
  await this.s3Client.send(new DeleteBucketCommand({ Bucket: bucketName }));
@@ -42655,6 +42758,25 @@ function mapHttpEndpointDescriptionToCfn(desc) {
42655
42758
  //#endregion
42656
42759
  //#region src/provisioning/providers/cloudtrail-provider.ts
42657
42760
  /**
42761
+ * The selector set a trail carries when its template declares NO
42762
+ * `EventSelectors`, and therefore the RESET payload for a removal.
42763
+ *
42764
+ * Live CFn A/B (issue #1549, us-east-1, 2026-08-11): removing `EventSelectors`
42765
+ * from a deployed trail's template resets the live selectors to exactly this
42766
+ * shape — AWS echoes it back as `{ReadWriteType: 'All', IncludeManagementEvents:
42767
+ * true, DataResources: [], ExcludeManagementEventSources: []}`, the two empty
42768
+ * lists being response-side defaults that do NOT need sending.
42769
+ *
42770
+ * It is a VALUE, not an empty array, because `PutEventSelectors` rejects `[]`
42771
+ * with `InvalidEventSelectorsException: Specify a valid number of selectors
42772
+ * (1 to 5) for your trail` — the divergence from the `InsightSelectors` sibling,
42773
+ * where AWS documents `[]` as the removal shape.
42774
+ */
42775
+ const DEFAULT_EVENT_SELECTORS = Object.freeze([Object.freeze({
42776
+ ReadWriteType: "All",
42777
+ IncludeManagementEvents: true
42778
+ })]);
42779
+ /**
42658
42780
  * SDK Provider for AWS CloudTrail resources
42659
42781
  *
42660
42782
  * Supports:
@@ -42783,15 +42905,29 @@ var CloudTrailProvider = class {
42783
42905
  SnsTopicName: snsTopicName,
42784
42906
  IsOrganizationTrail: isOrganizationTrail
42785
42907
  }));
42786
- const newEventSelectors = properties["EventSelectors"];
42908
+ const rawEventSelectors = properties["EventSelectors"];
42909
+ let eventSelectorsUnusable = false;
42910
+ let newEventSelectors;
42911
+ if (rawEventSelectors != null) try {
42912
+ newEventSelectors = requireConfigArray(rawEventSelectors, "AWS::CloudTrail::Trail EventSelectors");
42913
+ } catch (error) {
42914
+ eventSelectorsUnusable = true;
42915
+ this.logger.warn(`${error instanceof Error ? error.message : String(error)} The trail's existing event selectors are left untouched for this update rather than reset to the AWS default.`);
42916
+ }
42787
42917
  const oldEventSelectors = previousProperties["EventSelectors"];
42788
- if (JSON.stringify(newEventSelectors) !== JSON.stringify(oldEventSelectors)) {
42789
- if (newEventSelectors && newEventSelectors.length > 0) {
42790
- this.logger.debug(`Updating event selectors for CloudTrail Trail ${logicalId}`);
42918
+ if (!eventSelectorsUnusable && JSON.stringify(newEventSelectors) !== JSON.stringify(oldEventSelectors)) {
42919
+ const isRemoval = newEventSelectors === void 0 || newEventSelectors.length === 0;
42920
+ const eventSelectorsToSend = newEventSelectors === void 0 || newEventSelectors.length === 0 ? DEFAULT_EVENT_SELECTORS : newEventSelectors;
42921
+ this.logger.debug(isRemoval ? `Resetting event selectors to the AWS default for CloudTrail Trail ${logicalId}` : `Updating event selectors for CloudTrail Trail ${logicalId}`);
42922
+ try {
42791
42923
  await this.getClient().send(new PutEventSelectorsCommand({
42792
42924
  TrailName: physicalId,
42793
- EventSelectors: newEventSelectors
42925
+ EventSelectors: [...eventSelectorsToSend]
42794
42926
  }));
42927
+ } catch (error) {
42928
+ const message = error instanceof Error ? error.message : String(error);
42929
+ if (!isRemoval || !/advanced[\s-]*event[\s-]*selector/i.test(message)) throw error;
42930
+ this.logger.warn(`CloudTrail Trail ${logicalId}: skipping the EventSelectors reset — the trail is using AdvancedEventSelectors, which AWS manages through a separate API, so there are no basic event selectors to clear (${message})`);
42795
42931
  }
42796
42932
  }
42797
42933
  const newInsightSelectors = properties["InsightSelectors"];
@@ -42803,7 +42939,8 @@ var CloudTrailProvider = class {
42803
42939
  InsightSelectors: newInsightSelectors ?? []
42804
42940
  }));
42805
42941
  }
42806
- if (isLogging !== previousProperties["IsLogging"]) if (isLogging === false) {
42942
+ const oldIsLogging = previousProperties["IsLogging"];
42943
+ if (isLogging !== void 0 && isLogging !== oldIsLogging) if (isLogging === false) {
42807
42944
  this.logger.debug(`Stopping logging for CloudTrail Trail ${logicalId}`);
42808
42945
  await this.getClient().send(new StopLoggingCommand({ Name: physicalId }));
42809
42946
  } else {
@@ -67602,7 +67739,7 @@ function createMigrateCommand() {
67602
67739
  */
67603
67740
  function buildProgram() {
67604
67741
  const program = new Command();
67605
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.278.50");
67742
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.278.52");
67606
67743
  program.hook("preAction", (_thisCommand, actionCommand) => {
67607
67744
  const { profile } = actionCommand.optsWithGlobals();
67608
67745
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;