@go-to-k/cdkd 0.117.1 → 0.117.2

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
@@ -7901,11 +7901,12 @@ var DynamoDBTableProvider = class {
7901
7901
  * is surfaced for BOTH the LOCAL replica AND cross-region replicas
7902
7902
  * via per-region SDK clients (cached in `regionalClientCache` for
7903
7903
  * the deploy run). Issue #389 lifted the v1 LOCAL-only limitation.
7904
- * - Cross-region replica Tags propagation (Issue #389): when the
7905
- * update path detects a Tags-only diff on a non-local replica,
7906
- * cdkd resolves the replica's table ARN by swapping the region
7907
- * segment of the local ARN and issues `TagResource` /
7908
- * `UntagResource` against a per-region client.
7904
+ * - Cross-region replica Tags propagation (Issue #389 / #441):
7905
+ * BOTH `create()` and `update()` resolve each non-local replica's
7906
+ * table ARN by swapping the region segment of the local ARN and
7907
+ * issue `TagResource` / `UntagResource` against a per-region
7908
+ * client. The shared helper `applyCrossRegionReplicaTagsDiff`
7909
+ * centralizes the diff + best-effort WARN-on-failure contract.
7909
7910
  */
7910
7911
  var DynamoDBGlobalTableProvider = class {
7911
7912
  dynamoDBClient;
@@ -8114,6 +8115,13 @@ var DynamoDBGlobalTableProvider = class {
8114
8115
  if (!region || region === currentRegion) continue;
8115
8116
  await this.addReplica(tableName, replica, region, logicalId);
8116
8117
  }
8118
+ for (const replica of replicas) {
8119
+ const region = replica["Region"];
8120
+ if (!region || region === currentRegion) continue;
8121
+ const replicaTags = replica["Tags"];
8122
+ if (!replicaTags || replicaTags.length === 0) continue;
8123
+ await this.applyCrossRegionReplicaTagsDiff(tableInfo.tableArn, region, void 0, replicaTags, tableName);
8124
+ }
8117
8125
  if (properties["TimeToLiveSpecification"]) {
8118
8126
  const ttl = properties["TimeToLiveSpecification"];
8119
8127
  const attributeName = ttl["AttributeName"];
@@ -8299,6 +8307,8 @@ var DynamoDBGlobalTableProvider = class {
8299
8307
  const region = replica["Region"];
8300
8308
  if (!region || region === currentRegion) continue;
8301
8309
  await this.addReplica(physicalId, replica, region, logicalId);
8310
+ const newReplicaTags = replica["Tags"];
8311
+ await this.applyCrossRegionReplicaTagsDiff(tableArn, region, void 0, newReplicaTags, physicalId);
8302
8312
  const newReadAutoScaling = (replica["ReadProvisionedThroughputSettings"] ?? {})["ReadCapacityAutoScalingSettings"];
8303
8313
  if (newBilling === "PROVISIONED" && newReadAutoScaling) {
8304
8314
  const regionalAutoScalingClient = this.getRegionalAutoScalingClient(region);
@@ -8311,16 +8321,7 @@ var DynamoDBGlobalTableProvider = class {
8311
8321
  const oldReplica = (previousProperties["Replicas"] ?? []).find((r) => r["Region"] === region);
8312
8322
  const oldReplicaTags = oldReplica?.["Tags"];
8313
8323
  const newReplicaTags = replica["Tags"];
8314
- if (!deepEqual$1(oldReplicaTags, newReplicaTags)) if (tableArn) {
8315
- const replicaArn = this.replicaArnForRegion(tableArn, region);
8316
- if (replicaArn) try {
8317
- const regionalClient = this.getRegionalClient(region);
8318
- await this.applyTagDiffOnClient(regionalClient, replicaArn, oldReplicaTags, newReplicaTags);
8319
- } catch (tagErr) {
8320
- this.logger.warn(`Could not apply Tags diff to cross-region replica ${region} of ${physicalId}: ${tagErr instanceof Error ? tagErr.message : String(tagErr)}. The replica's Tags state will surface as drift until the next successful deploy.`);
8321
- }
8322
- else this.logger.warn(`Could not derive replica ARN for region ${region} from ${tableArn} — skipping Tags propagation for ${physicalId}`);
8323
- } else this.logger.warn(`Local DescribeTable returned no TableArn — cannot propagate Tags to cross-region replica ${region} of ${physicalId}`);
8324
+ await this.applyCrossRegionReplicaTagsDiff(tableArn, region, oldReplicaTags, newReplicaTags, physicalId);
8324
8325
  const oldReadAutoScaling = (oldReplica?.["ReadProvisionedThroughputSettings"] ?? {})["ReadCapacityAutoScalingSettings"];
8325
8326
  const newReadAutoScaling = (replica["ReadProvisionedThroughputSettings"] ?? {})["ReadCapacityAutoScalingSettings"];
8326
8327
  const effectiveNewReadAutoScaling = newBilling === "PAY_PER_REQUEST" ? void 0 : newReadAutoScaling;
@@ -8439,10 +8440,49 @@ var DynamoDBGlobalTableProvider = class {
8439
8440
  await this.applyTagDiffOnClient(this.dynamoDBClient, tableArn, oldTagsRaw, newTagsRaw);
8440
8441
  }
8441
8442
  /**
8443
+ * Propagate a per-replica Tags diff to ONE cross-region replica via a
8444
+ * per-region client (Issue #389 / #441 — closes the create-side gap).
8445
+ * Centralizes the common shape used by BOTH `create()` (`oldTags`
8446
+ * undefined → every new tag is an add) and `update()` (per-replica
8447
+ * modify path's old-vs-new diff). Best-effort: a failure here logs at
8448
+ * WARN naming the offending region + ARN + reason and the deploy
8449
+ * continues — the cross-region Tags state will surface as drift on
8450
+ * the next run (or `cdkd drift --revert`) rather than aborting the
8451
+ * deploy mid-flight. Mirrors the autoscaling diff's failure contract
8452
+ * (PR #393).
8453
+ *
8454
+ * `tableArn` is the LOCAL replica's table ARN (returned by the
8455
+ * post-create `waitForTableActive` or the inline `DescribeTable` in
8456
+ * `update()`); the helper swaps the region segment via
8457
+ * `replicaArnForRegion` before issuing `TagResource` / `UntagResource`
8458
+ * against the per-region client.
8459
+ *
8460
+ * No-op when `oldTags` deep-equals `newTags` — the caller is allowed
8461
+ * to invoke unconditionally without first diffing.
8462
+ */
8463
+ async applyCrossRegionReplicaTagsDiff(tableArn, region, oldTags, newTags, physicalIdForLogs) {
8464
+ if (deepEqual$1(oldTags, newTags)) return;
8465
+ if (!tableArn) {
8466
+ this.logger.warn(`Local DescribeTable returned no TableArn — cannot propagate Tags to cross-region replica ${region} of ${physicalIdForLogs}`);
8467
+ return;
8468
+ }
8469
+ const replicaArn = this.replicaArnForRegion(tableArn, region);
8470
+ if (!replicaArn) {
8471
+ this.logger.warn(`Could not derive replica ARN for region ${region} from ${tableArn} — skipping Tags propagation for ${physicalIdForLogs}`);
8472
+ return;
8473
+ }
8474
+ try {
8475
+ const regionalClient = this.getRegionalClient(region);
8476
+ await this.applyTagDiffOnClient(regionalClient, replicaArn, oldTags, newTags);
8477
+ } catch (tagErr) {
8478
+ this.logger.warn(`Could not apply Tags diff to cross-region replica ${region} of ${physicalIdForLogs}: ${tagErr instanceof Error ? tagErr.message : String(tagErr)}. The replica's Tags state will surface as drift until the next successful deploy.`);
8479
+ }
8480
+ }
8481
+ /**
8442
8482
  * Apply a Tags diff against the given `DynamoDBClient` (which may be
8443
8483
  * the local client or a per-region client returned by
8444
8484
  * `getRegionalClient`). Used by the local-replica path AND the
8445
- * cross-region replica Tags propagation path (Issue #389).
8485
+ * cross-region replica Tags propagation path (Issue #389 / #441).
8446
8486
  */
8447
8487
  async applyTagDiffOnClient(client, tableArn, oldTagsRaw, newTagsRaw) {
8448
8488
  const toMap = (tags) => {
@@ -8732,9 +8772,12 @@ var DynamoDBGlobalTableProvider = class {
8732
8772
  *
8733
8773
  * Per-replica sub-specifications (`ContributorInsightsSpecification` /
8734
8774
  * `PointInTimeRecoverySpecification` / `KinesisStreamSpecification`)
8735
- * are surfaced only for the LOCAL replica. Cross-region replicas
8736
- * require per-region SDK clients (`new DynamoDBClient({region})`),
8737
- * deferred to a follow-up PR.
8775
+ * are surfaced for BOTH the LOCAL replica AND cross-region replicas
8776
+ * via per-region SDK clients cached in `regionalClientCache` (Issue
8777
+ * #389 lifted the v1 LOCAL-only limitation; the per-replica reads
8778
+ * happen in `readReplicaSubSpecs` below). Each cross-region call is
8779
+ * best-effort — a permissions gap in one region omits the offending
8780
+ * key rather than aborting the whole drift read.
8738
8781
  */
8739
8782
  async readCurrentState(physicalId, _logicalId, _resourceType) {
8740
8783
  try {
@@ -46031,7 +46074,7 @@ function reorderArgs(argv) {
46031
46074
  */
46032
46075
  async function main() {
46033
46076
  const program = new Command();
46034
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.117.1");
46077
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.117.2");
46035
46078
  program.addCommand(createBootstrapCommand());
46036
46079
  program.addCommand(createSynthCommand());
46037
46080
  program.addCommand(createListCommand());