@go-to-k/cdkd 0.278.43 → 0.278.45

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 DiffCalculator, $t as resolveBucketRegion, A as red, At as getDockerImageBySourceHash, B as isTerminationProtectionPropagationError, Bt as resolveStateBucketWithDefaultAndSource, C as isStatefulRecreateTargetSync, Ct as validateContainerRepoName, D as cyan, Dt as runDockerForeground, E as bold, En as withErrorHandling, Et as getDockerCmd, F as ProviderRegistry, Ft as resolveApp, G as normalizeAwsTagsToCfn, Gt as CFN_TEMPLATE_URL_LIMIT, H as cfnRefValueFromPhysicalId, Ht as stateBucketExistenceConfirmed, I as findActionableSilentDrops, It as resolveAutoAssetStorage, J as readConfigString, Jt as uploadCfnTemplate, K as resolveExplicitPhysicalId, Kt as MIGRATE_TMP_PREFIX, L as CloudControlProvider, Lt as resolveCaptureObservedState, M as IAMRoleProvider, Mt as synthesisStatusMessage, N as collectInlinePolicyNamesManagedBySiblings, Nt as getDefaultStateBucketName, O as gray, Ot as runDockerStreaming, P as clearOnUpdateRemoval, Pt as getLegacyStateBucketName, Q as applyRoleArnIfSet, R as slowCcOperationTimeoutMs, Rt as resolveSkipPrefix, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, St as validateAssetBucketName, T as formatResourceLine, Tn as normalizeAwsError, Tt as formatDockerLoginError, U as refStateLookupFromResource, Ut as warnDeprecatedNoPrefixCliFlag, V as IntrinsicFunctionResolver, Vt as resolveUseCdkBootstrapAssets, W as WAFv2WebACLProvider, Wt as CFN_TEMPLATE_BODY_LIMIT, X as requireConfigArray, Xt as AssemblyReader, Y as replayWarn, Yt as expectedOwnerParam, Z as requireConfigString, Zt as processStackMessages, _ as createPreDeleteFinalSnapshot, _n as ResourceTimeoutError, _t as AssetModeResolver, a as DeploymentEventsStore, an as CdkdError, at as TemplateParser, b as unsupportedFinalSnapshotError, bn as StackTerminationProtectionError, bt as getBootstrapMarkerKey, c as replayFailedOperations, cn as DeployCancelledError, ct as rebuildClientForBucketRegion, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalStartServiceError, dt as stringifyValue, en as AwsClients, et as describeTypeWithThrottleRetry, f as computeImplicitDeleteEdges, ft as WorkGraph, g as ccRoutedFinalSnapshotError, gn as ProvisioningError, gt as rewriteTemplateAssetReferences, h as buildFinalSnapshotIdentifier, hn as PartialFailureError, ht as loadPublishableAssetManifest, i as DeploymentEventsReader, it as DagBuilder, j as yellow, jt as Synthesizer, k as green, kt as AssetManifestLoader, l as replayRollback, ln as LocalInvokeBuildError$1, lt as shouldRetainResource, m as PRE_DELETE_SNAPSHOT_TYPES, mn as NestedStackChildDirectDestroyError, mt as createAssetRedirectResolver, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resetAwsClients, nt as isRetryableTransientError, o as planFailedOps, ot as LockManager, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as MissingCdkCliError, pt as buildAssetRedirectMap, q as assertRegionMatch, qt as findLargeInlineResources, r as DeployEngine, rn as setAwsClients, rt as isThrottlingError, s as planRollback, st as S3StateBackend, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as getAwsClients, tt as withRetry, u as withResourceDeadline, un as LocalMigrateError, ut as AssetPublisher, v as isFinalSnapshotError, vn as ResourceUpdateNotSupportedError, vt as BOOTSTRAP_MARKER_PREFIX, w as renderStatefulReason, wt as buildDockerImage, x as extractDeploymentEventError, xt as parseBootstrapMarker, y as refusesFinalSnapshot, yn as StackHasActiveImportsError, yt as ensureAssetStorage, z as disableInstanceApiTermination, zt as resolveStateBucketWithDefault } from "./deploy-engine-1qwryuQH.js";
2
+ import { $ as DiffCalculator, $t as resolveBucketRegion, A as red, At as getDockerImageBySourceHash, B as isTerminationProtectionPropagationError, Bt as resolveStateBucketWithDefaultAndSource, C as isStatefulRecreateTargetSync, Ct as validateContainerRepoName, D as cyan, Dt as runDockerForeground, E as bold, En as withErrorHandling, Et as getDockerCmd, F as ProviderRegistry, Ft as resolveApp, G as normalizeAwsTagsToCfn, Gt as CFN_TEMPLATE_URL_LIMIT, H as cfnRefValueFromPhysicalId, Ht as stateBucketExistenceConfirmed, I as findActionableSilentDrops, It as resolveAutoAssetStorage, J as readConfigString, Jt as uploadCfnTemplate, K as resolveExplicitPhysicalId, Kt as MIGRATE_TMP_PREFIX, L as CloudControlProvider, Lt as resolveCaptureObservedState, M as IAMRoleProvider, Mt as synthesisStatusMessage, N as collectInlinePolicyNamesManagedBySiblings, Nt as getDefaultStateBucketName, O as gray, Ot as runDockerStreaming, P as clearOnUpdateRemoval, Pt as getLegacyStateBucketName, Q as applyRoleArnIfSet, R as slowCcOperationTimeoutMs, Rt as resolveSkipPrefix, S as MULTI_REGION_RECREATE_BLOCKED_TYPES, St as validateAssetBucketName, T as formatResourceLine, Tn as normalizeAwsError, Tt as formatDockerLoginError, U as refStateLookupFromResource, Ut as warnDeprecatedNoPrefixCliFlag, V as IntrinsicFunctionResolver, Vt as resolveUseCdkBootstrapAssets, W as WAFv2WebACLProvider, Wt as CFN_TEMPLATE_BODY_LIMIT, X as requireConfigArray, Xt as AssemblyReader, Y as replayWarn, Yt as expectedOwnerParam, Z as requireConfigString, Zt as processStackMessages, _ as createPreDeleteFinalSnapshot, _n as ResourceTimeoutError, _t as AssetModeResolver, a as DeploymentEventsStore, an as CdkdError, at as TemplateParser, b as unsupportedFinalSnapshotError, bn as StackTerminationProtectionError, bt as getBootstrapMarkerKey, c as replayFailedOperations, cn as DeployCancelledError, ct as rebuildClientForBucketRegion, d as IMPLICIT_DELETE_DEPENDENCIES, dn as LocalStartServiceError, dt as stringifyValue, en as AwsClients, et as describeTypeWithThrottleRetry, f as computeImplicitDeleteEdges, ft as WorkGraph, g as ccRoutedFinalSnapshotError, gn as ProvisioningError, gt as rewriteTemplateAssetReferences, h as buildFinalSnapshotIdentifier, hn as PartialFailureError, ht as loadPublishableAssetManifest, i as DeploymentEventsReader, it as DagBuilder, j as yellow, jt as Synthesizer, k as green, kt as AssetManifestLoader, l as replayRollback, ln as LocalInvokeBuildError$1, lt as shouldRetainResource, m as PRE_DELETE_SNAPSHOT_TYPES, mn as NestedStackChildDirectDestroyError, mt as createAssetRedirectResolver, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as resetAwsClients, nt as isRetryableTransientError, o as planFailedOps, ot as LockManager, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as MissingCdkCliError, pt as buildAssetRedirectMap, q as assertRegionMatch, qt as findLargeInlineResources, r as DeployEngine, rn as setAwsClients, rt as isThrottlingError, s as planRollback, st as S3StateBackend, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as getAwsClients, tt as withRetry, u as withResourceDeadline, un as LocalMigrateError, ut as AssetPublisher, v as isFinalSnapshotError, vn as ResourceUpdateNotSupportedError, vt as BOOTSTRAP_MARKER_PREFIX, w as renderStatefulReason, wt as buildDockerImage, x as extractDeploymentEventError, xt as parseBootstrapMarker, y as refusesFinalSnapshot, yn as StackHasActiveImportsError, yt as ensureAssetStorage, z as disableInstanceApiTermination, zt as resolveStateBucketWithDefault } from "./deploy-engine-BmTgBkZO.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-DIkqTnMR.js";
4
+ import { t as ASGProvider } from "./asg-provider-QfA3xnx8.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";
@@ -8001,7 +8001,7 @@ var SNSTopicProvider = class {
8001
8001
  * attributes (`{Protocol}SuccessFeedbackRoleArn` etc.) back to the CFn
8002
8002
  * array shape `[{Protocol, SuccessFeedbackRoleArn?, SuccessFeedbackSampleRate?,
8003
8003
  * FailureFeedbackRoleArn?}]`. Walks the known protocol prefix list
8004
- * (`HTTP` / `HTTPS` / `SQS` / `Lambda` / `Firehose` / `Application`); a
8004
+ * (`HTTP` / `SQS` / `Lambda` / `Firehose` / `Application`); a
8005
8005
  * protocol is included in the result iff at least one of its three
8006
8006
  * sub-attributes is set on the topic. Entries are sorted by canonical
8007
8007
  * PascalCase `Protocol` for stable positional compare (AWS does not
@@ -8166,11 +8166,26 @@ const SNS_DELIVERY_STATUS_PROTOCOLS = [
8166
8166
  "Application",
8167
8167
  "Firehose",
8168
8168
  "HTTP",
8169
- "HTTPS",
8170
8169
  "Lambda",
8171
8170
  "SQS"
8172
8171
  ];
8173
8172
  /**
8173
+ * The template-side `Protocol` spellings `normalizeDeliveryStatusProtocol`
8174
+ * accepts, for the fail-fast error message. This is deliberately NOT
8175
+ * `SNS_DELIVERY_STATUS_PROTOCOLS` (the AWS attribute prefixes): the canonical
8176
+ * CFn / CDK spelling of the HTTP-family protocol is `http/s`, which is not a
8177
+ * prefix, and `https` is accepted only as a tolerated legacy alias. Listing
8178
+ * the prefixes would tell a user to write `HTTP`, which is not what the CFn
8179
+ * schema's allowed-value list nor `sns.LoggingProtocol` says.
8180
+ */
8181
+ const SNS_DELIVERY_STATUS_PROTOCOL_SPELLINGS = [
8182
+ "application",
8183
+ "firehose",
8184
+ "http/s",
8185
+ "lambda",
8186
+ "sqs"
8187
+ ];
8188
+ /**
8174
8189
  * The per-protocol attribute suffixes an inline `DeliveryStatusLogging`
8175
8190
  * entry maps to (`<Protocol><Suffix>` flat attribute names on the topic).
8176
8191
  */
@@ -8195,10 +8210,33 @@ const SNS_DELIVERY_STATUS_ATTRIBUTE_SUFFIXES = [
8195
8210
  * side (cdkd state — refusing a value an older binary recorded would make
8196
8211
  * the stack permanently undeployable, and an entry whose protocol cannot
8197
8212
  * be canonicalized maps to no attribute names anyway).
8213
+ *
8214
+ * Two entries whose `Protocol` values canonicalize to the SAME prefix
8215
+ * (`http/s` + `https`, say) collapse onto one set of attribute names. The
8216
+ * collapse is a PER-FIELD merge, not a per-entry overwrite: a later entry
8217
+ * overwrites only the sub-fields it declares, because the loop below skips
8218
+ * an absent field (`value == null`) rather than clearing it. So
8219
+ * `[{http/s, RoleArn: A, SampleRate: 10}, {https, RoleArn: B}]` yields
8220
+ * `RoleArn: B` AND `SampleRate: 10`. The warning says exactly that.
8221
+ * The case became reachable only with issue #1529, which folded the whole
8222
+ * HTTP family onto the single `HTTP` prefix — before it, the `https` arm
8223
+ * produced `HTTPS*` names AWS rejected outright, so no such template ever
8224
+ * deployed.
8225
+ *
8226
+ * The collision WARNS rather than throws because this function's `'throw'`
8227
+ * side is also fed by the rollback executor's `update()` replay of a cdkd
8228
+ * STATE record, where the user has no template-side remedy. NOTE the three
8229
+ * pre-existing throws below (unsupported protocol, non-array container,
8230
+ * non-object entry) sit on that same side and are NOT covered by that
8231
+ * reasoning — a state record carrying one of those is permanently
8232
+ * unreplayable. That is a real but latent gap, tracked as issue #1538;
8233
+ * #1529 deliberately did not widen its scope to change the create path's
8234
+ * validation contract.
8198
8235
  */
8199
8236
  function buildDeliveryStatusAttributeMap(logging, logicalId, onMalformed) {
8200
8237
  const map = /* @__PURE__ */ new Map();
8201
8238
  if (logging == null) return map;
8239
+ const seenProtocols = /* @__PURE__ */ new Set();
8202
8240
  if (!Array.isArray(logging)) {
8203
8241
  if (onMalformed === "skip") return map;
8204
8242
  throw new Error(`SNS topic ${logicalId}: DeliveryStatusLogging must be an array of {Protocol, ...} objects, got ${JSON.stringify(logging)}`);
@@ -8216,6 +8254,8 @@ function buildDeliveryStatusAttributeMap(logging, logicalId, onMalformed) {
8216
8254
  if (normalized === void 0) continue;
8217
8255
  protocol = normalized;
8218
8256
  }
8257
+ if (onMalformed === "throw" && seenProtocols.has(protocol)) getLogger().child("SNSTopicProvider").warn(`SNS topic ${logicalId}: DeliveryStatusLogging declares more than one entry for the "${protocol}" attribute prefix (${JSON.stringify(config["Protocol"])} canonicalizes to it). AWS has one attribute set per prefix, so these are merged per field — a later entry overwrites only the sub-fields it declares, and a field it omits keeps the earlier entry's value. Declare a single entry per protocol.`);
8258
+ seenProtocols.add(protocol);
8219
8259
  for (const suffix of SNS_DELIVERY_STATUS_ATTRIBUTE_SUFFIXES) {
8220
8260
  const value = config[suffix];
8221
8261
  if (value == null) continue;
@@ -8251,21 +8291,39 @@ function deliveryStatusRemovalResetValue(attributeName) {
8251
8291
  * `InvalidParameter: Invalid parameter: AttributeName` message; failing
8252
8292
  * fast in cdkd lets us name the offending value.
8253
8293
  *
8254
- * Case map (lowercase canonical → PascalCase prefix):
8294
+ * The whole HTTP family collapses onto the single `HTTP` prefix, which is
8295
+ * the ONLY HTTP-family prefix AWS accepts (issue #1529, live-verified
8296
+ * 2026-08-11 against CloudFormation + `SetTopicAttributes`):
8297
+ *
8298
+ * - A CFn template carrying the canonical `Protocol: http/s` produces
8299
+ * `HTTPSuccessFeedbackRoleArn` / `HTTPFailureFeedbackRoleArn` /
8300
+ * `HTTPSuccessFeedbackSampleRate` on the live topic. `http/s` is what
8301
+ * `sns.LoggingProtocol.HTTP` and the CFn schema's allowed-value list both
8302
+ * spell, so it is the spelling most real templates carry — and it used to
8303
+ * throw `unsupported DeliveryStatusLogging protocol "http/s"`.
8304
+ * - `HTTPS*` attribute names do NOT exist: `SetTopicAttributes` rejects
8305
+ * `HTTPSSuccessFeedbackRoleArn` with `InvalidParameter: Invalid parameter:
8306
+ * AttributeName`. Mapping `https` to a `HTTPS` prefix (the pre-#1529
8307
+ * behavior) therefore produced a hard AWS failure on write and a
8308
+ * permanently-absent attribute on read.
8309
+ *
8310
+ * Case map (lowercase input → PascalCase prefix):
8255
8311
  * application → Application
8256
8312
  * firehose → Firehose
8257
- * http → HTTP
8258
- * https → HTTPS
8313
+ * http/s → HTTP (the canonical CFn / CDK L2 spelling)
8314
+ * http → HTTP (tolerated alias)
8315
+ * https → HTTP (tolerated alias; NOT a distinct prefix)
8259
8316
  * lambda → Lambda
8260
- * sqs → SQS
8317
+ * sqs → SQS
8261
8318
  */
8262
8319
  function normalizeDeliveryStatusProtocol(input) {
8263
8320
  if (typeof input !== "string") return void 0;
8264
8321
  switch (input.toLowerCase()) {
8265
8322
  case "application": return "Application";
8266
8323
  case "firehose": return "Firehose";
8267
- case "http": return "HTTP";
8268
- case "https": return "HTTPS";
8324
+ case "http/s":
8325
+ case "http":
8326
+ case "https": return "HTTP";
8269
8327
  case "lambda": return "Lambda";
8270
8328
  case "sqs": return "SQS";
8271
8329
  default: return;
@@ -8279,7 +8337,7 @@ function normalizeDeliveryStatusProtocol(input) {
8279
8337
  */
8280
8338
  function normalizeDeliveryStatusProtocolOrThrow(input, logicalId) {
8281
8339
  const normalized = normalizeDeliveryStatusProtocol(input);
8282
- if (normalized === void 0) throw new Error(`SNS topic ${logicalId}: unsupported DeliveryStatusLogging protocol ${JSON.stringify(input)}. Expected one of ${SNS_DELIVERY_STATUS_PROTOCOLS.join(", ")} (case-insensitive).`);
8340
+ if (normalized === void 0) throw new Error(`SNS topic ${logicalId}: unsupported DeliveryStatusLogging protocol ${JSON.stringify(input)}. Expected one of ${SNS_DELIVERY_STATUS_PROTOCOL_SPELLINGS.join(", ")} (case-insensitive).`);
8283
8341
  return normalized;
8284
8342
  }
8285
8343
  /**
@@ -32105,6 +32163,24 @@ var ElastiCacheProvider = class {
32105
32163
  //#endregion
32106
32164
  //#region src/provisioning/providers/servicediscovery-provider.ts
32107
32165
  /**
32166
+ * Reset targets for a REMOVED `Properties.DnsProperties.SOA.TTL` (issue
32167
+ * #1160, servicediscovery batch). The Update*Namespace change objects MERGE
32168
+ * (an absent field keeps the live value), so the provider must send the
32169
+ * reset explicitly to mirror CloudFormation — and the default TTL is
32170
+ * PER KIND, not shared:
32171
+ * - PublicDnsNamespace: 60. Live CFn A/B 2026-08-11 (removing the SOA
32172
+ * block reset the customized 300 back to 60) + raw-SDK create-default
32173
+ * probe (a namespace created without Properties reports TTL 60).
32174
+ * - PrivateDnsNamespace: 15. Raw-SDK create-default probe 2026-08-11 (a
32175
+ * namespace created without Properties reports TTL 15 — matching the
32176
+ * PR #201-era live observation recorded on the create path below) +
32177
+ * live CFn A/B 2026-08-11 on the private kind itself.
32178
+ * Removing `Description` clears it entirely on every kind (the `''`
32179
+ * sentinel; live A/B'd on all three kinds).
32180
+ */
32181
+ const PUBLIC_DNS_NAMESPACE_DEFAULT_SOA_TTL = 60;
32182
+ const PRIVATE_DNS_NAMESPACE_DEFAULT_SOA_TTL = 15;
32183
+ /**
32108
32184
  * AWS Service Discovery Provider
32109
32185
  *
32110
32186
  * Implements resource provisioning for:
@@ -32242,13 +32318,20 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
32242
32318
  *
32243
32319
  * Empty-string Description is intentionally allowed through (`!== undefined`
32244
32320
  * gate, not truthy) so `cdkd drift --revert` can clear a console-side ADD.
32321
+ *
32322
+ * Removal resets (issue #1160): the change object MERGES (absent = "no
32323
+ * change"), so a Description / SOA.TTL REMOVED from the template must be
32324
+ * reset explicitly — Description via the `''` clear sentinel, TTL to the
32325
+ * kind's Cloud Map default ({@link PRIVATE_DNS_NAMESPACE_DEFAULT_SOA_TTL}) —
32326
+ * the CFn-parity shape, live A/B'd 2026-08-11 on the private kind itself.
32245
32327
  */
32246
32328
  async updateNamespace(logicalId, physicalId, resourceType, properties, previousProperties) {
32247
32329
  this.logger.debug(`Updating private DNS namespace ${logicalId}: ${physicalId}`);
32248
32330
  const client = this.getClient();
32249
32331
  const namespaceChange = {};
32250
- if (properties["Description"] !== void 0) namespaceChange.Description = properties["Description"];
32251
- const soaProperties = this.extractSoaTtlProperties(properties);
32332
+ const description = clearOnUpdateRemoval(properties["Description"], previousProperties["Description"], "");
32333
+ if (description !== void 0) namespaceChange.Description = description;
32334
+ const soaProperties = this.resolveSoaTtlChange(properties, previousProperties, PRIVATE_DNS_NAMESPACE_DEFAULT_SOA_TTL);
32252
32335
  if (soaProperties) namespaceChange.Properties = soaProperties;
32253
32336
  try {
32254
32337
  if (Object.keys(namespaceChange).length > 0) {
@@ -32335,13 +32418,19 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
32335
32418
  * Empty-string Description is intentionally allowed through
32336
32419
  * (`!== undefined` gate, not truthy) so `cdkd drift --revert` can clear a
32337
32420
  * console-side ADD.
32421
+ *
32422
+ * Removal reset (issue #1160): `HttpNamespaceChange` MERGES conceptually
32423
+ * (skipping the call keeps the live value), so a Description REMOVED from
32424
+ * the template must be cleared explicitly via the `''` sentinel — the
32425
+ * CFn-parity shape, live A/B'd 2026-08-11 on this exact kind.
32338
32426
  */
32339
32427
  async updateHttpNamespace(logicalId, physicalId, resourceType, properties, previousProperties) {
32340
32428
  this.logger.debug(`Updating HTTP namespace ${logicalId}: ${physicalId}`);
32341
32429
  const client = this.getClient();
32430
+ const description = clearOnUpdateRemoval(properties["Description"], previousProperties["Description"], "");
32342
32431
  try {
32343
- if (properties["Description"] !== void 0) {
32344
- const namespaceChange = { Description: properties["Description"] };
32432
+ if (description !== void 0) {
32433
+ const namespaceChange = { Description: description };
32345
32434
  const operationId = (await client.send(new UpdateHttpNamespaceCommand({
32346
32435
  Id: physicalId,
32347
32436
  Namespace: namespaceChange
@@ -32410,13 +32499,20 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
32410
32499
  * `Properties.DnsProperties.SOA.TTL`. `Name` is createOnly — replacement
32411
32500
  * is routed through DELETE+CREATE upstream. Tags ride on the separate
32412
32501
  * `TagResource` / `UntagResource` APIs (see {@link syncNamespaceTags}).
32502
+ *
32503
+ * Removal resets (issue #1160): the change object MERGES (absent = "no
32504
+ * change"), so a Description / SOA.TTL REMOVED from the template must be
32505
+ * reset explicitly — Description via the `''` clear sentinel, TTL to the
32506
+ * kind's Cloud Map default ({@link PUBLIC_DNS_NAMESPACE_DEFAULT_SOA_TTL}) —
32507
+ * the CFn-parity shape, live A/B'd 2026-08-11 on this exact kind.
32413
32508
  */
32414
32509
  async updatePublicDnsNamespace(logicalId, physicalId, resourceType, properties, previousProperties) {
32415
32510
  this.logger.debug(`Updating public DNS namespace ${logicalId}: ${physicalId}`);
32416
32511
  const client = this.getClient();
32417
32512
  const namespaceChange = {};
32418
- if (properties["Description"] !== void 0) namespaceChange.Description = properties["Description"];
32419
- const soaProperties = this.extractSoaTtlProperties(properties);
32513
+ const description = clearOnUpdateRemoval(properties["Description"], previousProperties["Description"], "");
32514
+ if (description !== void 0) namespaceChange.Description = description;
32515
+ const soaProperties = this.resolveSoaTtlChange(properties, previousProperties, PUBLIC_DNS_NAMESPACE_DEFAULT_SOA_TTL);
32420
32516
  if (soaProperties) namespaceChange.Properties = soaProperties;
32421
32517
  try {
32422
32518
  if (Object.keys(namespaceChange).length > 0) {
@@ -32595,6 +32691,20 @@ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
32595
32691
  return soa?.TTL !== void 0 ? { DnsProperties: { SOA: { TTL: Number(soa.TTL) } } } : void 0;
32596
32692
  }
32597
32693
  /**
32694
+ * Resolve the SOA-TTL entry for an Update*Namespace change object,
32695
+ * including the REMOVAL reset (issue #1160): a TTL present in the desired
32696
+ * template passes through; a TTL absent from the desired template but
32697
+ * present in the previous one is reset to the Cloud Map default
32698
+ * the caller-supplied per-kind default (the CFn-parity shape — the change
32699
+ * object merges, so skipping it would silently keep the customized TTL).
32700
+ * Never-present stays absent (no change entry).
32701
+ */
32702
+ resolveSoaTtlChange(properties, previousProperties, defaultTtl) {
32703
+ const desired = this.extractSoaTtlProperties(properties);
32704
+ if (desired) return desired;
32705
+ if (this.extractSoaTtlProperties(previousProperties)) return { DnsProperties: { SOA: { TTL: defaultTtl } } };
32706
+ }
32707
+ /**
32598
32708
  * Resolve a namespace's ARN — authoritative via `GetNamespace`, with a
32599
32709
  * deterministic STS-based construction as fallback so a transient read
32600
32710
  * failure right after create does not fail the whole resource.
@@ -67352,7 +67462,7 @@ function createMigrateCommand() {
67352
67462
  */
67353
67463
  function buildProgram() {
67354
67464
  const program = new Command();
67355
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.278.43");
67465
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.278.45");
67356
67466
  program.hook("preAction", (_thisCommand, actionCommand) => {
67357
67467
  const { profile } = actionCommand.optsWithGlobals();
67358
67468
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;