@go-to-k/cdkd 0.289.6 → 0.289.8

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.
@@ -1,8 +1,8 @@
1
- import { $ as collectInlinePolicyNamesManagedBySiblings, $n as buildDenyExternalAccessPolicy, $r as DynamicReferenceRegionAmbiguousError, $t as describeTypeWithThrottleRetry, A as isStatefulRecreateTargetForReplace, An as exportNamesCarriedFrom, Ar as CFN_TEMPLATE_URL_LIMIT, At as coerceCfnBoolean, B as gray, Bn as createAssetRedirectResolver, Br as processStackMessages, Bt as classifyReplaySecretRegion, C as refusesFinalSnapshot, Ci as retryClassificationText, Cn as UNRENDERABLE, Cr as resolveSkipPrefix, Ct as isUnboundTemplateParameter, D as makeSiblingClaimReader, Dn as shellQuote, Dr as stateBucketExistenceConfirmed, Dt as normalizeAwsTagsToCfn, E as extractDeploymentEventError, En as forceQuitRecoveryClause, Er as resolveUseCdkBootstrapAssets, Et as WAFv2WebACLProvider, F as isWarmThroughputDecrease, Fn as shouldRetainResource, Fr as expectedOwnerParam, Ft as readConfigString, G as collectPublishedOutputNames, Gn as assertAssetBucketRegion, Gr as resetAwsClients, Gt as s3BucketDualStackDomainName, H as red, Hn as rewriteTemplateAssetReferences, Hr as resolveBucketRegion, Ht as withSharedDrainBudget, I as toFiniteNumber, In as AssetPublisher, Ir as PARTITION_TABLE, It as replayWarn, J as secretBearing, Jn as isCrossRegionRedirect, Jr as CdkdError, Jt as applyRoleArnIfSet, K as exportAliasCollisionScrubWarning, Kn as ensureAssetStorage, Kr as setAwsClients, Kt as s3BucketRegionalDomainName, L as formatResourceLine, Ln as stringifyValue, Lr as canonicalizeRegion, Lt as requireConfigArray, M as renderStatefulReason, Mn as importableOutputs, Mr as findLargeInlineResources, Mt as configBooleanRefusal, N as WARM_THROUGHPUT_MEMBERS, Nn as orphansAfterRollback, Nr as uploadCfnTemplate, Nt as configIntegerRefusal, O as planOrphanAdoption, On as CUSTOM_RESOURCE_RESPONSE_PREFIX, Or as warnDeprecatedNoPrefixCliFlag, Ot as resolveExplicitPhysicalId, P as coerceWarmThroughput$1, Pn as orphansCarriedFrom, Pr as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, Pt as configStringRefusal, Q as IAMRoleProvider, Qn as validateContainerRepoName, Qr as DeployCancelledError, Qt as findSilentDropProperties, R as bold, Rn as WorkGraph, Rr as derivePartitionAndUrlSuffix, Rt as requireConfigObject, S as isFinalSnapshotError, Si as markRedactedCause, Sn as rebuildClientForBucketRegion, Sr as resolveCaptureObservedState, St as getAccountInfo, T as makeCanonicalizePropertiesFn, Tn as buildLockContentionMessage, Tr as resolveStateBucketWithDefaultAndSource, Tt as refStateLookupFromResource, U as yellow, Un as AssetModeResolver, Ur as AwsClients, Ut as s3BucketArn, V as green, Vn as loadPublishableAssetManifest, Vt as producerRegionsFromState, W as collectDeclaredOutputNames, Wn as BOOTSTRAP_MARKER_PREFIX, Wr as getAwsClients, Wt as s3BucketDomainName, X as secretSafeKeyDisplay, Xn as readBootstrapMarkerBody, Xr as CrossAccountSecretRefusalError, Xt as INTRINSIC_KEYS, Y as secretBearingStateKeyWarning, Yn as parseBootstrapMarker, Yt as DiffCalculator, Z as getCurrentResourceSecrets, Zn as validateAssetBucketName, Zt as findActionableSilentDrops, _ as ATOMIC_FINAL_SNAPSHOT_TYPES, _i as isMarkedNonRetryable, _n as recoverMaskedOutput, _r as synthesisStatusMessage, _t as isTerminationProtectionPropagationError, a as DeploymentEventsStore, ai as PartialFailureError, an as STATE_SOURCED_READBACK_RULES, ar as dockerSpawnEnvWithSensitive, at as maskerOrIdentity, b as ccRoutedFinalSnapshotError, bi as isTransientServerError, bn as LockManager, br as resolveApp, bt as cfnRefValueFromPhysicalId, c as replayFailedOperations, ci as ResourceUpdateNotSupportedError, cn as createSecretMasker, cr as partitionSensitiveEnv, ct as interruptWatchListenerCount, d as updatePartialReason, dn as identityKeyFor, dr as runDockerStreaming, dt as CloudControlProvider, ei as IntrinsicResolutionRefusalError, en as withRetry, er as describeAwsFailure, et as clearOnUpdateRemoval, f as withResourceDeadline, fn as isSingleDynamicReferenceToken, fr as escapeRegExp, ft as slowCcOperationTimeoutMs, g as bindingSkippedOutputs, gi as withErrorHandling, gn as recordMaskOnlyValue, gr as Synthesizer, gt as disableInstanceApiTermination, h as computeImplicitDeleteEdges, hi as normalizeAwsError, hn as maskSecretsInText, hr as getDockerImageBySourceHash, ht as deleteSkipReason, i as DeploymentEventsReader, ii as NestedStackChildDirectDestroyError, in as STATE_SOURCED_CROSS_GENERATION_RULES, ir as describeDockerFailure, it as maskDeep, j as isStatefulRecreateTargetSync, jn as importableOutputKeys, jr as MIGRATE_TMP_PREFIX, jt as coerceCfnInteger, k as MULTI_REGION_RECREATE_BLOCKED_TYPES, kn as DEFAULT_STATE_PREFIX, kr as CFN_TEMPLATE_BODY_LIMIT, kt as assertRegionMatch, l as replayRollback, li as StackHasActiveImportsError, ln as dynamicReferenceTokens, lr as redactDockerArgvValues, lt as isInterruptedWaitError, m as IMPLICIT_DELETE_DEPENDENCIES, mn as maskSecretsInError, mr as AssetManifestLoader, mt as deleteIndeterminateGuards, n as DEFAULT_RESOURCE_WARN_AFTER_MS, ni as LocalStartServiceError, nn as TemplateParser, nr as describeDockerCapturedOutput, nt as wouldReturnToSdkProvider, o as planFailedOps, oi as ProvisioningError, on as TEMPLATE_SOURCED_RULES, or as formatDockerLoginError, ot as beginCommandInterruptScope, p as maskingRetryLogger, pn as markSameGenerationBag, pr as stripControlChars, pt as UNSPECIFIED_SKIP_REASON, q as isExportAliasCollision, qn as getBootstrapMarkerKey, qt as s3BucketWebsiteUrl, r as DeployEngine, rn as STATE_SOURCED_BASELINE_RULES, rr as describeDockerExecFailure, rt as createMaskedRetryLogger, s as planRollback, si as ResourceTimeoutError, sn as carriesSecretMask, sr as getDockerCmd, st as endCommandInterruptScope, t as DEFAULT_RESOURCE_TIMEOUT_MS, ti as LocalInvokeBuildError$1, tn as DagBuilder, tr as buildDockerImage, tt as ProviderRegistry, u as updatePartialMessage, ui as StackTerminationProtectionError, un as errorCauseChain, ur as runDockerForeground, ut as startInterruptWatch, v as PRE_DELETE_SNAPSHOT_TYPES, vi as isRetryableTransientError, vn as redactSecretsForState, vr as getDefaultStateBucketName, vt as IntrinsicFunctionResolver, w as unsupportedFinalSnapshotError, wn as buildForceUnlockCommand, wr as resolveStateBucketWithDefault, wt as parameterTypeMayLoseSecretIdentity, x as createPreDeleteFinalSnapshot, xi as markNonRetryable, xn as S3StateBackend, xr as resolveAutoAssetStorage, xt as coerceParameterTypedValue, y as buildFinalSnapshotIdentifier, yi as isThrottlingError, yn as scrubResourceRecord, yr as getLegacyStateBucketName, yt as carriesDynamicReference, z as cyan, zn as buildAssetRedirectMap, zr as AssemblyReader, zt as requireConfigString } from "./deploy-engine-CpmvgRtm.js";
2
- import { _ as withSkipPrefix, b as truncateCodePoints, c as PATTERN_B_NAME_OPTIONS, f as explicitNamePropertyFor, h as getCurrentStackName, i as reserveStdoutForPayload, l as PATTERN_B_NAME_PROPERTIES, m as generateResourceNameWithFallback, n as getLogger, o as runStackBuffered, p as generateResourceName, s as getLiveRenderer, u as PATTERN_B_RESOURCE_TYPES, v as withStackName, y as displaySafe } from "./logger-BK-B0slT.js";
1
+ import { $ as collectInlinePolicyNamesManagedBySiblings, $n as buildDenyExternalAccessPolicy, $r as DynamicReferenceRegionAmbiguousError, $t as describeTypeWithThrottleRetry, A as isStatefulRecreateTargetForReplace, An as exportNamesCarriedFrom, Ar as CFN_TEMPLATE_URL_LIMIT, At as coerceCfnBoolean, B as gray, Bn as createAssetRedirectResolver, Br as processStackMessages, Bt as classifyReplaySecretRegion, C as refusesFinalSnapshot, Ci as retryClassificationText, Cn as buildForceUnlockCommand, Cr as resolveSkipPrefix, Ct as isUnboundTemplateParameter, D as makeSiblingClaimReader, Dn as shellQuote, Dr as stateBucketExistenceConfirmed, Dt as normalizeAwsTagsToCfn, E as extractDeploymentEventError, En as formatLockExpiry, Er as resolveUseCdkBootstrapAssets, Et as WAFv2WebACLProvider, F as isWarmThroughputDecrease, Fn as shouldRetainResource, Fr as expectedOwnerParam, Ft as readConfigString, G as collectPublishedOutputNames, Gn as assertAssetBucketRegion, Gr as resetAwsClients, Gt as s3BucketDualStackDomainName, H as red, Hn as rewriteTemplateAssetReferences, Hr as resolveBucketRegion, Ht as withSharedDrainBudget, I as toFiniteNumber, In as AssetPublisher, Ir as PARTITION_TABLE, It as replayWarn, J as secretBearing, Jn as isCrossRegionRedirect, Jr as CdkdError, Jt as applyRoleArnIfSet, K as exportAliasCollisionScrubWarning, Kn as ensureAssetStorage, Kr as setAwsClients, Kt as s3BucketRegionalDomainName, L as formatResourceLine, Ln as stringifyValue, Lr as canonicalizeRegion, Lt as requireConfigArray, M as renderStatefulReason, Mn as importableOutputs, Mr as findLargeInlineResources, Mt as configBooleanRefusal, N as WARM_THROUGHPUT_MEMBERS, Nn as orphansAfterRollback, Nr as uploadCfnTemplate, Nt as configIntegerRefusal, O as planOrphanAdoption, On as CUSTOM_RESOURCE_RESPONSE_PREFIX, Or as warnDeprecatedNoPrefixCliFlag, Ot as resolveExplicitPhysicalId, P as coerceWarmThroughput$1, Pn as orphansCarriedFrom, Pr as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, Pt as configStringRefusal, Q as IAMRoleProvider, Qn as validateContainerRepoName, Qr as DeployCancelledError, Qt as findSilentDropProperties, R as bold, Rn as WorkGraph, Rr as derivePartitionAndUrlSuffix, Rt as requireConfigObject, S as isFinalSnapshotError, Si as markRedactedCause, Sn as rebuildClientForBucketRegion, Sr as resolveCaptureObservedState, St as getAccountInfo, T as makeCanonicalizePropertiesFn, Tn as forceQuitRecoveryClause, Tr as resolveStateBucketWithDefaultAndSource, Tt as refStateLookupFromResource, U as yellow, Un as AssetModeResolver, Ur as AwsClients, Ut as s3BucketArn, V as green, Vn as loadPublishableAssetManifest, Vt as producerRegionsFromState, W as collectDeclaredOutputNames, Wn as BOOTSTRAP_MARKER_PREFIX, Wr as getAwsClients, Wt as s3BucketDomainName, X as secretSafeKeyDisplay, Xn as readBootstrapMarkerBody, Xr as CrossAccountSecretRefusalError, Xt as INTRINSIC_KEYS, Y as secretBearingStateKeyWarning, Yn as parseBootstrapMarker, Yt as DiffCalculator, Z as getCurrentResourceSecrets, Zn as validateAssetBucketName, Zt as findActionableSilentDrops, _ as ATOMIC_FINAL_SNAPSHOT_TYPES, _i as isMarkedNonRetryable, _n as recoverMaskedOutput, _r as synthesisStatusMessage, _t as isTerminationProtectionPropagationError, a as DeploymentEventsStore, ai as PartialFailureError, an as STATE_SOURCED_READBACK_RULES, ar as dockerSpawnEnvWithSensitive, at as maskerOrIdentity, b as ccRoutedFinalSnapshotError, bi as isTransientServerError, bn as LockManager, br as resolveApp, bt as cfnRefValueFromPhysicalId, c as replayFailedOperations, ci as ResourceUpdateNotSupportedError, cn as createSecretMasker, cr as partitionSensitiveEnv, ct as interruptWatchListenerCount, d as updatePartialReason, dn as identityKeyFor, dr as runDockerStreaming, dt as CloudControlProvider, ei as IntrinsicResolutionRefusalError, en as withRetry, er as describeAwsFailure, et as clearOnUpdateRemoval, f as withResourceDeadline, fn as isSingleDynamicReferenceToken, fr as escapeRegExp, ft as slowCcOperationTimeoutMs, g as bindingSkippedOutputs, gi as withErrorHandling, gn as recordMaskOnlyValue, gr as Synthesizer, gt as disableInstanceApiTermination, h as computeImplicitDeleteEdges, hi as normalizeAwsError, hn as maskSecretsInText, hr as getDockerImageBySourceHash, ht as deleteSkipReason, i as DeploymentEventsReader, ii as NestedStackChildDirectDestroyError, in as STATE_SOURCED_CROSS_GENERATION_RULES, ir as describeDockerFailure, it as maskDeep, j as isStatefulRecreateTargetSync, jn as importableOutputKeys, jr as MIGRATE_TMP_PREFIX, jt as coerceCfnInteger, k as MULTI_REGION_RECREATE_BLOCKED_TYPES, kn as DEFAULT_STATE_PREFIX, kr as CFN_TEMPLATE_BODY_LIMIT, kt as assertRegionMatch, l as replayRollback, li as StackHasActiveImportsError, ln as dynamicReferenceTokens, lr as redactDockerArgvValues, lt as isInterruptedWaitError, m as IMPLICIT_DELETE_DEPENDENCIES, mn as maskSecretsInError, mr as AssetManifestLoader, mt as deleteIndeterminateGuards, n as DEFAULT_RESOURCE_WARN_AFTER_MS, ni as LocalStartServiceError, nn as TemplateParser, nr as describeDockerCapturedOutput, nt as wouldReturnToSdkProvider, o as planFailedOps, oi as ProvisioningError, on as TEMPLATE_SOURCED_RULES, or as formatDockerLoginError, ot as beginCommandInterruptScope, p as maskingRetryLogger, pn as markSameGenerationBag, pr as stripControlChars, pt as UNSPECIFIED_SKIP_REASON, q as isExportAliasCollision, qn as getBootstrapMarkerKey, qt as s3BucketWebsiteUrl, r as DeployEngine, rn as STATE_SOURCED_BASELINE_RULES, rr as describeDockerExecFailure, rt as createMaskedRetryLogger, s as planRollback, si as ResourceTimeoutError, sn as carriesSecretMask, sr as getDockerCmd, st as endCommandInterruptScope, t as DEFAULT_RESOURCE_TIMEOUT_MS, ti as LocalInvokeBuildError$1, tn as DagBuilder, tr as buildDockerImage, tt as ProviderRegistry, u as updatePartialMessage, ui as StackTerminationProtectionError, un as errorCauseChain, ur as runDockerForeground, ut as startInterruptWatch, v as PRE_DELETE_SNAPSHOT_TYPES, vi as isRetryableTransientError, vn as redactSecretsForState, vr as getDefaultStateBucketName, vt as IntrinsicFunctionResolver, w as unsupportedFinalSnapshotError, wn as buildLockContentionMessage, wr as resolveStateBucketWithDefault, wt as parameterTypeMayLoseSecretIdentity, x as createPreDeleteFinalSnapshot, xi as markNonRetryable, xn as S3StateBackend, xr as resolveAutoAssetStorage, xt as coerceParameterTypedValue, y as buildFinalSnapshotIdentifier, yi as isThrottlingError, yn as scrubResourceRecord, yr as getLegacyStateBucketName, yt as carriesDynamicReference, z as cyan, zn as buildAssetRedirectMap, zr as AssemblyReader, zt as requireConfigString } from "./deploy-engine-zEwQVCh8.js";
2
+ import { _ as withSkipPrefix, b as displaySafe, c as PATTERN_B_NAME_OPTIONS, f as explicitNamePropertyFor, h as getCurrentStackName, i as reserveStdoutForPayload, l as PATTERN_B_NAME_PROPERTIES, m as generateResourceNameWithFallback, n as getLogger, o as runStackBuffered, p as generateResourceName, s as getLiveRenderer, u as PATTERN_B_RESOURCE_TYPES, v as withStackName, x as truncateCodePoints, y as UNRENDERABLE } from "./logger-DTEUzYP_.js";
3
3
  import { t as awsClientDefaults } from "./aws-client-defaults-D-iYiIJ6.js";
