@go-to-k/cdkd 0.280.13 → 0.280.15

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 applyRoleArnIfSet, A as red, At as AssetManifestLoader, B as isTerminationProtectionPropagationError, Bt as resolveStateBucketWithDefault, C as isStatefulRecreateTargetSync, Ct as validateAssetBucketName, D as cyan, Dn as withErrorHandling, Dt as getDockerCmd, E as bold, En as normalizeAwsError, Et as formatDockerLoginError, F as ProviderRegistry, Ft as getLegacyStateBucketName, G as normalizeAwsTagsToCfn, Gt as CFN_TEMPLATE_BODY_LIMIT, H as cfnRefValueFromPhysicalId, Ht as resolveUseCdkBootstrapAssets, I as findActionableSilentDrops, It as resolveApp, J as readConfigString, Jt as findLargeInlineResources, K as resolveExplicitPhysicalId, Kt as CFN_TEMPLATE_URL_LIMIT, L as CloudControlProvider, Lt as resolveAutoAssetStorage, M as IAMRoleProvider, Mt as Synthesizer, N as collectInlinePolicyNamesManagedBySiblings, Nt as synthesisStatusMessage, O as gray, Ot as runDockerForeground, P as clearOnUpdateRemoval, Pt as getDefaultStateBucketName, Q as requireConfigString, Qt as processStackMessages, R as slowCcOperationTimeoutMs, Rt as resolveCaptureObservedState, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, St as parseBootstrapMarker, T as formatResourceLine, Tt as buildDockerImage, U as refStateLookupFromResource, Ut as stateBucketExistenceConfirmed, V as IntrinsicFunctionResolver, Vt as resolveStateBucketWithDefaultAndSource, W as WAFv2WebACLProvider, Wt as warnDeprecatedNoPrefixCliFlag, X as requireConfigArray, Xt as expectedOwnerParam, Y as replayWarn, Yt as uploadCfnTemplate, Z as requireConfigObject, Zt as AssemblyReader, _ as createPreDeleteFinalSnapshot, _n as ProvisioningError, _t as rewriteTemplateAssetReferences, a as DeploymentEventsStore, at as DagBuilder, b as unsupportedFinalSnapshotError, bn as StackHasActiveImportsError, bt as ensureAssetStorage, c as replayFailedOperations, ct as S3StateBackend, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalMigrateError, dt as AssetPublisher, en as resolveBucketRegion, et as DiffCalculator, f as computeImplicitDeleteEdges, fn as LocalStartServiceError, ft as stringifyValue, g as ccRoutedFinalSnapshotError, gn as PartialFailureError, gt as loadPublishableAssetManifest, h as buildFinalSnapshotIdentifier, hn as NestedStackChildDirectDestroyError, ht as createAssetRedirectResolver, i as DeploymentEventsReader, in as setAwsClients, it as isThrottlingError, j as yellow, jt as getDockerImageBySourceHash, k as green, kt as runDockerStreaming, l as replayRollback, ln as DeployCancelledError, lt as rebuildClientForBucketRegion, m as PRE_DELETE_SNAPSHOT_TYPES, mn as MissingCdkCliError, mt as buildAssetRedirectMap, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as getAwsClients, nt as withRetry, o as planFailedOps, on as CdkdError, ot as TemplateParser, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pt as WorkGraph, q as assertRegionMatch, qt as MIGRATE_TMP_PREFIX, r as DeployEngine, rn as resetAwsClients, rt as isRetryableTransientError, s as planRollback, st as LockManager, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as AwsClients, tt as describeTypeWithThrottleRetry, u as withResourceDeadline, un as LocalInvokeBuildError$1, ut as shouldRetainResource, v as isFinalSnapshotError, vn as ResourceTimeoutError, vt as AssetModeResolver, w as renderStatefulReason, wt as validateContainerRepoName, x as extractDeploymentEventError, xn as StackTerminationProtectionError, xt as getBootstrapMarkerKey, y as refusesFinalSnapshot, yn as ResourceUpdateNotSupportedError, yt as BOOTSTRAP_MARKER_PREFIX, z as disableInstanceApiTermination, zt as resolveSkipPrefix } from "./deploy-engine-CE-J9Vlu.js";
2
+ import { $ as requireConfigString, $t as processStackMessages, A as red, At as runDockerStreaming, B as isTerminationProtectionPropagationError, Bt as resolveSkipPrefix, C as isStatefulRecreateTargetSync, Ct as parseBootstrapMarker, D as cyan, Dn as normalizeAwsError, Dt as formatDockerLoginError, E as bold, Et as buildDockerImage, F as ProviderRegistry, Ft as getDefaultStateBucketName, G as normalizeAwsTagsToCfn, Gt as warnDeprecatedNoPrefixCliFlag, H as cfnRefValueFromPhysicalId, Ht as resolveStateBucketWithDefaultAndSource, I as findActionableSilentDrops, It as getLegacyStateBucketName, J as configStringRefusal, Jt as MIGRATE_TMP_PREFIX, K as resolveExplicitPhysicalId, Kt as CFN_TEMPLATE_BODY_LIMIT, L as CloudControlProvider, Lt as resolveApp, M as IAMRoleProvider, Mt as getDockerImageBySourceHash, N as collectInlinePolicyNamesManagedBySiblings, Nt as Synthesizer, O as gray, On as withErrorHandling, Ot as getDockerCmd, P as clearOnUpdateRemoval, Pt as synthesisStatusMessage, Q as requireConfigObject, Qt as AssemblyReader, R as slowCcOperationTimeoutMs, Rt as resolveAutoAssetStorage, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, Sn as StackTerminationProtectionError, St as getBootstrapMarkerKey, T as formatResourceLine, Tt as validateContainerRepoName, U as refStateLookupFromResource, Ut as resolveUseCdkBootstrapAssets, V as IntrinsicFunctionResolver, Vt as resolveStateBucketWithDefault, W as WAFv2WebACLProvider, Wt as stateBucketExistenceConfirmed, X as replayWarn, Xt as uploadCfnTemplate, Y as readConfigString, Yt as findLargeInlineResources, Z as requireConfigArray, Zt as expectedOwnerParam, _ as createPreDeleteFinalSnapshot, _n as PartialFailureError, _t as loadPublishableAssetManifest, a as DeploymentEventsStore, an as setAwsClients, at as isThrottlingError, b as unsupportedFinalSnapshotError, bn as ResourceUpdateNotSupportedError, bt as BOOTSTRAP_MARKER_PREFIX, c as replayFailedOperations, ct as LockManager, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalInvokeBuildError$1, dt as shouldRetainResource, et as applyRoleArnIfSet, f as computeImplicitDeleteEdges, fn as LocalMigrateError, ft as AssetPublisher, g as ccRoutedFinalSnapshotError, gn as NestedStackChildDirectDestroyError, gt as createAssetRedirectResolver, h as buildFinalSnapshotIdentifier, hn as MissingCdkCliError, ht as buildAssetRedirectMap, i as DeploymentEventsReader, in as resetAwsClients, it as isRetryableTransientError, j as yellow, jt as AssetManifestLoader, k as green, kt as runDockerForeground, l as replayRollback, lt as S3StateBackend, m as PRE_DELETE_SNAPSHOT_TYPES, mt as WorkGraph, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as AwsClients, nt as describeTypeWithThrottleRetry, o as planFailedOps, ot as DagBuilder, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalStartServiceError, pt as stringifyValue, q as assertRegionMatch, qt as CFN_TEMPLATE_URL_LIMIT, r as DeployEngine, rn as getAwsClients, rt as withRetry, s as planRollback, sn as CdkdError, st as TemplateParser, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as resolveBucketRegion, tt as DiffCalculator, u as withResourceDeadline, un as DeployCancelledError, ut as rebuildClientForBucketRegion, v as isFinalSnapshotError, vn as ProvisioningError, vt as rewriteTemplateAssetReferences, w as renderStatefulReason, wt as validateAssetBucketName, x as extractDeploymentEventError, xn as StackHasActiveImportsError, xt as ensureAssetStorage, y as refusesFinalSnapshot, yn as ResourceTimeoutError, yt as AssetModeResolver, z as disableInstanceApiTermination, zt as resolveCaptureObservedState } from "./deploy-engine-CJPLgh5z.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-DJSCLI9C.js";
4
+ import { t as ASGProvider } from "./asg-provider-BRvHsDmu.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";
@@ -5065,6 +5065,40 @@ var S3BucketProvider = class S3BucketProvider {
5065
5065
  this.logger.debug(`Applied CORS configuration to bucket ${bucketName}`);
5066
5066
  }
