@go-to-k/cdkd 0.111.0 → 0.111.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
@@ -8074,9 +8074,7 @@ var DynamoDBGlobalTableProvider = class {
8074
8074
  if (sse["SSEType"]) sseInput.SSEType = sse["SSEType"];
8075
8075
  createParams.SSESpecification = sseInput;
8076
8076
  }
8077
- const dpePerReplica = replicas.find((r) => r["Region"] === currentRegion)?.["DeletionProtectionEnabled"];
8078
- const dpeTopLevel = properties["DeletionProtectionEnabled"];
8079
- const dpeResolved = typeof dpePerReplica === "boolean" ? dpePerReplica : typeof dpeTopLevel === "boolean" ? dpeTopLevel : void 0;
8077
+ const dpeResolved = extractLocalDeletionProtection(properties, currentRegion);
8080
8078
  if (dpeResolved !== void 0) createParams.DeletionProtectionEnabled = dpeResolved;
8081
8079
  if (properties["TableClass"]) createParams.TableClass = properties["TableClass"];
8082
8080
  const wodts = properties["WriteOnDemandThroughputSettings"];
@@ -8202,22 +8200,19 @@ var DynamoDBGlobalTableProvider = class {
8202
8200
  const currentRegion = await this.dynamoDBClient.config.region() ?? "";
8203
8201
  try {
8204
8202
  await this.waitForTableActiveAfterUpdate(physicalId, logicalId);
8205
- const tableArn = (await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: physicalId }))).Table?.TableArn;
8203
+ const describeResp = await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: physicalId }));
8204
+ const tableArn = describeResp.Table?.TableArn;
8206
8205
  const extractLocalTags = (props) => {
8207
8206
  return (props["Replicas"] ?? []).find((r) => r["Region"] === currentRegion)?.["Tags"];
8208
8207
  };
8209
8208
  if (tableArn) await this.applyTagDiff(tableArn, extractLocalTags(previousProperties), extractLocalTags(properties));
8210
- const extractLocalDP = (props) => {
8211
- const perReplica = (props["Replicas"] ?? []).find((r) => r["Region"] === currentRegion)?.["DeletionProtectionEnabled"];
8212
- if (typeof perReplica === "boolean") return perReplica;
8213
- const topLevel = props["DeletionProtectionEnabled"];
8214
- return typeof topLevel === "boolean" ? topLevel : void 0;
8215
- };
8216
- const newDpe = extractLocalDP(properties);
8217
- const oldDpe = extractLocalDP(previousProperties);
8209
+ const newDpe = extractLocalDeletionProtection(properties, currentRegion);
8210
+ const oldDpe = extractLocalDeletionProtection(previousProperties, currentRegion);
8211
+ const awsDpe = describeResp.Table?.DeletionProtectionEnabled;
8218
8212
  const flatUpdate = { TableName: physicalId };
8219
8213
  let flatChanged = false;
