@go-to-k/cdkd 0.281.10 → 0.281.11

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 replayWarn, $t as uploadCfnTemplate, A as green, An as normalizeAwsError, At as formatDockerLoginError, B as slowCcOperationTimeoutMs, Bt as resolveApp, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as ResourceUpdateNotSupportedError, Ct as BOOTSTRAP_MARKER_PREFIX, D as bold, Dt as validateAssetBucketName, E as formatResourceLine, Et as parseBootstrapMarker, F as clearOnUpdateRemoval, Ft as getDockerImageBySourceHash, G as getAccountInfo, Gt as resolveStateBucketWithDefaultAndSource, H as isTerminationProtectionPropagationError, Ht as resolveCaptureObservedState, I as ProviderRegistry, It as Synthesizer, J as normalizeAwsTagsToCfn, Jt as warnDeprecatedNoPrefixCliFlag, K as refStateLookupFromResource, Kt as resolveUseCdkBootstrapAssets, L as findActionableSilentDrops, Lt as synthesisStatusMessage, M as yellow, Mt as runDockerForeground, N as IAMRoleProvider, Nt as runDockerStreaming, O as cyan, Ot as validateContainerRepoName, P as collectInlinePolicyNamesManagedBySiblings, Pt as AssetManifestLoader, Q as readConfigString, Qt as findLargeInlineResources, R as findSilentDropProperties, Rt as getDefaultStateBucketName, S as extractDeploymentEventError, Sn as ResourceTimeoutError, St as AssetModeResolver, T as renderStatefulReason, Tn as StackTerminationProtectionError, Tt as getBootstrapMarkerKey, U as IntrinsicFunctionResolver, Ut as resolveSkipPrefix, V as disableInstanceApiTermination, Vt as resolveAutoAssetStorage, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefault, X as assertRegionMatch, Xt as CFN_TEMPLATE_URL_LIMIT, Y as resolveExplicitPhysicalId, Yt as CFN_TEMPLATE_BODY_LIMIT, Z as configStringRefusal, Zt as MIGRATE_TMP_PREFIX, _ as createPreDeleteFinalSnapshot, _t as WorkGraph, a as DeploymentEventsStore, an as AwsClients, at as describeTypeWithThrottleRetry, b as unsupportedFinalSnapshotError, bn as PartialFailureError, bt as loadPublishableAssetManifest, c as replayFailedOperations, cn as setAwsClients, ct as isThrottlingError, d as IMPLICIT_DELETE_DEPENDENCIES, dt as LockManager, en as expectedOwnerParam, et as requireConfigArray, f as computeImplicitDeleteEdges, ft as S3StateBackend, g as ccRoutedFinalSnapshotError, gn as LocalStartServiceError, gt as stringifyValue, h as buildFinalSnapshotIdentifier, hn as LocalMigrateError, ht as AssetPublisher, i as DeploymentEventsReader, in as resolveBucketRegion, it as DiffCalculator, j as red, jn as withErrorHandling, jt as getDockerCmd, k as gray, kt as buildDockerImage, l as replayRollback, lt as DagBuilder, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalInvokeBuildError$1, mt as shouldRetainResource, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as processStackMessages, nt as requireConfigString, o as planFailedOps, on as getAwsClients, ot as withRetry, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as DeployCancelledError, pt as rebuildClientForBucketRegion, q as WAFv2WebACLProvider, qt as stateBucketExistenceConfirmed, r as DeployEngine, rt as applyRoleArnIfSet, s as planRollback, sn as resetAwsClients, st as isRetryableTransientError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as AssemblyReader, tt as requireConfigObject, u as withResourceDeadline, un as CdkdError, ut as TemplateParser, v as isFinalSnapshotError, vn as MissingCdkCliError, vt as buildAssetRedirectMap, w as isStatefulRecreateTargetSync, wn as StackHasActiveImportsError, wt as ensureAssetStorage, x as makeCanonicalizePropertiesFn, xn as ProvisioningError, xt as rewriteTemplateAssetReferences, y as refusesFinalSnapshot, yn as NestedStackChildDirectDestroyError, yt as createAssetRedirectResolver, z as CloudControlProvider, zt as getLegacyStateBucketName } from "./deploy-engine-DMY-UXvg.js";
2
+ import { $ as replayWarn, $t as uploadCfnTemplate, A as green, An as normalizeAwsError, At as formatDockerLoginError, B as slowCcOperationTimeoutMs, Bt as resolveApp, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as ResourceUpdateNotSupportedError, Ct as BOOTSTRAP_MARKER_PREFIX, D as bold, Dt as validateAssetBucketName, E as formatResourceLine, Et as parseBootstrapMarker, F as clearOnUpdateRemoval, Ft as getDockerImageBySourceHash, G as getAccountInfo, Gt as resolveStateBucketWithDefaultAndSource, H as isTerminationProtectionPropagationError, Ht as resolveCaptureObservedState, I as ProviderRegistry, It as Synthesizer, J as normalizeAwsTagsToCfn, Jt as warnDeprecatedNoPrefixCliFlag, K as refStateLookupFromResource, Kt as resolveUseCdkBootstrapAssets, L as findActionableSilentDrops, Lt as synthesisStatusMessage, M as yellow, Mt as runDockerForeground, N as IAMRoleProvider, Nt as runDockerStreaming, O as cyan, Ot as validateContainerRepoName, P as collectInlinePolicyNamesManagedBySiblings, Pt as AssetManifestLoader, Q as readConfigString, Qt as findLargeInlineResources, R as findSilentDropProperties, Rt as getDefaultStateBucketName, S as extractDeploymentEventError, Sn as ResourceTimeoutError, St as AssetModeResolver, T as renderStatefulReason, Tn as StackTerminationProtectionError, Tt as getBootstrapMarkerKey, U as IntrinsicFunctionResolver, Ut as resolveSkipPrefix, V as disableInstanceApiTermination, Vt as resolveAutoAssetStorage, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefault, X as assertRegionMatch, Xt as CFN_TEMPLATE_URL_LIMIT, Y as resolveExplicitPhysicalId, Yt as CFN_TEMPLATE_BODY_LIMIT, Z as configStringRefusal, Zt as MIGRATE_TMP_PREFIX, _ as createPreDeleteFinalSnapshot, _t as WorkGraph, a as DeploymentEventsStore, an as AwsClients, at as describeTypeWithThrottleRetry, b as unsupportedFinalSnapshotError, bn as PartialFailureError, bt as loadPublishableAssetManifest, c as replayFailedOperations, cn as setAwsClients, ct as isThrottlingError, d as IMPLICIT_DELETE_DEPENDENCIES, dt as LockManager, en as expectedOwnerParam, et as requireConfigArray, f as computeImplicitDeleteEdges, ft as S3StateBackend, g as ccRoutedFinalSnapshotError, gn as LocalStartServiceError, gt as stringifyValue, h as buildFinalSnapshotIdentifier, hn as LocalMigrateError, ht as AssetPublisher, i as DeploymentEventsReader, in as resolveBucketRegion, it as DiffCalculator, j as red, jn as withErrorHandling, jt as getDockerCmd, k as gray, kt as buildDockerImage, l as replayRollback, lt as DagBuilder, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalInvokeBuildError$1, mt as shouldRetainResource, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as processStackMessages, nt as requireConfigString, o as planFailedOps, on as getAwsClients, ot as withRetry, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as DeployCancelledError, pt as rebuildClientForBucketRegion, q as WAFv2WebACLProvider, qt as stateBucketExistenceConfirmed, r as DeployEngine, rt as applyRoleArnIfSet, s as planRollback, sn as resetAwsClients, st as isRetryableTransientError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as AssemblyReader, tt as requireConfigObject, u as withResourceDeadline, un as CdkdError, ut as TemplateParser, v as isFinalSnapshotError, vn as MissingCdkCliError, vt as buildAssetRedirectMap, w as isStatefulRecreateTargetSync, wn as StackHasActiveImportsError, wt as ensureAssetStorage, x as makeCanonicalizePropertiesFn, xn as ProvisioningError, xt as rewriteTemplateAssetReferences, y as refusesFinalSnapshot, yn as NestedStackChildDirectDestroyError, yt as createAssetRedirectResolver, z as CloudControlProvider, zt as getLegacyStateBucketName } from "./deploy-engine-BErTJjXl.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-mWcJAGAu.js";
4
+ import { t as ASGProvider } from "./asg-provider-AKp6xuP0.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";
@@ -6074,6 +6074,63 @@ var S3BucketProvider = class S3BucketProvider {
6074
6074
  return config;
6075
6075
  }
