@go-to-k/cdkd 0.296.28 → 0.296.29

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.
Files changed (26) hide show
  1. package/dist/{asg-provider-B3zcS87C.js → asg-provider-UKRukGI_.js} +3 -3
  2. package/dist/{asg-provider-B3zcS87C.js.map → asg-provider-UKRukGI_.js.map} +1 -1
  3. package/dist/cli.js +2 -2
  4. package/dist/{deploy-engine-D4FdwPCi.js → deploy-engine-Bt-8KvUj.js} +1913 -57
  5. package/dist/deploy-engine-Bt-8KvUj.js.map +1 -0
  6. package/dist/{iam-policy-targets-B61e5_Sk.js → iam-policy-targets-Cz2tPxXk.js} +2 -2
  7. package/dist/{iam-policy-targets-B61e5_Sk.js.map → iam-policy-targets-Cz2tPxXk.js.map} +1 -1
  8. package/dist/{iam-role-provider-0U4kMuzh.js → iam-role-provider-BBFYFBLx.js} +3 -3
  9. package/dist/{iam-role-provider-0U4kMuzh.js.map → iam-role-provider-BBFYFBLx.js.map} +1 -1
  10. package/dist/index.d.ts +121 -55
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -3
  13. package/dist/{neptune-provider-DF6Eh4Tl.js → neptune-provider-B9InVgs6.js} +3 -3
  14. package/dist/{neptune-provider-DF6Eh4Tl.js.map → neptune-provider-B9InVgs6.js.map} +1 -1
  15. package/dist/{program-v_QNBjtZ.js → program-CN7Dqb3j.js} +513 -30
  16. package/dist/program-CN7Dqb3j.js.map +1 -0
  17. package/dist/{provider-classes-wbKBBEol.js → provider-classes-eEgFT-Vt.js} +196 -22
  18. package/dist/provider-classes-eEgFT-Vt.js.map +1 -0
  19. package/dist/{rds-provider-BfQsw4hw.js → rds-provider-DgbVxaPP.js} +3 -3
  20. package/dist/{rds-provider-BfQsw4hw.js.map → rds-provider-DgbVxaPP.js.map} +1 -1
  21. package/dist/{version-B0JEGOLV.js → version-DyV_xwRX.js} +2 -2
  22. package/dist/{version-B0JEGOLV.js.map → version-DyV_xwRX.js.map} +1 -1
  23. package/package.json +1 -1
  24. package/dist/deploy-engine-D4FdwPCi.js.map +0 -1
  25. package/dist/program-v_QNBjtZ.js.map +0 -1
  26. package/dist/provider-classes-wbKBBEol.js.map +0 -1
@@ -1,9 +1,9 @@
1
1
  import { a as runWithStackAwsClients, i as resetAwsClients, o as setAwsClients, t as AwsClients } from "./aws-clients-CnmtbrxD.js";
2
2
  import { A as UNRENDERABLE, B as stringifyJsonPayload, D as SAFE_MSG_ALTERED_CHAR, F as displayStackName, I as isPasteableIdent, M as displayAwsMessage, N as displayIdent, O as SECRET_REF_MAX_CODE_POINTS, P as displaySafe, R as plainIdentOr, T as withStackName, V as truncateCodePoints, _ as derivesPatternBName, a as getLogger, f as getLiveRenderer, h as PATTERN_B_RESOURCE_TYPES, j as cutMarker, k as STACK_REF_MAX_CODE_POINTS, l as runStackBuffered, m as PATTERN_B_NAME_PROPERTIES, o as isStdoutReservedForPayload, p as PATTERN_B_NAME_OPTIONS, r as safeStringify, s as reserveStdoutForPayload, t as describeAwsFailure, v as explicitNamePropertyFor, w as withSkipPrefix, y as generateResourceName, z as safeMsg } from "./aws-failure-text-BaWeCWRz.js";
3
- import { $t as AccountIdUnavailableError, An as commandHole, Bn as setPasteableRunFlags, D as VALUE_NOT_SHOWN, E as assertRegionMatch, En as TIMEOUT_FLAG_RESOURCE_TYPE, Fn as plainOrDescribed, Ft as buildLockContentionMessage, G as runDeleteAttempt, Gt as producerCoordinateKey, Ht as DEFAULT_STATE_PREFIX, In as quotedOrDescribed, It as forceQuitRecoveryClause, Jt as withPasteableAwsProfile, Kt as producerRecordKey, Ln as shellBoundedDisplay, Lt as formatLockExpiry, Mn as isInertUnquoted, Nn as pasteableCommand, Nt as UNREPRODUCIBLE_LOCK_CLAUSE, On as SHELL_ACTIVE_WHY, P as remedyLogicalId, Pt as buildForceUnlockCommand, Qn as isAmbiguousOutcomeError, Qt as credentialFingerprint, Rn as shellQuote, Rt as formatLockOperation, T as RESOURCE_NOT_FOUND, Tn as withErrorHandling, Ut as injectiveKey, Vn as setPasteableVerbFlags, Vt as CUSTOM_RESOURCE_RESPONSE_PREFIX, Xt as ambientCredentialConfig, Yt as ambientClientDefaults, Z as isAwsCliLiteral, Zt as clientDefaultsFor, _n as ResourceUpdateNotSupportedError, an as DeployCancelledError, ar as isThrottlingError, cn as LocalInvokeBuildError$1, er as isRetryableTransientError, fn as MalformedProducerRecordRefusalError, ft as logicalIdShown, gn as ResourceTimeoutError, hn as ProvisioningError, ir as isMarkedNonRetryable, it as isInterruptedWaitError, ln as LocalStartServiceError, mn as PartialFailureError, mt as resourceTypeShown, n as RESOLVED_PREVIOUS_PRINCIPAL_KEYS, nr as retryClassificationText, nt as endCommandInterruptScope, on as DynamicReferenceRegionAmbiguousError, or as markNonRetryable, pn as NestedStackChildDirectDestroyError, qt as setPasteableAwsProfile, rn as CrossAccountSecretRefusalError, rt as interruptWatchListenerCount, s as readRecordedPrincipals, sn as IntrinsicResolutionRefusalError, t as IAM_PRINCIPAL_NAME, tn as CdkdError, tr as isTransientServerError, tt as beginCommandInterruptScope, vn as StackHasActiveImportsError, wn as normalizeAwsError, xn as SynthesisError, yn as StackTerminationProtectionError, zn as withheldTargetClause, zt as formatLockOwner } from "./iam-policy-targets-B61e5_Sk.js";
3
+ import { $n as isAmbiguousOutcomeError, $t as credentialFingerprint, Bn as withheldTargetClause, D as VALUE_NOT_SHOWN, Dn as TIMEOUT_FLAG_RESOURCE_TYPE, E as assertRegionMatch, En as withErrorHandling, Ft as buildLockContentionMessage, G as runDeleteAttempt, Hn as setPasteableVerbFlags, Ht as CUSTOM_RESOURCE_RESPONSE_PREFIX, In as plainOrDescribed, It as forceQuitRecoveryClause, Jt as setPasteableAwsProfile, Kt as producerCoordinateKey, Ln as quotedOrDescribed, Lt as formatLockExpiry, Nn as isInertUnquoted, Nt as UNREPRODUCIBLE_LOCK_CLAUSE, P as remedyLogicalId, Pn as pasteableCommand, Pt as buildForceUnlockCommand, Qt as clientDefaultsFor, Rn as shellBoundedDisplay, Rt as formatLockOperation, Sn as SynthesisError, T as RESOURCE_NOT_FOUND, Tn as normalizeAwsError, Ut as DEFAULT_STATE_PREFIX, Vn as setPasteableRunFlags, Wt as injectiveKey, Xt as ambientClientDefaults, Yt as withPasteableAwsProfile, Z as isAwsCliLiteral, Zt as ambientCredentialConfig, _n as ResourceTimeoutError, ar as isMarkedNonRetryable, bn as StackTerminationProtectionError, cn as IntrinsicResolutionRefusalError, en as AccountIdUnavailableError, ft as logicalIdShown, gn as ProvisioningError, hn as PartialFailureError, in as CrossAccountSecretRefusalError, it as isInterruptedWaitError, jn as commandHole, kn as SHELL_ACTIVE_WHY, ln as LocalInvokeBuildError$1, mn as NestedStackChildDirectDestroyError, mt as resourceTypeShown, n as RESOLVED_PREVIOUS_PRINCIPAL_KEYS, nn as CdkdError, nr as isTransientServerError, nt as endCommandInterruptScope, on as DeployCancelledError, or as isThrottlingError, pn as MalformedProducerRecordRefusalError, qt as producerRecordKey, rr as retryClassificationText, rt as interruptWatchListenerCount, s as readRecordedPrincipals, sn as DynamicReferenceRegionAmbiguousError, sr as markNonRetryable, t as IAM_PRINCIPAL_NAME, tr as isRetryableTransientError, tt as beginCommandInterruptScope, un as LocalStartServiceError, vn as ResourceUpdateNotSupportedError, yn as StackHasActiveImportsError, zn as shellQuote, zt as formatLockOwner } from "./iam-policy-targets-Cz2tPxXk.js";
4
4
  import { n as awsClientDefaults, r as getAssumedRoleCredentials, u as formatAuthority } from "./aws-client-defaults-D0q0z4dG.js";
