@go-to-k/cdkd 0.289.5 → 0.289.7
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/{asg-provider-DD_xuWE3.js → asg-provider-D6Zyjgrr.js} +3 -3
- package/dist/{asg-provider-DD_xuWE3.js.map → asg-provider-D6Zyjgrr.js.map} +1 -1
- package/dist/cli.js +2 -2
- package/dist/{deploy-engine-Dhgm0r8o.js → deploy-engine-DrTOY3f-.js} +151 -47
- package/dist/deploy-engine-DrTOY3f-.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/{logger-CecsQ1UT.js → logger-DTEUzYP_.js} +46 -3
- package/dist/logger-DTEUzYP_.js.map +1 -0
- package/dist/{program-CgSZ7WgF.js → program-Ca0PiFL-.js} +236 -89
- package/dist/{program-CgSZ7WgF.js.map → program-Ca0PiFL-.js.map} +1 -1
- package/dist/{version-DMsY_Ble.js → version-DJGTB4Rm.js} +2 -2
- package/dist/{version-DMsY_Ble.js.map → version-DJGTB4Rm.js.map} +1 -1
- package/package.json +1 -1
- package/dist/deploy-engine-Dhgm0r8o.js.map +0 -1
- package/dist/logger-CecsQ1UT.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { $ as collectInlinePolicyNamesManagedBySiblings, $n as
|
|
2
|
-
import { _ as withSkipPrefix, 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
|
|
1
|
+
import { $ as collectInlinePolicyNamesManagedBySiblings, $n as describeAwsFailure, $r as IntrinsicResolutionRefusalError, $t as describeTypeWithThrottleRetry, A as isStatefulRecreateTargetForReplace, An as importableOutputKeys, Ar as MIGRATE_TMP_PREFIX, At as coerceCfnBoolean, B as gray, Bn as loadPublishableAssetManifest, Bt as classifyReplaySecretRegion, C as refusesFinalSnapshot, Cn as buildForceUnlockCommand, Cr as resolveStateBucketWithDefault, Ct as isUnboundTemplateParameter, D as makeSiblingClaimReader, Dn as CUSTOM_RESOURCE_RESPONSE_PREFIX, Dr as warnDeprecatedNoPrefixCliFlag, Dt as normalizeAwsTagsToCfn, E as extractDeploymentEventError, En as shellQuote, Er as stateBucketExistenceConfirmed, Et as WAFv2WebACLProvider, F as isWarmThroughputDecrease, Fn as AssetPublisher, Fr as PARTITION_TABLE, Ft as readConfigString, G as collectPublishedOutputNames, Gn as ensureAssetStorage, Gr as setAwsClients, Gt as s3BucketDualStackDomainName, H as red, Hn as AssetModeResolver, Hr as AwsClients, Ht as withSharedDrainBudget, I as toFiniteNumber, In as stringifyValue, Ir as canonicalizeRegion, It as replayWarn, J as secretBearing, Jn as parseBootstrapMarker, Jt as applyRoleArnIfSet, K as exportAliasCollisionScrubWarning, Kn as getBootstrapMarkerKey, Kt as s3BucketRegionalDomainName, L as formatResourceLine, Ln as WorkGraph, Lr as derivePartitionAndUrlSuffix, Lt as requireConfigArray, M as renderStatefulReason, Mn as orphansAfterRollback, Mr as uploadCfnTemplate, Mt as configBooleanRefusal, N as WARM_THROUGHPUT_MEMBERS, Nn as orphansCarriedFrom, Nr as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, Nt as configIntegerRefusal, O as planOrphanAdoption, On as DEFAULT_STATE_PREFIX, Or as CFN_TEMPLATE_BODY_LIMIT, Ot as resolveExplicitPhysicalId, P as coerceWarmThroughput$1, Pn as shouldRetainResource, Pr as expectedOwnerParam, Pt as configStringRefusal, Q as IAMRoleProvider, Qn as buildDenyExternalAccessPolicy, Qr as DynamicReferenceRegionAmbiguousError, Qt as findSilentDropProperties, R as bold, Rn as buildAssetRedirectMap, Rr as AssemblyReader, Rt as requireConfigObject, S as isFinalSnapshotError, Si as retryClassificationText, Sn as rebuildClientForBucketRegion, Sr as resolveSkipPrefix, St as getAccountInfo, T as makeCanonicalizePropertiesFn, Tn as forceQuitRecoveryClause, Tr as resolveUseCdkBootstrapAssets, Tt as refStateLookupFromResource, U as yellow, Un as BOOTSTRAP_MARKER_PREFIX, Ur as getAwsClients, Ut as s3BucketArn, V as green, Vn as rewriteTemplateAssetReferences, Vr as resolveBucketRegion, Vt as producerRegionsFromState, W as collectDeclaredOutputNames, Wn as assertAssetBucketRegion, Wr as resetAwsClients, Wt as s3BucketDomainName, X as secretSafeKeyDisplay, Xn as validateAssetBucketName, Xt as INTRINSIC_KEYS, Y as secretBearingStateKeyWarning, Yn as readBootstrapMarkerBody, Yr as CrossAccountSecretRefusalError, Yt as DiffCalculator, Z as getCurrentResourceSecrets, Zn as validateContainerRepoName, Zr as DeployCancelledError, Zt as findActionableSilentDrops, _ as ATOMIC_FINAL_SNAPSHOT_TYPES, _i as isRetryableTransientError, _n as recoverMaskedOutput, _r as getDefaultStateBucketName, _t as isTerminationProtectionPropagationError, a as DeploymentEventsStore, ai as ProvisioningError, an as STATE_SOURCED_READBACK_RULES, ar as formatDockerLoginError, at as maskerOrIdentity, b as ccRoutedFinalSnapshotError, bi as markNonRetryable, bn as LockManager, br as resolveAutoAssetStorage, bt as cfnRefValueFromPhysicalId, c as replayFailedOperations, ci as StackHasActiveImportsError, cn as createSecretMasker, cr as redactDockerArgvValues, ct as interruptWatchListenerCount, d as updatePartialReason, dn as identityKeyFor, dr as escapeRegExp, dt as CloudControlProvider, ei as LocalInvokeBuildError$1, en as withRetry, er as buildDockerImage, et as clearOnUpdateRemoval, f as withResourceDeadline, fn as isSingleDynamicReferenceToken, fr as stripControlChars, ft as slowCcOperationTimeoutMs, g as bindingSkippedOutputs, gi as isMarkedNonRetryable, gn as recordMaskOnlyValue, gr as synthesisStatusMessage, gt as disableInstanceApiTermination, h as computeImplicitDeleteEdges, hi as withErrorHandling, hn as maskSecretsInText, hr as Synthesizer, ht as deleteSkipReason, i as DeploymentEventsReader, ii as PartialFailureError, in as STATE_SOURCED_CROSS_GENERATION_RULES, ir as dockerSpawnEnvWithSensitive, it as maskDeep, j as isStatefulRecreateTargetSync, jn as importableOutputs, jr as findLargeInlineResources, jt as coerceCfnInteger, k as MULTI_REGION_RECREATE_BLOCKED_TYPES, kn as exportNamesCarriedFrom, kr as CFN_TEMPLATE_URL_LIMIT, kt as assertRegionMatch, l as replayRollback, li as StackTerminationProtectionError, ln as dynamicReferenceTokens, lr as runDockerForeground, lt as isInterruptedWaitError, m as IMPLICIT_DELETE_DEPENDENCIES, mi as normalizeAwsError, mn as maskSecretsInError, mr as getDockerImageBySourceHash, mt as deleteIndeterminateGuards, n as DEFAULT_RESOURCE_WARN_AFTER_MS, nn as TemplateParser, nr as describeDockerExecFailure, nt as wouldReturnToSdkProvider, o as planFailedOps, oi as ResourceTimeoutError, on as TEMPLATE_SOURCED_RULES, or as getDockerCmd, ot as beginCommandInterruptScope, p as maskingRetryLogger, pn as markSameGenerationBag, pr as AssetManifestLoader, pt as UNSPECIFIED_SKIP_REASON, q as isExportAliasCollision, qn as isCrossRegionRedirect, qr as CdkdError, qt as s3BucketWebsiteUrl, r as DeployEngine, ri as NestedStackChildDirectDestroyError, rn as STATE_SOURCED_BASELINE_RULES, rr as describeDockerFailure, rt as createMaskedRetryLogger, s as planRollback, si as ResourceUpdateNotSupportedError, sn as carriesSecretMask, sr as partitionSensitiveEnv, st as endCommandInterruptScope, t as DEFAULT_RESOURCE_TIMEOUT_MS, ti as LocalStartServiceError, tn as DagBuilder, tr as describeDockerCapturedOutput, tt as ProviderRegistry, u as updatePartialMessage, un as errorCauseChain, ur as runDockerStreaming, ut as startInterruptWatch, v as PRE_DELETE_SNAPSHOT_TYPES, vi as isThrottlingError, vn as redactSecretsForState, vr as getLegacyStateBucketName, vt as IntrinsicFunctionResolver, w as unsupportedFinalSnapshotError, wn as buildLockContentionMessage, wr as resolveStateBucketWithDefaultAndSource, wt as parameterTypeMayLoseSecretIdentity, x as createPreDeleteFinalSnapshot, xi as markRedactedCause, xn as S3StateBackend, xr as resolveCaptureObservedState, xt as coerceParameterTypedValue, y as buildFinalSnapshotIdentifier, yi as isTransientServerError, yn as scrubResourceRecord, yr as resolveApp, yt as carriesDynamicReference, z as cyan, zn as createAssetRedirectResolver, zr as processStackMessages, zt as requireConfigString } from "./deploy-engine-DrTOY3f-.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-
|
|
5
|
-
import { r as protectedReplacementAdvice, t as ASGProvider } from "./asg-provider-
|
|
4
|
+
import { t as getCdkdVersion } from "./version-DJGTB4Rm.js";
|
|
5
|
+
import { r as protectedReplacementAdvice, t as ASGProvider } from "./asg-provider-D6Zyjgrr.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
|
|
24689
|
-
*
|
|
24690
|
-
* `RequireEachIncludedType
|
|
24691
|
-
*
|
|
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
|
|
24704
|
-
const
|
|
24705
|
-
|
|
24706
|
-
const
|
|
24707
|
-
const
|
|
24708
|
-
|
|
24709
|
-
|
|
24710
|
-
|
|
24711
|
-
|
|
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;
|
|
@@ -74601,8 +74700,8 @@ async function buildCdkdStateStackTree(rootStackName, region, stateBackend, pref
|
|
|
74601
74700
|
}
|
|
74602
74701
|
async function walkCdkdStateStackTree(stackName, region, state, stateBackend) {
|
|
74603
74702
|
const nestedChildren = /* @__PURE__ */ new Map();
|
|
74604
|
-
for (const [logicalId,
|
|
74605
|
-
if (
|
|
74703
|
+
for (const [logicalId, entry] of Object.entries(state.resources ?? {})) {
|
|
74704
|
+
if (entry?.resourceType !== "AWS::CloudFormation::Stack") continue;
|
|
74606
74705
|
const childStackName = `${stackName}~${logicalId}`;
|
|
74607
74706
|
const childResult = await stateBackend.getState(childStackName, region);
|
|
74608
74707
|
if (!childResult) throw new Error(`cdkd state is missing nested-child '${safeSegment(childStackName)}' (${safeSegment(region)}). Parent stack '${safeSegment(stackName)}' lists '${safeSegment(logicalId)}' as an ${NESTED_STACK_RESOURCE_TYPE} row but no child state file exists at 'cdkd/${safeSegment(childStackName)}/${safeSegment(region)}/state.json'. The cdkd state tree is inconsistent — re-deploy the parent stack to refresh, or run 'cdkd state orphan ${safeSegment(stackName)}' and re-import.`);
|
|
@@ -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,
|
|
@@ -76819,7 +76918,7 @@ async function stateListCommand(options) {
|
|
|
76819
76918
|
return {
|
|
76820
76919
|
stackName: ref.stackName,
|
|
76821
76920
|
region: ref.region ?? null,
|
|
76822
|
-
resourceCount: state ? Object.keys(state.resources).length : 0,
|
|
76921
|
+
resourceCount: state ? Object.keys(state.resources ?? {}).length : 0,
|
|
76823
76922
|
lastModified: state && typeof state.lastModified === "number" ? new Date(state.lastModified).toISOString() : null,
|
|
76824
76923
|
locked
|
|
76825
76924
|
};
|
|
@@ -76928,17 +77027,20 @@ 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
|
-
const details = Object.entries(resources).map(([logicalId,
|
|
76936
|
-
|
|
76937
|
-
|
|
76938
|
-
|
|
76939
|
-
|
|
76940
|
-
|
|
76941
|
-
|
|
77034
|
+
const details = Object.entries(resources).map(([logicalId, entry]) => {
|
|
77035
|
+
const resource = entry ?? {};
|
|
77036
|
+
return {
|
|
77037
|
+
logicalId,
|
|
77038
|
+
resourceType: resource.resourceType,
|
|
77039
|
+
physicalId: resource.physicalId,
|
|
77040
|
+
dependencies: resource.dependencies ?? [],
|
|
77041
|
+
attributes: resource.attributes ?? {}
|
|
77042
|
+
};
|
|
77043
|
+
}).sort((a, b) => a.logicalId.localeCompare(b.logicalId));
|
|
76942
77044
|
if (options.json) {
|
|
76943
77045
|
process.stdout.write(`${JSON.stringify(details, null, 2)}\n`);
|
|
76944
77046
|
return;
|
|
@@ -77082,20 +77184,35 @@ function formatLastModified(value) {
|
|
|
77082
77184
|
* whole control class with spaces. They arrive here as control-free strings, so
|
|
77083
77185
|
* a guard would be redundant — and a test for one could only be written by
|
|
77084
77186
|
* mocking the read that sanitises them, which would pin nothing about the real
|
|
77085
|
-
* path.
|
|
77086
|
-
*
|
|
77087
|
-
* not something a guard here could catch either.
|
|
77187
|
+
* path. A value whose coercion THROWS is absorbed there too: `displaySafe`
|
|
77188
|
+
* falls back to `Object.prototype.toString` (go-to-k/cdkd#2947).
|
|
77088
77189
|
*
|
|
77089
77190
|
* `expiresAt` is declared a number and is not guaranteed to be one, but it
|
|
77090
77191
|
* reaches the row only through subtraction and `formatDuration`, so no character
|
|
77091
|
-
* the record carries can survive into the output either.
|
|
77192
|
+
* the record carries can survive into the output either. One that is not a
|
|
77193
|
+
* finite number — absent, `{}`, `"soon"`, or the `NaN` that `getLockRecord`
|
|
77194
|
+
* substitutes for a coercion that throws (go-to-k/cdkd#2947) — is reported as
|
|
77195
|
+
* an UNKNOWN deadline rather than pushed through the arithmetic, which printed
|
|
77196
|
+
* `expired NaNmNaNs ago` (issue #3083). The wording is the one
|
|
77197
|
+
* `lock-contention-message.ts`'s `formatRemaining` already uses for the same
|
|
77198
|
+
* input, so the two lock renderers agree. What the expiry CHECK does with such
|
|
77199
|
+
* a value (`isLockExpired` treats it as expired) is a separate decision that
|
|
77200
|
+
* this row does not restate.
|
|
77092
77201
|
*/
|
|
77093
77202
|
function formatLockSummary(lockInfo) {
|
|
77094
77203
|
if (!lockInfo) return "unlocked";
|
|
77095
77204
|
const opStr = lockInfo.operation ? ` (operation: ${lockInfo.operation})` : "";
|
|
77096
|
-
|
|
77097
|
-
|
|
77098
|
-
|
|
77205
|
+
return `locked by ${lockInfo.owner}${opStr}, ${formatExpiry(lockInfo.expiresAt)}`;
|
|
77206
|
+
}
|
|
77207
|
+
/**
|
|
77208
|
+
* `expires in 1m23s` / `expired 45s ago` for a finite deadline, `expires at an
|
|
77209
|
+
* unknown time` for anything else. The non-finite arm exists because
|
|
77210
|
+
* `expiresAt` is an unchecked cast (see `formatLockSummary`).
|
|
77211
|
+
*/
|
|
77212
|
+
function formatExpiry(expiresAt) {
|
|
77213
|
+
if (!Number.isFinite(expiresAt)) return "expires at an unknown time";
|
|
77214
|
+
const expiresInMs = expiresAt - Date.now();
|
|
77215
|
+
return expiresInMs > 0 ? `expires in ${formatDuration(expiresInMs)}` : `expired ${formatDuration(-expiresInMs)} ago`;
|
|
77099
77216
|
}
|
|
77100
77217
|
/**
|
|
77101
77218
|
* Create the `state resources` subcommand.
|
|
@@ -77135,9 +77252,9 @@ async function stateShowCommand(stackName, options) {
|
|
|
77135
77252
|
const setup = await setupStateBackend(options);
|
|
77136
77253
|
try {
|
|
77137
77254
|
const ref = resolveSingleRegion(stackName, await setup.stateBackend.listStacks(), options.stackRegion);
|
|
77138
|
-
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.`);
|
|
77255
|
+
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.`);
|
|
77139
77256
|
const [stateResult, lockInfo] = await Promise.all([setup.stateBackend.getState(stackName, ref.region), setup.lockManager.getLockInfo(stackName, ref.region)]);
|
|
77140
|
-
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.`);
|
|
77257
|
+
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.`);
|
|
77141
77258
|
if (options.showNested) {
|
|
77142
77259
|
const treeWithLocks = await loadLocksForTree(await buildCdkdStateStackTree(stackName, ref.region, setup.stateBackend, stateResult.state), setup.lockManager, lockInfo);
|
|
77143
77260
|
if (options.json) {
|
|
@@ -77243,12 +77360,13 @@ function renderStateBlock(state, lockInfo, withLegend) {
|
|
|
77243
77360
|
lines.push("Skipped outputs:");
|
|
77244
77361
|
for (const [k, digest] of sortedSkippedOutputs(state)) {
|
|
77245
77362
|
const fullDigest = formatAttributeValue(digest);
|
|
77246
|
-
const
|
|
77363
|
+
const cut = truncateCodePoints(fullDigest, SKIPPED_DIGEST_PREVIEW_LEN);
|
|
77364
|
+
const shownDigest = cut.truncated && fullDigest !== UNSERIALIZABLE ? `${cut.text}…` : fullDigest;
|
|
77247
77365
|
lines.push(` ${stripControlChars(k)}: ${shownDigest}`);
|
|
77248
77366
|
}
|
|
77249
77367
|
if (withLegend) lines.push(...skippedOutputsLegend());
|
|
77250
77368
|
}
|
|
77251
|
-
const resourceEntries = Object.entries(state.resources ?? {}).sort(([a], [b]) => a.localeCompare(b));
|
|
77369
|
+
const resourceEntries = Object.entries(state.resources ?? {}).map(([logicalId, entry]) => [logicalId, entry ?? {}]).sort(([a], [b]) => a.localeCompare(b));
|
|
77252
77370
|
lines.push("");
|
|
77253
77371
|
lines.push(`Resources (${resourceEntries.length}):`);
|
|
77254
77372
|
for (const [logicalId, resource] of resourceEntries) {
|
|
@@ -78301,6 +78419,35 @@ function snapshotNote(resourceType, effectiveProvisionedBy, skipFinalSnapshot) {
|
|
|
78301
78419
|
return "DeletionPolicy Snapshot — final snapshot, then delete";
|
|
78302
78420
|
}
|
|
78303
78421
|
/**
|
|
78422
|
+
* One spelling of "this value came from an S3 key or a rollback-journal record,
|
|
78423
|
+
* and is about to be interpolated into a message a terminal will render"
|
|
78424
|
+
* (issue #3064).
|
|
78425
|
+
*
|
|
78426
|
+
* `rollback-journal.json` is a sibling of `state.json` in the same bucket, so
|
|
78427
|
+
* anyone with `s3:PutObject` writes it, and cdkd's output is line-oriented --
|
|
78428
|
+
* an injected newline invents a line that reads like a real one. Here that is
|
|
78429
|
+
* worse than a forged diagnostic: the plan preview below is what the user
|
|
78430
|
+
* CONFIRMS against, so a planted journal could forge the plan rows themselves.
|
|
78431
|
+
*
|
|
78432
|
+
* The ASCII allowlist, because every value it guards has a known charset: a
|
|
78433
|
+
* logical id, a CFn resource type, a change type, a run id, a segment reason,
|
|
78434
|
+
* a stack name, an AWS region. Call it for those; `grep safe(` answers the
|
|
78435
|
+
* scope and this comment does not.
|
|
78436
|
+
*
|
|
78437
|
+
* NOT for a value that is about to be USED rather than shown -- the preview
|
|
78438
|
+
* indexes `previewState` by the RAW `op.logicalId`, and sanitising a lookup
|
|
78439
|
+
* key silently mismatches the record it is meant to find.
|
|
78440
|
+
*
|
|
78441
|
+
* NOT for free-form error text either. An SDK or provider message legitimately
|
|
78442
|
+
* carries non-ASCII (a resource name, AWS's own wording), so a site that renders
|
|
78443
|
+
* one calls `displaySafe()` directly and takes the DENYLIST -- the same class
|
|
78444
|
+
* `formatError` picks for a `cause`, and for the same reason. `grep displaySafe(`
|
|
78445
|
+
* answers how many; a count written here was wrong on its first revision.
|
|
78446
|
+
*/
|
|
78447
|
+
function safe(value) {
|
|
78448
|
+
return displaySafe(value, { asciiOnly: true }) || "<unrenderable>";
|
|
78449
|
+
}
|
|
78450
|
+
/**
|
|
78304
78451
|
* Human label for a planned rollback action (plan preview). `skipFinalSnapshot`
|
|
78305
78452
|
* is threaded in because the classifier is pure (it cannot see CLI flags) and
|
|
78306
78453
|
* the Snapshot label would otherwise promise a final snapshot the run is about
|
|
@@ -78310,17 +78457,17 @@ function actionLabel(item, skipFinalSnapshot) {
|
|
|
78310
78457
|
const { op, action, replacement } = item;
|
|
78311
78458
|
const rep = replacement ? " [replacement occurred, best-effort revert]" : "";
|
|
78312
78459
|
switch (action) {
|
|
78313
|
-
case "delete": return ` - delete ${op.logicalId} (${op.resourceType})${rep}`;
|
|
78314
|
-
case "delete-with-final-snapshot": return ` - delete ${op.logicalId} (${op.resourceType}) [${snapshotNote(op.resourceType, item.effectiveProvisionedBy, skipFinalSnapshot)}]`;
|
|
78315
|
-
case "orphan-retain": return ` - orphan ${op.logicalId} (${op.resourceType}) [DeletionPolicy Retain — left in AWS]`;
|
|
78316
|
-
case "orphan-flag": return ` - orphan ${op.logicalId} (${op.resourceType}) [--orphan]`;
|
|
78317
|
-
case "revert": return ` - revert ${op.logicalId} (${op.resourceType})${rep}`;
|
|
78318
|
-
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]`;
|
|
78319
|
-
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]`;
|
|
78320
|
-
case "unrecoverable-delete": return ` - (cannot restore) ${op.logicalId} (${op.resourceType}) — was DELETED, unrecoverable`;
|
|
78321
|
-
case "skip-mismatch": return ` - skip ${op.logicalId} (${op.resourceType}) — physical id changed, needs manual attention`;
|
|
78322
|
-
case "skip-absent": return ` - skip ${op.logicalId} (${op.resourceType}) — no longer in state`;
|
|
78323
|
-
case "skip-already-done": return ` - skip ${op.logicalId} (${op.resourceType}) — already reverted`;
|
|
78460
|
+
case "delete": return ` - delete ${safe(op.logicalId)} (${safe(op.resourceType)})${rep}`;
|
|
78461
|
+
case "delete-with-final-snapshot": return ` - delete ${safe(op.logicalId)} (${safe(op.resourceType)}) [${snapshotNote(op.resourceType, item.effectiveProvisionedBy, skipFinalSnapshot)}]`;
|
|
78462
|
+
case "orphan-retain": return ` - orphan ${safe(op.logicalId)} (${safe(op.resourceType)}) [DeletionPolicy Retain — left in AWS]`;
|
|
78463
|
+
case "orphan-flag": return ` - orphan ${safe(op.logicalId)} (${safe(op.resourceType)}) [--orphan]`;
|
|
78464
|
+
case "revert": return ` - revert ${safe(op.logicalId)} (${safe(op.resourceType)})${rep}`;
|
|
78465
|
+
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]`;
|
|
78466
|
+
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]`;
|
|
78467
|
+
case "unrecoverable-delete": return ` - (cannot restore) ${safe(op.logicalId)} (${safe(op.resourceType)}) — was DELETED, unrecoverable`;
|
|
78468
|
+
case "skip-mismatch": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — physical id changed, needs manual attention`;
|
|
78469
|
+
case "skip-absent": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — no longer in state`;
|
|
78470
|
+
case "skip-already-done": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — already reverted`;
|
|
78324
78471
|
}
|
|
78325
78472
|
}
|
|
78326
78473
|
/**
|
|
@@ -78332,13 +78479,13 @@ function actionLabel(item, skipFinalSnapshot) {
|
|
|
78332
78479
|
function failedActionLabel(item, skipFinalSnapshot) {
|
|
78333
78480
|
const { op, action } = item;
|
|
78334
78481
|
switch (action) {
|
|
78335
|
-
case "revert-failed-update": return ` - revert ${op.logicalId} (${op.resourceType}) [FAILED update — remote state unknown, force-applying previous properties]`;
|
|
78336
|
-
case "delete-failed-create": return ` - delete ${op.logicalId} (${op.resourceType}) [FAILED create]`;
|
|
78337
|
-
case "delete-failed-create-with-final-snapshot": return ` - delete ${op.logicalId} (${op.resourceType}) [FAILED create, ${snapshotNote(op.resourceType, item.effectiveProvisionedBy, skipFinalSnapshot)}]`;
|
|
78338
|
-
case "orphan-failed-create-retain": return ` - orphan ${op.logicalId} (${op.resourceType}) [FAILED create, DeletionPolicy Retain — left in AWS]`;
|
|
78339
|
-
case "skip-failed-unknown": return ` - skip ${op.logicalId} (${op.resourceType}) — failed CREATE recorded no physical id`;
|
|
78340
|
-
case "skip-failed-noop": return ` - skip ${op.logicalId} (${op.resourceType}) — failed ${op.changeType} left nothing to revert`;
|
|
78341
|
-
case "skip-failed-absent": return ` - skip ${op.logicalId} (${op.resourceType}) — no previous state available`;
|
|
78482
|
+
case "revert-failed-update": return ` - revert ${safe(op.logicalId)} (${safe(op.resourceType)}) [FAILED update — remote state unknown, force-applying previous properties]`;
|
|
78483
|
+
case "delete-failed-create": return ` - delete ${safe(op.logicalId)} (${safe(op.resourceType)}) [FAILED create]`;
|
|
78484
|
+
case "delete-failed-create-with-final-snapshot": return ` - delete ${safe(op.logicalId)} (${safe(op.resourceType)}) [FAILED create, ${snapshotNote(op.resourceType, item.effectiveProvisionedBy, skipFinalSnapshot)}]`;
|
|
78485
|
+
case "orphan-failed-create-retain": return ` - orphan ${safe(op.logicalId)} (${safe(op.resourceType)}) [FAILED create, DeletionPolicy Retain — left in AWS]`;
|
|
78486
|
+
case "skip-failed-unknown": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — failed CREATE recorded no physical id`;
|
|
78487
|
+
case "skip-failed-noop": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — failed ${safe(op.changeType)} left nothing to revert`;
|
|
78488
|
+
case "skip-failed-absent": return ` - skip ${safe(op.logicalId)} (${safe(op.resourceType)}) — no previous state available`;
|
|
78342
78489
|
}
|
|
78343
78490
|
}
|
|
78344
78491
|
/**
|
|
@@ -78379,7 +78526,7 @@ async function rollbackCommand(stackArg, options) {
|
|
|
78379
78526
|
return;
|
|
78380
78527
|
}
|
|
78381
78528
|
if (scoped.length > 1) {
|
|
78382
|
-
const list = scoped.map((c) => ` - ${c.stackName} (${c.region})`).join("\n");
|
|
78529
|
+
const list = scoped.map((c) => ` - ${safe(c.stackName)} (${safe(c.region)})`).join("\n");
|
|
78383
78530
|
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).`);
|
|
78384
78531
|
}
|
|
78385
78532
|
ref = scoped[0];
|
|
@@ -78412,25 +78559,25 @@ async function rollbackCommand(stackArg, options) {
|
|
|
78412
78559
|
try {
|
|
78413
78560
|
const stateData = await setup.stateBackend.getState(stackName, region);
|
|
78414
78561
|
const journal = await setup.stateBackend.loadRollbackJournal(stackName, region);
|
|
78415
|
-
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.`);
|
|
78416
|
-
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.`);
|
|
78562
|
+
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.`);
|
|
78563
|
+
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.`);
|
|
78417
78564
|
const baseState = stateData.state;
|
|
78418
78565
|
const stateResources = { ...baseState.resources };
|
|
78419
78566
|
const mintedOrphans = [];
|
|
78420
78567
|
const orphanLogicalIds = new Set(options.orphan ?? []);
|
|
78421
78568
|
const newestSegment = journal.segments[journal.segments.length - 1];
|
|
78422
|
-
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).`);
|
|
78423
|
-
logger.info(`\nRollback plan for '${stackName}' (${region}):`);
|
|
78569
|
+
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).`);
|
|
78570
|
+
logger.info(`\nRollback plan for '${safe(stackName)}' (${safe(region)}):`);
|
|
78424
78571
|
const planStateView = { ...stateResources };
|
|
78425
78572
|
for (let s = journal.segments.length - 1; s >= 0; s--) {
|
|
78426
78573
|
const segment = journal.segments[s];
|
|
78427
|
-
logger.info(`\n Segment ${s + 1}/${journal.segments.length} (${segment.reason}${segment.runId ? `, run ${segment.runId}` : ""}):`);
|
|
78574
|
+
logger.info(`\n Segment ${s + 1}/${journal.segments.length} (${safe(segment.reason)}${segment.runId ? `, run ${safe(segment.runId)}` : ""}):`);
|
|
78428
78575
|
if (segment.failedOperations && segment.failedOperations.length > 0) {
|
|
78429
78576
|
if (options.revertFailed) {
|
|
78430
78577
|
const failedPlan = planFailedOps(segment.failedOperations, planStateView);
|
|
78431
78578
|
for (const item of failedPlan) logger.info(failedActionLabel(item, options.skipFinalSnapshot === true));
|
|
78432
78579
|
applyFailedPlanToPreview(failedPlan, planStateView, options.skipFinalSnapshot === true);
|
|
78433
|
-
} 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`);
|
|
78580
|
+
} 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`);
|
|
78434
78581
|
}
|
|
78435
78582
|
const plan = planRollback(segment.operations, planStateView, orphanLogicalIds);
|
|
78436
78583
|
for (const item of plan) logger.info(actionLabel(item, options.skipFinalSnapshot === true));
|
|
@@ -78438,7 +78585,7 @@ async function rollbackCommand(stackArg, options) {
|
|
|
78438
78585
|
}
|
|
78439
78586
|
logger.info("");
|
|
78440
78587
|
if (!skipConfirmation) {
|
|
78441
|
-
if (!await confirm(`Roll back '${stackName}' (${region})?`)) {
|
|
78588
|
+
if (!await confirm(`Roll back '${safe(stackName)}' (${safe(region)})?`)) {
|
|
78442
78589
|
logger.info("Rollback cancelled");
|
|
78443
78590
|
return;
|
|
78444
78591
|
}
|
|
@@ -78476,7 +78623,7 @@ async function rollbackCommand(stackArg, options) {
|
|
|
78476
78623
|
const fresh = await setup.stateBackend.getState(stackName, region);
|
|
78477
78624
|
currentEtag = await setup.stateBackend.saveState(stackName, region, next(), { ...fresh?.etag !== void 0 && { expectedEtag: fresh.etag } });
|
|
78478
78625
|
} catch (retryError) {
|
|
78479
|
-
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.`);
|
|
78626
|
+
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.`);
|
|
78480
78627
|
}
|
|
78481
78628
|
}
|
|
78482
78629
|
};
|
|
@@ -78519,7 +78666,7 @@ async function rollbackCommand(stackArg, options) {
|
|
|
78519
78666
|
if (remaining.length === 0) delete segment.failedOperations;
|
|
78520
78667
|
else segment.failedOperations = remaining;
|
|
78521
78668
|
} catch (stripError) {
|
|
78522
|
-
logger.warn(`Failed to strip replayed failed-ops from the journal: ${stripError instanceof Error ? stripError.message : String(stripError)}`);
|
|
78669
|
+
logger.warn(`Failed to strip replayed failed-ops from the journal: ${displaySafe(stripError instanceof Error ? stripError.message : String(stripError))}`);
|
|
78523
78670
|
}
|
|
78524
78671
|
if (failedResult.interrupted) return {
|
|
78525
78672
|
failures: failedOpFailures,
|
|
@@ -78555,16 +78702,16 @@ async function rollbackCommand(stackArg, options) {
|
|
|
78555
78702
|
const survivingOrphans = orphansAfterRollback(baseState, mintedOrphans).orphans ?? [];
|
|
78556
78703
|
if (journal.segments.length === 0 && oldestInitialDeploy && Object.keys(stateResources).length === 0 && survivingOrphans.length === 0) {
|
|
78557
78704
|
await setup.stateBackend.deleteState(stackName, region);
|
|
78558
|
-
logger.info(`State for '${stackName}' (${region}) removed (stack fully rolled back).`);
|
|
78705
|
+
logger.info(`State for '${safe(stackName)}' (${safe(region)}) removed (stack fully rolled back).`);
|
|
78559
78706
|
}
|
|
78560
|
-
if (interrupted) throw new PartialFailureError(`Rollback interrupted. Journal preserved — re-run 'cdkd rollback ${stackName}' to finish.`);
|
|
78561
|
-
if (totalFailures > 0) throw new PartialFailureError(`Rollback completed with ${totalFailures} failed operation(s). Journal preserved — re-run 'cdkd rollback ${stackName}' to retry.`);
|
|
78707
|
+
if (interrupted) throw new PartialFailureError(`Rollback interrupted. Journal preserved — re-run 'cdkd rollback ${safe(stackName)}' to finish.`);
|
|
78708
|
+
if (totalFailures > 0) throw new PartialFailureError(`Rollback completed with ${totalFailures} failed operation(s). Journal preserved — re-run 'cdkd rollback ${safe(stackName)}' to retry.`);
|
|
78562
78709
|
if (totalWarnings > 0) throw new PartialFailureError(`Rollback completed with ${totalWarnings} skipped/unrecoverable operation(s) (see warnings above).`);
|
|
78563
|
-
logger.info(`\nRollback of '${stackName}' (${region}) complete.`);
|
|
78710
|
+
logger.info(`\nRollback of '${safe(stackName)}' (${safe(region)}) complete.`);
|
|
78564
78711
|
} finally {
|
|
78565
78712
|
try {
|
|
78566
78713
|
await setup.lockManager.releaseLock(stackName, region).catch((err) => {
|
|
78567
|
-
logger.warn(`Failed to release lock for '${stackName}' (${region}): ${err instanceof Error ? err.message : String(err)}`);
|
|
78714
|
+
logger.warn(`Failed to release lock for '${safe(stackName)}' (${safe(region)}): ${displaySafe(err instanceof Error ? err.message : String(err))}`);
|
|
78568
78715
|
});
|
|
78569
78716
|
} finally {
|
|
78570
78717
|
process.removeListener("SIGINT", sigintHandler);
|
|
@@ -91937,4 +92084,4 @@ function buildProgram() {
|
|
|
91937
92084
|
|
|
91938
92085
|
//#endregion
|
|
91939
92086
|
export { buildProgram };
|
|
91940
|
-
//# sourceMappingURL=program-
|
|
92087
|
+
//# sourceMappingURL=program-Ca0PiFL-.js.map
|