@go-to-k/cdkd 0.230.8 → 0.230.9

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
@@ -1445,7 +1445,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1445
1445
  const FLUSH_EVENT_THRESHOLD = 50;
1446
1446
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1447
1447
  function getCdkdVersion() {
1448
- return "0.230.8";
1448
+ return "0.230.9";
1449
1449
  }
1450
1450
  /**
1451
1451
  * Generate a time-sortable unique run id, e.g.
@@ -10057,7 +10057,10 @@ var DynamoDBTableProvider = class {
10057
10057
  }
10058
10058
  if (JSON.stringify(properties["GlobalSecondaryIndexes"]) !== JSON.stringify(previousProperties["GlobalSecondaryIndexes"])) await this.applyGsiUpdates(physicalId, resourceType, logicalId, previousProperties["GlobalSecondaryIndexes"], properties["GlobalSecondaryIndexes"], properties["AttributeDefinitions"]);
10059
10059
  if (JSON.stringify(properties["PointInTimeRecoverySpecification"]) !== JSON.stringify(previousProperties["PointInTimeRecoverySpecification"])) await this.applyPointInTimeRecovery(physicalId, properties["PointInTimeRecoverySpecification"], previousProperties["PointInTimeRecoverySpecification"]);
10060
- if (JSON.stringify(properties["TimeToLiveSpecification"]) !== JSON.stringify(previousProperties["TimeToLiveSpecification"])) await this.applyTimeToLive(physicalId, properties["TimeToLiveSpecification"], previousProperties["TimeToLiveSpecification"]);
10060
+ if (JSON.stringify(properties["TimeToLiveSpecification"]) !== JSON.stringify(previousProperties["TimeToLiveSpecification"])) {
10061
+ this.assertNoActiveTtlAttributeNameChange(logicalId, resourceType, physicalId, properties["TimeToLiveSpecification"], previousProperties["TimeToLiveSpecification"]);
10062
+ await this.applyTimeToLive(physicalId, properties["TimeToLiveSpecification"], previousProperties["TimeToLiveSpecification"]);
10063
+ }
10061
10064
  if (JSON.stringify(properties["ResourcePolicy"]) !== JSON.stringify(previousProperties["ResourcePolicy"])) {
10062
10065
  if (!table?.TableArn) throw new ProvisioningError(`Cannot apply ResourcePolicy change for DynamoDB table ${logicalId}: DescribeTable returned no TableArn`, resourceType, logicalId, physicalId);
10063
10066
  await this.applyResourcePolicy(table.TableArn, properties["ResourcePolicy"], previousProperties["ResourcePolicy"]);
@@ -10075,6 +10078,7 @@ var DynamoDBTableProvider = class {
10075
10078
  }
10076
10079
  };
10077
10080
  } catch (error) {
10081
+ if (error instanceof ProvisioningError) throw error;
10078
10082
  const cause = error instanceof Error ? error : void 0;
10079
10083
  throw new ProvisioningError(`Failed to update DynamoDB table ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
10080
10084
  }
@@ -10208,12 +10212,48 @@ var DynamoDBTableProvider = class {
10208
10212
  * block but it was present before — we disable TTL using the PREVIOUS
10209
10213
  * `AttributeName` (AWS requires the attribute name even to disable TTL).
10210
10214
  */
10215
+ /**
10216
+ * Pre-emptively reject a TTL `AttributeName` change between two enabled
10217
+ * specs with a clear, actionable message.
10218
+ *
10219
+ * AWS allows TTL on only ONE attribute per table, so enabling TTL on a new
10220
+ * attribute while TTL is still active on the old one fails with the opaque
10221
+ * `TimeToLive is active on a different AttributeName: <old>`; and because
10222
+ * DynamoDB rate-limits `UpdateTimeToLive` to one modification per table per
10223
+ * ~1 hour, the user cannot disable-then-re-enable within a single deploy
10224
+ * either. CloudFormation hits the same wall (UPDATE_ROLLBACK). Surfacing the
10225
+ * two-deploy remediation up front beats letting the raw AWS error bubble.
10226
+ *
10227
+ * Only fires when BOTH the old and new specs are present and enabled with a
10228
+ * DIFFERENT `AttributeName`. Enable-from-disabled, disable, and same-name
10229
+ * Enabled toggles all pass through to {@link applyTimeToLive}.
10230
+ */
10231
+ assertNoActiveTtlAttributeNameChange(logicalId, resourceType, physicalId, spec, previousSpec) {
10232
+ const cur = this.readTtlSpec(spec);
10233
+ const prev = this.readTtlSpec(previousSpec);
10234
+ if (cur.enabled && prev.enabled && cur.attributeName !== void 0 && prev.attributeName !== void 0 && cur.attributeName !== prev.attributeName) throw new ProvisioningError(`DynamoDB table ${logicalId}: cannot change the TimeToLive AttributeName from '${prev.attributeName}' to '${cur.attributeName}' in a single deploy. AWS allows TTL on only one attribute and rejects enabling it on a new attribute while TTL is still active on '${prev.attributeName}' ("TimeToLive is active on a different AttributeName"); DynamoDB also limits UpdateTimeToLive to one change per table per ~1 hour. To change the TTL attribute, do it in two deploys: (1) remove TimeToLiveSpecification (or set Enabled: false) to disable TTL on '${prev.attributeName}', then (2) after the disable settles (~1h), deploy again enabling TTL on '${cur.attributeName}'.`, resourceType, logicalId, physicalId);
10235
+ }
10236
+ /**
10237
+ * Normalize a `TimeToLiveSpecification` value into `{ enabled, attributeName }`.
10238
+ * Mirrors {@link applyTimeToLive}'s default (`Enabled` absent => true).
10239
+ */
10240
+ readTtlSpec(spec) {
10241
+ if (spec === void 0 || spec === null) return {
10242
+ enabled: false,
10243
+ attributeName: void 0
10244
+ };
10245
+ const s = spec;
10246
+ const attributeName = s["AttributeName"];
10247
+ const rawEnabled = s["Enabled"];
10248
+ return {
10249
+ enabled: rawEnabled === void 0 ? true : typeof rawEnabled === "string" ? rawEnabled.toLowerCase() === "true" : Boolean(rawEnabled),
10250
+ attributeName
10251
+ };
10252
+ }
10211
10253
  async applyTimeToLive(tableName, spec, previousSpec) {
10212
10254
  if (spec !== void 0 && spec !== null) {
10213
- const s = spec;
10214
- const attributeName = s["AttributeName"];
10255
+ const { enabled, attributeName } = this.readTtlSpec(spec);
10215
10256
  if (!attributeName) return;
10216
- const enabled = s["Enabled"] !== void 0 ? Boolean(s["Enabled"]) : true;
10217
10257
  await this.retryOnTransientControlPlane(() => this.dynamoDBClient.send(new UpdateTimeToLiveCommand({
10218
10258
  TableName: tableName,
10219
10259
  TimeToLiveSpecification: {
@@ -55314,7 +55354,7 @@ function reorderArgs(argv) {
55314
55354
  async function main() {
55315
55355
  installPipeCloseHandler();
55316
55356
  const program = new Command();
55317
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.230.8");
55357
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.230.9");
55318
55358
  program.addCommand(createBootstrapCommand());
55319
55359
  program.addCommand(createSynthCommand());
55320
55360
  program.addCommand(createListCommand());