6076
6076
  /**
6077
+ * True when the DESIRED side DECLARES the property but its collection is
6078
+ * empty — the shape {@link emptyListConfigToUndefined} folds to `undefined`
6079
+ * and therefore cannot be told apart from an ABSENT property downstream
6080
+ * (issue #1713).
6081
+ *
6082
+ * That collapse is the whole defect. `OwnershipControls` /
6083
+ * `BucketEncryption` normalize BOTH sides through the fold before
6084
+ * `diffSubConfig`, so a non-empty previous against a declared-but-empty
6085
+ * desired took the **onDelete** arm and issued
6086
+ * `DeleteBucketOwnershipControls` / `DeleteBucketEncryption` — where the
6087
+ * lifecycle / CORS siblings SKIP the Put and leave the live configuration
6088
+ * alone (issue #1671). Measured against live CloudFormation (us-east-1,
6089
+ * 2026-08-12): updating a deployed bucket from an `aws:kms` default and a
6090
+ * `BucketOwnerPreferred` rule to `ServerSideEncryptionConfiguration: []` /
6091
+ * `Rules: []` drives the stack to `UPDATE_ROLLBACK_COMPLETE` with
6092
+ * `The XML you provided was not well-formed or did not validate against our
6093
+ * published schema`, and BOTH live configurations survive unchanged. So CFn
6094
+ * treats the empty collection as an INVALID template, not as a removal —
6095
+ * the same answer the #1671 A/B produced for lifecycle / CORS on the same
6096
+ * date and account — and cdkd was DELETING instead. For `BucketEncryption`
6097
+ * that silently drops a declared `aws:kms` default down to SSE-S3 / AES256
6098
+ * on a template whose only fault is a condition-pruned or
6099
+ * intrinsic-collapsed array.
6100
+ *
6101
+ * The fold itself is load-bearing and is NOT what changes here:
6102
+ * `readCurrentState` ALWAYS emits
6103
+ * `BucketEncryption: { ServerSideEncryptionConfiguration: [] }` and
6104
+ * `OwnershipControls: { Rules: [] }` for a bucket with no explicit setting,
6105
+ * so `cdkd drift --revert` feeds that placeholder back through `update()`
6106
+ * and both sides must keep normalizing for empty-vs-empty to compare EQUAL
6107
+ * and issue no call at all. This predicate rides alongside it and only
6108
+ * splits the arm the fold reaches: **declared-but-empty SKIPS, absent
6109
+ * DELETES**. A removal therefore still works — dropping the whole property
6110
+ * from the template is what expresses it, which is exactly what
6111
+ * `emptyCollectionSkip`'s warning tells the user.
6112
+ *
6113
+ * **Scoped to the shape #1713 MEASURED — the list key PRESENT and EMPTY —
6114
+ * and no wider.** The tempting spelling is "present, and the fold erased it",
6115
+ * i.e. delegate to {@link emptyListConfigToUndefined}. That is wrong here:
6116
+ * the fold ALSO erases a bare `{}`, which issue #1466 pinned as a REMOVAL and
6117
+ * #1713's live A/B did not exercise, so delegating would have reversed that
6118
+ * contract on evidence that does not cover it — caught when its pinned row
6119
+ * failed. (`{listKey: null}` as the sole key is NOT folded — the block
6120
+ * carries one key, so `emptyListConfigToUndefined` passes it through as
6121
+ * MALFORMED; an earlier draft of this comment claimed it was, which the
6122
+ * type's own `'{Rules: null} as the SOLE key is malformed'` test contradicts.)
6123
+ *
6124
+ * A MALFORMED block is out of scope for a different reason and needs no
6125
+ * clause here: the fold passes it through unchanged, so it never reaches the
6126
+ * Delete arm at all and is refused by name by the apply call.
6127
+ */
6128
+ static declaresEmptyCollection(config, listKey) {
6129
+ if (typeof config !== "object" || config === null || Array.isArray(config)) return false;
6130
+ const list = config[listKey];
6131
+ return Array.isArray(list) && list.length === 0;
6132
+ }
6133
+ /**
6077
6134
  * Turn a set of per-property overrides into the `effectiveProperties` bag the
6078
6135
  * deploy engine records in place of the desired one (issues #1612 / #1670).
6079
6136
  *
@@ -6327,7 +6384,7 @@ var S3BucketProvider = class S3BucketProvider {
6327
6384
  * direction: a later template that REMOVES the block would then derive no
6328
6385
  * removal and the live configuration would survive forever.
6329
6386
  */
