@go-to-k/cdkd 0.240.0 → 0.242.0

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
@@ -2,7 +2,7 @@
2
2
  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-BzO-joNR.js";
3
3
  import { A as withErrorHandling, C as StackHasActiveImportsError, S as ResourceUpdateNotSupportedError, _ as MissingCdkCliError, a as normalizeAwsTagsToCfn, b as ProvisioningError, f as LocalInvokeBuildError$1, i as matchesCdkPath, k as normalizeAwsError, l as CdkdError, m as LocalStartServiceError, n as isTerminationProtectionPropagationError, o as resolveExplicitPhysicalId, p as LocalMigrateError, r as CDK_PATH_TAG, s as assertRegionMatch, t as disableInstanceApiTermination, v as NestedStackChildDirectDestroyError, w as StackTerminationProtectionError, x as ResourceTimeoutError, y as PartialFailureError } from "./ec2-termination-protection-q-WGWgxa.js";
4
4
  import { a as setAwsClients, i as resetAwsClients, r as getAwsClients, t as AwsClients } from "./aws-clients-B15NAPbL.js";
5
- import { $ as getDockerCmd, A as DiffCalculator, B as buildAssetRedirectMap, C as findActionableSilentDrops, Ct as resolveBucketRegion, D as refStateLookupFromResource, E as cfnRefValueFromPhysicalId, F as rebuildClientForBucketRegion, G as BOOTSTRAP_MARKER_PREFIX, H as loadPublishableAssetManifest, I as shouldRetainResource, J as parseBootstrapMarker, K as ensureAssetStorage, L as AssetPublisher, M as TemplateParser, N as LockManager, O as WAFv2WebACLProvider, P as S3StateBackend, Q as formatDockerLoginError, R as stringifyValue, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as rewriteTemplateAssetReferences, V as createAssetRedirectResolver, W as AssetModeResolver, X as validateContainerRepoName, Y as validateAssetBucketName, Z as buildDockerImage, _ as green, _t as CFN_TEMPLATE_URL_LIMIT, a as withRetry, at as synthesisStatusMessage, b as IAMRoleProvider, bt as uploadCfnTemplate, c as computeImplicitDeleteEdges, ct as resolveApp, d as isStatefulRecreateTargetSync, dt as resolveSkipPrefix, et as runDockerForeground, f as renderStatefulReason, ft as resolveStateBucketWithDefault, g as gray, gt as CFN_TEMPLATE_BODY_LIMIT, h as cyan, ht as warnDeprecatedNoPrefixCliFlag, i as withResourceDeadline, it as Synthesizer, j as DagBuilder, k as applyRoleArnIfSet, l as extractDeploymentEventError, lt as resolveAutoAssetStorage, m as bold, mt as resolveUseCdkBootstrapAssets, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as AssetManifestLoader, o as isRetryableTransientError, ot as getDefaultStateBucketName, p as formatResourceLine, pt as resolveStateBucketWithDefaultAndSource, q as getBootstrapMarkerKey, r as DeployEngine, rt as getDockerImageBySourceHash, s as IMPLICIT_DELETE_DEPENDENCIES, st as getLegacyStateBucketName, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as runDockerStreaming, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, ut as resolveCaptureObservedState, v as red, vt as MIGRATE_TMP_PREFIX, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, xt as AssemblyReader, y as yellow, yt as findLargeInlineResources, z as WorkGraph } from "./deploy-engine-D_OJrSGP.js";
5
+ import { $ as getDockerCmd, A as DiffCalculator, B as buildAssetRedirectMap, C as findActionableSilentDrops, Ct as resolveBucketRegion, D as refStateLookupFromResource, E as cfnRefValueFromPhysicalId, F as rebuildClientForBucketRegion, G as BOOTSTRAP_MARKER_PREFIX, H as loadPublishableAssetManifest, I as shouldRetainResource, J as parseBootstrapMarker, K as ensureAssetStorage, L as AssetPublisher, M as TemplateParser, N as LockManager, O as WAFv2WebACLProvider, P as S3StateBackend, Q as formatDockerLoginError, R as stringifyValue, S as ProviderRegistry, T as IntrinsicFunctionResolver, U as rewriteTemplateAssetReferences, V as createAssetRedirectResolver, W as AssetModeResolver, X as validateContainerRepoName, Y as validateAssetBucketName, Z as buildDockerImage, _ as green, _t as CFN_TEMPLATE_URL_LIMIT, a as withRetry, at as synthesisStatusMessage, b as IAMRoleProvider, bt as uploadCfnTemplate, c as computeImplicitDeleteEdges, ct as resolveApp, d as isStatefulRecreateTargetSync, dt as resolveSkipPrefix, et as runDockerForeground, f as renderStatefulReason, ft as resolveStateBucketWithDefault, g as gray, gt as CFN_TEMPLATE_BODY_LIMIT, h as cyan, ht as warnDeprecatedNoPrefixCliFlag, i as withResourceDeadline, it as Synthesizer, j as DagBuilder, k as applyRoleArnIfSet, l as extractDeploymentEventError, lt as resolveAutoAssetStorage, m as bold, mt as resolveUseCdkBootstrapAssets, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as AssetManifestLoader, o as isRetryableTransientError, ot as getDefaultStateBucketName, p as formatResourceLine, pt as resolveStateBucketWithDefaultAndSource, q as getBootstrapMarkerKey, r as DeployEngine, rt as getDockerImageBySourceHash, s as IMPLICIT_DELETE_DEPENDENCIES, st as getLegacyStateBucketName, t as DEFAULT_RESOURCE_TIMEOUT_MS, tt as runDockerStreaming, u as MULTI_REGION_RECREATE_BLOCKED_TYPES, ut as resolveCaptureObservedState, v as red, vt as MIGRATE_TMP_PREFIX, w as CloudControlProvider, x as collectInlinePolicyNamesManagedBySiblings, xt as AssemblyReader, y as yellow, yt as findLargeInlineResources, z as WorkGraph } from "./deploy-engine-7FfFEJkw.js";
6
6
  import { t as expectedOwnerParam } from "./expected-bucket-owner-BjEfUnkA.js";
7
7
  import { t as ASGProvider } from "./asg-provider-Dbl1_mwT.js";
8
8
  import { AsyncLocalStorage } from "node:async_hooks";