5
- import { $ as gray, $a as prefetchCreateOnlyPropertyPaths, $i as refuseMalformedOutputs, $o as wholeStringLeavesOf, $r as getAccountInfo, $s as partitionSensitiveEnv, A as perType, Aa as NO_CC_HANDLERS_REASON, Ac as decodeListingKey, Ai as malformedLocalResourceEntriesWarning, An as buildFinalSnapshotIdentifier, Ao as shareLogOnlyValues, Ar as poisonRenderedSpellingsCollidingIn, As as rewriteTemplateAssetReferences, Bc as hasPlainPrototype, Bi as malformedResourceEntriesWarning, Bn as formatDestructiveChange, Bo as isUncertifiedBaselineMaskPosition, Br as AWS_CREDENTIAL_ENV_KEYS, Bs as validateContainerRepoName, Bt as planRollback, C as noEchoComparisonForTemplate, Ca as unreadableOrphanRecords, Cc as ssmResolvedValueType, Ci as hasReadableResources, Cn as maskEventTextWithBoundBags, Co as createUnionSecretMasker, Cs as AssetPublisher, Ct as isHandledOrphan, D as recordedProtectionNote, Dc as findLargeInlineResources, Di as malformedExportNamesWarning, Dn as extractDeploymentEventError, Do as printingCorpusOf, Dr as DiffCalculator, Ds as buildAssetRedirectMap, Dt as sameJournaledOrphans, E as recordedProtectionEvidence, Ea as findActionableSilentDrops, Ec as MIGRATE_TMP_PREFIX, Ei as malformedDriftResourcePropertiesWarning, En as stateSecretNameNeedles, Eo as logOnlyValueCount, Es as WorkGraph, Et as makeForeignHolderScan, Fa as isStatefulRecreateTargetForReplace, Fc as AssemblyReader, Fi as malformedOrphansRefusalMessage, Fn as refusesFinalSnapshot, Fo as markSameGenerationBag, Fr as assertFlagRoleArn, Fs as getBootstrapMarkerKey, Ft as recordAfterRollbackUpdate, Gc as displayAssemblyPath, Gi as previewableOrphanRecords, Gn as withCreateTokenLedger, Gs as describeDockerExecFailure, Gt as seedsDeleteFirstGuard, Hc as ownValue, Hi as malformedResourcesWarning, Ho as identityKeyFor, Hr as callerEnvCredentials, Hs as buildDockerImage, Ht as recordUnderIdIsNotOwn, Ia as isStatefulRecreateTargetSync, Ic as StageLoadError, Ii as malformedOrphansWarning, In as unsupportedFinalSnapshotError, Io as redactSecretsForState, Ir as assertSendableRoleArn, Is as isCrossRegionRedirect, It as demoteSupersededOrphans, Ji as refuseMalformedOrphanRecords, Jo as recordMaskOnlyValue, Js as finchSecretArgvRefusal, Kc as renderAssemblyPathEscape, Ki as refuseDivergentRecordRegionForDestroy, Ko as carriesSecretMask, Ks as describeDockerFailure, Kt as orphanDeleteNeedsIdentity, La as renderStatefulReason, Lc as processStackMessages, Li as malformedOutputsRefusalMessage, Ln as maskingRetryLogger, Lo as scrubResourceRecord, Lr as explicitRoleArnOrThrow, Ls as parseBootstrapMarker, Lt as isJournaledOrphan, Ma as findReplacedReadersOfRecreateTargets, Mc as PARTITION_TABLE, Mi as malformedOrphanRecordsRefusalMessage, Mn as createPreDeleteFinalSnapshot, Mo as errorCauseChain, Mr as producerRegionsFromState, Ms as BOOTSTRAP_MARKER_PREFIX, Na as shownType, Nc as canonicalizeRegion, Ni as malformedOrphanRecordsWarning, Nn as effectiveDeletionPolicy, No as maskSecretsInError, Nr as regionLessSecretName, Ns as assertAssetBucketRegion, Nt as withStackRecords, O as PROTECTION_PROPERTY_BY_TYPE, Oa as unwrittenCreateOnlyReplacement, Oc as uploadCfnTemplate, Oi as malformedExportSourceWarning, On as ATOMIC_FINAL_SNAPSHOT_TYPES, Oo as recordLogOnlyParameterValue, Or as INTRINSIC_KEYS, Os as createAssetRedirectResolver, Ot as replayFailedOperations, Pa as MULTI_REGION_RECREATE_BLOCKED_TYPES, Pc as derivePartitionAndUrlSuffix, Pi as malformedOrphanRowsKeptWarning, Pn as isFinalSnapshotError, Po as maskSecretsInText, Pr as applyRoleArnIfSet, Ps as ensureAssetStorage, Pt as removeProtectionTypeList, Q as cyan, Qi as refuseMalformedOrphansForOrphan, Qo as recordProvenPublicExpression, Qr as parameterTypeMayLoseSecretIdentity, Qs as isMalformedEnvKey, Rc as defineOwnKey, Ri as malformedOutputsWarning, Rn as constructPathOf, Ro as DYNAMIC_REFERENCE_TOKEN_SCAN, Rr as isIamRoleArn, Rs as readBootstrapMarkerBody, Rt as isReplacementOrphan, S as noEchoAttributeNamesOf, Sa as unpreviewableOrphanRecords, Sc as warnDeprecatedNoPrefixCliFlag, Si as hasReadableOutputs, Sn as journaledOrphanPrintingBag, So as carryLogOnlyValues, Ss as shouldRetainResource, St as dropFailedHint, T as noEchoParameterNamesOf, Ta as withheldAccountClause, Tc as CFN_TEMPLATE_URL_LIMIT, Ti as isReadableResourceEntry, Tn as secretNamePrintingBag, To as literalSplitDelimitersOf, Ts as stringifyValue, Tt as loadJournaledOrphans, Uc as absoluteAssemblyPathEscape, Ui as malformedScrubResourceEntriesRefusalMessage, Un as ledgerForStack, Uo as inheritNestedStackParameterAssociations, Ur as envCredentialsAreAssumedRole, Us as resolveDockerContextDirectory, Ut as replacementNeverSwapped, Vc as nullPrototypeRecord, Vi as malformedResourcePropertiesWarning, Vn as RollbackInlinePolicyWriters, Vo as pathCrossesDottedKey, Vr as applyCallerIdentityCredentials, Vs as buildDenyExternalAccessPolicy, Vt as recheckFailedPlan, Wc as describeFileReadFailure, Wi as malformedStateRefusalMessage, Wo as recordNestedStackParameterExpressions, Ws as describeDockerCapturedOutput, Wt as resolveReplacementOldType, X as createReadOnlyAttributeHealerFactory, Xi as refuseMalformedOrphans, Xo as recordNoEchoAttributeValues, Xr as coerceParameterTypedValue, Xs as getDockerCmd, Y as formatResourceLine, Yc as resolveBucketRegion, Yi as refuseMalformedOrphanRecordsForDestroy, Yo as recordMaskOnlyValuesIn, Ys as formatDockerLoginError, Yt as inheritProducerRegions, Z as bold, Zi as refuseMalformedOrphansForDestroy, Zo as recordNoEchoParameterFreshValue, Zr as isUnboundTemplateParameter, Zs as isDockerClientEnvKey, _ as makeCanonicalizePropertiesFn, _a as repairMalformedOrphansForReadOnly, _c as resolveSkipPrefix, _i as UNREADABLE_RESOURCES_MAP_ROW, _n as isExportAliasCollision, _r as deleteSkipReason, _s as importableOutputKeys, _t as revertedNestedRowIds, a as findNestedTemplateTreeDefect, aa as refuseMalformedResourceEntriesForImport, ac as escapeRegExp, ai as AWS_NO_VALUE, an as displayTextOrWithheld, ar as isCustomResource, as as isSingleDynamicReferenceToken, at as reachableDivergentParameters, b as serviceTokenBlockingReason, ba as repairMalformedResourcePropertiesForReadOnly, bc as resolveUseCdkBootstrapAssets, bi as displayLogicalId, bn as DEFAULT_RESOURCE_WARN_AFTER_MS, bo as valueAtCoordinate, bs as orphansAfterRollback, bt as withNestedStackContext, c as renderNestedTemplateTreeDefect, ca as refuseMalformedResourcePropertiesForDestroy, cc as getDockerImageBySourceHash, ci as refStateLookupFromResource, cn as secretBearingStateKeyWarning, co as canonicalCoordinates, cr as readsNoEchoDeleteValues, cs as S3StateBackend, ct as planOrphanAdoption, d as conditionInputsFrom, da as refuseMalformedResourcePropertiesForOrphan, dc as getDefaultStateBucketName, di as parameterInputsFor, dn as exportNameNoEchoParameters, do as maskReadbackAtCoordinates, dr as withPrintingSecrets, ds as acceptedCreateOnlyDropsOf, dt as displacedPhysicalIdShown, ea as refuseMalformedOutputsForDestroy, ec as redactDockerArgvValues, ei as isImpossibleEmptyStoredAttribute, en as updatePartialMessage, eo as templateResourceTypes, es as STATE_SOURCED_BASELINE_RULES, et as green, f as parentSuppliedValues, fa as refuseMalformedResourcesForDeploy, fc as getLegacyStateBucketName, fn as exportNameSecretExposure, fo as maskWholeValue, fr as CloudControlProvider, fs as describeRegionValueKind, ft as dropSettledNestedJournals, g as mergeNoChangeOutputs, ga as repairMalformedOrphanRecordsForReadOnly, gc as resolveCaptureObservedState, gi as UNREADABLE_ORPHANS_CONTAINER_ROW, gn as collectPublishedOutputNames, go as noEchoOutputsComparison, gr as deleteIndeterminateGuards, gs as hasUnverifiableParameterRefusal, h as keptWholeReasonText, ha as refuseMalformedState, hc as resolveAutoAssetStorage, hi as STATE_RESOURCES_MALFORMED, hn as collectDeclaredOutputNames, ho as noEchoLeavesOf, hr as UNSPECIFIED_SKIP_REASON, hs as hasReasonlessBaselineRefusal, ht as recordDisplacedSkips, i as childTemplateLoader, ia as refuseMalformedResourceEntriesForDestroy, ic as warnFinchArgvExposure, ii as keepsSecretReferenceToken, in as WITHHELD_NAME_DISPLAY, ir as ccBrokenReason, is as WHOLE_DYNAMIC_REFERENCE_PATTERN, it as namesAnyDeclaredParameter, j as readProtection, ja as hasNoCloudControlHandlers, jc as expectedOwnerParam, ji as malformedLocalResourcesWarning, jn as ccRoutedFinalSnapshotError, jo as createSecretMasker, jr as classifyReplaySecretRegion, js as AssetModeResolver, jt as destroyStackRecordsView, k as isProtectionValueActive, kc as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, ki as malformedLocalOutputsWarning, kn as PRE_DELETE_SNAPSHOT_TYPES, ko as recordLogOnlyValue, kr as IntrinsicFunctionResolver, ks as loadPublishableAssetManifest, kt as replayRollback, l as templateIdentity, la as refuseMalformedResourcePropertiesForDrift, lc as Synthesizer, ln as secretSafeKeyDisplay, lo as isMarkedCoordinate, lr as isCustomResourceType$1, ls as rebuildClientForBucketRegion, lt as NESTED_PENDING_PARENT_REASON, m as isSecretBearingReferenceString, ma as refuseMalformedResourcesForExport, mc as resolveApp, mi as STATE_REGION_DIVERGED, mn as noEchoParameterValueSeed, mo as noEchoCoordinatesOf, ms as hasReadableExportSet, mt as nestedChildStackName$1, n as IMPLICIT_DELETE_DEPENDENCIES, na as refuseMalformedResourceEntries, nc as runDockerForeground, ni as carriesFetchableDynamicReference, nn as DeploymentEventsReader, no as withRetry, nr as CC_BROKEN_REASON, ns as STATE_SOURCED_READBACK_RULES, nt as yellow, o as isAbsoluteAssetPath, oa as refuseMalformedResourceEntriesForImportSave, oc as stripControlChars, oi as cfnRefValueFromPhysicalId, on as exportAliasCollisionScrubWarning, oo as DagBuilder, or as wouldReturnToSdkProvider, os as LockManager, ot as resourcesNamingDeclaredParameter, p as readRecordedConditionVerdicts, pa as refuseMalformedResourcesForDestroy, pc as loadCdkJson, pi as JSON_LISTING_HOLE_VALUE, pn as isWholeDynamicReferenceValue, po as maskedLeafCoordinatesOf, pr as slowCcOperationTimeoutMs, ps as exportNamesCarriedFrom, qc as resolveAssemblyPath, qo as provenPublicValue, qs as dockerSpawnEnvWithSensitive, qt as findNestedStackTypeChanges, r as computeImplicitDeleteEdges, ra as refuseMalformedResourceEntriesForDeploy, rc as runDockerStreaming, ri as isNamelessDynamicReferenceError, rn as DeploymentEventsStore, rr as ProviderRegistry, rs as TEMPLATE_SOURCED_RULES, rt as computeParameterTaint, s as listNestedTemplateRows, sa as refuseMalformedResourceEntriesForOrphan, sc as AssetManifestLoader, si as isStalePlaceholderArnAttribute, sn as secretBearing, so as TemplateParser, sr as TemplateNoEchoReresolver, ss as isLockInfoExpired, st as makeSiblingClaimReader, t as DeployEngine, ta as refuseMalformedResourceAttributesForOrphan, tc as redactedDockerCause, ti as carriesDynamicReference, tn as updatePartialReason, to as describeTypeWithThrottleRetry, ts as STATE_SOURCED_CROSS_GENERATION_RULES, tt as red, u as conditionFingerprint, ua as refuseMalformedResourcePropertiesForExport, uc as synthesisStatusMessage, ui as withSharedDrainBudget, un as carriedExportAliasExposure, uo as maskAtCoordinates, us as splitImportedOps, ut as displacedOpClause, v as deferredServiceTokenWarning, va as repairMalformedOutputsForReadOnly, vc as resolveStateBucketWithDefault, vi as accountArgs, vn as bindingSkippedOutputs, vo as readbackPathFor, vs as importableOutputs, vt as withNestedRevertRun, w as noEchoExactEchoLeavesOf, wa as unreadableResourceEntries, wc as CFN_TEMPLATE_BODY_LIMIT, wi as isReadableOrphanRecord, wn as orphanRecordsPrintingBag, wo as hasMaskableValues, ws as isSensitiveAttributeName, wt as journaledOrphanLines, x as withResourceDeadline, xa as repairMalformedResourcesForReadOnly, xc as stateBucketExistenceConfirmed, xi as hasReadableOrphans, xn as completedReplayEntries, xo as liveMatchesUnresolvedTokenFrame, xs as orphansCarriedFrom, xt as deleteJournaledOrphans, y as findServiceTokenRefusals, ya as repairMalformedResourceEntriesForReadOnly, yc as resolveStateBucketWithDefaultAndSource, yi as deployRefusesOrphanRowsReason, yn as DEFAULT_RESOURCE_TIMEOUT_MS, yo as readsNoEchoSource, yr as isWaitAbandonedError, ys as isReadableBag, zc as hasOwnKey, zi as malformedRenderedContainersWarning, zn as findDestructiveChanges, zo as dynamicReferenceTokens, zr as sendableAssumeRoleCommand, zs as validateAssetBucketName, zt as planFailedOps } from "./deploy-engine-D4FdwPCi.js";
6
- import { t as getCdkdVersion } from "./version-B0JEGOLV.js";
5
+ import { $c as nullPrototypeRecord, $o as provenPublicValue, $s as buildDenyExternalAccessPolicy, $t as findNestedStackTypeChanges, A as noEchoExactEchoLeavesOf, Aa as unreadableResourceEntries, Ac as resolveStateBucketWithDefault, Ai as isReadableOrphanRecord, An as orphanRecordsPrintingBag, Ao as hasMaskableValues, As as importableOutputs, At as journaledOrphanLines, Ba as MULTI_REGION_RECREATE_BLOCKED_TYPES, Bc as uploadCfnTemplate, Bi as malformedOrphanRowsKeptWarning, Bn as isFinalSnapshotError, Bo as maskSecretsInText, Br as applyRoleArnIfSet, Bs as createAssetRedirectResolver, Bt as removeProtectionTypeList, C as recordRetainedForReadoption, Ca as repairMalformedOrphansForReadOnly, Cc as getDefaultStateBucketName, Ci as UNREADABLE_RESOURCES_MAP_ROW, Cn as isExportAliasCollision, Cr as deleteSkipReason, Cs as acceptedCreateOnlyDropsOf, Ct as revertedNestedRowIds, D as withResourceDeadline, Da as repairMalformedResourcesForReadOnly, Dc as resolveAutoAssetStorage, Di as hasReadableOrphans, Dn as completedReplayEntries, Do as liveMatchesUnresolvedTokenFrame, Ds as hasReasonlessBaselineRefusal, Dt as deleteJournaledOrphans, E as serviceTokenBlockingReason, Ea as repairMalformedResourcePropertiesForReadOnly, Ec as resolveApp, Ei as displayLogicalId, En as DEFAULT_RESOURCE_WARN_AFTER_MS, Eo as valueAtCoordinate, Es as hasReadableExportSet, Et as withNestedStackContext, F as isProtectionValueActive, Fc as ssmResolvedValueType, Fi as malformedLocalOutputsWarning, Fn as PRE_DELETE_SNAPSHOT_TYPES, Fo as recordLogOnlyValue, Fr as IntrinsicFunctionResolver, Fs as AssetPublisher, Ft as replayRollback, Gc as canonicalizeRegion, Gi as malformedRenderedContainersWarning, Gn as findDestructiveChanges, Go as dynamicReferenceTokens, Gr as sendableAssumeRoleCommand, Gs as assertAssetBucketRegion, Gt as planFailedOps, Ha as isStatefulRecreateTargetSync, Hc as decodeListingKey, Hi as malformedOrphansWarning, Hn as unsupportedFinalSnapshotError, Ho as redactSecretsForState, Hr as assertSendableRoleArn, Hs as rewriteTemplateAssetReferences, Ht as demoteSupersededOrphans, I as perType, Ia as NO_CC_HANDLERS_REASON, Ic as CFN_TEMPLATE_BODY_LIMIT, Ii as malformedLocalResourceEntriesWarning, In as buildFinalSnapshotIdentifier, Io as shareLogOnlyValues, Ir as poisonRenderedSpellingsCollidingIn, Is as isSensitiveAttributeName, Jc as StageLoadError, Ji as malformedResourcesWarning, Jo as identityKeyFor, Jr as callerEnvCredentials, Js as isCrossRegionRedirect, Jt as recordUnderIdIsNotOwn, Kc as derivePartitionAndUrlSuffix, Ki as malformedResourceEntriesWarning, Kn as formatDestructiveChange, Ko as isUncertifiedBaselineMaskPosition, Kr as AWS_CREDENTIAL_ENV_KEYS, Ks as ensureAssetStorage, Kt as planRollback, L as readProtection, La as hasNoCloudControlHandlers, Lc as CFN_TEMPLATE_URL_LIMIT, Li as malformedLocalResourcesWarning, Ln as ccRoutedFinalSnapshotError, Lo as createSecretMasker, Lr as classifyReplaySecretRegion, Ls as stringifyValue, Lt as destroyStackRecordsView, M as recordedProtectionEvidence, Ma as findActionableSilentDrops, Mc as resolveUseCdkBootstrapAssets, Mi as malformedDriftResourcePropertiesWarning, Mn as stateSecretNameNeedles, Mo as logOnlyValueCount, Ms as orphansAfterRollback, Mt as makeForeignHolderScan, N as recordedProtectionNote, Nc as stateBucketExistenceConfirmed, Ni as malformedExportNamesWarning, Nn as extractDeploymentEventError, No as printingCorpusOf, Nr as DiffCalculator, Ns as orphansCarriedFrom, Nt as sameJournaledOrphans, O as noEchoAttributeNamesOf, Oa as unpreviewableOrphanRecords, Oc as resolveCaptureObservedState, Oi as hasReadableOutputs, On as journaledOrphanPrintingBag, Oo as carryLogOnlyValues, Os as hasUnverifiableParameterRefusal, Ot as dropFailedHint, P as PROTECTION_PROPERTY_BY_TYPE, Pa as unwrittenCreateOnlyReplacement, Pc as warnDeprecatedNoPrefixCliFlag, Pi as malformedExportSourceWarning, Pn as ATOMIC_FINAL_SNAPSHOT_TYPES, Po as recordLogOnlyParameterValue, Pr as INTRINSIC_KEYS, Ps as shouldRetainResource, Pt as replayFailedOperations, Qc as hasPlainPrototype, Qi as refuseDivergentRecordRegionForDestroy, Qo as carriesSecretMask, Qs as validateContainerRepoName, Qt as orphanDeleteNeedsIdentity, Ra as findReplacedReadersOfRecreateTargets, Rc as MIGRATE_TMP_PREFIX, Ri as malformedOrphanRecordsRefusalMessage, Rn as createPreDeleteFinalSnapshot, Ro as errorCauseChain, Rr as producerRegionsFromState, Rs as WorkGraph, S as keptForReadoption, Sa as repairMalformedOrphanRecordsForReadOnly, Sc as synthesisStatusMessage, Si as UNREADABLE_ORPHANS_CONTAINER_ROW, Sn as collectPublishedOutputNames, So as noEchoOutputsComparison, Sr as deleteIndeterminateGuards, Ss as splitImportedOps, T as findServiceTokenRefusals, Ta as repairMalformedResourceEntriesForReadOnly, Tc as loadCdkJson, Ti as deployRefusesOrphanRowsReason, Tn as DEFAULT_RESOURCE_TIMEOUT_MS, To as readsNoEchoSource, Tr as isWaitAbandonedError, Ts as exportNamesCarriedFrom, Ua as renderStatefulReason, Uc as expectedOwnerParam, Ui as malformedOutputsRefusalMessage, Un as maskingRetryLogger, Uo as scrubResourceRecord, Ur as explicitRoleArnOrThrow, Us as AssetModeResolver, Ut as isJournaledOrphan, Va as isStatefulRecreateTargetForReplace, Vc as CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION, Vi as malformedOrphansRefusalMessage, Vn as refusesFinalSnapshot, Vo as markSameGenerationBag, Vr as assertFlagRoleArn, Vs as loadPublishableAssetManifest, Vt as recordAfterRollbackUpdate, Wc as PARTITION_TABLE, Wi as malformedOutputsWarning, Wn as constructPathOf, Wo as DYNAMIC_REFERENCE_TOKEN_SCAN, Wr as isIamRoleArn, Ws as BOOTSTRAP_MARKER_PREFIX, Wt as isReplacementOrphan, Xc as defineOwnKey, Xi as malformedStateRefusalMessage, Xo as recordNestedStackParameterExpressions, Xs as readBootstrapMarkerBody, Xt as resolveReplacementOldType, Yc as processStackMessages, Yi as malformedScrubResourceEntriesRefusalMessage, Yn as ledgerForStack, Yo as inheritNestedStackParameterAssociations, Yr as envCredentialsAreAssumedRole, Ys as parseBootstrapMarker, Yt as replacementNeverSwapped, Zc as hasOwnKey, Zi as previewableOrphanRecords, Zn as withCreateTokenLedger, Zs as validateAssetBucketName, Zt as seedsDeleteFirstGuard, _ as makeCanonicalizePropertiesFn, _a as refuseMalformedResourcePropertiesForOrphan, _c as escapeRegExp, _i as parameterInputsFor, _n as exportNameNoEchoParameters, _o as maskReadbackAtCoordinates, _r as withPrintingSecrets, _s as CrossPrefixScanCache, _t as displacedPhysicalIdShown, a as findNestedTemplateTreeDefect, aa as refuseMalformedOutputs, ac as dockerSpawnEnvWithSensitive, ai as getAccountInfo, al as resolveAssemblyPath, ao as prefetchCreateOnlyPropertyPaths, as as wholeStringLeavesOf, at as gray, ba as refuseMalformedResourcesForExport, bc as getDockerImageBySourceHash, bi as STATE_REGION_DIVERGED, bn as noEchoParameterValueSeed, bo as noEchoCoordinatesOf, bs as isAccessDenied, bt as nestedChildStackName$1, c as renderNestedTemplateTreeDefect, ca as refuseMalformedResourceEntries, cc as getDockerCmd, ci as carriesFetchableDynamicReference, cn as DeploymentEventsReader, co as withRetry, cr as CC_BROKEN_REASON, cs as STATE_SOURCED_READBACK_RULES, ct as yellow, d as conditionInputsFrom, da as refuseMalformedResourceEntriesForImport, dc as partitionSensitiveEnv, di as AWS_NO_VALUE, dn as displayTextOrWithheld, dr as isCustomResource, ds as isSingleDynamicReferenceToken, dt as reachableDivergentParameters, ea as refuseMalformedOrphanRecords, ec as buildDockerImage, el as ownValue, es as recordMaskOnlyValue, f as parentSuppliedValues, fa as refuseMalformedResourceEntriesForImportSave, fc as redactDockerArgvValues, fi as cfnRefValueFromPhysicalId, fn as exportAliasCollisionScrubWarning, fo as DagBuilder, fr as wouldReturnToSdkProvider, fs as LockManager, ft as resourcesNamingDeclaredParameter, g as mergeNoChangeOutputs, ga as refuseMalformedResourcePropertiesForExport, gc as warnFinchArgvExposure, gi as withSharedDrainBudget, gn as carriedExportAliasExposure, go as maskAtCoordinates, gs as CrossPrefixReadError, gt as displacedOpClause, h as keptWholeReasonText, ha as refuseMalformedResourcePropertiesForDrift, hc as runDockerStreaming, hn as secretSafeKeyDisplay, ho as isMarkedCoordinate, hr as isCustomResourceType$1, hs as rebuildClientForBucketRegion, ht as NESTED_PENDING_PARENT_REASON, i as childTemplateLoader, ia as refuseMalformedOrphansForOrphan, ic as describeDockerFailure, ii as parameterTypeMayLoseSecretIdentity, il as renderAssemblyPathEscape, is as recordProvenPublicExpression, it as cyan, j as noEchoParameterNamesOf, ja as withheldAccountClause, jc as resolveStateBucketWithDefaultAndSource, ji as isReadableResourceEntry, jn as secretNamePrintingBag, jo as literalSplitDelimitersOf, js as isReadableBag, jt as loadJournaledOrphans, k as noEchoComparisonForTemplate, ka as unreadableOrphanRecords, kc as resolveSkipPrefix, ki as hasReadableResources, kn as maskEventTextWithBoundBags, ko as createUnionSecretMasker, ks as importableOutputKeys, kt as isHandledOrphan, l as templateIdentity, la as refuseMalformedResourceEntriesForDeploy, lc as isDockerClientEnvKey, li as isNamelessDynamicReferenceError, ln as DeploymentEventsStore, lr as ProviderRegistry, ls as TEMPLATE_SOURCED_RULES, lt as computeParameterTaint, m as isSecretBearingReferenceString, ma as refuseMalformedResourcePropertiesForDestroy, mc as runDockerForeground, mi as refStateLookupFromResource, mn as secretBearingStateKeyWarning, mo as canonicalCoordinates, mr as readsNoEchoDeleteValues, ms as S3StateBackend, mt as planOrphanAdoption, n as IMPLICIT_DELETE_DEPENDENCIES, na as refuseMalformedOrphans, nc as describeDockerCapturedOutput, ni as coerceParameterTypedValue, nl as describeFileReadFailure, ns as recordNoEchoAttributeValues, nt as createReadOnlyAttributeHealerFactory, o as isAbsoluteAssetPath, oa as refuseMalformedOutputsForDestroy, oc as finchSecretArgvRefusal, oi as isImpossibleEmptyStoredAttribute, on as updatePartialMessage, oo as templateResourceTypes, os as STATE_SOURCED_BASELINE_RULES, ot as green, p as readRecordedConditionVerdicts, pa as refuseMalformedResourceEntriesForOrphan, pc as redactedDockerCause, pi as isStalePlaceholderArnAttribute, pn as secretBearing, po as TemplateParser, pr as TemplateNoEchoReresolver, ps as isLockInfoExpired, pt as makeSiblingClaimReader, qc as AssemblyReader, qi as malformedResourcePropertiesWarning, qn as RollbackInlinePolicyWriters, qo as pathCrossesDottedKey, qr as applyCallerIdentityCredentials, qs as getBootstrapMarkerKey, qt as recheckFailedPlan, r as computeImplicitDeleteEdges, ra as refuseMalformedOrphansForDestroy, rc as describeDockerExecFailure, ri as isUnboundTemplateParameter, rl as displayAssemblyPath, rs as recordNoEchoParameterFreshValue, rt as bold, s as listNestedTemplateRows, sa as refuseMalformedResourceAttributesForOrphan, sc as formatDockerLoginError, si as carriesDynamicReference, sl as resolveBucketRegion, sn as updatePartialReason, so as describeTypeWithThrottleRetry, ss as STATE_SOURCED_CROSS_GENERATION_RULES, st as red, t as DeployEngine, ta as refuseMalformedOrphanRecordsForDestroy, tc as resolveDockerContextDirectory, tl as absoluteAssemblyPathEscape, tn as inheritProducerRegions, ts as recordMaskOnlyValuesIn, tt as formatResourceLine, u as conditionFingerprint, ua as refuseMalformedResourceEntriesForDestroy, uc as isMalformedEnvKey, ui as keepsSecretReferenceToken, un as WITHHELD_NAME_DISPLAY, ur as ccBrokenReason, us as WHOLE_DYNAMIC_REFERENCE_PATTERN, ut as namesAnyDeclaredParameter, va as refuseMalformedResourcesForDeploy, vc as stripControlChars, vn as exportNameSecretExposure, vo as maskWholeValue, vr as CloudControlProvider, vs as applyCrossPrefixScan, vt as dropSettledNestedJournals, w as deferredServiceTokenWarning, wa as repairMalformedOutputsForReadOnly, wc as getLegacyStateBucketName, wi as accountArgs, wn as bindingSkippedOutputs, wo as readbackPathFor, ws as describeRegionValueKind, wt as withNestedRevertRun, xa as refuseMalformedState, xc as Synthesizer, xi as STATE_RESOURCES_MALFORMED, xn as collectDeclaredOutputNames, xo as noEchoLeavesOf, xr as UNSPECIFIED_SKIP_REASON, xs as isNotImplemented, xt as recordDisplacedSkips, ya as refuseMalformedResourcesForDestroy, yc as AssetManifestLoader, yi as JSON_LISTING_HOLE_VALUE, yn as isWholeDynamicReferenceValue, yo as maskedLeafCoordinatesOf, yr as slowCcOperationTimeoutMs, ys as crossPrefixDeniedWarning, za as shownType, zc as findLargeInlineResources, zi as malformedOrphanRecordsWarning, zn as effectiveDeletionPolicy, zo as maskSecretsInError, zr as regionLessSecretName, zs as buildAssetRedirectMap, zt as withStackRecords } from "./deploy-engine-Bt-8KvUj.js";
6
+ import { t as getCdkdVersion } from "./version-DyV_xwRX.js";
7
7
  import { randomBytes, randomUUID } from "node:crypto";