8220
- if (newDpe !== oldDpe) {
8214
+ if (newDpe !== oldDpe || newDpe !== void 0 && typeof awsDpe === "boolean" && Boolean(newDpe) !== awsDpe) {
8215
+ if ((oldDpe === true || awsDpe === true) && Boolean(newDpe ?? false) === false && !(newDpe !== void 0)) this.logger.warn(`Auto-disabling DeletionProtectionEnabled on ${physicalId}: the property was removed from the CDK code. AWS will accept DeleteTable on this resource after this deploy. If you meant to keep protection on, restore 'deletionProtection: true' in your CDK code; if you meant to disable it explicitly, set 'deletionProtection: false' to silence this warning.`);
8221
8216
  flatUpdate.DeletionProtectionEnabled = Boolean(newDpe ?? false);
8222
8217
  flatChanged = true;
8223
8218
  }
@@ -8368,8 +8363,17 @@ var DynamoDBGlobalTableProvider = class {
8368
8363
  await this.waitForTableActiveAfterUpdate(physicalId, logicalId);
8369
8364
  }
8370
8365
  if (!deepEqual$1(properties["TimeToLiveSpecification"], previousProperties["TimeToLiveSpecification"])) {
8366
+ const sendTtl = async (cmd) => {
8367
+ try {
8368
+ await this.dynamoDBClient.send(cmd);
8369
+ } catch (ttlErr) {
8370
+ const msg = ttlErr instanceof Error ? ttlErr.message : String(ttlErr);
8371
+ if (msg.includes("Time to live has been modified multiple times")) throw new ProvisioningError(`AWS rejected TimeToLive update on ${physicalId}: ${msg}. AWS enforces a ~4-hour rate limit on TTL changes per table; wait and redeploy, or keep the previous TTL state in this deploy.`, resourceType, logicalId, physicalId, ttlErr instanceof Error ? ttlErr : void 0);
8372
+ throw ttlErr;
8373
+ }
8374
+ };
8371
8375
  const ttl = properties["TimeToLiveSpecification"];
8372
- if (ttl?.["AttributeName"]) await this.dynamoDBClient.send(new UpdateTimeToLiveCommand({
8376
+ if (ttl?.["AttributeName"]) await sendTtl(new UpdateTimeToLiveCommand({
8373
8377
  TableName: physicalId,
8374
8378
  TimeToLiveSpecification: {
8375
8379
  Enabled: ttl["Enabled"] !== void 0 ? Boolean(ttl["Enabled"]) : true,
@@ -8378,7 +8382,7 @@ var DynamoDBGlobalTableProvider = class {
8378
8382
  }));
8379
8383
  else if (previousProperties["TimeToLiveSpecification"]) {
8380
8384
  const prevTtl = previousProperties["TimeToLiveSpecification"];
8381
- if (prevTtl["AttributeName"]) await this.dynamoDBClient.send(new UpdateTimeToLiveCommand({
8385
+ if (prevTtl["AttributeName"]) await sendTtl(new UpdateTimeToLiveCommand({
8382
8386
  TableName: physicalId,
8383
8387
  TimeToLiveSpecification: {
8384
8388
  Enabled: false,
@@ -9098,6 +9102,26 @@ var DynamoDBGlobalTableProvider = class {
9098
9102
  * (per-replica, the deploy region's setting). Same literal-vs-auto-
9099
9103
  * scaling-vs-default-5 precedence.
9100
9104
  */
9105
+ /**
9106
+ * Extract the local replica's `DeletionProtectionEnabled` from a CFn
9107
+ * properties shape. The `AWS::DynamoDB::GlobalTable` CFn schema places
9108
+ * the field inside `Replicas[?Region==<region>].DeletionProtectionEnabled`;
9109
+ * CDK 2.x's `deletionProtection: true` synthesizes there. Falls back
9110
+ * to the top-level `DeletionProtectionEnabled` for legacy or
9111
+ * hand-authored templates (the property doesn't formally exist at
9112
+ * the top level in the CFn schema, but cdkd tolerates it as a
9113
+ * pass-through to avoid breaking older state files).
9114
+ *
9115
+ * Returns `undefined` when neither shape carries a boolean — the
9116
+ * caller treats that as "unset" and does not include the field in
9117
+ * the SDK call.
9118
+ */
9119
+ function extractLocalDeletionProtection(props, region) {
9120
+ const perReplica = (props["Replicas"] ?? []).find((r) => r["Region"] === region)?.["DeletionProtectionEnabled"];
9121
+ if (typeof perReplica === "boolean") return perReplica;
9122
+ const topLevel = props["DeletionProtectionEnabled"];
9123
+ return typeof topLevel === "boolean" ? topLevel : void 0;
9124
+ }
9101
9125
  function derivePerCallProvisionedThroughput(properties, region) {
9102
9126
  const wps = properties["WriteProvisionedThroughputSettings"];
9103
9127
  const writeAutoScaling = wps?.["WriteCapacityAutoScalingSettings"];
@@ -14426,6 +14450,25 @@ var ApiGatewayV2Provider = class {
14426
14450
  "AuthorizerPayloadFormatVersion"
14427
14451
  ])]
14428
14452
  ]);
14453
+ /**
14454
+ * Properties this provider deliberately does NOT wire through to the SDK
14455
+ * call, with a one-line rationale per entry. Consumed by the development-
14456
+ * time coverage check (`tests/unit/provisioning/property-coverage.test.ts`,
14457
+ * issue #391) — see `ResourceProvider.unhandledByDesign` doc.
14458
+ *
14459
+ * The five OpenAPI-import fields on `AWS::ApiGatewayV2::Api` trigger an
14460
+ * entirely separate `ImportApi` AWS API code path (inline OpenAPI spec or
14461
+ * S3-hosted), not the field-by-field `CreateApi` cdkd already supports.
14462
+ * Wiring them would require parsing OpenAPI semantics + a different
14463
+ * mutation surface and is out of scope for the SDK-Provider safety net.
14464
+ */
14465
+ unhandledByDesign = new Map([["AWS::ApiGatewayV2::Api", new Map([
14466
+ ["Body", "OpenAPI/Swagger inline spec; routed through ImportApi, not the field-by-field CreateApi path."],
14467
+ ["BodyS3Location", "OpenAPI/Swagger spec on S3; routed through ImportApi, not the field-by-field CreateApi path."],
14468
+ ["FailOnWarnings", "OpenAPI-import-only flag; meaningful only on the ImportApi code path."],
14469
+ ["DisableSchemaValidation", "Schema-validation toggle on CreateApi/UpdateApi that AWS docs scope to WebSocket APIs using AWS::ApiGatewayV2::Model — that resource type is not yet registered in cdkd, so the toggle has no effect to wire."],
14470
+ ["BasePath", "OpenAPI-import-only basePath override; meaningful only on the ImportApi code path."]
14471
+ ])]]);
14429
14472
  getClient() {
14430
14473
  if (!this.client) this.client = new ApiGatewayV2Client(this.providerRegion ? { region: this.providerRegion } : {});
14431
14474
  return this.client;
@@ -45257,7 +45300,7 @@ function reorderArgs(argv) {
45257
45300
  */
45258
45301
  async function main() {
45259
45302
  const program = new Command();
45260
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.111.0");
45303
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.111.2");
45261
45304
  program.addCommand(createBootstrapCommand());
45262
45305
  program.addCommand(createSynthCommand());
45263
45306
  program.addCommand(createListCommand());