5067
5067
  /**
5068
+ * The per-item / per-rule STRING guard, with the applier's own SKIP as the
5069
+ * replay downgrade (issue #1595).
5070
+ *
5071
+ * Four per-item reads in this file refuse a malformed configuration ITEM
5072
+ * through a `readConfigString` that carries no `onUnusable`, so they threw on
5073
+ * the state-replay paths too — the un-rollbackable refusal every container
5074
+ * guard beside them exists to avoid. What they must NOT do instead is take
5075
+ * `readConfigString`'s own downgrade: its fallback is applied to a LIVE
5076
+ * resource, and each of these defaults ENABLES something (a lifecycle
5077
+ * expiration rule, an intelligent-tiering transition, a replication rule),
5078
+ * so warn-and-default is worse than the refusal it replaces. The correct
5079
+ * downgrade is the SKIP the sibling container guards already perform, with
5080
+ * the same per-applier unit — whole Put where the Put replaces every rule,
5081
+ * the single configuration item where the Put is per-Id.
5082
+ *
5083
+ * Returns `true` when the caller must skip. On the CREATE path (`onUnusable`
5084
+ * absent) it always returns `false` and the original read below still
5085
+ * throws, so template-borne behavior is unchanged.
5086
+ *
5087
+ * No `ConfigStringOptions` passthrough, and that is a decision rather than an
5088
+ * omission: a probe whose relaxations disagree with the read it fronts would
5089
+ * refuse exactly where the read accepts. All four sites are ENUM-valued
5090
+ * (`Status` / `IncludedObjectVersions`), so `coerceNumber` is wrong for them
5091
+ * by the rule in `config-shape.ts`'s header — a number where an enum belongs
5092
+ * is a bug. A site that ever needs an option must thread the SAME bag here.
5093
+ */
5094
+ skipOnUnusableConfigString(container, key, fallback, containerPath, skipClause, onUnusable) {
5095
+ if (!onUnusable) return false;
5096
+ const refusal = configStringRefusal(container, key, fallback, containerPath);
5097
+ if (refusal === void 0) return false;
5098
+ onUnusable(`${refusal}. ${skipClause}; the same value is REFUSED on a template-path create`);
5099
+ return true;
5100
+ }
5101
+ /**
5068
5102
  * Apply lifecycle configuration
5069
5103
  *
5070
5104
  * CFn property: LifecycleConfiguration.Rules[]
@@ -5083,6 +5117,7 @@ var S3BucketProvider = class S3BucketProvider {
5083
5117
  if (rawTagFilters != null) {
5084
5118
  if (requireConfigArray(rawTagFilters, "AWS::S3::Bucket LifecycleConfiguration.Rules[].TagFilters", { ...onUnusable ? { onUnusable } : {} }) === void 0) return;
5085
5119
  }
5120
+ if (this.skipOnUnusableConfigString(rule, "Status", "Enabled", "AWS::S3::Bucket LifecycleConfiguration.Rules[]", "Leaving the whole lifecycle configuration unapplied here", onUnusable)) return;
5086
5121
  }
5087
5122
  const gatherScope = (rule) => {
5088
5123
  const filter = rule["Filter"];
@@ -5511,6 +5546,7 @@ var S3BucketProvider = class S3BucketProvider {
5511
5546
  async applyIntelligentTieringConfigurations(bucketName, configs, onUnusable) {
5512
5547
  for (const config of configs) {
5513
5548
  const id = config["Id"];
5549
+ if (this.skipOnUnusableConfigString(config, "Status", "Enabled", "AWS::S3::Bucket IntelligentTieringConfigurations[]", "Skipping this intelligent tiering configuration", onUnusable)) continue;
5514
5550
  const tierings = config["Tierings"];
5515
5551
  const itConfig = {
5516
5552
  Id: id,
@@ -5547,6 +5583,7 @@ var S3BucketProvider = class S3BucketProvider {
5547
5583
  async applyInventoryConfigurations(bucketName, configs, onUnusable) {
5548
5584
  for (const config of configs) {
5549
5585
  const id = config["Id"];
5586
+ if (this.skipOnUnusableConfigString(config, "IncludedObjectVersions", "All", "AWS::S3::Bucket InventoryConfigurations[]", "Skipping this inventory configuration", onUnusable)) continue;
5550
5587
  const inventoryDestPath = "AWS::S3::Bucket InventoryConfigurations[].Destination";
5551
5588
  const rawDest = config["Destination"];
5552
5589
  const s3Dest = this.resolveS3BucketDestination(rawDest, inventoryDestPath, onUnusable);
@@ -5635,6 +5672,7 @@ var S3BucketProvider = class S3BucketProvider {
5635
5672
  for (const rule of rules || []) {
5636
5673
  const rawFilter = rule["Filter"];
5637
5674
  if (rawFilter != null && requireConfigObject(rawFilter, "AWS::S3::Bucket ReplicationConfiguration.Rules[].Filter", { ...onUnusable ? { onUnusable } : {} }) === void 0) return;
5675
+ if (this.skipOnUnusableConfigString(rule, "Status", "Enabled", "AWS::S3::Bucket ReplicationConfiguration.Rules[]", "Leaving the whole replication configuration unapplied here", onUnusable)) return;
5638
5676
  }
5639
5677
  await this.s3Client.send(new PutBucketReplicationCommand({
5640
5678
  Bucket: bucketName,
@@ -11658,6 +11696,28 @@ function mapSSESpecification(raw) {
11658
11696
  return out;
11659
11697
  }
11660
11698
  /**
11699
+ * Read one capacity member out of a per-index `ProvisionedThroughput` block,
11700
+ * returning `undefined` for anything that is not a usable number.
11701
+ *
11702
+ * Deliberately has NO default (issue #1588 review). The BillingMode-flip caller
11703
+ * suppresses the per-index update path for every index it handles, so a
11704
+ * defaulted capacity would never be corrected by a later call and would land in
11705
+ * cdkd state as if the template had declared it. Returning `undefined` routes
11706
+ * the index to the same warn-and-omit path an absent block takes, letting AWS
11707
+ * name it — the CFn-handler outcome.
11708
+ *
11709
+ * CFn is stringly typed, so a numeric string is accepted and coerced; `NaN` /
11710
+ * `Infinity` / objects / unresolved intrinsics are not.
11711
+ */
11712
+ function readCapacityNumber(block, member) {
11713
+ if (typeof block !== "object" || block === null || Array.isArray(block)) return void 0;
11714
+ const raw = block[member];
11715
+ if (raw === void 0 || raw === null || raw === "") return void 0;
11716
+ if (typeof raw !== "number" && typeof raw !== "string") return void 0;
11717
+ const value = Number(raw);
11718
+ return Number.isFinite(value) ? value : void 0;
11719
+ }
11720
+ /**
11661
11721
  * `DescribeTable` poll budget (seconds, 1 poll/s) after an ordinary
11662
11722
  * `UpdateTable` — capacity, TTL, tags, table class. Calibrated on those and
11663
11723
  * sufficient for them.
@@ -11797,7 +11857,8 @@ var DynamoDBTableProvider = class {
11797
11857
  } });
11798
11858
  const billingMode = billingModeUnusable ? prevBillingMode : requestedBillingMode;
11799
11859
  const billingOrThroughputChanged = billingMode !== prevBillingMode || JSON.stringify(properties["ProvisionedThroughput"]) !== JSON.stringify(previousProperties["ProvisionedThroughput"]);
11800
- if (billingMode === "PROVISIONED" && prevBillingMode === "PAY_PER_REQUEST" && properties["OnDemandThroughput"] !== void 0) throw new ProvisioningError(`AWS::DynamoDB::Table ${logicalId}: the template flips BillingMode to PROVISIONED${properties["BillingMode"] === void 0 ? " (BillingMode is absent from the template, which CloudFormation resets to PROVISIONED)" : ""} while still declaring OnDemandThroughput, which AWS accepts only on a PAY_PER_REQUEST table. Nothing was applied. Remove OnDemandThroughput, or keep BillingMode: PAY_PER_REQUEST.`, logicalId, resourceType);
11860
+ if (billingOrThroughputChanged && billingMode === "PROVISIONED" && (prevBillingMode === "PAY_PER_REQUEST" || liveBillingMode === "PAY_PER_REQUEST") && properties["OnDemandThroughput"] !== void 0) throw new ProvisioningError(`AWS::DynamoDB::Table ${logicalId}: the template flips BillingMode to PROVISIONED${properties["BillingMode"] === void 0 ? " (BillingMode is absent from the template, which CloudFormation resets to PROVISIONED)" : ""} while still declaring OnDemandThroughput, which AWS accepts only on a PAY_PER_REQUEST table. Nothing was applied. Remove OnDemandThroughput, or keep BillingMode: PAY_PER_REQUEST.`, logicalId, resourceType);
11861
+ const gsiHandledByBillingFlip = /* @__PURE__ */ new Set();
11801
11862
  if (billingOrThroughputChanged || tableClassChanged) {
11802
11863
  const updateInput = { TableName: physicalId };
11803
11864
  if (billingOrThroughputChanged) updateInput.BillingMode = billingMode;
@@ -11809,6 +11870,38 @@ var DynamoDBTableProvider = class {
11809
11870
  WriteCapacityUnits: Number(pt["WriteCapacityUnits"] ?? 5)
11810
11871
  };
11811
11872
  }
