@go-to-k/cdkd 0.239.0 → 0.241.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-8lyaaElh.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-BxXIBZoc.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";
@@ -55,15 +55,17 @@ import { CreatePrivateDnsNamespaceCommand, CreateServiceCommand as CreateService
55
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";
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$14, UntagResourceCommand as UntagResourceCommand$14, 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$15, UntagResourceCommand as UntagResourceCommand$15, 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 { CreateLifecyclePolicyCommand, DLMClient, DeleteLifecyclePolicyCommand as DeleteLifecyclePolicyCommand$1, GetLifecyclePoliciesCommand, GetLifecyclePolicyCommand as GetLifecyclePolicyCommand$1, ResourceNotFoundException as ResourceNotFoundException$12, TagResourceCommand as TagResourceCommand$15, UntagResourceCommand as UntagResourceCommand$15, UpdateLifecyclePolicyCommand } from "@aws-sdk/client-dlm";
65
- import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$17, ListVectorBucketsCommand, S3VectorsClient, TagResourceCommand as TagResourceCommand$16, UntagResourceCommand as UntagResourceCommand$16 } from "@aws-sdk/client-s3vectors";
66
- 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$18, NotFoundException as NotFoundException$5, S3TablesClient, TagResourceCommand as TagResourceCommand$17, UntagResourceCommand as UntagResourceCommand$17 } 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$16, UntagResourceCommand as UntagResourceCommand$16, 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$17, UntagResourceCommand as UntagResourceCommand$17, UpdateLifecyclePolicyCommand } from "@aws-sdk/client-dlm";
67
+ import { CreateVectorBucketCommand, DeleteIndexCommand, DeleteVectorBucketCommand, GetVectorBucketCommand, ListIndexesCommand, ListTagsForResourceCommand as ListTagsForResourceCommand$19, ListVectorBucketsCommand, S3VectorsClient, TagResourceCommand as TagResourceCommand$18, UntagResourceCommand as UntagResourceCommand$18 } 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$19, UntagResourceCommand as UntagResourceCommand$19 } from "@aws-sdk/client-s3tables";
67
69
  import { Document, Pair, Scalar, YAMLMap, YAMLSeq, parse as parse$1, stringify } from "yaml";
68
70
  import { createLocalStartAgentCoreCommand, createLocalStartCloudFrontCommand, createLocalStateProvider, getEmbedConfig, isCfnFlagPresent, listTargets, rejectExplicitCfnStackWithMultipleStacks, resolveCfnFallbackRegion, setEmbedConfig, substituteAgainstState, substituteAgainstStateAsync, substituteEnvVarsFromState, substituteEnvVarsFromStateAsync } from "cdk-local";
69
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";
@@ -1886,7 +1888,7 @@ const FLUSH_INTERVAL_MS = 2e3;
1886
1888
  const FLUSH_EVENT_THRESHOLD = 50;
1887
1889
  /** Build-time cdkd version, with a dev fallback for non-built contexts. */
1888
1890
  function getCdkdVersion() {
1889
- return "0.239.0";
1891
+ return "0.241.0";
1890
1892
  }
