@go-to-k/cdkd 0.281.1 → 0.281.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { $ as requireConfigArray, $t as expectedOwnerParam, A as green, An as withErrorHandling, At as getDockerCmd, B as slowCcOperationTimeoutMs, Bt as resolveAutoAssetStorage, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackHasActiveImportsError, Ct as ensureAssetStorage, D as bold, Dt as validateContainerRepoName, E as formatResourceLine, Et as validateAssetBucketName, F as clearOnUpdateRemoval, Ft as Synthesizer, G as refStateLookupFromResource, Gt as resolveUseCdkBootstrapAssets, H as isTerminationProtectionPropagationError, Ht as resolveSkipPrefix, I as ProviderRegistry, It as synthesisStatusMessage, J as resolveExplicitPhysicalId, Jt as CFN_TEMPLATE_BODY_LIMIT, K as WAFv2WebACLProvider, Kt as stateBucketExistenceConfirmed, L as findActionableSilentDrops, Lt as getDefaultStateBucketName, M as yellow, Mt as runDockerStreaming, N as IAMRoleProvider, Nt as AssetManifestLoader, O as cyan, Ot as buildDockerImage, P as collectInlinePolicyNamesManagedBySiblings, Pt as getDockerImageBySourceHash, Q as replayWarn, Qt as uploadCfnTemplate, R as findSilentDropProperties, Rt as getLegacyStateBucketName, S as extractDeploymentEventError, Sn as ResourceUpdateNotSupportedError, St as BOOTSTRAP_MARKER_PREFIX, T as renderStatefulReason, Tt as parseBootstrapMarker, U as IntrinsicFunctionResolver, Ut as resolveStateBucketWithDefault, V as disableInstanceApiTermination, Vt as resolveCaptureObservedState, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefaultAndSource, X as configStringRefusal, Xt as MIGRATE_TMP_PREFIX, Y as assertRegionMatch, Yt as CFN_TEMPLATE_URL_LIMIT, Z as readConfigString, Zt as findLargeInlineResources, _ as createPreDeleteFinalSnapshot, _n as MissingCdkCliError, _t as buildAssetRedirectMap, a as DeploymentEventsStore, an as getAwsClients, at as withRetry, b as unsupportedFinalSnapshotError, bn as ProvisioningError, bt as rewriteTemplateAssetReferences, c as replayFailedOperations, ct as DagBuilder, d as IMPLICIT_DELETE_DEPENDENCIES, dt as S3StateBackend, en as AssemblyReader, et as requireConfigObject, f as computeImplicitDeleteEdges, fn as DeployCancelledError, ft as rebuildClientForBucketRegion, g as ccRoutedFinalSnapshotError, gt as WorkGraph, h as buildFinalSnapshotIdentifier, hn as LocalStartServiceError, ht as stringifyValue, i as DeploymentEventsReader, in as AwsClients, it as describeTypeWithThrottleRetry, j as red, jt as runDockerForeground, k as gray, kn as normalizeAwsError, kt as formatDockerLoginError, l as replayRollback, ln as CdkdError, lt as TemplateParser, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalMigrateError, mt as AssetPublisher, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as applyRoleArnIfSet, o as planFailedOps, on as resetAwsClients, ot as isRetryableTransientError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalInvokeBuildError$1, pt as shouldRetainResource, q as normalizeAwsTagsToCfn, qt as warnDeprecatedNoPrefixCliFlag, r as DeployEngine, rn as resolveBucketRegion, rt as DiffCalculator, s as planRollback, sn as setAwsClients, st as isThrottlingError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as processStackMessages, tt as requireConfigString, u as withResourceDeadline, ut as LockManager, v as isFinalSnapshotError, vn as NestedStackChildDirectDestroyError, vt as createAssetRedirectResolver, w as isStatefulRecreateTargetSync, wn as StackTerminationProtectionError, wt as getBootstrapMarkerKey, x as makeCanonicalizePropertiesFn, xn as ResourceTimeoutError, xt as AssetModeResolver, y as refusesFinalSnapshot, yn as PartialFailureError, yt as loadPublishableAssetManifest, z as CloudControlProvider, zt as resolveApp } from "./deploy-engine-CGL3Vw1P.js";
2
+ import { $ as requireConfigArray, $t as expectedOwnerParam, A as green, An as withErrorHandling, At as getDockerCmd, B as slowCcOperationTimeoutMs, Bt as resolveAutoAssetStorage, C as MULTI_REGION_RECREATE_BLOCKED_TYPES, Cn as StackHasActiveImportsError, Ct as ensureAssetStorage, D as bold, Dt as validateContainerRepoName, E as formatResourceLine, Et as validateAssetBucketName, F as clearOnUpdateRemoval, Ft as Synthesizer, G as refStateLookupFromResource, Gt as resolveUseCdkBootstrapAssets, H as isTerminationProtectionPropagationError, Ht as resolveSkipPrefix, I as ProviderRegistry, It as synthesisStatusMessage, J as resolveExplicitPhysicalId, Jt as CFN_TEMPLATE_BODY_LIMIT, K as WAFv2WebACLProvider, Kt as stateBucketExistenceConfirmed, L as findActionableSilentDrops, Lt as getDefaultStateBucketName, M as yellow, Mt as runDockerStreaming, N as IAMRoleProvider, Nt as AssetManifestLoader, O as cyan, Ot as buildDockerImage, P as collectInlinePolicyNamesManagedBySiblings, Pt as getDockerImageBySourceHash, Q as replayWarn, Qt as uploadCfnTemplate, R as findSilentDropProperties, Rt as getLegacyStateBucketName, S as extractDeploymentEventError, Sn as ResourceUpdateNotSupportedError, St as BOOTSTRAP_MARKER_PREFIX, T as renderStatefulReason, Tt as parseBootstrapMarker, U as IntrinsicFunctionResolver, Ut as resolveStateBucketWithDefault, V as disableInstanceApiTermination, Vt as resolveCaptureObservedState, W as cfnRefValueFromPhysicalId, Wt as resolveStateBucketWithDefaultAndSource, X as configStringRefusal, Xt as MIGRATE_TMP_PREFIX, Y as assertRegionMatch, Yt as CFN_TEMPLATE_URL_LIMIT, Z as readConfigString, Zt as findLargeInlineResources, _ as createPreDeleteFinalSnapshot, _n as MissingCdkCliError, _t as buildAssetRedirectMap, a as DeploymentEventsStore, an as getAwsClients, at as withRetry, b as unsupportedFinalSnapshotError, bn as ProvisioningError, bt as rewriteTemplateAssetReferences, c as replayFailedOperations, ct as DagBuilder, d as IMPLICIT_DELETE_DEPENDENCIES, dt as S3StateBackend, en as AssemblyReader, et as requireConfigObject, f as computeImplicitDeleteEdges, fn as DeployCancelledError, ft as rebuildClientForBucketRegion, g as ccRoutedFinalSnapshotError, gt as WorkGraph, h as buildFinalSnapshotIdentifier, hn as LocalStartServiceError, ht as stringifyValue, i as DeploymentEventsReader, in as AwsClients, it as describeTypeWithThrottleRetry, j as red, jt as runDockerForeground, k as gray, kn as normalizeAwsError, kt as formatDockerLoginError, l as replayRollback, ln as CdkdError, lt as TemplateParser, m as PRE_DELETE_SNAPSHOT_TYPES, mn as LocalMigrateError, mt as AssetPublisher, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nt as applyRoleArnIfSet, o as planFailedOps, on as resetAwsClients, ot as isRetryableTransientError, p as ATOMIC_FINAL_SNAPSHOT_TYPES, pn as LocalInvokeBuildError$1, pt as shouldRetainResource, q as normalizeAwsTagsToCfn, qt as warnDeprecatedNoPrefixCliFlag, r as DeployEngine, rn as resolveBucketRegion, rt as DiffCalculator, s as planRollback, sn as setAwsClients, st as isThrottlingError, t as DEFAULT_RESOURCE_TIMEOUT_MS, tn as processStackMessages, tt as requireConfigString, u as withResourceDeadline, ut as LockManager, v as isFinalSnapshotError, vn as NestedStackChildDirectDestroyError, vt as createAssetRedirectResolver, w as isStatefulRecreateTargetSync, wn as StackTerminationProtectionError, wt as getBootstrapMarkerKey, x as makeCanonicalizePropertiesFn, xn as ResourceTimeoutError, xt as AssetModeResolver, y as refusesFinalSnapshot, yn as PartialFailureError, yt as loadPublishableAssetManifest, z as CloudControlProvider, zt as resolveApp } from "./deploy-engine-drWGPyTA.js";
3
3
  import { a as getLiveRenderer, c as PATTERN_B_RESOURCE_TYPES, d as generateResourceNameWithFallback, h as withStackName, i as runStackBuffered, m as withSkipPrefix, n as getLogger, o as PATTERN_B_NAME_OPTIONS, s as PATTERN_B_NAME_PROPERTIES, u as generateResourceName } from "./logger-zRrlbaQt.js";