11873
+ const liveIndexes = table?.GlobalSecondaryIndexes ?? [];
11874
+ if (billingOrThroughputChanged && billingMode === "PROVISIONED" && liveBillingMode === "PAY_PER_REQUEST" && liveIndexes.length > 0) {
11875
+ const desiredIndexes = Array.isArray(properties["GlobalSecondaryIndexes"]) ? properties["GlobalSecondaryIndexes"] : [];
11876
+ const desiredByName = /* @__PURE__ */ new Map();
11877
+ for (const entry of desiredIndexes) {
11878
+ const name = entry?.["IndexName"];
11879
+ if (typeof name === "string") desiredByName.set(name, entry);
11880
+ }
11881
+ const indexUpdates = [];
11882
+ const unspecified = [];
11883
+ for (const live of liveIndexes) {
11884
+ const indexName = live.IndexName;
11885
+ if (typeof indexName !== "string") continue;
11886
+ const declared = desiredByName.get(indexName)?.["ProvisionedThroughput"];
11887
+ const read = readCapacityNumber(declared, "ReadCapacityUnits");
11888
+ const write = readCapacityNumber(declared, "WriteCapacityUnits");
11889
+ if (read === void 0 || write === void 0) {
11890
+ unspecified.push(indexName);
11891
+ continue;
11892
+ }
11893
+ indexUpdates.push({ Update: {
11894
+ IndexName: indexName,
11895
+ ProvisionedThroughput: {
11896
+ ReadCapacityUnits: read,
11897
+ WriteCapacityUnits: write
11898
+ }
11899
+ } });
11900
+ gsiHandledByBillingFlip.add(indexName);
11901
+ }
11902
+ if (indexUpdates.length > 0) updateInput.GlobalSecondaryIndexUpdates = indexUpdates;
11903
+ if (unspecified.length > 0) this.logger.warn(`AWS::DynamoDB::Table ${logicalId}: flipping BillingMode to PROVISIONED, but the template declares no usable ProvisionedThroughput for live index(es) ${unspecified.join(", ")}. AWS requires per-index capacity in the same UpdateTable and will reject the flip naming them. Declare GlobalSecondaryIndexes[].ProvisionedThroughput (both ReadCapacityUnits and WriteCapacityUnits) for each. If an index is listed here because this deploy REMOVES it, drop it in a separate deploy BEFORE the flip — AWS demands capacity for every index still live at flip time, so the two cannot be combined.`);
11904
+ }
11812
11905
  await this.dynamoDBClient.send(new UpdateTableCommand(updateInput));