4
- import { t as getCdkdVersion } from "./version-DCxqZhgp.js";
5
- import { r as protectedReplacementAdvice, t as ASGProvider } from "./asg-provider-eIVYMrmW.js";
4
+ import { t as getCdkdVersion } from "./version-DWnjHtUC.js";
5
+ import { r as protectedReplacementAdvice, t as ASGProvider } from "./asg-provider-D2lf-Qdo.js";
6
6
  import { AsyncLocalStorage } from "node:async_hooks";
7
7
  import { createHash, randomBytes, randomUUID } from "node:crypto";
8
8
  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, NotFound, 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";
@@ -24300,6 +24300,109 @@ function requireSecretStringShape(literal) {
24300
24300
  throw new Error(`SecretString must be a string, got ${literal === null ? "null" : Array.isArray(literal) ? "array" : typeof literal}`);
24301
24301
  }
24302
24302
  /**
24303
+ * The character classes a `GenerateSecretString` block leaves available,
24304
+ * after the `Exclude*` switches and `ExcludeCharacters` (issue #3068), or the
24305
+ * refusal that says why no password can be minted from it. ONE function for
24306
+ * the predicate and the generator, so the shapes the predicate refuses are
24307
+ * exactly the shapes the generator cannot serve.
24308
+ *
24309
+ * The caller has already run the member SHAPE predicates (`ExcludeCharacters`
24310
+ * is a string or absent, the booleans coerce, `PasswordLength` is an integer
24311
+ * in range) — this function reads the block by cast on that precondition.
24312
+ *
24313
+ * Three refusals, each MEASURED on CloudFormation (us-east-1, 2026-09-14): the
24314
+ * docs give the default (`RequireEachIncludedType` on) and the four-type
24315
+ * wording, but none of the refusal shapes or their messages:
24316
+ *
24317
+ * - `RequireEachIncludedType` defaults to TRUE and covers the four classes
24318
+ * (upper, lower, number, punctuation) that are not switched off; a space is
24319
+ * never required, only admitted. With it on, a class the `Exclude*` switch
24320
+ * keeps but `ExcludeCharacters` empties is refused: `All characters of the
24321
+ * desired type have been excluded`. With it OFF the same template CREATES
24322
+ * (measured), so the refusal is scoped to REQUIRED classes.
24323
+ * - With it on, `PasswordLength` below the number of required classes is
24324
+ * refused: `Password length is too short based on the required types`.
24325
+ * - A pool with no character at all is refused: `All characters have been
24326
+ * excluded from selection`. The old local fallback to lowercase invented a
24327
+ * charset the template had excluded.
24328
+ */
24329
+ function generateCharset(config) {
24330
+ const PUNCTUATION = "!\"#$%&'()*+,-./:;<=>?@[\\]^_" + String.fromCharCode(96) + "{|}~";
24331
+ const off = (key) => coerceCfnBoolean(config[key]) ?? false;
24332
+ const excluded = new Set(config["ExcludeCharacters"] ?? "");
24333
+ const strip = (chars) => [...chars].filter((c) => !excluded.has(c)).join("");
24334
+ const classes = [
24335
+ [
24336
+ "uppercase",
24337
+ strip("ABCDEFGHIJKLMNOPQRSTUVWXYZ"),
24338
+ "ExcludeUppercase"
24339
+ ],
24340
+ [
24341
+ "lowercase",
24342
+ strip("abcdefghijklmnopqrstuvwxyz"),
24343
+ "ExcludeLowercase"
24344
+ ],
24345
+ [
24346
+ "number",
24347
+ strip("0123456789"),
24348
+ "ExcludeNumbers"
24349
+ ],
24350
+ [
24351
+ "punctuation",
24352
+ strip(PUNCTUATION),
24353
+ "ExcludePunctuation"
24354
+ ]
24355
+ ];
24356
+ const requireEach = coerceCfnBoolean(config["RequireEachIncludedType"]) ?? true;
24357
+ const included = classes.filter(([, , switchKey]) => !off(switchKey));
24358
+ const required = [];
24359
+ if (requireEach) for (const [name, chars, switchKey] of included) {
24360
+ if (chars.length === 0) return {
24361
+ required: [],
24362
+ pool: "",
24363
+ refusal: `all characters of the ${name} type have been excluded while RequireEachIncludedType requires one (exclude the type with ${switchKey} instead)`
24364
+ };
24365
+ required.push(chars);
24366
+ }
24367
+ const space = (coerceCfnBoolean(config["IncludeSpace"]) ?? false) && !excluded.has(" ") ? " " : "";
24368
+ const pool = included.map(([, chars]) => chars).join("") + space;
24369
+ if (pool.length === 0) return {
24370
+ required: [],
24371
+ pool: "",
24372
+ refusal: "all characters have been excluded from selection, so no password can be generated"
24373
+ };
24374
+ const length = coerceCfnInteger(config["PasswordLength"]) ?? 32;
24375
+ if (required.length > length) return {
24376
+ required: [],
24377
+ pool: "",
24378
+ refusal: `PasswordLength ${length} is too short for the ${required.length} character types RequireEachIncludedType requires`
24379
+ };
24380
+ return {
24381
+ required,
24382
+ pool
24383
+ };
24384
+ }
24385
+ /**
24386
+ * A uniformly distributed index below `n`, by rejection: a raw draw taken
24387
+ * modulo `n` biases toward the low indexes whenever the draw's range is not
24388
+ * a multiple of `n` (2^32 never is for a 26- or 32-character class), and a
24389
+ * password generator should not.
24390
+ * The rejection IS fenced, deterministically: the unit suite stubs
24391
+ * `crypto.getRandomValues` to hand back a draw at or above `limit` and then
24392
+ * one below it, and asserts the first is thrown away (a `% n` shortcut would
24393
+ * mint from it). The bias itself is about 1 part in 2^32 / n per index at
24394
+ * this width — negligible either way; the rejection makes it zero.
24395
+ */
24396
+ function randomIndex(n) {
24397
+ if (!Number.isInteger(n) || n <= 0) throw new Error(`randomIndex: range must be a positive integer (got ${n})`);
24398
+ const limit = Math.floor(4294967296 / n) * n;
24399
+ const draw = /* @__PURE__ */ new Uint32Array(1);
24400
+ for (;;) {
24401
+ crypto.getRandomValues(draw);
24402
+ if (draw[0] < limit) return draw[0] % n;
24403
+ }
24404
+ }
24405
+ /**
24303
24406
  * The refusal for the MEMBERS of a `GenerateSecretString` block whose container
24304
24407
  * has already passed `requireConfigObject` (issue #3056), or `undefined` when
24305
24408
  * every member is usable. ONE predicate for two readers — the generator, which
@@ -24328,8 +24431,10 @@ function requireSecretStringShape(literal) {
24328
24431
  */