1891
1893
  /**
1892
1894
  * Generate a time-sortable unique run id, e.g.
@@ -31579,6 +31581,492 @@ var KMSProvider = class {
31579
31581
  }
31580
31582
  };
31581
31583
 
31584
+ //#endregion
31585
+ //#region src/provisioning/providers/budgets-budget-provider.ts
31586
+ /**
31587
+ * SDK Provider for AWS::Budgets::Budget (issue #1041).
31588
+ *
31589
+ * The type is `ProvisioningType: NON_PROVISIONABLE`, so the Cloud Control
31590
+ * fallback cannot handle it — without this provider cdkd's pre-flight
31591
+ * rejects the type outright.
31592
+ *
31593
+ * **Global endpoint / region semantics**: the Budgets API is a global,
31594
+ * per-account service served from `us-east-1`. The `@aws-sdk/client-budgets`
31595
+ * endpoint ruleset resolves EVERY aws-partition region to the single global
31596
+ * endpoint (`budgets.amazonaws.com`, SigV4 scope `us-east-1`), so the client
31597
+ * below is deliberately created with the deploy region like every other
31598
+ * provider — the SDK itself pins the endpoint. This also keeps
31599
+ * `client.config.region()` equal to the deploy region, so the standard
31600
+ * `assertRegionMatch` idempotent-delete guard behaves exactly like it does
31601
+ * for regional services: a destroy run with a mismatched `--region` still
31602
+ * refuses to trust a NotFound. (For a global namespace a NotFound would
31603
+ * actually be trustworthy from any region, but keeping the guard uniform is
31604
+ * strictly safer and costs nothing.)
31605
+ *
31606
+ * **AccountId**: every Budgets API call requires the account id. It is
31607
+ * resolved once per provider instance via STS `GetCallerIdentity` (shared
31608
+ * `AwsClients.sts`) and cached as a single-flight promise for the deploy
31609
+ * lifetime; failed resolutions are not cached so a transient STS throttle
31610
+ * cannot poison the rest of the run (mirrors
31611
+ * `src/utils/expected-bucket-owner.ts`).
31612
+ *
31613
+ * **Physical id**: the budget NAME. `Budget.BudgetName` is createOnly —
31614
+ * a rename is classified as replacement by the `AWS::Budgets::Budget`
31615
+ * conditional rule in `src/analyzer/replacement-rules.ts`.
31616
+ *
31617
+ * **NotificationsWithSubscribers**: CloudFormation treats the whole property
31618
+ * as createOnly (replacement on any change). cdkd does better — `update()`
31619
+ * reconciles in place via CreateNotification / DeleteNotification /
31620
+ * CreateSubscriber / DeleteSubscriber, so alert history and the budget
31621
+ * itself survive a notification edit.
31622
+ */
31623
+ var BudgetsBudgetProvider = class {
31624
+ client;
31625
+ providerRegion = process.env["AWS_REGION"];
31626
+ logger = getLogger().child("BudgetsBudgetProvider");
31627
+ accountIdPromise;
31628
+ handledProperties = new Map([["AWS::Budgets::Budget", new Set([
31629
+ "Budget",
31630
+ "NotificationsWithSubscribers",
31631
+ "ResourceTags"
31632
+ ])]]);
31633
+ getClient() {
31634
+ if (!this.client) this.client = new BudgetsClient(this.providerRegion ? { region: this.providerRegion } : {});
31635
+ return this.client;
31636
+ }
31637
+ /**
31638
+ * Resolve the caller's AWS account id (required on every Budgets call).
31639
+ * Cached per provider instance as a single-flight promise; a failed
31640
+ * resolution is evicted so the next call retries instead of replaying a
31641
+ * transient error for the rest of the deploy.
31642
+ */
31643
+ resolveAccountId() {
31644
+ if (!this.accountIdPromise) this.accountIdPromise = (async () => {
31645
+ try {
31646
+ const identity = await getAwsClients().sts.send(new GetCallerIdentityCommand({}));
31647
+ if (!identity.Account) throw new Error("STS GetCallerIdentity returned no Account");
31648
+ return identity.Account;
31649
+ } catch (error) {
31650
+ this.accountIdPromise = void 0;
31651
+ throw error;
31652
+ }
31653
+ })();
31654
+ return this.accountIdPromise;
31655
+ }
31656
+ /**
31657
+ * Budget ARN for the tagging APIs (`ListTagsForResource` / `TagResource` /
31658
+ * `UntagResource`). Budgets ARNs carry no region component. The `aws`
31659
+ * partition is assumed — consistent with other providers that construct
31660
+ * ARNs; non-`aws` partitions are not supported by cdkd today.
31661
+ */
31662
+ budgetArn(accountId, budgetName) {
31663
+ return `arn:aws:budgets::${accountId}:budget/${budgetName}`;
31664
+ }
31665
+ /**
31666
+ * Convert a CFn `Spend` shape to the SDK shape. CFn templates carry
31667
+ * `Amount` as a number (CDK synthesizes `budgetLimit: { amount: 10 }` to a
31668
+ * numeric JSON value); the SDK wants a numeric string.
31669
+ */
31670
+ toSdkSpend(raw) {
31671
+ if (raw === void 0 || raw === null || typeof raw !== "object") return void 0;
31672
+ const spend = raw;
31673
+ const amount = spend["Amount"];
31674
+ return {
31675
+ Amount: typeof amount === "string" ? amount : typeof amount === "number" ? String(amount) : void 0,
31676
+ Unit: spend["Unit"]
31677
+ };
31678
+ }
31679
+ /**
31680
+ * Convert a CFn `TimePeriod` `Start` / `End` value to a `Date`. CFn accepts
31681
+ * a UTC date string (`2026-07-01T00:00:00Z`) or an epoch timestamp in
31682
+ * seconds (possibly as a numeric string).
31683
+ */
31684
+ toSdkDate(raw, field, logicalId, resourceType) {
31685
+ let date;
31686
+ if (typeof raw === "number") date = new Date(raw < 0xe8d4a51000 ? raw * 1e3 : raw);
31687
+ else if (typeof raw === "string" && /^\d+$/.test(raw)) {
31688
+ const num = Number(raw);
31689
+ date = new Date(num < 0xe8d4a51000 ? num * 1e3 : num);
31690
+ } else if (typeof raw === "string") date = new Date(raw);
31691
+ else throw new ProvisioningError(`Invalid TimePeriod.${field} for budget ${logicalId}: expected a date string or epoch timestamp, got ${JSON.stringify(raw)}`, resourceType, logicalId);
31692
+ if (Number.isNaN(date.getTime())) throw new ProvisioningError(`Invalid TimePeriod.${field} for budget ${logicalId}: ${JSON.stringify(raw)} is not a parseable date`, resourceType, logicalId);
31693
+ return date;
31694
+ }
31695
+ /**
31696
+ * Map the CFn `Budget` (BudgetData) property to the SDK `Budget` shape.
31697
+ * The two are PascalCase-identical except: `BudgetLimit` /
31698
+ * `PlannedBudgetLimits` amounts are numeric strings on the wire, and
31699
+ * `TimePeriod.Start` / `.End` are `Date`s. `FilterExpression` / `Metrics` /
31700
+ * `CostFilters` / `CostTypes` / `AutoAdjustData` pass through verbatim.
31701
+ */
31702
+ toSdkBudget(raw, budgetName, logicalId, resourceType) {
31703
+ if (raw === void 0 || raw === null || typeof raw !== "object") throw new ProvisioningError(`The Budget property is required for ${logicalId}`, resourceType, logicalId);
31704
+ const src = raw;
31705
+ const budget = {
31706
+ ...src,
31707
+ BudgetName: budgetName
31708
+ };
31709
+ if (src["BudgetLimit"] !== void 0) budget["BudgetLimit"] = this.toSdkSpend(src["BudgetLimit"]);
31710
+ if (src["PlannedBudgetLimits"] !== void 0 && typeof src["PlannedBudgetLimits"] === "object") {
31711
+ const limits = {};
31712
+ for (const [key, value] of Object.entries(src["PlannedBudgetLimits"])) limits[key] = this.toSdkSpend(value);
31713
+ budget["PlannedBudgetLimits"] = limits;
31714
+ }
31715
+ if (src["TimePeriod"] !== void 0 && typeof src["TimePeriod"] === "object") {
31716
+ const rawPeriod = src["TimePeriod"];
31717
+ const period = {};
31718
+ if (rawPeriod["Start"] !== void 0) period.Start = this.toSdkDate(rawPeriod["Start"], "Start", logicalId, resourceType);
31719
+ if (rawPeriod["End"] !== void 0) period.End = this.toSdkDate(rawPeriod["End"], "End", logicalId, resourceType);
31720
+ budget["TimePeriod"] = period;
31721
+ }
31722
+ return budget;
31723
+ }
31724
+ /** Normalize a CFn notification block to the SDK `Notification` shape. */
31725
+ toSdkNotification(raw) {
31726
+ return {
31727
+ NotificationType: raw["NotificationType"],
31728
+ ComparisonOperator: raw["ComparisonOperator"],
31729
+ Threshold: raw["Threshold"] !== void 0 ? Number(raw["Threshold"]) : void 0,
31730
+ ...raw["ThresholdType"] !== void 0 && { ThresholdType: raw["ThresholdType"] }
31731
+ };
31732
+ }
31733
+ /** Normalize a CFn subscriber block to the SDK `Subscriber` shape. */
31734
+ toSdkSubscriber(raw) {
31735
+ return {
31736
+ SubscriptionType: raw["SubscriptionType"],
31737
+ Address: raw["Address"]
31738
+ };
31739
+ }
31740
+ /**
31741
+ * Parse the CFn `NotificationsWithSubscribers` property into SDK shape.
31742
+ * Tolerates absent / non-array values (returns `[]`).
31743
+ */
31744
+ toSdkNotificationsWithSubscribers(raw) {
31745
+ if (!Array.isArray(raw)) return [];
31746
+ const out = [];
31747
+ for (const item of raw) {
31748
+ if (item === null || typeof item !== "object") continue;
31749
+ const entry = item;
31750
+ const notification = entry["Notification"];
31751
+ const subscribers = entry["Subscribers"];
31752
+ out.push({
31753
+ Notification: notification && typeof notification === "object" ? this.toSdkNotification(notification) : void 0,
31754
+ Subscribers: Array.isArray(subscribers) ? subscribers.filter((s) => s !== null && typeof s === "object").map((s) => this.toSdkSubscriber(s)) : void 0
31755
+ });
31756
+ }
31757
+ return out;
31758
+ }
31759
+ /**
31760
+ * Identity key for a notification. The Budgets API addresses notifications
31761
+ * by their full value (there is no notification id), so the reconciler
31762
+ * treats a change to any of these fields as delete-old + create-new.
31763
+ * `ThresholdType` defaults to `PERCENTAGE` service-side — normalize the
31764
+ * absent case so an explicit `PERCENTAGE` and an omitted one compare equal.
31765
+ */
31766
+ notificationKey(n) {
31767
+ return JSON.stringify([
31768
+ n.NotificationType,
31769
+ n.ComparisonOperator,
31770
+ n.Threshold,
31771
+ n.ThresholdType ?? "PERCENTAGE"
31772
+ ]);
31773
+ }
31774
+ /** Identity key for a subscriber. */
31775
+ subscriberKey(s) {
31776
+ return JSON.stringify([s.SubscriptionType, s.Address]);
31777
+ }
31778
+ /** Normalize the CFn `ResourceTags` property (`{Key,Value}[]`). */
31779
+ toSdkResourceTags(raw) {
31780
+ if (!Array.isArray(raw)) return [];
31781
+ const out = [];
31782
+ for (const item of raw) {
31783
+ if (item === null || typeof item !== "object") continue;
31784
+ const tag = item;
31785
+ if (typeof tag["Key"] !== "string") continue;
31786
+ const value = tag["Value"];
31787
+ out.push({
31788
+ Key: tag["Key"],
31789
+ Value: typeof value === "string" ? value : typeof value === "number" || typeof value === "boolean" ? String(value) : ""
31790
+ });
31791
+ }
31792
+ return out;
31793
+ }
31794
+ /**
31795
+ * Create a budget via `CreateBudget` (a single call carries the budget,
31796
+ * its notifications with subscribers, and resource tags — no post-create
31797
+ * wiring to clean up on partial failure).
31798
+ */
31799
+ async create(logicalId, resourceType, properties) {
31800
+ this.logger.debug(`Creating budget ${logicalId}`);
31801
+ const rawName = (properties["Budget"] ?? {})["BudgetName"];
31802
+ const name = typeof rawName === "string" && rawName.length > 0 ? rawName : generateResourceName(logicalId, {
31803
+ maxLength: 100,
31804
+ allowedPattern: /[^a-zA-Z0-9\-_.]/g
31805
+ });
31806
+ try {
31807
+ const accountId = await this.resolveAccountId();
31808
+ const notifications = this.toSdkNotificationsWithSubscribers(properties["NotificationsWithSubscribers"]);
31809
+ const resourceTags = this.toSdkResourceTags(properties["ResourceTags"]);
31810
+ await this.getClient().send(new CreateBudgetCommand({
31811
+ AccountId: accountId,
31812
+ Budget: this.toSdkBudget(properties["Budget"], name, logicalId, resourceType),
31813
+ ...notifications.length > 0 && { NotificationsWithSubscribers: notifications },
31814
+ ...resourceTags.length > 0 && { ResourceTags: resourceTags }
31815
+ }));
31816
+ this.logger.debug(`Successfully created budget ${logicalId}: ${name}`);
31817
+ return {
31818
+ physicalId: name,
31819
+ attributes: { Arn: this.budgetArn(accountId, name) }
31820
+ };
31821
+ } catch (error) {
31822
+ if (error instanceof ProvisioningError) throw error;
31823
+ const cause = error instanceof Error ? error : void 0;
31824
+ throw new ProvisioningError(`Failed to create budget ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, void 0, cause);
31825
+ }
31826
+ }
31827
+ /**
31828
+ * Update a budget: `UpdateBudget` for the budget definition, then
31829
+ * reconcile `NotificationsWithSubscribers` in place (CloudFormation would
31830
+ * replace the whole budget instead) and diff `ResourceTags`.
31831
+ */
31832
+ async update(logicalId, physicalId, resourceType, properties, previousProperties) {
31833
+ this.logger.debug(`Updating budget ${logicalId}: ${physicalId}`);
31834
+ try {
31835
+ const accountId = await this.resolveAccountId();
31836
+ await this.getClient().send(new UpdateBudgetCommand({
31837
+ AccountId: accountId,
31838
+ NewBudget: this.toSdkBudget(properties["Budget"], physicalId, logicalId, resourceType)
31839
+ }));
31840
+ await this.reconcileNotifications(accountId, physicalId, this.toSdkNotificationsWithSubscribers(previousProperties["NotificationsWithSubscribers"]), this.toSdkNotificationsWithSubscribers(properties["NotificationsWithSubscribers"]));
31841
+ await this.reconcileResourceTags(accountId, physicalId, this.toSdkResourceTags(previousProperties["ResourceTags"]), this.toSdkResourceTags(properties["ResourceTags"]));
31842
+ this.logger.debug(`Successfully updated budget ${logicalId}`);
31843
+ return {
31844
+ physicalId,
31845
+ wasReplaced: false,
31846
+ attributes: { Arn: this.budgetArn(accountId, physicalId) }
31847
+ };
31848
+ } catch (error) {
31849
+ if (error instanceof ProvisioningError) throw error;
31850
+ const cause = error instanceof Error ? error : void 0;
31851
+ throw new ProvisioningError(`Failed to update budget ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
31852
+ }
31853
+ }
31854
+ /**
31855
+ * Send a reconciler DELETE call, treating `NotFoundException` as success.
31856
+ * The reconciler must be idempotent: after a partial failure the deploy
31857
+ * engine retries the update forward (re-deleting an already-deleted
31858
+ * notification/subscriber) or rolls it back with the reversed diff
31859
+ * (deleting a notification the forward pass never created) — both land
31860
+ * here as NotFound and must not fail the recovery.
31861
+ */
31862
+ async sendDeleteIdempotent(command, what) {
31863
+ try {
31864
+ await this.getClient().send(command);
31865
+ } catch (error) {
31866
+ if (error instanceof NotFoundException$5) {
31867
+ this.logger.debug(`${what} already absent, skipping delete`);
31868
+ return;
31869
+ }
31870
+ throw error;
31871
+ }
31872
+ }
31873
+ /**
31874
+ * Send a reconciler CREATE call, treating `DuplicateRecordException` as
31875
+ * success — the retry/rollback twin of {@link sendDeleteIdempotent} for
31876
+ * re-creating a notification/subscriber a previous partial pass already
31877
+ * created.
31878
+ */
31879
+ async sendCreateIdempotent(command, what) {
31880
+ try {
31881
+ await this.getClient().send(command);
31882
+ } catch (error) {
31883
+ if (error instanceof DuplicateRecordException) {
31884
+ this.logger.debug(`${what} already exists, skipping create`);
31885
+ return;
31886
+ }
31887
+ throw error;
31888
+ }
31889
+ }
31890
+ /**
31891
+ * Reconcile the notification set: delete removed notifications first
31892
+ * (frees the 10-notifications-per-budget cap before additions), create
31893
+ * added ones, then diff subscribers on retained notifications. Every
31894
+ * step is idempotent (NotFound on delete / DuplicateRecord on create are
31895
+ * success) so a partial failure can be retried forward or rolled back.
31896
+ */
31897
+ async reconcileNotifications(accountId, budgetName, oldList, newList) {
31898
+ const buildKeyed = (list, side) => {
31899
+ const byKey = /* @__PURE__ */ new Map();
31900
+ for (const nws of list) {
31901
+ if (!nws.Notification) continue;
31902
+ const key = this.notificationKey(nws.Notification);
31903
+ if (byKey.has(key)) this.logger.warn(`Duplicate notification key ${key} in ${side} NotificationsWithSubscribers for budget ${budgetName}; the last entry's subscribers win`);
31904
+ byKey.set(key, nws);
31905
+ }
31906
+ return byKey;
31907
+ };
31908
+ const oldByKey = buildKeyed(oldList, "previous");
31909
+ const newByKey = buildKeyed(newList, "desired");
31910
+ for (const [key, nws] of oldByKey) {
31911
+ if (newByKey.has(key)) continue;
31912
+ await this.sendDeleteIdempotent(new DeleteNotificationCommand({
31913
+ AccountId: accountId,
31914
+ BudgetName: budgetName,
31915
+ Notification: nws.Notification
31916
+ }), `Notification ${key} on budget ${budgetName}`);
31917
+ this.logger.debug(`Deleted notification ${key} from budget ${budgetName}`);
31918
+ }
31919
+ for (const [key, nws] of newByKey) {
31920
+ if (oldByKey.has(key)) continue;
31921
+ await this.sendCreateIdempotent(new CreateNotificationCommand({
31922
+ AccountId: accountId,
31923
+ BudgetName: budgetName,
31924
+ Notification: nws.Notification,
31925
+ Subscribers: nws.Subscribers
31926
+ }), `Notification ${key} on budget ${budgetName}`);
31927
+ this.logger.debug(`Created notification ${key} on budget ${budgetName}`);
31928
+ }
31929
+ for (const [key, newNws] of newByKey) {
31930
+ const oldNws = oldByKey.get(key);
31931
+ if (!oldNws) continue;
31932
+ const oldSubs = /* @__PURE__ */ new Map();
31933
+ for (const s of oldNws.Subscribers ?? []) oldSubs.set(this.subscriberKey(s), s);
31934
+ const newSubs = /* @__PURE__ */ new Map();
31935
+ for (const s of newNws.Subscribers ?? []) newSubs.set(this.subscriberKey(s), s);
31936
+ for (const [subKey, subscriber] of newSubs) {
31937
+ if (oldSubs.has(subKey)) continue;
31938
+ await this.sendCreateIdempotent(new CreateSubscriberCommand({
31939
+ AccountId: accountId,
31940
+ BudgetName: budgetName,
31941
+ Notification: newNws.Notification,
31942
+ Subscriber: subscriber
31943
+ }), `Subscriber ${subKey} on notification ${key}`);
31944
+ this.logger.debug(`Created subscriber ${subKey} on notification ${key}`);
31945
+ }
31946
+ for (const [subKey, subscriber] of oldSubs) {
31947
+ if (newSubs.has(subKey)) continue;
31948
+ await this.sendDeleteIdempotent(new DeleteSubscriberCommand({
31949
+ AccountId: accountId,
31950
+ BudgetName: budgetName,
31951
+ Notification: newNws.Notification,
31952
+ Subscriber: subscriber
31953
+ }), `Subscriber ${subKey} on notification ${key}`);
31954
+ this.logger.debug(`Deleted subscriber ${subKey} from notification ${key}`);
31955
+ }
31956
+ }
31957
+ }
31958
+ /** Diff `ResourceTags` via `UntagResource` (removed keys) + `TagResource` (upsert). */
31959
+ async reconcileResourceTags(accountId, budgetName, oldTags, newTags) {
31960
+ const sortedJson = (tags) => JSON.stringify([...tags].sort((a, b) => (a.Key ?? "").localeCompare(b.Key ?? "")));
31961
+ if (sortedJson(oldTags) === sortedJson(newTags)) return;
31962
+ const arn = this.budgetArn(accountId, budgetName);
31963
+ const newKeys = new Set(newTags.map((t) => t.Key));
31964
+ const removedKeys = oldTags.map((t) => t.Key).filter((k) => {
31965
+ return typeof k === "string" && !newKeys.has(k);
31966
+ });
31967
+ if (removedKeys.length > 0) await this.getClient().send(new UntagResourceCommand$14({
31968
+ ResourceARN: arn,
31969
+ ResourceTagKeys: removedKeys
31970
+ }));
31971
+ if (newTags.length > 0) await this.getClient().send(new TagResourceCommand$14({
31972
+ ResourceARN: arn,
31973
+ ResourceTags: newTags
31974
+ }));
31975
+ this.logger.debug(`Updated resource tags for budget ${budgetName}`);
31976
+ }
31977
+ /**
31978
+ * Delete a budget (`DeleteBudget` also deletes all of its notifications
31979
+ * and subscribers). NotFound is idempotent success — after the standard
31980
+ * region assertion (see the class doc for why the guard stays uniform
31981
+ * even though the Budgets namespace is global).
31982
+ */
31983
+ async delete(logicalId, physicalId, resourceType, _properties, context) {
31984
+ this.logger.debug(`Deleting budget ${logicalId}: ${physicalId}`);
31985
+ try {
31986
+ const accountId = await this.resolveAccountId();
31987
+ await this.getClient().send(new DeleteBudgetCommand({
31988
+ AccountId: accountId,
31989
+ BudgetName: physicalId
31990
+ }));
31991
+ this.logger.debug(`Successfully deleted budget ${logicalId}`);
31992
+ } catch (error) {
31993
+ if (error instanceof NotFoundException$5) {
31994
+ assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
31995
+ this.logger.debug(`Budget ${physicalId} does not exist, skipping deletion`);
31996
+ return;
31997
+ }
31998
+ const cause = error instanceof Error ? error : void 0;
31999
+ throw new ProvisioningError(`Failed to delete budget ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
32000
+ }
32001
+ }
32002
+ /**
32003
+ * `Fn::GetAtt` support. CloudFormation documents no attributes for
32004
+ * `AWS::Budgets::Budget`; `Arn` is served as a cdkd convenience (computed
32005
+ * — Budgets ARNs are `arn:aws:budgets::{account}:budget/{name}`, verified
32006
+ * to exist via `DescribeBudget` first).
32007
+ */
32008
+ async getAttribute(physicalId, resourceType, attributeName) {
32009
+ if (attributeName !== "Arn") throw new ProvisioningError(`Unknown attribute ${attributeName} for ${resourceType}`, resourceType, physicalId);
32010
+ try {
32011
+ const accountId = await this.resolveAccountId();
32012
+ await this.getClient().send(new DescribeBudgetCommand({
32013
+ AccountId: accountId,
32014
+ BudgetName: physicalId
32015
+ }));
32016
+ return this.budgetArn(accountId, physicalId);
32017
+ } catch (error) {
32018
+ const cause = error instanceof Error ? error : void 0;
32019
+ throw new ProvisioningError(`Failed to resolve Arn for budget ${physicalId}: ${cause?.message ?? String(error)}`, resourceType, physicalId, physicalId, cause);
32020
+ }
32021
+ }
32022
+ /**
32023
+ * Adopt an existing budget into cdkd state.
32024
+ *
32025
+ * Lookup order:
32026
+ * 1. `--resource` override or `Properties.Budget.BudgetName` → verify via
32027
+ * `DescribeBudget`.
32028
+ * 2. `aws:cdk:path` tag match: walk `DescribeBudgets` and check each
32029
+ * budget's tags via `ListTagsForResource` (budget ARNs are
32030
+ * region-free, so the lookup works from any deploy region).
32031
+ */
32032
+ async import(input) {
32033
+ const rawBudget = input.properties["Budget"] ?? {};
32034
+ const explicit = input.knownPhysicalId ?? (typeof rawBudget["BudgetName"] === "string" && rawBudget["BudgetName"].length > 0 ? rawBudget["BudgetName"] : void 0);
32035
+ const accountId = await this.resolveAccountId();
32036
+ const client = this.getClient();
32037
+ if (explicit) try {
32038
+ await client.send(new DescribeBudgetCommand({
32039
+ AccountId: accountId,
32040
+ BudgetName: explicit
32041
+ }));
32042
+ return {
32043
+ physicalId: explicit,
32044
+ attributes: { Arn: this.budgetArn(accountId, explicit) }
32045
+ };
32046
+ } catch (error) {
32047
+ if (error instanceof NotFoundException$5) return null;
32048
+ throw error;
32049
+ }
32050
+ if (!input.cdkPath) return null;
32051
+ let nextToken;
32052
+ do {
32053
+ const list = await client.send(new DescribeBudgetsCommand({
32054
+ AccountId: accountId,
32055
+ ...nextToken && { NextToken: nextToken }
32056
+ }));
32057
+ for (const budget of list.Budgets ?? []) {
32058
+ if (!budget.BudgetName) continue;
32059
+ if (matchesCdkPath((await client.send(new ListTagsForResourceCommand$16({ ResourceARN: this.budgetArn(accountId, budget.BudgetName) }))).ResourceTags, input.cdkPath)) return {
32060
+ physicalId: budget.BudgetName,
32061
+ attributes: { Arn: this.budgetArn(accountId, budget.BudgetName) }
32062
+ };
32063
+ }
32064
+ nextToken = list.NextToken;
32065
+ } while (nextToken);
32066
+ return null;
32067
+ }
32068
+ };
32069
+
31582
32070
  //#endregion
31583
32071
  //#region src/provisioning/providers/kinesis-provider.ts
31584
32072
  /**
@@ -32139,7 +32627,7 @@ var KinesisStreamConsumerProvider = class {
32139
32627
  if (desc.ConsumerName !== void 0) result["ConsumerName"] = desc.ConsumerName;
32140
32628
  if (desc.StreamARN !== void 0) result["StreamARN"] = desc.StreamARN;
32141
32629
  try {
32142
- result["Tags"] = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsForResourceCommand$16({ ResourceARN: physicalId }))).Tags);
32630
+ result["Tags"] = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsForResourceCommand$17({ ResourceARN: physicalId }))).Tags);
32143
32631
  } catch (err) {
32144
32632
  if (err instanceof ResourceNotFoundException$8) return void 0;
32145
32633
  this.logger.debug(`ListTagsForResource(${physicalId}) failed: ${err instanceof Error ? err.message : String(err)}`);
@@ -32163,14 +32651,14 @@ var KinesisStreamConsumerProvider = class {
32163
32651
  const tagsToRemove = [];
32164
32652
  for (const k of Object.keys(oldMap)) if (!(k in newMap)) tagsToRemove.push(k);
32165
32653
  if (tagsToRemove.length > 0) {
32166
- await this.getClient().send(new UntagResourceCommand$14({
32654
+ await this.getClient().send(new UntagResourceCommand$15({
32167
32655
  ResourceARN: consumerArn,
32168
32656
  TagKeys: tagsToRemove
32169
32657
  }));
32170
32658
  this.logger.debug(`Removed ${tagsToRemove.length} tag(s) from Kinesis stream consumer ${consumerArn}`);
32171
32659
  }
32172
32660
  if (Object.keys(tagsToAdd).length > 0) {
32173
- await this.getClient().send(new TagResourceCommand$14({
32661
+ await this.getClient().send(new TagResourceCommand$15({
32174
32662
  ResourceARN: consumerArn,
32175
32663
  Tags: tagsToAdd
32176
32664
  }));
@@ -35163,6 +35651,293 @@ var CodeBuildProvider = class {
35163
35651
  }
35164
35652
  };
35165
35653
 
35654
+ //#endregion
35655
+ //#region src/provisioning/providers/codecommit-repository-provider.ts
35656
+ /**
35657
+ * Convert the CFn `Tags` list shape to CodeCommit's `Record<string, string>`
35658
+ * map. Entries without a string `Key` are skipped; non-string values are
35659
+ * stringified (post-intrinsic-resolution values can be numbers/booleans).
35660
+ * Returns `undefined` for an absent/empty list so callers can omit the field.
35661
+ */
35662
+ function toSdkTagMap(tags) {
35663
+ if (!tags || tags.length === 0) return void 0;
35664
+ const out = {};
35665
+ for (const tag of tags) {
35666
+ if (typeof tag?.Key !== "string" || tag.Key.length === 0) continue;
35667
+ const value = tag.Value;
35668
+ out[tag.Key] = typeof value === "string" ? value : typeof value === "number" || typeof value === "boolean" ? String(value) : "";
35669
+ }
35670
+ return Object.keys(out).length > 0 ? out : void 0;
35671
+ }
35672
+ /** Order-independent equality for two SDK tag maps. */
35673
+ function tagMapsEqual(a, b) {
35674
+ const aKeys = Object.keys(a);
35675
+ if (aKeys.length !== Object.keys(b).length) return false;
35676
+ return aKeys.every((k) => b[k] === a[k]);
35677
+ }
35678
+ /**
35679
+ * AWS CodeCommit Repository Provider
35680
+ *
35681
+ * Implements resource provisioning for AWS::CodeCommit::Repository using the
35682
+ * CodeCommit SDK. The type is `ProvisioningType: NON_PROVISIONABLE`, so the
35683
+ * Cloud Control fallback cannot handle it — without this SDK provider cdkd's
35684
+ * pre-flight rejects the type outright (issue #1045). CodeCommit returned to
35685
+ * full General Availability on 2025-11-24, so the service is fully usable for
35686
+ * new sign-ups again.
35687
+ *
35688
+ * Physical id: the repository NAME (every CodeCommit API is name-based;
35689
+ * there is no lookup-by-id API). CloudFormation's `Ref` returns the
35690
+ * repository ID (a GUID), so `create()` stores `RepositoryId` in attributes
35691
+ * and the intrinsic resolver's `cfnRefValueFromPhysicalId` recovers it via
35692
+ * `stateLookup` for CFn `Ref` parity.
35693
+ */
35694
+ var CodeCommitRepositoryProvider = class {
35695
+ client;
35696
+ providerRegion = process.env["AWS_REGION"];
35697
+ logger = getLogger().child("CodeCommitRepositoryProvider");
35698
+ handledProperties = new Map([["AWS::CodeCommit::Repository", new Set([
35699
+ "RepositoryName",
35700
+ "RepositoryDescription",
35701
+ "KmsKeyId",
35702
+ "Tags"
35703
+ ])]]);
35704
+ unhandledByDesign = new Map([["AWS::CodeCommit::Repository", new Map([["Code", "CFn-only seed-content orchestration (S3 zip unpacked into an initial commit on a chosen branch); not wired in v1 — pre-flight rejects templates carrying it so nothing is silently dropped; a follow-up could implement it via CreateCommit/PutFile"], ["Triggers", "repository trigger management not wired in v1 — pre-flight rejects templates carrying it so nothing is silently dropped; a follow-up could implement it via PutRepositoryTriggers"]])]]);
35705
+ getClient() {
35706
+ if (!this.client) this.client = new CodeCommitClient(this.providerRegion ? { region: this.providerRegion } : {});
35707
+ return this.client;
35708
+ }
35709
+ /**
35710
+ * Build the `Fn::GetAtt` attribute map from a `RepositoryMetadata`
35711
+ * response. `RepositoryId` is additionally stored so the intrinsic
35712
+ * resolver can recover CFn's `Ref` value (the repository ID) from state.
35713
+ */
35714
+ toAttributes(metadata) {
35715
+ return {
35716
+ Arn: metadata?.Arn ?? "",
35717
+ CloneUrlHttp: metadata?.cloneUrlHttp ?? "",
35718
+ CloneUrlSsh: metadata?.cloneUrlSsh ?? "",
35719
+ Name: metadata?.repositoryName ?? "",
35720
+ KmsKeyId: metadata?.kmsKeyId ?? "",
35721
+ RepositoryId: metadata?.repositoryId ?? ""
35722
+ };
35723
+ }
35724
+ /**
35725
+ * Create a CodeCommit Repository
35726
+ */
35727
+ async create(logicalId, resourceType, properties) {
35728
+ this.logger.debug(`Creating CodeCommit Repository ${logicalId}`);
35729
+ const repositoryName = properties["RepositoryName"] || generateResourceName(logicalId, { maxLength: 100 });
35730
+ try {
35731
+ const tags = toSdkTagMap(properties["Tags"]);
35732
+ const description = properties["RepositoryDescription"];
35733
+ const kmsKeyId = properties["KmsKeyId"];
35734
+ const metadata = (await this.getClient().send(new CreateRepositoryCommand$1({
35735
+ repositoryName,
35736
+ ...description !== void 0 ? { repositoryDescription: description } : {},
35737
+ ...kmsKeyId !== void 0 ? { kmsKeyId } : {},
35738
+ ...tags ? { tags } : {}
35739
+ }))).repositoryMetadata;
35740
+ if (!metadata?.repositoryName) throw new Error("CreateRepository did not return repository metadata");
35741
+ this.logger.debug(`Successfully created CodeCommit Repository ${logicalId}: ${metadata.repositoryName}`);
35742
+ return {
35743
+ physicalId: metadata.repositoryName,
35744
+ attributes: this.toAttributes(metadata)
35745
+ };
35746
+ } catch (error) {
35747
+ const cause = error instanceof Error ? error : void 0;
35748
+ throw new ProvisioningError(`Failed to create CodeCommit Repository ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, repositoryName, cause);
35749
+ }
35750
+ }
35751
+ /**
35752
+ * Update a CodeCommit Repository
35753
+ *
35754
+ * Mutable properties: RepositoryName (UpdateRepositoryName — CFn's docs
35755
+ * mark the property "Update requires: No interruption" and the registry
35756
+ * schema's createOnlyProperties is empty, so CFn parity is an IN-PLACE
35757
+ * rename that preserves the repository's git history; the repository ID —
35758
+ * CFn's `Ref` value — survives the rename), RepositoryDescription
35759
+ * (UpdateRepositoryDescription), KmsKeyId (UpdateRepositoryEncryptionKey),
35760
+ * Tags (TagResource / UntagResource — full tag removal handled explicitly,
35761
+ * see the ECR Tags regression class in issue #981).
35762
+ *
35763
+ * A rename returns the NEW repository name as `physicalId` with
35764
+ * `wasReplaced: false`; the deploy engine persists the returned physical
35765
+ * id into state unconditionally.
35766
+ */
35767
+ async update(logicalId, physicalId, _resourceType, properties, previousProperties) {
35768
+ this.logger.debug(`Updating CodeCommit Repository ${logicalId} (${physicalId})`);
35769
+ let currentName = physicalId;
35770
+ try {
35771
+ const newName = properties["RepositoryName"];
35772
+ if (newName && newName !== physicalId) {
35773
+ try {
35774
+ await this.getClient().send(new UpdateRepositoryNameCommand({
35775
+ oldName: physicalId,
35776
+ newName
35777
+ }));
35778
+ } catch (err) {
35779
+ if (!(err instanceof RepositoryDoesNotExistException)) throw err;
35780
+ await this.getRepositoryMetadata(newName);
35781
+ this.logger.debug(`Rename ${physicalId} -> ${newName} already applied by a previous attempt`);
35782
+ }
35783
+ currentName = newName;
35784
+ this.logger.debug(`Renamed CodeCommit Repository ${physicalId} -> ${newName}`);
35785
+ }
35786
+ const newDescription = properties["RepositoryDescription"];
35787
+ if (newDescription !== previousProperties["RepositoryDescription"]) {
35788
+ await this.getClient().send(new UpdateRepositoryDescriptionCommand({
35789
+ repositoryName: currentName,
35790
+ repositoryDescription: newDescription ?? ""
35791
+ }));
35792
+ this.logger.debug(`Updated description for ${currentName}`);
35793
+ }
35794
+ const newKmsKeyId = properties["KmsKeyId"];
35795
+ if (newKmsKeyId !== previousProperties["KmsKeyId"]) {
35796
+ await this.getClient().send(new UpdateRepositoryEncryptionKeyCommand({
35797
+ repositoryName: currentName,
35798
+ kmsKeyId: newKmsKeyId ?? "alias/aws/codecommit"
35799
+ }));
35800
+ this.logger.debug(`Updated encryption key for ${currentName}`);
35801
+ }
35802
+ const newTags = properties["Tags"];
35803
+ const oldTags = previousProperties["Tags"];
35804
+ const newTagMap = toSdkTagMap(newTags) ?? {};
35805
+ const oldTagMap = toSdkTagMap(oldTags) ?? {};
35806
+ let metadata;
35807
+ if (!tagMapsEqual(newTagMap, oldTagMap)) {
35808
+ metadata = await this.getRepositoryMetadata(currentName);
35809
+ const repoArn = metadata?.Arn;
35810
+ if (repoArn) {
35811
+ const removedKeys = Object.keys(oldTagMap).filter((k) => !(k in newTagMap));
35812
+ if (removedKeys.length > 0) await this.getClient().send(new UntagResourceCommand$16({
35813
+ resourceArn: repoArn,
35814
+ tagKeys: removedKeys
35815
+ }));
35816
+ if (Object.keys(newTagMap).length > 0) await this.getClient().send(new TagResourceCommand$16({
35817
+ resourceArn: repoArn,
35818
+ tags: newTagMap
35819
+ }));
35820
+ this.logger.debug(`Updated tags for ${currentName}`);
35821
+ } else this.logger.warn(`Could not resolve ARN for CodeCommit Repository ${currentName}; tag update skipped`);
35822
+ }
35823
+ metadata = await this.getRepositoryMetadata(currentName);
35824
+ return {
35825
+ physicalId: currentName,
35826
+ wasReplaced: false,
35827
+ attributes: this.toAttributes(metadata)
35828
+ };
35829
+ } catch (error) {
35830
+ const cause = error instanceof Error ? error : void 0;
35831
+ throw new ProvisioningError(`Failed to update CodeCommit Repository ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, _resourceType, logicalId, physicalId, cause);
35832
+ }
35833
+ }
35834
+ /**
35835
+ * Delete a CodeCommit Repository
35836
+ *
35837
+ * `DeleteRepository` is idempotent on the AWS side: for an
35838
+ * already-deleted repository it does NOT throw — it returns a null
35839
+ * `repositoryId`. That silent-success shape would bypass the shared
35840
+ * region check entirely (the exact scenario `assertRegionMatch` exists
35841
+ * for: a client pointed at region B while the state says the repo lives
35842
+ * in region A), so a null `repositoryId` runs the region check before
35843
+ * being treated as idempotent success. A
35844
+ * `RepositoryDoesNotExistException` is additionally handled (same
35845
+ * check) for defense in depth.
35846
+ */
35847
+ async delete(logicalId, physicalId, resourceType, _properties, context) {
35848
+ this.logger.debug(`Deleting CodeCommit Repository ${logicalId}: ${physicalId}`);
35849
+ let deletedRepositoryId;
35850
+ try {
35851
+ deletedRepositoryId = (await this.getClient().send(new DeleteRepositoryCommand$1({ repositoryName: physicalId }))).repositoryId;
35852
+ } catch (error) {
35853
+ if (error instanceof RepositoryDoesNotExistException) {
35854
+ assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
35855
+ this.logger.debug(`CodeCommit Repository ${physicalId} does not exist, skipping deletion`);
35856
+ return;
35857
+ }
35858
+ const cause = error instanceof Error ? error : void 0;
35859
+ throw new ProvisioningError(`Failed to delete CodeCommit Repository ${logicalId}: ${error instanceof Error ? error.message : String(error)}`, resourceType, logicalId, physicalId, cause);
35860
+ }
35861
+ if (!deletedRepositoryId) {
35862
+ assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
35863
+ this.logger.debug(`CodeCommit Repository ${physicalId} does not exist, skipping deletion`);
35864
+ return;
35865
+ }
35866
+ this.logger.debug(`Successfully deleted CodeCommit Repository ${logicalId}`);
35867
+ }
35868
+ /**
35869
+ * Get repository attributes for Fn::GetAtt resolution.
35870
+ *
35871
+ * Supported: `Arn`, `CloneUrlHttp`, `CloneUrlSsh`, `Name`, `KmsKeyId`
35872
+ * (the CFn-documented attribute set).
35873
+ */
35874
+ async getAttribute(physicalId, _resourceType, attributeName) {
35875
+ switch (attributeName) {
35876
+ case "Name": return physicalId;
35877
+ case "Arn":
35878
+ case "CloneUrlHttp":
35879
+ case "CloneUrlSsh":
35880
+ case "KmsKeyId": {
35881
+ const metadata = await this.getRepositoryMetadata(physicalId);
35882
+ return this.toAttributes(metadata)[attributeName];
35883
+ }
35884
+ default: return;
35885
+ }
35886
+ }
35887
+ /**
35888
+ * Adopt an existing CodeCommit repository into cdkd state.
35889
+ *
35890
+ * Lookup order:
35891
+ * 1. `--resource` override or `Properties.RepositoryName` → verify via
35892
+ * `GetRepository`.
35893
+ * 2. `ListRepositories` paginated, then `ListTagsForResource(arn)` per
35894
+ * repository to match `aws:cdk:path` (CodeCommit uses the
35895
+ * `Record<string, string>` tag-map shape).
35896
+ */
35897
+ async import(input) {
35898
+ const explicit = resolveExplicitPhysicalId(input, "RepositoryName");
35899
+ if (explicit) try {
35900
+ const resp = await this.getClient().send(new GetRepositoryCommand({ repositoryName: explicit }));
35901
+ return resp.repositoryMetadata?.repositoryName ? {
35902
+ physicalId: explicit,
35903
+ attributes: this.toAttributes(resp.repositoryMetadata)
35904
+ } : null;
35905
+ } catch (err) {
35906
+ if (err instanceof RepositoryDoesNotExistException) return null;
35907
+ throw err;
35908
+ }
35909
+ if (!input.cdkPath) return null;
35910
+ let nextToken;
35911
+ do {
35912
+ const list = await this.getClient().send(new ListRepositoriesCommand({ ...nextToken && { nextToken } }));
35913
+ for (const repo of list.repositories ?? []) {
35914
+ if (!repo.repositoryName) continue;
35915
+ let metadata;
35916
+ try {
35917
+ metadata = await this.getRepositoryMetadata(repo.repositoryName);
35918
+ } catch (err) {
35919
+ if (err instanceof RepositoryDoesNotExistException) continue;
35920
+ throw err;
35921
+ }
35922
+ if (!metadata?.Arn) continue;
35923
+ if ((await this.getClient().send(new ListTagsForResourceCommand$18({ resourceArn: metadata.Arn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
35924
+ physicalId: repo.repositoryName,
35925
+ attributes: this.toAttributes(metadata)
35926
+ };
35927
+ }
35928
+ nextToken = list.nextToken;
35929
+ } while (nextToken);
35930
+ return null;
35931
+ }
35932
+ /**
35933
+ * Fetch the repository's metadata via `GetRepository`. Throws
35934
+ * `RepositoryDoesNotExistException` through to the caller.
35935
+ */
35936
+ async getRepositoryMetadata(repositoryName) {
35937
+ return (await this.getClient().send(new GetRepositoryCommand({ repositoryName }))).repositoryMetadata;
35938
+ }
35939
+ };
35940
+
35166
35941
  //#endregion
35167
35942
  //#region src/provisioning/providers/dlm-lifecycle-policy-provider.ts
35168
35943
  /**
@@ -35295,7 +36070,7 @@ var DLMLifecyclePolicyProvider = class {
35295
36070
  if (tagsChanged && arn) {
35296
36071
  const removedKeys = Object.keys(oldTags).filter((k) => !(k in newTags));
35297
36072
  if (removedKeys.length > 0) {
35298
- await this.getClient().send(new UntagResourceCommand$15({
36073
+ await this.getClient().send(new UntagResourceCommand$17({
35299
36074
  ResourceArn: arn,
35300
36075
  TagKeys: removedKeys
35301
36076
  }));
@@ -35304,7 +36079,7 @@ var DLMLifecyclePolicyProvider = class {
35304
36079
  const tagsToAdd = {};
35305
36080
  for (const [k, v] of Object.entries(newTags)) if (oldTags[k] !== v) tagsToAdd[k] = v;
35306
36081
  if (Object.keys(tagsToAdd).length > 0) {
35307
- await this.getClient().send(new TagResourceCommand$15({
36082
+ await this.getClient().send(new TagResourceCommand$17({
35308
36083
  ResourceArn: arn,
35309
36084
  Tags: tagsToAdd
35310
36085
  }));
@@ -35507,11 +36282,11 @@ var S3VectorsProvider = class {
35507
36282
  }
35508
36283
  if (!resourceArn) throw new ProvisioningError(`Could not resolve ARN for S3 VectorBucket ${logicalId} (${physicalId}); cannot apply tag update.`, resourceType, logicalId, physicalId);
35509
36284
  try {
35510
- if (Object.keys(toSet).length > 0) await this.getClient().send(new TagResourceCommand$16({
36285
+ if (Object.keys(toSet).length > 0) await this.getClient().send(new TagResourceCommand$18({
35511
36286
  resourceArn,
35512
36287
  tags: toSet
35513
36288
  }));
35514
- if (toRemove.length > 0) await this.getClient().send(new UntagResourceCommand$16({
36289
+ if (toRemove.length > 0) await this.getClient().send(new UntagResourceCommand$18({
35515
36290
  resourceArn,
35516
36291
  tagKeys: toRemove
35517
36292
  }));
@@ -35639,7 +36414,7 @@ var S3VectorsProvider = class {
35639
36414
  if (Object.keys(enc).length > 0) result["EncryptionConfiguration"] = enc;
35640
36415
  }
35641
36416
  if (bucket?.vectorBucketArn) try {
35642
- result["Tags"] = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsForResourceCommand$17({ resourceArn: bucket.vectorBucketArn }))).tags);
36417
+ result["Tags"] = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsForResourceCommand$19({ resourceArn: bucket.vectorBucketArn }))).tags);
35643
36418
  } catch (err) {
35644
36419
  this.logger.debug(`S3Vectors ListTagsForResource(${bucket.vectorBucketArn}) failed: ${err instanceof Error ? err.message : String(err)}`);
35645
36420
  result["Tags"] = [];
@@ -35675,7 +36450,7 @@ var S3VectorsProvider = class {
35675
36450
  for (const bucket of list.vectorBuckets ?? []) {
35676
36451
  if (!bucket.vectorBucketName || !bucket.vectorBucketArn) continue;
35677
36452
  try {
35678
- if ((await this.getClient().send(new ListTagsForResourceCommand$17({ resourceArn: bucket.vectorBucketArn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
36453
+ if ((await this.getClient().send(new ListTagsForResourceCommand$19({ resourceArn: bucket.vectorBucketArn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
35679
36454
  physicalId: bucket.vectorBucketName,
35680
36455
  attributes: {}
35681
36456
  };
@@ -36026,7 +36801,7 @@ var S3TablesProvider = class {
36026
36801
  await this.getClient().send(new DeleteTableBucketCommand({ tableBucketARN: physicalId }));
36027
36802
  this.logger.debug(`Successfully deleted S3 Table Bucket ${logicalId}`);
36028
36803
  } catch (error) {
36029
- if (error instanceof NotFoundException$5) {
36804
+ if (error instanceof NotFoundException$6) {
36030
36805
  assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
36031
36806
  this.logger.debug(`S3 Table Bucket ${physicalId} does not exist, skipping deletion`);
36032
36807
  return;
@@ -36067,7 +36842,7 @@ var S3TablesProvider = class {
36067
36842
  name: table.name
36068
36843
  }));
36069
36844
  } catch (error) {
36070
- if (!(error instanceof NotFoundException$5)) throw error;
36845
+ if (!(error instanceof NotFoundException$6)) throw error;
36071
36846
  }
36072
36847
  }
36073
36848
  tableContinuationToken = tablesResult.continuationToken;
@@ -36079,7 +36854,7 @@ var S3TablesProvider = class {
36079
36854
  namespace: namespaceName
36080
36855
  }));
36081
36856
  } catch (error) {
36082
- if (!(error instanceof NotFoundException$5)) throw error;
36857
+ if (!(error instanceof NotFoundException$6)) throw error;
36083
36858
  }
36084
36859
  }
36085
36860
  namespaceContinuationToken = namespacesResult.continuationToken;
@@ -36121,7 +36896,7 @@ var S3TablesProvider = class {
36121
36896
  }));
36122
36897
  this.logger.debug(`Successfully deleted S3 Tables Namespace ${logicalId}`);
36123
36898
  } catch (error) {
36124
- if (error instanceof NotFoundException$5) {
36899
+ if (error instanceof NotFoundException$6) {
36125
36900
  assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
36126
36901
  this.logger.debug(`S3 Tables Namespace ${physicalId} does not exist, skipping deletion`);
36127
36902
  return;
@@ -36195,7 +36970,7 @@ var S3TablesProvider = class {
36195
36970
  try {
36196
36971
  bucket = await this.getClient().send(new GetTableBucketCommand({ tableBucketARN: physicalId }));
36197
36972
  } catch (err) {
36198
- if (err instanceof NotFoundException$5) return void 0;
36973
+ if (err instanceof NotFoundException$6) return void 0;
36199
36974
  throw err;
36200
36975
  }
36201
36976
  const result = {};
@@ -36224,7 +36999,7 @@ var S3TablesProvider = class {
36224
36999
  name
36225
37000
  }));
36226
37001
  } catch (err) {
36227
- if (err instanceof NotFoundException$5) return void 0;
37002
+ if (err instanceof NotFoundException$6) return void 0;
36228
37003
  throw err;
36229
37004
  }
36230
37005
  const tableNameValue = resp.name ?? name;
@@ -36271,7 +37046,7 @@ var S3TablesProvider = class {
36271
37046
  attributes: {}
36272
37047
  };
36273
37048
  } catch (err) {
36274
- if (err instanceof NotFoundException$5) return null;
37049
+ if (err instanceof NotFoundException$6) return null;
36275
37050
  throw err;
36276
37051
  }
36277
37052
  const desiredName = typeof input.properties?.["TableBucketName"] === "string" ? input.properties["TableBucketName"] : void 0;
@@ -36285,12 +37060,12 @@ var S3TablesProvider = class {
36285
37060
  attributes: {}
36286
37061
  };
36287
37062
  if (input.cdkPath) try {
36288
- if ((await this.getClient().send(new ListTagsForResourceCommand$18({ resourceArn: bucket.arn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
37063
+ if ((await this.getClient().send(new ListTagsForResourceCommand$20({ resourceArn: bucket.arn }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
36289
37064
  physicalId: bucket.arn,
36290
37065
  attributes: {}
36291
37066
  };
36292
37067
  } catch (err) {
36293
- if (err instanceof NotFoundException$5) continue;
37068
+ if (err instanceof NotFoundException$6) continue;
36294
37069
  throw err;
36295
37070
  }
36296
37071
  }
@@ -36319,7 +37094,7 @@ var S3TablesProvider = class {
36319
37094
  attributes: {}
36320
37095
  };
36321
37096
  } catch (err) {
36322
- if (err instanceof NotFoundException$5) return null;
37097
+ if (err instanceof NotFoundException$6) return null;
36323
37098
  throw err;
36324
37099
  }
36325
37100
  return {
@@ -36352,12 +37127,12 @@ var S3TablesProvider = class {
36352
37127
  for (const table of tables.tables ?? []) {
36353
37128
  if (!table.name || !table.tableARN) continue;
36354
37129
  try {
36355
- if ((await this.getClient().send(new ListTagsForResourceCommand$18({ resourceArn: table.tableARN }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
37130
+ if ((await this.getClient().send(new ListTagsForResourceCommand$20({ resourceArn: table.tableARN }))).tags?.["aws:cdk:path"] === input.cdkPath) return {
36356
37131
  physicalId: `${bucket.arn}|${namespaceName}|${table.name}`,
36357
37132
  attributes: {}
36358
37133
  };
36359
37134
  } catch (err) {
36360
- if (err instanceof NotFoundException$5) continue;
37135
+ if (err instanceof NotFoundException$6) continue;
36361
37136
  throw err;
36362
37137
  }
36363
37138
  }
@@ -36386,7 +37161,7 @@ var S3TablesProvider = class {
36386
37161
  }));
36387
37162
  this.logger.debug(`Successfully deleted S3 Tables Table ${logicalId}`);
36388
37163
  } catch (error) {
36389
- if (error instanceof NotFoundException$5) {
37164
+ if (error instanceof NotFoundException$6) {
36390
37165
  assertRegionMatch(await this.getClient().config.region(), context?.expectedRegion, resourceType, logicalId, physicalId);
36391
37166
  this.logger.debug(`S3 Tables Table ${physicalId} does not exist, skipping deletion`);
36392
37167
  return;
@@ -36436,7 +37211,7 @@ var S3TablesProvider = class {
36436
37211
  name
36437
37212
  }))).tableARN ?? null;
36438
37213
  } catch (err) {
36439
- if (err instanceof NotFoundException$5) return null;
37214
+ if (err instanceof NotFoundException$6) return null;
36440
37215
  throw err;
36441
37216
  }
36442
37217
  }
@@ -36448,7 +37223,7 @@ var S3TablesProvider = class {
36448
37223
  */
36449
37224
  async readTagsBestEffort(resourceArn) {
36450
37225
  try {
36451
- const tags = (await this.getClient().send(new ListTagsForResourceCommand$18({ resourceArn }))).tags ?? {};
37226
+ const tags = (await this.getClient().send(new ListTagsForResourceCommand$20({ resourceArn }))).tags ?? {};
36452
37227
  const out = [];
36453
37228
  for (const [Key, Value] of Object.entries(tags)) out.push({
36454
37229
  Key,
@@ -36502,7 +37277,7 @@ var S3TablesProvider = class {
36502
37277
  const resourceArn = await this.lookupTableArn(tableBucketARN, namespace, name);
36503
37278
  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);
36504
37279
  if (removedKeys.length > 0) try {
36505
- await this.getClient().send(new UntagResourceCommand$17({
37280
+ await this.getClient().send(new UntagResourceCommand$19({
36506
37281
  resourceArn,
36507
37282
  tagKeys: removedKeys
36508
37283
  }));
@@ -36511,7 +37286,7 @@ var S3TablesProvider = class {
36511
37286
  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);
36512
37287
  }
36513
37288
  if (Object.keys(upserts).length > 0) try {
36514
- await this.getClient().send(new TagResourceCommand$17({
37289
+ await this.getClient().send(new TagResourceCommand$19({
36515
37290
  resourceArn,
36516
37291
  tags: upserts
36517
37292
  }));
@@ -36543,7 +37318,7 @@ var S3TablesProvider = class {
36543
37318
  if (removedKeys.length === 0 && Object.keys(upserts).length === 0) return;
36544
37319
  const resourceArn = physicalId;
36545
37320
  if (removedKeys.length > 0) try {
36546
- await this.getClient().send(new UntagResourceCommand$17({
37321
+ await this.getClient().send(new UntagResourceCommand$19({
36547
37322
  resourceArn,
36548
37323
  tagKeys: removedKeys
36549
37324
  }));
@@ -36552,7 +37327,7 @@ var S3TablesProvider = class {
36552
37327
  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);
36553
37328
  }
36554
37329
  if (Object.keys(upserts).length > 0) try {
36555
- await this.getClient().send(new TagResourceCommand$17({
37330
+ await this.getClient().send(new TagResourceCommand$19({
36556
37331
  resourceArn,
36557
37332
  tags: upserts
36558
37333
  }));
@@ -38199,6 +38974,7 @@ function registerAllProviders(registry) {
38199
38974
  registry.register("AWS::KinesisFirehose::DeliveryStream", new FirehoseProvider());
38200
38975
  registry.register("AWS::CloudTrail::Trail", new CloudTrailProvider());
38201
38976
  registry.register("AWS::CodeBuild::Project", new CodeBuildProvider());
38977
+ registry.register("AWS::CodeCommit::Repository", new CodeCommitRepositoryProvider());
38202
38978
  registry.register("AWS::DLM::LifecyclePolicy", new DLMLifecyclePolicyProvider());
38203
38979
  registry.register("AWS::S3Vectors::VectorBucket", new S3VectorsProvider());
38204
38980
  registry.register("AWS::ECR::Repository", new ECRProvider());
@@ -38207,6 +38983,7 @@ function registerAllProviders(registry) {
38207
38983
  registry.register("AWS::S3Tables::TableBucket", s3TablesProvider);
38208
38984
  registry.register("AWS::S3Tables::Namespace", s3TablesProvider);
38209
38985
  registry.register("AWS::S3Tables::Table", s3TablesProvider);
38986
+ registry.register("AWS::Budgets::Budget", new BudgetsBudgetProvider());
38210
38987
  registry.register("AWS::CloudFormation::Stack", new NestedStackProvider());
38211
38988
  registry.register("AWS::CloudFormation::WaitConditionHandle", new WaitConditionHandleProvider());
38212
38989
  }
@@ -57472,7 +58249,7 @@ function reorderArgs(argv) {
57472
58249
  async function main() {
57473
58250
  installPipeCloseHandler();
57474
58251
  const program = new Command();
57475
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.239.0");
58252
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.241.0");
57476
58253
  program.addCommand(createBootstrapCommand());
57477
58254
  program.addCommand(createSynthCommand());
57478
58255
  program.addCommand(createListCommand());