11813
11906
  if (billingMode !== liveBillingMode) await this.waitForTableAndIndexesActive(physicalId, BILLING_FLIP_ACTIVE_WAIT_ATTEMPTS);
11814
11907
  else await this.waitForTableActiveAfterUpdate(physicalId, TABLE_ACTIVE_WAIT_ATTEMPTS);
@@ -11885,7 +11978,7 @@ var DynamoDBTableProvider = class {
11885
11978
  this.logger.debug(`Disabled DynamoDB Stream on table ${physicalId}`);
11886
11979
  }
11887
11980
  }
11888
- if (JSON.stringify(properties["GlobalSecondaryIndexes"]) !== JSON.stringify(previousProperties["GlobalSecondaryIndexes"])) await this.applyGsiUpdates(physicalId, resourceType, logicalId, previousProperties["GlobalSecondaryIndexes"], properties["GlobalSecondaryIndexes"], properties["AttributeDefinitions"]);
11981
+ if (JSON.stringify(properties["GlobalSecondaryIndexes"]) !== JSON.stringify(previousProperties["GlobalSecondaryIndexes"])) await this.applyGsiUpdates(physicalId, resourceType, logicalId, previousProperties["GlobalSecondaryIndexes"], properties["GlobalSecondaryIndexes"], properties["AttributeDefinitions"], gsiHandledByBillingFlip);
11889
11982
  if (JSON.stringify(properties["PointInTimeRecoverySpecification"]) !== JSON.stringify(previousProperties["PointInTimeRecoverySpecification"])) await this.applyPointInTimeRecovery(physicalId, properties["PointInTimeRecoverySpecification"], previousProperties["PointInTimeRecoverySpecification"]);