4
- import { t as ASGProvider } from "./asg-provider-DYdmsCfd.js";
4
+ import { t as ASGProvider } from "./asg-provider-n21zWyH-.js";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
  import { createHash, randomBytes, randomUUID } from "node:crypto";
7
7
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketAnalyticsConfigurationCommand, DeleteBucketCommand, DeleteBucketCorsCommand, DeleteBucketEncryptionCommand, DeleteBucketIntelligentTieringConfigurationCommand, DeleteBucketInventoryConfigurationCommand, DeleteBucketLifecycleCommand, DeleteBucketMetricsConfigurationCommand, DeleteBucketOwnershipControlsCommand, DeleteBucketPolicyCommand, DeleteBucketReplicationCommand, DeleteBucketTaggingCommand, DeleteBucketWebsiteCommand, DeleteObjectsCommand, GetBucketAccelerateConfigurationCommand, GetBucketCorsCommand, GetBucketEncryptionCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketLoggingCommand, GetBucketNotificationConfigurationCommand, GetBucketOwnershipControlsCommand, GetBucketPolicyCommand, GetBucketReplicationCommand, GetBucketTaggingCommand, GetBucketVersioningCommand, GetBucketWebsiteCommand, GetObjectCommand, GetObjectLockConfigurationCommand, GetPublicAccessBlockCommand, HeadBucketCommand, ListBucketAnalyticsConfigurationsCommand, ListBucketIntelligentTieringConfigurationsCommand, ListBucketInventoryConfigurationsCommand, ListBucketMetricsConfigurationsCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, PutBucketAccelerateConfigurationCommand, PutBucketAnalyticsConfigurationCommand, PutBucketCorsCommand, PutBucketEncryptionCommand, PutBucketIntelligentTieringConfigurationCommand, PutBucketInventoryConfigurationCommand, PutBucketLifecycleConfigurationCommand, PutBucketLoggingCommand, PutBucketMetricsConfigurationCommand, PutBucketNotificationConfigurationCommand, PutBucketOwnershipControlsCommand, PutBucketPolicyCommand, PutBucketReplicationCommand, PutBucketTaggingCommand, PutBucketVersioningCommand, PutBucketWebsiteCommand, PutObjectCommand, PutObjectLockConfigurationCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -54,7 +54,7 @@ import { AppSyncClient, CreateApiKeyCommand, CreateDataSourceCommand, CreateGrap
54
54
  import { parse, print } from "graphql";
55
55
  import { ConcurrentModificationException, 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, GetJobCommand, GetSecurityConfigurationCommand, GetTableCommand, GetTagsCommand, GetTriggerCommand, GetWorkflowCommand, GlueClient, StartCrawlerScheduleCommand, StartTriggerCommand, StopCrawlerCommand, StopCrawlerScheduleCommand, StopTriggerCommand, UpdateConnectionCommand, UpdateCrawlerCommand, UpdateDatabaseCommand, UpdateJobCommand, UpdateTableCommand as UpdateTableCommand$1, UpdateTriggerCommand, UpdateWorkflowCommand } from "@aws-sdk/client-glue";
56
56
  import { BudgetsClient, CreateBudgetCommand, CreateNotificationCommand, CreateSubscriberCommand, DeleteBudgetCommand, DeleteNotificationCommand, DeleteSubscriberCommand, DescribeBudgetCommand, DuplicateRecordException, NotFoundException as NotFoundException$5, TagResourceCommand as TagResourceCommand$17, UntagResourceCommand as UntagResourceCommand$17, UpdateBudgetCommand } from "@aws-sdk/client-budgets";
57
- import { AddTagsToStreamCommand, CreateStreamCommand, DecreaseStreamRetentionPeriodCommand, DeleteStreamCommand, DeregisterStreamConsumerCommand, DescribeStreamCommand, DescribeStreamConsumerCommand, DescribeStreamSummaryCommand, IncreaseStreamRetentionPeriodCommand, KinesisClient, ListTagsForResourceCommand as ListTagsForResourceCommand$15, ListTagsForStreamCommand, RegisterStreamConsumerCommand, RemoveTagsFromStreamCommand, ResourceNotFoundException as ResourceNotFoundException$10, StartStreamEncryptionCommand, StopStreamEncryptionCommand, TagResourceCommand as TagResourceCommand$18, UntagResourceCommand as UntagResourceCommand$18, UpdateShardCountCommand, UpdateStreamModeCommand } from "@aws-sdk/client-kinesis";
57
+ import { AddTagsToStreamCommand, CreateStreamCommand, DecreaseStreamRetentionPeriodCommand, DeleteStreamCommand, DeregisterStreamConsumerCommand, DescribeStreamCommand, DescribeStreamConsumerCommand, DescribeStreamSummaryCommand, DisableEnhancedMonitoringCommand, EnableEnhancedMonitoringCommand, IncreaseStreamRetentionPeriodCommand, KinesisClient, ListTagsForResourceCommand as ListTagsForResourceCommand$15, ListTagsForStreamCommand, RegisterStreamConsumerCommand, RemoveTagsFromStreamCommand, ResourceNotFoundException as ResourceNotFoundException$10, StartStreamEncryptionCommand, StopStreamEncryptionCommand, TagResourceCommand as TagResourceCommand$18, UntagResourceCommand as UntagResourceCommand$18, UpdateMaxRecordSizeCommand, UpdateShardCountCommand, UpdateStreamModeCommand } from "@aws-sdk/client-kinesis";
58
58
  import { CreateScheduleCommand, DeleteScheduleCommand, GetScheduleCommand, ResourceNotFoundException as ResourceNotFoundException$11, SchedulerClient, UpdateScheduleCommand } from "@aws-sdk/client-scheduler";
59
59
  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";
60
60
  import { CreateFileSystemCommand as CreateFileSystemCommand$1, CreateFileSystemFromBackupCommand, DeleteFileSystemCommand as DeleteFileSystemCommand$1, DescribeFileSystemsCommand as DescribeFileSystemsCommand$1, FSxClient, FileSystemNotFound as FileSystemNotFound$1, TagResourceCommand as TagResourceCommand$19, UntagResourceCommand as UntagResourceCommand$19, UpdateFileSystemCommand as UpdateFileSystemCommand$1 } from "@aws-sdk/client-fsx";
@@ -41101,6 +41101,134 @@ function isKmsEncryption(value) {
41101
41101
  return value["EncryptionType"] === "KMS";
41102
41102
  }
41103
41103
  /**
41104
+ * The seven shard-level metrics `ALL` expands to.
41105
+ *
41106
+ * MEASURED, not copied from the docs (us-east-1, 2026-08-12): an
41107
+ * `EnableEnhancedMonitoring(ShardLevelMetrics: ['ALL'])` responds with exactly
41108
+ * these seven in `DesiredShardLevelMetrics`, and once the stream settles back
41109
+ * to ACTIVE `DescribeStream` reports the same seven — never the literal `ALL`.
41110
+ * The readback order is AWS-chosen and matched neither the input order nor
41111
+ * alphabetical, which is why the type also declares the path unordered (see
41112
+ * {@link KinesisStreamProvider.getDriftUnorderedPaths}).
41113
+ */
41114
+ const ALL_SHARD_LEVEL_METRICS = [
41115
+ "IncomingBytes",
41116
+ "IncomingRecords",
41117
+ "OutgoingBytes",
41118
+ "OutgoingRecords",
41119
+ "WriteProvisionedThroughputExceeded",
41120
+ "ReadProvisionedThroughputExceeded",
41121
+ "IteratorAgeMilliseconds"
41122
+ ];
41123
+ /**
41124
+ * Whether a value is a usable shard-level-metrics list: an array whose every
41125
+ * element is a string.
41126
+ *
41127
+ * A MIXED array (`['IncomingBytes', {Ref: 'X'}]`) is deliberately UNUSABLE
41128
+ * rather than partially usable. Filtering the unresolved element away would put
41129
+ * a list on the wire that the template never declared, while state recorded the
41130
+ * declared one — the permanent phantom drift `effectiveProperties` exists to
41131
+ * prevent, arrived at through the back door.
41132
+ */
41133
+ function isUsableMetricsList(value) {
41134
+ return Array.isArray(value) && value.every((entry) => typeof entry === "string");
41135
+ }
41136
+ /**
41137
+ * Expand the `ALL` shard-level-metrics shorthand into the seven metric names
41138
+ * AWS actually stores.
41139
+ *
41140
+ * This is the ONE definition of the rule, shared by the provisioning path (what
41141
+ * goes on the wire, and therefore what `effectiveProperties` records) and by
41142
+ * {@link KinesisStreamProvider.canonicalizeDesiredProperties} (what the diff
41143
+ * compares). Deriving it twice is how state and template end up narrowed
41144
+ * differently — see the `effectiveProperties` contract in
41145
+ * `.claude/rules/providers.md`.
41146
+ *
41147
+ * Idempotent: an already-expanded list is returned with its own values (deduped
41148
+ * and otherwise untouched), so a state-borne bag that has been through this
41149
+ * before is unchanged. An UNUSABLE value is returned as-is — the callers that
41150
+ * put bytes on the wire refuse it via {@link readShardLevelMetrics} rather than
41151
+ * sending a partial list, and `canonicalizeDesiredProperties` must stay a total
41152
+ * function because the diff runs on bags no provider validated.
41153
+ */
41154
+ function expandShardLevelMetrics(value) {
41155
+ if (!isUsableMetricsList(value)) return value;
41156
+ const names = value;
41157
+ const expanded = names.includes("ALL") ? [...names.filter((n) => n !== "ALL"), ...ALL_SHARD_LEVEL_METRICS] : names;
41158
+ const seen = /* @__PURE__ */ new Set();
41159
+ const deduped = [];
41160
+ for (const name of expanded) {
41161
+ if (seen.has(name)) continue;
41162
+ seen.add(name);
41163
+ deduped.push(name);
41164
+ }
41165
+ if (deduped.length === names.length && deduped.every((n, i) => n === names[i])) return value;
41166
+ return deduped;
41167
+ }
41168
+ /**
41169
+ * Classify a declared `DesiredShardLevelMetrics` value, expanding `ALL` when it
41170
+ * is usable.
41171
+ *
41172
+ * Callers own the ACTION per the update-path rules in
41173
+ * `.claude/rules/providers.md`: a create refuses an unusable value (it is
41174
+ * template-borne), an update WARNS and skips (it may be replaying a state
41175
+ * record, where refusing would leave the resource un-rollbackable). The
41176
+ * previous side is never routed through the refusal at all — see
41177
+ * {@link previousMetricNames}.
41178
+ */
41179
+ function readShardLevelMetrics(value) {
41180
+ if (value == null) return { kind: "absent" };
41181
+ if (!isUsableMetricsList(value)) return {
41182
+ kind: "unusable",
41183
+ reason: `AWS::Kinesis::Stream DesiredShardLevelMetrics must be an array of metric-name strings, got ${JSON.stringify(value)}`
41184
+ };
41185
+ const expanded = expandShardLevelMetrics(value);
41186
+ return {
41187
+ kind: "usable",
41188
+ metrics: expanded,
41189
+ expanded
41190
+ };
41191
+ }
41192
+ /**
41193
+ * Read the PREVIOUS side leniently: it comes from cdkd state, not the user's
41194
+ * template, so an unreadable value recorded by an older binary must never
41195
+ * refuse the update (the #1471 desired-side-only rule). An unusable previous
41196
+ * side simply contributes no metrics to disable.
41197
+ */
41198
+ function previousMetricNames(value) {
41199
+ const expanded = expandShardLevelMetrics(value);
41200
+ return isUsableMetricsList(expanded) ? expanded : [];
41201
+ }
41202
+ function readMaxRecordSize(value) {
41203
+ if (value == null) return { kind: "absent" };
41204
+ if (typeof value === "number" && Number.isFinite(value)) return {
41205
+ kind: "usable",
41206
+ size: value
41207
+ };
41208
+ if (typeof value === "string" && value.trim() !== "") {
41209
+ const n = Number(value);
41210
+ if (Number.isFinite(n)) return {
41211
+ kind: "usable",
41212
+ size: n
41213
+ };
41214
+ }
41215
+ return {
41216
+ kind: "unusable",
41217
+ reason: `AWS::Kinesis::Stream MaxRecordSizeInKiB must be a number, got ${JSON.stringify(value)}`
41218
+ };
41219
+ }
41220
+ /**
41221
+ * The comparison-side read: the UPDATE path needs both sides reduced to the
41222
+ * same shape so a state record holding the number and a template holding the
41223
+ * numeric string do not read as a change and re-issue the call every deploy.
41224
+ * Unusable / absent both yield `undefined`, which the caller treats as "no
41225
+ * declared size" rather than refusing — the previous side is state-borne.
41226
+ */
41227
+ function comparableRecordSize(value) {
41228
+ const read = readMaxRecordSize(value);
41229
+ return read.kind === "usable" ? read.size : void 0;
41230
+ }
41231
+ /**
41104
41232
  * AWS Kinesis Stream Provider
41105
41233
  *
41106
41234
  * Implements resource provisioning for AWS::Kinesis::Stream using the Kinesis SDK.
@@ -41118,7 +41246,9 @@ var KinesisStreamProvider = class {
41118
41246
  "ShardCount",
41119
41247
  "Tags",
41120
41248
  "RetentionPeriodHours",
41121
- "StreamEncryption"
41249
+ "StreamEncryption",
41250
+ "DesiredShardLevelMetrics",
41251
+ "MaxRecordSizeInKiB"
41122
41252
  ])]]);
41123
41253
  getClient() {
41124
41254
  if (!this.client) this.client = new KinesisClient(this.providerRegion ? { region: this.providerRegion } : {});
@@ -41127,17 +41257,25 @@ var KinesisStreamProvider = class {
41127
41257
  /**
41128
41258
  * Create a Kinesis stream
41129
41259
  */
41130
- async create(logicalId, resourceType, properties) {
41260
+ async create(logicalId, resourceType, properties, context) {
41131
41261
  this.logger.debug(`Creating Kinesis stream ${logicalId}`);
41132
41262
  const streamName = properties["Name"] || generateResourceName(logicalId, { maxLength: 128 });
41263
+ const desiredRead = readShardLevelMetrics(properties["DesiredShardLevelMetrics"]);
41264
+ if (desiredRead.kind === "unusable") if (context?.replayingState === true) this.logger.warn(`${desiredRead.reason}. Replaying a state record, so the shard-level metrics are left unset on ${streamName} rather than refusing the restore`);
41265
+ else throw new ProvisioningError(desiredRead.reason, resourceType, logicalId, streamName);
41266
+ const maxRecordRead = readMaxRecordSize(properties["MaxRecordSizeInKiB"]);
41267
+ if (maxRecordRead.kind === "unusable") if (context?.replayingState === true) this.logger.warn(`${maxRecordRead.reason}. Replaying a state record, so ${streamName} is created with AWS's default maximum record size rather than refusing the restore`);
41268
+ else throw new ProvisioningError(maxRecordRead.reason, resourceType, logicalId, streamName);
41133
41269
  try {
41134
41270
  const streamModeDetails = properties["StreamModeDetails"];
41135
41271
  const streamMode = readConfigString(streamModeDetails, "StreamMode", "PROVISIONED", "AWS::Kinesis::Stream StreamModeDetails");
41136
41272
  const shardCount = streamMode === "PROVISIONED" ? Number(properties["ShardCount"] ?? 1) : void 0;
41273
+ const maxRecordSizeInKiB = maxRecordRead.kind === "usable" ? maxRecordRead.size : void 0;
41137
41274
  await this.getClient().send(new CreateStreamCommand({
41138
41275
  StreamName: streamName,
41139
41276
  ...shardCount !== void 0 && { ShardCount: shardCount },
41140
- StreamModeDetails: { StreamMode: streamMode }
41277
+ StreamModeDetails: { StreamMode: streamMode },
41278
+ ...maxRecordSizeInKiB !== void 0 && { MaxRecordSizeInKiB: maxRecordSizeInKiB }
41141
41279
  }));
41142
41280
  this.logger.debug(`CreateStream initiated for ${streamName}, waiting for ACTIVE status`);
41143
41281
  const streamInfo = await this.waitForStreamActive(streamName);
@@ -41174,10 +41312,21 @@ var KinesisStreamProvider = class {
41174
41312
  }));
41175
41313
  await this.waitForStreamActive(streamName);
41176
41314
  }
41315
+ const desiredMetrics = desiredRead.kind === "usable" ? desiredRead.expanded : void 0;
41316
+ const metricsToEnable = desiredRead.kind === "usable" ? desiredRead.metrics : [];
41317
+ if (metricsToEnable.length > 0) {
41318
+ this.logger.debug(`Enabling ${metricsToEnable.length} shard-level metric(s) on ${streamName}`);
41319
+ await this.getClient().send(new EnableEnhancedMonitoringCommand({
41320
+ StreamName: streamName,
41321
+ ShardLevelMetrics: metricsToEnable
41322
+ }));
41323
+ await this.waitForStreamActive(streamName);
41324
+ }
41177
41325
  this.logger.debug(`Successfully created Kinesis stream ${logicalId}: ${streamName}`);
41178
41326
  return {
41179
41327
  physicalId: streamName,
41180
- attributes: { Arn: streamInfo.streamArn }
41328
+ attributes: { Arn: streamInfo.streamArn },
41329
+ ...this.effectiveMetricsProperties(properties, desiredMetrics)
41181
41330
  };
41182
41331
  } catch (error) {
41183
41332
  if (error instanceof ProvisioningError) throw error;
@@ -41263,10 +41412,49 @@ var KinesisStreamProvider = class {
41263
41412
  await this.waitForStreamActive(physicalId);
41264
41413
  }
41265
41414
  }