@@ -51,20 +51,21 @@ import { CreateClusterCommand, CreateServiceCommand, DeleteClusterCommand, Delet
51
51
  import { AddTagsToResourceCommand as AddTagsToResourceCommand$3, CreateDBClusterCommand as CreateDBClusterCommand$1, CreateDBInstanceCommand as CreateDBInstanceCommand$1, CreateDBSubnetGroupCommand as CreateDBSubnetGroupCommand$1, DeleteDBClusterCommand as DeleteDBClusterCommand$1, DeleteDBInstanceCommand as DeleteDBInstanceCommand$1, DeleteDBSubnetGroupCommand as DeleteDBSubnetGroupCommand$1, DescribeDBClustersCommand as DescribeDBClustersCommand$1, DescribeDBInstancesCommand as DescribeDBInstancesCommand$1, DescribeDBSubnetGroupsCommand as DescribeDBSubnetGroupsCommand$1, DocDBClient, ListTagsForResourceCommand as ListTagsForResourceCommand$12, ModifyDBClusterCommand as ModifyDBClusterCommand$1, ModifyDBInstanceCommand as ModifyDBInstanceCommand$1, ModifyDBSubnetGroupCommand as ModifyDBSubnetGroupCommand$1, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$3 } from "@aws-sdk/client-docdb";
52
52
  import { AddTagsToResourceCommand as AddTagsToResourceCommand$4, CreateDBClusterCommand as CreateDBClusterCommand$2, CreateDBInstanceCommand as CreateDBInstanceCommand$2, CreateDBSubnetGroupCommand as CreateDBSubnetGroupCommand$2, DeleteDBClusterCommand as DeleteDBClusterCommand$2, DeleteDBInstanceCommand as DeleteDBInstanceCommand$2, DeleteDBSubnetGroupCommand as DeleteDBSubnetGroupCommand$2, DescribeDBClustersCommand as DescribeDBClustersCommand$2, DescribeDBInstancesCommand as DescribeDBInstancesCommand$2, DescribeDBSubnetGroupsCommand as DescribeDBSubnetGroupsCommand$2, ListTagsForResourceCommand as ListTagsForResourceCommand$13, ModifyDBClusterCommand as ModifyDBClusterCommand$2, ModifyDBInstanceCommand as ModifyDBInstanceCommand$2, ModifyDBSubnetGroupCommand as ModifyDBSubnetGroupCommand$2, NeptuneClient, RemoveTagsFromResourceCommand as RemoveTagsFromResourceCommand$4 } from "@aws-sdk/client-neptune";
53
53
  import { AddCustomAttributesCommand, CognitoIdentityProviderClient, CreateUserPoolCommand, DeleteUserPoolCommand, DescribeUserPoolCommand, GetUserPoolMfaConfigCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$14, ListUserPoolsCommand, ResourceNotFoundException as ResourceNotFoundException$7, SetUserPoolMfaConfigCommand, UpdateUserPoolCommand } from "@aws-sdk/client-cognito-identity-provider";
54
- import { CreatePrivateDnsNamespaceCommand, CreateServiceCommand as CreateServiceCommand$1, DeleteNamespaceCommand, DeleteServiceAttributesCommand, DeleteServiceCommand as DeleteServiceCommand$1, GetNamespaceCommand, GetOperationCommand, GetServiceAttributesCommand, GetServiceCommand, ListNamespacesCommand, ListServicesCommand as ListServicesCommand$1, ListTagsForResourceCommand as ListTagsForResourceCommand$15, NamespaceNotFound, ServiceDiscoveryClient, ServiceNotFound, UpdatePrivateDnsNamespaceCommand, UpdateServiceAttributesCommand, UpdateServiceCommand as UpdateServiceCommand$1 } from "@aws-sdk/client-servicediscovery";
55
- import { AppSyncClient, CreateApiKeyCommand, CreateDataSourceCommand, CreateGraphqlApiCommand, CreateResolverCommand, DeleteApiKeyCommand, DeleteDataSourceCommand, DeleteGraphqlApiCommand, DeleteResolverCommand, GetDataSourceCommand, GetGraphqlApiCommand, GetIntrospectionSchemaCommand, GetResolverCommand, ListApiKeysCommand, ListGraphqlApisCommand, NotFoundException as NotFoundException$4, StartSchemaCreationCommand, TagResourceCommand as TagResourceCommand$13, UntagResourceCommand as UntagResourceCommand$13, UpdateApiKeyCommand, UpdateDataSourceCommand, UpdateGraphqlApiCommand, UpdateResolverCommand } from "@aws-sdk/client-appsync";
54
+ import { CreateHttpNamespaceCommand, CreatePrivateDnsNamespaceCommand, CreatePublicDnsNamespaceCommand, CreateServiceCommand as CreateServiceCommand$1, DeleteNamespaceCommand, DeleteServiceAttributesCommand, DeleteServiceCommand as DeleteServiceCommand$1, GetNamespaceCommand, GetOperationCommand, GetServiceAttributesCommand, GetServiceCommand, ListNamespacesCommand, ListServicesCommand as ListServicesCommand$1, ListTagsForResourceCommand as ListTagsForResourceCommand$15, NamespaceNotFound, ServiceDiscoveryClient, ServiceNotFound, TagResourceCommand as TagResourceCommand$13, UntagResourceCommand as UntagResourceCommand$13, UpdateHttpNamespaceCommand, UpdatePrivateDnsNamespaceCommand, UpdatePublicDnsNamespaceCommand, UpdateServiceAttributesCommand, UpdateServiceCommand as UpdateServiceCommand$1 } from "@aws-sdk/client-servicediscovery";
55
+ import { AppSyncClient, CreateApiKeyCommand, CreateDataSourceCommand, CreateGraphqlApiCommand, CreateResolverCommand, DeleteApiKeyCommand, DeleteDataSourceCommand, DeleteGraphqlApiCommand, DeleteResolverCommand, GetDataSourceCommand, GetGraphqlApiCommand, GetIntrospectionSchemaCommand, GetResolverCommand, ListApiKeysCommand, ListGraphqlApisCommand, NotFoundException as NotFoundException$4, StartSchemaCreationCommand, TagResourceCommand as TagResourceCommand$14, UntagResourceCommand as UntagResourceCommand$14, UpdateApiKeyCommand, UpdateDataSourceCommand, UpdateGraphqlApiCommand, UpdateResolverCommand } from "@aws-sdk/client-appsync";
56
56
  import { parse, print } from "graphql";
57
57
  import { CrawlerRunningException, CreateConnectionCommand, CreateCrawlerCommand, CreateDatabaseCommand, CreateJobCommand, CreateSecurityConfigurationCommand, CreateTableCommand as CreateTableCommand$1, CreateTriggerCommand, CreateWorkflowCommand, DeleteConnectionCommand, DeleteCrawlerCommand, DeleteDatabaseCommand, DeleteJobCommand, DeleteSecurityConfigurationCommand, DeleteTableCommand as DeleteTableCommand$1, DeleteTriggerCommand, DeleteWorkflowCommand, EntityNotFoundException, GetConnectionCommand, GetCrawlerCommand, GetDatabaseCommand, GetDatabasesCommand, GetJobCommand, GetSecurityConfigurationCommand, GetSecurityConfigurationsCommand, GetTableCommand, GetTablesCommand, GetTagsCommand, GetTriggerCommand, GetWorkflowCommand, GlueClient, ListWorkflowsCommand, StartCrawlerScheduleCommand, StartTriggerCommand, StopCrawlerCommand, StopCrawlerScheduleCommand, StopTriggerCommand, UpdateConnectionCommand, UpdateCrawlerCommand, UpdateDatabaseCommand, UpdateJobCommand, UpdateTableCommand as UpdateTableCommand$1, UpdateTriggerCommand, UpdateWorkflowCommand } from "@aws-sdk/client-glue";
58
- import { AddTagsToStreamCommand, CreateStreamCommand, DecreaseStreamRetentionPeriodCommand, DeleteStreamCommand, DeregisterStreamConsumerCommand, DescribeStreamCommand, DescribeStreamConsumerCommand, DescribeStreamSummaryCommand, IncreaseStreamRetentionPeriodCommand, KinesisClient, ListStreamsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$16, ListTagsForStreamCommand, RegisterStreamConsumerCommand, RemoveTagsFromStreamCommand, ResourceNotFoundException as ResourceNotFoundException$8, StartStreamEncryptionCommand, StopStreamEncryptionCommand, TagResourceCommand as TagResourceCommand$14, UntagResourceCommand as UntagResourceCommand$14, UpdateShardCountCommand, UpdateStreamModeCommand } from "@aws-sdk/client-kinesis";
58
+ import { BudgetsClient, CreateBudgetCommand, CreateNotificationCommand, CreateSubscriberCommand, DeleteBudgetCommand, DeleteNotificationCommand, DeleteSubscriberCommand, DescribeBudgetCommand, DescribeBudgetsCommand, DuplicateRecordException, ListTagsForResourceCommand as ListTagsForResourceCommand$16, NotFoundException as NotFoundException$5, TagResourceCommand as TagResourceCommand$15, UntagResourceCommand as UntagResourceCommand$15, UpdateBudgetCommand } from "@aws-sdk/client-budgets";
59
+ import { AddTagsToStreamCommand, CreateStreamCommand, DecreaseStreamRetentionPeriodCommand, DeleteStreamCommand, DeregisterStreamConsumerCommand, DescribeStreamCommand, DescribeStreamConsumerCommand, DescribeStreamSummaryCommand, IncreaseStreamRetentionPeriodCommand, KinesisClient, ListStreamsCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$17, ListTagsForStreamCommand, RegisterStreamConsumerCommand, RemoveTagsFromStreamCommand, ResourceNotFoundException as ResourceNotFoundException$8, StartStreamEncryptionCommand, StopStreamEncryptionCommand, TagResourceCommand as TagResourceCommand$16, UntagResourceCommand as UntagResourceCommand$16, UpdateShardCountCommand, UpdateStreamModeCommand } from "@aws-sdk/client-kinesis";
59
60
  import { CreateScheduleCommand, DeleteScheduleCommand, GetScheduleCommand, ResourceNotFoundException as ResourceNotFoundException$9, SchedulerClient, UpdateScheduleCommand } from "@aws-sdk/client-scheduler";
60
61
  import { AccessPointNotFound, CreateAccessPointCommand, CreateFileSystemCommand, CreateMountTargetCommand, DeleteAccessPointCommand, DeleteFileSystemCommand, DeleteMountTargetCommand, DescribeAccessPointsCommand, DescribeBackupPolicyCommand, DescribeFileSystemPolicyCommand, DescribeFileSystemsCommand, DescribeLifecycleConfigurationCommand, DescribeMountTargetSecurityGroupsCommand, DescribeMountTargetsCommand, EFSClient, FileSystemNotFound, ModifyMountTargetSecurityGroupsCommand, MountTargetNotFound, PutBackupPolicyCommand, PutFileSystemPolicyCommand, PutLifecycleConfigurationCommand, UpdateFileSystemCommand, UpdateFileSystemProtectionCommand } from "@aws-sdk/client-efs";
61
62
  import { CreateDeliveryStreamCommand, DeleteDeliveryStreamCommand, DescribeDeliveryStreamCommand, FirehoseClient, ListDeliveryStreamsCommand, ListTagsForDeliveryStreamCommand, ResourceNotFoundException as ResourceNotFoundException$10, TagDeliveryStreamCommand, UntagDeliveryStreamCommand, UpdateDestinationCommand } from "@aws-sdk/client-firehose";
62
63
  import { AddTagsCommand as AddTagsCommand$1, CloudTrailClient, CreateTrailCommand, DeleteTrailCommand, GetEventSelectorsCommand, GetInsightSelectorsCommand, GetTrailCommand, GetTrailStatusCommand, ListTagsCommand as ListTagsCommand$1, ListTrailsCommand, PutEventSelectorsCommand, PutInsightSelectorsCommand, RemoveTagsCommand as RemoveTagsCommand$1, StartLoggingCommand, StopLoggingCommand, TrailNotFoundException, UpdateTrailCommand } from "@aws-sdk/client-cloudtrail";
63
64
  import { BatchGetProjectsCommand, CodeBuildClient, CreateProjectCommand, DeleteProjectCommand, ListProjectsCommand, ResourceNotFoundException as ResourceNotFoundException$11, UpdateProjectCommand } from "@aws-sdk/client-codebuild";
64
- import { CodeCommitClient, CreateRepositoryCommand as CreateRepositoryCommand$1, DeleteRepositoryCommand as DeleteRepositoryCommand$1, GetRepositoryCommand, ListRepositoriesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$17, RepositoryDoesNotExistException, TagResourceCommand as TagResourceCommand$15, UntagResourceCommand as UntagResourceCommand$15, UpdateRepositoryDescriptionCommand, UpdateRepositoryEncryptionKeyCommand, UpdateRepositoryNameCommand } from "@aws-sdk/client-codecommit";
65
- import { CreateLifecyclePolicyCommand, DLMClient, DeleteLifecyclePolicyCommand as DeleteLifecyclePolicyCommand$1, GetLifecyclePoliciesCommand, GetLifecyclePolicyCommand as GetLifecyclePolicyCommand$1, ResourceNotFoundException as ResourceNotFoundException$12, TagResourceCommand as TagResourceCommand$16, UntagResourceCommand as UntagResourceCommand$16, UpdateLifecyclePolicyCommand } from "@aws-sdk/client-dlm";
66
- import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$18, ListVectorBucketsCommand, S3VectorsClient, TagResourceCommand as TagResourceCommand$17, UntagResourceCommand as UntagResourceCommand$17 } from "@aws-sdk/client-s3vectors";
67
- import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableCommand as DeleteTableCommand$2, GetTableBucketCommand, GetTableCommand as GetTableCommand$1, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand as ListTablesCommand$1, ListTagsForResourceCommand as ListTagsForResourceCommand$19, NotFoundException as NotFoundException$5, S3TablesClient, TagResourceCommand as TagResourceCommand$18, UntagResourceCommand as UntagResourceCommand$18 } from "@aws-sdk/client-s3tables";
65
+ import { CodeCommitClient, CreateRepositoryCommand as CreateRepositoryCommand$1, DeleteRepositoryCommand as DeleteRepositoryCommand$1, GetRepositoryCommand, ListRepositoriesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$18, RepositoryDoesNotExistException, TagResourceCommand as TagResourceCommand$17, UntagResourceCommand as UntagResourceCommand$17, UpdateRepositoryDescriptionCommand, UpdateRepositoryEncryptionKeyCommand, UpdateRepositoryNameCommand } from "@aws-sdk/client-codecommit";
66
+ import { CreateLifecyclePolicyCommand, DLMClient, DeleteLifecyclePolicyCommand as DeleteLifecyclePolicyCommand$1, GetLifecyclePoliciesCommand, GetLifecyclePolicyCommand as GetLifecyclePolicyCommand$1, ResourceNotFoundException as ResourceNotFoundException$12, TagResourceCommand as TagResourceCommand$18, UntagResourceCommand as UntagResourceCommand$18, UpdateLifecyclePolicyCommand } from "@aws-sdk/client-dlm";
67
+ import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$19, ListVectorBucketsCommand, S3VectorsClient, TagResourceCommand as TagResourceCommand$19, UntagResourceCommand as UntagResourceCommand$19 } from "@aws-sdk/client-s3vectors";
68
+ import { CreateNamespaceCommand, CreateTableBucketCommand, CreateTableCommand as CreateTableCommand$2, DeleteNamespaceCommand as DeleteNamespaceCommand$1, DeleteTableBucketCommand, DeleteTableCommand as DeleteTableCommand$2, GetTableBucketCommand, GetTableCommand as GetTableCommand$1, ListNamespacesCommand as ListNamespacesCommand$1, ListTableBucketsCommand, ListTablesCommand as ListTablesCommand$1, ListTagsForResourceCommand as ListTagsForResourceCommand$20, NotFoundException as NotFoundException$6, S3TablesClient, TagResourceCommand as TagResourceCommand$20, UntagResourceCommand as UntagResourceCommand$20 } from "@aws-sdk/client-s3tables";
68
69
  import { Document, Pair, Scalar, YAMLMap, YAMLSeq, parse as parse$1, stringify } from "yaml";
69
70
  import { createLocalStartAgentCoreCommand, createLocalStartCloudFrontCommand, createLocalStateProvider, getEmbedConfig, isCfnFlagPresent, listTargets, rejectExplicitCfnStackWithMultipleStacks, resolveCfnFallbackRegion, setEmbedConfig, substituteAgainstState, substituteAgainstStateAsync, substituteEnvVarsFromState, substituteEnvVarsFromStateAsync } from "cdk-local";
70
71
  import { A2A_CONTAINER_PORT, A2A_PATH, AGENTCORE_A2A_PROTOCOL, AGENTCORE_AGUI_PROTOCOL, AGENTCORE_MCP_PROTOCOL, ConnectionRegistry, EcsTaskResolutionError, HOST_GATEWAY_MIN_VERSION, LocalInvokeBuildError, MCP_CONTAINER_PORT, MCP_PATH, a2aInvokeOnce, addAlbSpecificOptions, addCommonEcsServiceOptions, addStartServiceSpecificOptions, albStrategy, architectureToPlatform, attachAuthorizers, attachStageContext, availableApiIdentifiers, bufferToBody, buildAgentCoreCodeImage, buildCognitoJwksUrl, buildConnectEvent, buildContainerImage, buildCorsConfigByApiId, buildCorsConfigFromCloudFrontChain, buildDisconnectEvent, buildJwksUrlFromIssuer, buildMessageEvent, buildMgmtEndpointEnvUrl, buildStageMap, classifySourceChange, createAuthorizerCache, createFileWatcher, createFileWatcher as createFileWatcher$1, createJwksCache, createWatchPredicates, defaultCredentialsLoader, derivePseudoParametersFromRegion, discoverRoutes, discoverWebSocketApis, downloadAndExtractS3Bundle, filterRoutesByApiIdentifier, groupRoutesByServer, handleConnectionsRequest, invokeAgentCore, invokeAgentCoreWs, materializeLayerFromArn, mcpInvokeOnce, parseConnectionsPath, parseSelectionExpressionPath, pickAgentCoreCandidateStack, pickAgentCoreCandidateStack as pickAgentCoreCandidateStack$1, probeHostGatewaySupport, readMtlsMaterialsFromDisk, resolveAgentCoreTarget, resolveEnvVars, resolveHostGatewayExtraHosts, resolveRuntimeCodeMountPath, resolveRuntimeFileExtension, resolveRuntimeImage, resolveSingleTarget, resolveWatchConfig, runEcsServiceEmulator, signAgentCoreInvocation, startApiServer, substituteImagePlaceholders, tryResolveImageFnJoin, verifyJwtViaDiscovery, waitForAgentCorePing } from "cdk-local/internal";
@@ -1887,7 +1888,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1887
1888
  const FLUSH_EVENT_THRESHOLD = 50;
1888
1889
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1889
1890
  function getCdkdVersion() {
1890
- return "0.240.0";
1891
+ return "0.242.0";
1891
1892
  }