11890
11983
  if (JSON.stringify(properties["TimeToLiveSpecification"]) !== JSON.stringify(previousProperties["TimeToLiveSpecification"])) {
11891
11984
  this.assertNoActiveTtlAttributeNameChange(logicalId, resourceType, physicalId, properties["TimeToLiveSpecification"], previousProperties["TimeToLiveSpecification"]);
@@ -12323,7 +12416,7 @@ var DynamoDBTableProvider = class {
12323
12416
  * a remove-then-add pair, so this method throws on such a change rather than
12324
12417
  * silently dropping it.
12325
12418
  */
12326
- async applyGsiUpdates(physicalId, resourceType, logicalId, previousGsis, desiredGsis, desiredAttributeDefinitions) {
12419
+ async applyGsiUpdates(physicalId, resourceType, logicalId, previousGsis, desiredGsis, desiredAttributeDefinitions, handledByBillingFlip = /* @__PURE__ */ new Set()) {
12327
12420
  const prev = previousGsis ?? [];
12328
12421
  const desired = desiredGsis ?? [];
12329
12422
  const prevByName = new Map(prev.filter((g) => g.IndexName).map((g) => [g.IndexName, g]));
@@ -12342,7 +12435,7 @@ var DynamoDBTableProvider = class {
12342
12435
  } else {
12343
12436
  const before = prevByName.get(name);
12344
12437
  if (JSON.stringify(before.KeySchema) !== JSON.stringify(gsi.KeySchema) || JSON.stringify(before.Projection) !== JSON.stringify(gsi.Projection)) throw new ProvisioningError(`GlobalSecondaryIndex ${name} on DynamoDB table ${logicalId} changed its KeySchema or Projection, which DynamoDB cannot modify in place. Rename the index (so it is dropped and re-created) or replace the table.`, resourceType, logicalId, physicalId);
12345
- if (gsi.ProvisionedThroughput && JSON.stringify(before.ProvisionedThroughput) !== JSON.stringify(gsi.ProvisionedThroughput)) ops.push({ Update: {
12438
+ if (gsi.ProvisionedThroughput && !handledByBillingFlip.has(name) && JSON.stringify(before.ProvisionedThroughput) !== JSON.stringify(gsi.ProvisionedThroughput)) ops.push({ Update: {
12346
12439
  IndexName: name,
12347
12440
  ProvisionedThroughput: gsi.ProvisionedThroughput
12348
12441
  } });
@@ -69187,7 +69280,7 @@ function createMigrateCommand() {
69187
69280
  */
69188
69281
  function buildProgram() {
69189
69282
  const program = new Command();
69190
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.13");
69283
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.280.15");
69191
69284
  program.hook("preAction", (_thisCommand, actionCommand) => {
69192
69285
  const { profile } = actionCommand.optsWithGlobals();
69193
69286
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;