24329
24432
  function generateMemberRefusal(config) {
24330
24433
  const P = "AWS::SecretsManager::Secret GenerateSecretString";
24331
- const shape = configIntegerRefusal(config, "PasswordLength", P, 1, 4096) ?? configBooleanRefusal(config, "ExcludeUppercase", P) ?? configBooleanRefusal(config, "ExcludeLowercase", P) ?? configBooleanRefusal(config, "ExcludeNumbers", P) ?? configBooleanRefusal(config, "ExcludePunctuation", P) ?? configStringRefusal(config, "ExcludeCharacters", "", P) ?? configStringRefusal(config, "GenerateStringKey", "required", P) ?? configStringRefusal(config, "SecretStringTemplate", "required", P);
24434
+ const shape = configIntegerRefusal(config, "PasswordLength", P, 1, 4096) ?? configBooleanRefusal(config, "ExcludeUppercase", P) ?? configBooleanRefusal(config, "ExcludeLowercase", P) ?? configBooleanRefusal(config, "ExcludeNumbers", P) ?? configBooleanRefusal(config, "ExcludePunctuation", P) ?? configBooleanRefusal(config, "IncludeSpace", P) ?? configBooleanRefusal(config, "RequireEachIncludedType", P) ?? configStringRefusal(config, "ExcludeCharacters", "", P) ?? configStringRefusal(config, "GenerateStringKey", "required", P) ?? configStringRefusal(config, "SecretStringTemplate", "required", P);
24332
24435
  if (shape !== void 0) return shape;
24436
+ const charset = generateCharset(config);
24437
+ if (charset.refusal !== void 0) return `${P}: ${charset.refusal}`;
24333
24438
  const key = config["GenerateStringKey"];
24334
24439
  const template = config["SecretStringTemplate"];
24335
24440
  if (key === void 0 && template === void 0) return void 0;
@@ -24685,10 +24790,11 @@ var SecretsManagerSecretProvider = class {
24685
24790
  * With no `onUnusable` a refusal THROWS (the create path, where the block
24686
24791
  * is template-borne). With one, the message is handed over and `undefined`
24687
24792
  * is returned — the update path's SKIP, decided by the caller, so that this
24688
- * function never mints from a block it could not read. The two members the
24689
- * schema declares that this recipe does not implement, `IncludeSpace` and
24690
- * `RequireEachIncludedType`, are a separate fidelity gap (issue #3068), not
24691
- * a shape question.
24793
+ * function never mints from a block it could not read. The recipe itself —
24794
+ * the four classes, the service's punctuation set, `IncludeSpace`, and the
24795
+ * `RequireEachIncludedType` guarantee — lives in `generateCharset` (issue
24796
+ * #3068), shared with the predicate so the block it refuses and the block
24797
+ * it mints from cannot disagree.
24692
24798
  */
24693
24799
  generateSecretString(config, options) {
24694
24800
  const refusal = generateMemberRefusal(config);
@@ -24700,22 +24806,15 @@ var SecretsManagerSecretProvider = class {
24700
24806
  throw new Error(refusal);
24701
24807
  }
24702
24808
  const length = coerceCfnInteger(config["PasswordLength"]) ?? 32;
24703
- const excludeUppercase = coerceCfnBoolean(config["ExcludeUppercase"]) ?? false;
24704
- const excludeLowercase = coerceCfnBoolean(config["ExcludeLowercase"]) ?? false;
24705
- const excludeNumbers = coerceCfnBoolean(config["ExcludeNumbers"]) ?? false;
24706
- const excludePunctuation = coerceCfnBoolean(config["ExcludePunctuation"]) ?? false;
24707
- const excludeCharacters = config["ExcludeCharacters"] ?? "";
24708
- let chars = "";
24709
- if (!excludeUppercase) chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
24710
- if (!excludeLowercase) chars += "abcdefghijklmnopqrstuvwxyz";
24711
- if (!excludeNumbers) chars += "0123456789";
24712
- if (!excludePunctuation) chars += "!@#$%^&*()_+-=[]{}|;:,.<>?";
24713
- if (excludeCharacters) for (const c of excludeCharacters) chars = chars.replaceAll(c, "");
24714
- if (chars.length === 0) chars = "abcdefghijklmnopqrstuvwxyz";
24715
- const bytes = new Uint8Array(length);
24716
- crypto.getRandomValues(bytes);
24717
- let password = "";
24718
- for (let i = 0; i < length; i++) password += chars[bytes[i] % chars.length];
24809
+ const { required, pool } = generateCharset(config);
24810
+ const out = [];
24811
+ for (let i = 0; i < length; i++) out.push(pool[randomIndex(pool.length)]);
24812
+ const positions = Array.from({ length }, (_, i) => i);
24813
+ for (const classChars of required) {
24814
+ const slot = positions.splice(randomIndex(positions.length), 1)[0];
24815
+ out[slot] = classChars[randomIndex(classChars.length)];
24816
+ }
24817
+ const password = out.join("");
24719
24818
  const generateStringKey = config["GenerateStringKey"];
24720
24819
  const secretStringTemplate = config["SecretStringTemplate"];
24721
24820
  if (generateStringKey === void 0 || secretStringTemplate === void 0) return password;
@@ -76659,7 +76758,7 @@ function formatStackRef(ref) {
76659
76758
  * `()` would read as "no region" rather than "a region cdkd will not print".
76660
76759
  */
76661
76760
  function formatStackRefSafe(ref) {
76662
- return ref.region ? `${safe(ref.stackName)} (${safe(ref.region)})` : safe(ref.stackName);
76761
+ return ref.region ? `${safe$1(ref.stackName)} (${safe$1(ref.region)})` : safe$1(ref.stackName);
76663
76762
  }
76664
76763
  /**
76665
76764
  * One spelling of "this value came from an S3 key or a state record, and is
@@ -76685,7 +76784,7 @@ function formatStackRefSafe(ref) {
76685
76784
  * text (a parser's own message, an AWS error) takes the denylist class
76686
76785
  * instead; `display-safe.ts`'s header draws that line.
76687
76786
  */
76688
- function safe(value) {
76787
+ function safe$1(value) {
76689
76788
  return displaySafe(value, { asciiOnly: true }) || "<unrenderable>";
76690
76789
  }
76691
76790
  /**
@@ -76696,18 +76795,18 @@ function safe(value) {
76696
76795
  */
76697
76796
  function resolveSingleRegion(stackName, refs, requestedRegion) {
76698
76797
  const matches = refs.filter((r) => r.stackName === stackName);
76699
- if (matches.length === 0) throw new Error(`No state found for stack '${safe(stackName)}'. Run 'cdkd state list' to see available stacks.`);
76798
+ if (matches.length === 0) throw new Error(`No state found for stack '${safe$1(stackName)}'. Run 'cdkd state list' to see available stacks.`);
76700
76799
  if (requestedRegion) {
76701
76800
  const ref = matches.find((r) => r.region === requestedRegion);
76702
76801
  if (!ref) {
76703
- const seen = matches.map((r) => r.region === void 0 ? "(legacy)" : safe(r.region));
76704
- throw new Error(`No state found for stack '${safe(stackName)}' in region '${safe(requestedRegion)}'. Available regions: ${seen.join(", ")}.`);
76802
+ const seen = matches.map((r) => r.region === void 0 ? "(legacy)" : safe$1(r.region));
76803
+ throw new Error(`No state found for stack '${safe$1(stackName)}' in region '${safe$1(requestedRegion)}'. Available regions: ${seen.join(", ")}.`);
76705
76804
  }
76706
76805
  return ref;
76707
76806
  }
76708
76807
  if (matches.length === 1) return matches[0];
76709
- const regions = matches.map((r) => r.region === void 0 ? "(legacy)" : safe(r.region));
76710
- throw new Error(`Stack '${safe(stackName)}' has state in multiple regions: ${regions.join(", ")}. Re-run with --stack-region <region> to disambiguate.`);
76808
+ const regions = matches.map((r) => r.region === void 0 ? "(legacy)" : safe$1(r.region));
76809
+ throw new Error(`Stack '${safe$1(stackName)}' has state in multiple regions: ${regions.join(", ")}. Re-run with --stack-region <region> to disambiguate.`);
76711
76810
  }
76712
76811
  /**
76713
76812
  * Shared bootstrap for every `state` subcommand: build the AWS clients,
@@ -76928,9 +77027,9 @@ async function stateResourcesCommand(stackName, options) {
76928
77027
  const setup = await setupStateBackend(options);
76929
77028
  try {
76930
77029
  const ref = resolveSingleRegion(stackName, await setup.stateBackend.listStacks(), options.stackRegion);
76931
- if (!ref.region) throw new Error(`Stack '${safe(stackName)}' has only a legacy state record without a region. Run 'cdkd deploy ${safe(stackName)}' (or any cdkd write) to migrate it to the region-scoped layout, then re-run this command.`);
77030
+ if (!ref.region) throw new Error(`Stack '${safe$1(stackName)}' has only a legacy state record without a region. Run 'cdkd deploy ${safe$1(stackName)}' (or any cdkd write) to migrate it to the region-scoped layout, then re-run this command.`);
76932
77031
  const stateResult = await setup.stateBackend.getState(stackName, ref.region);
76933
- if (!stateResult) throw new Error(`No state found for stack '${safe(stackName)}' (${safe(ref.region)}) in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`);
77032
+ if (!stateResult) throw new Error(`No state found for stack '${safe$1(stackName)}' (${safe$1(ref.region)}) in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`);
76934
77033
  const resources = stateResult.state.resources ?? {};
76935
77034
  const details = Object.entries(resources).map(([logicalId, entry]) => {
76936
77035
  const resource = entry ?? {};
@@ -77025,14 +77124,6 @@ function formatAttributeValue(value) {
77025
77124
  return json === void 0 ? UNSERIALIZABLE : stripControlChars(json);
77026
77125
  }
77027
77126
  /**
77028
- * Render a duration in milliseconds as `1m23s` / `45s`.
77029
- */
77030
- function formatDuration(ms) {
77031
- const seconds = Math.floor(ms / 1e3);
77032
- if (seconds < 60) return `${seconds}s`;
77033
- return `${Math.floor(seconds / 60)}m${seconds % 60}s`;
77034
- }
77035
- /**
77036
77127
  * Render a whole `Dependencies` row from a list that is an unchecked cast.
77037
77128
  *
77038
77129
  * It owns the `(none)` case as well as the values, so that no caller touches
@@ -77089,17 +77180,19 @@ function formatLastModified(value) {
77089
77180
  * falls back to `Object.prototype.toString` (go-to-k/cdkd#2947).
77090
77181
  *
77091
77182
  * `expiresAt` is declared a number and is not guaranteed to be one, but it
77092
- * reaches the row only through subtraction and `formatDuration`, so no character
77093
- * the record carries can survive into the output either. One that cannot be
77094
- * coerced arrives as `NaN` (`getLockRecord`), so the row reads as expired
77095
- * rather than the read throwing.
77183
+ * reaches the row only through `formatLockExpiry`, which tests the raw value
77184
+ * with `Number.isFinite` and renders a fixed phrase or a duration, so no
77185
+ * character the record carries can survive into the output either. A
77186
+ * non-finite value — absent, `{}`, `"soon"`, or the `NaN` that `getLockRecord`
77187
+ * substitutes for a coercion that throws (go-to-k/cdkd#2947) — reads as an
77188
+ * unknown deadline rather than `expired NaNmNaNs ago` (issue #3083); the
77189
+ * helper is shared with the contention refusal and `LockManager` (issue
77190
+ * #3085) so the row cannot drift from them.
77096
77191
  */
77097
77192
  function formatLockSummary(lockInfo) {
77098
77193
  if (!lockInfo) return "unlocked";
77099
77194
  const opStr = lockInfo.operation ? ` (operation: ${lockInfo.operation})` : "";
77100
- const expiresInMs = lockInfo.expiresAt - Date.now();
77101
- const expiresStr = expiresInMs > 0 ? `expires in ${formatDuration(expiresInMs)}` : `expired ${formatDuration(-expiresInMs)} ago`;
77102
- return `locked by ${lockInfo.owner}${opStr}, ${expiresStr}`;
77195
+ return `locked by ${lockInfo.owner}${opStr}, ${formatLockExpiry(lockInfo.expiresAt)}`;
77103
77196
  }
77104
77197
  /**
77105
77198
  * Create the `state resources` subcommand.
@@ -77139,9 +77232,9 @@ async function stateShowCommand(stackName, options) {
77139
77232
  const setup = await setupStateBackend(options);
77140
77233
  try {
77141
77234
  const ref = resolveSingleRegion(stackName, await setup.stateBackend.listStacks(), options.stackRegion);
77142
- if (!ref.region) throw new Error(`Stack '${safe(stackName)}' has only a legacy state record without a region. Run 'cdkd deploy ${safe(stackName)}' (or any cdkd write) to migrate it to the region-scoped layout, then re-run this command.`);
77235
+ if (!ref.region) throw new Error(`Stack '${safe$1(stackName)}' has only a legacy state record without a region. Run 'cdkd deploy ${safe$1(stackName)}' (or any cdkd write) to migrate it to the region-scoped layout, then re-run this command.`);
77143
77236
  const [stateResult, lockInfo] = await Promise.all([setup.stateBackend.getState(stackName, ref.region), setup.lockManager.getLockInfo(stackName, ref.region)]);
77144
- if (!stateResult) throw new Error(`No state found for stack '${safe(stackName)}' (${safe(ref.region)}) in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`);
77237
+ if (!stateResult) throw new Error(`No state found for stack '${safe$1(stackName)}' (${safe$1(ref.region)}) in s3://${setup.bucket}/${setup.prefix}/. Run 'cdkd state list' to see available stacks.`);
77145
77238
  if (options.showNested) {
77146
77239
  const treeWithLocks = await loadLocksForTree(await buildCdkdStateStackTree(stackName, ref.region, setup.stateBackend, stateResult.state), setup.lockManager, lockInfo);
77147
77240
  if (options.json) {
@@ -78306,6 +78399,35 @@ function snapshotNote(resourceType, effectiveProvisionedBy, skipFinalSnapshot) {
78306
78399
  return "DeletionPolicy Snapshot — final snapshot, then delete";
78307
78400
  }
78308
78401
  /**
78402
+ * One spelling of "this value came from an S3 key or a rollback-journal record,
78403
+ * and is about to be interpolated into a message a terminal will render"
78404
+ * (issue #3064).
78405
+ *
78406
+ * `rollback-journal.json` is a sibling of `state.json` in the same bucket, so
78407
+ * anyone with `s3:PutObject` writes it, and cdkd's output is line-oriented --
78408
+ * an injected newline invents a line that reads like a real one. Here that is
78409
+ * worse than a forged diagnostic: the plan preview below is what the user
78410
+ * CONFIRMS against, so a planted journal could forge the plan rows themselves.
78411
+ *
78412
+ * The ASCII allowlist, because every value it guards has a known charset: a
78413
+ * logical id, a CFn resource type, a change type, a run id, a segment reason,
78414
+ * a stack name, an AWS region. Call it for those; `grep safe(` answers the
78415
+ * scope and this comment does not.
78416
+ *
78417
+ * NOT for a value that is about to be USED rather than shown -- the preview
78418
+ * indexes `previewState` by the RAW `op.logicalId`, and sanitising a lookup
78419
+ * key silently mismatches the record it is meant to find.
78420
+ *
78421
+ * NOT for free-form error text either. An SDK or provider message legitimately
78422
+ * carries non-ASCII (a resource name, AWS's own wording), so a site that renders
78423
+ * one calls `displaySafe()` directly and takes the DENYLIST -- the same class
78424
+ * `formatError` picks for a `cause`, and for the same reason. `grep displaySafe(`
78425
+ * answers how many; a count written here was wrong on its first revision.
78426
+ */
78427
+ function safe(value) {
78428
+ return displaySafe(value, { asciiOnly: true }) || "<unrenderable>";
78429
+ }
78430
+ /**
78309
78431
  * Human label for a planned rollback action (plan preview). `skipFinalSnapshot`
78310
78432
  * is threaded in because the classifier is pure (it cannot see CLI flags) and
78311
78433
  * the Snapshot label would otherwise promise a final snapshot the run is about
@@ -78315,17 +78437,17 @@ function actionLabel(item, skipFinalSnapshot) {
78315
78437
  const { op, action, replacement } = item;
78316
78438
  const rep = replacement ? " [replacement occurred, best-effort revert]" : "";
78317
78439
  switch (action) {
78318
- case "delete": return ` - delete ${op.logicalId} (${op.resourceType})${rep}`;
78319
- case "delete-with-final-snapshot": return ` - delete ${op.logicalId} (${op.resourceType}) [${snapshotNote(op.resourceType, item.effectiveProvisionedBy, skipFinalSnapshot)}]`;
78320
- case "orphan-retain": return ` - orphan ${op.logicalId} (${op.resourceType}) [DeletionPolicy Retain — left in AWS]`;
78321
- case "orphan-flag": return ` - orphan ${op.logicalId} (${op.resourceType}) [--orphan]`;
78322
- case "revert": return ` - revert ${op.logicalId} (${op.resourceType})${rep}`;
78323
- case "reverse-replacement": return item.retainsNewResource ? ` - reverse-replace ${op.logicalId} (${op.resourceType}) [re-create old resource; new one RETAINED (UpdateReplacePolicy: Retain) and left untracked — REFUSED instead if the re-create collides with the name the retained resource still holds]` : ` - reverse-replace ${op.logicalId} (${op.resourceType}) [re-create old resource, delete new]`;
78324
- case "reverse-replacement-readopt": return item.retainsNewResource ? ` - reverse-replace ${op.logicalId} (${op.resourceType}) [re-adopt retained old resource; new one RETAINED (UpdateReplacePolicy: Retain) and left untracked]` : ` - reverse-replace ${op.logicalId} (${op.resourceType}) [delete new, re-adopt retained old resource]`;
78325
- case "unrecoverable-delete": return ` - (cannot restore) ${op.logicalId} (${op.resourceType}) — was DELETED, unrecoverable`;
78326
- case "skip-mismatch": return ` - skip ${op.logicalId} (${op.resourceType}) — physical id changed, needs manual attention`;
78327
- case "skip-absent": return ` - skip ${op.logicalId} (${op.resourceType}) — no longer in state`;
78328
- case "skip-already-done": return ` - skip ${op.logicalId} (${op.resourceType}) — already reverted`;
78440
+ case "delete": return ` - delete ${safe(op.logicalId)} (${safe(op.resourceType)})${rep}`;
78441
+ case "delete-with-final-snapshot": return ` - delete ${safe(op.logicalId)} (${safe(op.resourceType)}) [${snapshotNote(op.resourceType, item.effectiveProvisionedBy, skipFinalSnapshot)}]`;
78442
+ case "orphan-retain": return ` - orphan ${safe(op.logicalId)} (${safe(op.resourceType)}) [DeletionPolicy Retain — left in AWS]`;
78443
+ case "orphan-flag": return ` - orphan ${safe(op.logicalId)} (${safe(op.resourceType)}) [--orphan]`;
78444
+ case "revert": return ` - revert ${safe(op.logicalId)} (${safe(op.resourceType)})${rep}`;
78445
+ case "reverse-replacement": return item.retainsNewResource ? ` - reverse-replace ${safe(op.logicalId)} (${safe(op.resourceType)}) [re-create old resource; new one RETAINED (UpdateReplacePolicy: Retain) and left untracked — REFUSED instead if the re-create collides with the name the retained resource still holds]` : ` - reverse-replace ${safe(op.logicalId)} (${safe(op.resourceType)}) [re-create old resource, delete new]`;
78446
+ case "reverse-replacement-readopt": return item.retainsNewResource ? ` - reverse-replace ${safe(op.logicalId)} (${safe(op.resourceType)}) [re-adopt retained old resource; new one RETAINED (UpdateReplacePolicy: Retain) and left untracked]` : ` - reverse-replace ${safe(op.logicalId)} (${safe(op.resourceType)}) [delete new, re-adopt retained old resource]`;
78447
+ case "unrecoverable-delete": return ` - (cannot restore) ${safe(op.logicalId)} (${safe(op.resourceType)}) — was DELETED, unrecoverable`;
78448
+ case "skip-mismatch": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — physical id changed, needs manual attention`;
78449
+ case "skip-absent": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — no longer in state`;
78450
+ case "skip-already-done": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — already reverted`;
78329
78451
  }
78330
78452
  }
78331
78453
  /**
@@ -78337,13 +78459,13 @@ function actionLabel(item, skipFinalSnapshot) {
78337
78459
  function failedActionLabel(item, skipFinalSnapshot) {
78338
78460
  const { op, action } = item;
78339
78461
  switch (action) {
78340
- case "revert-failed-update": return ` - revert ${op.logicalId} (${op.resourceType}) [FAILED update — remote state unknown, force-applying previous properties]`;
78341
- case "delete-failed-create": return ` - delete ${op.logicalId} (${op.resourceType}) [FAILED create]`;
78342
- case "delete-failed-create-with-final-snapshot": return ` - delete ${op.logicalId} (${op.resourceType}) [FAILED create, ${snapshotNote(op.resourceType, item.effectiveProvisionedBy, skipFinalSnapshot)}]`;
78343
- case "orphan-failed-create-retain": return ` - orphan ${op.logicalId} (${op.resourceType}) [FAILED create, DeletionPolicy Retain — left in AWS]`;
78344
- case "skip-failed-unknown": return ` - skip ${op.logicalId} (${op.resourceType}) — failed CREATE recorded no physical id`;
78345
- case "skip-failed-noop": return ` - skip ${op.logicalId} (${op.resourceType}) — failed ${op.changeType} left nothing to revert`;
78346
- case "skip-failed-absent": return ` - skip ${op.logicalId} (${op.resourceType}) — no previous state available`;
78462
+ case "revert-failed-update": return ` - revert ${safe(op.logicalId)} (${safe(op.resourceType)}) [FAILED update — remote state unknown, force-applying previous properties]`;
78463
+ case "delete-failed-create": return ` - delete ${safe(op.logicalId)} (${safe(op.resourceType)}) [FAILED create]`;
78464
+ case "delete-failed-create-with-final-snapshot": return ` - delete ${safe(op.logicalId)} (${safe(op.resourceType)}) [FAILED create, ${snapshotNote(op.resourceType, item.effectiveProvisionedBy, skipFinalSnapshot)}]`;
78465
+ case "orphan-failed-create-retain": return ` - orphan ${safe(op.logicalId)} (${safe(op.resourceType)}) [FAILED create, DeletionPolicy Retain — left in AWS]`;
78466
+ case "skip-failed-unknown": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — failed CREATE recorded no physical id`;
78467
+ case "skip-failed-noop": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — failed ${safe(op.changeType)} left nothing to revert`;
78468
+ case "skip-failed-absent": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — no previous state available`;
78347
78469
  }
78348
78470
  }
78349
78471
  /**
@@ -78384,7 +78506,7 @@ async function rollbackCommand(stackArg, options) {
78384
78506
  return;
78385
78507
  }
78386
78508
  if (scoped.length > 1) {
78387
- const list = scoped.map((c) => ` - ${c.stackName} (${c.region})`).join("\n");
78509
+ const list = scoped.map((c) => ` - ${safe(c.stackName)} (${safe(c.region)})`).join("\n");
78388
78510
  throw new Error(`Multiple stacks have a rollback journal. Pick one:\n${list}\nRe-run 'cdkd rollback <stack>' (add --stack-region if the same name spans regions).`);
78389
78511
  }
78390
78512
  ref = scoped[0];
@@ -78417,25 +78539,25 @@ async function rollbackCommand(stackArg, options) {
78417
78539
  try {
78418
78540
  const stateData = await setup.stateBackend.getState(stackName, region);
78419
78541
  const journal = await setup.stateBackend.loadRollbackJournal(stackName, region);
78420
- if (!journal || journal.segments.length === 0) throw new Error(`Nothing to roll back for '${stackName}' (${region}). Run 'cdkd deploy' to (re)deploy, or 'cdkd destroy' to clean up.`);
78421
- if (!stateData) throw new Error(`Rollback journal exists for '${stackName}' (${region}) but its state.json is missing (keys: ${setup.prefix}/${stackName}/${region}/state.json and .../rollback-journal.json). State appears corrupted — inspect the bucket manually.`);
78542
+ if (!journal || journal.segments.length === 0) throw new Error(`Nothing to roll back for '${safe(stackName)}' (${safe(region)}). Run 'cdkd deploy' to (re)deploy, or 'cdkd destroy' to clean up.`);
78543
+ if (!stateData) throw new Error(`Rollback journal exists for '${safe(stackName)}' (${safe(region)}) but its state.json is missing (keys: ${safe(`${setup.prefix}/${stackName}/${region}`)}/state.json and .../rollback-journal.json). State appears corrupted — inspect the bucket manually.`);
78422
78544
  const baseState = stateData.state;
78423
78545
  const stateResources = { ...baseState.resources };
78424
78546
  const mintedOrphans = [];
78425
78547
  const orphanLogicalIds = new Set(options.orphan ?? []);
78426
78548
  const newestSegment = journal.segments[journal.segments.length - 1];
78427
- if (newestSegment.roleArn && !options.roleArn) logger.info(`Note: the failed deploy ran with --role-arn ${newestSegment.roleArn}; this rollback is running with ambient credentials (pass --role-arn to match).`);
78428
- logger.info(`\nRollback plan for '${stackName}' (${region}):`);
78549
+ if (newestSegment.roleArn && !options.roleArn) logger.info(`Note: the failed deploy ran with --role-arn ${safe(newestSegment.roleArn)}; this rollback is running with ambient credentials (pass --role-arn to match).`);
78550
+ logger.info(`\nRollback plan for '${safe(stackName)}' (${safe(region)}):`);
78429
78551
  const planStateView = { ...stateResources };
78430
78552
  for (let s = journal.segments.length - 1; s >= 0; s--) {
78431
78553
  const segment = journal.segments[s];
78432
- logger.info(`\n Segment ${s + 1}/${journal.segments.length} (${segment.reason}${segment.runId ? `, run ${segment.runId}` : ""}):`);
78554
+ logger.info(`\n Segment ${s + 1}/${journal.segments.length} (${safe(segment.reason)}${segment.runId ? `, run ${safe(segment.runId)}` : ""}):`);
78433
78555
  if (segment.failedOperations && segment.failedOperations.length > 0) {
78434
78556
  if (options.revertFailed) {
78435
78557
  const failedPlan = planFailedOps(segment.failedOperations, planStateView);
78436
78558
  for (const item of failedPlan) logger.info(failedActionLabel(item, options.skipFinalSnapshot === true));
78437
78559
  applyFailedPlanToPreview(failedPlan, planStateView, options.skipFinalSnapshot === true);
78438
- } else for (const fop of segment.failedOperations) logger.info(` - (left as-is) ${fop.logicalId} (${fop.resourceType}) — its ${fop.changeType} FAILED mid-deploy; pass --revert-failed to attempt reverting it`);
78560
+ } else for (const fop of segment.failedOperations) logger.info(` - (left as-is) ${safe(fop.logicalId)} (${safe(fop.resourceType)}) — its ${safe(fop.changeType)} FAILED mid-deploy; pass --revert-failed to attempt reverting it`);
78439
78561
  }
78440
78562
  const plan = planRollback(segment.operations, planStateView, orphanLogicalIds);
78441
78563
  for (const item of plan) logger.info(actionLabel(item, options.skipFinalSnapshot === true));
@@ -78443,7 +78565,7 @@ async function rollbackCommand(stackArg, options) {
78443
78565
  }
78444
78566
  logger.info("");
78445
78567
  if (!skipConfirmation) {
78446
- if (!await confirm(`Roll back '${stackName}' (${region})?`)) {
78568
+ if (!await confirm(`Roll back '${safe(stackName)}' (${safe(region)})?`)) {
78447
78569
  logger.info("Rollback cancelled");
78448
78570
  return;
78449
78571
  }
@@ -78481,7 +78603,7 @@ async function rollbackCommand(stackArg, options) {
78481
78603
  const fresh = await setup.stateBackend.getState(stackName, region);
78482
78604
  currentEtag = await setup.stateBackend.saveState(stackName, region, next(), { ...fresh?.etag !== void 0 && { expectedEtag: fresh.etag } });
78483
78605
  } catch (retryError) {
78484
- logger.warn(`Failed to persist state after a rollback operation: ${retryError instanceof Error ? retryError.message : String(retryError)}. The resource was reverted in AWS; re-run 'cdkd rollback ${stackName}' to reconcile state.`);
78606
+ logger.warn(`Failed to persist state after a rollback operation: ${displaySafe(retryError instanceof Error ? retryError.message : String(retryError))}. The resource was reverted in AWS; re-run 'cdkd rollback ${safe(stackName)}' to reconcile state.`);
78485
78607
  }
78486
78608
  }
78487
78609
  };
@@ -78524,7 +78646,7 @@ async function rollbackCommand(stackArg, options) {
78524
78646
  if (remaining.length === 0) delete segment.failedOperations;
78525
78647
  else segment.failedOperations = remaining;
78526
78648
  } catch (stripError) {
78527
- logger.warn(`Failed to strip replayed failed-ops from the journal: ${stripError instanceof Error ? stripError.message : String(stripError)}`);
78649
+ logger.warn(`Failed to strip replayed failed-ops from the journal: ${displaySafe(stripError instanceof Error ? stripError.message : String(stripError))}`);
78528
78650
  }
78529
78651
  if (failedResult.interrupted) return {
78530
78652
  failures: failedOpFailures,
@@ -78560,16 +78682,16 @@ async function rollbackCommand(stackArg, options) {
78560
78682
  const survivingOrphans = orphansAfterRollback(baseState, mintedOrphans).orphans ?? [];
78561
78683
  if (journal.segments.length === 0 && oldestInitialDeploy && Object.keys(stateResources).length === 0 && survivingOrphans.length === 0) {
78562
78684
  await setup.stateBackend.deleteState(stackName, region);
78563
- logger.info(`State for '${stackName}' (${region}) removed (stack fully rolled back).`);
78685
+ logger.info(`State for '${safe(stackName)}' (${safe(region)}) removed (stack fully rolled back).`);
78564
78686
  }
78565
- if (interrupted) throw new PartialFailureError(`Rollback interrupted. Journal preserved — re-run 'cdkd rollback ${stackName}' to finish.`);
78566
- if (totalFailures > 0) throw new PartialFailureError(`Rollback completed with ${totalFailures} failed operation(s). Journal preserved — re-run 'cdkd rollback ${stackName}' to retry.`);
78687
+ if (interrupted) throw new PartialFailureError(`Rollback interrupted. Journal preserved — re-run 'cdkd rollback ${safe(stackName)}' to finish.`);
78688
+ if (totalFailures > 0) throw new PartialFailureError(`Rollback completed with ${totalFailures} failed operation(s). Journal preserved — re-run 'cdkd rollback ${safe(stackName)}' to retry.`);
78567
78689
  if (totalWarnings > 0) throw new PartialFailureError(`Rollback completed with ${totalWarnings} skipped/unrecoverable operation(s) (see warnings above).`);
78568
- logger.info(`\nRollback of '${stackName}' (${region}) complete.`);
78690
+ logger.info(`\nRollback of '${safe(stackName)}' (${safe(region)}) complete.`);
78569
78691
  } finally {
78570
78692
  try {
78571
78693
  await setup.lockManager.releaseLock(stackName, region).catch((err) => {
78572
- logger.warn(`Failed to release lock for '${stackName}' (${region}): ${err instanceof Error ? err.message : String(err)}`);
78694
+ logger.warn(`Failed to release lock for '${safe(stackName)}' (${safe(region)}): ${displaySafe(err instanceof Error ? err.message : String(err))}`);
78573
78695
  });
78574
78696
  } finally {
78575
78697
  process.removeListener("SIGINT", sigintHandler);
@@ -91942,4 +92064,4 @@ function buildProgram() {
91942
92064
 
91943
92065
  //#endregion
91944
92066
  export { buildProgram };
91945
- //# sourceMappingURL=program-B3I46yaG.js.map
92067
+ //# sourceMappingURL=program-BJxsQ7qM.js.map