1892
1893
  /**
1893
1894
  * Generate a time-sortable unique run id, e.g.
@@ -27884,34 +27885,53 @@ var ElastiCacheProvider = class {
27884
27885
  *
27885
27886
  * Implements resource provisioning for:
27886
27887
  * - AWS::ServiceDiscovery::PrivateDnsNamespace
27888
+ * - AWS::ServiceDiscovery::HttpNamespace
27889
+ * - AWS::ServiceDiscovery::PublicDnsNamespace
27887
27890
  * - AWS::ServiceDiscovery::Service
27888
27891
  *
27889
- * WHY: CreatePrivateDnsNamespace is async (returns OperationId) but we handle
27890
- * the polling ourselves, avoiding the CC API's generic polling overhead and
27891
- * giving us direct control over the operation lifecycle.
27892
+ * WHY: the Create*Namespace APIs are async (they return an OperationId) but we
27893
+ * handle the polling ourselves, avoiding the CC API's generic polling overhead
27894
+ * and giving us direct control over the operation lifecycle. HttpNamespace and
27895
+ * PublicDnsNamespace are `ProvisioningType: NON_PROVISIONABLE`, so Cloud
27896
+ * Control cannot handle them at all — this SDK provider is the only route
27897
+ * (issue #1044).
27892
27898
  */