41415
+ const desiredSizeRead = readMaxRecordSize(properties["MaxRecordSizeInKiB"]);
41416
+ if (desiredSizeRead.kind === "unusable") this.logger.warn(`${desiredSizeRead.reason}. Leaving the maximum record size on ${physicalId} unchanged; the same value is REFUSED on a template-path create`);
41417
+ const newMaxRecordSize = comparableRecordSize(properties["MaxRecordSizeInKiB"]);
41418
+ const oldMaxRecordSize = comparableRecordSize(previousProperties["MaxRecordSizeInKiB"]);
41419
+ if (newMaxRecordSize !== void 0 && newMaxRecordSize !== oldMaxRecordSize) {
41420
+ this.logger.debug(`Updating max record size for ${physicalId}: ${oldMaxRecordSize} -> ${newMaxRecordSize}`);
41421
+ await this.getClient().send(new UpdateMaxRecordSizeCommand({
41422
+ StreamARN: await this.resolveStreamArn(physicalId),
41423
+ MaxRecordSizeInKiB: newMaxRecordSize
41424
+ }));
41425
+ await this.waitForStreamActive(physicalId);
41426
+ }
41427
+ const desiredRead = readShardLevelMetrics(properties["DesiredShardLevelMetrics"]);
41428
+ let desiredMetrics;
41429
+ if (desiredRead.kind === "unusable") this.logger.warn(`${desiredRead.reason}. Leaving the shard-level metrics on ${physicalId} unchanged rather than disabling the live ones; the same value is REFUSED on a template-path create`);
41430
+ else {
41431
+ desiredMetrics = desiredRead.kind === "usable" ? desiredRead.expanded : void 0;
41432
+ const desiredSet = desiredRead.kind === "usable" ? desiredRead.metrics : [];
41433
+ const previousSet = previousMetricNames(previousProperties["DesiredShardLevelMetrics"]);
41434
+ const toDisable = previousSet.filter((m) => !desiredSet.includes(m));
41435
+ const toEnable = desiredSet.filter((m) => !previousSet.includes(m));
41436
+ if (toDisable.length > 0) {
41437
+ this.logger.debug(`Disabling ${toDisable.length} shard-level metric(s) on ${physicalId}`);
41438
+ await this.getClient().send(new DisableEnhancedMonitoringCommand({
41439
+ StreamName: physicalId,
41440
+ ShardLevelMetrics: toDisable
41441
+ }));
41442
+ await this.waitForStreamActive(physicalId);
41443
+ }
41444
+ if (toEnable.length > 0) {
41445
+ this.logger.debug(`Enabling ${toEnable.length} shard-level metric(s) on ${physicalId}`);
41446
+ await this.getClient().send(new EnableEnhancedMonitoringCommand({
41447
+ StreamName: physicalId,
41448
+ ShardLevelMetrics: toEnable
41449
+ }));
41450
+ await this.waitForStreamActive(physicalId);
41451
+ }
41452
+ }
41266
41453
  return {
41267
41454
  physicalId,
41268
41455
  wasReplaced: false,
41269
- attributes: { Arn: (await this.getClient().send(new DescribeStreamCommand({ StreamName: physicalId }))).StreamDescription?.StreamARN }
41456
+ attributes: { Arn: (await this.getClient().send(new DescribeStreamCommand({ StreamName: physicalId }))).StreamDescription?.StreamARN },
41457
+ ...this.effectiveMetricsProperties(properties, desiredMetrics)
41270
41458
  };