8
8
  import { CopyObjectCommand, CreateBucketCommand, DeleteBucketCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetObjectCommand, HeadBucketCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchBucket, NotFound, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutBucketVersioningCommand, PutObjectCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
9
9
  import { GetRoleCommand, GetUserCommand } from "@aws-sdk/client-iam";
@@ -1306,6 +1306,14 @@ function createListCommand() {
1306
1306
 
1307
1307
  //#endregion
1308
1308
  //#region src/utils/interrupt-signals.ts
1309
+ const postCleanupListeners = /* @__PURE__ */ new WeakSet();
1310
+ function prependPostCleanupSigintListener(listener) {
1311
+ postCleanupListeners.add(listener);
1312
+ process.prependListener("SIGINT", listener);
1313
+ return () => {
1314
+ process.removeListener("SIGINT", listener);
1315
+ };
1316
+ }
1309
1317
  function forwardSigtermToSigint() {
1310
1318
  beginCommandInterruptScope();
1311
1319
  try {
@@ -1333,7 +1341,7 @@ function watchCommandInterrupt(opts) {
1333
1341
  }
1334
1342
  let stacksInFlight = 0;
1335
1343
  function gracefulOwnerArmed() {
1336
- return process.listeners("SIGINT").filter((l) => l !== handler).length - interruptWatchListenerCount() > 0;
1344
+ return process.listeners("SIGINT").filter((l) => l !== handler && !postCleanupListeners.has(l)).length - interruptWatchListenerCount() > 0;
1337
1345
  }
1338
1346
  const handler = () => {
1339
1347
  if (stacksInFlight > 0 && gracefulOwnerArmed()) {
@@ -1923,8 +1931,8 @@ function resolveRequireApproval(cliValue, logger, cdkJson = loadCdkJson()) {
1923
1931
  throw new CdkdError(`cdk.json "requireApproval" must be one of ${REQUIRE_APPROVAL_VALUES.join(", ")}, got: ${displayIdent(typeof configured === "string" ? configured : JSON.stringify(configured))}`, "INVALID_REQUIRE_APPROVAL");
1924
1932
  }
1925
1933
  function createApprovalPrompter(options) {
1934
+ if (options.yes) return Object.assign(() => Promise.resolve(true), { autoApproves: true });
1926
1935
  return (request) => {
1927
- if (options.yes) return Promise.resolve(true);
1928
1936
  return serializePrompt(() => getLiveRenderer().suspendWhile(async () => {
1929
1937
  process.stdout.write(renderApprovalRequest(request));
1930
1938
  return confirmOrRefuse("Do you wish to deploy these changes?", {
@@ -2396,7 +2404,7 @@ function collectCrossStackRefs(node, onRef) {
2396
2404
  //#region src/provisioning/register-providers.ts
2397
2405
  let providerClasses;
2398
2406
  function loadProviderClasses() {
2399
- providerClasses ??= import("./provider-classes-wbKBBEol.js");
2407
+ providerClasses ??= import("./provider-classes-eEgFT-Vt.js");
2400
2408
  return providerClasses;
2401
2409
  }
2402
2410
  function registerAllProviders(registry, classes) {
@@ -2637,6 +2645,262 @@ function createPrefixMigrationGate(opts) {
2637
2645
  };
2638
2646
  }
2639
2647
 
2648
+ //#endregion
2649
+ //#region src/cli/commands/registry-release.ts
2650
+ async function releaseRegistryMarkerQuietly(backend, stackName, region, logger, known) {
2651
+ if (stackName.includes("~")) return;
2652
+ try {
2653
+ const released = known === void 0 ? await backend.releaseRegistryMarker(stackName, region) : await backend.releaseRegistryMarker(stackName, region, known);
2654
+ logger.debug(safeMsg`Stack registry marker: ${released}`);
2655
+ } catch (error) {
2656
+ logger.warn(safeMsg`Could not delete the stack registry marker of ${displayStackName(stackName)} ` + safeMsg`(${describeAwsFailure(error).summary}). It names this state prefix, which no longer ` + `records the stack, so a deploy under another prefix treats it as stale.`);
2657
+ }
2658
+ }
2659
+
2660
+ //#endregion
2661
+ //#region src/cli/commands/cross-prefix-gate.ts
2662
+ function deployStackRegion(stack, baseRegion) {
2663
+ return stack.region || baseRegion;
2664
+ }
2665
+ function createCrossPrefixDeployGate(opts) {
2666
+ return async (gateStackName, state) => {
2667
+ if (gateStackName !== opts.stackName) return;
2668
+ if (state !== void 0) return;
2669
+ const result = await opts.guard.firstDeploy(opts.stackName, opts.region);
2670
+ applyCrossPrefixScan(result, {
2671
+ stackName: opts.stackName,
2672
+ region: opts.region,
2673
+ bucket: opts.bucket,
2674
+ recovery: opts.recovery
2675
+ }, "deploy", ...reportOnce(result));
2676
+ };
2677
+ }
2678
+ const reported = /* @__PURE__ */ new WeakSet();
2679
+ function reportOnce(result) {
2680
+ const first = !reported.has(result);
2681
+ reported.add(result);
2682
+ return first ? [(message) => getLogger().warn(message), (message) => getLogger().info(message)] : [() => void 0, () => void 0];
2683
+ }
2684
+ function createCrossPrefixDestructiveGate(opts) {
2685
+ return async (stackName, _destructive, stage) => {
2686
+ const result = await opts.cache.full(stackName, opts.region);
2687
+ applyCrossPrefixScan(result, {
2688
+ stackName,
2689
+ region: opts.region,
2690
+ bucket: opts.bucket,
2691
+ recovery: opts.recovery
2692
+ }, stage === "late" ? "deploy-late-replace" : "deploy-destructive", ...reportOnce(result));
2693
+ };
2694
+ }
2695
+ function createCrossPrefixHolder(opts) {
2696
+ return async (stackName) => {
2697
+ const result = await opts.cache.full(stackName, opts.region);
2698
+ switch (result.kind) {
2699
+ case "found": return {
2700
+ kind: "unreadable",
2701
+ what: safeMsg`bucket ${opts.bucket} also records this stack under another state prefix (${displayIdent(result.prefixes[0])}), whose record may hold it`
2702
+ };
2703
+ case "in-progress": return {
2704
+ kind: "unreadable",
2705
+ what: safeMsg`bucket ${opts.bucket} assigns this stack to another state prefix (${displayIdent(result.prefix)}), where a deploy may be in progress`
2706
+ };
2707
+ case "failed": return {
2708
+ kind: "unreadable",
2709
+ what: safeMsg`the other state prefixes of bucket ${opts.bucket} could not be checked`,
2710
+ retryable: true
2711
+ };
2712
+ case "denied":
2713
+ reportOnce(result)[0](crossPrefixDeniedWarning({
2714
+ stackName,
2715
+ region: opts.region,
2716
+ bucket: opts.bucket
2717
+ }, result.error, result.stage));
2718
+ return;
2719
+ default: return;
2720
+ }
2721
+ };
2722
+ }
2723
+ function crossPrefixEngineOptions(opts) {
2724
+ const backend = opts.backend;
2725
+ return {
2726
+ ...backend !== void 0 && { onFirstDeployLeftNoRecord: async (stackName) => {
2727
+ if (stackName !== opts.stackName) return;
2728
+ const known = await opts.guard.knownMarker?.(stackName, opts.region);
2729
+ await releaseRegistryMarkerQuietly(backend, stackName, opts.region, getLogger(), known);
2730
+ } },
2731
+ firstDeployGate: createCrossPrefixDeployGate({
2732
+ stackName: opts.stackName,
2733
+ region: opts.region,
2734
+ bucket: opts.bucket,
2735
+ recovery: opts.recovery,
2736
+ guard: opts.guard
2737
+ }),
2738
+ onDestructivePlan: createCrossPrefixDestructiveGate({
2739
+ region: opts.region,
2740
+ bucket: opts.bucket,
2741
+ recovery: opts.recovery,
2742
+ cache: opts.guard
2743
+ }),
2744
+ crossPrefixHolder: createCrossPrefixHolder({
2745
+ region: opts.region,
2746
+ bucket: opts.bucket,
2747
+ cache: opts.guard
2748
+ })
2749
+ };
2750
+ }
2751
+ function composeStateLoadedGates(crossPrefix, migration) {
2752
+ return async (stackName, state) => {
2753
+ await crossPrefix(stackName, state);
2754
+ if (migration) await migration(stackName, state);
2755
+ };
2756
+ }
2757
+
2758
+ //#endregion
2759
+ //#region src/state/stack-registry.ts
2760
+ function unwrapReadError(error) {
2761
+ return error instanceof CrossPrefixReadError ? error.cause : error;
2762
+ }
2763
+ function topLevelStackName(stackName) {
2764
+ return stackName.split("~")[0];
2765
+ }
2766
+ var CrossPrefixGuard = class {
2767
+ scan;
2768
+ backend;
2769
+ readOnly;
2770
+ markers = /* @__PURE__ */ new Map();
2771
+ answers = /* @__PURE__ */ new Map();
2772
+ constructor(backend, opts = {}) {
2773
+ this.backend = backend;
2774
+ this.readOnly = opts.readOnly === true;
2775
+ this.scan = opts.scan ?? new CrossPrefixScanCache(backend);
2776
+ }
2777
+ get target() {
2778
+ return this.scan.target;
2779
+ }
2780
+ full(stackName, region, when = "now") {
2781
+ const key = JSON.stringify([stackName, region]);
2782
+ let answer = this.answers.get(key);
2783
+ if (answer === void 0) {
2784
+ answer = this.evaluate(stackName, region, false, when);
2785
+ this.answers.set(key, answer);
2786
+ } else if (when === "now") this.scan.target.rank(stackName, region, "now");
2787
+ return answer;
2788
+ }
2789
+ firstDeploy(stackName, region) {
2790
+ const key = JSON.stringify([stackName, region]);
2791
+ const answer = this.evaluate(stackName, region, true, "now");
2792
+ this.answers.set(key, answer);
2793
+ return answer;
2794
+ }
2795
+ async knownMarker(stackName, region) {
2796
+ const read = this.markers.get(JSON.stringify([topLevelStackName(stackName), region]));
2797
+ if (read === void 0) return void 0;
2798
+ return read.catch(() => void 0);
2799
+ }
2800
+ marker(top, region, fresh = false) {
2801
+ const key = JSON.stringify([top, region]);
2802
+ let read = fresh ? void 0 : this.markers.get(key);
2803
+ if (read === void 0) {
2804
+ read = this.backend.getRegistryMarker(top, region);
2805
+ this.markers.set(key, read);
2806
+ }
2807
+ return read;
2808
+ }
2809
+ async evaluate(stackName, region, firstDeploy, when) {
2810
+ const top = topLevelStackName(stackName);
2811
+ const claimable = top === stackName && !this.readOnly;
2812
+ if (firstDeploy && claimable && !this.markers.has(JSON.stringify([top, region]))) {
2813
+ if (await this.claim(top, region) === "claimed") return { kind: "clear" };
2814
+ }
2815
+ for (let attempt = 0; attempt < 2; attempt++) {
2816
+ let marker;
2817
+ try {
2818
+ marker = await this.marker(top, region, attempt > 0);
2819
+ } catch (error) {
2820
+ return this.fallback(stackName, region, when, error);
2821
+ }
2822
+ if (marker === null) {
2823
+ if (firstDeploy) {
2824
+ if (!claimable) return { kind: "clear" };
2825
+ const claimed = await this.claim(top, region);
2826
+ if (claimed === "conflict") continue;
2827
+ if (claimed !== "claimed") return this.fallback(stackName, region, when, claimed.error);
2828
+ return { kind: "clear" };
2829
+ }
2830
+ const scanned = await this.scan.full(stackName, region, when);
2831
+ if (scanned.kind === "clear" && claimable) {
2832
+ if (await this.claim(top, region) === "conflict") continue;
2833
+ }
2834
+ return scanned;
2835
+ }
2836
+ if (marker.prefix === this.backend.prefix) return { kind: "clear" };
2837
+ let held;
2838
+ let locked;
2839
+ try {
2840
+ held = await this.backend.recordUnderPrefix(marker.prefix, stackName, region);
2841
+ locked = held === "holder" ? false : await this.backend.lockUnderPrefix(marker.prefix, top, region);
2842
+ } catch (error) {
2843
+ return isAccessDenied(error) ? {
2844
+ kind: "denied",
2845
+ error,
2846
+ stage: "probe"
2847
+ } : {
2848
+ kind: "failed",
2849
+ error
2850
+ };
2851
+ }
2852
+ if (held === "holder") return {
2853
+ kind: "found",
2854
+ prefixes: [marker.prefix]
2855
+ };
2856
+ if (locked) return {
2857
+ kind: "in-progress",
2858
+ prefix: marker.prefix
2859
+ };
2860
+ const stale = held === "empty" ? [marker.prefix] : [];
2861
+ const scanned = await this.scan.full(stackName, region, when);
2862
+ if (scanned.kind !== "clear") return scanned;
2863
+ const allStale = [.../* @__PURE__ */ new Set([...stale, ...scanned.stale ?? []])];
2864
+ const answer = {
2865
+ kind: "clear",
2866
+ ...allStale.length > 0 && { stale: allStale }
2867
+ };
2868
+ if (!claimable) return answer;
2869
+ if (await this.claim(top, region, marker.etag) === "conflict") continue;
2870
+ return answer;
2871
+ }
2872
+ return {
2873
+ kind: "failed",
2874
+ error: new CrossPrefixReadError(`_cdkd-registry/${region}/${top}.json`, Object.assign(/* @__PURE__ */ new Error("the marker changed twice while cdkd was claiming it"), { name: "ConcurrentClaim" }))
2875
+ };
2876
+ }
2877
+ async claim(top, region, ifMatch) {
2878
+ try {
2879
+ const result = await this.backend.claimRegistryMarker(top, region, ifMatch);
2880
+ if (result === "claimed") this.markers.set(JSON.stringify([top, region]), Promise.resolve({
2881
+ prefix: this.backend.prefix,
2882
+ etag: ""
2883
+ }));
2884
+ return result;
2885
+ } catch (error) {
2886
+ return { error };
2887
+ }
2888
+ }
2889
+ async fallback(stackName, region, when, error) {
2890
+ if (!isAccessDenied(error) && !isNotImplemented(unwrapReadError(error))) return {
2891
+ kind: "failed",
2892
+ error
2893
+ };
2894
+ const scanned = await this.scan.full(stackName, region, when);
2895
+ return scanned.kind === "clear" ? {
2896
+ kind: "denied",
2897
+ error,
2898
+ stage: "registry",
2899
+ ...scanned.stale && { stale: scanned.stale }
2900
+ } : scanned;
2901
+ }
2902
+ };
2903
+
2640
2904
  //#endregion
2641
2905
  //#region src/cli/commands/deploy.ts
2642
2906
  async function deployCommand(stacks, options) {
@@ -2706,6 +2970,7 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
2706
2970
  };
2707
2971
  process.on("SIGINT", topLevelSigintHandler);
2708
2972
  const unforwardSigterm = forwardSigtermToSigint();
2973
+ let preflightBackendForCleanup;
2709
2974
  try {
2710
2975
  logger.info(cyan(synthesisStatusMessage(app, "Synthesizing CDK app...")));
2711
2976
  const synthesizer = new Synthesizer();
@@ -2721,6 +2986,7 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
2721
2986
  };
2722
2987
  const [result, statePrep] = await Promise.all([synthesizer.synthesize(synthOptions), statePrepPromise]);
2723
2988
  const { stateBucket, preflightStateBackend, exportIndexStore } = statePrep;
2989
+ preflightBackendForCleanup = preflightStateBackend;
2724
2990
  synthOptions.stateBucket = stateBucket;
2725
2991
  const refusalRecovery = {
2726
2992
  profile: options.profile,
@@ -2787,6 +3053,8 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
2787
3053
  ignoreErrors: options.ignoreErrors === true
2788
3054
  });
2789
3055
  refuseMalformedNestedTemplateTrees(targetStacks);
3056
+ const baseRegion = namedCliRegion(options.region) ?? "us-east-1";
3057
+ const crossPrefixGuard = new CrossPrefixGuard(preflightStateBackend, { readOnly: options.dryRun === true });
2790
3058
  await synthesizer.expandMacrosForStacks(targetStacks, synthOptions);
2791
3059
  const { STSClient, GetCallerIdentityCommand } = await import("@aws-sdk/client-sts");
2792
3060
  const stsClient = new STSClient({
@@ -2816,7 +3084,6 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
2816
3084
  };
2817
3085
  const dagBuilder = new DagBuilder({ relaxCdkVpcDefensiveDeps: !!options.aggressiveVpcParallel });
2818
3086
  const diffCalculator = new DiffCalculator();
2819
- const baseRegion = namedCliRegion(options.region) ?? "us-east-1";
2820
3087
  const workGraph = new WorkGraph();
2821
3088
  const stackMap = new Map(targetStacks.map((s) => [s.stackName, s]));
2822
3089
  const stackRedirects = /* @__PURE__ */ new Map();
@@ -2864,13 +3131,14 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
2864
3131
  logger.debug(`Work graph: ${summary["asset-publish"]} asset(s), ${summary["stack"]} stack(s)`);
2865
3132
  const bufferStackOutput = targetStacks.length > 1;
2866
3133
  let totalUnaddressed = 0;
3134
+ let totalCrossPrefixKept = 0;
2867
3135
  let cancelledStacks = 0;
2868
3136
  const runStack = async (stackInfo) => {
2869
3137
  return withSkipPrefix(skipPrefix, () => runStackInner(stackInfo));
2870
3138
  };
2871
3139
  const runStackInner = async (stackInfo) => {
2872
3140
  if (deployInterrupted) throw new DeployCancelledError(`Deploy interrupted before stack '${stackInfo.stackName}' started — not starting it.`);
2873
- const stackRegion = stackInfo.region || baseRegion;
3141
+ const stackRegion = deployStackRegion(stackInfo, baseRegion);
2874
3142
  logger.info(`\n${cyan("Deploying stack:")} ${bold(cyan(stackInfo.stackName))}${stackRegion !== baseRegion ? gray(` (region: ${stackRegion})`) : ""}`);
2875
3143
  const stackAwsClients = new AwsClients({
2876
3144
  region: stackRegion,
@@ -2908,6 +3176,14 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
2908
3176
  skipPrefix,
2909
3177
  yes: options.yes
2910
3178
  });
3179
+ const crossPrefix = crossPrefixEngineOptions({
3180
+ stackName: stackInfo.stackName,
3181
+ region: stackRegion,
3182
+ bucket: stateBucket,
3183
+ recovery: refusalRecovery,
3184
+ guard: crossPrefixGuard,
3185
+ backend: preflightStateBackend
3186
+ });
2911
3187
  let recreateTargets;
2912
3188
  if (options.recreateViaCcApi?.length || options.recreateViaSdkProvider?.length) {
2913
3189
  const stateForRecreateCheck = await stackStateBackend.getState(stackInfo.stackName, stackRegion);
@@ -2987,7 +3263,10 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
2987
3263
  refusalRecovery,
2988
3264
  ...assetRedirect && { assetRedirect },
2989
3265
  ...eventRecorder && { eventRecorder },
2990
- ...migrationGate && { onCurrentStateLoaded: migrationGate },
3266
+ onCurrentStateLoaded: composeStateLoadedGates(crossPrefix.firstDeployGate, migrationGate),
3267
+ ...crossPrefix.onFirstDeployLeftNoRecord && { onFirstDeployLeftNoRecord: crossPrefix.onFirstDeployLeftNoRecord },
3268
+ onDestructivePlan: crossPrefix.onDestructivePlan,
3269
+ crossPrefixHolder: crossPrefix.crossPrefixHolder,
2991
3270
  ...options.pinCcApi?.length && { pinCcApi: {
2992
3271
  stackName: stackInfo.stackName,
2993
3272
  logicalIds: new Set(options.pinCcApi)
@@ -3038,10 +3317,15 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
3038
3317
  logger.info(` Updated: ${updatedTotal > 0 ? yellow(updatedTotal) : gray(updatedTotal)}`);
3039
3318
  logger.info(` Deleted: ${deployResult.deleted > 0 ? red(deployResult.deleted) : gray(deployResult.deleted)}`);
3040
3319
  if (deployResult.deleteSkipped > 0) logger.info(` Skipped (not deleted): ${yellow(deployResult.deleteSkipped)}`);
3320
+ const crossPrefixKept = deployResult.crossPrefixKept ?? 0;
3321
+ if (crossPrefixKept > 0) logger.info(` Kept (replacement refused: another state prefix records the stack, or the check could not run): ${yellow(crossPrefixKept)}`);
3041
3322
  if (ownUpdatePartial > 0) logger.info(safeMsg` of which left an orphaned predecessor: ${yellow(ownUpdatePartial)}`);
3042
3323
  if (nestedUpdatePartial > 0) logger.info(safeMsg` Left an orphaned predecessor in a nested stack: ${yellow(nestedUpdatePartial)}`);
3043
- const stackUnaddressed = deployResult.deleteSkipped + deployResult.updatePartial;
3044
- if (!options.dryRun) totalUnaddressed += stackUnaddressed;
3324
+ const stackUnaddressed = deployResult.deleteSkipped + deployResult.updatePartial + crossPrefixKept;
3325
+ if (!options.dryRun) {
3326
+ totalUnaddressed += stackUnaddressed;
3327
+ totalCrossPrefixKept += crossPrefixKept;
3328
+ }
3045
3329
  logger.info(` Unchanged: ${gray(deployResult.unchanged)}`);
3046
3330
  logger.info(` Duration: ${cyan((deployResult.durationMs / 1e3).toFixed(2) + "s")}`);
3047
3331
  if (deployResult.attributeFallbackCount > 0) logger.warn(`${deployResult.attributeFallbackCount} attribute resolution(s) fell back to the physical ID (potentially wrong values); re-run with --strict-getatt to fail on these`);
@@ -3057,7 +3341,7 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
3057
3341
  created: deployResult.created,
3058
3342
  updated: updatedTotal,
3059
3343
  deleted: deployResult.deleted,
3060
- ...deployResult.deleteSkipped + deployResult.updatePartial > 0 && { skipped: deployResult.deleteSkipped + deployResult.updatePartial }
3344
+ ...stackUnaddressed > 0 && { skipped: stackUnaddressed }
3061
3345
  }, deployResult.durationMs);
3062
3346
  } catch (deployError) {
3063
3347
  if (deployError instanceof DeployCancelledError) {
@@ -3102,11 +3386,12 @@ Force-quit: stack locks may not be released. If the next run reports a lock, run
3102
3386
  if (!outcome.ok) throw outcome.error;
3103
3387
  }
3104
3388
  });
3105
- if (totalUnaddressed > 0 && !options.allowUnaddressed) throw new PartialFailureError(`Deploy left ${totalUnaddressed} resource(s) unaddressed, so they may still exist in AWS. The two cases differ in what happens next: a DELETE the provider could not issue KEEPS its state record, so the next 'cdkd deploy' re-attempts it, while a replacement's surviving predecessor is NOT tracked and will never be retried — delete it by hand. The per-stack summaries above give the breakdown, and each resource's own warning names its cause and remedy. ` + (cancelledStacks > 0 ? `Note ${cancelledStacks} stack(s) were also cancelled and never deployed, so the template is not fully applied beyond the resources named above. ` : "") + `Pass --allow-unaddressed to exit 0 instead.`);
3389
+ if (totalUnaddressed > 0 && !options.allowUnaddressed) throw new PartialFailureError(`Deploy left ${totalUnaddressed} resource(s) unaddressed, so they may still exist in AWS. The two cases differ in what happens next: a DELETE the provider could not issue KEEPS its state record, so the next 'cdkd deploy' re-attempts it, while a replacement's surviving predecessor is NOT tracked and will never be retried — delete it by hand. ` + (totalCrossPrefixKept > 0 ? "A replacement kept because another state prefix records the stack, or the check could not run, keeps its old resource and applies no new value — resolve the pair, or let the check run, and re-deploy. " : "") + "The per-stack summaries above give the breakdown, and each resource's own warning names its cause and remedy. " + (cancelledStacks > 0 ? `Note ${cancelledStacks} stack(s) were also cancelled and never deployed, so the template is not fully applied beyond the resources named above. ` : "") + `Pass --allow-unaddressed to exit 0 instead.`);
3106
3390
  } finally {
3107
3391
  unforwardSigterm();
3108
3392
  process.removeListener("SIGINT", topLevelSigintHandler);
3109
3393
  awsClients.destroy();
3394
+ preflightBackendForCleanup?.destroyClient();
3110
3395
  }
3111
3396
  }
3112
3397
  function createDeployCommand() {
@@ -10744,19 +11029,40 @@ async function acquireStackLock(opts) {
10744
11029
  get interrupted() {
10745
11030
  return interrupted;
10746
11031
  },
10747
- async release({ failureMessage, beforeRelease }) {
11032
+ async release({ failureMessage, beforeRelease, holdUntil }) {
10748
11033
  if (released) return;
10749
11034
  released = true;
10750
- try {
10751
- await beforeRelease?.();
11035
+ const releaseNow = async () => {
10752
11036
  try {
10753
11037
  await lockManager.releaseLock(stackName, region);
10754
11038
  lockHeld = false;
10755
11039
  } catch (releaseErr) {
10756
11040
  getLogger().warn(safeMsg`${failureMessage}: ${describeAwsFailure(releaseErr).detail}`);
10757
11041
  }
11042
+ };
11043
+ let deferred = false;
11044
+ try {
11045
+ await beforeRelease?.();
11046
+ if (holdUntil !== void 0) {
11047
+ process.removeListener("SIGINT", sigintHandler);
11048
+ let forced = false;
11049
+ const removeDeferred = prependPostCleanupSigintListener(() => {
11050
+ if (!interrupted) {
11051
+ interrupted = true;
11052
+ return;
11053
+ }
11054
+ if (forced || !lockHeld) return;
11055
+ forced = true;
11056
+ lockManager.releaseLock(stackName, region).catch(() => {});
11057
+ process.stderr.write(`\nForce-quit (post-destroy cleanup): stack lock may not be released.${forceQuitRecoveryClause(stackName, region, recovery)}\n`);
11058
+ });
11059
+ holdUntil.defer(holdUntil.work.then(() => void 0, () => void 0).then(releaseNow).finally(removeDeferred));
11060
+ deferred = true;
11061
+ return;
11062
+ }
11063
+ await releaseNow();
10758
11064
  } finally {
10759
- process.removeListener("SIGINT", sigintHandler);
11065
+ if (!deferred) process.removeListener("SIGINT", sigintHandler);
10760
11066
  }
10761
11067
  }
10762
11068
  };
@@ -10864,6 +11170,16 @@ function countProtectedJournaledOrphans(orphans, region) {
10864
11170
  }
10865
11171
  return count;
10866
11172
  }
11173
+ async function releaseRegistryMarkerAfterDestroy(ctx, stackName, region, logger) {
11174
+ if (ctx.crossPrefixCheck === void 0) return;
11175
+ try {
11176
+ const known = await ctx.crossPrefixCheck.cache.knownMarker?.(stackName, region);
11177
+ const released = await ctx.stateBackend.releaseRegistryMarker(stackName, region, known);
11178
+ logger.debug(safeMsg`Stack registry marker: ${released}`);
11179
+ } catch (error) {
11180
+ logger.warn(safeMsg`Could not delete the stack registry marker of ${displayStackName(stackName)} ` + safeMsg`(${describeAwsFailure(error).summary}). It names this state prefix, which no longer ` + `records the stack, so a deploy under another prefix treats it as stale.`);
11181
+ }
11182
+ }
10867
11183
  async function runDestroyForStack(stackName, state, ctx) {
10868
11184
  const providerClasses = await loadProviderClasses();
10869
11185
  const logger = getLogger();
@@ -10878,8 +11194,11 @@ async function runDestroyForStack(stackName, state, ctx) {
10878
11194
  errorCount: 0,
10879
11195
  interrupted: false
10880
11196
  };
11197
+ const retainedForReadoption = [];
11198
+ let retainedEarlier;
10881
11199
  const guardIndeterminateTargets = /* @__PURE__ */ new Set();
10882
11200
  const regionForState = state.region ?? ctx.baseRegion;
11201
+ const crossPrefixScan = ctx.crossPrefixCheck?.cache.full(stackName, regionForState);
10883
11202
  const refusalRecovery = {
10884
11203
  profile: ctx.profile,
10885
11204
  stateBucket: ctx.stateBucket,
@@ -10902,6 +11221,15 @@ async function runDestroyForStack(stackName, state, ctx) {
10902
11221
  const resourceCount = Object.keys(state.resources).length;
10903
11222
  const orphanCount = (state.orphans ?? []).length;
10904
11223
  refuseMalformedOutputsForDestroy(state, stackName, regionForState, refusalRecovery);
11224
+ if (crossPrefixScan) applyCrossPrefixScan(await crossPrefixScan, {
11225
+ stackName,
11226
+ region: regionForState,
11227
+ bucket: ctx.stateBucket,
11228
+ recovery: {
11229
+ profile: ctx.profile,
11230
+ stateBucket: ctx.stateBucket
11231
+ }
11232
+ }, "destroy", (message) => logger.warn(message), (message) => logger.info(message));
10905
11233
  if (resourceCount === 0 && orphanCount === 0 && journaledOrphans.count === 0) {
10906
11234
  logger.info(`Stack ${displayStackName(stackName)} has no resources, cleaning up state...`);
10907
11235
  const emptyLock = await acquireStackLock({
@@ -10925,6 +11253,7 @@ async function runDestroyForStack(stackName, state, ctx) {
10925
11253
  if (!(!recheck || recheckResources === 0 && recheckOrphans === 0)) throw new Error(`Stack ${displayStackName(stackName)} (${displaySafe(regionForState, { asciiOnly: true })}) was empty when this run started but now has ${recheckResources} resource(s) and ${recheckOrphans} rollback-orphaned resource(s) — another cdkd process wrote to it. Re-run the destroy to act on the current state.`);
10926
11254
  await ctx.stateBackend.deleteState(stackName, regionForState);
10927
11255
  logger.info(`${green("✓")} State deleted`);
11256
+ await Promise.all([recordRetainedForReadoption(ctx.stateBackend, stackName, regionForState, [], logger), releaseRegistryMarkerAfterDestroy(ctx, stackName, regionForState, logger)]);
10928
11257
  } finally {
10929
11258
  await emptyLock.release({ failureMessage: "Failed to release lock after empty-state cleanup" });
10930
11259
  }
@@ -11012,11 +11341,14 @@ async function runDestroyForStack(stackName, state, ctx) {
11012
11341
  }
11013
11342
  const renderer = getLiveRenderer();
11014
11343
  let statePreserved = false;
11344
+ let heldTail;
11345
+ let stackFinished = false;
11015
11346
  let journaledOrphanFailures = 0;
11016
11347
  let journaledOrphanSkips = 0;
11017
11348
  const lock = await acquireStackLock({
11018
11349
  ...stackLockBase,
11019
11350
  onFirstSignal: () => {
11351
+ if (stackFinished) return;
11020
11352
  renderer.printAbove(() => {
11021
11353
  process.stderr.write("\nInterrupted — finishing in-flight deletes, then flushing state and releasing the lock (press Ctrl-C again to force-quit)...\n");
11022
11354
  });
@@ -11190,6 +11522,17 @@ async function runDestroyForStack(stackName, state, ctx) {
11190
11522
  if (shouldRetainResource(resource.deletionPolicy)) {
11191
11523
  logger.info(` ⊘ ${displaySafe(logicalId)} (${displaySafe(resource.resourceType)}) retained — DeletionPolicy: ${displaySafe(resource.deletionPolicy)}`);
11192
11524
  result.retainedCount++;
11525
+ if (keptForReadoption(resource)) {
11526
+ retainedForReadoption.push({
11527
+ logicalId,
11528
+ resourceType: resource.resourceType,
11529
+ physicalId: resource.physicalId
11530
+ });
11531
+ if (retainedEarlier === void 0) {
11532
+ retainedEarlier = Promise.resolve().then(() => ctx.stateBackend.loadRetainedRecord(stackName, regionForState));
11533
+ retainedEarlier.catch(() => void 0);
11534
+ }
11535
+ }
11193
11536
  recordDestroyEvent(ctx.eventRecorder, {
11194
11537
  eventType: "RESOURCE_RETAINED",
11195
11538
  stackName,
@@ -11401,7 +11744,16 @@ async function runDestroyForStack(stackName, state, ctx) {
11401
11744
  if (!preserveState) {
11402
11745
  await ctx.stateBackend.deleteState(stackName, regionForState);
11403
11746
  logger.debug("State deleted");
11404
- if (ctx.exportIndexStore) await ctx.exportIndexStore.removeStack(stackName, regionForState);
11747
+ const writeKept = () => recordRetainedForReadoption(ctx.stateBackend, stackName, regionForState, retainedForReadoption, logger, retainedEarlier);
11748
+ const releaseMarker = () => releaseRegistryMarkerAfterDestroy(ctx, stackName, regionForState, logger);
11749
+ if (ctx.deferRegistryTail !== void 0) {
11750
+ heldTail = writeKept().then(releaseMarker);
11751
+ await ctx.exportIndexStore?.removeStack(stackName, regionForState);
11752
+ } else await Promise.all([
11753
+ writeKept(),
11754
+ releaseMarker(),
11755
+ ctx.exportIndexStore?.removeStack(stackName, regionForState)
11756
+ ]);
11405
11757
  } else {
11406
11758
  try {
11407
11759
  await ctx.stateBackend.saveState(stackName, regionForState, buildDestroySnapshot());
@@ -11448,6 +11800,10 @@ async function runDestroyForStack(stackName, state, ctx) {
11448
11800
  try {
11449
11801
  await lock.release({
11450
11802
  failureMessage: `Failed to release lock for stack ${displayStackName(stackName)}`,
11803
+ ...heldTail !== void 0 && ctx.deferRegistryTail !== void 0 && { holdUntil: {
11804
+ work: heldTail,
11805
+ defer: ctx.deferRegistryTail
11806
+ } },
11451
11807
  beforeRelease: async () => {
11452
11808
  try {
11453
11809
  renderer.stop();
@@ -11458,6 +11814,7 @@ async function runDestroyForStack(stackName, state, ctx) {
11458
11814
  logger.debug("Releasing lock...");
11459
11815
  }
11460
11816
  });
11817
+ stackFinished = true;
11461
11818
  } finally {
11462
11819
  restoreBaseRegionAndClients();
11463
11820
  }
@@ -11508,6 +11865,10 @@ function orderConsumersBeforeProducers(stackNames, consumerToProducers) {
11508
11865
  }
11509
11866
  return ordered;
11510
11867
  }
11868
+ function plannedDestroyRegion(refs, synthRegion, cliRegion) {
11869
+ if (refs.length === 1) return refs[0]?.region || cliRegion;
11870
+ if (refs.length > 1 && synthRegion && refs.some((r) => r.region === synthRegion)) return synthRegion;
11871
+ }
11511
11872
  async function purgeEventsAfterDestroy(reader, stackName, region, opts, logger) {
11512
11873
  if (opts.purgeEvents !== true || opts.runResult !== "SUCCEEDED" || opts.interrupted) return null;
11513
11874
  try {
@@ -11565,6 +11926,9 @@ async function destroyCommand(stackArgs, options) {
11565
11926
  interruptWatch.dispose();
11566
11927
  throw error;
11567
11928
  }
11929
+ let stateBackendForCleanup;
11930
+ const deferredTails = [];
11931
+ let deferRegistryTail;
11568
11932
  try {
11569
11933
  const stateConfig = {
11570
11934
  bucket: stateBucket,
@@ -11574,6 +11938,7 @@ async function destroyCommand(stackArgs, options) {
11574
11938
  ...options.region && { region: options.region },
11575
11939
  ...options.profile && { profile: options.profile }
11576
11940
  });
11941
+ stateBackendForCleanup = stateBackend;
11577
11942
  await stateBackend.verifyBucketExists();
11578
11943
  const lockManager = new LockManager(awsClients.s3, stateConfig);
11579
11944
  const exportIndexStore = new ExportIndexStore(awsClients.s3, stateBucket, options.statePrefix, region, stateBackend, { profile: options.profile });
@@ -11716,6 +12081,14 @@ async function destroyCommand(stackArgs, options) {
11716
12081
  arr.push(ref);
11717
12082
  stateRefsByName.set(ref.stackName, arr);
11718
12083
  }
12084
+ const crossPrefixCheck = { cache: new CrossPrefixGuard(stateBackend) };
12085
+ if (stackNames.length > 1) deferRegistryTail = (released) => deferredTails.push(released);
12086
+ for (const name of stackNames) {
12087
+ const synth = appStacks.find((s) => s.stackName === name);
12088
+ if (synth?.terminationProtection === true && !options.removeProtection) continue;
12089
+ const planned = plannedDestroyRegion(stateRefsByName.get(name) ?? [], synth?.region, region);
12090
+ if (planned !== void 0) crossPrefixCheck.cache.full(name, planned, "prestart");
12091
+ }
11719
12092
  for (const [stackIndex, stackName] of stackNames.entries()) {
11720
12093
  logger.info(`\nPreparing to destroy stack: ${displaySafe(stackName)}`);
11721
12094
  const refs = stateRefsByName.get(stackName) ?? [];
@@ -11733,15 +12106,12 @@ async function destroyCommand(stackArgs, options) {
11733
12106
  continue;
11734
12107
  }
11735
12108
  }
12109
+ const plannedRegion = plannedDestroyRegion(refs, synthRegion, region);
11736
12110
  let stackTargetRegion;
11737
12111
  if (refs.length === 0) {
11738
12112
  logger.warn(`No state found for stack ${displaySafe(stackName)}, skipping`);
11739
12113
  continue;
11740
- } else if (refs.length === 1) {
11741
- const onlyRegion = refs[0]?.region;
11742
- if (!onlyRegion) stackTargetRegion = region;
11743
- else stackTargetRegion = onlyRegion;
11744
- } else if (synthRegion && refs.some((r) => r.region === synthRegion)) stackTargetRegion = synthRegion;
12114
+ } else if (plannedRegion !== void 0) stackTargetRegion = plannedRegion;
11745
12115
  else {
11746
12116
  const regions = refs.map((r) => r.region === void 0 ? "(legacy)" : plainOrDescribed(r.region, "region")).join(", ");
11747
12117
  const orphanOneClause = withheldAccountClause(accountRecovery, "the command below prints").trimEnd();
@@ -11819,6 +12189,8 @@ async function destroyCommand(stackArgs, options) {
11819
12189
  skipFinalSnapshot: options.skipFinalSnapshot === true,
11820
12190
  resolveSecretDerivedPrincipals: {},
11821
12191
  stackDestroy: true,
12192
+ crossPrefixCheck,
12193
+ ...deferRegistryTail !== void 0 && { deferRegistryTail },
11822
12194
  exportIndexStore,
11823
12195
  ...TemplateNoEchoReresolver.usable(synthStack?.template) && (synthStack.region === void 0 || synthStack.region === stackTargetRegion) && { noEchoReresolver: new TemplateNoEchoReresolver({
11824
12196
  template: synthStack.template,
@@ -11872,9 +12244,11 @@ async function destroyCommand(stackArgs, options) {
11872
12244
  if (interrupted || interruptWatch.interrupted() && stoppedEarly) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd destroy' to finish.`);
11873
12245
  if (totalSkipped > 0) throw new PartialFailureError(`Destroy skipped ${totalSkipped} entr${totalSkipped === 1 ? "y" : "ies"} whose delete cdkd did not confirm, so the underlying resources may still exist in AWS. A skipped nested stack counts as ONE entry and may cover several of its own resources — the per-stack summaries above give the exact breakdown. State preserved (the records are kept). The per-resource 'skipped (...)' lines and their warnings name each cause and whether repairing the record in state.json helps: where it does, repair it and re-run 'cdkd destroy'; otherwise (for example a custom-resource Delete handler that reported FAILED), delete the resources by hand and drop the records with 'cdkd state orphan <stack> --stack-region <region>'.`);
11874
12246
  } finally {
12247
+ await Promise.allSettled(deferredTails);
11875
12248
  unforwardSigterm();
11876
12249
  interruptWatch.dispose();
11877
12250
  awsClients.destroy();
12251
+ stateBackendForCleanup?.destroyClient();
11878
12252
  }
11879
12253
  }
11880
12254
  function createDestroyCommand() {
@@ -14022,7 +14396,7 @@ async function exportCommand(stackArg, options) {
14022
14396
  2. Re-run the phase 2 UPDATE manually with the full synth template:
14023
14397
  ${phase2RetryCommand(cfnStackName)}\n 3. Once phase 2 succeeds, clean up cdkd's stale state record.${orphan.note}\n Run: ${orphan.command}`);
14024
14398
  }
14025
- await stateBackend.deleteState(resolvedStackName, targetRegion);
14399
+ await removeExportedStackRecord(stateBackend, resolvedStackName, targetRegion, logger);
14026
14400
  logger.info(`cdkd state for ${quotedOrNotShown(resolvedStackName)} (${quotedRegion(targetRegion)}) removed. Manage the stack with 'cdk deploy' or 'aws cloudformation' from here on.`);
14027
14401
  printNextSteps({
14028
14402
  cfnStackName,
@@ -15626,6 +16000,11 @@ async function buildResolvedParametersPerStack(args) {
15626
16000
  intrinsicSkippedByCdkdName
15627
16001
  };
15628
16002
  }
16003
+ async function removeExportedStackRecord(stateBackend, stackName, region, logger) {
16004
+ await stateBackend.deleteState(stackName, region);
16005
+ await recordRetainedForReadoption(stateBackend, stackName, region, [], logger);
16006
+ await releaseRegistryMarkerQuietly(stateBackend, stackName, region, logger);
16007
+ }
15629
16008
  async function runPerStackImportLoop(args) {
15630
16009
  const logger = getLogger();
15631
16010
  const { rootStackName, rootRegion, rootStackInfoNestedTemplates, rootTemplateFormat, tree, rootTemplate, cfnStackNameOverrides, rootParameters, deps, options } = args;
@@ -15903,7 +16282,7 @@ async function runPerStackImportLoop(args) {
15903
16282
  }
15904
16283
  const stateDeletionFailures = [];
15905
16284
  for (const node of leafFirst) try {
15906
- await deps.stateBackend.deleteState(node.stackName, node.region);
16285
+ await removeExportedStackRecord(deps.stateBackend, node.stackName, node.region, logger);
15907
16286
  logger.info(`cdkd state for ${quotedOrNotShown(node.stackName)} (${quotedRegion(node.region)}) removed.`);
15908
16287
  } catch (err) {
15909
16288
  stateDeletionFailures.push({
@@ -16129,6 +16508,10 @@ const STATE_READ_REASONS = {
16129
16508
  "read-failed": STATE_READ_FAILED_REASON,
16130
16509
  "resources-malformed": "resources is not a JSON object; run `cdkd state show --json` to see the record"
16131
16510
  };
16511
+ function stateDestroyTargets(refs, stackRegion) {
16512
+ if (stackRegion) return refs.filter((r) => r.region === stackRegion || !r.region);
16513
+ return refs.length === 1 ? [...refs] : void 0;
16514
+ }
16132
16515
  function resourceCountOrNull(resources) {
16133
16516
  if (resources === void 0 || resources === null) return 0;
16134
16517
  if (typeof resources !== "object" || Array.isArray(resources)) return null;
@@ -16249,7 +16632,10 @@ async function setupStateBackend(options) {
16249
16632
  bucket,
16250
16633
  prefix,
16251
16634
  exportIndexStore: new ExportIndexStore(awsClients.s3, bucket, prefix, region, stateBackend, { profile: options.profile }),
16252
- dispose: () => awsClients.destroy()
16635
+ dispose: () => {
16636
+ awsClients.destroy();
16637
+ stateBackend.destroyClient();
16638
+ }
16253
16639
  };
16254
16640
  }
16255
16641
  function renderRecovery(options, setup) {
@@ -16690,6 +17076,43 @@ function createStateShowCommand() {
16690
17076
  cmd.addOption(deprecatedRegionOption);
16691
17077
  return cmd;
16692
17078
  }
17079
+ async function clearRetainedQuietly(backend, stackName, region, logger) {
17080
+ try {
17081
+ await backend.saveRetainedResources(stackName, region, []);
17082
+ return true;
17083
+ } catch (error) {
17084
+ logger.warn(safeMsg`Could not empty the kept-resource record of ${displayStackName(stackName)} ` + safeMsg`(${describeAwsFailure(error).summary}): a later deploy here may still take a kept ` + `resource back. Re-run 'cdkd state orphan' once it can write.`);
17085
+ return false;
17086
+ }
17087
+ }
17088
+ async function clearRetainedWithoutRecord(backend, stackName, stackRegion, logger) {
17089
+ if (stackName.includes("/")) return {
17090
+ cleared: [],
17091
+ attempted: 0
17092
+ };
17093
+ const base = `${backend.prefix}/${stackName}/`;
17094
+ let regions;
17095
+ try {
17096
+ const keys = (await backend.listRawKeys(base)).map((key) => key.slice(base.length).split("/")).filter((parts) => parts.length >= 2 && parts[0] !== "");
17097
+ const recorded = new Set(keys.filter((parts) => parts.length === 2 && parts[1] === "state.json").map((parts) => parts[0]));
17098
+ regions = [...new Set(keys.map((parts) => parts[0]).filter((region) => stackRegion === void 0 || region === stackRegion).filter((region) => !recorded.has(region)))];
17099
+ } catch (error) {
17100
+ logger.warn(safeMsg`Could not look for a kept-resource record of ${displayStackName(stackName)} ` + safeMsg`(${describeAwsFailure(error).summary}).`);
17101
+ return {
17102
+ cleared: [],
17103
+ attempted: 0
17104
+ };
17105
+ }
17106
+ const cleared = [];
17107
+ for (const region of regions) {
17108
+ if (await clearRetainedQuietly(backend, stackName, region, logger)) cleared.push(region);
17109
+ await releaseRegistryMarkerQuietly(backend, stackName, region, logger);
17110
+ }
17111
+ return {
17112
+ cleared,
17113
+ attempted: regions.length
17114
+ };
17115
+ }
16693
17116
  async function stateOrphanCommand(stackArgs, options) {
16694
17117
  const logger = getLogger();
16695
17118
  if (options.verbose) logger.setLevel("debug");
@@ -16705,6 +17128,12 @@ async function stateOrphanCommand(stackArgs, options) {
16705
17128
  for (const stackName of stackArgs) {
16706
17129
  const stackRefs = refs.filter((r) => r.stackName === stackName);
16707
17130
  if (stackRefs.length === 0) {
17131
+ const { cleared, attempted } = await clearRetainedWithoutRecord(setup.stateBackend, stackName, options.stackRegion, logger);
17132
+ if (attempted > 0 && cleared.length === 0) continue;
17133
+ if (cleared.length > 0) {
17134
+ logger.info(safeMsg`Cleared the kept-resource record of ${plainOrDescribed(stackName, "stack name")} ` + safeMsg`(${cleared.map((r) => displaySafe(r, { asciiOnly: true })).join(", ")}): ` + `a later deploy here no longer takes a kept resource back.`);
17135
+ continue;
17136
+ }
16708
17137
  logger.info(safeMsg`No state found for stack: ${plainOrDescribed(stackName, "stack name")}, skipping` + (isPasteableIdent(stackName) ? "" : safeMsg`. ${STATE_LIST_POINTER}`));
16709
17138
  continue;
16710
17139
  }
@@ -16748,10 +17177,13 @@ async function stateOrphanCommand(stackArgs, options) {
16748
17177
  await warnOnLiveForeignLock(setup.lockManager, stackName, target.region, logger);
16749
17178
  await setup.stateBackend.deleteState(stackName, target.region);
16750
17179
  await setup.lockManager.forceReleaseLock(stackName, target.region);
17180
+ await clearRetainedQuietly(setup.stateBackend, stackName, target.region, logger);
17181
+ await releaseRegistryMarkerQuietly(setup.stateBackend, stackName, target.region, logger);
16751
17182
  } else {
16752
17183
  await warnOnLiveForeignLock(setup.lockManager, stackName, void 0, logger);
16753
17184
  await setup.stateBackend.deleteLegacyState(stackName);
16754
17185
  await setup.lockManager.forceReleaseLock(stackName, void 0);
17186
+ await clearRetainedWithoutRecord(setup.stateBackend, stackName, void 0, logger);
16755
17187
  }
16756
17188
  logger.info(safeMsg`✓ Removed state for stack: ${describedStackRef(target)}` + ((options.yes || options.force) && refIsDescribed(target) ? safeMsg`. ${STATE_LIST_POINTER}` : ""));
16757
17189
  }
@@ -16899,6 +17331,8 @@ async function stateDestroyCommand(stackArgs, options) {
16899
17331
  interruptWatch.dispose();
16900
17332
  throw error;
16901
17333
  }
17334
+ const deferredTails = [];
17335
+ let deferRegistryTail;
16902
17336
  try {
16903
17337
  const stateRefs = await setup.stateBackend.listStacks();
16904
17338
  const knownStackNames = new Set(stateRefs.map((r) => r.stackName));
@@ -16916,16 +17350,23 @@ async function stateDestroyCommand(stackArgs, options) {
16916
17350
  if (!options.stackRegion) return laterRefs.length > 0;
16917
17351
  return laterRefs.some((r) => r.region === options.stackRegion || !r.region);
16918
17352
  });
17353
+ const crossPrefixCheck = { cache: new CrossPrefixGuard(setup.stateBackend) };
17354
+ if (stackNames.length > 1) deferRegistryTail = (released) => deferredTails.push(released);
17355
+ for (const name of stackNames) {
17356
+ const refs = stateRefs.filter((r) => r.stackName === name);
17357
+ for (const ref of stateDestroyTargets(refs, options.stackRegion) ?? []) crossPrefixCheck.cache.full(name, ref.region ?? setup.region, "prestart");
17358
+ }
16919
17359
  for (const [stackIndex, stackName] of stackNames.entries()) {
16920
17360
  const refs = stateRefs.filter((r) => r.stackName === stackName);
16921
17361
  let targets;
17362
+ const planned = stateDestroyTargets(refs, options.stackRegion);
16922
17363
  if (options.stackRegion) {
16923
- targets = refs.filter((r) => r.region === options.stackRegion || !r.region);
17364
+ targets = planned ?? [];
16924
17365
  if (targets.length === 0) {
16925
17366
  logger.warn(safeMsg`Skipping ${plainOrDescribed(stackName, "stack name")} (no state record matches ` + safeMsg`--stack-region ${displayIdent(options.stackRegion)})`);
16926
17367
  continue;
16927
17368
  }
16928
- } else if (refs.length === 1) targets = refs;
17369
+ } else if (planned !== void 0) targets = planned;
16929
17370
  else throw multipleRegionsError(stackName, refs, `Use --stack-region ${commandHole("region")} to pick one.`);
16930
17371
  for (const [refIndex, ref] of targets.entries()) {
16931
17372
  logger.info(safeMsg`\nPreparing to destroy stack: ${formatStackRefSafe(ref)}`);
@@ -16982,6 +17423,8 @@ async function stateDestroyCommand(stackArgs, options) {
16982
17423
  skipFinalSnapshot: options.skipFinalSnapshot === true,
16983
17424
  resolveSecretDerivedPrincipals: {},
16984
17425
  stackDestroy: true,
17426
+ crossPrefixCheck,
17427
+ ...deferRegistryTail !== void 0 && { deferRegistryTail },
16985
17428
  exportIndexStore: setup.exportIndexStore,
16986
17429
  ...options.allowUnsupportedTypes?.length && { allowUnsupportedTypes: options.allowUnsupportedTypes },
16987
17430
  ...options.resourceWarnAfter?.globalMs !== void 0 && { resourceWarnAfterMs: options.resourceWarnAfter.globalMs },
@@ -17022,6 +17465,7 @@ async function stateDestroyCommand(stackArgs, options) {
17022
17465
  if (interrupted || interruptWatch.interrupted() && stoppedEarly) throw new PartialFailureError(`Destroy interrupted by Ctrl-C. State preserved — re-run 'cdkd state destroy' to finish.`);
17023
17466
  if (totalSkipped > 0) throw new PartialFailureError(`Destroy skipped ${totalSkipped} entr${totalSkipped === 1 ? "y" : "ies"} whose delete cdkd did not confirm, so the underlying resources may still exist in AWS. A skipped nested stack counts as ONE entry and may cover several of its own resources — the per-stack summaries above give the exact breakdown. State preserved (the records are kept). The per-resource 'skipped (...)' lines and their warnings name each cause and whether repairing the record in state.json helps: where it does, repair it and re-run 'cdkd state destroy'; otherwise (for example a custom-resource Delete handler that reported FAILED), delete the resources by hand and drop the records with 'cdkd state orphan <stack> --stack-region <region>'.`);
17024
17467
  } finally {
17468
+ await Promise.allSettled(deferredTails);
17025
17469
  unforwardSigterm();
17026
17470
  interruptWatch.dispose();
17027
17471
  setup.dispose();
@@ -17684,6 +18128,7 @@ async function rollbackCommand(stackArg, options) {
17684
18128
  });
17685
18129
  return;
17686
18130
  }
18131
+ const crossPrefixScan = new CrossPrefixGuard(setup.stateBackend).full(stackName, region);
17687
18132
  stackAwsClients = new AwsClients({
17688
18133
  region,
17689
18134
  ...options.profile && { profile: options.profile }
@@ -17718,6 +18163,15 @@ async function rollbackCommand(stackArg, options) {
17718
18163
  segments: journal.segments.filter((s) => s.reason !== NESTED_PENDING_PARENT_REASON)
17719
18164
  };
17720
18165
  if (!journal || journal.segments.length === 0 && orphanedPending === 0) throw new Error(`Nothing to roll back for ${plainOrDescribed(stackName, "stack name")} (${plainOrDescribed(region, "region")}). Run 'cdkd deploy' to (re)deploy, or 'cdkd destroy' to clean up.`);
18166
+ applyCrossPrefixScan(await crossPrefixScan, {
18167
+ stackName,
18168
+ region,
18169
+ bucket: setup.bucket,
18170
+ recovery: {
18171
+ profile: options.profile,
18172
+ stateBucket: setup.bucket
18173
+ }
18174
+ }, "rollback", (message) => logger.warn(message), (message) => logger.info(message));
17721
18175
  if (!stateData) throw new Error(`Rollback journal exists for ${safeStack(stackName)} (${safe(region)}) but its state.json is missing (keys: ${safe(setup.prefix)}/${safeStack(stackName)}/${safe(region)}/state.json and .../rollback-journal.json). State appears corrupted — inspect the bucket manually.`);
17722
18176
  demoteSupersededOrphans(journal.segments, Array.isArray(stateData.state.orphans) ? stateData.state.orphans : []);
17723
18177
  if (!options.revertFailed) for (const segment of journal.segments) {
@@ -17961,6 +18415,8 @@ async function rollbackCommand(stackArg, options) {
17961
18415
  const survivingOrphans = orphansAfterRollback(baseState, mintedOrphans).orphans ?? [];
17962
18416
  if (journal.segments.length === 0 && oldestInitialDeploy && Object.keys(stateResources).length === 0 && survivingOrphans.length === 0) {
17963
18417
  await setup.stateBackend.deleteState(stackName, region);
18418
+ await recordRetainedForReadoption(setup.stateBackend, stackName, region, [], logger);
18419
+ await releaseRegistryMarkerQuietly(setup.stateBackend, stackName, region, logger);
17964
18420
  logger.info(`State for ${stackRegionShown(stackName, region)} removed (stack fully rolled back).`);
17965
18421
  }
17966
18422
  if (declinedDivergentRewrite) throw new PartialFailureError(`Rollback stopped: ${declinedDivergentReason}.` + (totalFailures > 0 ? ` ${totalFailures} operation(s) also failed.` : "") + " Journal preserved (this segment, any older ones, and their failed operations) — re-run the rollback once the record's region field matches its key.");
@@ -19108,8 +19564,20 @@ async function forceUnlockCommand(stackArgs, options) {
19108
19564
  const where = r ? `${displayStackName(stackName)} (${displayIdent(r)})` : `${displayStackName(stackName)} (legacy lock key)`;
19109
19565
  logger.info(`Force-unlocking stack: ${where}`);
19110
19566
  try {
19111
- await lockManager.forceReleaseLock(stackName, r);
19567
+ let ledgerError;
19568
+ let recorded = false;
19569
+ await lockManager.forceReleaseLock(stackName, r, async (horizon) => {
19570
+ if (r === void 0) return;
19571
+ const ledger = ledgerForStack(stateBackend, stackName, r);
19572
+ for (let attempt = 0; attempt < 2 && !recorded; attempt++) try {
19573
+ await ledger.noteAbandoned(horizon);
19574
+ recorded = true;
19575
+ } catch (error) {
19576
+ ledgerError = error;
19577
+ }
19578
+ });
19112
19579
  logger.info(`✓ Lock released for stack: ${where}`);
19580
+ if (!recorded && ledgerError !== void 0) logger.warn(safeMsg`Lock released, but the create-token ledger of ${where} could not record when the ` + safeMsg`abandoned run stopped: ${describeAwsFailure(ledgerError).summary}. ` + "A later deploy may take back a resource of those names that another deployment creates.");
19113
19581
  } catch (error) {
19114
19582
  const message = describeAwsFailure(error).detail;
19115
19583
  if (message.includes("No lock found") || message.includes("NoSuchKey")) logger.info(`No lock found for stack: ${where}`);
@@ -19219,6 +19687,20 @@ var ObservedBaselineRefusals = class extends Set {
19219
19687
  unverifiableParameter = /* @__PURE__ */ new Set();
19220
19688
  hadDeployedParameterSource = false;
19221
19689
  };
19690
+ async function claimRegistryMarkerAfterImport(backend, stackName, region, logger) {
19691
+ const answer = await new CrossPrefixGuard(backend).full(stackName, region);
19692
+ const regionShown = displaySafe(region, { asciiOnly: true });
19693
+ switch (answer.kind) {
19694
+ case "clear": return;
19695
+ case "found":
19696
+ logger.warn(safeMsg`The state bucket also records ${displayStackName(stackName)} (${regionShown}) under another state prefix ` + safeMsg`(${answer.prefixes.map((p) => displayIdent(p)).join(", ")}). One stack name per ` + "account and region is supported: drop one of the records with 'cdkd state orphan' before deploying or destroying either.");
19697
+ return;
19698
+ case "in-progress":
19699
+ logger.warn(safeMsg`A deploy of ${displayStackName(stackName)} (${regionShown}) holds a lock under another state prefix ` + safeMsg`(${displayIdent(answer.prefix)}). One stack name per account and region is ` + `supported: keep one of the two before deploying or destroying either.`);
19700
+ return;
19701
+ default: logger.warn(safeMsg`Could not record ${displayStackName(stackName)} (${regionShown}) in the state bucket's stack registry` + (answer.kind === "denied" || answer.kind === "failed" ? safeMsg` (${describeAwsFailure(answer.error).summary})` : "") + `. Its next guarded command records it.`);
19702
+ }
19703
+ }
19222
19704
  async function importCommand(stackArg, options) {
19223
19705
  const providerClasses = await loadProviderClasses();
19224
19706
  const logger = getLogger();
@@ -19439,6 +19921,7 @@ async function importCommand(stackArg, options) {
19439
19921
  await recordImportOnRollbackJournal(stateBackend, stackInfo.stackName, targetRegion, importedRows.map((r) => r.logicalId), stackState.resources, logger);
19440
19922
  await stateBackend.saveState(stackInfo.stackName, targetRegion, stackState, saveOptions);
19441
19923
  logger.info(`✓ State written: ${stackInfo.stackName} (${targetRegion})`);
19924
+ await claimRegistryMarkerAfterImport(stateBackend, stackInfo.stackName, targetRegion, logger);
19442
19925
  logger.info(` ${importedRows.length} resource(s) imported. Run 'cdkd diff' to see how the imported state lines up with the template.`);
19443
19926
  if (migrationCfnStackName && migrationTree && accountIdForNestedSynth) await importNestedStackChildrenRecursive({
19444
19927
  lockRecovery,
@@ -27766,4 +28249,4 @@ function collectVerbFlags(program) {
27766
28249
 
27767
28250
  //#endregion
27768
28251
  export { canonicalizeIpProtocolValue as a, buildProgram, resolveSecretDerivedPrincipals as i, runDestroyForStack as n, resolvedResourceTimeoutMs as o, isResolvableSecretPrincipalList as r, canonicalizeIpv4Cidr as t };
27769
- //# sourceMappingURL=program-v_QNBjtZ.js.map
28252
+ //# sourceMappingURL=program-CN7Dqb3j.js.map