27893
- var ServiceDiscoveryProvider = class {
27899
+ var ServiceDiscoveryProvider = class ServiceDiscoveryProvider {
27894
27900
  client;
27895
27901
  stsClient;
27896
27902
  providerRegion = process.env["AWS_REGION"];
27897
27903
  logger = getLogger().child("ServiceDiscoveryProvider");
27898
- handledProperties = new Map([["AWS::ServiceDiscovery::PrivateDnsNamespace", new Set([
27899
- "Name",
27900
- "Vpc",
27901
- "Description",
27902
- "Tags",
27903
- "Properties"
27904
- ])], ["AWS::ServiceDiscovery::Service", new Set([
27905
- "Name",
27906
- "NamespaceId",
27907
- "DnsConfig",
27908
- "HealthCheckCustomConfig",
27909
- "Description",
27910
- "HealthCheckConfig",
27911
- "Tags",
27912
- "Type",
27913
- "ServiceAttributes"
27914
- ])]]);
27904
+ handledProperties = new Map([
27905
+ ["AWS::ServiceDiscovery::PrivateDnsNamespace", new Set([
27906
+ "Name",
27907
+ "Vpc",
27908
+ "Description",
27909
+ "Tags",
27910
+ "Properties"
27911
+ ])],
27912
+ ["AWS::ServiceDiscovery::HttpNamespace", new Set([
27913
+ "Name",
27914
+ "Description",
27915
+ "Tags"
27916
+ ])],
27917
+ ["AWS::ServiceDiscovery::PublicDnsNamespace", new Set([
27918
+ "Name",
27919
+ "Description",
27920
+ "Tags",
27921
+ "Properties"
27922
+ ])],
27923
+ ["AWS::ServiceDiscovery::Service", new Set([
27924
+ "Name",
27925
+ "NamespaceId",
27926
+ "DnsConfig",
27927
+ "HealthCheckCustomConfig",
27928
+ "Description",
27929
+ "HealthCheckConfig",
27930
+ "Tags",
27931
+ "Type",
27932
+ "ServiceAttributes"
27933
+ ])]
27934
+ ]);
27915
27935
  getClient() {
27916
27936
  if (!this.client) this.client = new ServiceDiscoveryClient(this.providerRegion ? { region: this.providerRegion } : {});
27917
27937
  return this.client;
@@ -27923,20 +27943,26 @@ var ServiceDiscoveryProvider = class {
27923
27943
  async create(logicalId, resourceType, properties) {
27924
27944
  switch (resourceType) {
27925
27945
  case "AWS::ServiceDiscovery::PrivateDnsNamespace": return this.createNamespace(logicalId, resourceType, properties);
27946
+ case "AWS::ServiceDiscovery::HttpNamespace": return this.createHttpNamespace(logicalId, resourceType, properties);
27947
+ case "AWS::ServiceDiscovery::PublicDnsNamespace": return this.createPublicDnsNamespace(logicalId, resourceType, properties);
27926
27948
  case "AWS::ServiceDiscovery::Service": return this.createService(logicalId, resourceType, properties);
27927
27949
  default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId);
27928
27950
  }
27929
27951
  }
27930
27952
  update(logicalId, physicalId, resourceType, properties, previousProperties) {
27931
27953
  switch (resourceType) {
27932
- case "AWS::ServiceDiscovery::PrivateDnsNamespace": return this.updateNamespace(logicalId, physicalId, resourceType, properties);
27954
+ case "AWS::ServiceDiscovery::PrivateDnsNamespace": return this.updateNamespace(logicalId, physicalId, resourceType, properties, previousProperties);
27955
+ case "AWS::ServiceDiscovery::HttpNamespace": return this.updateHttpNamespace(logicalId, physicalId, resourceType, properties, previousProperties);
27956
+ case "AWS::ServiceDiscovery::PublicDnsNamespace": return this.updatePublicDnsNamespace(logicalId, physicalId, resourceType, properties, previousProperties);
27933
27957
  case "AWS::ServiceDiscovery::Service": return this.updateService(logicalId, physicalId, resourceType, properties, previousProperties);
27934
27958
  default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId, physicalId);
27935
27959
  }
27936
27960
  }
27937
27961
  async delete(logicalId, physicalId, resourceType, _properties, context) {
27938
27962
  switch (resourceType) {
27939
- case "AWS::ServiceDiscovery::PrivateDnsNamespace": return this.deleteNamespace(logicalId, physicalId, resourceType, context);
27963
+ case "AWS::ServiceDiscovery::PrivateDnsNamespace":
27964
+ case "AWS::ServiceDiscovery::HttpNamespace":
27965
+ case "AWS::ServiceDiscovery::PublicDnsNamespace": return this.deleteNamespace(logicalId, physicalId, resourceType, context);
27940
27966
  case "AWS::ServiceDiscovery::Service": return this.deleteService(logicalId, physicalId, resourceType, context);
27941
27967
  default: throw new ProvisioningError(`Unsupported resource type: ${resourceType}`, resourceType, logicalId, physicalId);
27942
27968
  }
@@ -27950,8 +27976,7 @@ var ServiceDiscoveryProvider = class {
27950
27976
  const tags = properties["Tags"];
27951
27977
  if (!name) throw new ProvisioningError(`Name is required for PrivateDnsNamespace ${logicalId}`, resourceType, logicalId);
27952
27978
  if (!vpc) throw new ProvisioningError(`Vpc is required for PrivateDnsNamespace ${logicalId}`, resourceType, logicalId);
27953
- const soa = (properties["Properties"]?.["DnsProperties"])?.["SOA"];
27954
- const inputProperties = soa?.TTL !== void 0 ? { DnsProperties: { SOA: { TTL: Number(soa.TTL) } } } : void 0;
27979
+ const inputProperties = this.extractSoaTtlProperties(properties);
27955
27980
  try {
27956
27981
  const operationId = (await client.send(new CreatePrivateDnsNamespaceCommand({
27957
27982
  Name: name,
@@ -27987,30 +28012,29 @@ var ServiceDiscoveryProvider = class {
27987
28012
  * `Name` and `Vpc` are immutable; the deploy engine's
27988
28013
  * replacement-detection layer routes those through DELETE+CREATE
27989
28014
  * before this method is ever called, so we do not validate them here.
28015
+ * Tags ride on the separate `TagResource` / `UntagResource` APIs
28016
+ * (see {@link syncNamespaceTags} — wired in with issue #1044 so a
28017
+ * Tags-only change is no longer silently dropped, the ECR #981 class).
27990
28018
  *
27991
28019
  * Empty-string Description is intentionally allowed through (`!== undefined`
27992
28020
  * gate, not truthy) so `cdkd drift --revert` can clear a console-side ADD.
27993
28021
  */
27994
- async updateNamespace(logicalId, physicalId, resourceType, properties) {
28022
+ async updateNamespace(logicalId, physicalId, resourceType, properties, previousProperties) {
27995
28023
  this.logger.debug(`Updating private DNS namespace ${logicalId}: ${physicalId}`);
27996
28024
  const client = this.getClient();
27997
28025
  const namespaceChange = {};
27998
28026
  if (properties["Description"] !== void 0) namespaceChange.Description = properties["Description"];
27999
- const soa = (properties["Properties"]?.["DnsProperties"])?.["SOA"];
28000
- if (soa?.TTL !== void 0) namespaceChange.Properties = { DnsProperties: { SOA: { TTL: Number(soa.TTL) } } };
28001
- if (Object.keys(namespaceChange).length === 0) {
28002
- this.logger.debug(`No mutable diff for PrivateDnsNamespace ${logicalId}, skipping update`);
28003
- return {
28004
- physicalId,
28005
- wasReplaced: false
28006
- };
28007
- }
28027
+ const soaProperties = this.extractSoaTtlProperties(properties);
28028
+ if (soaProperties) namespaceChange.Properties = soaProperties;
28008
28029
  try {
28009
- const operationId = (await client.send(new UpdatePrivateDnsNamespaceCommand({
28010
- Id: physicalId,
28011
- Namespace: namespaceChange
28012
- }))).OperationId;
28013
- if (operationId) await this.pollOperation(operationId, logicalId, resourceType);
28030
+ if (Object.keys(namespaceChange).length > 0) {
28031
+ const operationId = (await client.send(new UpdatePrivateDnsNamespaceCommand({
28032
+ Id: physicalId,
28033
+ Namespace: namespaceChange
28034
+ }))).OperationId;
28035
+ if (operationId) await this.pollOperation(operationId, logicalId, resourceType);
28036
+ } else this.logger.debug(`No mutable namespace-body diff for PrivateDnsNamespace ${logicalId}`);
28037
+ await this.syncNamespaceTags(logicalId, physicalId, properties, previousProperties);
28014
28038
  this.logger.debug(`Successfully updated private DNS namespace ${logicalId}`);
28015
28039
  return {
28016
28040
  physicalId,
@@ -28022,21 +28046,172 @@ var ServiceDiscoveryProvider = class {
28022
28046
  throw new ProvisioningError(`Failed to update private DNS namespace ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
28023
28047
  }
28024
28048
  }
28049
+ /**
28050
+ * Delete a Cloud Map namespace (shared by PrivateDnsNamespace,
28051
+ * HttpNamespace, and PublicDnsNamespace — `DeleteNamespace` is
28052
+ * kind-agnostic and operation-based for all three).
28053
+ */
28025
28054
  async deleteNamespace(logicalId, physicalId, resourceType, context) {
28026
- this.logger.debug(`Deleting private DNS namespace ${logicalId}: ${physicalId}`);
28055
+ this.logger.debug(`Deleting Cloud Map namespace ${logicalId}: ${physicalId}`);
28027
28056
  const client = this.getClient();
28028
28057
  try {
28029
28058
  const operationId = (await client.send(new DeleteNamespaceCommand({ Id: physicalId }))).OperationId;
28030
28059
  if (operationId) await this.pollOperation(operationId, logicalId, resourceType);
28031
- this.logger.debug(`Successfully deleted private DNS namespace ${logicalId}`);
28060
+ this.logger.debug(`Successfully deleted Cloud Map namespace ${logicalId}`);
28032
28061
  } catch (error) {
28033
28062
  if (error instanceof NamespaceNotFound) {
28034
28063
  assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
28035
28064
  this.logger.debug(`Namespace ${physicalId} does not exist, skipping deletion`);
28036
28065
  return;
28037
28066
  }
28067
+ if (error instanceof ProvisioningError) throw error;
28068
+ const cause = error instanceof Error ? error : void 0;
28069
+ throw new ProvisioningError(`Failed to delete Cloud Map namespace ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
28070
+ }
28071
+ }
28072
+ async createHttpNamespace(logicalId, resourceType, properties) {
28073
+ this.logger.debug(`Creating HTTP namespace ${logicalId}`);
28074
+ const client = this.getClient();
28075
+ const name = properties["Name"];
28076
+ const description = properties["Description"];
28077
+ const tags = properties["Tags"];
28078
+ if (!name) throw new ProvisioningError(`Name is required for HttpNamespace ${logicalId}`, resourceType, logicalId);
28079
+ try {
28080
+ const operationId = (await client.send(new CreateHttpNamespaceCommand({
28081
+ Name: name,
28082
+ ...description && { Description: description },
28083
+ ...tags && tags.length > 0 && { Tags: tags }
28084
+ }))).OperationId;
28085
+ if (!operationId) throw new Error("CreateHttpNamespace did not return OperationId");
28086
+ const namespaceId = await this.pollOperation(operationId, logicalId, resourceType);
28087
+ const arn = await this.resolveNamespaceArn(namespaceId);
28088
+ this.logger.debug(`Successfully created HTTP namespace ${logicalId}: ${namespaceId}`);
28089
+ return {
28090
+ physicalId: namespaceId,
28091
+ attributes: {
28092
+ Id: namespaceId,
28093
+ Arn: arn
28094
+ }
28095
+ };
28096
+ } catch (error) {
28097
+ if (error instanceof ProvisioningError) throw error;
28038
28098
  const cause = error instanceof Error ? error : void 0;
28039
- throw new ProvisioningError(`Failed to delete private DNS namespace ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
28099
+ throw new ProvisioningError(`Failed to create HTTP namespace ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
28100
+ }
28101
+ }
28102
+ /**
28103
+ * Update an HTTP namespace.
28104
+ *
28105
+ * `UpdateHttpNamespace` exposes exactly one mutable field: `Description`
28106
+ * (the SDK's `HttpNamespaceChange` shape). `Name` is createOnly — the
28107
+ * replacement-detection layer routes a Name change through DELETE+CREATE
28108
+ * before this method is ever called. Tags ride on the separate
28109
+ * `TagResource` / `UntagResource` APIs (see {@link syncNamespaceTags}).
28110
+ *
28111
+ * Empty-string Description is intentionally allowed through
28112
+ * (`!== undefined` gate, not truthy) so `cdkd drift --revert` can clear a
28113
+ * console-side ADD.
28114
+ */
28115
+ async updateHttpNamespace(logicalId, physicalId, resourceType, properties, previousProperties) {
28116
+ this.logger.debug(`Updating HTTP namespace ${logicalId}: ${physicalId}`);
28117
+ const client = this.getClient();
28118
+ try {
28119
+ if (properties["Description"] !== void 0) {
28120
+ const namespaceChange = { Description: properties["Description"] };
28121
+ const operationId = (await client.send(new UpdateHttpNamespaceCommand({
28122
+ Id: physicalId,
28123
+ Namespace: namespaceChange
28124
+ }))).OperationId;
28125
+ if (operationId) await this.pollOperation(operationId, logicalId, resourceType);
28126
+ }
28127
+ await this.syncNamespaceTags(logicalId, physicalId, properties, previousProperties);
28128
+ this.logger.debug(`Successfully updated HTTP namespace ${logicalId}`);
28129
+ return {
28130
+ physicalId,
28131
+ wasReplaced: false
28132
+ };
28133
+ } catch (error) {
28134
+ if (error instanceof ProvisioningError) throw error;
28135
+ const cause = error instanceof Error ? error : void 0;
28136
+ throw new ProvisioningError(`Failed to update HTTP namespace ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
28137
+ }
28138
+ }
28139
+ async createPublicDnsNamespace(logicalId, resourceType, properties) {
28140
+ this.logger.debug(`Creating public DNS namespace ${logicalId}`);
28141
+ const client = this.getClient();
28142
+ const name = properties["Name"];
28143
+ const description = properties["Description"];
28144
+ const tags = properties["Tags"];
28145
+ if (!name) throw new ProvisioningError(`Name is required for PublicDnsNamespace ${logicalId}`, resourceType, logicalId);
28146
+ const inputProperties = this.extractSoaTtlProperties(properties);
28147
+ try {
28148
+ const operationId = (await client.send(new CreatePublicDnsNamespaceCommand({
28149
+ Name: name,
28150
+ ...description && { Description: description },
28151
+ ...tags && tags.length > 0 && { Tags: tags },
28152
+ ...inputProperties && { Properties: inputProperties }
28153
+ }))).OperationId;
28154
+ if (!operationId) throw new Error("CreatePublicDnsNamespace did not return OperationId");
28155
+ const namespaceId = await this.pollOperation(operationId, logicalId, resourceType);
28156
+ let arn;
28157
+ let hostedZoneId;
28158
+ try {
28159
+ const nsResp = await client.send(new GetNamespaceCommand({ Id: namespaceId }));
28160
+ arn = nsResp.Namespace?.Arn;
28161
+ hostedZoneId = nsResp.Namespace?.Properties?.DnsProperties?.HostedZoneId;
28162
+ } catch (err) {
28163
+ this.logger.debug(`GetNamespace(${namespaceId}) after create failed: ${err instanceof Error ? err.message : String(err)}`);
28164
+ }
28165
+ if (!arn) arn = await this.buildNamespaceArn(namespaceId);
28166
+ this.logger.debug(`Successfully created public DNS namespace ${logicalId}: ${namespaceId}`);
28167
+ return {
28168
+ physicalId: namespaceId,
28169
+ attributes: {
28170
+ Id: namespaceId,
28171
+ Arn: arn,
28172
+ ...hostedZoneId && { HostedZoneId: hostedZoneId }
28173
+ }
28174
+ };
28175
+ } catch (error) {
28176
+ if (error instanceof ProvisioningError) throw error;
28177
+ const cause = error instanceof Error ? error : void 0;
28178
+ throw new ProvisioningError(`Failed to create public DNS namespace ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
28179
+ }
28180
+ }
28181
+ /**
28182
+ * Update a public DNS namespace.
28183
+ *
28184
+ * `UpdatePublicDnsNamespace` exposes two mutable surfaces (the SDK's
28185
+ * `PublicDnsNamespaceChange` shape): `Description` and
28186
+ * `Properties.DnsProperties.SOA.TTL`. `Name` is createOnly — replacement
28187
+ * is routed through DELETE+CREATE upstream. Tags ride on the separate
28188
+ * `TagResource` / `UntagResource` APIs (see {@link syncNamespaceTags}).
28189
+ */
28190
+ async updatePublicDnsNamespace(logicalId, physicalId, resourceType, properties, previousProperties) {
28191
+ this.logger.debug(`Updating public DNS namespace ${logicalId}: ${physicalId}`);
28192
+ const client = this.getClient();
28193
+ const namespaceChange = {};
28194
+ if (properties["Description"] !== void 0) namespaceChange.Description = properties["Description"];
28195
+ const soaProperties = this.extractSoaTtlProperties(properties);
28196
+ if (soaProperties) namespaceChange.Properties = soaProperties;
28197
+ try {
28198
+ if (Object.keys(namespaceChange).length > 0) {
28199
+ const operationId = (await client.send(new UpdatePublicDnsNamespaceCommand({
28200
+ Id: physicalId,
28201
+ Namespace: namespaceChange
28202
+ }))).OperationId;
28203
+ if (operationId) await this.pollOperation(operationId, logicalId, resourceType);
28204
+ }
28205
+ await this.syncNamespaceTags(logicalId, physicalId, properties, previousProperties);
28206
+ this.logger.debug(`Successfully updated public DNS namespace ${logicalId}`);
28207
+ return {
28208
+ physicalId,
28209
+ wasReplaced: false
28210
+ };
28211
+ } catch (error) {
28212
+ if (error instanceof ProvisioningError) throw error;
28213
+ const cause = error instanceof Error ? error : void 0;
28214
+ throw new ProvisioningError(`Failed to update public DNS namespace ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
28040
28215
  }
28041
28216
  }
28042
28217
  async createService(logicalId, resourceType, properties) {
@@ -28186,6 +28361,59 @@ var ServiceDiscoveryProvider = class {
28186
28361
  }
28187
28362
  }
28188
28363
  /**
28364
+ * Extract the CFn `Properties.DnsProperties.SOA.TTL` nested field (the only
28365
+ * mutable entry in the namespace `Properties` bag, shared by the private
28366
+ * and public DNS namespace kinds) into the SDK's input shape. Returns
28367
+ * `undefined` when the template does not set a TTL.
28368
+ */
28369
+ extractSoaTtlProperties(properties) {
28370
+ const soa = (properties["Properties"]?.["DnsProperties"])?.["SOA"];
28371
+ return soa?.TTL !== void 0 ? { DnsProperties: { SOA: { TTL: Number(soa.TTL) } } } : void 0;
28372
+ }
28373
+ /**
28374
+ * Resolve a namespace's ARN — authoritative via `GetNamespace`, with a
28375
+ * deterministic STS-based construction as fallback so a transient read
28376
+ * failure right after create does not fail the whole resource.
28377
+ */
28378
+ async resolveNamespaceArn(namespaceId) {
28379
+ try {
28380
+ const resp = await this.getClient().send(new GetNamespaceCommand({ Id: namespaceId }));
28381
+ if (resp.Namespace?.Arn) return resp.Namespace.Arn;
28382
+ } catch (err) {
28383
+ this.logger.debug(`GetNamespace(${namespaceId}) failed while resolving ARN: ${err instanceof Error ? err.message : String(err)}`);
28384
+ }
28385
+ return this.buildNamespaceArn(namespaceId);
28386
+ }
28387
+ /**
28388
+ * Diff-and-apply namespace tags via `TagResource` / `UntagResource`.
28389
+ *
28390
+ * `TagResource` is additive-only, so a tag dropped from the template
28391
+ * (partial removal) — or the entire `Tags` property removed (full removal,
28392
+ * `newTags === undefined`) — would survive on AWS unless we explicitly
28393
+ * `UntagResource` the removed keys (the ECR #981 regression class).
28394
+ * Failures THROW (never warn-swallow) so cdkd state is never written
28395
+ * as-if-applied; the next deploy retries naturally.
28396
+ */
28397
+ async syncNamespaceTags(logicalId, physicalId, properties, previousProperties) {
28398
+ const newTags = properties["Tags"];
28399
+ const oldTags = previousProperties["Tags"];
28400
+ if (JSON.stringify(newTags) === JSON.stringify(oldTags)) return;
28401
+ const newKeys = new Set((newTags ?? []).map((t) => t.Key).filter((k) => !!k));
28402
+ const removedKeys = (oldTags ?? []).map((t) => t.Key).filter((k) => !!k && !newKeys.has(k));
28403
+ const hasAdds = !!newTags && newTags.length > 0;
28404
+ if (removedKeys.length === 0 && !hasAdds) return;
28405
+ const arn = await this.resolveNamespaceArn(physicalId);
28406
+ if (removedKeys.length > 0) await this.getClient().send(new UntagResourceCommand$13({
28407
+ ResourceARN: arn,
28408
+ TagKeys: removedKeys
28409
+ }));
28410
+ if (hasAdds) await this.getClient().send(new TagResourceCommand$13({
28411
+ ResourceARN: arn,
28412
+ Tags: newTags
28413
+ }));
28414
+ this.logger.debug(`Updated tags for namespace ${logicalId} (${physicalId})`);
28415
+ }
28416
+ /**
28189
28417
  * Poll a Service Discovery operation until it completes.
28190
28418
  * Returns the target resource ID from the operation result.
28191
28419
  */
@@ -28208,6 +28436,44 @@ var ServiceDiscoveryProvider = class {
28208
28436
  throw new ProvisioningError(`Operation timed out for ${logicalId} (operationId: ${operationId})`, resourceType, logicalId);
28209
28437
  }
28210
28438
  /**
28439
+ * Resolve a `Fn::GetAtt` attribute live from AWS (used by `cdkd orphan`'s
28440
+ * sibling-reference rewriting and other post-deploy attribute reads).
28441
+ *
28442
+ * Namespace kinds resolve `Id` / `Arn` (plus `HostedZoneId` for the DNS
28443
+ * namespace kinds, read from `GetNamespace`'s
28444
+ * `Properties.DnsProperties.HostedZoneId`); Services resolve `Id` / `Arn` /
28445
+ * `Name` via `GetService`. Returns `undefined` for unknown attributes and
28446
+ * for gone resources.
28447
+ */
28448
+ async getAttribute(physicalId, resourceType, attributeName) {
28449
+ switch (resourceType) {
28450
+ case "AWS::ServiceDiscovery::PrivateDnsNamespace":
28451
+ case "AWS::ServiceDiscovery::HttpNamespace":
28452
+ case "AWS::ServiceDiscovery::PublicDnsNamespace":
28453
+ if (attributeName === "Id") return physicalId;
28454
+ if (attributeName !== "Arn" && attributeName !== "HostedZoneId") return void 0;
28455
+ try {
28456
+ const resp = await this.getClient().send(new GetNamespaceCommand({ Id: physicalId }));
28457
+ if (attributeName === "Arn") return resp.Namespace?.Arn;
28458
+ return resp.Namespace?.Properties?.DnsProperties?.HostedZoneId;
28459
+ } catch (err) {
28460
+ if (err instanceof NamespaceNotFound) return void 0;
28461
+ throw err;
28462
+ }
28463
+ case "AWS::ServiceDiscovery::Service":
28464
+ if (attributeName === "Id") return physicalId;
28465
+ if (attributeName !== "Arn" && attributeName !== "Name") return void 0;
28466
+ try {
28467
+ const resp = await this.getClient().send(new GetServiceCommand({ Id: physicalId }));
28468
+ return attributeName === "Arn" ? resp.Service?.Arn : resp.Service?.Name;
28469
+ } catch (err) {
28470
+ if (err instanceof ServiceNotFound) return void 0;
28471
+ throw err;
28472
+ }
28473
+ default: return;
28474
+ }
28475
+ }
28476
+ /**
28211
28477
  * Adopt an existing Cloud Map (Service Discovery) resource into cdkd state.
28212
28478
  *
28213
28479
  * - **AWS::ServiceDiscovery::PrivateDnsNamespace**: tag-based auto-lookup
@@ -28241,7 +28507,9 @@ var ServiceDiscoveryProvider = class {
28241
28507
  */
28242
28508
  async readCurrentState(physicalId, _logicalId, resourceType) {
28243
28509
  switch (resourceType) {
28244
- case "AWS::ServiceDiscovery::PrivateDnsNamespace": return this.readNamespace(physicalId);
28510
+ case "AWS::ServiceDiscovery::PrivateDnsNamespace":
28511
+ case "AWS::ServiceDiscovery::PublicDnsNamespace": return this.readNamespace(physicalId, { includeProperties: true });
28512
+ case "AWS::ServiceDiscovery::HttpNamespace": return this.readNamespace(physicalId, { includeProperties: false });
28245
28513
  case "AWS::ServiceDiscovery::Service": return this.readService(physicalId);
28246
28514
  default: return;
28247
28515
  }
@@ -28262,7 +28530,7 @@ var ServiceDiscoveryProvider = class {
28262
28530
  if (resourceType === "AWS::ServiceDiscovery::PrivateDnsNamespace") return ["Vpc"];
28263
28531
  return [];
28264
28532
  }
28265
- async readNamespace(physicalId) {
28533
+ async readNamespace(physicalId, options) {
28266
28534
  let ns;
28267
28535
  try {
28268
28536
  ns = (await this.getClient().send(new GetNamespaceCommand({ Id: physicalId }))).Namespace;
@@ -28274,9 +28542,11 @@ var ServiceDiscoveryProvider = class {
28274
28542
  const result = {};
28275
28543
  if (ns.Name !== void 0) result["Name"] = ns.Name;
28276
28544
  result["Description"] = ns.Description ?? "";
28277
- const soa = ns.Properties?.DnsProperties?.SOA;
28278
- if (soa?.TTL !== void 0) result["Properties"] = { DnsProperties: { SOA: { TTL: soa.TTL } } };
28279
- else result["Properties"] = {};
28545
+ if (options.includeProperties) {
28546
+ const soa = ns.Properties?.DnsProperties?.SOA;
28547
+ if (soa?.TTL !== void 0) result["Properties"] = { DnsProperties: { SOA: { TTL: soa.TTL } } };
28548
+ else result["Properties"] = {};
28549
+ }
28280
28550
  if (ns.Arn) await this.attachTags(result, ns.Arn);
28281
28551
  return result;
28282
28552
  }
@@ -28332,14 +28602,32 @@ var ServiceDiscoveryProvider = class {
28332
28602
  }
28333
28603
  async import(input) {
28334
28604
  switch (input.resourceType) {
28335
- case "AWS::ServiceDiscovery::PrivateDnsNamespace": return this.importNamespaceResource(input);
28605
+ case "AWS::ServiceDiscovery::PrivateDnsNamespace":
28606
+ case "AWS::ServiceDiscovery::HttpNamespace":
28607
+ case "AWS::ServiceDiscovery::PublicDnsNamespace": return this.importNamespaceResource(input);
28336
28608
  case "AWS::ServiceDiscovery::Service": return this.importServiceResource(input);
28337
28609
  default: return null;
28338
28610
  }
28339
28611
  }
28612
+ /**
28613
+ * Map each namespace CFn type to its Cloud Map `Namespace.Type` value so
28614
+ * the import walk never adopts a same-named namespace of a different kind
28615
+ * (Cloud Map names are NOT unique across kinds; adopting the wrong one
28616
+ * would make a later destroy delete the wrong resource).
28617
+ */
28618
+ static NAMESPACE_KIND_BY_TYPE = {
28619
+ "AWS::ServiceDiscovery::PrivateDnsNamespace": "DNS_PRIVATE",
28620
+ "AWS::ServiceDiscovery::HttpNamespace": "HTTP",
28621
+ "AWS::ServiceDiscovery::PublicDnsNamespace": "DNS_PUBLIC"
28622
+ };
28340
28623
  async importNamespaceResource(input) {
28624
+ const expectedKind = ServiceDiscoveryProvider.NAMESPACE_KIND_BY_TYPE[input.resourceType];
28341
28625
  if (input.knownPhysicalId) try {
28342
- await this.getClient().send(new GetNamespaceCommand({ Id: input.knownPhysicalId }));
28626
+ const resp = await this.getClient().send(new GetNamespaceCommand({ Id: input.knownPhysicalId }));
28627
+ if (expectedKind && resp.Namespace?.Type && resp.Namespace.Type !== expectedKind) {
28628
+ this.logger.debug(`Namespace ${input.knownPhysicalId} is kind ${resp.Namespace.Type}, expected ${expectedKind} for ${input.resourceType} — refusing to adopt`);
28629
+ return null;
28630
+ }
28343
28631
  return {
28344
28632
  physicalId: input.knownPhysicalId,
28345
28633
  attributes: {}
@@ -28354,6 +28642,7 @@ var ServiceDiscoveryProvider = class {
28354
28642
  const list = await this.getClient().send(new ListNamespacesCommand({ ...token && { NextToken: token } }));
28355
28643
  for (const ns of list.Namespaces ?? []) {
28356
28644
  if (!ns.Id || !ns.Arn) continue;
28645
+ if (expectedKind && ns.Type && ns.Type !== expectedKind) continue;
28357
28646
  if (desiredName && ns.Name === desiredName) return {
28358
28647
  physicalId: ns.Id,
28359
28648
  attributes: {}
@@ -28780,7 +29069,7 @@ var AppSyncProvider = class {
28780
29069
  const tagsToAdd = {};
28781
29070
  for (const [k, v] of Object.entries(newMap)) if (oldMap[k] !== v) tagsToAdd[k] = v;
28782
29071
  if (tagKeysToRemove.length > 0) try {
28783
- await this.getClient().send(new UntagResourceCommand$13({
29072
+ await this.getClient().send(new UntagResourceCommand$14({
28784
29073
  resourceArn: arn,
28785
29074
  tagKeys: tagKeysToRemove
28786
29075
  }));
@@ -28788,7 +29077,7 @@ var AppSyncProvider = class {
28788
29077
  throw this.wrapUpdateError(error, resourceType, logicalId, apiId, "GraphqlApi (untag)");
28789
29078
  }
28790
29079
  if (Object.keys(tagsToAdd).length > 0) try {
28791
- await this.getClient().send(new TagResourceCommand$13({
29080
+ await this.getClient().send(new TagResourceCommand$14({
28792
29081
  resourceArn: arn,
28793
29082
  tags: tagsToAdd
28794
29083
  }));
@@ -31580,6 +31869,492 @@ var KMSProvider = class {
31580
31869
  }
31581
31870
  };
31582
31871
 
31872
+ //#endregion
31873
+ //#region src/provisioning/providers/budgets-budget-provider.ts
31874
+ /**
31875
+ * SDK Provider for AWS::Budgets::Budget (issue #1041).
31876
+ *
31877
+ * The type is `ProvisioningType: NON_PROVISIONABLE`, so the Cloud Control
31878
+ * fallback cannot handle it — without this provider cdkd's pre-flight
31879
+ * rejects the type outright.
31880
+ *
31881
+ * **Global endpoint / region semantics**: the Budgets API is a global,
31882
+ * per-account service served from `us-east-1`. The `@aws-sdk/client-budgets`
31883
+ * endpoint ruleset resolves EVERY aws-partition region to the single global
31884
+ * endpoint (`budgets.amazonaws.com`, SigV4 scope `us-east-1`), so the client
31885
+ * below is deliberately created with the deploy region like every other
31886
+ * provider — the SDK itself pins the endpoint. This also keeps
31887
+ * `client.config.region()` equal to the deploy region, so the standard
31888
+ * `assertRegionMatch` idempotent-delete guard behaves exactly like it does
31889
+ * for regional services: a destroy run with a mismatched `--region` still
31890
+ * refuses to trust a NotFound. (For a global namespace a NotFound would
31891
+ * actually be trustworthy from any region, but keeping the guard uniform is
31892
+ * strictly safer and costs nothing.)
31893
+ *
31894
+ * **AccountId**: every Budgets API call requires the account id. It is
31895
+ * resolved once per provider instance via STS `GetCallerIdentity` (shared
31896
+ * `AwsClients.sts`) and cached as a single-flight promise for the deploy
31897
+ * lifetime; failed resolutions are not cached so a transient STS throttle
31898
+ * cannot poison the rest of the run (mirrors
31899
+ * `src/utils/expected-bucket-owner.ts`).
31900
+ *
31901
+ * **Physical id**: the budget NAME. `Budget.BudgetName` is createOnly —
31902
+ * a rename is classified as replacement by the `AWS::Budgets::Budget`
31903
+ * conditional rule in `src/analyzer/replacement-rules.ts`.
31904
+ *
31905
+ * **NotificationsWithSubscribers**: CloudFormation treats the whole property
31906
+ * as createOnly (replacement on any change). cdkd does better — `update()`
31907
+ * reconciles in place via CreateNotification / DeleteNotification /
31908
+ * CreateSubscriber / DeleteSubscriber, so alert history and the budget
31909
+ * itself survive a notification edit.
31910
+ */
31911
+ var BudgetsBudgetProvider = class {
31912
+ client;
31913
+ providerRegion = process.env["AWS_REGION"];
31914
+ logger = getLogger().child("BudgetsBudgetProvider");
31915
+ accountIdPromise;
31916
+ handledProperties = new Map([["AWS::Budgets::Budget", new Set([
31917
+ "Budget",
31918
+ "NotificationsWithSubscribers",
31919
+ "ResourceTags"
31920
+ ])]]);
31921
+ getClient() {
31922
+ if (!this.client) this.client = new BudgetsClient(this.providerRegion ? { region: this.providerRegion } : {});
31923
+ return this.client;
31924
+ }
31925
+ /**
31926
+ * Resolve the caller's AWS account id (required on every Budgets call).
31927
+ * Cached per provider instance as a single-flight promise; a failed
31928
+ * resolution is evicted so the next call retries instead of replaying a
31929
+ * transient error for the rest of the deploy.
31930
+ */
31931
+ resolveAccountId() {
31932
+ if (!this.accountIdPromise) this.accountIdPromise = (async () => {
31933
+ try {
31934
+ const identity = await getAwsClients().sts.send(new GetCallerIdentityCommand({}));
31935
+ if (!identity.Account) throw new Error("STS GetCallerIdentity returned no Account");
31936
+ return identity.Account;
31937
+ } catch (error) {
31938
+ this.accountIdPromise = void 0;
31939
+ throw error;
31940
+ }
31941
+ })();
31942
+ return this.accountIdPromise;
31943
+ }
31944
+ /**
31945
+ * Budget ARN for the tagging APIs (`ListTagsForResource` / `TagResource` /
31946
+ * `UntagResource`). Budgets ARNs carry no region component. The `aws`
31947
+ * partition is assumed — consistent with other providers that construct
31948
+ * ARNs; non-`aws` partitions are not supported by cdkd today.
31949
+ */
31950
+ budgetArn(accountId, budgetName) {
31951
+ return `arn:aws:budgets::${accountId}:budget/${budgetName}`;
31952
+ }
31953
+ /**
31954
+ * Convert a CFn `Spend` shape to the SDK shape. CFn templates carry
31955
+ * `Amount` as a number (CDK synthesizes `budgetLimit: { amount: 10 }` to a
31956
+ * numeric JSON value); the SDK wants a numeric string.
31957
+ */
31958
+ toSdkSpend(raw) {
31959
+ if (raw === void 0 || raw === null || typeof raw !== "object") return void 0;
31960
+ const spend = raw;
31961
+ const amount = spend["Amount"];
31962
+ return {
31963
+ Amount: typeof amount === "string" ? amount : typeof amount === "number" ? String(amount) : void 0,
31964
+ Unit: spend["Unit"]
31965
+ };
31966
+ }
31967
+ /**
31968
+ * Convert a CFn `TimePeriod` `Start` / `End` value to a `Date`. CFn accepts
31969
+ * a UTC date string (`2026-07-01T00:00:00Z`) or an epoch timestamp in
31970
+ * seconds (possibly as a numeric string).
31971
+ */
31972
+ toSdkDate(raw, field, logicalId, resourceType) {
31973
+ let date;
31974
+ if (typeof raw === "number") date = new Date(raw < 0xe8d4a51000 ? raw * 1e3 : raw);
31975
+ else if (typeof raw === "string" && /^\d+$/.test(raw)) {
31976
+ const num = Number(raw);
31977
+ date = new Date(num < 0xe8d4a51000 ? num * 1e3 : num);
31978
+ } else if (typeof raw === "string") date = new Date(raw);
31979
+ else throw new ProvisioningError(`Invalid TimePeriod.${field} for budget ${logicalId}: expected a date string or epoch timestamp, got ${JSON.stringify(raw)}`, resourceType, logicalId);
31980
+ if (Number.isNaN(date.getTime())) throw new ProvisioningError(`Invalid TimePeriod.${field} for budget ${logicalId}: ${JSON.stringify(raw)} is not a parseable date`, resourceType, logicalId);
31981
+ return date;
31982
+ }
31983
+ /**
31984
+ * Map the CFn `Budget` (BudgetData) property to the SDK `Budget` shape.
31985
+ * The two are PascalCase-identical except: `BudgetLimit` /
31986
+ * `PlannedBudgetLimits` amounts are numeric strings on the wire, and
31987
+ * `TimePeriod.Start` / `.End` are `Date`s. `FilterExpression` / `Metrics` /
31988
+ * `CostFilters` / `CostTypes` / `AutoAdjustData` pass through verbatim.
31989
+ */
31990
+ toSdkBudget(raw, budgetName, logicalId, resourceType) {
31991
+ if (raw === void 0 || raw === null || typeof raw !== "object") throw new ProvisioningError(`The Budget property is required for ${logicalId}`, resourceType, logicalId);
31992
+ const src = raw;
31993
+ const budget = {
31994
+ ...src,
31995
+ BudgetName: budgetName
31996
+ };
31997
+ if (src["BudgetLimit"] !== void 0) budget["BudgetLimit"] = this.toSdkSpend(src["BudgetLimit"]);
31998
+ if (src["PlannedBudgetLimits"] !== void 0 && typeof src["PlannedBudgetLimits"] === "object") {
31999
+ const limits = {};
32000
+ for (const [key, value] of Object.entries(src["PlannedBudgetLimits"])) limits[key] = this.toSdkSpend(value);
32001
+ budget["PlannedBudgetLimits"] = limits;
32002
+ }
32003
+ if (src["TimePeriod"] !== void 0 && typeof src["TimePeriod"] === "object") {
32004
+ const rawPeriod = src["TimePeriod"];
32005
+ const period = {};
32006
+ if (rawPeriod["Start"] !== void 0) period.Start = this.toSdkDate(rawPeriod["Start"], "Start", logicalId, resourceType);
32007
+ if (rawPeriod["End"] !== void 0) period.End = this.toSdkDate(rawPeriod["End"], "End", logicalId, resourceType);
32008
+ budget["TimePeriod"] = period;
32009
+ }
32010
+ return budget;
32011
+ }
32012
+ /** Normalize a CFn notification block to the SDK `Notification` shape. */
32013
+ toSdkNotification(raw) {
32014
+ return {
32015
+ NotificationType: raw["NotificationType"],
32016
+ ComparisonOperator: raw["ComparisonOperator"],
32017
+ Threshold: raw["Threshold"] !== void 0 ? Number(raw["Threshold"]) : void 0,
32018
+ ...raw["ThresholdType"] !== void 0 && { ThresholdType: raw["ThresholdType"] }
32019
+ };
32020
+ }
32021
+ /** Normalize a CFn subscriber block to the SDK `Subscriber` shape. */
32022
+ toSdkSubscriber(raw) {
32023
+ return {
32024
+ SubscriptionType: raw["SubscriptionType"],
32025
+ Address: raw["Address"]
32026
+ };
32027
+ }
32028
+ /**
32029
+ * Parse the CFn `NotificationsWithSubscribers` property into SDK shape.
32030
+ * Tolerates absent / non-array values (returns `[]`).
32031
+ */
32032
+ toSdkNotificationsWithSubscribers(raw) {
32033
+ if (!Array.isArray(raw)) return [];
32034
+ const out = [];
32035
+ for (const item of raw) {
32036
+ if (item === null || typeof item !== "object") continue;
32037
+ const entry = item;
32038
+ const notification = entry["Notification"];
32039
+ const subscribers = entry["Subscribers"];
32040
+ out.push({
32041
+ Notification: notification && typeof notification === "object" ? this.toSdkNotification(notification) : void 0,
32042
+ Subscribers: Array.isArray(subscribers) ? subscribers.filter((s) => s !== null && typeof s === "object").map((s) => this.toSdkSubscriber(s)) : void 0
32043
+ });
32044
+ }
32045
+ return out;
32046
+ }
32047
+ /**
32048
+ * Identity key for a notification. The Budgets API addresses notifications
32049
+ * by their full value (there is no notification id), so the reconciler
32050
+ * treats a change to any of these fields as delete-old + create-new.
32051
+ * `ThresholdType` defaults to `PERCENTAGE` service-side — normalize the
32052
+ * absent case so an explicit `PERCENTAGE` and an omitted one compare equal.
32053
+ */
32054
+ notificationKey(n) {
32055
+ return JSON.stringify([
32056
+ n.NotificationType,
32057
+ n.ComparisonOperator,
32058
+ n.Threshold,
32059
+ n.ThresholdType ?? "PERCENTAGE"
32060
+ ]);
32061
+ }
32062
+ /** Identity key for a subscriber. */
32063
+ subscriberKey(s) {
32064
+ return JSON.stringify([s.SubscriptionType, s.Address]);
32065
+ }
32066
+ /** Normalize the CFn `ResourceTags` property (`{Key,Value}[]`). */
32067
+ toSdkResourceTags(raw) {
32068
+ if (!Array.isArray(raw)) return [];
32069
+ const out = [];
32070
+ for (const item of raw) {
32071
+ if (item === null || typeof item !== "object") continue;
32072
+ const tag = item;
32073
+ if (typeof tag["Key"] !== "string") continue;
32074
+ const value = tag["Value"];
32075
+ out.push({
32076
+ Key: tag["Key"],
32077
+ Value: typeof value === "string" ? value : typeof value === "number" || typeof value === "boolean" ? String(value) : ""
32078
+ });
32079
+ }
32080
+ return out;
32081
+ }
32082
+ /**
32083
+ * Create a budget via `CreateBudget` (a single call carries the budget,
32084
+ * its notifications with subscribers, and resource tags — no post-create
32085
+ * wiring to clean up on partial failure).
32086
+ */
32087
+ async create(logicalId, resourceType, properties) {
32088
+ this.logger.debug(`Creating budget ${logicalId}`);
32089
+ const rawName = (properties["Budget"] ?? {})["BudgetName"];
32090
+ const name = typeof rawName === "string" && rawName.length > 0 ? rawName : generateResourceName(logicalId, {
32091
+ maxLength: 100,
32092
+ allowedPattern: /[^a-zA-Z0-9\-_.]/g
32093
+ });
32094
+ try {
32095
+ const accountId = await this.resolveAccountId();
32096
+ const notifications = this.toSdkNotificationsWithSubscribers(properties["NotificationsWithSubscribers"]);
32097
+ const resourceTags = this.toSdkResourceTags(properties["ResourceTags"]);
32098
+ await this.getClient().send(new CreateBudgetCommand({
32099
+ AccountId: accountId,
32100
+ Budget: this.toSdkBudget(properties["Budget"], name, logicalId, resourceType),
32101
+ ...notifications.length > 0 && { NotificationsWithSubscribers: notifications },
32102
+ ...resourceTags.length > 0 && { ResourceTags: resourceTags }
32103
+ }));
32104
+ this.logger.debug(`Successfully created budget ${logicalId}: ${name}`);
32105
+ return {
32106
+ physicalId: name,
32107
+ attributes: { Arn: this.budgetArn(accountId, name) }
32108
+ };
32109
+ } catch (error) {
32110
+ if (error instanceof ProvisioningError) throw error;
32111
+ const cause = error instanceof Error ? error : void 0;
32112
+ throw new ProvisioningError(`Failed to create budget ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
32113
+ }
32114
+ }
32115
+ /**
32116
+ * Update a budget: `UpdateBudget` for the budget definition, then
32117
+ * reconcile `NotificationsWithSubscribers` in place (CloudFormation would
32118
+ * replace the whole budget instead) and diff `ResourceTags`.
32119
+ */
32120
+ async update(logicalId, physicalId, resourceType, properties, previousProperties) {
32121
+ this.logger.debug(`Updating budget ${logicalId}: ${physicalId}`);
32122
+ try {
32123
+ const accountId = await this.resolveAccountId();
32124
+ await this.getClient().send(new UpdateBudgetCommand({
32125
+ AccountId: accountId,
32126
+ NewBudget: this.toSdkBudget(properties["Budget"], physicalId, logicalId, resourceType)
32127
+ }));
32128
+ await this.reconcileNotifications(accountId, physicalId, this.toSdkNotificationsWithSubscribers(previousProperties["NotificationsWithSubscribers"]), this.toSdkNotificationsWithSubscribers(properties["NotificationsWithSubscribers"]));
32129
+ await this.reconcileResourceTags(accountId, physicalId, this.toSdkResourceTags(previousProperties["ResourceTags"]), this.toSdkResourceTags(properties["ResourceTags"]));
32130
+ this.logger.debug(`Successfully updated budget ${logicalId}`);
32131
+ return {
32132
+ physicalId,
32133
+ wasReplaced: false,
32134
+ attributes: { Arn: this.budgetArn(accountId, physicalId) }
32135
+ };
32136
+ } catch (error) {
32137
+ if (error instanceof ProvisioningError) throw error;
32138
+ const cause = error instanceof Error ? error : void 0;
32139
+ throw new ProvisioningError(`Failed to update budget ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
32140
+ }
32141
+ }
32142
+ /**
32143
+ * Send a reconciler DELETE call, treating `NotFoundException` as success.
32144
+ * The reconciler must be idempotent: after a partial failure the deploy
32145
+ * engine retries the update forward (re-deleting an already-deleted
32146
+ * notification/subscriber) or rolls it back with the reversed diff
32147
+ * (deleting a notification the forward pass never created) — both land
32148
+ * here as NotFound and must not fail the recovery.
32149
+ */
32150
+ async sendDeleteIdempotent(command, what) {
32151
+ try {
32152
+ await this.getClient().send(command);
32153
+ } catch (error) {
32154
+ if (error instanceof NotFoundException$5) {
32155
+ this.logger.debug(`${what} already absent, skipping delete`);
32156
+ return;
32157
+ }
32158
+ throw error;
32159
+ }
32160
+ }
32161
+ /**
32162
+ * Send a reconciler CREATE call, treating `DuplicateRecordException` as
32163
+ * success — the retry/rollback twin of {@link sendDeleteIdempotent} for
32164
+ * re-creating a notification/subscriber a previous partial pass already
32165
+ * created.
32166
+ */
32167
+ async sendCreateIdempotent(command, what) {
32168
+ try {
32169
+ await this.getClient().send(command);
32170
+ } catch (error) {
32171
+ if (error instanceof DuplicateRecordException) {
32172
+ this.logger.debug(`${what} already exists, skipping create`);
32173
+ return;
32174
+ }
32175
+ throw error;
32176
+ }
32177
+ }
32178
+ /**
32179
+ * Reconcile the notification set: delete removed notifications first
32180
+ * (frees the 10-notifications-per-budget cap before additions), create
32181
+ * added ones, then diff subscribers on retained notifications. Every
32182
+ * step is idempotent (NotFound on delete / DuplicateRecord on create are
32183
+ * success) so a partial failure can be retried forward or rolled back.
32184
+ */
32185
+ async reconcileNotifications(accountId, budgetName, oldList, newList) {
32186
+ const buildKeyed = (list, side) => {
32187
+ const byKey = /* @__PURE__ */ new Map();
32188
+ for (const nws of list) {
32189
+ if (!nws.Notification) continue;
32190
+ const key = this.notificationKey(nws.Notification);
32191
+ if (byKey.has(key)) this.logger.warn(`Duplicate notification key ${key} in ${side} NotificationsWithSubscribers for budget ${budgetName}; the last entry's subscribers win`);
32192
+ byKey.set(key, nws);
32193
+ }
32194
+ return byKey;
32195
+ };
32196
+ const oldByKey = buildKeyed(oldList, "previous");
32197
+ const newByKey = buildKeyed(newList, "desired");
32198
+ for (const [key, nws] of oldByKey) {
32199
+ if (newByKey.has(key)) continue;
32200
+ await this.sendDeleteIdempotent(new DeleteNotificationCommand({
32201
+ AccountId: accountId,
32202
+ BudgetName: budgetName,
32203
+ Notification: nws.Notification
32204
+ }), `Notification ${key} on budget ${budgetName}`);
32205
+ this.logger.debug(`Deleted notification ${key} from budget ${budgetName}`);
32206
+ }
32207
+ for (const [key, nws] of newByKey) {
32208
+ if (oldByKey.has(key)) continue;
32209
+ await this.sendCreateIdempotent(new CreateNotificationCommand({
32210
+ AccountId: accountId,
32211
+ BudgetName: budgetName,
32212
+ Notification: nws.Notification,
32213
+ Subscribers: nws.Subscribers
32214
+ }), `Notification ${key} on budget ${budgetName}`);
32215
+ this.logger.debug(`Created notification ${key} on budget ${budgetName}`);
32216
+ }
32217
+ for (const [key, newNws] of newByKey) {
32218
+ const oldNws = oldByKey.get(key);
32219
+ if (!oldNws) continue;
32220
+ const oldSubs = /* @__PURE__ */ new Map();
32221
+ for (const s of oldNws.Subscribers ?? []) oldSubs.set(this.subscriberKey(s), s);
32222
+ const newSubs = /* @__PURE__ */ new Map();
32223
+ for (const s of newNws.Subscribers ?? []) newSubs.set(this.subscriberKey(s), s);
32224
+ for (const [subKey, subscriber] of newSubs) {
32225
+ if (oldSubs.has(subKey)) continue;
32226
+ await this.sendCreateIdempotent(new CreateSubscriberCommand({
32227
+ AccountId: accountId,
32228
+ BudgetName: budgetName,
32229
+ Notification: newNws.Notification,
32230
+ Subscriber: subscriber
32231
+ }), `Subscriber ${subKey} on notification ${key}`);
32232
+ this.logger.debug(`Created subscriber ${subKey} on notification ${key}`);
32233
+ }
32234
+ for (const [subKey, subscriber] of oldSubs) {
32235
+ if (newSubs.has(subKey)) continue;
32236
+ await this.sendDeleteIdempotent(new DeleteSubscriberCommand({
32237
+ AccountId: accountId,
32238
+ BudgetName: budgetName,
32239
+ Notification: newNws.Notification,
32240
+ Subscriber: subscriber
32241
+ }), `Subscriber ${subKey} on notification ${key}`);
32242
+ this.logger.debug(`Deleted subscriber ${subKey} from notification ${key}`);
32243
+ }
32244
+ }
32245
+ }
32246
+ /** Diff `ResourceTags` via `UntagResource` (removed keys) + `TagResource` (upsert). */
32247
+ async reconcileResourceTags(accountId, budgetName, oldTags, newTags) {
32248
+ const sortedJson = (tags) => JSON.stringify([...tags].sort((a, b) => (a.Key ?? "").localeCompare(b.Key ?? "")));
32249
+ if (sortedJson(oldTags) === sortedJson(newTags)) return;
32250
+ const arn = this.budgetArn(accountId, budgetName);
32251
+ const newKeys = new Set(newTags.map((t) => t.Key));
32252
+ const removedKeys = oldTags.map((t) => t.Key).filter((k) => {
32253
+ return typeof k === "string" && !newKeys.has(k);
32254
+ });
32255
+ if (removedKeys.length > 0) await this.getClient().send(new UntagResourceCommand$15({
32256
+ ResourceARN: arn,
32257
+ ResourceTagKeys: removedKeys
32258
+ }));
32259
+ if (newTags.length > 0) await this.getClient().send(new TagResourceCommand$15({
32260
+ ResourceARN: arn,
32261
+ ResourceTags: newTags
32262
+ }));
32263
+ this.logger.debug(`Updated resource tags for budget ${budgetName}`);
32264
+ }
32265
+ /**
32266
+ * Delete a budget (`DeleteBudget` also deletes all of its notifications
32267
+ * and subscribers). NotFound is idempotent success — after the standard
32268
+ * region assertion (see the class doc for why the guard stays uniform
32269
+ * even though the Budgets namespace is global).
32270
+ */
32271
+ async delete(logicalId, physicalId, resourceType, _properties, context) {
32272
+ this.logger.debug(`Deleting budget ${logicalId}: ${physicalId}`);
32273
+ try {
32274
+ const accountId = await this.resolveAccountId();
32275
+ await this.getClient().send(new DeleteBudgetCommand({
32276
+ AccountId: accountId,
32277
+ BudgetName: physicalId
32278
+ }));
32279
+ this.logger.debug(`Successfully deleted budget ${logicalId}`);
32280
+ } catch (error) {
32281
+ if (error instanceof NotFoundException$5) {
32282
+ assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
32283
+ this.logger.debug(`Budget ${physicalId} does not exist, skipping deletion`);
32284
+ return;
32285
+ }
32286
+ const cause = error instanceof Error ? error : void 0;
32287
+ throw new ProvisioningError(`Failed to delete budget ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
32288
+ }
32289
+ }
32290
+ /**
32291
+ * `Fn::GetAtt` support. CloudFormation documents no attributes for
32292
+ * `AWS::Budgets::Budget`; `Arn` is served as a cdkd convenience (computed
32293
+ * — Budgets ARNs are `arn:aws:budgets::{account}:budget/{name}`, verified
32294
+ * to exist via `DescribeBudget` first).
32295
+ */
32296
+ async getAttribute(physicalId, resourceType, attributeName) {
32297
+ if (attributeName !== "Arn") throw new ProvisioningError(`Unknown attribute ${attributeName} for ${resourceType}`, resourceType, physicalId);
32298
+ try {
32299
+ const accountId = await this.resolveAccountId();
32300
+ await this.getClient().send(new DescribeBudgetCommand({
32301
+ AccountId: accountId,
32302
+ BudgetName: physicalId
32303
+ }));
32304
+ return this.budgetArn(accountId, physicalId);
32305
+ } catch (error) {
32306
+ const cause = error instanceof Error ? error : void 0;
32307
+ throw new ProvisioningError(`Failed to resolve Arn for budget ${physicalId}: ${cause?.message ?? String(error)}`, resourceType, physicalId, physicalId, cause);
32308
+ }
32309
+ }
32310
+ /**
32311
+ * Adopt an existing budget into cdkd state.
32312
+ *
32313
+ * Lookup order:
32314
+ * 1. `--resource` override or `Properties.Budget.BudgetName` → verify via
32315
+ * `DescribeBudget`.
32316
+ * 2. `aws:cdk:path` tag match: walk `DescribeBudgets` and check each
32317
+ * budget's tags via `ListTagsForResource` (budget ARNs are
32318
+ * region-free, so the lookup works from any deploy region).
32319
+ */
32320
+ async import(input) {
32321
+ const rawBudget = input.properties["Budget"] ?? {};
32322
+ const explicit = input.knownPhysicalId ?? (typeof rawBudget["BudgetName"] === "string" && rawBudget["BudgetName"].length > 0 ? rawBudget["BudgetName"] : void 0);
32323
+ const accountId = await this.resolveAccountId();
32324
+ const client = this.getClient();
32325
+ if (explicit) try {
32326
+ await client.send(new DescribeBudgetCommand({
32327
+ AccountId: accountId,
32328
+ BudgetName: explicit
32329
+ }));
32330
+ return {
32331
+ physicalId: explicit,
32332
+ attributes: { Arn: this.budgetArn(accountId, explicit) }
32333
+ };
32334
+ } catch (error) {
32335
+ if (error instanceof NotFoundException$5) return null;
32336
+ throw error;
32337
+ }
32338
+ if (!input.cdkPath) return null;
32339
+ let nextToken;
32340
+ do {
32341
+ const list = await client.send(new DescribeBudgetsCommand({
32342
+ AccountId: accountId,
32343
+ ...nextToken && { NextToken: nextToken }
32344
+ }));
32345
+ for (const budget of list.Budgets ?? []) {
32346
+ if (!budget.BudgetName) continue;
32347
+ if (matchesCdkPath((await client.send(new ListTagsForResourceCommand$16({ ResourceARN: this.budgetArn(accountId, budget.BudgetName) }))).ResourceTags, input.cdkPath)) return {
32348
+ physicalId: budget.BudgetName,
32349
+ attributes: { Arn: this.budgetArn(accountId, budget.BudgetName) }
32350
+ };
32351
+ }
32352
+ nextToken = list.NextToken;
32353
+ } while (nextToken);
32354
+ return null;
32355
+ }
32356
+ };
32357
+
31583
32358
  //#endregion
31584
32359
  //#region src/provisioning/providers/kinesis-provider.ts
31585
32360
  /**
@@ -32140,7 +32915,7 @@ var KinesisStreamConsumerProvider = class {
32140
32915
  if (desc.ConsumerName !== void 0) result["ConsumerName"] = desc.ConsumerName;
32141
32916
  if (desc.StreamARN !== void 0) result["StreamARN"] = desc.StreamARN;
32142
32917
  try {
32143
- result["Tags"] = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsForResourceCommand$16({ ResourceARN: physicalId }))).Tags);
32918
+ result["Tags"] = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsForResourceCommand$17({ ResourceARN: physicalId }))).Tags);
32144
32919
  } catch (err) {
32145
32920
  if (err instanceof ResourceNotFoundException$8) return void 0;
32146
32921
  this.logger.debug(`ListTagsForResource(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -32164,14 +32939,14 @@ var KinesisStreamConsumerProvider = class {
32164
32939
  const tagsToRemove = [];
32165
32940
  for (const k of Object.keys(oldMap)) if (!(k in newMap)) tagsToRemove.push(k);
32166
32941
  if (tagsToRemove.length > 0) {
32167
- await this.getClient().send(new UntagResourceCommand$14({
32942
+ await this.getClient().send(new UntagResourceCommand$16({
32168
32943
  ResourceARN: consumerArn,
32169
32944
  TagKeys: tagsToRemove
32170
32945
  }));
32171
32946
  this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from Kinesis stream consumer ${consumerArn}`);
32172
32947
  }
32173
32948
  if (Object.keys(tagsToAdd).length > 0) {
32174
- await this.getClient().send(new TagResourceCommand$14({
32949
+ await this.getClient().send(new TagResourceCommand$16({
32175
32950
  ResourceARN: consumerArn,
32176
32951
  Tags: tagsToAdd
32177
32952
  }));
@@ -35322,11 +36097,11 @@ var CodeCommitRepositoryProvider = class {
35322
36097
  const repoArn = metadata?.Arn;
35323
36098
  if (repoArn) {
35324
36099
  const removedKeys = Object.keys(oldTagMap).filter((k) => !(k in newTagMap));
35325
- if (removedKeys.length > 0) await this.getClient().send(new UntagResourceCommand$15({
36100
+ if (removedKeys.length > 0) await this.getClient().send(new UntagResourceCommand$17({
35326
36101
  resourceArn: repoArn,
35327
36102
  tagKeys: removedKeys
35328
36103
  }));
35329
- if (Object.keys(newTagMap).length > 0) await this.getClient().send(new TagResourceCommand$15({
36104
+ if (Object.keys(newTagMap).length > 0) await this.getClient().send(new TagResourceCommand$17({
35330
36105
  resourceArn: repoArn,
35331
36106
  tags: newTagMap
35332
36107
  }));
@@ -35433,7 +36208,7 @@ var CodeCommitRepositoryProvider = class {
35433
36208
  throw err;
35434
36209
  }
35435
36210
  if (!metadata?.Arn) continue;
35436
- if ((await this.getClient().send(new ListTagsForResourceCommand$17({ resourceArn: metadata.Arn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
36211
+ if ((await this.getClient().send(new ListTagsForResourceCommand$18({ resourceArn: metadata.Arn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
35437
36212
  physicalId: repo.repositoryName,
35438
36213
  attributes: this.toAttributes(metadata)
35439
36214
  };
@@ -35583,7 +36358,7 @@ var DLMLifecyclePolicyProvider = class {
35583
36358
  if (tagsChanged && arn) {
35584
36359
  const removedKeys = Object.keys(oldTags).filter((k) => !(k in newTags));
35585
36360
  if (removedKeys.length > 0) {
35586
- await this.getClient().send(new UntagResourceCommand$16({
36361
+ await this.getClient().send(new UntagResourceCommand$18({
35587
36362
  ResourceArn: arn,
35588
36363
  TagKeys: removedKeys
35589
36364
  }));
@@ -35592,7 +36367,7 @@ var DLMLifecyclePolicyProvider = class {
35592
36367
  const tagsToAdd = {};
35593
36368
  for (const [k, v] of Object.entries(newTags)) if (oldTags[k] !== v) tagsToAdd[k] = v;
35594
36369
  if (Object.keys(tagsToAdd).length > 0) {
35595
- await this.getClient().send(new TagResourceCommand$16({
36370
+ await this.getClient().send(new TagResourceCommand$18({
35596
36371
  ResourceArn: arn,
35597
36372
  Tags: tagsToAdd
35598
36373
  }));
@@ -35795,11 +36570,11 @@ var S3VectorsProvider = class {
35795
36570
  }
35796
36571
  if (!resourceArn) throw new ProvisioningError(`Could not resolve ARN for S3 VectorBucket ${logicalId} (${physicalId}); cannot apply tag update.`, resourceType, logicalId, physicalId);
35797
36572
  try {
35798
- if (Object.keys(toSet).length > 0) await this.getClient().send(new TagResourceCommand$17({
36573
+ if (Object.keys(toSet).length > 0) await this.getClient().send(new TagResourceCommand$19({
35799
36574
  resourceArn,
35800
36575
  tags: toSet
35801
36576
  }));
35802
- if (toRemove.length > 0) await this.getClient().send(new UntagResourceCommand$17({
36577
+ if (toRemove.length > 0) await this.getClient().send(new UntagResourceCommand$19({
35803
36578
  resourceArn,
35804
36579
  tagKeys: toRemove
35805
36580
  }));
@@ -35927,7 +36702,7 @@ var S3VectorsProvider = class {
35927
36702
  if (Object.keys(enc).length > 0) result["EncryptionConfiguration"] = enc;
35928
36703
  }
35929
36704
  if (bucket?.vectorBucketArn) try {
35930
- result["Tags"] = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsForResourceCommand$18({ resourceArn: bucket.vectorBucketArn }))).tags);
36705
+ result["Tags"] = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsForResourceCommand$19({ resourceArn: bucket.vectorBucketArn }))).tags);
35931
36706
  } catch (err) {
35932
36707
  this.logger.debug(`S3Vectors ListTagsForResource(${bucket.vectorBucketArn}) failed: ${err instanceof Error ? err.message : String(err)}`);
35933
36708
  result["Tags"] = [];
@@ -35963,7 +36738,7 @@ var S3VectorsProvider = class {
35963
36738
  for (const bucket of list.vectorBuckets ?? []) {
35964
36739
  if (!bucket.vectorBucketName || !bucket.vectorBucketArn) continue;
35965
36740
  try {
35966
- if ((await this.getClient().send(new ListTagsForResourceCommand$18({ resourceArn: bucket.vectorBucketArn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
36741
+ if ((await this.getClient().send(new ListTagsForResourceCommand$19({ resourceArn: bucket.vectorBucketArn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
35967
36742
  physicalId: bucket.vectorBucketName,
35968
36743
  attributes: {}
35969
36744
  };
@@ -36314,7 +37089,7 @@ var S3TablesProvider = class {
36314
37089
  await this.getClient().send(new DeleteTableBucketCommand({ tableBucketARN: physicalId }));
36315
37090
  this.logger.debug(`Successfully deleted S3 Table Bucket ${logicalId}`);
36316
37091
  } catch (error) {
36317
- if (error instanceof NotFoundException$5) {
37092
+ if (error instanceof NotFoundException$6) {
36318
37093
  assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
36319
37094
  this.logger.debug(`S3 Table Bucket ${physicalId} does not exist, skipping deletion`);
36320
37095
  return;
@@ -36355,7 +37130,7 @@ var S3TablesProvider = class {
36355
37130
  name: table.name
36356
37131
  }));
36357
37132
  } catch (error) {
36358
- if (!(error instanceof NotFoundException$5)) throw error;
37133
+ if (!(error instanceof NotFoundException$6)) throw error;
36359
37134
  }
36360
37135
  }
36361
37136
  tableContinuationToken = tablesResult.continuationToken;
@@ -36367,7 +37142,7 @@ var S3TablesProvider = class {
36367
37142
  namespace: namespaceName
36368
37143
  }));
36369
37144
  } catch (error) {
36370
- if (!(error instanceof NotFoundException$5)) throw error;
37145
+ if (!(error instanceof NotFoundException$6)) throw error;
36371
37146
  }
36372
37147
  }
36373
37148
  namespaceContinuationToken = namespacesResult.continuationToken;
@@ -36409,7 +37184,7 @@ var S3TablesProvider = class {
36409
37184
  }));
36410
37185
  this.logger.debug(`Successfully deleted S3 Tables Namespace ${logicalId}`);
36411
37186
  } catch (error) {
36412
- if (error instanceof NotFoundException$5) {
37187
+ if (error instanceof NotFoundException$6) {
36413
37188
  assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
36414
37189
  this.logger.debug(`S3 Tables Namespace ${physicalId} does not exist, skipping deletion`);
36415
37190
  return;
@@ -36483,7 +37258,7 @@ var S3TablesProvider = class {
36483
37258
  try {
36484
37259
  bucket = await this.getClient().send(new GetTableBucketCommand({ tableBucketARN: physicalId }));
36485
37260
  } catch (err) {
36486
- if (err instanceof NotFoundException$5) return void 0;
37261
+ if (err instanceof NotFoundException$6) return void 0;
36487
37262
  throw err;
36488
37263
  }
36489
37264
  const result = {};
@@ -36512,7 +37287,7 @@ var S3TablesProvider = class {
36512
37287
  name
36513
37288
  }));
36514
37289
  } catch (err) {
36515
- if (err instanceof NotFoundException$5) return void 0;
37290
+ if (err instanceof NotFoundException$6) return void 0;
36516
37291
  throw err;
36517
37292
  }
36518
37293
  const tableNameValue = resp.name ?? name;
@@ -36559,7 +37334,7 @@ var S3TablesProvider = class {
36559
37334
  attributes: {}
36560
37335
  };
36561
37336
  } catch (err) {
36562
- if (err instanceof NotFoundException$5) return null;
37337
+ if (err instanceof NotFoundException$6) return null;
36563
37338
  throw err;
36564
37339
  }
36565
37340
  const desiredName = typeof input.properties?.["TableBucketName"] === "string" ? input.properties["TableBucketName"] : void 0;
@@ -36573,12 +37348,12 @@ var S3TablesProvider = class {
36573
37348
  attributes: {}
36574
37349
  };
36575
37350
  if (input.cdkPath) try {
36576
- if ((await this.getClient().send(new ListTagsForResourceCommand$19({ resourceArn: bucket.arn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
37351
+ if ((await this.getClient().send(new ListTagsForResourceCommand$20({ resourceArn: bucket.arn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
36577
37352
  physicalId: bucket.arn,
36578
37353
  attributes: {}
36579
37354
  };
36580
37355
  } catch (err) {
36581
- if (err instanceof NotFoundException$5) continue;
37356
+ if (err instanceof NotFoundException$6) continue;
36582
37357
  throw err;
36583
37358
  }
36584
37359
  }
@@ -36607,7 +37382,7 @@ var S3TablesProvider = class {
36607
37382
  attributes: {}
36608
37383
  };
36609
37384
  } catch (err) {
36610
- if (err instanceof NotFoundException$5) return null;
37385
+ if (err instanceof NotFoundException$6) return null;
36611
37386
  throw err;
36612
37387
  }
36613
37388
  return {
@@ -36640,12 +37415,12 @@ var S3TablesProvider = class {
36640
37415
  for (const table of tables.tables ?? []) {
36641
37416
  if (!table.name || !table.tableARN) continue;
36642
37417
  try {
36643
- if ((await this.getClient().send(new ListTagsForResourceCommand$19({ resourceArn: table.tableARN }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
37418
+ if ((await this.getClient().send(new ListTagsForResourceCommand$20({ resourceArn: table.tableARN }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
36644
37419
  physicalId: `${bucket.arn}|${namespaceName}|${table.name}`,
36645
37420
  attributes: {}
36646
37421
  };
36647
37422
  } catch (err) {
36648
- if (err instanceof NotFoundException$5) continue;
37423
+ if (err instanceof NotFoundException$6) continue;
36649
37424
  throw err;
36650
37425
  }
36651
37426
  }
@@ -36674,7 +37449,7 @@ var S3TablesProvider = class {
36674
37449
  }));
36675
37450
  this.logger.debug(`Successfully deleted S3 Tables Table ${logicalId}`);
36676
37451
  } catch (error) {
36677
- if (error instanceof NotFoundException$5) {
37452
+ if (error instanceof NotFoundException$6) {
36678
37453
  assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
36679
37454
  this.logger.debug(`S3 Tables Table ${physicalId} does not exist, skipping deletion`);
36680
37455
  return;
@@ -36724,7 +37499,7 @@ var S3TablesProvider = class {
36724
37499
  name
36725
37500
  }))).tableARN ?? null;
36726
37501
  } catch (err) {
36727
- if (err instanceof NotFoundException$5) return null;
37502
+ if (err instanceof NotFoundException$6) return null;
36728
37503
  throw err;
36729
37504
  }
36730
37505
  }
@@ -36736,7 +37511,7 @@ var S3TablesProvider = class {
36736
37511
  */
36737
37512
  async readTagsBestEffort(resourceArn) {
36738
37513
  try {
36739
- const tags = (await this.getClient().send(new ListTagsForResourceCommand$19({ resourceArn }))).tags ?? {};
37514
+ const tags = (await this.getClient().send(new ListTagsForResourceCommand$20({ resourceArn }))).tags ?? {};
36740
37515
  const out = [];
36741
37516
  for (const [Key, Value] of Object.entries(tags)) out.push({
36742
37517
  Key,
@@ -36790,7 +37565,7 @@ var S3TablesProvider = class {
36790
37565
  const resourceArn = await this.lookupTableArn(tableBucketARN, namespace, name);
36791
37566
  if (!resourceArn) throw new ProvisioningError(`applyTableTagsDiff: GetTable returned no tableARN for ${physicalId} — table is gone or state is out-of-sync. Refusing to silently drop the tag update (run 'cdkd state orphan ${logicalId}' to clean up if the table was deleted out-of-band).`, resourceType, logicalId, physicalId);
36792
37567
  if (removedKeys.length > 0) try {
36793
- await this.getClient().send(new UntagResourceCommand$18({
37568
+ await this.getClient().send(new UntagResourceCommand$20({
36794
37569
  resourceArn,
36795
37570
  tagKeys: removedKeys
36796
37571
  }));
@@ -36799,7 +37574,7 @@ var S3TablesProvider = class {
36799
37574
  throw new ProvisioningError(`applyTableTagsDiff: UntagResource failed for ${resourceArn} (keys: ${removedKeys.join(", ")}): ${err instanceof Error ? err.message : String(err)}. State has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
36800
37575
  }
36801
37576
  if (Object.keys(upserts).length > 0) try {
36802
- await this.getClient().send(new TagResourceCommand$18({
37577
+ await this.getClient().send(new TagResourceCommand$20({
36803
37578
  resourceArn,
36804
37579
  tags: upserts
36805
37580
  }));
@@ -36831,7 +37606,7 @@ var S3TablesProvider = class {
36831
37606
  if (removedKeys.length === 0 && Object.keys(upserts).length === 0) return;
36832
37607
  const resourceArn = physicalId;
36833
37608
  if (removedKeys.length > 0) try {
36834
- await this.getClient().send(new UntagResourceCommand$18({
37609
+ await this.getClient().send(new UntagResourceCommand$20({
36835
37610
  resourceArn,
36836
37611
  tagKeys: removedKeys
36837
37612
  }));
@@ -36840,7 +37615,7 @@ var S3TablesProvider = class {
36840
37615
  throw new ProvisioningError(`applyTableBucketTagsDiff: UntagResource failed for ${resourceArn} (keys: ${removedKeys.join(", ")}): ${err instanceof Error ? err.message : String(err)}. State has NOT been updated so the next deploy will retry the tag-diff.`, resourceType, logicalId, physicalId, cause);
36841
37616
  }
36842
37617
  if (Object.keys(upserts).length > 0) try {
36843
- await this.getClient().send(new TagResourceCommand$18({
37618
+ await this.getClient().send(new TagResourceCommand$20({
36844
37619
  resourceArn,
36845
37620
  tags: upserts
36846
37621
  }));
@@ -38457,6 +39232,8 @@ function registerAllProviders(registry) {
38457
39232
  registry.register("AWS::ElastiCache::CacheCluster", elasticacheProvider);
38458
39233
  const serviceDiscoveryProvider = new ServiceDiscoveryProvider();
38459
39234
  registry.register("AWS::ServiceDiscovery::PrivateDnsNamespace", serviceDiscoveryProvider);
39235
+ registry.register("AWS::ServiceDiscovery::HttpNamespace", serviceDiscoveryProvider);
39236
+ registry.register("AWS::ServiceDiscovery::PublicDnsNamespace", serviceDiscoveryProvider);
38460
39237
  registry.register("AWS::ServiceDiscovery::Service", serviceDiscoveryProvider);
38461
39238
  registry.register("AWS::BedrockAgentCore::Runtime", new AgentCoreRuntimeProvider());
38462
39239
  const appSyncProvider = new AppSyncProvider();
@@ -38496,6 +39273,7 @@ function registerAllProviders(registry) {
38496
39273
  registry.register("AWS::S3Tables::TableBucket", s3TablesProvider);
38497
39274
  registry.register("AWS::S3Tables::Namespace", s3TablesProvider);
38498
39275
  registry.register("AWS::S3Tables::Table", s3TablesProvider);
39276
+ registry.register("AWS::Budgets::Budget", new BudgetsBudgetProvider());
38499
39277
  registry.register("AWS::CloudFormation::Stack", new NestedStackProvider());
38500
39278
  registry.register("AWS::CloudFormation::WaitConditionHandle", new WaitConditionHandleProvider());
38501
39279
  }
@@ -57761,7 +58539,7 @@ function reorderArgs(argv) {
57761
58539
  async function main() {
57762
58540
  installPipeCloseHandler();
57763
58541
  const program = new Command();
57764
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.240.0");
58542
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.242.0");
57765
58543
  program.addCommand(createBootstrapCommand());
57766
58544
  program.addCommand(createSynthCommand());
57767
58545
  program.addCommand(createListCommand());