41271
41459
  } catch (error) {
41272
41460
  const cause = error instanceof Error ? error : void 0;
@@ -41295,6 +41483,52 @@ var KinesisStreamProvider = class {
41295
41483
  }
41296
41484
  }
41297
41485
  /**
41486
+ * The `effectiveProperties` half of the `ALL` expansion (issue #609).
41487
+ *
41488
+ * Returns a spreadable `{ effectiveProperties }` ONLY when the expansion
41489
+ * actually rewrote the declared value; otherwise `{}`, so the engine records
41490
+ * the desired bag verbatim (the `??` gate on the engine side treats an absent
41491
+ * field as "record the desired properties"). The returned bag is a COMPLETE
41492
+ * replacement, not a patch, per the `EffectivePropertiesResult` contract.
41493
+ */
41494
+ effectiveMetricsProperties(properties, expanded) {
41495
+ if (expanded === void 0) return {};
41496
+ if (expanded === properties["DesiredShardLevelMetrics"]) return {};
41497
+ return { effectiveProperties: {
41498
+ ...properties,
41499
+ DesiredShardLevelMetrics: expanded
41500
+ } };
41501
+ }
41502
+ /**
41503
+ * Narrow the desired bag the same way the provisioning path does, so the
41504
+ * diff compares the EXPANDED metric list on both sides.
41505
+ *
41506
+ * Required paired half of the `effectiveProperties` above: without it, state
41507
+ * holds the seven expanded names while the template still says `ALL`, and
41508
+ * every later `cdkd deploy` / `cdkd diff` reads that as a user-made change.
41509
+ * Shares {@link expandShardLevelMetrics} rather than re-deriving the rule.
41510
+ */
41511
+ canonicalizeDesiredProperties(resourceType, properties) {
41512
+ if (resourceType !== "AWS::Kinesis::Stream") return properties;
41513
+ if (!("DesiredShardLevelMetrics" in properties)) return properties;
41514
+ const expanded = expandShardLevelMetrics(properties["DesiredShardLevelMetrics"]);
41515
+ if (expanded === properties["DesiredShardLevelMetrics"]) return properties;
41516
+ return {
41517
+ ...properties,
41518
+ DesiredShardLevelMetrics: expanded
41519
+ };
41520
+ }
41521
+ /**
41522
+ * `DesiredShardLevelMetrics` is a SET: AWS returns it in an order that
41523
+ * matched neither the request order nor alphabetical when measured
41524
+ * (us-east-1, 2026-08-12), so comparing positionally would report drift on a
41525
+ * stream nobody touched.
41526
+ */
41527
+ getDriftUnorderedPaths(resourceType) {
41528
+ if (resourceType !== "AWS::Kinesis::Stream") return [];
41529
+ return ["DesiredShardLevelMetrics"];
41530
+ }
41531
+ /**
41298
41532
  * Apply a diff between old and new CFn-shape Tags arrays via Kinesis's
41299
41533
  * `AddTagsToStream` (map shape) / `RemoveTagsFromStream` (TagKeys list)
41300
41534
  * APIs.
@@ -41338,8 +41572,10 @@ var KinesisStreamProvider = class {
41338
41572
  *
41339
41573
  * Issues `DescribeStream` and surfaces the keys cdkd's `create()`
41340
41574
  * accepts: `Name`, `StreamModeDetails`, `ShardCount`, `RetentionPeriodHours`,
41341
- * and `StreamEncryption`. Tags are surfaced via a follow-up
41342
- * `ListTagsForStream` with `aws:*` filtered out.
41575
+ * `StreamEncryption`, and `DesiredShardLevelMetrics`. Tags are surfaced via a
41576
+ * follow-up `ListTagsForStream` with `aws:*` filtered out, and
41577
+ * `MaxRecordSizeInKiB` via a follow-up `DescribeStreamSummary` (the field is
41578
+ * absent from `DescribeStream`'s `StreamDescription` shape).
41343
41579
  *
41344
41580
  * `ShardCount` is reported as the count of `Shards[]` in the stream
41345
41581
  * description (only present for PROVISIONED-mode streams; ON_DEMAND
@@ -41375,6 +41611,14 @@ var KinesisStreamProvider = class {
41375
41611
  if (stream.KeyId !== void 0) encryption["KeyId"] = stream.KeyId;
41376
41612
  result["StreamEncryption"] = encryption;
41377
41613
  }
41614
+ result["DesiredShardLevelMetrics"] = (stream.EnhancedMonitoring ?? []).flatMap((entry) => entry.ShardLevelMetrics ?? []);
41615
+ try {
41616
+ const maxRecordSize = (await this.getClient().send(new DescribeStreamSummaryCommand({ StreamName: physicalId }))).StreamDescriptionSummary?.MaxRecordSizeInKiB;
41617
+ if (maxRecordSize !== void 0) result["MaxRecordSizeInKiB"] = maxRecordSize;
41618
+ } catch (err) {
41619
+ if (err instanceof ResourceNotFoundException$10) return void 0;
41620
+ throw err;
41621
+ }
41378
41622
  try {
41379
41623
  result["Tags"] = normalizeAwsTagsToCfn((await this.getClient().send(new ListTagsForStreamCommand({ StreamName: physicalId }))).Tags);
41380
41624
  } catch (err) {
@@ -72376,7 +72620,7 @@ function createMigrateCommand() {
72376
72620
  */
72377
72621
  function buildProgram() {
72378
72622
  const program = new Command();
72379
- program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.1");
72623
+ program.name("cdkd").description("CDK Direct - Deploy AWS CDK apps directly via SDK/Cloud Control API").version("0.281.2");
72380
72624
  program.hook("preAction", (_thisCommand, actionCommand) => {
72381
72625
  const { profile } = actionCommand.optsWithGlobals();
72382
72626
  if (profile !== void 0) process.env["AWS_PROFILE"] = profile;