6330
- async applySubConfigDiffs(bucketName, properties, previousProperties) {
6387
+ async applySubConfigDiffs(bucketName, properties, previousProperties, context) {
6331
6388
  const overrides = /* @__PURE__ */ new Map();
6332
6389
  /** Record a WHOLE-BLOCK skip: the effective value is the previous one. */
6333
6390
  const retainPrevious = (key) => {
@@ -6383,16 +6440,31 @@ var S3BucketProvider = class S3BucketProvider {
6383
6440
  if (versioningRefusal === void 0 && versioningChanged && nextVersioning != null && desiredVersioningStatus !== "Suspended") {
6384
6441
  if (!await this.applyVersioning(bucketName, nextVersioning, (m) => this.logger.warn(m))) retainPrevious("VersioningConfiguration");
6385
6442
  }
6443
+ const ownershipEmptyDesired = S3BucketProvider.declaresEmptyCollection(properties["OwnershipControls"], "Rules");
6386
6444
  await this.diffSubConfig(bucketName, S3BucketProvider.emptyListConfigToUndefined(previousProperties["OwnershipControls"], "Rules"), S3BucketProvider.emptyListConfigToUndefined(properties["OwnershipControls"], "Rules"), async (cfg) => this.applyOwnershipControls(bucketName, cfg), async () => {
6445
+ if (ownershipEmptyDesired && context?.desiredFromAwsReadback !== true) {
6446
+ this.emptyCollectionSkip("OwnershipControls", "OwnershipControls.Rules", previousProperties, retainPrevious);
6447
+ return;
6448
+ }
6387
6449
  await this.s3Client.send(new DeleteBucketOwnershipControlsCommand({ Bucket: bucketName }));
6388
6450
  this.logger.debug(`Deleted ownership controls on bucket ${bucketName}`);
6389
6451
  });
6452
+ const encryptionEmptyDesired = S3BucketProvider.declaresEmptyCollection(properties["BucketEncryption"], "ServerSideEncryptionConfiguration");
6390
6453
  await this.diffSubConfig(bucketName, S3BucketProvider.emptyListConfigToUndefined(previousProperties["BucketEncryption"], "ServerSideEncryptionConfiguration"), S3BucketProvider.emptyListConfigToUndefined(properties["BucketEncryption"], "ServerSideEncryptionConfiguration"), async (cfg) => this.applyBucketEncryption(bucketName, cfg), async () => {
6454
+ if (encryptionEmptyDesired && context?.desiredFromAwsReadback !== true) {
6455
+ this.emptyCollectionSkip("BucketEncryption", "BucketEncryption.ServerSideEncryptionConfiguration", previousProperties, retainPrevious);
6456
+ return;
6457
+ }
6391
6458
  await this.s3Client.send(new DeleteBucketEncryptionCommand({ Bucket: bucketName }));
6392
6459
  this.logger.debug(`Deleted bucket encryption on bucket ${bucketName}`);
6393
6460
  });
6394
6461
  await this.diffSubConfig(bucketName, previousProperties["LifecycleConfiguration"], properties["LifecycleConfiguration"], async (cfg) => {
6395
6462
  if (!cfg.Rules || !Array.isArray(cfg.Rules) || cfg.Rules.length === 0) {
6463
+ if (context?.desiredFromAwsReadback === true) {
6464
+ await this.s3Client.send(new DeleteBucketLifecycleCommand({ Bucket: bucketName }));
6465
+ this.logger.debug(`Deleted lifecycle configuration on bucket ${bucketName} (reverting to an unset baseline)`);
6466
+ return;
6467
+ }
6396
6468
  this.emptyCollectionSkip("LifecycleConfiguration", "LifecycleConfiguration.Rules", previousProperties, retainPrevious);
6397
6469
  return;
6398
6470
  }
@@ -6403,6 +6475,11 @@ var S3BucketProvider = class S3BucketProvider {
6403
6475
  });
6404
6476
  await this.diffSubConfig(bucketName, previousProperties["CorsConfiguration"], properties["CorsConfiguration"], async (cfg) => {
6405
6477
  if (!cfg.CorsRules || !Array.isArray(cfg.CorsRules) || cfg.CorsRules.length === 0) {
6478
+ if (context?.desiredFromAwsReadback === true) {
6479
+ await this.s3Client.send(new DeleteBucketCorsCommand({ Bucket: bucketName }));
6480
+ this.logger.debug(`Deleted CORS configuration on bucket ${bucketName} (reverting to an unset baseline)`);
6481
+ return;
6482
+ }
6406
6483
  this.emptyCollectionSkip("CorsConfiguration", "CorsConfiguration.CorsRules", previousProperties, retainPrevious);
6407
6484
  return;
6408
6485
  }
@@ -6613,7 +6690,7 @@ var S3BucketProvider = class S3BucketProvider {
6613
6690
  /**
6614
6691
  * Update an S3 bucket
6615
6692
  */
6616
- async update(logicalId, physicalId, resourceType, properties, previousProperties) {
6693
+ async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
6617
6694
  this.logger.debug(`Updating S3 bucket ${logicalId}: ${physicalId}`);
6618
6695
  const newBucketName = properties["BucketName"];
6619
6696
  if (newBucketName && newBucketName !== physicalId) {
@@ -6628,7 +6705,7 @@ var S3BucketProvider = class S3BucketProvider {
6628
6705
  skipTags: true,
6629
6706
  skipDiffManaged: true
6630
6707
  });
6631
- for (const [key, value] of await this.applySubConfigDiffs(physicalId, properties, previousProperties)) effectiveOverrides.set(key, value);
6708
+ for (const [key, value] of await this.applySubConfigDiffs(physicalId, properties, previousProperties, context)) effectiveOverrides.set(key, value);
6632
6709
  await this.applyTagDiff(physicalId, previousProperties["Tags"], properties["Tags"]);
6633
6710
  const attributes = await this.buildAttributes(physicalId);
6634
6711
  this.logger.debug(`Successfully updated S3 bucket ${logicalId}`);
@@ -56251,7 +56328,7 @@ async function runRevert(reports, providerRegistry, stateBackend, stateConfig, a
56251
56328
  const desiredProperties = stateResource.observedProperties ?? stateResource.properties ?? {};
56252
56329
  const newProperties = buildRevertNewProperties(outcome.changes, desiredProperties, outcome.awsProperties, { preserveUntemplated: stateResource.observedProperties === void 0 });
56253
56330
  try {
56254
- const updateResult = await withRetry(() => provider.update(outcome.logicalId, stateResource.physicalId, outcome.resourceType, newProperties, outcome.awsProperties), outcome.logicalId, { logger: { debug: (msg) => logger.debug(msg) } });
56331
+ const updateResult = await withRetry(() => provider.update(outcome.logicalId, stateResource.physicalId, outcome.resourceType, newProperties, outcome.awsProperties, { desiredFromAwsReadback: true }), outcome.logicalId, { logger: { debug: (msg) => logger.debug(msg) } });
56255
56332
  totalSucceeded++;
56256
56333
  logger.info(` ✓ ${report.stackName}/${outcome.logicalId} (${outcome.resourceType}): reverted.`);
56257
56334
  try {
@@ -73436,7 +73513,7 @@ function createMigrateCommand() {
73436
73513
  */
73437
73514
  function buildProgram() {
73438
73515
  const program = new Command();
73439
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.10");
73516
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.11");
73440
73517
  program.hook("preAction", (_thisCommand, actionCommand) => {
73441
73518
  const { profile } = actionCommand.optsWithGlobals();
73442
73519
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;