@go-to-k/cdkd 0.301.14 → 0.302.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/{asg-provider-ak7zMqaQ.js → asg-provider-BRr_hsky.js} +5 -5
  2. package/dist/asg-provider-BRr_hsky.js.map +1 -0
  3. package/dist/{aws-failure-text-CdgZn80O.js → aws-failure-text-BDZdavf4.js} +310 -35
  4. package/dist/aws-failure-text-BDZdavf4.js.map +1 -0
  5. package/dist/cli.js +2 -2
  6. package/dist/{deploy-engine-B0ObJCy0.js → deploy-engine-DU0BoQqo.js} +1575 -492
  7. package/dist/deploy-engine-DU0BoQqo.js.map +1 -0
  8. package/dist/{iam-policy-targets-Dap4bLyq.js → iam-policy-targets-Dnk6FCsr.js} +2 -2
  9. package/dist/{iam-policy-targets-Dap4bLyq.js.map → iam-policy-targets-Dnk6FCsr.js.map} +1 -1
  10. package/dist/{iam-role-provider-CukWclVP.js → iam-role-provider-WGsb9RxZ.js} +14 -5
  11. package/dist/iam-role-provider-WGsb9RxZ.js.map +1 -0
  12. package/dist/index.d.ts +31 -1
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +4 -4
  15. package/dist/{neptune-provider-BTkMpImX.js → neptune-provider-WE1O3kXY.js} +7 -16
  16. package/dist/neptune-provider-WE1O3kXY.js.map +1 -0
  17. package/dist/{program-9BJEui0z.js → program-BVLiidXb.js} +172 -30
  18. package/dist/program-BVLiidXb.js.map +1 -0
  19. package/dist/{provider-classes-Dmz-lVVh.js → provider-classes-CXSiWJVn.js} +235 -125
  20. package/dist/provider-classes-CXSiWJVn.js.map +1 -0
  21. package/dist/{rds-provider-D0srL6Rb.js → rds-provider-6RgDTDCV.js} +7 -16
  22. package/dist/rds-provider-6RgDTDCV.js.map +1 -0
  23. package/dist/{version-BTi3OoSX.js → version-C2XBsD-i.js} +2 -2
  24. package/dist/{version-BTi3OoSX.js.map → version-C2XBsD-i.js.map} +1 -1
  25. package/package.json +1 -1
  26. package/dist/asg-provider-ak7zMqaQ.js.map +0 -1
  27. package/dist/aws-failure-text-CdgZn80O.js.map +0 -1
  28. package/dist/deploy-engine-B0ObJCy0.js.map +0 -1
  29. package/dist/iam-role-provider-CukWclVP.js.map +0 -1
  30. package/dist/neptune-provider-BTkMpImX.js.map +0 -1
  31. package/dist/program-9BJEui0z.js.map +0 -1
  32. package/dist/provider-classes-Dmz-lVVh.js.map +0 -1
  33. package/dist/rds-provider-D0srL6Rb.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { r as getAwsClients, s as __exportAll } from "./aws-clients-B_CEQGE1.js";
2
- import { A as SECRET_REF_MAX_CODE_POINTS, C as getCurrentSkipPrefix, D as withStackName, E as withSkipPrefix, F as displayAwsMessage, G as truncateCodePoints, H as safeMsg, I as displayIdent, L as displaySafe, M as UNRENDERABLE, N as asIsMessage, O as withoutGeneratedFallbackName, R as displayStackName, S as generateResourceNameWithFallback, T as looksLikeCdkdGeneratedName, V as plainIdentOr, W as terminalSafe, a as safeStringify$1, b as explicitNamePropertyFor, c as isStdoutReservedForPayload, f as currentLogLineMasker, j as STACK_REF_MAX_CODE_POINTS, k as SAFE_MSG_ALTERED_CHAR, m as getLiveRenderer, n as describeAwsFailure, p as installLogLineMaskerSource, s as getLogger, v as applyDefaultNameForFallback, w as getCurrentStackName, x as generateResourceName, z as isPasteableIdent } from "./aws-failure-text-CdgZn80O.js";
3
- import { $ as protectedReplacementAdvice, $n as markReplayMayCollide, $t as ambientCredentialConfig, A as isQuotableImportValue, An as SHELL_ACTIVE, At as isAuxiliaryMarkOf, B as isTerminalDeleteFailure, Bn as shellBoundedDisplay, Bt as formatLockOperation, Cn as StateError, Ct as RETRY_AUXILIARY_OWNER, Dn as normalizeAwsError, Dt as createdResourceIdentityBeforeFailure, E as assertRegionMatch, Et as createdBeforeFailure, F as resolveExplicitPhysicalId, Fn as isInertUnquoted, Ft as UNREPRODUCIBLE_LOCK_CLAUSE, G as runDeleteAttempt, Gn as isUpdateUnsupportedError, Gt as DEFAULT_STATE_PREFIX, H as observeThenDisableProtection, Hn as withheldTargetClause, Ht as recoveryCommandFlags, In as pasteableCommand, It as buildForceUnlockCommand, J as DELETION_PROTECTION_DOC_POINTER, Jn as isNameCollisionErrorFrom, Kn as hasReplayMayCollide, Kt as injectiveKey, L as ProtectionFlipRegistry, Ln as physicalIdShownBesideCommand, M as quotedRemedyLogicalId, Mn as UNSHOWABLE_VALUE, Mt as markCreatedBeforeFailure, N as refusalTypeShown, Nn as commandHole, Ot as hasCreatedBeforeFailure, Pt as replayMadeAnotherResource, Q as pasteableAwsCommand, Qt as ambientClientDefaults, R as compensateProtectionFlip, Rn as plainOrDescribed, St as withDerivedNameMasks, T as RESOURCE_NOT_FOUND, U as protectionFlipKey, Ut as sanitizeRecoveryValue, Vn as shellQuote, Vt as formatLockOwner, Wt as CUSTOM_RESOURCE_RESPONSE_PREFIX, Xn as isRecreateRetryableError, Yn as isNameCooldownError, Yt as producerRecordKey, Zn as isReplayedNameCollisionFrom, Zt as withPasteableAwsProfile, _r as markRedactedCause, _t as createMaskedLogSinks, ar as formatRetryClassificationSignals, at as startInterruptWatch, bn as ResourceUpdateNotSupportedError, bt as maskDeep, ct as canonicalizeRoute53QueryName, d as prepareRemovalForUpdate, dr as isTransientServerError, en as clientDefaultsFor, er as relayedNameCollision, f as removalWarning, fr as retryClassificationText, ft as logicalIdShown, gr as markNonRetryable, gt as stateOrphanRecordRemedy, hn as MalformedProducerRecordRefusalError, hr as isThrottlingError, ht as segmentAfterAnchor, i as holdsSecretDerivedEntry, in as CdkdError, it as isInterruptedWaitError, j as normalizeAwsTagsToCfn, jn as SHELL_ACTIVE_WHY, jt as markAuxiliaryFailure, kt as isAuxiliaryFailure, l as withUnchangedSecretPrincipalLists, ln as DynamicReferenceRegionAmbiguousError, lr as isIamPropagationError, m as withoutInjectedRemovals, mn as MacroExpansionError, mr as isMarkedNonRetryable, mt as resourceTypeShown, nn as AccountIdUnavailableError, nr as stripControlChars, on as CrossAccountSecretRefusalError, or as isAmbiguousCcHandlerErrorCode, ot as ElapsedBudgetRegistry, pn as LockError, rn as AssetError, sn as DependencyError, sr as isAmbiguousOutcomeError, st as monotonicNowMs, tn as credentialFingerprint, tr as escapeRegExp$3, un as IntrinsicResolutionRefusalError, ur as isRetryableTransientError, ut as compositeIdSeparatorRefusal, vn as ProvisioningError, vr as wrapMaskedAwsError, vt as createMaskedRetryLogger, w as withoutServerErrorRetries, wn as SynthesisError, wt as carryCreatedBeforeFailure, xt as maskerOrIdentity, yn as ResourceTimeoutError, yt as isSecretDerivedValue, z as deleteWithProtectionCompensation, zn as quotedOrDescribed, zt as formatLockExpiry } from "./iam-policy-targets-Dap4bLyq.js";
2
+ import { $ as terminalSafe, A as looksLikeCdkdGeneratedName, B as STACK_REF_MAX_CODE_POINTS, D as getCurrentStackInstanceId, E as getCurrentSkipPrefix, F as withStackScope, G as displayIdent, H as asIsMessage, I as withStackScopeBeforeStateRead, J as isPasteableIdent, K as displaySafe, L as withoutGeneratedFallbackName, M as stackInstanceNameSuffix, N as withNameGeneration, O as getCurrentStackName, P as withSkipPrefix, R as SAFE_MSG_ALTERED_CHAR, S as fallbackNamePropertyFor, T as generatedNameFor, V as UNRENDERABLE, W as displayAwsMessage, X as plainIdentOr, Z as safeMsg, a as safeStringify$1, c as isStdoutReservedForPayload, et as truncateCodePoints, f as currentLogLineMasker, k as isNameGeneration, m as getLiveRenderer, n as describeAwsFailure, p as installLogLineMaskerSource, q as displayStackName, s as getLogger, t as VERBOSE_POINTER, v as applyDefaultNameForFallback, w as generateResourceNameWithFallback, x as explicitNamePropertyFor, y as currentNameGeneration, z as SECRET_REF_MAX_CODE_POINTS } from "./aws-failure-text-BDZdavf4.js";
3
+ import { $ as protectedReplacementAdvice, $n as markReplayMayCollide, $t as ambientCredentialConfig, A as isQuotableImportValue, An as SHELL_ACTIVE, At as isAuxiliaryMarkOf, B as isTerminalDeleteFailure, Bn as shellBoundedDisplay, Bt as formatLockOperation, Cn as StateError, Ct as RETRY_AUXILIARY_OWNER, Dn as normalizeAwsError, Dt as createdResourceIdentityBeforeFailure, E as assertRegionMatch, Et as createdBeforeFailure, F as resolveExplicitPhysicalId, Fn as isInertUnquoted, Ft as UNREPRODUCIBLE_LOCK_CLAUSE, G as runDeleteAttempt, Gn as isUpdateUnsupportedError, Gt as DEFAULT_STATE_PREFIX, H as observeThenDisableProtection, Hn as withheldTargetClause, Ht as recoveryCommandFlags, In as pasteableCommand, It as buildForceUnlockCommand, J as DELETION_PROTECTION_DOC_POINTER, Jn as isNameCollisionErrorFrom, Kn as hasReplayMayCollide, Kt as injectiveKey, L as ProtectionFlipRegistry, Ln as physicalIdShownBesideCommand, M as quotedRemedyLogicalId, Mn as UNSHOWABLE_VALUE, Mt as markCreatedBeforeFailure, N as refusalTypeShown, Nn as commandHole, Ot as hasCreatedBeforeFailure, Pt as replayMadeAnotherResource, Q as pasteableAwsCommand, Qt as ambientClientDefaults, R as compensateProtectionFlip, Rn as plainOrDescribed, St as withDerivedNameMasks, T as RESOURCE_NOT_FOUND, U as protectionFlipKey, Ut as sanitizeRecoveryValue, Vn as shellQuote, Vt as formatLockOwner, Wt as CUSTOM_RESOURCE_RESPONSE_PREFIX, Xn as isRecreateRetryableError, Yn as isNameCooldownError, Yt as producerRecordKey, Zn as isReplayedNameCollisionFrom, Zt as withPasteableAwsProfile, _r as markRedactedCause, _t as createMaskedLogSinks, ar as formatRetryClassificationSignals, at as startInterruptWatch, bn as ResourceUpdateNotSupportedError, bt as maskDeep, ct as canonicalizeRoute53QueryName, d as prepareRemovalForUpdate, dr as isTransientServerError, en as clientDefaultsFor, er as relayedNameCollision, f as removalWarning, fr as retryClassificationText, ft as logicalIdShown, gr as markNonRetryable, gt as stateOrphanRecordRemedy, hn as MalformedProducerRecordRefusalError, hr as isThrottlingError, ht as segmentAfterAnchor, i as holdsSecretDerivedEntry, in as CdkdError, it as isInterruptedWaitError, j as normalizeAwsTagsToCfn, jn as SHELL_ACTIVE_WHY, jt as markAuxiliaryFailure, kt as isAuxiliaryFailure, l as withUnchangedSecretPrincipalLists, ln as DynamicReferenceRegionAmbiguousError, lr as isIamPropagationError, m as withoutInjectedRemovals, mn as MacroExpansionError, mr as isMarkedNonRetryable, mt as resourceTypeShown, nn as AccountIdUnavailableError, nr as stripControlChars, on as CrossAccountSecretRefusalError, or as isAmbiguousCcHandlerErrorCode, ot as ElapsedBudgetRegistry, pn as LockError, rn as AssetError, sn as DependencyError, sr as isAmbiguousOutcomeError, st as monotonicNowMs, tn as credentialFingerprint, tr as escapeRegExp$3, un as IntrinsicResolutionRefusalError, ur as isRetryableTransientError, ut as compositeIdSeparatorRefusal, vn as ProvisioningError, vr as wrapMaskedAwsError, vt as createMaskedRetryLogger, w as withoutServerErrorRetries, wn as SynthesisError, wt as carryCreatedBeforeFailure, xt as maskerOrIdentity, yn as ResourceTimeoutError, yt as isSecretDerivedValue, z as deleteWithProtectionCompensation, zn as quotedOrDescribed, zt as formatLockExpiry } from "./iam-policy-targets-Dnk6FCsr.js";
4
4
  import { a as setAssumedRoleCredentials, i as getPreAssumeEnvCredentials, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, s as ambientRegion, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-DBXBcg0J.js";
5
- import { t as getCdkdVersion } from "./version-BTi3OoSX.js";
5
+ import { t as getCdkdVersion } from "./version-C2XBsD-i.js";
6
6
  import { createHash, randomUUID } from "node:crypto";
7
7
  import { AsyncLocalStorage } from "node:async_hooks";
8
8
  import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketLifecycleConfigurationCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -4803,7 +4803,8 @@ const STATE_SCHEMA_VERSIONS_READABLE = [
4803
4803
  9,
4804
4804
  10,
4805
4805
  11,
4806
- 12
4806
+ 12,
4807
+ 13
4807
4808
  ];
4808
4809
  function hasUnverifiableParameterRefusal(record) {
4809
4810
  return record?.observedBaselineRefused === true && record.observedBaselineRefusalReason === "unverifiable-parameter";
@@ -4851,6 +4852,13 @@ function importableOutputs(state) {
4851
4852
  function exportNamesCarriedFrom(previous) {
4852
4853
  return previous.exportNames === void 0 ? {} : { exportNames: previous.exportNames };
4853
4854
  }
4855
+ function stackInstanceIdCarriedFrom(previous) {
4856
+ return {
4857
+ ...previous?.stackInstanceId !== void 0 && { stackInstanceId: previous.stackInstanceId },
4858
+ ...previous?.retiredNameGenerations !== void 0 && { retiredNameGenerations: previous.retiredNameGenerations },
4859
+ ...previous?.supersededResources !== void 0 && { supersededResources: previous.supersededResources }
4860
+ };
4861
+ }
4854
4862
  function skippedOutputsCarriedFrom(previous) {
4855
4863
  return previous.skippedOutputs === void 0 ? {} : { skippedOutputs: previous.skippedOutputs };
4856
4864
  }
@@ -4942,6 +4950,7 @@ function refuseMalformedOperation(shownStack, where, op) {
4942
4950
  if (o["changeType"] !== "UPDATE") refuseMalformed(shownStack, `${where}.replacementOrphaned is only valid on an UPDATE.`);
4943
4951
  }
4944
4952
  if (o["wasReplaced"] !== void 0 && typeof o["wasReplaced"] !== "boolean") fail("wasReplaced", o["wasReplaced"], "a boolean when present");
4953
+ if (o["nameGeneration"] !== void 0 && !(typeof o["nameGeneration"] === "number" && Number.isSafeInteger(o["nameGeneration"]) && o["nameGeneration"] >= 0)) fail("nameGeneration", o["nameGeneration"], "a non-negative integer when present");
4945
4954
  if (o["oldDeletedBeforeCreate"] !== void 0 && typeof o["oldDeletedBeforeCreate"] !== "boolean") fail("oldDeletedBeforeCreate", o["oldDeletedBeforeCreate"], "a boolean when present");
4946
4955
  if (o["oldResourceMaySurvive"] !== void 0 && !["kept", "unconfirmed"].includes(o["oldResourceMaySurvive"])) fail("oldResourceMaySurvive", o["oldResourceMaySurvive"], "kept or unconfirmed when present");
4947
4956
  if (o["physicalIdRecoveredFromError"] !== void 0 && typeof o["physicalIdRecoveredFromError"] !== "boolean") fail("physicalIdRecoveredFromError", o["physicalIdRecoveredFromError"], "a boolean when present");
@@ -5099,6 +5108,53 @@ async function notifyStateSaved(stackName, region) {
5099
5108
  await stateSavedObserver.getStore()?.(stackName, region);
5100
5109
  }
5101
5110
 
5111
+ //#endregion
5112
+ //#region src/state/stack-instance-id.ts
5113
+ const STACK_INSTANCE_SIBLING_VERSION = 1;
5114
+ const STACK_INSTANCE_SIBLING_FILE = "stack-instance.json";
5115
+ const STACK_INSTANCE_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
5116
+ function isStackInstanceId(value) {
5117
+ return typeof value === "string" && STACK_INSTANCE_ID_PATTERN.test(value);
5118
+ }
5119
+ function stackInstanceSiblingBody(id) {
5120
+ return JSON.stringify({
5121
+ stackInstanceVersion: 1,
5122
+ stackInstanceId: id
5123
+ }, null, 2);
5124
+ }
5125
+ function parseStackInstanceSibling(body) {
5126
+ let raw;
5127
+ try {
5128
+ raw = JSON.parse(body);
5129
+ } catch {
5130
+ return null;
5131
+ }
5132
+ if (typeof raw !== "object" || raw === null) return null;
5133
+ const doc = raw;
5134
+ if (doc["stackInstanceVersion"] !== 1) return null;
5135
+ return isStackInstanceId(doc["stackInstanceId"]) ? doc["stackInstanceId"] : null;
5136
+ }
5137
+ var MalformedStackInstanceIdError = class extends Error {
5138
+ constructor(stackLabel) {
5139
+ super(`The state record of ${stackLabel} holds a stackInstanceId that is not a well-formed id. cdkd does not guess which lifetime of the stack it names, since names derive from it; restore the field from an earlier version of state.json.`);
5140
+ this.name = "MalformedStackInstanceIdError";
5141
+ }
5142
+ };
5143
+ function stackInstanceIdOf(state, stackLabel) {
5144
+ const value = state?.stackInstanceId;
5145
+ if (value === void 0) return void 0;
5146
+ if (!isStackInstanceId(value)) throw new MalformedStackInstanceIdError(stackLabel);
5147
+ return value;
5148
+ }
5149
+ const STACK_INSTANCE_ID_WITHHELD = "<withheld>";
5150
+ function withStackInstanceIdWithheld(state) {
5151
+ if (state === null || typeof state !== "object" || state.stackInstanceId === void 0) return state;
5152
+ return {
5153
+ ...state,
5154
+ stackInstanceId: STACK_INSTANCE_ID_WITHHELD
5155
+ };
5156
+ }
5157
+
5102
5158
  //#endregion
5103
5159
  //#region src/state/cross-prefix-stack-scan.ts
5104
5160
  function journalCanOwnResources(journal) {
@@ -5110,6 +5166,8 @@ function recordCanOwnResources(record, journal) {
5110
5166
  if (Object.keys(resources).length > 0) return true;
5111
5167
  const orphans = record.orphans;
5112
5168
  if (orphans !== void 0 && (!Array.isArray(orphans) || orphans.length > 0)) return true;
5169
+ const superseded = record.supersededResources;
5170
+ if (superseded !== void 0 && (!Array.isArray(superseded) || superseded.length > 0)) return true;
5113
5171
  if (journal === null) return false;
5114
5172
  const segments = journal.segments;
5115
5173
  if (!Array.isArray(segments)) return true;
@@ -5616,6 +5674,7 @@ function legacyProbeBelongsTo(probe, region) {
5616
5674
  }
5617
5675
  const KEPT_AT_CLOCK_TOLERANCE_MS = 2e3;
5618
5676
  const ROLLBACK_JOURNAL_OBJECT_DESCRIPTION = "the rollback journal, whose `failedOperations[].attemptedProperties` records the properties of the failed write verbatim";
5677
+ const STACK_INSTANCE_OBJECT_DESCRIPTION = "the write-ahead stack instance id, from which a stack's generated resource names derive";
5619
5678
  const STATE_RECORD_OBJECT_DESCRIPTION = "the stack's state record, which carries every resource's recorded properties and attributes";
5620
5679
  var S3StateBackend = class S3StateBackend {
5621
5680
  logger = getLogger().child("S3StateBackend");
@@ -5627,6 +5686,7 @@ var S3StateBackend = class S3StateBackend {
5627
5686
  resolveInFlight = null;
5628
5687
  journalsReadAbsent = /* @__PURE__ */ new Set();
5629
5688
  journalTouches = /* @__PURE__ */ new Map();
5689
+ pendingStackInstanceSiblings = /* @__PURE__ */ new Map();
5630
5690
  constructor(s3Client, config, clientOpts = {}) {
5631
5691
  this.s3Client = s3Client;
5632
5692
  this.config = config;
@@ -5684,6 +5744,9 @@ var S3StateBackend = class S3StateBackend {
5684
5744
  async purgeRollbackJournalVersions(stackName, region) {
5685
5745
  await this.purgeNoncurrentVersions([this.rollbackJournalKey(stackName, region)], { objectDescription: ROLLBACK_JOURNAL_OBJECT_DESCRIPTION });
5686
5746
  }
5747
+ getStackInstanceKey(stackName, region) {
5748
+ return `${this.config.prefix}/${stackName}/${region}/${STACK_INSTANCE_SIBLING_FILE}`;
5749
+ }
5687
5750
  getCreateTokenLedgerKey(stackName, region) {
5688
5751
  return `${this.config.prefix}/${stackName}/${region}/create-tokens.json`;
5689
5752
  }
@@ -5798,7 +5861,8 @@ var S3StateBackend = class S3StateBackend {
5798
5861
  const { expectedEtag, migrateLegacy } = options;
5799
5862
  const body = {
5800
5863
  ...state,
5801
- version: 12,
5864
+ ...stackInstanceIdCarriedFrom(state),
5865
+ version: 13,
5802
5866
  stackName,
5803
5867
  region
5804
5868
  };
@@ -5827,6 +5891,12 @@ var S3StateBackend = class S3StateBackend {
5827
5891
  this.logger.warn(`Migrated stack ${this.displayName(stackName)} to new key, but failed to delete legacy key: ${errorDetail$2(deleteError)}`);
5828
5892
  }
5829
5893
  await notifyStateSaved(stackName, region);
5894
+ const siblingKey = this.getStackInstanceKey(stackName, region);
5895
+ const pendingId = this.pendingStackInstanceSiblings.get(siblingKey);
5896
+ if (pendingId !== void 0 && body.stackInstanceId === pendingId) {
5897
+ this.pendingStackInstanceSiblings.delete(siblingKey);
5898
+ await this.dropStackInstanceSiblingAfterSave(stackName, region);
5899
+ }
5830
5900
  return response.ETag;
5831
5901
  } catch (error) {
5832
5902
  if (error.name === "PreconditionFailed") throw new StateError(`State has been modified by another process. Expected ETag: ${expectedEtag}, but state has changed.`, error instanceof Error ? error : void 0);
@@ -5840,6 +5910,7 @@ var S3StateBackend = class S3StateBackend {
5840
5910
  async deleteState(stackName, region) {
5841
5911
  await this.ensureClientForBucket();
5842
5912
  await this.deleteCreateTokenLedger(stackName, region);
5913
+ await this.deleteStackInstanceSibling(stackName, region);
5843
5914
  try {
5844
5915
  this.logger.debug(`Deleting state: ${this.stackRef(stackName, region)}`);
5845
5916
  await this.s3Client.send(new DeleteObjectCommand({
@@ -5868,7 +5939,7 @@ var S3StateBackend = class S3StateBackend {
5868
5939
  });
5869
5940
  throw new StateError(`Failed to delete state for stack ${this.stackRef(stackName, region)}: ${errorDetail$2(normalized)}`, normalized);
5870
5941
  } finally {
5871
- await this.deleteRollbackJournal(stackName, region);
5942
+ await Promise.all([this.deleteRollbackJournal(stackName, region), this.purgeNoncurrentVersions([this.getStackInstanceKey(stackName, region)], { objectDescription: STACK_INSTANCE_OBJECT_DESCRIPTION })]);
5872
5943
  }
5873
5944
  }
5874
5945
  async purgeDeletedStateHistory(stackName, region) {
@@ -6413,6 +6484,102 @@ var S3StateBackend = class S3StateBackend {
6413
6484
  throw new StateError(`Failed to delete the create-token ledger for stack ${this.stackRef(stackName, region)}: ${errorDetail$2(normalized)}. The state record was left in place; re-run once the ledger can be deleted.`, normalized);
6414
6485
  }
6415
6486
  }
6487
+ async stackInstanceIdForFirstWrite(stackName, region, options) {
6488
+ const key = this.getStackInstanceKey(stackName, region);
6489
+ const read = async () => this.readSiblingId(key, stackName, region);
6490
+ try {
6491
+ const existing = await read();
6492
+ if (existing !== null) {
6493
+ this.pendingStackInstanceSiblings.set(key, existing);
6494
+ this.logger.debug(safeMsg`Reusing the write-ahead stack instance id of ${displayStackName(stackName)}`);
6495
+ return existing;
6496
+ }
6497
+ const minted = randomUUID();
6498
+ if (!options.writeAhead) return minted;
6499
+ await this.ensureClientForBucket();
6500
+ const body = stackInstanceSiblingBody(minted);
6501
+ const put = async () => this.s3Client.send(new PutObjectCommand({
6502
+ Bucket: this.config.bucket,
6503
+ ...await this.ownerParam(),
6504
+ Key: key,
6505
+ Body: body,
6506
+ ContentLength: Buffer.byteLength(body),
6507
+ ContentType: "application/json",
6508
+ IfNoneMatch: "*"
6509
+ }));
6510
+ try {
6511
+ try {
6512
+ await put();
6513
+ } catch (error) {
6514
+ if (!isConditionalConflict(error)) throw error;
6515
+ await put();
6516
+ }
6517
+ } catch (error) {
6518
+ if (isNotImplemented(error)) {
6519
+ await this.putRawObject(key, body);
6520
+ this.pendingStackInstanceSiblings.set(key, minted);
6521
+ return minted;
6522
+ }
6523
+ if (!isConditionFailure(error)) throw error;
6524
+ const winner = await read();
6525
+ if (winner === null) throw error;
6526
+ this.pendingStackInstanceSiblings.set(key, winner);
6527
+ return winner;
6528
+ }
6529
+ this.pendingStackInstanceSiblings.set(key, minted);
6530
+ return minted;
6531
+ } catch (error) {
6532
+ if (error instanceof StateError) throw error;
6533
+ throw this.stackInstanceSiblingError(stackName, region, error, "write");
6534
+ }
6535
+ }
6536
+ stackInstanceSiblingError(stackName, region, error, access) {
6537
+ const normalized = normalizeAwsError(error, { bucket: this.config.bucket });
6538
+ return new StateError(`Failed to ${access === "write" ? "read or write" : "read"} the write-ahead stack instance id of stack ${this.stackRef(stackName, region)} (${STACK_INSTANCE_SIBLING_FILE} beside its state.json): ${errorDetail$2(normalized)}. ` + (access === "write" ? "Nothing was created; re-run once the state bucket can be written." : "Nothing was changed; re-run once the state bucket can be read."), normalized);
6539
+ }
6540
+ async readSiblingId(key, stackName, region) {
6541
+ const body = await this.getRawObject(key);
6542
+ if (body === null) return null;
6543
+ const id = parseStackInstanceSibling(body);
6544
+ if (id === null) throw new StateError(`The write-ahead stack instance id of stack ${this.stackRef(stackName, region)} (${STACK_INSTANCE_SIBLING_FILE} beside its state.json) is in a format this cdkd version cannot read; upgrade cdkd, or delete that object if it is damaged`);
6545
+ return id;
6546
+ }
6547
+ async readStackInstanceSibling(stackName, region) {
6548
+ try {
6549
+ return await this.readSiblingId(this.getStackInstanceKey(stackName, region), stackName, region) ?? void 0;
6550
+ } catch (error) {
6551
+ if (error instanceof StateError) throw error;
6552
+ throw this.stackInstanceSiblingError(stackName, region, error, "read");
6553
+ }
6554
+ }
6555
+ async deleteStackInstanceSibling(stackName, region) {
6556
+ await this.ensureClientForBucket();
6557
+ const key = this.getStackInstanceKey(stackName, region);
6558
+ this.pendingStackInstanceSiblings.delete(key);
6559
+ try {
6560
+ await this.s3Client.send(new DeleteObjectCommand({
6561
+ Bucket: this.config.bucket,
6562
+ ...await this.ownerParam(),
6563
+ Key: key
6564
+ }));
6565
+ } catch (error) {
6566
+ if (isNoSuchKey(error) || error.name === "NotFound") return;
6567
+ const normalized = normalizeAwsError(error, {
6568
+ bucket: this.config.bucket,
6569
+ operation: "DeleteObject"
6570
+ });
6571
+ throw new StateError(`Failed to delete the write-ahead stack instance id for stack ${this.stackRef(stackName, region)}: ${errorDetail$2(normalized)}. The state record was left in place; re-run once that object can be deleted.`, normalized);
6572
+ }
6573
+ }
6574
+ async dropStackInstanceSiblingAfterSave(stackName, region) {
6575
+ try {
6576
+ await this.deleteStackInstanceSibling(stackName, region);
6577
+ } catch (error) {
6578
+ this.logger.debug(safeMsg`Could not delete the write-ahead stack instance id of ${displayStackName(stackName)}: ${describeAwsFailure(error).summary}`);
6579
+ return;
6580
+ }
6581
+ await this.purgeNoncurrentVersions([this.getStackInstanceKey(stackName, region)], { objectDescription: STACK_INSTANCE_OBJECT_DESCRIPTION });
6582
+ }
6416
6583
  async loadRollbackJournal(stackName, region) {
6417
6584
  const key = this.rollbackJournalKey(stackName, region);
6418
6585
  const touches = this.journalTouches.get(key) ?? 0;
@@ -6611,6 +6778,7 @@ var S3StateBackend = class S3StateBackend {
6611
6778
  if (raw === region) return { state };
6612
6779
  if (raw === void 0) return { state: {
6613
6780
  ...state,
6781
+ ...stackInstanceIdCarriedFrom(state),
6614
6782
  region
6615
6783
  } };
6616
6784
  const kind = describeRegionValueKind(raw);
@@ -6619,6 +6787,7 @@ var S3StateBackend = class S3StateBackend {
6619
6787
  return {
6620
6788
  state: {
6621
6789
  ...state,
6790
+ ...stackInstanceIdCarriedFrom(state),
6622
6791
  region
6623
6792
  },
6624
6793
  divergentBodyRegion: raw
@@ -13577,62 +13746,21 @@ function sentIdentifierIs(requested, recorded, observed, physicalId) {
13577
13746
  return sent !== void 0 && heldAt(recorded, observed, [key]).value === sent;
13578
13747
  });
13579
13748
  }
13749
+ const derivedEntry = (resourceType, file) => ({
13750
+ file,
13751
+ source: `generatedNameFor('${resourceType}', logicalId)`,
13752
+ derive: (id) => generatedNameFor(resourceType, id)
13753
+ });
13580
13754
  const DERIVED_GENERATED_NAMES = {
13581
- "AWS::AutoScaling::AutoScalingGroup": {
13582
- file: "asg-provider.ts",
13583
- source: "generateResourceName(logicalId, { maxLength: 255 })",
13584
- derive: (id) => generateResourceName(id, { maxLength: 255 })
13585
- },
13586
- "AWS::CodeCommit::Repository": {
13587
- file: "codecommit-repository-provider.ts",
13588
- source: "generateResourceName(logicalId, { maxLength: 100 })",
13589
- derive: (id) => generateResourceName(id, { maxLength: 100 })
13590
- },
13591
- "AWS::DynamoDB::GlobalTable": {
13592
- file: "dynamodb-globaltable-provider.ts",
13593
- source: "generateResourceName(logicalId, { maxLength: 255 })",
13594
- derive: (id) => generateResourceName(id, { maxLength: 255 })
13595
- },
13596
- "AWS::Logs::LogGroup": {
13597
- file: "logs-loggroup-provider.ts",
13598
- source: "`/cdkd/${generateResourceName(logicalId, { maxLength: 506, allowedPattern: /[^a-zA-Z0-9-/_]/g })}`",
13599
- derive: (id) => `/cdkd/${generateResourceName(id, {
13600
- maxLength: 506,
13601
- allowedPattern: /[^a-zA-Z0-9-/_]/g
13602
- })}`
13603
- },
13604
- "AWS::RDS::DBProxy": {
13605
- file: "rds-dbproxy-provider.ts",
13606
- source: "generateResourceName(logicalId, { maxLength: 64 })",
13607
- derive: (id) => generateResourceName(id, { maxLength: 64 })
13608
- },
13609
- "AWS::RDS::DBProxyEndpoint": {
13610
- file: "rds-dbproxy-endpoint-provider.ts",
13611
- source: "generateResourceName(logicalId, { maxLength: 64 })",
13612
- derive: (id) => generateResourceName(id, { maxLength: 64 })
13613
- },
13614
- "AWS::S3::Bucket": {
13615
- file: "s3-bucket-provider.ts",
13616
- source: "generateResourceName(logicalId, {\n maxLength: 63,\n lowercase: true,\n allowedPattern: /[^a-z0-9.-]/g,\n })",
13617
- derive: (id) => generateResourceName(id, {
13618
- maxLength: 63,
13619
- lowercase: true,
13620
- allowedPattern: /[^a-z0-9.-]/g
13621
- })
13622
- },
13623
- "AWS::Scheduler::Schedule": {
13624
- file: "scheduler-schedule-provider.ts",
13625
- source: "generateResourceName(logicalId, { maxLength: 64 })",
13626
- derive: (id) => generateResourceName(id, { maxLength: 64 })
13627
- },
13628
- "AWS::SSM::Parameter": {
13629
- file: "ssm-parameter-provider.ts",
13630
- source: "`/${generateResourceName(logicalId, { maxLength: 1023, allowedPattern: /[^a-zA-Z0-9-/_]/g })}`",
13631
- derive: (id) => `/${generateResourceName(id, {
13632
- maxLength: 1023,
13633
- allowedPattern: /[^a-zA-Z0-9-/_]/g
13634
- })}`
13635
- }
13755
+ "AWS::AutoScaling::AutoScalingGroup": derivedEntry("AWS::AutoScaling::AutoScalingGroup", "asg-provider.ts"),
13756
+ "AWS::CodeCommit::Repository": derivedEntry("AWS::CodeCommit::Repository", "codecommit-repository-provider.ts"),
13757
+ "AWS::DynamoDB::GlobalTable": derivedEntry("AWS::DynamoDB::GlobalTable", "dynamodb-globaltable-provider.ts"),
13758
+ "AWS::Logs::LogGroup": derivedEntry("AWS::Logs::LogGroup", "logs-loggroup-provider.ts"),
13759
+ "AWS::RDS::DBProxy": derivedEntry("AWS::RDS::DBProxy", "rds-dbproxy-provider.ts"),
13760
+ "AWS::RDS::DBProxyEndpoint": derivedEntry("AWS::RDS::DBProxyEndpoint", "rds-dbproxy-endpoint-provider.ts"),
13761
+ "AWS::S3::Bucket": derivedEntry("AWS::S3::Bucket", "s3-bucket-provider.ts"),
13762
+ "AWS::Scheduler::Schedule": derivedEntry("AWS::Scheduler::Schedule", "scheduler-schedule-provider.ts"),
13763
+ "AWS::SSM::Parameter": derivedEntry("AWS::SSM::Parameter", "ssm-parameter-provider.ts")
13636
13764
  };
13637
13765
 
13638
13766
  //#endregion
@@ -13720,6 +13848,52 @@ function replacementSentNameMoves(input) {
13720
13848
  physicalId: input.physicalId
13721
13849
  };
13722
13850
  }
13851
+ function generatedReplacementName(resourceType, createdVia, desired, logicalId) {
13852
+ const declared = (property) => {
13853
+ const value = desired?.[property];
13854
+ return value !== void 0 && value !== null && value !== "";
13855
+ };
13856
+ const fallbackProperty = fallbackNamePropertyFor(resourceType);
13857
+ if (createdVia === "cc-api" || GENERATED_NAME_VERBATIM.has(resourceType)) {
13858
+ if (fallbackProperty === void 0 || declared(fallbackProperty)) return void 0;
13859
+ const name = applyDefaultNameForFallback(logicalId, resourceType, desired ?? {}, "omit")[fallbackProperty];
13860
+ return typeof name === "string" ? {
13861
+ property: fallbackProperty,
13862
+ name
13863
+ } : void 0;
13864
+ }
13865
+ const rewrite = ownEntry$1(SENT_NAME_REWRITTEN, resourceType);
13866
+ if (rewrite !== void 0) {
13867
+ if (declared(rewrite.property)) return void 0;
13868
+ return {
13869
+ property: rewrite.property,
13870
+ name: generateResourceNameWithFallback(void 0, logicalId, { maxLength: rewrite.maxLength })
13871
+ };
13872
+ }
13873
+ const derived = ownEntry$1(DERIVED_GENERATED_NAMES, resourceType);
13874
+ const property = explicitNamePropertyFor(resourceType);
13875
+ if (derived === void 0 || property === void 0 || declared(property)) return void 0;
13876
+ return {
13877
+ property,
13878
+ name: derived.derive(logicalId)
13879
+ };
13880
+ }
13881
+ function replacementGeneratedNameMoves(input) {
13882
+ if (getCurrentStackInstanceId() === void 0) return void 0;
13883
+ if (input.oldResourceType !== input.newResourceType) return void 0;
13884
+ const generated = generatedReplacementName(input.newResourceType, input.createdVia, input.desiredProperties, input.logicalId);
13885
+ if (generated === void 0 || generated.name === "") return void 0;
13886
+ const fold = CASE_INSENSITIVE_NAME_TYPES.has(input.newResourceType) ? (value) => value.toLowerCase() : (value) => value;
13887
+ if (input.physicalId === "" || holderIdNames(fold(input.physicalId), fold(generated.name))) return;
13888
+ return {
13889
+ property: generated.property,
13890
+ desiredName: generated.name,
13891
+ heldName: void 0,
13892
+ heldProperty: void 0,
13893
+ physicalId: input.physicalId,
13894
+ generated: true
13895
+ };
13896
+ }
13723
13897
  function maskRewrittenSentName(resourceType, properties, logicalId, base) {
13724
13898
  const sent = sentRewrittenName(resourceType, properties, logicalId);
13725
13899
  if (sent === void 0) return base;
@@ -27247,7 +27421,7 @@ var CloudControlProvider = class {
27247
27421
  const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
27248
27422
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
27249
27423
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
27250
- const { ASGProvider } = await import("./asg-provider-ak7zMqaQ.js");
27424
+ const { ASGProvider } = await import("./asg-provider-BRr_hsky.js");
27251
27425
  const delegateRegion = ambientRegion();
27252
27426
  let asgProvider = this.asgDeleteDelegates.get(delegateRegion);
27253
27427
  if (asgProvider === void 0) {
@@ -27353,7 +27527,7 @@ var CloudControlProvider = class {
27353
27527
  const family = SDK_DELETE_FAMILIES.get(resourceType);
27354
27528
  const cached = this.sdkDeleteDelegates.get(family);
27355
27529
  if (cached !== void 0 && cached.region === ccRegion) return cached.provider;
27356
- const provider = family === "rds" ? new (await (import("./rds-provider-D0srL6Rb.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-BTkMpImX.js"))).NeptuneProvider({ region: ccRegion });
27530
+ const provider = family === "rds" ? new (await (import("./rds-provider-6RgDTDCV.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-WE1O3kXY.js"))).NeptuneProvider({ region: ccRegion });
27357
27531
  this.sdkDeleteDelegates.set(family, {
27358
27532
  region: ccRegion,
27359
27533
  provider
@@ -28864,6 +29038,9 @@ function parseLambdaPayload(payloadBytes, mask) {
28864
29038
  }
28865
29039
  return parsed;
28866
29040
  }
29041
+ function asSentence(text) {
29042
+ return text.endsWith(".") ? text : `${text}.`;
29043
+ }
28867
29044
  function decodeInvokeLogTail(logResult) {
28868
29045
  if (!logResult) return void 0;
28869
29046
  try {
@@ -28875,19 +29052,57 @@ function decodeInvokeLogTail(logResult) {
28875
29052
  }
28876
29053
  function lambdaStatusParts(response) {
28877
29054
  const config = response?.Configuration;
28878
- if (typeof config !== "object" || config === null || Array.isArray(config)) return [];
29055
+ if (typeof config !== "object" || config === null || Array.isArray(config)) return {
29056
+ parts: [],
29057
+ reasons: []
29058
+ };
28879
29059
  const fields = config;
28880
29060
  const status = [
28881
- ["State", fields["State"]],
28882
- ["StateReasonCode", fields["StateReasonCode"]],
28883
- ["StateReason", fields["StateReason"]],
28884
- ["LastUpdateStatus", fields["LastUpdateStatus"]],
28885
- ["LastUpdateStatusReasonCode", fields["LastUpdateStatusReasonCode"]],
28886
- ["LastUpdateStatusReason", fields["LastUpdateStatusReason"]]
29061
+ [
29062
+ "State",
29063
+ fields["State"],
29064
+ "shown"
29065
+ ],
29066
+ [
29067
+ "StateReasonCode",
29068
+ fields["StateReasonCode"],
29069
+ "shown"
29070
+ ],
29071
+ [
29072
+ "StateReason",
29073
+ fields["StateReason"],
29074
+ "withheld"
29075
+ ],
29076
+ [
29077
+ "LastUpdateStatus",
29078
+ fields["LastUpdateStatus"],
29079
+ "shown"
29080
+ ],
29081
+ [
29082
+ "LastUpdateStatusReasonCode",
29083
+ fields["LastUpdateStatusReasonCode"],
29084
+ "shown"
29085
+ ],
29086
+ [
29087
+ "LastUpdateStatusReason",
29088
+ fields["LastUpdateStatusReason"],
29089
+ "withheld"
29090
+ ]
28887
29091
  ];
28888
29092
  const parts = [];
28889
- for (const [key, value] of status) if (typeof value === "string" && value !== "") parts.push(`${key}=${value}`);
28890
- return parts;
29093
+ const reasons = [];
29094
+ for (const [key, value, kind] of status) {
29095
+ if (typeof value !== "string" || value === "") continue;
29096
+ if (kind === "shown") parts.push(`${key}=${value}`);
29097
+ else {
29098
+ parts.push(`${key} withheld`);
29099
+ reasons.push(`${key}=${value}`);
29100
+ }
29101
+ }
29102
+ return {
29103
+ parts,
29104
+ reasons
29105
+ };
28891
29106
  }
28892
29107
  var WaiterRejections = class {
28893
29108
  seen = /* @__PURE__ */ new Map();
@@ -28965,7 +29180,7 @@ function describeLambdaWaiterFailure(error, rejections) {
28965
29180
  if (typeof parsed !== "object" || parsed === null || !("state" in parsed)) return void 0;
28966
29181
  const result = parsed;
28967
29182
  const observed = typeof result.observedResponses === "object" && result.observedResponses !== null && !Array.isArray(result.observedResponses) ? result.observedResponses : {};
28968
- const parts = lambdaStatusParts(result.reason);
29183
+ const { parts, reasons } = lambdaStatusParts(result.reason);
28969
29184
  if (parts.length === 0) for (const key of Object.keys(observed).reverse()) {
28970
29185
  let response;
28971
29186
  try {
@@ -28973,9 +29188,10 @@ function describeLambdaWaiterFailure(error, rejections) {
28973
29188
  } catch {
28974
29189
  continue;
28975
29190
  }
28976
- const observedParts = lambdaStatusParts(response);
28977
- if (observedParts.length > 0) {
28978
- parts.push(...observedParts);
29191
+ const observedStatus = lambdaStatusParts(response);
29192
+ if (observedStatus.parts.length > 0) {
29193
+ parts.push(...observedStatus.parts);
29194
+ reasons.push(...observedStatus.reasons);
28979
29195
  break;
28980
29196
  }
28981
29197
  }
@@ -28994,11 +29210,16 @@ function describeLambdaWaiterFailure(error, rejections) {
28994
29210
  if (recorded.length === 0 && nonErrors === 0 && rejectionKeys > 0) parts.push(`${rejectionKeys} observed error message(s) withheld`);
28995
29211
  const state = typeof result.state === "string" ? result.state : "failure";
28996
29212
  const reason = typeof result.reason === "string" && result.reason !== "" ? `: ${result.reason}` : "";
28997
- return `${error.name} (waiter ${state}${reason}; ${parts.length > 0 ? parts.join(", ") : "no function status reported"}). The waiter's raw payload is withheld because it embeds the whole GetFunction response, environment variables included; run \`aws lambda get-function\` for the detail.`;
29213
+ return {
29214
+ text: `${error.name} (waiter ${state}${reason}; ${parts.length > 0 ? parts.join(", ") : "no function status reported"}). ` + (reasons.length > 0 ? `${VERBOSE_POINTER} ` : "") + "The waiter's raw payload is withheld because it embeds the whole GetFunction response, environment variables included; run `aws lambda get-function` for the detail.",
29215
+ reasons
29216
+ };
28998
29217
  }
28999
- function withholdWaiterPayload(error, rejections) {
29000
- const described = describeLambdaWaiterFailure(error, rejections);
29001
- if (described === void 0 || !(error instanceof Error)) return void 0;
29218
+ function withholdWaiterPayload(error, rejections, debug) {
29219
+ const failure = describeLambdaWaiterFailure(error, rejections);
29220
+ if (failure === void 0 || !(error instanceof Error)) return void 0;
29221
+ for (const reason of failure.reasons) debug(safeMsg`Lambda waiter status reason: ${reason}`);
29222
+ const described = failure.text;
29002
29223
  const header = `${error.name}: ${error.message}`;
29003
29224
  const stack = typeof error.stack === "string" ? error.stack : "";
29004
29225
  try {
@@ -29017,8 +29238,8 @@ function withholdWaiterPayload(error, rejections) {
29017
29238
  } catch {}
29018
29239
  return described;
29019
29240
  }
29020
- function describeWaiterFailure(error, rejections) {
29021
- const withheld = withholdWaiterPayload(error, rejections);
29241
+ function describeWaiterFailure(error, rejections, debug) {
29242
+ const withheld = withholdWaiterPayload(error, rejections, debug);
29022
29243
  if (withheld !== void 0) return withheld;
29023
29244
  return `${error instanceof Error ? error.name : "Error"} (no function status reported). The waiter's raw payload is withheld because it embeds the whole GetFunction response, environment variables included; run \`aws lambda get-function\` for the detail.`;
29024
29245
  }
@@ -29035,7 +29256,7 @@ async function waitForLambdaFunctionActive(client, functionArn, abortSignal) {
29035
29256
  } catch (error) {
29036
29257
  const log = getLogger().child("LambdaActiveWait");
29037
29258
  for (const line of waiterRejectionDebugLines(rejections)) log.debug(safeMsg`Active waiter for ${functionArn} observed ${line}`);
29038
- throw markNonRetryable(new Error(`Lambda function ${functionArn} did not reach the Active state: ${describeWaiterFailure(error, rejections)}`, { cause: error }));
29259
+ throw markNonRetryable(new Error(`Lambda function ${functionArn} did not reach the Active state: ${describeWaiterFailure(error, rejections, (line) => log.debug(line))}`, { cause: error }));
29039
29260
  }
29040
29261
  }
29041
29262
  const CR_TRANSIENT_AUTHZ_SIGNALS = [
@@ -29201,6 +29422,13 @@ var CustomResourceProvider = class CustomResourceProvider {
29201
29422
  await this.sleepInterruptibly(delayMs, watch);
29202
29423
  }
29203
29424
  }
29425
+ wrapCaughtError(mask, error, build) {
29426
+ const failure = describeAwsFailure(error);
29427
+ if (!failure.redacted) return build(failure.detail);
29428
+ this.logger.debug(maskerOrIdentity(mask)(build(failure.detail).message));
29429
+ const wrapped = build(failure.summary);
29430
+ return error instanceof Error ? markRedactedCause(wrapped) : wrapped;
29431
+ }
29204
29432
  async create(logicalId, resourceType, properties, context) {
29205
29433
  this.logger.debug(`Creating custom resource ${logicalId} (${resourceType})`);
29206
29434
  const serviceToken = properties["ServiceToken"];
@@ -29229,7 +29457,7 @@ var CustomResourceProvider = class CustomResourceProvider {
29229
29457
  } catch (error) {
29230
29458
  markAuxiliaryFailure(error, logicalId);
29231
29459
  const cause = error instanceof Error ? error : void 0;
29232
- throw new ProvisioningError(`Failed to create custom resource ${logicalId}: ${describeAwsFailure(error).detail}`, resourceType, logicalId, void 0, cause);
29460
+ throw this.wrapCaughtError(context?.maskSecrets, error, (text) => new ProvisioningError(`Failed to create custom resource ${logicalId}: ${text}`, resourceType, logicalId, void 0, cause));
29233
29461
  }
29234
29462
  }
29235
29463
  async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
@@ -29263,7 +29491,7 @@ var CustomResourceProvider = class CustomResourceProvider {
29263
29491
  };
29264
29492
  } catch (error) {
29265
29493
  const cause = error instanceof Error ? error : void 0;
29266
- throw new ProvisioningError(`Failed to update custom resource ${logicalId}: ${describeAwsFailure(error).detail}`, resourceType, logicalId, physicalId, cause);
29494
+ throw this.wrapCaughtError(context?.maskSecrets, error, (text) => new ProvisioningError(`Failed to update custom resource ${logicalId}: ${text}`, resourceType, logicalId, physicalId, cause));
29267
29495
  }
29268
29496
  }
29269
29497
  async delete(logicalId, physicalId, resourceType, properties, context) {
@@ -29348,7 +29576,9 @@ var CustomResourceProvider = class CustomResourceProvider {
29348
29576
  }
29349
29577
  this.logger.debug(`Successfully deleted custom resource ${logicalId}`);
29350
29578
  } catch (error) {
29351
- this.logger.warn(show(`Failed to delete custom resource ${logicalId}, but continuing: ${describeAwsFailure(error).detail}. The Delete handler did not complete, so anything this custom resource manages may still be LIVE${handlerSkipRemedy(context, logicalId)}`));
29579
+ const failure = describeAwsFailure(error);
29580
+ this.logger.warn(show(`Failed to delete custom resource ${logicalId}, but continuing: ${asSentence(failure.summary)} The Delete handler did not complete, so anything this custom resource manages may still be LIVE${handlerSkipRemedy(context, logicalId)}`));
29581
+ if (failure.redacted) this.logger.debug(show(`Custom resource ${logicalId} delete failure detail: ${failure.detail}`));
29352
29582
  return {
29353
29583
  outcome: "skipped",
29354
29584
  reason: CR_DELETE_INVOKE_FAILED_SKIP_REASON
@@ -29388,7 +29618,7 @@ var CustomResourceProvider = class CustomResourceProvider {
29388
29618
  let logResult;
29389
29619
  let invocation;
29390
29620
  try {
29391
- invocation = await this.prepareInvocation(logicalId, watch);
29621
+ invocation = await this.prepareInvocation(logicalId, watch, mask);
29392
29622
  const request = buildRequest({
29393
29623
  ...invocation,
29394
29624
  stackId
@@ -29402,7 +29632,9 @@ var CustomResourceProvider = class CustomResourceProvider {
29402
29632
  } catch (error) {
29403
29633
  if (delivered || preDeliveryRetries >= this.preDeliveryAuthzMaxRetries || !this.isTransientAuthzThrow(error)) throw error;
29404
29634
  const delayMs = Math.min(250 * Math.pow(2, preDeliveryRetries), IAM_PROPAGATION_MAX_DELAY_MS);
29405
- this.logger.warn(`Custom resource ${operation} for ${logicalId} hit a transient IAM-authorization error before the request was delivered (attempt ${attempt + 1}/${this.preDeliveryAuthzMaxRetries + 1}): ${this.truncateReason(shown(describeAwsFailure(error).detail))}. Retrying in ${delayMs / 1e3}s with a fresh response URL and RequestId.`);
29635
+ const failure = describeAwsFailure(error);
29636
+ this.logger.warn(`Custom resource ${operation} for ${logicalId} hit a transient IAM-authorization error before the request was delivered (attempt ${attempt + 1}/${this.preDeliveryAuthzMaxRetries + 1}): ${asSentence(this.truncateReason(shown(failure.summary)))} Retrying in ${delayMs / 1e3}s with a fresh response URL and RequestId.`);
29637
+ if (failure.redacted) this.logger.debug(`Custom resource ${operation} for ${logicalId} pre-delivery failure detail: ${shown(failure.detail)}`);
29406
29638
  if (invocation !== void 0) await this.cleanupResponseObject(invocation.responseKey);
29407
29639
  preDeliveryRetries += 1;
29408
29640
  await this.sleepInterruptibly(delayMs, watch);
@@ -29414,7 +29646,7 @@ var CustomResourceProvider = class CustomResourceProvider {
29414
29646
  if (cfnResponse.Status === "FAILED" && failedResponseRetries < this.transientAuthzMaxRetries && (reasonIsAuthz || logAuthzMatch !== void 0)) {
29415
29647
  failedResponseRetries += 1;
29416
29648
  this.logger.warn(`Custom resource ${operation} for ${logicalId} returned a transient IAM-authorization FAILED (attempt ${attempt + 1}/${this.transientAuthzMaxRetries + 1}): ${this.truncateReason(cfnResponse.Reason === void 0 ? void 0 : shown(cfnResponse.Reason))}. ` + (logAuthzMatch === void 0 ? "" : `The handler's reason carried no authorization wording; the denial was found in the backing function's log: ${this.truncateReason(shown(logAuthzMatch.line))}. `) + `Recycling the backing function's execution environment and retrying so its next cold start picks up the propagated policy.`);
29417
- await this.recycleBackingFunctionExecEnv(serviceToken, logicalId);
29649
+ await this.recycleBackingFunctionExecEnv(serviceToken, logicalId, mask);
29418
29650
  continue;
29419
29651
  }
29420
29652
  if (cfnResponse.Status === "FAILED" && logAuthzMatch !== void 0) return {
@@ -29461,7 +29693,7 @@ var CustomResourceProvider = class CustomResourceProvider {
29461
29693
  const r = displaySafe(reason ?? "Unknown reason");
29462
29694
  return r.length > max ? `${r.slice(0, max)}...` : r;
29463
29695
  }
29464
- async recycleBackingFunctionExecEnv(serviceToken, logicalId) {
29696
+ async recycleBackingFunctionExecEnv(serviceToken, logicalId, mask) {
29465
29697
  if (this.isSnsServiceToken(serviceToken)) return;
29466
29698
  const rejections = new WaiterRejections();
29467
29699
  try {
@@ -29476,7 +29708,7 @@ var CustomResourceProvider = class CustomResourceProvider {
29476
29708
  maxDelay: 5
29477
29709
  }, { FunctionName: serviceToken });
29478
29710
  } catch (error) {
29479
- this.logger.debug(`Could not recycle backing function for ${logicalId} (${withholdWaiterPayload(error, rejections) ?? (error instanceof Error && carriesResponseBody(error) ? `${error.name} (response body withheld)` : describeAwsFailure(error).detail)}); retrying invoke without a forced cold start`);
29711
+ this.logger.debug(`Could not recycle backing function for ${logicalId} (${withholdWaiterPayload(error, rejections, (line) => this.logger.debug(maskerOrIdentity(mask)(line))) ?? (error instanceof Error && carriesResponseBody(error) ? `${error.name} (response body withheld)` : describeAwsFailure(error).detail)}); retrying invoke without a forced cold start`);
29480
29712
  this.debugWaiterRejections(logicalId, rejections);
29481
29713
  }
29482
29714
  }
@@ -29490,7 +29722,7 @@ var CustomResourceProvider = class CustomResourceProvider {
29490
29722
  onDelivered();
29491
29723
  return { response: await this.pollS3Response(responseKey, logicalId, operation) };
29492
29724
  }
29493
- await this.waitForBackingLambdaReady(serviceToken, logicalId);
29725
+ await this.waitForBackingLambdaReady(serviceToken, logicalId, mask);
29494
29726
  const invokeResponse = await this.invokeLambda(serviceToken, request);
29495
29727
  onDelivered();
29496
29728
  return {
@@ -29498,7 +29730,7 @@ var CustomResourceProvider = class CustomResourceProvider {
29498
29730
  ...invokeResponse.LogResult === void 0 ? {} : { logResult: invokeResponse.LogResult }
29499
29731
  };
29500
29732
  }
29501
- async waitForBackingLambdaReady(serviceToken, logicalId) {
29733
+ async waitForBackingLambdaReady(serviceToken, logicalId, mask) {
29502
29734
  let rejections = new WaiterRejections();
29503
29735
  try {
29504
29736
  await waitUntilFunctionActiveV2({
@@ -29516,7 +29748,7 @@ var CustomResourceProvider = class CustomResourceProvider {
29516
29748
  }, { FunctionName: serviceToken });
29517
29749
  } catch (error) {
29518
29750
  this.debugWaiterRejections(logicalId, rejections);
29519
- throw markNonRetryable(new Error(`Lambda backing custom resource ${logicalId} (${serviceToken}) did not reach a ready state for Invoke: ${describeWaiterFailure(error, rejections)}`, { cause: error }));
29751
+ throw markNonRetryable(new Error(`Lambda backing custom resource ${logicalId} (${serviceToken}) did not reach a ready state for Invoke: ${describeWaiterFailure(error, rejections, (line) => this.logger.debug(maskerOrIdentity(mask)(line)))}`, { cause: error }));
29520
29752
  }
29521
29753
  }
29522
29754
  async publishToSns(topicArn, request) {
@@ -29574,16 +29806,16 @@ var CustomResourceProvider = class CustomResourceProvider {
29574
29806
  const timeoutMs = isAsyncPattern ? this.asyncResponseTimeoutMs : this.SYNC_RESPONSE_TIMEOUT_MS;
29575
29807
  return await this.pollS3Response(responseKey, logicalId, operation, timeoutMs, isAsyncPattern);
29576
29808
  }
29577
- async prepareInvocation(logicalId, watch) {
29809
+ async prepareInvocation(logicalId, watch, mask) {
29578
29810
  const requestId = `cdkd-${Date.now()}-${Math.random().toString(36).substring(7)}`;
29579
29811
  const responseKey = this.getResponseKey(requestId);
29580
29812
  return {
29581
29813
  requestId,
29582
29814
  responseKey,
29583
- responseURL: await this.generateResponseURL(responseKey, logicalId, watch)
29815
+ responseURL: await this.generateResponseURL(responseKey, logicalId, watch, mask)
29584
29816
  };
29585
29817
  }
29586
- async generateResponseURL(responseKey, logicalId, watch) {
29818
+ async generateResponseURL(responseKey, logicalId, watch, mask) {
29587
29819
  if (!this.responseBucket) return "https://localhost/cfn-response-not-configured";
29588
29820
  await this.ensureResponseClient();
29589
29821
  const bucket = this.responseBucket;
@@ -29602,7 +29834,10 @@ var CustomResourceProvider = class CustomResourceProvider {
29602
29834
  sleep: customResourceRetryDelays.sleep
29603
29835
  });
29604
29836
  } catch (error) {
29605
- throw markNonRetryable(error instanceof Error ? error : new Error(safeStringify$1(error)));
29837
+ if (error instanceof Error) throw markNonRetryable(error);
29838
+ const failure = describeAwsFailure(error);
29839
+ this.logger.debug(maskerOrIdentity(mask)(`Response placeholder PutObject failure detail: ${failure.detail}`));
29840
+ throw markNonRetryable(new Error(failure.summary));
29606
29841
  }
29607
29842
  const command = new PutObjectCommand({
29608
29843
  Bucket: this.responseBucket,
@@ -32024,7 +32259,7 @@ const STACK_SCOPED_DIGEST_LENGTH = 12;
32024
32259
  function stackScopedCreateToken(options) {
32025
32260
  const { logicalId, immutableInputs, maxLength } = options;
32026
32261
  const stackName = getCurrentStackName();
32027
- if (stackName === void 0 && !unscopedCreateTokensAllowed) throw new Error(`cdkd internal error: a create token for ${logicalId} was requested outside a stack scope (withStackName), so it cannot be scoped to its stack`);
32262
+ if (stackName === void 0 && !unscopedCreateTokensAllowed) throw new Error(`cdkd internal error: a create token for ${logicalId} was requested outside a stack scope (withStackScope), so it cannot be scoped to its stack`);
32028
32263
  const digest = createHash("sha256").update(injectiveKey(stackName ?? "", ambientRegion() ?? "", logicalId, ...immutableInputs.map((v) => JSON.stringify(v ?? null)))).digest("hex").slice(0, STACK_SCOPED_DIGEST_LENGTH);
32029
32264
  const prefixLength = maxLength - 5 - 1 - STACK_SCOPED_DIGEST_LENGTH;
32030
32265
  return `cdkd-${logicalId.slice(0, prefixLength)}-${digest}`;
@@ -33079,8 +33314,13 @@ function retainedSurvivorMessages(logicalId, resourceType, survivorPhysicalId, s
33079
33314
  //#endregion
33080
33315
  //#region src/deployment/rollback-executor/names.ts
33081
33316
  function replayPrefixScope(input, logger, mask, restoring) {
33317
+ const generation = input.nameGeneration;
33318
+ const inGeneration = (fn) => generation === void 0 ? fn() : withNameGeneration({
33319
+ logicalId: input.logicalId,
33320
+ generation
33321
+ }, fn);
33082
33322
  const choice = replayPrefixChoice(input);
33083
- if (choice.kind === "not-applicable") return (fn) => fn();
33323
+ if (choice.kind === "not-applicable") return (fn) => inGeneration(fn);
33084
33324
  const setting = (skip) => skip ? "SKIPPED" : "KEPT";
33085
33325
  const subject = `${safe(input.logicalId)} (${safe(input.resourceType)})`;
33086
33326
  const declared = choice.declared;
@@ -33100,7 +33340,7 @@ function replayPrefixScope(input, logger, mask, restoring) {
33100
33340
  logger.warn(mask(` ⚠ ${subject}: cdkd cannot tell which user-supplied-name prefix setting created the old resource (` + (withheld ? `its physical id is withheld, as its name is secret-derived or unreadable` : shown(input.physicalId)) + `) — ` + (choice.names === void 0 ? unreadable !== void 0 ? `cdkd cannot read ${unreadable} to compare` : `cdkd cannot derive the names its ${prop} takes to compare` : secretDerived ? `its ${prop} is secret-derived, and neither name it derives matches` : `its ${prop} derives to ${quoted(choice.names.skipped)} (prefix skipped) or ${quoted(choice.names.kept)} (prefix kept), and it is neither`) + `; re-creating it with the stack-name prefix ${setting(choice.skipPrefix)}, as the failed deploy ran, so it may come back under a different physical name.`));
33101
33341
  }
33102
33342
  const skip = choice.skipPrefix;
33103
- return (fn) => withSkipPrefix(skip, fn);
33343
+ return (fn) => withSkipPrefix(skip, () => inGeneration(fn));
33104
33344
  }
33105
33345
  function createOpMasker(logger, secrets, deployBag) {
33106
33346
  const base = createMaskedLogSinks(logger, deployBag === void 0 ? (text) => maskSecretsInText(text, secrets) : createUnionSecretMasker([secrets, deployBag]));
@@ -34196,6 +34436,149 @@ function maskedRecordRemedyFor(reads, resources, causeScoped = false) {
34196
34436
  return [parts.join(" "), ...commandLines].join("\n");
34197
34437
  }
34198
34438
 
34439
+ //#endregion
34440
+ //#region src/deployment/delete-guard-scope.ts
34441
+ const storage$1 = new AsyncLocalStorage();
34442
+ function collectDeleteGuards(sink, fn) {
34443
+ return storage$1.run(sink, fn);
34444
+ }
34445
+ function reportDeleteGuards(result, target) {
34446
+ const sink = storage$1.getStore();
34447
+ if (!sink) return;
34448
+ for (const guard of deleteIndeterminateGuards(result)) sink.push({
34449
+ guard: guard.guard,
34450
+ reason: guard.reason,
34451
+ physicalId: target.physicalId,
34452
+ resourceType: target.resourceType,
34453
+ ...target.provisionedBy && { provisionedBy: target.provisionedBy }
34454
+ });
34455
+ }
34456
+
34457
+ //#endregion
34458
+ //#region src/deployment/superseded-resources.ts
34459
+ function supersededResourcesOf(state) {
34460
+ const rows = state?.supersededResources;
34461
+ if (!Array.isArray(rows)) return [];
34462
+ return rows.filter(isSupersededResourceRecord);
34463
+ }
34464
+ function isSupersededResourceRecord(row) {
34465
+ if (typeof row !== "object" || row === null) return false;
34466
+ const entry = row;
34467
+ const record = entry["state"];
34468
+ if (typeof entry["logicalId"] !== "string") return false;
34469
+ if (typeof record !== "object" || record === null) return false;
34470
+ const { physicalId, resourceType, properties } = record;
34471
+ return typeof physicalId === "string" && physicalId !== "" && typeof resourceType === "string" && resourceType !== "" && typeof properties === "object" && properties !== null && !Array.isArray(properties);
34472
+ }
34473
+ function supersededHolderOf(entry, resources) {
34474
+ const holders = Object.values(resources).filter((record) => typeof record === "object" && record !== null && record.physicalId === entry.state.physicalId);
34475
+ return holders.find((record) => record.resourceType === entry.state.resourceType) ?? holders[0];
34476
+ }
34477
+ function isSupersededHeldBySameType(entry, resources) {
34478
+ return Object.values(resources).some((record) => typeof record === "object" && record !== null && record.physicalId === entry.state.physicalId && record.resourceType === entry.state.resourceType);
34479
+ }
34480
+ function supersededHeldByOtherTypeWarning(entry, holderType) {
34481
+ return `the superseded ${entry.state.resourceType} of ${entry.logicalId} (${entry.state.physicalId}) was not deleted: a ${holderType} record of this stack has the same physical id, and cdkd never deletes an id a record names. If the ${entry.state.resourceType} still exists, delete it by hand; it is no longer tracked in state.`;
34482
+ }
34483
+ function addSuperseded(host, entry) {
34484
+ host.supersededResources = [...(Array.isArray(host.supersededResources) ? host.supersededResources : []).filter((row) => !isSupersededResourceRecord(row) || row.state.physicalId !== entry.state.physicalId || row.state.resourceType !== entry.state.resourceType), entry];
34485
+ }
34486
+ function canRecordSuperseded(record, deleteContext) {
34487
+ if (deleteContext.noEchoDeleteValues !== void 0) return false;
34488
+ if (deleteContext.inlinePolicyClaimed !== void 0) return false;
34489
+ if (Array.isArray(record.noEchoLeaves) && record.noEchoLeaves.length > 0) return false;
34490
+ return !INLINE_POLICY_TYPES.has(record.resourceType);
34491
+ }
34492
+ const INLINE_POLICY_TYPES = /* @__PURE__ */ new Set([
34493
+ "AWS::IAM::Policy",
34494
+ "AWS::IAM::RolePolicy",
34495
+ "AWS::IAM::UserPolicy",
34496
+ "AWS::IAM::GroupPolicy"
34497
+ ]);
34498
+ function removeSuperseded(host, entry) {
34499
+ if (!Array.isArray(host.supersededResources)) return;
34500
+ const remaining = host.supersededResources.filter((row) => row !== entry);
34501
+ if (remaining.length === 0) delete host.supersededResources;
34502
+ else host.supersededResources = remaining;
34503
+ }
34504
+ function supersededAfterRollback(base, pending) {
34505
+ const added = Array.isArray(pending.supersededResources) ? pending.supersededResources : [];
34506
+ if (added.length === 0) return {};
34507
+ return { supersededResources: [...Array.isArray(base.supersededResources) ? base.supersededResources : [], ...added] };
34508
+ }
34509
+ const SUPERSEDED_KEPT_REMEDY = "cdkd keeps it in state: the next `cdkd deploy` of this stack retries the delete, and `cdkd destroy` deletes it";
34510
+ function withoutSuperseded(state) {
34511
+ const { supersededResources: _dropped, ...rest } = state;
34512
+ return rest;
34513
+ }
34514
+ async function deleteSupersededEntry(entry, input) {
34515
+ const record = entry.state;
34516
+ let result;
34517
+ try {
34518
+ const send = () => input.provider.delete(entry.logicalId, record.physicalId, record.resourceType, record.properties, {
34519
+ expectedRegion: input.region,
34520
+ ...entry.forceDataDelete === true && { forceDataDelete: true },
34521
+ ...entry.finalSnapshotIdentifier !== void 0 && { finalSnapshotIdentifier: entry.finalSnapshotIdentifier },
34522
+ deletionPolicy: replacementDeletePolicy(entry.updateReplacePolicy),
34523
+ ...entry.skipFinalSnapshot === true && { skipFinalSnapshot: true },
34524
+ ...input.removeProtection === true && { removeProtection: true },
34525
+ ...input.stackDestroy === true && { stackDestroy: true },
34526
+ recordedAttributes: record.attributes,
34527
+ recordedNoEchoLeaves: record.noEchoLeaves,
34528
+ maskSecrets: input.maskSecrets
34529
+ });
34530
+ result = input.once === true ? await send() : await retryWhileInUse(send, input.stop);
34531
+ } catch (error) {
34532
+ return {
34533
+ kind: "failed",
34534
+ error
34535
+ };
34536
+ }
34537
+ reportDeleteGuards(result, {
34538
+ physicalId: record.physicalId,
34539
+ resourceType: record.resourceType,
34540
+ provisionedBy: record.provisionedBy
34541
+ });
34542
+ const reason = deleteSkipReason(result);
34543
+ return reason === void 0 ? { kind: "deleted" } : {
34544
+ kind: "notDeleted",
34545
+ reason
34546
+ };
34547
+ }
34548
+ const supersededInUseRetry = {
34549
+ attempts: 6,
34550
+ delayMs: 1e4
34551
+ };
34552
+ const IN_USE_ERROR_NAMES = /* @__PURE__ */ new Set([
34553
+ "ResourceInUseException",
34554
+ "ResourceInUse",
34555
+ "DependencyViolation"
34556
+ ]);
34557
+ const IN_USE_CONFLICT = /\bare using it\b/;
34558
+ function isInUseRefusal(error) {
34559
+ for (let current = error, depth = 0; current !== void 0 && depth < 8; depth++) {
34560
+ if (typeof current !== "object" || current === null) return false;
34561
+ const { name, message } = current;
34562
+ if (typeof name === "string" && IN_USE_ERROR_NAMES.has(name)) return true;
34563
+ if (name === "ConflictException" && typeof message === "string" && IN_USE_CONFLICT.test(message)) return true;
34564
+ current = current.cause;
34565
+ }
34566
+ return false;
34567
+ }
34568
+ async function retryWhileInUse(send, stop) {
34569
+ for (let attempt = 1;; attempt++) try {
34570
+ return await send();
34571
+ } catch (error) {
34572
+ if (attempt >= supersededInUseRetry.attempts || stop() || !isInUseRefusal(error)) throw error;
34573
+ await new Promise((resolve) => setTimeout(resolve, supersededInUseRetry.delayMs));
34574
+ if (stop()) throw error;
34575
+ }
34576
+ }
34577
+ function holdsSupersededResources(record) {
34578
+ const rows = record.supersededResources;
34579
+ return rows !== void 0 && (!Array.isArray(rows) || rows.length > 0);
34580
+ }
34581
+
34199
34582
  //#endregion
34200
34583
  //#region src/utils/colors.ts
34201
34584
  const codes = {
@@ -34222,6 +34605,16 @@ function withReplayDeletePrinting(scope, fn) {
34222
34605
  const deployBag = scope.ctx.logOnlyNeedlesFor?.(scope.op.logicalId);
34223
34606
  return withPrintingSecrets(scope.secrets, () => deployBag === void 0 ? fn() : withPrintingSecrets(deployBag, fn));
34224
34607
  }
34608
+ function noteRolledBackCreate(scope, op, record) {
34609
+ if (op.changeType !== "CREATE") return;
34610
+ const create = {
34611
+ logicalId: op.logicalId,
34612
+ record,
34613
+ ...op.nameGeneration !== void 0 && { nameGeneration: op.nameGeneration }
34614
+ };
34615
+ scope.result.rolledBackCreates.push(create);
34616
+ scope.onRolledBackCreate?.(create);
34617
+ }
34225
34618
 
34226
34619
  //#endregion
34227
34620
  //#region src/deployment/rollback-executor/replaced-survivor.ts
@@ -34271,24 +34664,6 @@ async function readSurvivor(s, oldType) {
34271
34664
  }
34272
34665
  }
34273
34666
 
34274
- //#endregion
34275
- //#region src/deployment/delete-guard-scope.ts
34276
- const storage$1 = new AsyncLocalStorage();
34277
- function collectDeleteGuards(sink, fn) {
34278
- return storage$1.run(sink, fn);
34279
- }
34280
- function reportDeleteGuards(result, target) {
34281
- const sink = storage$1.getStore();
34282
- if (!sink) return;
34283
- for (const guard of deleteIndeterminateGuards(result)) sink.push({
34284
- guard: guard.guard,
34285
- reason: guard.reason,
34286
- physicalId: target.physicalId,
34287
- resourceType: target.resourceType,
34288
- ...target.provisionedBy && { provisionedBy: target.provisionedBy }
34289
- });
34290
- }
34291
-
34292
34667
  //#endregion
34293
34668
  //#region src/deployment/stack-records-scope.ts
34294
34669
  async function awaitInFlightSibling(view, self, sibling) {
@@ -34333,11 +34708,92 @@ function replayStackRecordsView(records, orphanLogicalIds = /* @__PURE__ */ new
34333
34708
  };
34334
34709
  }
34335
34710
 
34711
+ //#endregion
34712
+ //#region src/deployment/deploy-engine/name-collision.ts
34713
+ function replacementNameOrigin(logicalId, physicalId) {
34714
+ if (looksLikeCdkdGeneratedName(physicalId, logicalId, getCurrentStackName(), getCurrentStackInstanceId())) return {
34715
+ descriptor: `The physical name (${physicalId}) was GENERATED by cdkd from the construct's logical id rather than declared in your template, and that derivation has no random component — so the new resource asks for exactly the name the existing one still holds`,
34716
+ remedy: "Either give the resource an explicit physical name in your CDK code, or rename the CONSTRUCT (its id feeds the generated name — note that this replaces the resource rather than renaming it in place)"
34717
+ };
34718
+ return {
34719
+ descriptor: `The resource has a user-supplied physical name (${physicalId})`,
34720
+ remedy: "Either rename the resource in your CDK code (a fresh name lets the safe create-first order proceed)"
34721
+ };
34722
+ }
34723
+ function generatedReplacementHolderAdvice(input) {
34724
+ if (input.change?.generated !== true) return "";
34725
+ const name = displaySafe(input.mask(input.change.desiredName), { asciiOnly: true });
34726
+ const old = displaySafe(input.mask(input.oldPhysicalId), { asciiOnly: true });
34727
+ const lead = ` The colliding name ${isInertUnquoted(name) ? name : "the generated name"} is the one this replacement generates for its next name generation, so its holder is most likely the new resource an interrupted earlier attempt of this replacement created. If it is, `;
34728
+ const tail = `, or delete it and re-run the deploy.`;
34729
+ if (input.stackName.includes("~")) return lead + `adopt it through the top-level stack with \`cdkd import\` (then delete ${old} by hand)` + tail;
34730
+ const adopt = pasteableCommand("cdkd import", [{
34731
+ value: input.stackName,
34732
+ hole: "stack"
34733
+ }, {
34734
+ flag: "--resource",
34735
+ value: `${input.logicalId}=${input.change.desiredName}`,
34736
+ hole: "logicalId=physicalId"
34737
+ }]);
34738
+ const command = input.mask(adopt.command) === adopt.command ? adopt.command : void 0;
34739
+ return lead + (command === void 0 ? `adopt it with \`cdkd import\`` : `adopt it with \`${command}\` (using its physical id where the type records another)`) + ` and then delete ${old} by hand` + tail;
34740
+ }
34741
+ function orphanedNameCollisionAdvice(providerRegistry, changeType, logicalId, error) {
34742
+ if (changeType !== "CREATE") return void 0;
34743
+ if (!(error instanceof ProvisioningError)) return void 0;
34744
+ const physicalId = error.physicalId;
34745
+ if (!physicalId) return void 0;
34746
+ const replayed = isReplayedNameCollisionFrom(error, logicalId, (link) => isAuxiliaryMarkOf(link, RETRY_AUXILIARY_OWNER));
34747
+ if (!replayed && !isNameCollisionErrorFrom(error, logicalId)) return void 0;
34748
+ const stackName = getCurrentStackName();
34749
+ if (!looksLikeCdkdGeneratedName(physicalId, logicalId, stackName, getCurrentStackInstanceId())) return;
34750
+ if (!stackName) return void 0;
34751
+ const safeId = displaySafe(physicalId, { asciiOnly: true });
34752
+ const safeStack = displaySafe(stackName, { asciiOnly: true });
34753
+ const safeLogicalId = displaySafe(logicalId, { asciiOnly: true });
34754
+ const idShown = isInertUnquoted(safeId);
34755
+ const shownId = idShown ? safeId : "a name that cannot be shown safely here";
34756
+ const shownLogicalId = isInertUnquoted(safeLogicalId) ? safeLogicalId : "A resource whose logical id cannot be shown safely here";
34757
+ const diagnosis = replayed ? `${shownLogicalId}: the name AWS reports as taken (${shownId}) is most likely held by a resource THIS create made. An earlier attempt of it ended without a clear verdict (a server error, a dropped connection or a timeout, or a failure after the create call itself may have succeeded), and the retry then found the name taken. A dropped connection can also happen before the request reached AWS, so the holder may be another resource: confirm it is yours before deleting or importing it. cdkd records a resource only once its create succeeds, so this one is in no state file: no rollback or cdkd destroy will remove it, and re-running collides with it again.` : `${shownLogicalId}: the name AWS reports as taken (${shownId}) is one cdkd DERIVED from the logical id, and that derivation has no random component — so this is most likely a resource an earlier cdkd run left behind. A rollback leaves a resource carrying DeletionPolicy: Retain in AWS and drops it from state, as CloudFormation does; what differs is the name. CloudFormation would generate a fresh one for an unnamed resource and redeploy clean, whereas cdkd asks again for the name the orphan still holds — so re-running does not clear this.`;
34758
+ const deleteArm = `If it is not a resource you want to keep, delete ${idShown ? safeId : "it"} in AWS — after confirming it holds nothing you need${replayed ? "" : ", since Retain is what kept it"} — and re-deploy.`;
34759
+ let canImport;
34760
+ try {
34761
+ canImport = typeof providerRegistry.getProvider(error.resourceType).import === "function";
34762
+ } catch {
34763
+ canImport = false;
34764
+ }
34765
+ const commandNamesTheRightResource = safeId === physicalId && safeStack === stackName && safeLogicalId === logicalId;
34766
+ const importableTarget = !stackName.includes("~");
34767
+ if (!canImport || !commandNamesTheRightResource || !importableTarget) return `${diagnosis} ${!canImport ? `cdkd cannot adopt ${displaySafe(error.resourceType, { asciiOnly: true })} back into state (its provider implements no import)` : !importableTarget ? `this is a nested-stack child, whose stack name cdkd import cannot resolve` : `cdkd cannot render an import command that provably names this resource`}, so the way forward is to delete it. ${deleteArm}`;
34768
+ const adopt = pasteableCommand("cdkd import", [{
34769
+ value: stackName,
34770
+ hole: "stack"
34771
+ }, {
34772
+ flag: "--resource",
34773
+ value: `${logicalId}=${physicalId}`,
34774
+ hole: "logicalId=physicalId"
34775
+ }]);
34776
+ return `${diagnosis} To recover, adopt it back into state instead of re-creating it, with the command below (a selective import merges into existing state and needs no --force while the resource is absent from it). CONFIRM IT IS YOURS FIRST — a name cdkd derives is predictable, so for a globally-namespaced type it can belong to another account, and the same stack deployed in another region derives the same name. ${deleteArm}${adopt.withheld.length === 0 ? "" : " The command below prints a quoted hole in place of a value cdkd will not name on a command line; replace it whole, quotes included, with your stack name or '<logicalId>=<name>', shell-quoted."}\nAdopt with: ${adopt.command}`;
34777
+ }
34778
+ function isReplacementNameRefusal(error, logicalId) {
34779
+ let current = error;
34780
+ for (let depth = 0; depth < 10 && current != null; depth++) {
34781
+ if (typeof current !== "object") return false;
34782
+ const linkId = current.logicalId;
34783
+ if (typeof linkId === "string" && linkId !== logicalId) return false;
34784
+ if (current instanceof CdkdError && current.code === "NAMED_REPLACEMENT_COLLISION") return true;
34785
+ current = current.cause;
34786
+ }
34787
+ return false;
34788
+ }
34789
+
34336
34790
  //#endregion
34337
34791
  //#region src/deployment/deploy-engine/replacement.ts
34338
34792
  var ReplacementRunState = class {
34339
34793
  replacedDeleteSkips = /* @__PURE__ */ new Map();
34340
34794
  deferredReplacedDeletes = void 0;
34795
+ supersededHost = void 0;
34796
+ supersededEntries = /* @__PURE__ */ new Map();
34341
34797
  retainedOldOnReplacement = /* @__PURE__ */ new Set();
34342
34798
  replacedOldMaySurvive = /* @__PURE__ */ new Map();
34343
34799
  recreatedUnderSameId = /* @__PURE__ */ new Set();
@@ -34346,6 +34802,7 @@ var ReplacementRunState = class {
34346
34802
  updateWasReplaced = /* @__PURE__ */ new Map();
34347
34803
  inPlaceCreateOnlyPaths = /* @__PURE__ */ new Map();
34348
34804
  oldDeletedBeforeCreate = /* @__PURE__ */ new Set();
34805
+ attemptedNameGeneration = /* @__PURE__ */ new Map();
34349
34806
  };
34350
34807
  function replacementDeleteContext(deps, updateReplacePolicy) {
34351
34808
  return {
@@ -34391,15 +34848,19 @@ async function replaceDeleteFirstAndRecreate(run, deps, logicalId, resourceType,
34391
34848
  if (replaceSkipReason !== void 0) throw new Error(deleteSkippedMessage(logicalId, currentResource.physicalId, replaceSkipReason, "during the --replace delete-first fallback"));
34392
34849
  deps.logger.info(safeMsg` ${green("✓")} Old resource deleted`);
34393
34850
  run.oldDeletedBeforeCreate.add(logicalId);
34851
+ await oldDeleteProvider.waitForNameReleased?.(logicalId, currentResource.physicalId, oldResourceType, {
34852
+ isInterrupted: () => deps.userInterrupted(),
34853
+ maskSecrets: (text) => maskSecretsInText(text, secrets)
34854
+ });
34394
34855
  deps.logger.info(safeMsg` Re-creating ${logicalId}...`);
34395
34856
  try {
34396
- return await withRetry(() => deps.withRetry(() => withCurrentResourceSecrets(secrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, createContext)), logicalId, void 0, void 0, replaceProvider), logicalId, {
34857
+ return await withRetry(() => deps.withRetry(() => withCurrentResourceSecrets(secrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, createContext)), logicalId, void 0, void 0, replaceProvider, true), logicalId, {
34397
34858
  maxRetries: 8,
34398
34859
  initialDelayMs: 2e3,
34399
34860
  maxDelayMs: 1e4,
34400
34861
  logger: deps.maskingRetryLoggerFor(secrets),
34401
- isInterrupted: () => deps.interrupted(),
34402
- onInterrupted: () => new InterruptedError(deps.interruptCause() ?? "user"),
34862
+ isInterrupted: () => deps.userInterrupted(),
34863
+ onInterrupted: () => new InterruptedError("user"),
34403
34864
  isRetryable: isRecreateRetryableError
34404
34865
  });
34405
34866
  } catch (recreateError) {
@@ -34433,6 +34894,14 @@ async function checkedReplacementNameChange(deps, input) {
34433
34894
  };
34434
34895
  const adopts = replacementCreateAdoptsName(resourceType, input.createdVia);
34435
34896
  const typeChanged = input.oldResourceType !== resourceType;
34897
+ const generatedMove = replacementGeneratedNameMoves({
34898
+ oldResourceType: input.oldResourceType,
34899
+ newResourceType: resourceType,
34900
+ createdVia: input.createdVia,
34901
+ desiredProperties: input.desiredProperties,
34902
+ physicalId: currentResource.physicalId,
34903
+ logicalId
34904
+ });
34436
34905
  const change = replacementRequestsDifferentName(question) ?? (adopts || replacementOrderIsCaseSensitive(resourceType) ? replacementRequestsDifferentName({
34437
34906
  ...question,
34438
34907
  caseSensitive: true
@@ -34443,8 +34912,9 @@ async function checkedReplacementNameChange(deps, input) {
34443
34912
  desiredProperties: input.desiredProperties,
34444
34913
  physicalId: currentResource.physicalId,
34445
34914
  logicalId
34446
- }) ?? (adopts && typeChanged ? typeChangeNameQuestion(resourceType, input) : void 0);
34915
+ }) ?? (adopts && typeChanged ? typeChangeNameQuestion(resourceType, input) : void 0) ?? generatedMove;
34447
34916
  if (change === void 0) return void 0;
34917
+ if (change === generatedMove && deps.generatedNameGuarded(logicalId)) return change;
34448
34918
  const probe = replacementNameProbe({
34449
34919
  resourceType,
34450
34920
  createdVia: input.createdVia,
@@ -34484,11 +34954,23 @@ async function createFirstThenDeleteOld(run, deps, input) {
34484
34954
  const maskName = maskRewrittenSentName(resourceType, input.createProps, logicalId, (text) => maskSecretsInText(text, secrets));
34485
34955
  let createResult;
34486
34956
  try {
34487
- createResult = await deps.withRetry(() => withCurrentResourceSecrets(secrets, () => input.createProvider.create(logicalId, resourceType, input.createProps, { maskSecrets: createSecretMasker(secrets) })), logicalId, void 0, void 0, input.createProvider);
34957
+ createResult = await deps.guardedReplacementCreate({
34958
+ logicalId,
34959
+ resourceType,
34960
+ stackName: input.stackName,
34961
+ createdVia: input.createdVia,
34962
+ resolvedProps: input.resolvedProps
34963
+ }, () => deps.withRetry(() => withCurrentResourceSecrets(secrets, () => input.createProvider.create(logicalId, resourceType, input.createProps, { maskSecrets: createSecretMasker(secrets) })), logicalId, void 0, void 0, input.createProvider));
34488
34964
  } catch (createError) {
34489
34965
  if (!isNameCollisionErrorFrom(createError, logicalId)) throw createError;
34490
34966
  const createMsg = displayAwsMessage(maskName(describeAwsFailure(createError).detail));
34491
- throw markNonRetryable(new CdkdError(maskName(`${displaySafe(logicalId)} (${displaySafe(resourceType)}) requires replacement (${input.trigger}), and cdkd created the new resource first because its name differs, but the create collided: ${createMsg}. If the collision is on the requested name: ${renderReplacementNameChange(input.change, input.createProps)}. Nothing was deleted` + (retainOld ? ` (UpdateReplacePolicy: Retain keeps the old resource in place)` : "") + ". Choose a name no other resource holds, or delete the resource holding it if it is yours."), "NAMED_REPLACEMENT_COLLISION", createError instanceof Error ? createError : void 0));
34967
+ throw markNonRetryable(new CdkdError(maskName(`${displaySafe(logicalId)} (${displaySafe(resourceType)}) requires replacement (${input.trigger}), and cdkd created the new resource first because its name differs, but the create collided: ${createMsg}. If the collision is on the requested name: ${renderReplacementNameChange(input.change, input.createProps)}. Nothing was deleted` + (retainOld ? ` (UpdateReplacePolicy: Retain keeps the old resource in place)` : "") + ". Choose a name no other resource holds, or delete the resource holding it if it is yours." + generatedReplacementHolderAdvice({
34968
+ stackName: input.stackName,
34969
+ logicalId,
34970
+ change: input.change,
34971
+ oldPhysicalId: currentResource.physicalId,
34972
+ mask: (text) => maskName(maskSecretsInText(text, unionOfSecretBags([secrets, printingSecretsFor(deps.secretsRun(), logicalId)])))
34973
+ })), "NAMED_REPLACEMENT_COLLISION", createError instanceof Error ? createError : void 0));
34492
34974
  }
34493
34975
  if (input.equalIdIsSameResource && createResult.physicalId === currentResource.physicalId) throw markNonRetryable(new CdkdError(maskName(`${displaySafe(logicalId)} (${displaySafe(resourceType)}) requires replacement (${input.trigger}) under a new name, but the create returned the resource being replaced (${displaySafe(currentResource.physicalId)}) instead of a new one, so cdkd cannot tell which name it holds. Nothing was deleted. Delete that resource by hand if it is yours, then re-run the deploy.`), "NAMED_REPLACEMENT_IDEMPOTENT_CREATE"));
34494
34976
  if (retainOld) return createResult;
@@ -34501,7 +34983,7 @@ async function deleteReplacedAfterCreate(run, deps, logicalId, oldResourceType,
34501
34983
  let deleteFailed = false;
34502
34984
  const inlinePolicyClaimed = isStandaloneInlinePolicyType(oldResourceType) ? deps.inlinePolicyClaimedFor(oldResourceType, logicalId, deps.deployStateResources()) : void 0;
34503
34985
  try {
34504
- deleteResult = await withPrintingSecrets(secrets, () => deleteProvider.delete(logicalId, currentResource.physicalId, oldResourceType, deleteProperties, {
34986
+ const sendDelete = () => deleteProvider.delete(logicalId, currentResource.physicalId, oldResourceType, deleteProperties, {
34505
34987
  expectedRegion: deps.stackRegion,
34506
34988
  forceDataDelete: deps.options.forceStatefulRecreation === true,
34507
34989
  ...finalSnapshotIdentifier !== void 0 && { finalSnapshotIdentifier },
@@ -34511,7 +34993,8 @@ async function deleteReplacedAfterCreate(run, deps, logicalId, oldResourceType,
34511
34993
  ...noEchoDeleteValues !== void 0 && { noEchoDeleteValues },
34512
34994
  ...inlinePolicyClaimed && { inlinePolicyClaimed },
34513
34995
  maskSecrets: createUnionSecretMasker([secrets, secretNameBagFor(deps.secretsRun(), logicalId)])
34514
- }));
34996
+ });
34997
+ deleteResult = await withPrintingSecrets(secrets, () => isRetry ? retryWhileInUse(sendDelete, () => deps.interrupted()) : sendDelete());
34515
34998
  } catch (deleteError) {
34516
34999
  const deleteMsg = maskSecretsInText(describeAwsFailure(deleteError).detail, secrets);
34517
35000
  deleteFailed = true;
@@ -34519,6 +35002,23 @@ async function deleteReplacedAfterCreate(run, deps, logicalId, oldResourceType,
34519
35002
  const deferred = run.deferredReplacedDeletes;
34520
35003
  if (!isRetry && deferred !== void 0) {
34521
35004
  deps.logger.info(safeMsg` Could not delete old ${logicalId} (${currentResource.physicalId}) yet: ${deleteMsg}. Retrying after the rest of the deploy.`);
35005
+ const host = run.supersededHost;
35006
+ if (host !== void 0 && canRecordSuperseded(currentResource, {
35007
+ noEchoDeleteValues,
35008
+ inlinePolicyClaimed
35009
+ }) && !Object.entries(deps.deployStateResources()).some(([id, record]) => id !== logicalId && record?.physicalId === currentResource.physicalId)) {
35010
+ const entry = {
35011
+ logicalId,
35012
+ supersededAt: Date.now(),
35013
+ state: currentResource,
35014
+ ...updateReplacePolicy !== void 0 && { updateReplacePolicy },
35015
+ ...finalSnapshotIdentifier !== void 0 && { finalSnapshotIdentifier },
35016
+ ...deps.options.forceStatefulRecreation === true && { forceDataDelete: true },
35017
+ ...deps.options.skipFinalSnapshot === true && { skipFinalSnapshot: true }
35018
+ };
35019
+ addSuperseded(host, entry);
35020
+ run.supersededEntries.set(logicalId, entry);
35021
+ }
34522
35022
  deferred.set(logicalId, {
34523
35023
  physicalId: currentResource.physicalId,
34524
35024
  resourceType: oldResourceType,
@@ -34528,7 +35028,13 @@ async function deleteReplacedAfterCreate(run, deps, logicalId, oldResourceType,
34528
35028
  });
34529
35029
  return;
34530
35030
  }
34531
- deps.logger.warn(safeMsg` ⚠ Failed to delete old resource ${logicalId} (${currentResource.physicalId}): ${deleteMsg}`);
35031
+ const kept = isRetry && run.supersededEntries.has(logicalId);
35032
+ deps.logger.warn(kept ? safeMsg` ⚠ Failed to delete old resource ${logicalId} (${currentResource.physicalId}): ${deleteMsg}. ${SUPERSEDED_KEPT_REMEDY}.` : safeMsg` ⚠ Failed to delete old resource ${logicalId} (${currentResource.physicalId}): ${deleteMsg}`);
35033
+ }
35034
+ const recorded = isRetry ? run.supersededEntries.get(logicalId) : void 0;
35035
+ if (recorded !== void 0 && !deleteFailed && run.supersededHost !== void 0) {
35036
+ removeSuperseded(run.supersededHost, recorded);
35037
+ run.supersededEntries.delete(logicalId);
34532
35038
  }
34533
35039
  reportDeleteGuards(deleteResult, {
34534
35040
  physicalId: currentResource.physicalId,
@@ -34601,8 +35107,9 @@ async function retryDeferredReplacedDeletes(run, deps, stackName, counts) {
34601
35107
  function warnUnretriedReplacedDeletes(run, deps, why) {
34602
35108
  const deferred = run.deferredReplacedDeletes;
34603
35109
  run.deferredReplacedDeletes = void 0;
34604
- const note = why === "failed" ? "not retried: the deploy failed first" : "not retried: the deploy was interrupted";
34605
- for (const [logicalId, entry] of deferred ?? []) withPrintingSecrets(secretNameBagFor(deps.secretsRun(), logicalId), () => deps.logger.warn(safeMsg` ⚠ Failed to delete old resource ${logicalId} (${entry.physicalId}): ${entry.failureMessage} (${note})`));
35110
+ const cause = why === "failed" ? "the deploy failed first" : "the deploy was interrupted";
35111
+ const noteFor = (logicalId) => run.supersededEntries.has(logicalId) ? `not retried: ${cause}; cdkd keeps it in state, and the next deploy retries the delete` : `not retried: ${cause}; it is no longer tracked in state, so delete it manually`;
35112
+ for (const [logicalId, entry] of deferred ?? []) withPrintingSecrets(secretNameBagFor(deps.secretsRun(), logicalId), () => deps.logger.warn(safeMsg` ⚠ Failed to delete old resource ${logicalId} (${entry.physicalId}): ${entry.failureMessage} (${noteFor(logicalId)})`));
34606
35113
  }
34607
35114
 
34608
35115
  //#endregion
@@ -35495,6 +36002,136 @@ function recaptureMaskedBaseline(args) {
35495
36002
  return changed ? result : void 0;
35496
36003
  }
35497
36004
 
36005
+ //#endregion
36006
+ //#region src/state/name-generation.ts
36007
+ var MalformedNameGenerationError = class extends Error {
36008
+ constructor(where, reason = "malformed") {
36009
+ super(`The state record holds a name generation for ${displayIdent(where)} that is ` + (reason === "exhausted" ? "too large to derive the next one from (the next is not a safe integer). " : "not a non-negative integer. ") + "cdkd does not guess which name the resource was given, since the next replacement's name derives from it; restore the field from an earlier version of state.json.");
36010
+ this.name = "MalformedNameGenerationError";
36011
+ }
36012
+ };
36013
+ function generationAfter(generation, logicalId) {
36014
+ const next = generation + 1;
36015
+ if (!isNameGeneration(next)) throw new MalformedNameGenerationError(logicalId, "exhausted");
36016
+ return next;
36017
+ }
36018
+ function nameGenerationOf(record, logicalId) {
36019
+ const value = record.nameGeneration;
36020
+ if (value === void 0) return 0;
36021
+ if (!isNameGeneration(value)) throw new MalformedNameGenerationError(logicalId);
36022
+ return value;
36023
+ }
36024
+ function nameGenerationHighWaterOf(record, logicalId) {
36025
+ const generation = nameGenerationOf(record, logicalId);
36026
+ const high = record.nameGenerationHigh;
36027
+ if (high === void 0) return generation;
36028
+ if (!isNameGeneration(high)) throw new MalformedNameGenerationError(logicalId);
36029
+ return Math.max(generation, high);
36030
+ }
36031
+ function retiredNameGenerationsOf(state) {
36032
+ const raw = state.retiredNameGenerations;
36033
+ const out = /* @__PURE__ */ new Map();
36034
+ if (raw === void 0) return out;
36035
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) throw new MalformedNameGenerationError("retiredNameGenerations");
36036
+ for (const [logicalId, value] of Object.entries(raw)) {
36037
+ if (!isNameGeneration(value)) throw new MalformedNameGenerationError(logicalId);
36038
+ out.set(logicalId, value);
36039
+ }
36040
+ return out;
36041
+ }
36042
+ function nameGenerationsOf(state) {
36043
+ const out = /* @__PURE__ */ new Map();
36044
+ for (const [logicalId, retired] of retiredNameGenerationsOf(state)) out.set(logicalId, generationAfter(retired, logicalId));
36045
+ for (const [logicalId, record] of Object.entries(state.resources ?? {})) {
36046
+ if (record === null || typeof record !== "object") continue;
36047
+ out.set(logicalId, nameGenerationOf(record, logicalId));
36048
+ }
36049
+ return out;
36050
+ }
36051
+ function nextNameGeneration(record, logicalId, stackInstanceId) {
36052
+ let next = generationAfter(nameGenerationHighWaterOf(record, logicalId), logicalId);
36053
+ const physicalId = typeof record.physicalId === "string" ? record.physicalId.toLowerCase() : "";
36054
+ while (physicalId.includes(stackInstanceNameSuffix(stackInstanceId, logicalId, next))) next = generationAfter(next, logicalId);
36055
+ return next;
36056
+ }
36057
+ function replacementNameGeneration(record, logicalId, stackInstanceId, keepsName) {
36058
+ if (stackInstanceId === void 0 || keepsName) return {
36059
+ generation: void 0,
36060
+ fields: nameGenerationCarriedFrom(record)
36061
+ };
36062
+ const generation = nextNameGeneration(record, logicalId, stackInstanceId);
36063
+ return {
36064
+ generation,
36065
+ fields: nameGenerationField(generation)
36066
+ };
36067
+ }
36068
+ function nameGenerationField(generation) {
36069
+ return generation === 0 ? {} : { nameGeneration: generation };
36070
+ }
36071
+ function nameGenerationCarriedFrom(previous) {
36072
+ return {
36073
+ ...previous?.nameGeneration !== void 0 && { nameGeneration: previous.nameGeneration },
36074
+ ...previous?.nameGenerationHigh !== void 0 && { nameGenerationHigh: previous.nameGenerationHigh }
36075
+ };
36076
+ }
36077
+ function withNameGenerationReached(record, logicalId, reached) {
36078
+ if (reached === void 0 || !isNameGeneration(reached)) return record;
36079
+ if (reached <= nameGenerationHighWaterOf(record, logicalId)) return record;
36080
+ return {
36081
+ ...record,
36082
+ nameGenerationHigh: reached
36083
+ };
36084
+ }
36085
+ function retiredNameGenerationsAfter(state, leaving) {
36086
+ if (state.stackInstanceId === void 0) return {};
36087
+ const retired = new Map(retiredNameGenerationsOf(state));
36088
+ let changed = false;
36089
+ for (const { logicalId, record } of leaving) {
36090
+ const reached = nameGenerationHighWaterOf(record, logicalId);
36091
+ const before = retired.get(logicalId);
36092
+ if (before !== void 0 && before >= reached) continue;
36093
+ retired.set(logicalId, reached);
36094
+ changed = true;
36095
+ }
36096
+ if (!changed) return state.retiredNameGenerations === void 0 ? {} : { retiredNameGenerations: state.retiredNameGenerations };
36097
+ return { retiredNameGenerations: Object.fromEntries(retired) };
36098
+ }
36099
+ function nameScopeOf(stackName, stackInstanceId, state) {
36100
+ return {
36101
+ stackName,
36102
+ stackInstanceId,
36103
+ nameGenerations: stackInstanceId === void 0 ? void 0 : nameGenerationsOf(state ?? { resources: {} })
36104
+ };
36105
+ }
36106
+ function rolledBackCreateReached(create) {
36107
+ let reached = 0;
36108
+ for (const value of [
36109
+ create.record?.nameGeneration,
36110
+ create.record?.nameGenerationHigh,
36111
+ create.nameGeneration
36112
+ ]) if (isNameGeneration(value)) reached = Math.max(reached, value);
36113
+ return reached;
36114
+ }
36115
+ function retiredAfterRollback(state, orphaned, rolledBackCreates = []) {
36116
+ return retiredNameGenerationsAfter(state, [...orphaned.map((o) => ({
36117
+ logicalId: o.logicalId,
36118
+ record: o.state
36119
+ })), ...rolledBackCreates.map((c) => ({
36120
+ logicalId: c.logicalId,
36121
+ record: { nameGenerationHigh: rolledBackCreateReached(c) }
36122
+ }))]);
36123
+ }
36124
+ function retiredNameGenerationsLeaving(state, remaining) {
36125
+ try {
36126
+ return retiredNameGenerationsAfter(state, Object.entries(state.resources ?? {}).filter(([logicalId, record]) => !Object.hasOwn(remaining, logicalId) && record !== null && typeof record === "object").map(([logicalId, record]) => ({
36127
+ logicalId,
36128
+ record
36129
+ })));
36130
+ } catch {
36131
+ return state.retiredNameGenerations === void 0 ? {} : { retiredNameGenerations: state.retiredNameGenerations };
36132
+ }
36133
+ }
36134
+
35498
36135
  //#endregion
35499
36136
  //#region src/deployment/update-outcome.ts
35500
36137
  function updatePartialReason(result) {
@@ -36182,6 +36819,30 @@ function planRollback(operations, stateResources, orphanLogicalIds = /* @__PURE_
36182
36819
  };
36183
36820
  });
36184
36821
  }
36822
+ function renamedReverseReplacement(op, stateResources, orphanLogicalIds, pendingNewIds = /* @__PURE__ */ new Set()) {
36823
+ if (op.changeType !== "UPDATE") return false;
36824
+ if (op.oldDeletedBeforeCreate === true || op.oldResourceMaySurvive !== void 0) return false;
36825
+ const current = Object.hasOwn(stateResources, op.logicalId) ? stateResources[op.logicalId] : void 0;
36826
+ const oldId = op.previousState?.physicalId;
36827
+ if (typeof oldId !== "string" || typeof current?.physicalId !== "string") return false;
36828
+ if (current.physicalId === oldId) return false;
36829
+ if (pendingNewIds.has(oldId)) return false;
36830
+ const oldType = op.previousState?.resourceType ?? op.resourceType;
36831
+ for (const [logicalId, other] of Object.entries(stateResources)) {
36832
+ if (logicalId === op.logicalId || typeof other?.physicalId !== "string") continue;
36833
+ if (other.physicalId === oldId || other.resourceType === oldType && samePhysicalId(oldType, other.physicalId, oldId)) return false;
36834
+ }
36835
+ return classifyRollbackOp(op, stateResources, orphanLogicalIds) === "reverse-replacement";
36836
+ }
36837
+ function revertReferences(op, stateResources) {
36838
+ const current = Object.hasOwn(stateResources, op.logicalId) ? stateResources[op.logicalId] : void 0;
36839
+ const refs = /* @__PURE__ */ new Set();
36840
+ for (const record of [op.previousState, current]) {
36841
+ if (!Array.isArray(record?.dependencies)) continue;
36842
+ for (const id of record.dependencies) if (typeof id === "string") refs.add(id);
36843
+ }
36844
+ return refs;
36845
+ }
36185
36846
  function partitionOps(operations) {
36186
36847
  const createOps = [];
36187
36848
  const otherOps = [];
@@ -36645,6 +37306,7 @@ async function replayOrphanFlag(s) {
36645
37306
  const orphanFlagProvisionedBy = effectiveProvisionedBy(record, op.provisionedBy);
36646
37307
  s.createRollbackRoute = orphanFlagProvisionedBy;
36647
37308
  delete stateResources[op.logicalId];
37309
+ if (record) noteRolledBackCreate(s, op, record);
36648
37310
  await noteRetainedResource(op.resourceType, op.logicalId);
36649
37311
  logger.info(` Rollback: Orphaning created resource ${safe(op.logicalId)} (--orphan)`);
36650
37312
  await afterOp?.(op.logicalId);
@@ -36677,6 +37339,7 @@ async function replayOrphanRetain(s) {
36677
37339
  onOrphan?.(orphaned);
36678
37340
  }
36679
37341
  delete stateResources[op.logicalId];
37342
+ noteRolledBackCreate(s, op, record);
36680
37343
  await noteRetainedResource(op.resourceType, op.logicalId);
36681
37344
  logger.info(` Rollback: Leaving ${safe(op.logicalId)} (${safe(op.resourceType)}) in AWS (DeletionPolicy: Retain) — removed from state`);
36682
37345
  await afterOp?.(op.logicalId);
@@ -36738,7 +37401,9 @@ async function replayDelete(s) {
36738
37401
  provisionedBy: deleteRoutedVia,
36739
37402
  mask
36740
37403
  });
37404
+ const deletedRecord = stateResources[op.logicalId];
36741
37405
  delete stateResources[op.logicalId];
37406
+ noteRolledBackCreate(s, op, deletedRecord);
36742
37407
  logger.info(` Rollback: ${safe(op.logicalId)} deleted successfully`);
36743
37408
  await afterOp?.(op.logicalId);
36744
37409
  ctx.recordEvent?.({
@@ -36803,7 +37468,7 @@ async function replayReadopt(s, survivor) {
36803
37468
  mask
36804
37469
  });
36805
37470
  }
36806
- stateResources[op.logicalId] = prev;
37471
+ stateResources[op.logicalId] = withNameGenerationReached(prev, op.logicalId, op.nameGeneration);
36807
37472
  logger.info(` Rollback: ${safe(op.logicalId)} restored to the ${oldKind} old resource`);
36808
37473
  await afterOp?.(op.logicalId);
36809
37474
  const survivorProvisionedBy = current.provisionedBy;
@@ -36886,7 +37551,8 @@ async function replayRevert(s) {
36886
37551
  properties: desiredProps,
36887
37552
  logicalId: op.logicalId,
36888
37553
  physicalId: current.physicalId,
36889
- via: revertVia
37554
+ via: revertVia,
37555
+ nameGeneration: nameGenerationOf(current, op.logicalId)
36890
37556
  }, logger, mask, false)(() => updateWithRollbackRetry(provider, [
36891
37557
  op.logicalId,
36892
37558
  current.physicalId,
@@ -36998,7 +37664,8 @@ async function replayReverseReplacement(s) {
36998
37664
  properties: resolvedPrevProps,
36999
37665
  logicalId: op.logicalId,
37000
37666
  physicalId: prev.physicalId,
37001
- via: createProvisionedBy
37667
+ via: createProvisionedBy,
37668
+ nameGeneration: nameGenerationOf(prev, op.logicalId)
37002
37669
  }, logger, mask, true);
37003
37670
  const resolveNewDeleteRoute = () => ctx.providerRegistry.getProviderFor({
37004
37671
  resourceType: op.resourceType,
@@ -37040,6 +37707,10 @@ async function replayReverseReplacement(s) {
37040
37707
  throwIfDeleteSkipped(deleteNewFirst, op.logicalId, current.physicalId, purpose, newDeleteGuardScope(deleteNewFirstRoute.provisionedBy));
37041
37708
  delete stateResources[op.logicalId];
37042
37709
  await afterOp?.(op.logicalId);
37710
+ await deleteNewFirstRoute.provider.waitForNameReleased?.(op.logicalId, current.physicalId, current.resourceType, {
37711
+ isInterrupted: () => isInterrupted?.() === true,
37712
+ maskSecrets: mask
37713
+ });
37043
37714
  };
37044
37715
  const recreateAfterNewDeleted = async () => {
37045
37716
  try {
@@ -37072,7 +37743,7 @@ async function replayReverseReplacement(s) {
37072
37743
  oldResourceType: oldType,
37073
37744
  newResourceType: op.resourceType,
37074
37745
  requested: replayCreateProps(),
37075
- generated: typeof op.logicalId === "string" ? applyDefaultNameForFallback(op.logicalId, oldType, resolvedPrevProps) : void 0,
37746
+ generated: typeof op.logicalId === "string" ? applyDefaultNameForFallback(op.logicalId, oldType, resolvedPrevProps, "omit") : void 0,
37076
37747
  logicalId: op.logicalId,
37077
37748
  createdVia: createProvisionedBy,
37078
37749
  mask,
@@ -37131,56 +37802,125 @@ async function replayReverseReplacement(s) {
37131
37802
  const { observedProperties: _staleObserved, ...prevRecord } = prev;
37132
37803
  recordNoEchoAttributeValues(createResult, secrets, resolvedPrevProps);
37133
37804
  stateResources[op.logicalId] = redactRollbackRecord({
37134
- ...prevRecord,
37805
+ ...withNameGenerationReached(prevRecord, op.logicalId, op.nameGeneration),
37135
37806
  physicalId: createResult.physicalId,
37136
37807
  attributes: createResult.attributes ?? {},
37137
37808
  properties: recordedPropertiesAfterReplayCreate(prevRecord, createResult)
37138
37809
  }, secrets, prevRecord.properties, prevRecord.attributes);
37139
37810
  if (!adoptedLiveNewResource) inlinePolicyWriters.record(op.logicalId, "create", stateResources[op.logicalId], false, createProvisionedBy);
37811
+ const deferral = s.deferral !== void 0 && !deletedNewFirst && !adoptedLiveNewResource && !rollbackRetainsNewResource(current) ? s.deferral : void 0;
37812
+ const supersededFinalSnapshot = rollbackFinalSnapshotId(op.resourceType, current, op.provisionedBy);
37813
+ const supersededPolicy = current.updateReplacePolicy;
37814
+ const superseded = {
37815
+ logicalId: op.logicalId,
37816
+ supersededAt: Date.now(),
37817
+ state: current,
37818
+ ...(supersededPolicy === "Delete" || supersededPolicy === "Snapshot" || supersededPolicy === "RetainExceptOnCreate") && { updateReplacePolicy: supersededPolicy },
37819
+ ...supersededFinalSnapshot !== void 0 && { finalSnapshotIdentifier: supersededFinalSnapshot }
37820
+ };
37821
+ const recordSuperseded = deferral?.onSuperseded !== void 0 && canRecordSuperseded(current, {});
37822
+ if (recordSuperseded) deferral?.onSuperseded?.(superseded);
37140
37823
  await afterOp?.(op.logicalId);
37141
- let survivorReason;
37142
- const survivorId = retainedSurvivorId(current, op);
37143
- if (!deletedNewFirst && !adoptedLiveNewResource && rollbackRetainsNewResource(current)) {
37144
- const survivorMessages = retainedSurvivorMessages(op.logicalId, op.resourceType, survivorId ?? "no recorded id", `State records the re-created old resource (${stateResources[op.logicalId]?.physicalId ?? prev.physicalId}).`, mask);
37145
- logger.warn(survivorMessages.warn);
37146
- survivorReason = survivorMessages.reason;
37147
- result.warnings++;
37148
- await noteRetainedResource(op.resourceType, op.logicalId);
37149
- } else if (!deletedNewFirst && !adoptedLiveNewResource) try {
37150
- const finalSnapshotIdentifier = rollbackFinalSnapshotId(op.resourceType, current, op.provisionedBy);
37151
- const deleteNewAfterRecreateRoute = resolveNewDeleteRoute();
37152
- const deleteNewAfterRecreate = await withReplayDeletePrinting(s, () => deleteNewAfterRecreateRoute.provider.delete(op.logicalId, current.physicalId, op.resourceType, current.properties, {
37153
- expectedRegion: ctx.region,
37154
- ...newCopyClaimed && { inlinePolicyClaimed: newCopyClaimed },
37155
- ...finalSnapshotIdentifier !== void 0 && { finalSnapshotIdentifier },
37156
- deletionPolicy: replacementDeletePolicy(current.updateReplacePolicy),
37157
- recordedAttributes: current.attributes,
37158
- recordedNoEchoLeaves: current.noEchoLeaves,
37159
- maskSecrets: mask
37160
- }));
37161
- throwIfDeleteSkipped(deleteNewAfterRecreate, op.logicalId, current.physicalId, "while deleting the new resource after re-creating the old one", newDeleteGuardScope(deleteNewAfterRecreateRoute.provisionedBy));
37162
- } catch (deleteError) {
37163
- logger.warn(mask(` Rollback: old ${safe(op.logicalId)} re-created, but deleting the new resource (${displaySafe(mask(current.physicalId))}) failed: ${displaySafe(describeAwsFailure(deleteError).detail)}. Delete it manually — it is no longer tracked in state.`));
37164
- survivorReason = `The replacement's new ${op.resourceType} (${current.physicalId}) could not be deleted after the old resource was re-created: ${describeAwsFailure(deleteError).detail}. It is live, still billing, and no longer tracked by cdkd — delete it yourself.`;
37824
+ const finish = async () => {
37825
+ let survivorReason;
37826
+ const survivorId = retainedSurvivorId(current, op);
37827
+ if (!deletedNewFirst && !adoptedLiveNewResource && rollbackRetainsNewResource(current)) {
37828
+ const survivorMessages = retainedSurvivorMessages(op.logicalId, op.resourceType, survivorId ?? "no recorded id", `State records the re-created old resource (${stateResources[op.logicalId]?.physicalId ?? prev.physicalId}).`, mask);
37829
+ logger.warn(survivorMessages.warn);
37830
+ survivorReason = survivorMessages.reason;
37831
+ result.warnings++;
37832
+ await noteRetainedResource(op.resourceType, op.logicalId);
37833
+ } else if (!deletedNewFirst && !adoptedLiveNewResource) try {
37834
+ const finalSnapshotIdentifier = rollbackFinalSnapshotId(op.resourceType, current, op.provisionedBy);
37835
+ const deleteNewAfterRecreateRoute = resolveNewDeleteRoute();
37836
+ const deleteNewAfterRecreate = await withReplayDeletePrinting(s, () => deleteNewAfterRecreateRoute.provider.delete(op.logicalId, current.physicalId, op.resourceType, current.properties, {
37837
+ expectedRegion: ctx.region,
37838
+ ...newCopyClaimed && { inlinePolicyClaimed: newCopyClaimed },
37839
+ ...finalSnapshotIdentifier !== void 0 && { finalSnapshotIdentifier },
37840
+ deletionPolicy: replacementDeletePolicy(current.updateReplacePolicy),
37841
+ recordedAttributes: current.attributes,
37842
+ recordedNoEchoLeaves: current.noEchoLeaves,
37843
+ maskSecrets: mask
37844
+ }));
37845
+ throwIfDeleteSkipped(deleteNewAfterRecreate, op.logicalId, current.physicalId, "while deleting the new resource after re-creating the old one", newDeleteGuardScope(deleteNewAfterRecreateRoute.provisionedBy));
37846
+ } catch (deleteError) {
37847
+ logger.warn(mask(` Rollback: old ${safe(op.logicalId)} re-created, but deleting the new resource (${displaySafe(mask(current.physicalId))}) failed: ${displaySafe(describeAwsFailure(deleteError).detail)}. ` + (recordSuperseded ? `${SUPERSEDED_KEPT_REMEDY}.` : `Delete it manually — it is no longer tracked in state.`)));
37848
+ survivorReason = `The replacement's new ${op.resourceType} (${current.physicalId}) could not be deleted after the old resource was re-created: ${describeAwsFailure(deleteError).detail}. ` + (recordSuperseded ? `It is live and still billing; ${SUPERSEDED_KEPT_REMEDY}.` : `It is live, still billing, and no longer tracked by cdkd — delete it yourself.`);
37849
+ result.warnings++;
37850
+ }
37851
+ const recreatedId = displaySafe(mask(String(createResult.physicalId)));
37852
+ logger.info(mask(adoptedLiveNewResource ? ` Rollback: ${safe(op.logicalId)} adopted the live resource (${recreatedId}) — replacement NOT fully reversed (name-idempotent Create API)` : ` Rollback: ${safe(op.logicalId)} replacement reversed (old resource re-created as ${recreatedId})`));
37853
+ const survivorProvisionedBy = current.provisionedBy;
37854
+ ctx.recordEvent?.({
37855
+ eventType: "ROLLBACK_RESOURCE_SUCCEEDED",
37856
+ stackName,
37857
+ operation: "UPDATE",
37858
+ logicalId: op.logicalId,
37859
+ resourceType: op.resourceType,
37860
+ ...op.provisionedBy && { provisionedBy: op.provisionedBy },
37861
+ ...survivorReason !== void 0 && {
37862
+ ...survivorId !== void 0 && { physicalId: survivorId },
37863
+ reason: mask(survivorReason),
37864
+ ...survivorProvisionedBy && { provisionedBy: survivorProvisionedBy }
37865
+ },
37866
+ ...adoptedLiveNewResource && { reason: mask("The re-create returned the live new resource instead of re-creating the old one (its Create API is name-idempotent), so the replacement was NOT fully reversed: the old resource's original properties may not have been re-applied. Inspect it with `cdkd drift` and run `cdkd deploy` to reconcile.") }
37867
+ });
37868
+ return survivorReason === void 0;
37869
+ };
37870
+ const keep = (reason) => {
37871
+ logger.warn(mask(` Rollback: old ${safe(op.logicalId)} re-created, but the new resource (${displaySafe(mask(current.physicalId))}) was not deleted: ${reason}. ${SUPERSEDED_KEPT_REMEDY}.`));
37165
37872
  result.warnings++;
37873
+ ctx.recordEvent?.({
37874
+ eventType: "ROLLBACK_RESOURCE_SUCCEEDED",
37875
+ stackName,
37876
+ operation: "UPDATE",
37877
+ logicalId: op.logicalId,
37878
+ resourceType: op.resourceType,
37879
+ ...current.provisionedBy && { provisionedBy: current.provisionedBy },
37880
+ physicalId: current.physicalId,
37881
+ reason: mask(`The old resource was re-created; the new one (${current.physicalId}) was not deleted: ${reason}. ${SUPERSEDED_KEPT_REMEDY}.`)
37882
+ });
37883
+ };
37884
+ if (deferral !== void 0) {
37885
+ logger.info(safeMsg` Rollback: old ${safe(op.logicalId)} re-created first; the new resource ` + safeMsg`(${mask(current.physicalId)}) is deleted once the resources that reference it ` + `are reverted`);
37886
+ deferral.defer(async () => {
37887
+ let gone = false;
37888
+ try {
37889
+ if (supersededHolderOf(superseded, stateResources) !== void 0) {
37890
+ logger.warn(safeMsg` Rollback: not deleting the new ${shownLogicalId(op.logicalId)} ` + safeMsg`(${mask(current.physicalId)}): a record of this stack now holds its ` + `physical id. Check it with cdkd drift.`);
37891
+ result.warnings++;
37892
+ ctx.recordEvent?.({
37893
+ eventType: "ROLLBACK_RESOURCE_SUCCEEDED",
37894
+ stackName,
37895
+ operation: "UPDATE",
37896
+ logicalId: op.logicalId,
37897
+ resourceType: op.resourceType,
37898
+ ...op.provisionedBy && { provisionedBy: op.provisionedBy },
37899
+ reason: mask(`The old resource was re-created; the new one (${current.physicalId}) was not deleted because a record of this stack now holds its physical id.`)
37900
+ });
37901
+ gone = true;
37902
+ } else gone = await finish();
37903
+ } catch (finishError) {
37904
+ logger.warn(maskedFailureText(` Rollback failed for ${shownLogicalId(op.logicalId)} (UPDATE): `, finishError, mask));
37905
+ result.failures++;
37906
+ ctx.recordEvent?.({
37907
+ eventType: "ROLLBACK_RESOURCE_FAILED",
37908
+ stackName,
37909
+ operation: op.changeType,
37910
+ logicalId: op.logicalId,
37911
+ resourceType: op.resourceType,
37912
+ ...op.provisionedBy && { provisionedBy: op.provisionedBy },
37913
+ error: maskedRollbackEventError(finishError, mask)
37914
+ });
37915
+ }
37916
+ if (recordSuperseded && gone) {
37917
+ deferral.onSupersededSettled?.(superseded);
37918
+ await afterOp?.(op.logicalId);
37919
+ }
37920
+ }, recordSuperseded ? keep : void 0);
37921
+ return;
37166
37922
  }
37167
- const recreatedId = displaySafe(mask(String(createResult.physicalId)));
37168
- logger.info(mask(adoptedLiveNewResource ? ` Rollback: ${safe(op.logicalId)} adopted the live resource (${recreatedId}) — replacement NOT fully reversed (name-idempotent Create API)` : ` Rollback: ${safe(op.logicalId)} replacement reversed (old resource re-created as ${recreatedId})`));
37169
- const survivorProvisionedBy = current.provisionedBy;
37170
- ctx.recordEvent?.({
37171
- eventType: "ROLLBACK_RESOURCE_SUCCEEDED",
37172
- stackName,
37173
- operation: "UPDATE",
37174
- logicalId: op.logicalId,
37175
- resourceType: op.resourceType,
37176
- ...op.provisionedBy && { provisionedBy: op.provisionedBy },
37177
- ...survivorReason !== void 0 && {
37178
- ...survivorId !== void 0 && { physicalId: survivorId },
37179
- reason: mask(survivorReason),
37180
- ...survivorProvisionedBy && { provisionedBy: survivorProvisionedBy }
37181
- },
37182
- ...adoptedLiveNewResource && { reason: mask("The re-create returned the live new resource instead of re-creating the old one (its Create API is name-idempotent), so the replacement was NOT fully reversed: the old resource's original properties may not have been re-applied. Inspect it with `cdkd drift` and run `cdkd deploy` to reconcile.") }
37183
- });
37923
+ await finish();
37184
37924
  }
37185
37925
  async function deleteMarkedRecreate(error, s) {
37186
37926
  const madeId = createdBeforeFailure(error, s.op.logicalId, s.oldType);
@@ -37257,7 +37997,8 @@ async function replayRollbackUnbound(operations, stateResources, stackName, ctx,
37257
37997
  warnings: 0,
37258
37998
  skipped: 0,
37259
37999
  interrupted: false,
37260
- orphaned: []
38000
+ orphaned: [],
38001
+ rolledBackCreates: []
37261
38002
  };
37262
38003
  if (operations.length === 0) {
37263
38004
  ctx.logger.info("No completed operations to roll back.");
@@ -37274,13 +38015,77 @@ async function replayRollbackUnbound(operations, stateResources, stackName, ctx,
37274
38015
  markDeleteFirstBlocked(operations, options.failedOperations);
37275
38016
  const { createOps, otherOps } = partitionOps(operations);
37276
38017
  const createdInSegment = new Set(createOps.map((o) => o.logicalId));
37277
- for (const op of orderInlinePolicyReversals([...otherOps].reverse(), stateResources)) {
38018
+ const stepOne = orderInlinePolicyReversals([...otherOps].reverse(), stateResources);
38019
+ const stepOneIds = /* @__PURE__ */ new Map();
38020
+ const stepOneIndex = /* @__PURE__ */ new Map();
38021
+ stepOne.forEach((op, at) => {
38022
+ if (!stepOneIds.has(op.logicalId)) stepOneIds.set(op.logicalId, op);
38023
+ stepOneIndex.set(op, at);
38024
+ });
38025
+ const started = /* @__PURE__ */ new Set();
38026
+ const pendingNewDeletes = /* @__PURE__ */ new Map();
38027
+ const failedOps = /* @__PURE__ */ new Set();
38028
+ const usedByFailedRevert = (target) => [...failedOps].some((failed) => failed !== target && revertReferences(failed, stateResources).has(target.logicalId));
38029
+ const pendingNewIds = /* @__PURE__ */ new Set();
38030
+ const runOp = async (op, deferral) => {
38031
+ const failuresBefore = result.failures;
38032
+ const skippedBefore = result.skipped;
38033
+ await replaySingle(op, stateResources, stackName, ctx, resolver, orphanLogicalIds, result, options.onOrphan, inlinePolicyWriters, options.afterOp, options.isInterrupted, createdInSegment, options.onRolledBackCreate, deferral);
38034
+ if (result.failures > failuresBefore || result.skipped > skippedBefore) failedOps.add(op);
38035
+ };
38036
+ const recreateAhead = async (refs) => {
38037
+ for (const target of [...refs].map((id) => stepOneIds.get(id))) {
38038
+ if (target === void 0 || started.has(target)) continue;
38039
+ if (!renamedReverseReplacement(target, stateResources, orphanLogicalIds, pendingNewIds)) continue;
38040
+ const ownRefs = revertReferences(target, stateResources);
38041
+ if ([...ownRefs].some((id) => {
38042
+ const named = stepOneIds.get(id);
38043
+ return named !== void 0 && !started.has(named) && stepOneIndex.get(named) < stepOneIndex.get(target) && !renamedReverseReplacement(named, stateResources, orphanLogicalIds, pendingNewIds);
38044
+ })) continue;
38045
+ if (options.isInterrupted?.()) return;
38046
+ started.add(target);
38047
+ await recreateAhead(ownRefs);
38048
+ if (options.isInterrupted?.()) return;
38049
+ const newId = stateResources[target.logicalId]?.physicalId;
38050
+ await runOp(target, {
38051
+ defer: (finish, keep) => {
38052
+ pendingNewDeletes.set(target, {
38053
+ finish: async () => {
38054
+ await finish();
38055
+ if (typeof newId === "string") pendingNewIds.delete(newId);
38056
+ },
38057
+ keep
38058
+ });
38059
+ if (typeof newId === "string") pendingNewIds.add(newId);
38060
+ },
38061
+ onSuperseded: options.onSuperseded,
38062
+ onSupersededSettled: options.onSupersededSettled
38063
+ });
38064
+ }
38065
+ };
38066
+ for (const op of stepOne) {
37278
38067
  if (options.isInterrupted?.()) {
37279
38068
  result.interrupted = true;
37280
38069
  break;
37281
38070
  }
37282
- await replaySingle(op, stateResources, stackName, ctx, resolver, orphanLogicalIds, result, options.onOrphan, inlinePolicyWriters, options.afterOp, options.isInterrupted, createdInSegment);
38071
+ if (!started.has(op)) await recreateAhead(revertReferences(op, stateResources));
38072
+ if (options.isInterrupted?.()) {
38073
+ result.interrupted = true;
38074
+ break;
38075
+ }
38076
+ if (started.has(op)) {
38077
+ const pending = pendingNewDeletes.get(op);
38078
+ pendingNewDeletes.delete(op);
38079
+ if (pending?.keep !== void 0 && usedByFailedRevert(op)) pending.keep("a resource that references it did not revert");
38080
+ else await pending?.finish();
38081
+ continue;
38082
+ }
38083
+ started.add(op);
38084
+ await runOp(op);
37283
38085
  }
38086
+ for (const pending of pendingNewDeletes.values()) if (pending.keep !== void 0) pending.keep("the rollback was interrupted");
38087
+ else await pending.finish();
38088
+ pendingNewDeletes.clear();
37284
38089
  if (!result.interrupted && createOps.length > 0) {
37285
38090
  const sorted = sortRollbackCreates(createOps, stateResources);
37286
38091
  for (const op of sorted) {
@@ -37288,7 +38093,7 @@ async function replayRollbackUnbound(operations, stateResources, stackName, ctx,
37288
38093
  result.interrupted = true;
37289
38094
  break;
37290
38095
  }
37291
- await replaySingle(op, stateResources, stackName, ctx, resolver, orphanLogicalIds, result, options.onOrphan, inlinePolicyWriters, options.afterOp, options.isInterrupted, createdInSegment);
38096
+ await replaySingle(op, stateResources, stackName, ctx, resolver, orphanLogicalIds, result, options.onOrphan, inlinePolicyWriters, options.afterOp, options.isInterrupted, createdInSegment, options.onRolledBackCreate);
37292
38097
  }
37293
38098
  }
37294
38099
  await restoreHeldInlinePolicies(inlinePolicyWriters, stateResources, stackName, ctx, result);
@@ -37318,7 +38123,7 @@ async function journaledOrphanKeepReason(op, foreignHolder, ctx) {
37318
38123
  return typeof journaled === "string" && journaled !== "" ? { retry: "its live identity could not be read, so nothing proves the resource now under that id is the one it created" } : { keep: "nothing proves the resource now under that id is the one it created (the journal recorded no identity for it; it may have been deleted and its name reused)" };
37319
38124
  }
37320
38125
  }
37321
- async function replaySingle(op, stateResources, stackName, ctx, resolver, orphanLogicalIds, result, onOrphan, inlinePolicyWriters, afterOp, isInterrupted, createdInSegment = /* @__PURE__ */ new Set()) {
38126
+ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphanLogicalIds, result, onOrphan, inlinePolicyWriters, afterOp, isInterrupted, createdInSegment = /* @__PURE__ */ new Set(), onRolledBackCreate, deferral) {
37322
38127
  const action = classifyRollbackOp(op, stateResources, orphanLogicalIds);
37323
38128
  const { logger } = ctx;
37324
38129
  const secrets = /* @__PURE__ */ new Map();
@@ -37335,6 +38140,7 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
37335
38140
  orphanLogicalIds,
37336
38141
  result,
37337
38142
  onOrphan,
38143
+ onRolledBackCreate,
37338
38144
  inlinePolicyWriters,
37339
38145
  afterOp,
37340
38146
  isInterrupted,
@@ -37344,7 +38150,8 @@ async function replaySingle(op, stateResources, stackName, ctx, resolver, orphan
37344
38150
  opMasker,
37345
38151
  mask,
37346
38152
  createdInSegment,
37347
- createRollbackRoute: void 0
38153
+ createRollbackRoute: void 0,
38154
+ deferral
37348
38155
  };
37349
38156
  const recordBefore = ownRecord(stateResources, op.logicalId);
37350
38157
  try {
@@ -37408,9 +38215,14 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
37408
38215
  remainingFailedOps: [],
37409
38216
  skippedOps: [],
37410
38217
  orphaned: [],
38218
+ rolledBackCreates: [],
37411
38219
  leftInPlace: 0
37412
38220
  };
37413
38221
  const { logger } = ctx;
38222
+ const rolledBack = {
38223
+ result,
38224
+ onRolledBackCreate: options.onRolledBackCreate
38225
+ };
37414
38226
  const resolver = new ReplayResolvers(ctx.region);
37415
38227
  const emitEnvelope = options.emitEnvelope === true && failedOps.length > 0;
37416
38228
  if (emitEnvelope) ctx.recordEvent?.({
@@ -37487,7 +38299,10 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
37487
38299
  result.orphaned.push(orphaned);
37488
38300
  options.onOrphan?.(orphaned);
37489
38301
  }
37490
- if (!recordUnderIdIsNotOwn(op, stateResources)) delete stateResources[op.logicalId];
38302
+ if (!recordUnderIdIsNotOwn(op, stateResources)) {
38303
+ delete stateResources[op.logicalId];
38304
+ noteRolledBackCreate(rolledBack, op, failedCreateRecord);
38305
+ }
37491
38306
  await noteRetainedResource(op.resourceType, op.logicalId);
37492
38307
  logger.info(` Rollback: leaving partially-created ${safe(op.logicalId)} (${safe(op.resourceType)}) in AWS (DeletionPolicy: Retain)` + (failedCreateRecord ? " — removed from state" : " — it was never in state"));
37493
38308
  await options.afterOp?.(op.logicalId);
@@ -37521,7 +38336,10 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
37521
38336
  }, ctx.foreignHolder, ctx);
37522
38337
  if (verdict === "gone") {
37523
38338
  logger.info(safeMsg` Rollback: partially-created ${shownLogicalId(op.logicalId)} (${refusalResourceType(op.resourceType)}) is already gone — nothing to delete`);
37524
- if (!recordUnderIdIsNotOwn(op, stateResources)) delete stateResources[op.logicalId];
38339
+ if (!recordUnderIdIsNotOwn(op, stateResources)) {
38340
+ delete stateResources[op.logicalId];
38341
+ noteRolledBackCreate(rolledBack, op, failedCreateRecord);
38342
+ }
37525
38343
  await options.afterOp?.(op.logicalId);
37526
38344
  ctx.recordEvent?.({
37527
38345
  eventType: "ROLLBACK_RESOURCE_SUCCEEDED",
@@ -37588,7 +38406,10 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
37588
38406
  result.warnings++;
37589
38407
  result.leftInPlace++;
37590
38408
  }
37591
- if (!recordUnderIdIsNotOwn(op, stateResources)) delete stateResources[op.logicalId];
38409
+ if (!recordUnderIdIsNotOwn(op, stateResources)) {
38410
+ delete stateResources[op.logicalId];
38411
+ noteRolledBackCreate(rolledBack, op, failedCreateRecord);
38412
+ }
37592
38413
  await options.afterOp?.(op.logicalId);
37593
38414
  ctx.recordEvent?.({
37594
38415
  eventType: "ROLLBACK_RESOURCE_SUCCEEDED",
@@ -37653,7 +38474,8 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
37653
38474
  properties: desiredProps,
37654
38475
  logicalId: op.logicalId,
37655
38476
  physicalId: current.physicalId,
37656
- via: revertVia
38477
+ via: revertVia,
38478
+ nameGeneration: nameGenerationOf(current, op.logicalId)
37657
38479
  }, logger, mask, false)(() => updateWithRollbackRetry(provider, [
37658
38480
  op.logicalId,
37659
38481
  current.physicalId,
@@ -37669,7 +38491,7 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
37669
38491
  }
37670
38492
  ], op.logicalId, logger, options.isInterrupted, secrets, mask));
37671
38493
  if (revertFailedResult) recordNoEchoAttributeValues(revertFailedResult, secrets, desiredProps);
37672
- stateResources[op.logicalId] = maskRestoredNoEchoRecord(redactRollbackRecord(recordAfterRollbackUpdate(prev, revertFailedResult), secrets, prev.properties, prev.attributes), prev, noEcho.substituted);
38494
+ stateResources[op.logicalId] = maskRestoredNoEchoRecord(redactRollbackRecord(withNameGenerationReached(recordAfterRollbackUpdate(prev, revertFailedResult), op.logicalId, op.nameGeneration), secrets, prev.properties, prev.attributes), prev, noEcho.substituted);
37673
38495
  if (updatePartialReason(revertFailedResult) === void 0) inlinePolicyWriters.record(op.logicalId, "update", stateResources[op.logicalId], !deepEqual$1(prev.properties?.["Policies"], (op.attemptedProperties ?? current.properties)?.["Policies"]), revertVia);
37674
38496
  const revertFailedPartial = updatePartialReason(revertFailedResult);
37675
38497
  if (revertFailedPartial !== void 0) logger.warn(mask(` Rollback: ${safe(op.logicalId)} reverted, ${updatePartialMessage(revertFailedPartial)}`));
@@ -38034,6 +38856,69 @@ function healPrintingBag(baseline, logicalId, resource, namingSecrets) {
38034
38856
  return hit.judge(logicalId);
38035
38857
  }
38036
38858
 
38859
+ //#endregion
38860
+ //#region src/deployment/deploy-engine/superseded-retry.ts
38861
+ async function retryCarriedSupersededResources(engine, host, carried, resources, options = {}) {
38862
+ let changed = false;
38863
+ if (carried.length === 0) return changed;
38864
+ const view = {
38865
+ live: () => Object.entries(resources),
38866
+ survivors: () => Object.entries(resources)
38867
+ };
38868
+ for (const entry of carried) {
38869
+ if (engine.interrupted) break;
38870
+ const { logicalId } = entry;
38871
+ const { physicalId, resourceType } = entry.state;
38872
+ const bag = unionOfSecretBags([secretNameBagFor(engine.secretsRun, logicalId), orphanRecordsPrintingBag([entry])]);
38873
+ const holder = supersededHolderOf(entry, resources);
38874
+ if (holder !== void 0) {
38875
+ removeSuperseded(host, entry);
38876
+ changed = true;
38877
+ if (holder.resourceType !== resourceType) {
38878
+ withPrintingSecrets(bag, () => engine.logger.warn(safeMsg` ⚠ ${supersededHeldByOtherTypeWarning(entry, holder.resourceType)}`));
38879
+ continue;
38880
+ }
38881
+ withPrintingSecrets(bag, () => engine.logger.debug(safeMsg`Superseded ${logicalId} (${physicalId}) is held by a record again; not deleting it`));
38882
+ continue;
38883
+ }
38884
+ await withPrintingSecrets(bag, () => withStackRecords(view, async () => {
38885
+ engine.logger.info(safeMsg` Deleting old ${logicalId} (${physicalId}), superseded by an earlier deploy...`);
38886
+ let outcome;
38887
+ try {
38888
+ const route = engine.providerRegistry.getProviderFor({
38889
+ resourceType,
38890
+ ...entry.state.provisionedBy !== void 0 && { provisionedBy: entry.state.provisionedBy }
38891
+ });
38892
+ outcome = await deleteSupersededEntry(entry, {
38893
+ provider: route.provider,
38894
+ region: engine.stackRegion,
38895
+ maskSecrets: createSecretMasker(bag),
38896
+ stop: () => engine.interrupted,
38897
+ once: options.waitInUse !== true
38898
+ });
38899
+ } catch (error) {
38900
+ outcome = {
38901
+ kind: "failed",
38902
+ error
38903
+ };
38904
+ }
38905
+ if (outcome.kind === "failed") {
38906
+ const detail = maskSecretsInText(describeAwsFailure(outcome.error).detail, bag);
38907
+ engine.logger.warn(safeMsg` ⚠ Failed to delete old resource ${logicalId} (${physicalId}): ${detail}. ${SUPERSEDED_KEPT_REMEDY}.`);
38908
+ return;
38909
+ }
38910
+ removeSuperseded(host, entry);
38911
+ changed = true;
38912
+ if (outcome.kind === "notDeleted") {
38913
+ engine.logger.warn(safeMsg` ⚠ ${deleteSkippedMessage(logicalId, physicalId, outcome.reason, "while cleaning up the superseded resource", { commandFreeLine: true })}. Delete it manually — it is no longer tracked in state.`);
38914
+ return;
38915
+ }
38916
+ engine.logger.info(safeMsg` ${green("✓")} Old ${logicalId} (${physicalId}) deleted`);
38917
+ }));
38918
+ }
38919
+ return changed;
38920
+ }
38921
+
38037
38922
  //#endregion
38038
38923
  //#region src/provisioning/name-lookup.ts
38039
38924
  const inFlight = /* @__PURE__ */ new Map();
@@ -38132,7 +39017,8 @@ var GeneratedNameGuard = class GeneratedNameGuard {
38132
39017
  static start(input) {
38133
39018
  const candidates = [];
38134
39019
  for (const change of input.changes) {
38135
- if (change.changeType !== "CREATE") continue;
39020
+ const generation = change.changeType === "UPDATE" ? input.replacementGeneration?.(change) : void 0;
39021
+ if (change.changeType !== "CREATE" && generation === void 0) continue;
38136
39022
  const properties = change.desiredProperties ?? {};
38137
39023
  let decision;
38138
39024
  let name;
@@ -38143,7 +39029,11 @@ var GeneratedNameGuard = class GeneratedNameGuard {
38143
39029
  properties
38144
39030
  });
38145
39031
  if (!replacementCreateAdoptsName(change.resourceType, decision.provisionedBy)) continue;
38146
- name = decision.provider.generatedCreateName?.(change.resourceType, change.logicalId, properties);
39032
+ const derive = () => decision.provider.generatedCreateName?.(change.resourceType, change.logicalId, properties);
39033
+ name = generation === void 0 ? derive() : withNameGeneration({
39034
+ logicalId: change.logicalId,
39035
+ generation
39036
+ }, derive);
38147
39037
  deferred = decision.provider.lookupNeedsResolvedProperties?.(change.resourceType, properties) === true;
38148
39038
  } catch {
38149
39039
  continue;
@@ -38443,7 +39333,7 @@ var GeneratedNameGuard = class GeneratedNameGuard {
38443
39333
  });
38444
39334
  unlicensed.push(c);
38445
39335
  }
38446
- if (unlicensed.length > 0 && input.loadKeptInHistory !== void 0 && evidence !== void 0 && !("error" in evidence) && evidence.retainedAbsent) {
39336
+ if (unlicensed.length > 0 && input.newScheme !== true && input.loadKeptInHistory !== void 0 && evidence !== void 0 && !("error" in evidence) && evidence.retainedAbsent) {
38447
39337
  let kept;
38448
39338
  try {
38449
39339
  this.historyRead ??= input.loadKeptInHistory();
@@ -38606,14 +39496,15 @@ async function lookupAll(input, candidates) {
38606
39496
  };
38607
39497
  }
38608
39498
  async function loadEvidence(input) {
38609
- const [journal, retained] = await Promise.all([input.loadJournal(), input.loadRetained()]);
39499
+ const kept = input.newScheme !== true;
39500
+ const [journal, retained] = await Promise.all([input.loadJournal(), kept ? input.loadRetained() : Promise.resolve([])]);
38610
39501
  const sources = [];
38611
39502
  for (const record of Object.values(input.records)) if (typeof record?.physicalId === "string") sources.push({
38612
39503
  via: "record",
38613
39504
  type: record.resourceType,
38614
39505
  id: record.physicalId
38615
39506
  });
38616
- for (const orphan of input.orphans ?? []) {
39507
+ for (const orphan of kept ? input.orphans ?? [] : []) {
38617
39508
  const s = orphan.state;
38618
39509
  if (typeof s?.physicalId === "string") sources.push({
38619
39510
  via: "orphan",
@@ -38792,7 +39683,7 @@ function warnDropFailed(logger, stackName, region, logicalIds) {
38792
39683
  logger.warn(safeMsg`${hint.intro}`);
38793
39684
  for (const command of hint.commands) logger.warn(safeMsg`Drop with: ${command}`);
38794
39685
  }
38795
- async function deleteJournaledOrphans(orphans, stateResources, stackName, ctx, options = {}) {
39686
+ async function deleteJournaledOrphans(orphans, stateResources, stackName, stackInstanceId, ctx, options = {}) {
38796
39687
  const total = {
38797
39688
  failures: 0,
38798
39689
  warnings: 0,
@@ -38816,7 +39707,10 @@ async function deleteJournaledOrphans(orphans, stateResources, stackName, ctx, o
38816
39707
  break;
38817
39708
  }
38818
39709
  const ops = [...companions ?? [], ...orphanOps];
38819
- const replay = () => withPrintingSecrets(printing, () => withStackName(stackName, () => replayFailedOperations(ops, stateResources, stackName, maskedCtx, {
39710
+ const replay = () => withPrintingSecrets(printing, () => withStackScope(nameScopeOf(stackName, stackInstanceId, {
39711
+ resources: stateResources,
39712
+ ...options.retiredNameGenerations !== void 0 && { retiredNameGenerations: options.retiredNameGenerations }
39713
+ }), () => replayFailedOperations(ops, stateResources, stackName, maskedCtx, {
38820
39714
  emitEnvelope: false,
38821
39715
  inlinePolicyWriters,
38822
39716
  forDestroy: true,
@@ -38902,14 +39796,15 @@ async function settleJournaledOrphansOnSuccess(args) {
38902
39796
  count: orphans.count - unreadable.size - tracked.size
38903
39797
  };
38904
39798
  const writtenThisRun = [...orphans.deployLogicalIds ?? []].filter((id) => Object.prototype.hasOwnProperty.call(stateResources, id)).map((id) => stateResources[id]).filter((r) => r !== void 0 && r !== null && typeof r === "object");
38905
- const outcome = await deleteJournaledOrphans(acting, { ...stateResources }, stackName, {
39799
+ const outcome = await deleteJournaledOrphans(acting, { ...stateResources }, stackName, args.stackInstanceId, {
38906
39800
  ...ctx,
38907
39801
  writtenThisRun,
38908
39802
  foreignHolder: args.foreignHolder,
38909
39803
  orphanDeleteProven: proven
38910
39804
  }, {
38911
39805
  pointAtDrop: false,
38912
- ...args.isInterrupted && { isInterrupted: args.isInterrupted }
39806
+ ...args.isInterrupted && { isInterrupted: args.isInterrupted },
39807
+ retiredNameGenerations: args.retiredNameGenerations
38913
39808
  });
38914
39809
  leftInPlace = outcome.leftInPlace;
38915
39810
  failedDeletes = outcome.failedLogicalIds;
@@ -39364,10 +40259,13 @@ async function revertNestedChildFromJournal(args) {
39364
40259
  refuseMalformedState(base, childStackName, region, refusalRecovery);
39365
40260
  refuseMalformedOrphans(base, childStackName, region, refusalRecovery);
39366
40261
  refuseMalformedOrphanRecords(base, childStackName, region, refusalRecovery);
40262
+ const childNamingScope = nameScopeOf(childStackName, stackInstanceIdOf(base, displayStackName(childStackName)), base);
39367
40263
  const segments = ((await ctx.stateBackend.loadRollbackJournal(childStackName, region))?.segments ?? []).filter((segment) => segment.runId === runId);
39368
40264
  if (segments.length === 0) refuse("its rollback journal holds no segment for this deploy run, so there is no record of what it held before.");
39369
40265
  const stateResources = { ...base.resources };
39370
40266
  const mintedOrphans = [];
40267
+ const rolledBackCreates = [];
40268
+ const supersededHost = {};
39371
40269
  const restoredOutputs = segments.find((s) => s.previousOutputs)?.previousOutputs;
39372
40270
  const restoredReads = segments.find((s) => s.previousCrossStackReads)?.previousCrossStackReads;
39373
40271
  let currentEtag = stateData.etag;
@@ -39376,10 +40274,13 @@ async function revertNestedChildFromJournal(args) {
39376
40274
  const { skippedOutputs: _dropped, ...carried } = base;
39377
40275
  const next = () => ({
39378
40276
  ...carried,
39379
- version: 12,
40277
+ ...stackInstanceIdCarriedFrom(base),
40278
+ ...supersededAfterRollback(base, supersededHost),
40279
+ version: 13,
39380
40280
  region,
39381
40281
  resources: { ...stateResources },
39382
40282
  ...orphansAfterRollback(base, mintedOrphans),
40283
+ ...retiredAfterRollback(base, mintedOrphans, rolledBackCreates),
39383
40284
  ...restoring && restoredOutputs && { outputs: { ...restoredOutputs.outputs } },
39384
40285
  ...restoring && restoredReads && {
39385
40286
  ...restoredReads.imports && { imports: [...restoredReads.imports] },
@@ -39448,12 +40349,15 @@ async function revertNestedChildFromJournal(args) {
39448
40349
  const segment = segments[s];
39449
40350
  const skipPrefix = segment.skipPrefix ?? getCurrentSkipPrefix();
39450
40351
  const split = splitImportedOps(segment.operations, segment);
39451
- const result = await withNestedStackContext(childCtx, () => withSkipPrefix(skipPrefix, () => withStackName(childStackName, () => withCreateTokenLedger(ledgerForStack(ctx.stateBackend, childStackName, region), () => withNestedRevertRun(runId, async (inner) => {
40352
+ const result = await withNestedStackContext(childCtx, () => withSkipPrefix(skipPrefix, () => withStackScope(childNamingScope, () => withCreateTokenLedger(ledgerForStack(ctx.stateBackend, childStackName, region), () => withNestedRevertRun(runId, async (inner) => {
39452
40353
  const replayed = await withPrintingSecrets(journaledOrphanPrintingBag(completedReplayEntries(split.replay), stateResources), () => replayRollback(split.replay, stateResources, childStackName, execCtx, {
39453
40354
  afterOp: save,
39454
40355
  onOrphan: (record) => mintedOrphans.push(record),
40356
+ onRolledBackCreate: (create) => rolledBackCreates.push(create),
39455
40357
  inlinePolicyWriters,
39456
- failedOperations: segment.failedOperations
40358
+ failedOperations: segment.failedOperations,
40359
+ onSuperseded: (entry) => addSuperseded(supersededHost, entry),
40360
+ onSupersededSettled: (entry) => removeSuperseded(supersededHost, entry)
39457
40361
  }));
39458
40362
  for (const [id, below] of inner.settled) settledBelow.set(id, below);
39459
40363
  return {
@@ -39483,13 +40387,18 @@ async function revertNestedChildFromJournal(args) {
39483
40387
 
39484
40388
  //#endregion
39485
40389
  //#region src/deployment/retained-readoption.ts
39486
- function keptForReadoption(resource) {
39487
- if (!replacementCreateAdoptsName(resource.resourceType, resource.provisionedBy)) return false;
40390
+ function keptUnderGeneratedName(resource) {
39488
40391
  if (typeof resource.physicalId !== "string" || resource.physicalId === "") return false;
39489
40392
  const property = explicitNamePropertyFor(resource.resourceType);
39490
40393
  const properties = resource.properties;
39491
40394
  return property === void 0 || !properties?.[property];
39492
40395
  }
40396
+ function keptForRetainedRecord(resource) {
40397
+ return replacementCreateAdoptsName(resource.resourceType, "sdk") ? keptForReadoption(resource) : keptUnderGeneratedName(resource);
40398
+ }
40399
+ function keptForReadoption(resource) {
40400
+ return replacementCreateAdoptsName(resource.resourceType, resource.provisionedBy) && keptUnderGeneratedName(resource);
40401
+ }
39493
40402
  async function recordRetainedForReadoption(backend, stackName, region, kept, logger, earlier) {
39494
40403
  if (kept.length === 0) {
39495
40404
  try {
@@ -39505,10 +40414,10 @@ async function recordRetainedForReadoption(backend, stackName, region, kept, log
39505
40414
  await backend.saveRetainedResources(stackName, region, [...before.filter((e) => !keptIds.has(e.logicalId)), ...kept]);
39506
40415
  } catch (error) {
39507
40416
  if (error instanceof RetainedTimeUnconfirmedError) {
39508
- logger.warn(safeMsg`Recorded the ${String(kept.length)} kept resource(s) of ${displayStackName(stackName)} ` + safeMsg`a later deploy takes back by name, but their time could not be confirmed from S3 ` + safeMsg`(${describeAwsFailure(error.cause).summary}); they carry this machine's clock instead.`);
40417
+ logger.warn(safeMsg`Recorded the ${String(kept.length)} kept resource(s) of ${displayStackName(stackName)}, ` + safeMsg`but their time could not be confirmed from S3 ` + safeMsg`(${describeAwsFailure(error.cause).summary}); they carry this machine's clock instead.`);
39509
40418
  return;
39510
40419
  }
39511
- logger.warn(safeMsg`Could not record the ${String(kept.length)} kept resource(s) of ${displayStackName(stackName)} ` + safeMsg`a later deploy takes back by name (${describeAwsFailure(error).summary}). That deploy ` + `refuses to create them over the kept ones; adopt them with 'cdkd import' then.`);
40420
+ logger.warn(safeMsg`Could not record the ${String(kept.length)} kept resource(s) of ${displayStackName(stackName)} ` + safeMsg`(${describeAwsFailure(error).summary}). A later deploy may refuse to create one over ` + `its kept copy, or not name them; adopt a kept one with 'cdkd import'.`);
39512
40421
  }
39513
40422
  }
39514
40423
  var KeptForReadoption = class {
@@ -39569,7 +40478,7 @@ async function provisionDelete(deps, logicalId, change, stateResources, stackNam
39569
40478
  deps.logger.info(safeMsg`Retaining ${logicalId} (${resourceType}) - DeletionPolicy: ${deletionPolicy}`);
39570
40479
  delete stateResources[logicalId];
39571
40480
  await noteRetainedResource(resourceType, logicalId);
39572
- if (keptForReadoption(currentResource)) {
40481
+ if (getCurrentStackInstanceId() !== void 0 ? keptForRetainedRecord(currentResource) : keptForReadoption(currentResource)) {
39573
40482
  let kept = keptByEngine.get(deps.owner);
39574
40483
  if (kept === void 0) {
39575
40484
  kept = new KeptForReadoption(deps.stateBackend, stackName, deps.stackRegion, deps.logger);
@@ -39748,6 +40657,9 @@ async function settlePending(params, pending) {
39748
40657
  const reader = params.reader();
39749
40658
  const isUnique = params.identifierUnique ?? ccIdentifierIsUnique;
39750
40659
  const stackShown = displayStackName(stackName);
40660
+ const source = params.stackInstanceId;
40661
+ let resolvedId;
40662
+ const stackInstanceId = () => resolvedId ??= typeof source === "function" ? source() : Promise.resolve(source);
39751
40663
  const settlements = /* @__PURE__ */ new Map();
39752
40664
  const unresolved = [];
39753
40665
  for (const [token, op] of pending) {
@@ -39779,7 +40691,9 @@ async function settlePending(params, pending) {
39779
40691
  identifier: made,
39780
40692
  attemptedProperties: op.attemptedProperties,
39781
40693
  logicalId: op.logicalId,
39782
- stackName
40694
+ stackName,
40695
+ stackInstanceId: await stackInstanceId(),
40696
+ nameGenerationsThrough: generationsThrough(op, held)
39783
40697
  });
39784
40698
  const ended = outcome.status === "succeeded" ? "completed" : outcome.status === "cancelled" ? "was cancelled" : "failed";
39785
40699
  if (outcome.status === "succeeded" && unique && held === void 0 && params.resume?.(op, made)) {
@@ -39833,7 +40747,7 @@ function holdsSecretReference(properties) {
39833
40747
  if (properties === void 0) return false;
39834
40748
  return carriesSecretMask(properties) || JSON.stringify(properties).includes("{{resolve:");
39835
40749
  }
39836
- const ccIdentifierIsUnique = async ({ resourceType, identifier, attemptedProperties, logicalId, stackName }) => {
40750
+ const ccIdentifierIsUnique = async ({ resourceType, identifier, attemptedProperties, logicalId, stackName, stackInstanceId, nameGenerationsThrough }) => {
39837
40751
  if (attemptedProperties === void 0 || holdsSecretReference(attemptedProperties)) return false;
39838
40752
  const [fields, readOnly] = await Promise.all([getPrimaryIdentifierFields(resourceType), getTopLevelReadOnlyProperties(resourceType)]);
39839
40753
  if (fields === void 0 || readOnly === void 0) return false;
@@ -39848,9 +40762,15 @@ const ccIdentifierIsUnique = async ({ resourceType, identifier, attemptedPropert
39848
40762
  collect(attemptedProperties);
39849
40763
  return parts.some((part, i) => {
39850
40764
  if (part === "" || !readOnly.has(fields[i])) return false;
39851
- return !nameSegments(part).some((segment) => sent.has(segment) || looksLikeCdkdGeneratedName(segment, logicalId, stackName));
40765
+ return !nameSegments(part).some((segment) => sent.has(segment) || looksLikeCdkdGeneratedName(segment, logicalId, stackName, stackInstanceId, nameGenerationsThrough === void 0 ? void 0 : { through: nameGenerationsThrough }));
39852
40766
  });
39853
40767
  };
40768
+ function generationsThrough(op, held) {
40769
+ const own = isNameGeneration(op.nameGeneration) ? op.nameGeneration : 0;
40770
+ let recorded = 0;
40771
+ for (const value of [held?.nameGeneration, held?.nameGenerationHigh]) if (isNameGeneration(value)) recorded = Math.max(recorded, value);
40772
+ return Math.max(own, recorded) + 1;
40773
+ }
39854
40774
  function nameSegments(value) {
39855
40775
  const text = value.toLowerCase();
39856
40776
  const arn = /^arn:[^:]*:[^:]*:[^:]*:[^:]*:(.*)$/.exec(text);
@@ -40220,9 +41140,19 @@ async function planOrphanAdoption(params) {
40220
41140
  adopted: {},
40221
41141
  remaining: [],
40222
41142
  refusals: [],
40223
- notices: []
41143
+ notices: [],
41144
+ warnings: []
40224
41145
  };
40225
41146
  if (params.records.length === 0) return outcome;
41147
+ if (params.newScheme === true) {
41148
+ for (const record of params.records) {
41149
+ if (params.managedLogicalIds.has(record.logicalId)) continue;
41150
+ outcome.remaining.push(record);
41151
+ if ((params.template.Resources?.[record.logicalId])?.Type !== record.state.resourceType) continue;
41152
+ outcome.warnings.push(`${displayIdent(record.logicalId)} (${displayIdent(record.state.resourceType)}) was left in AWS by an earlier rollback as ${displaySafe(record.state.physicalId)} (DeletionPolicy: Retain). This deploy does not take it back: it creates a new resource under a new name, as CloudFormation does. To manage the kept resource again, adopt it with 'cdkd import'.`);
41153
+ }
41154
+ return outcome;
41155
+ }
40226
41156
  let siblingClaims;
40227
41157
  const claims = async () => siblingClaims ??= await params.readSiblingClaims();
40228
41158
  for (const record of params.records) {
@@ -40412,9 +41342,11 @@ async function adoptRollbackOrphans(deps, currentState, effectiveTemplate) {
40412
41342
  selfRegion: deps.stackRegion,
40413
41343
  logger: deps.logger
40414
41344
  }),
40415
- logger: { debug: (m) => deps.logger.debug(m) }
41345
+ logger: { debug: (m) => deps.logger.debug(m) },
41346
+ newScheme: currentState.stackInstanceId !== void 0
40416
41347
  }));
40417
41348
  for (const notice of plan.notices) deps.logger.info(maskSecretsInText(notice, named));
41349
+ for (const warning of plan.warnings) deps.logger.warn(maskSecretsInText(warning, named));
40418
41350
  const adoptedFrom = /* @__PURE__ */ new Map();
40419
41351
  adoptedOrphanRecords.set(deps.owner, adoptedFrom);
40420
41352
  if (plan.refusals.length > 0) throw new Error(safeMsg`Deploy refused — cdkd left ${plan.refusals.length} resource(s) in AWS that it cannot ` + "safely re-adopt:" + plan.refusals.map((r) => safeMsg`\n ${maskSecretsInText(r, named)}`).join(""));
@@ -40473,6 +41405,7 @@ async function performRollback(deps, completedOperations, stateResources, stackN
40473
41405
  createdResourceHolder: crossPrefixHolder === void 0 ? void 0 : () => crossPrefixAnswer ??= crossPrefixHolder(stackName)
40474
41406
  };
40475
41407
  const inlinePolicyWriters = new RollbackInlinePolicyWriters();
41408
+ const supersededHost = {};
40476
41409
  const runId = deps.options.eventRecorder?.runId;
40477
41410
  const { result, failed, run } = await withNestedRevertRun(runId, async (scope) => {
40478
41411
  return {
@@ -40485,7 +41418,10 @@ async function performRollback(deps, completedOperations, stateResources, stackN
40485
41418
  })) : void 0,
40486
41419
  result: await withPrintingSecrets(replayPrintingBag(deps, completedReplayEntries(completedOperations), stateResources), () => replayRollback(completedOperations, stateResources, stackName, ctx, {
40487
41420
  inlinePolicyWriters,
40488
- failedOperations
41421
+ failedOperations,
41422
+ isInterrupted: () => deps.userInterrupted(),
41423
+ onSuperseded: (entry) => addSuperseded(supersededHost, entry),
41424
+ onSupersededSettled: (entry) => removeSuperseded(supersededHost, entry)
40489
41425
  })),
40490
41426
  run: scope
40491
41427
  };
@@ -40496,7 +41432,10 @@ async function performRollback(deps, completedOperations, stateResources, stackN
40496
41432
  failures: result.failures + (failed?.failures ?? 0),
40497
41433
  warnings: result.warnings + run.warnings + (failed?.warnings ?? 0),
40498
41434
  skipped: result.skipped + (failed?.skipped ?? 0),
41435
+ interrupted: result.interrupted,
40499
41436
  orphaned: [...failed?.orphaned ?? [], ...result.orphaned],
41437
+ rolledBackCreates: [...failed?.rolledBackCreates ?? [], ...result.rolledBackCreates],
41438
+ superseded: supersededHost.supersededResources ?? [],
40500
41439
  settledNested: run.settled,
40501
41440
  remainingFailedOps: failedOperations.filter((_, i) => !handled.has(i))
40502
41441
  };
@@ -40539,9 +41478,11 @@ async function settleJournalAfterSuccess(deps, stackName, completedOperations, p
40539
41478
  const own = await settleJournaledOrphansOnSuccess({
40540
41479
  stateBackend: deps.stateBackend,
40541
41480
  stackName,
41481
+ stackInstanceId: stackInstanceIdOf(previousState, displayStackName(stackName)),
40542
41482
  region: deps.stackRegion,
40543
41483
  stateResources: finalResources,
40544
41484
  rollbackOrphans: previousState.orphans,
41485
+ retiredNameGenerations: previousState.retiredNameGenerations,
40545
41486
  newerOperations: completedOperations,
40546
41487
  ...deployRunId !== void 0 && { deployRunId },
40547
41488
  foreignHolder: foreignHolderFor({
@@ -40567,9 +41508,11 @@ async function settleJournalAfterSuccess(deps, stackName, completedOperations, p
40567
41508
  const settled = await settleJournaledOrphansOnSuccess({
40568
41509
  stateBackend: deps.stateBackend,
40569
41510
  stackName: child,
41511
+ stackInstanceId: stackInstanceIdOf(childState, displayStackName(child)),
40570
41512
  region: deps.stackRegion,
40571
41513
  stateResources: childState?.resources,
40572
41514
  rollbackOrphans: childState?.orphans,
41515
+ retiredNameGenerations: childState?.retiredNameGenerations,
40573
41516
  newerOperations: [],
40574
41517
  ...deployRunId !== void 0 && { deployRunId },
40575
41518
  foreignHolder: foreignHolderFor({
@@ -43219,60 +44162,10 @@ function peekRoutingForLabel(providerRegistry, options, change, existingState, s
43219
44162
  }
43220
44163
  return deriveLabelRouting(change, existingState, providerRegistry, isPinnedToCcApi(options, stackName, logicalId));
43221
44164
  }
43222
- function preparePropertiesForCcApi(providerRegistry, resourceType, resolvedProps, logicalId) {
44165
+ function preparePropertiesForCcApi(providerRegistry, resourceType, resolvedProps, logicalId, underivable = "refuse") {
43223
44166
  const sdkProvider = providerRegistry.getRegisteredTypes().includes(resourceType) ? providerRegistry.getProvider(resourceType) : void 0;
43224
44167
  if (sdkProvider?.preparePropertiesForFallback) return sdkProvider.preparePropertiesForFallback(logicalId, resourceType, resolvedProps);
43225
- return applyDefaultNameForFallback(logicalId, resourceType, resolvedProps);
43226
- }
43227
-
43228
- //#endregion
43229
- //#region src/deployment/deploy-engine/name-collision.ts
43230
- function replacementNameOrigin(logicalId, physicalId) {
43231
- if (looksLikeCdkdGeneratedName(physicalId, logicalId, getCurrentStackName())) return {
43232
- descriptor: `The physical name (${physicalId}) was GENERATED by cdkd from the construct's logical id rather than declared in your template, and that derivation has no random component — so the new resource asks for exactly the name the existing one still holds`,
43233
- remedy: "Either give the resource an explicit physical name in your CDK code, or rename the CONSTRUCT (its id feeds the generated name — note that this replaces the resource rather than renaming it in place)"
43234
- };
43235
- return {
43236
- descriptor: `The resource has a user-supplied physical name (${physicalId})`,
43237
- remedy: "Either rename the resource in your CDK code (a fresh name lets the safe create-first order proceed)"
43238
- };
43239
- }
43240
- function orphanedNameCollisionAdvice(providerRegistry, changeType, logicalId, error) {
43241
- if (changeType !== "CREATE") return void 0;
43242
- if (!(error instanceof ProvisioningError)) return void 0;
43243
- const physicalId = error.physicalId;
43244
- if (!physicalId) return void 0;
43245
- const replayed = isReplayedNameCollisionFrom(error, logicalId, (link) => isAuxiliaryMarkOf(link, RETRY_AUXILIARY_OWNER));
43246
- if (!replayed && !isNameCollisionErrorFrom(error, logicalId)) return void 0;
43247
- const stackName = getCurrentStackName();
43248
- if (!looksLikeCdkdGeneratedName(physicalId, logicalId, stackName)) return void 0;
43249
- if (!stackName) return void 0;
43250
- const safeId = displaySafe(physicalId, { asciiOnly: true });
43251
- const safeStack = displaySafe(stackName, { asciiOnly: true });
43252
- const safeLogicalId = displaySafe(logicalId, { asciiOnly: true });
43253
- const idShown = isInertUnquoted(safeId);
43254
- const shownId = idShown ? safeId : "a name that cannot be shown safely here";
43255
- const shownLogicalId = isInertUnquoted(safeLogicalId) ? safeLogicalId : "A resource whose logical id cannot be shown safely here";
43256
- const diagnosis = replayed ? `${shownLogicalId}: the name AWS reports as taken (${shownId}) is most likely held by a resource THIS create made. An earlier attempt of it ended without a clear verdict (a server error, a dropped connection or a timeout, or a failure after the create call itself may have succeeded), and the retry then found the name taken. A dropped connection can also happen before the request reached AWS, so the holder may be another resource: confirm it is yours before deleting or importing it. cdkd records a resource only once its create succeeds, so this one is in no state file: no rollback or cdkd destroy will remove it, and re-running collides with it again.` : `${shownLogicalId}: the name AWS reports as taken (${shownId}) is one cdkd DERIVED from the logical id, and that derivation has no random component — so this is most likely a resource an earlier cdkd run left behind. A rollback leaves a resource carrying DeletionPolicy: Retain in AWS and drops it from state, as CloudFormation does; what differs is the name. CloudFormation would generate a fresh one for an unnamed resource and redeploy clean, whereas cdkd asks again for the name the orphan still holds — so re-running does not clear this.`;
43257
- const deleteArm = `If it is not a resource you want to keep, delete ${idShown ? safeId : "it"} in AWS — after confirming it holds nothing you need${replayed ? "" : ", since Retain is what kept it"} — and re-deploy.`;
43258
- let canImport;
43259
- try {
43260
- canImport = typeof providerRegistry.getProvider(error.resourceType).import === "function";
43261
- } catch {
43262
- canImport = false;
43263
- }
43264
- const commandNamesTheRightResource = safeId === physicalId && safeStack === stackName && safeLogicalId === logicalId;
43265
- const importableTarget = !stackName.includes("~");
43266
- if (!canImport || !commandNamesTheRightResource || !importableTarget) return `${diagnosis} ${!canImport ? `cdkd cannot adopt ${displaySafe(error.resourceType, { asciiOnly: true })} back into state (its provider implements no import)` : !importableTarget ? `this is a nested-stack child, whose stack name cdkd import cannot resolve` : `cdkd cannot render an import command that provably names this resource`}, so the way forward is to delete it. ${deleteArm}`;
43267
- const adopt = pasteableCommand("cdkd import", [{
43268
- value: stackName,
43269
- hole: "stack"
43270
- }, {
43271
- flag: "--resource",
43272
- value: `${logicalId}=${physicalId}`,
43273
- hole: "logicalId=physicalId"
43274
- }]);
43275
- return `${diagnosis} To recover, adopt it back into state instead of re-creating it, with the command below (a selective import merges into existing state and needs no --force while the resource is absent from it). CONFIRM IT IS YOURS FIRST — a name cdkd derives is predictable, so for a globally-namespaced type it can belong to another account, and the same stack deployed in another region derives the same name. ${deleteArm}${adopt.withheld.length === 0 ? "" : " The command below prints a quoted hole in place of a value cdkd will not name on a command line; replace it whole, quotes included, with your stack name or '<logicalId>=<name>', shell-quoted."}\nAdopt with: ${adopt.command}`;
44168
+ return applyDefaultNameForFallback(logicalId, resourceType, resolvedProps, underivable);
43276
44169
  }
43277
44170
 
43278
44171
  //#endregion
@@ -43449,6 +44342,7 @@ async function provisionCreate(engine, logicalId, change, stateResources, stackN
43449
44342
  const recordedProperties = propertiesToRecord(resolvedProps, result, resourceType, createDecision.provisionedBy);
43450
44343
  stateResources[logicalId] = {
43451
44344
  physicalId: result.physicalId,
44345
+ ...getCurrentStackInstanceId() !== void 0 && nameGenerationField(currentNameGeneration(logicalId) ?? 0),
43452
44346
  resourceType,
43453
44347
  properties: recordedProperties,
43454
44348
  ...acceptedCreateOnlyDropsField(recordedProperties, resourceType, createDecision.provisionedBy, "new-resource"),
@@ -43475,6 +44369,21 @@ async function provisionCreate(engine, logicalId, change, stateResources, stackN
43475
44369
  renderer.removeTask(logicalId);
43476
44370
  engine.logger.info(safeMsg`${createPrefix}${formatResourceLine("created", logicalId, resourceType)}`);
43477
44371
  }
44372
+ async function guardedReplacementCreate(engine, input, create) {
44373
+ const guard = engine.generatedNameGuard;
44374
+ if (input.keepsName === true || guard?.candidate(input.logicalId) === void 0) return create();
44375
+ await refuseUnlicensedGeneratedName(engine, input);
44376
+ guard.noteSent(input.logicalId);
44377
+ let result;
44378
+ try {
44379
+ result = await create();
44380
+ } catch (error) {
44381
+ guard.noteFailed(input.logicalId, error);
44382
+ throw error;
44383
+ }
44384
+ guard.noteReturned(input.logicalId);
44385
+ return result;
44386
+ }
43478
44387
  async function refuseUnlicensedGeneratedName(engine, input) {
43479
44388
  const { logicalId, resourceType } = input;
43480
44389
  const asked = engine.generatedNameGuard?.candidate(logicalId);
@@ -43960,7 +44869,7 @@ var DynamoDBGlobalTableProvider = class {
43960
44869
  const warn = log.warn;
43961
44870
  log.debug(`Creating DynamoDB GlobalTable ${logicalId}`);
43962
44871
  const desiredReplicaTags = refuseMalformedReplicaTags(properties, resourceType, logicalId);
43963
- const tableName = properties["TableName"] || generateResourceName(logicalId, { maxLength: 255 });
44872
+ const tableName = properties["TableName"] || generatedNameFor("AWS::DynamoDB::GlobalTable", logicalId);
43964
44873
  const keySchema = properties["KeySchema"];
43965
44874
  const attributeDefinitions = properties["AttributeDefinitions"];
43966
44875
  if (!keySchema) throw new ProvisioningError(`KeySchema is required for DynamoDB GlobalTable ${logicalId}`, resourceType, logicalId);
@@ -46404,7 +47313,7 @@ function recordedProtectionNote(evidence, flags) {
46404
47313
 
46405
47314
  //#endregion
46406
47315
  //#region src/deployment/deploy-engine/update-replace.ts
46407
- async function updateByReplacement(engine, { change, counts, currentProps, currentResource, dependencies, logicalId, oldResourceType, progress, propertyDrivenReplacement, recreateFlagged, recreateViaCcApi, recreateViaSdkProvider, renderer, resolvedProps, resourceType, stackName, stateResources, template, typeChanged, updateReplacePolicy, updateSecrets, lostWithParent }) {
47316
+ async function updateByReplacement(engine, { change, counts, currentProps, currentResource, dependencies, logicalId, oldResourceType, progress, propertyDrivenReplacement, recreateFlagged, recreateViaCcApi, recreateViaSdkProvider, renderer, resolvedProps, resourceType, stackName, stateResources, template, typeChanged, updateReplacePolicy, updateSecrets, lostWithParent, nameGenerationFields }) {
46408
47317
  const noEchoDeleteValues = await noEchoDeleteValuesFromResolved({
46409
47318
  record: currentResource,
46410
47319
  templateResource: template?.Resources?.[logicalId],
@@ -46479,6 +47388,9 @@ async function updateByReplacement(engine, { change, counts, currentProps, curre
46479
47388
  }
46480
47389
  createResult = await createFirstThenDeleteOld(engine.replacementRun, engine.replacementDeps(), {
46481
47390
  retainOld,
47391
+ stackName,
47392
+ createdVia: replaceDecision.provisionedBy,
47393
+ resolvedProps,
46482
47394
  logicalId,
46483
47395
  resourceType,
46484
47396
  oldResourceType,
@@ -46530,17 +47442,27 @@ async function updateByReplacement(engine, { change, counts, currentProps, curre
46530
47442
  if (recreateSkipReason !== void 0) throw new Error(deleteSkippedMessage(logicalId, currentResource.physicalId, recreateSkipReason, `during ${recreateFlagName}`));
46531
47443
  engine.logger.info(safeMsg` ${green("✓")} Old resource deleted`);
46532
47444
  engine.replacementRun.oldDeletedBeforeCreate.add(logicalId);
47445
+ await oldDeleteProvider.waitForNameReleased?.(logicalId, currentResource.physicalId, oldResourceType, {
47446
+ isInterrupted: () => engine.userInterrupted,
47447
+ maskSecrets: createSecretMasker(updateSecrets)
47448
+ });
46533
47449
  }
46534
47450
  engine.logger.info(safeMsg` Creating new ${logicalId}...`);
46535
- createResult = await withRetry(() => engine.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replaceProvider), logicalId, {
47451
+ createResult = await guardedReplacementCreate(engine, {
47452
+ logicalId,
47453
+ resourceType,
47454
+ stackName,
47455
+ createdVia: replaceDecision.provisionedBy,
47456
+ resolvedProps
47457
+ }, () => withRetry(() => engine.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replaceProvider, true), logicalId, {
46536
47458
  maxRetries: 8,
46537
47459
  initialDelayMs: 2e3,
46538
47460
  maxDelayMs: 1e4,
46539
47461
  logger: engine.maskingRetryLoggerFor(updateSecrets),
46540
- isInterrupted: () => engine.interrupted,
46541
- onInterrupted: () => new InterruptedError(engine.interruptCause ?? "user"),
47462
+ isInterrupted: () => engine.userInterrupted,
47463
+ onInterrupted: () => new InterruptedError("user"),
46542
47464
  isRetryable: isRecreateRetryableError
46543
- });
47465
+ }));
46544
47466
  if (equalIdIsSameResource && updateReplacePolicy === "Retain" && createResult.physicalId === currentResource.physicalId) throw new CdkdError(safeMsg`${logicalId} (${resourceType}) recreate returned the existing resource ` + safeMsg`(${currentResource.physicalId}) instead of creating a new one — its Create ` + "API is name-idempotent — and UpdateReplacePolicy: Retain means the old resource was never destroyed, so the new properties were not applied. Rename the resource in your CDK code (or remove the explicit physical name) so the recreate can produce a genuinely new resource.", "NAMED_REPLACEMENT_IDEMPOTENT_CREATE");
46545
47467
  } else {
46546
47468
  engine.logger.info(safeMsg` Creating new ${logicalId}...`);
@@ -46550,7 +47472,14 @@ async function updateByReplacement(engine, { change, counts, currentProps, curre
46550
47472
  engine.logger.info(safeMsg` ${logicalId} went with ${lostWithParent}, which was destroyed and re-created under the same id: re-creating it`);
46551
47473
  }
46552
47474
  try {
46553
- createResult = await engine.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replaceProvider);
47475
+ createResult = await guardedReplacementCreate(engine, {
47476
+ logicalId,
47477
+ resourceType,
47478
+ stackName,
47479
+ createdVia: replaceDecision.provisionedBy,
47480
+ resolvedProps,
47481
+ keepsName: lostWithParent !== void 0
47482
+ }, () => engine.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replaceProvider.create(logicalId, resourceType, replaceProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replaceProvider, lostWithParent !== void 0));
46554
47483
  } catch (createError) {
46555
47484
  const createMsg = displayAwsMessage(maskSecretsInText(describeAwsFailure(createError).detail, updateSecrets));
46556
47485
  const createSentence = createMsg.endsWith(".") ? createMsg.slice(0, -1) : createMsg;
@@ -46569,7 +47498,7 @@ async function updateByReplacement(engine, { change, counts, currentProps, curre
46569
47498
  createType: resourceType,
46570
47499
  holderType: oldResourceType,
46571
47500
  requested: replaceProps,
46572
- generated: applyDefaultNameForFallback(logicalId, resourceType, resolvedProps),
47501
+ generated: applyDefaultNameForFallback(logicalId, resourceType, resolvedProps, "omit"),
46573
47502
  recorded: currentResource.properties,
46574
47503
  observed: currentResource.observedProperties,
46575
47504
  physicalId: currentResource.physicalId,
@@ -46580,7 +47509,13 @@ async function updateByReplacement(engine, { change, counts, currentProps, curre
46580
47509
  });
46581
47510
  if (!holder.holds) {
46582
47511
  const flagClause = engine.options.replace === true ? ` --replace was NOT applied and nothing was deleted.` : updateReplacePolicy === "Retain" ? " Nothing was deleted. UpdateReplacePolicy: Retain keeps the resource being replaced in place; removing it and re-running with `cdkd deploy --replace` would refuse the same way rather than delete it." : " Nothing was deleted, and `cdkd deploy --replace` would refuse the same way rather than delete it.";
46583
- throw markNonRetryable(new CdkdError(maskSecretsInText(`${displaySafe(logicalId)} (${displaySafe(resourceType)}) requires replacement, but the create-first attempt collided: ${holder.diagnosis} — ` + (holder.known ? "so another resource holds the colliding name (an orphan of an earlier attempt, or one made outside this stack), and deleting the resource being replaced would destroy it and collide again." + flagClause + " Remove or rename the resource holding that name if it is yours, then re-run the deploy." : "so if another resource holds it (an orphan of an earlier attempt, or one made outside this stack), deleting the resource being replaced would destroy it and collide again." + flagClause + " Remove or rename whatever holds that name if it is yours — if that is the resource being replaced itself, delete it by hand — then re-run the deploy.") + ` Underlying collision: ${createMsg}`, updateSecrets), "NAMED_REPLACEMENT_COLLISION", createError instanceof Error ? createError : void 0));
47512
+ throw markNonRetryable(new CdkdError(maskSecretsInText(`${displaySafe(logicalId)} (${displaySafe(resourceType)}) requires replacement, but the create-first attempt collided: ${holder.diagnosis} — ` + (holder.known ? "so another resource holds the colliding name (an orphan of an earlier attempt, or one made outside this stack), and deleting the resource being replaced would destroy it and collide again." + flagClause + " Remove or rename the resource holding that name if it is yours, then re-run the deploy." : "so if another resource holds it (an orphan of an earlier attempt, or one made outside this stack), deleting the resource being replaced would destroy it and collide again." + flagClause + " Remove or rename whatever holds that name if it is yours — if that is the resource being replaced itself, delete it by hand — then re-run the deploy.") + generatedReplacementHolderAdvice({
47513
+ stackName,
47514
+ logicalId,
47515
+ change: nameChange,
47516
+ oldPhysicalId: currentResource.physicalId,
47517
+ mask: (value) => maskSecretsInText(value, unionOfSecretBags([updateSecrets, printingSecretsFor(engine.secretsRun, logicalId)]))
47518
+ }) + ` Underlying collision: ${createMsg}`, updateSecrets), "NAMED_REPLACEMENT_COLLISION", createError instanceof Error ? createError : void 0));
46584
47519
  }
46585
47520
  if (updateReplacePolicy === "Retain") throw new CdkdError(safeMsg`${logicalId} (${resourceType}) requires replacement, but its physical name ` + `is still held by the existing resource AND UpdateReplacePolicy: Retain ` + safeMsg`pins that resource in place. ${nameOrigin.descriptor}. ` + safeMsg`${nameOrigin.remedy} — with Retain, the old resource keeps the name, so a ` + `same-name replacement can never proceed.`, "NAMED_REPLACEMENT_COLLISION");
46586
47521
  if (engine.options.replace !== true) throw new CdkdError(safeMsg`${logicalId} (${resourceType}) requires replacement, but the create-first ` + safeMsg`attempt collided with the existing resource: ${createSentence}. ` + safeMsg`${nameOrigin.descriptor}, so the CloudFormation-style safe replacement ` + "order (create the new resource before deleting the old) cannot reuse the occupied name — CloudFormation refuses this shape with \"cannot update a stack when a custom-named resource requires replacing\". " + safeMsg`${nameOrigin.remedy}, or re-run with \`cdkd deploy --replace\` to delete ` + "the old resource FIRST and recreate it under the same name (the resource is briefly unavailable while it is recreated).", "NAMED_REPLACEMENT_COLLISION");
@@ -46620,6 +47555,7 @@ async function updateByReplacement(engine, { change, counts, currentProps, curre
46620
47555
  const recordedReplacementProperties = propertiesToRecord(resolvedProps, createResult, resourceType, replaceDecision.provisionedBy);
46621
47556
  stateResources[logicalId] = {
46622
47557
  physicalId: createResult.physicalId,
47558
+ ...nameGenerationFields,
46623
47559
  resourceType,
46624
47560
  properties: recordedReplacementProperties,
46625
47561
  ...acceptedCreateOnlyDropsField(recordedReplacementProperties, resourceType, replaceDecision.provisionedBy, "new-resource"),
@@ -46688,7 +47624,7 @@ async function updateInPlace(engine, { conditions, counts, currentProps, current
46688
47624
  engine.logger.info(message);
46689
47625
  }
46690
47626
  const updateProvider = updateDecision.provider;
46691
- const updateProps = updateDecision.provisionedBy === "cc-api" ? withoutGeneratedFallbackName(resourceType, resolvedProps, preparePropertiesForCcApi(engine.providerRegistry, resourceType, resolvedProps, logicalId)) : resolvedProps;
47627
+ const updateProps = updateDecision.provisionedBy === "cc-api" ? withoutGeneratedFallbackName(resourceType, resolvedProps, preparePropertiesForCcApi(engine.providerRegistry, resourceType, resolvedProps, logicalId, "omit")) : resolvedProps;
46692
47628
  const { previous: previousWithSecretsDropped, dropped: droppedPrincipalKinds } = withUnchangedSecretPrincipalLists(resourceType, currentResource.physicalId, noEchoHeldPaths.size === 0 ? currentPropsAsWritten : {
46693
47629
  ...currentPropsAsWritten,
46694
47630
  ...Object.fromEntries([...noEchoHeldPaths].filter((path) => Object.prototype.hasOwnProperty.call(updateProps, path)).map((path) => [path, updateProps[path]]))
@@ -46711,6 +47647,7 @@ async function updateInPlace(engine, { conditions, counts, currentProps, current
46711
47647
  let result;
46712
47648
  let resultProvisionedBy = updateDecision.provisionedBy;
46713
47649
  let captureProvider = updateProvider;
47650
+ let replacedAtGeneration;
46714
47651
  const inlinePolicyClaimed = engine.inlinePolicyClaimedFor(resourceType, logicalId, stateResources);
46715
47652
  try {
46716
47653
  result = await engine.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => updateProvider.update(logicalId, currentResource.physicalId, resourceType, removal.properties, previousForUpdate, {
@@ -46728,153 +47665,181 @@ async function updateInPlace(engine, { conditions, counts, currentProps, current
46728
47665
  const ccUnsupported = isUpdateUnsupportedError(updateError, logicalId);
46729
47666
  const replaceOptIn = updateError instanceof ResourceUpdateNotSupportedError && engine.options.replace === true;
46730
47667
  if (ccUnsupported || replaceOptIn) {
46731
- const retainOldOnReplace = updateReplacePolicy === "Retain";
46732
- const statefulReason = retainOldOnReplace ? null : isStatefulRecreateTargetForReplace(resourceType, currentProps, currentResource.observedProperties);
46733
- if (statefulReason && engine.options.forceStatefulRecreation !== true) {
46734
- const protection = recordedProtectionEvidence(resourceType, currentProps, currentResource.observedProperties, engine.stackRegion);
46735
- throw markNonRetryable(new CdkdError(replaceOptIn ? safeMsg`--replace would DELETE + CREATE the stateful resource ${logicalId} ` + safeMsg`(${resourceType}) — ${renderStatefulReason(statefulReason)}. ` + (protection ? safeMsg`${recordedProtectionNote(protection, "--replace --force-stateful-recreation")} ` + `Or change the resource's definition to avoid the immutable-property change.` : "Re-run with --force-stateful-recreation to confirm the data loss, or change the resource definition to avoid the immutable-property change.") : safeMsg`${logicalId} (${resourceType}) cannot be updated in place by the ` + "provisioning layer it routes through, so applying this change would DELETE + CREATE it — but it is a stateful resource: " + safeMsg`${renderStatefulReason(statefulReason)}. ` + (protection ? safeMsg`${recordedProtectionNote(protection, "--force-stateful-recreation")} ` + `Or change the resource's definition to avoid the update.` : "Re-run with --force-stateful-recreation to confirm the data loss, or change the resource definition to avoid the update."), "STATEFUL_REPLACE_BLOCKED", updateError instanceof Error ? updateError : void 0));
46736
- }
46737
- const replDecision = engine.providerRegistry.getProviderFor({
46738
- resourceType,
46739
- properties: resolvedProps,
46740
- previousProperties: currentResource.properties
46741
- });
46742
- const replProvider = replDecision.provider;
46743
- const replProps = replDecision.provisionedBy === "cc-api" ? preparePropertiesForCcApi(engine.providerRegistry, resourceType, resolvedProps, logicalId) : resolvedProps;
46744
- const fallbackNameChange = await checkedReplacementNameChange(engine.replacementDeps(), {
46745
- logicalId,
46746
- resourceType,
46747
- oldResourceType: resourceType,
46748
- stackName,
46749
- currentResource,
46750
- desiredProperties: resolvedProps,
46751
- createProvider: replProvider,
46752
- createdVia: replDecision.provisionedBy,
46753
- createProps: replProps,
46754
- secrets: updateSecrets
46755
- });
46756
- const createFirst = !retainOldOnReplace && fallbackNameChange !== void 0;
46757
- const noEchoDeleteValues = await noEchoDeleteValuesFromResolved({
46758
- record: currentResource,
46759
- templateResource: template?.Resources?.[logicalId],
46760
- resolvedProperties: resolvedProps,
46761
- noEchoParameters: noEchoPositionSources(engine.noEchoRun, stateResources, template)?.parameters ?? /* @__PURE__ */ new Set(),
46762
- conditions: engine.noEchoRun.noEchoConditions,
46763
- secrets: updateSecrets,
46764
- inputSources: template && maskedInputSources(engine.resolverContextDeps(), template, stateResources, engine.noEchoRun.noEchoConditions, stackName)
46765
- });
46766
- engine.logger.info(retainOldOnReplace ? safeMsg`UPDATE not supported for ${logicalId} (${resourceType}), replacing ` + `(CREATE only — UpdateReplacePolicy: Retain keeps the old resource)` : createFirst ? safeMsg`UPDATE not supported for ${logicalId} (${resourceType}), replacing (CREATE → DELETE — the new name differs from the old resource's)` : safeMsg`UPDATE not supported for ${logicalId} (${resourceType}), replacing (DELETE → CREATE)`);
46767
- if (retainOldOnReplace) await noteRetainedResource(resourceType, logicalId);
46768
- if (!retainOldOnReplace && !createFirst) {
46769
- const fallbackUpdateReplacePolicy = template?.Resources?.[logicalId]?.UpdateReplacePolicy ?? currentResource.updateReplacePolicy;
46770
- const fallbackFinalSnapshotId = await prepareFinalSnapshotForDelete(engine.replacementDeps(), logicalId, resourceType, currentResource, fallbackUpdateReplacePolicy);
46771
- let fallbackDeleteResult = void 0;
46772
- try {
46773
- fallbackDeleteResult = await withPrintingSecrets(updateSecrets, () => updateProvider.delete(logicalId, currentResource.physicalId, resourceType, currentProps, {
46774
- expectedRegion: engine.stackRegion,
46775
- forceDataDelete: engine.options.forceStatefulRecreation === true,
46776
- ...fallbackFinalSnapshotId !== void 0 && { finalSnapshotIdentifier: fallbackFinalSnapshotId },
46777
- ...replacementDeleteContext(engine.replacementDeps(), fallbackUpdateReplacePolicy),
46778
- recordedAttributes: currentResource.attributes,
46779
- recordedNoEchoLeaves: currentResource.noEchoLeaves,
46780
- ...noEchoDeleteValues !== void 0 && { noEchoDeleteValues },
46781
- maskSecrets: createUnionSecretMasker([updateSecrets, secretNameBagFor(engine.secretsRun, logicalId)])
46782
- }));
46783
- } catch (deleteError) {
46784
- const deleteMsg = describeAwsFailure(deleteError).detail;
46785
- if (!isWaitAbandonedError(deleteError) && !isInterruptedWaitError(deleteError) && !isMarkedNonRetryable(deleteError) && (deleteMsg.includes("does not exist") || deleteMsg.includes("not found") || deleteMsg.includes("NotFound"))) engine.logger.debug(safeMsg`Old resource ${logicalId} already gone, proceeding with CREATE`);
46786
- else throw deleteError;
47668
+ const fallbackStackInstanceId = getCurrentStackInstanceId();
47669
+ const fallbackGeneration = fallbackStackInstanceId === void 0 ? void 0 : nextNameGeneration(currentResource, logicalId, fallbackStackInstanceId);
47670
+ if (fallbackGeneration !== void 0) engine.replacementRun.attemptedNameGeneration.set(logicalId, fallbackGeneration);
47671
+ const replaceFallback = async () => {
47672
+ const retainOldOnReplace = updateReplacePolicy === "Retain";
47673
+ const statefulReason = retainOldOnReplace ? null : isStatefulRecreateTargetForReplace(resourceType, currentProps, currentResource.observedProperties);
47674
+ if (statefulReason && engine.options.forceStatefulRecreation !== true) {
47675
+ const protection = recordedProtectionEvidence(resourceType, currentProps, currentResource.observedProperties, engine.stackRegion);
47676
+ throw markNonRetryable(new CdkdError(replaceOptIn ? safeMsg`--replace would DELETE + CREATE the stateful resource ${logicalId} ` + safeMsg`(${resourceType}) — ${renderStatefulReason(statefulReason)}. ` + (protection ? safeMsg`${recordedProtectionNote(protection, "--replace --force-stateful-recreation")} ` + `Or change the resource's definition to avoid the immutable-property change.` : "Re-run with --force-stateful-recreation to confirm the data loss, or change the resource definition to avoid the immutable-property change.") : safeMsg`${logicalId} (${resourceType}) cannot be updated in place by the ` + "provisioning layer it routes through, so applying this change would DELETE + CREATE it — but it is a stateful resource: " + safeMsg`${renderStatefulReason(statefulReason)}. ` + (protection ? safeMsg`${recordedProtectionNote(protection, "--force-stateful-recreation")} ` + `Or change the resource's definition to avoid the update.` : "Re-run with --force-stateful-recreation to confirm the data loss, or change the resource definition to avoid the update."), "STATEFUL_REPLACE_BLOCKED", updateError instanceof Error ? updateError : void 0));
46787
47677
  }
46788
- reportDeleteGuards(fallbackDeleteResult, {
46789
- physicalId: currentResource.physicalId,
47678
+ const replDecision = engine.providerRegistry.getProviderFor({
46790
47679
  resourceType,
46791
- provisionedBy: updateDecision.provisionedBy
47680
+ properties: resolvedProps,
47681
+ previousProperties: currentResource.properties
46792
47682
  });
46793
- const fallbackSkipReason = deleteSkipReason(fallbackDeleteResult);
46794
- if (fallbackSkipReason !== void 0) throw new Error(deleteSkippedMessage(logicalId, currentResource.physicalId, fallbackSkipReason, "during the UPDATE-not-supported replacement"));
46795
- engine.replacementRun.oldDeletedBeforeCreate.add(logicalId);
46796
- }
46797
- let retainedSurvivorReason;
46798
- let createResult;
46799
- try {
46800
- createResult = createFirst && fallbackNameChange !== void 0 ? await createFirstThenDeleteOld(engine.replacementRun, engine.replacementDeps(), {
47683
+ const replProvider = replDecision.provider;
47684
+ const replProps = replDecision.provisionedBy === "cc-api" ? preparePropertiesForCcApi(engine.providerRegistry, resourceType, resolvedProps, logicalId) : resolvedProps;
47685
+ const fallbackNameChange = await checkedReplacementNameChange(engine.replacementDeps(), {
46801
47686
  logicalId,
46802
47687
  resourceType,
46803
47688
  oldResourceType: resourceType,
47689
+ stackName,
46804
47690
  currentResource,
47691
+ desiredProperties: resolvedProps,
46805
47692
  createProvider: replProvider,
47693
+ createdVia: replDecision.provisionedBy,
46806
47694
  createProps: replProps,
46807
- deleteProvider: updateProvider,
46808
- deleteProvisionedBy: updateDecision.provisionedBy,
46809
- deleteProperties: currentProps,
47695
+ secrets: updateSecrets
47696
+ });
47697
+ const createFirst = !retainOldOnReplace && fallbackNameChange !== void 0;
47698
+ const noEchoDeleteValues = await noEchoDeleteValuesFromResolved({
47699
+ record: currentResource,
47700
+ templateResource: template?.Resources?.[logicalId],
47701
+ resolvedProperties: resolvedProps,
47702
+ noEchoParameters: noEchoPositionSources(engine.noEchoRun, stateResources, template)?.parameters ?? /* @__PURE__ */ new Set(),
47703
+ conditions: engine.noEchoRun.noEchoConditions,
46810
47704
  secrets: updateSecrets,
46811
- change: fallbackNameChange,
46812
- equalIdIsSameResource: !equalIdNamesDifferentResources({
46813
- resourceType,
47705
+ inputSources: template && maskedInputSources(engine.resolverContextDeps(), template, stateResources, engine.noEchoRun.noEchoConditions, stackName)
47706
+ });
47707
+ engine.logger.info(retainOldOnReplace ? safeMsg`UPDATE not supported for ${logicalId} (${resourceType}), replacing ` + `(CREATE only — UpdateReplacePolicy: Retain keeps the old resource)` : createFirst ? safeMsg`UPDATE not supported for ${logicalId} (${resourceType}), replacing (CREATE → DELETE — the new name differs from the old resource's)` : safeMsg`UPDATE not supported for ${logicalId} (${resourceType}), replacing (DELETE → CREATE)`);
47708
+ if (retainOldOnReplace) await noteRetainedResource(resourceType, logicalId);
47709
+ if (!retainOldOnReplace && !createFirst) {
47710
+ const fallbackUpdateReplacePolicy = template?.Resources?.[logicalId]?.UpdateReplacePolicy ?? currentResource.updateReplacePolicy;
47711
+ const fallbackFinalSnapshotId = await prepareFinalSnapshotForDelete(engine.replacementDeps(), logicalId, resourceType, currentResource, fallbackUpdateReplacePolicy);
47712
+ let fallbackDeleteResult = void 0;
47713
+ try {
47714
+ fallbackDeleteResult = await withPrintingSecrets(updateSecrets, () => updateProvider.delete(logicalId, currentResource.physicalId, resourceType, currentProps, {
47715
+ expectedRegion: engine.stackRegion,
47716
+ forceDataDelete: engine.options.forceStatefulRecreation === true,
47717
+ ...fallbackFinalSnapshotId !== void 0 && { finalSnapshotIdentifier: fallbackFinalSnapshotId },
47718
+ ...replacementDeleteContext(engine.replacementDeps(), fallbackUpdateReplacePolicy),
47719
+ recordedAttributes: currentResource.attributes,
47720
+ recordedNoEchoLeaves: currentResource.noEchoLeaves,
47721
+ ...noEchoDeleteValues !== void 0 && { noEchoDeleteValues },
47722
+ maskSecrets: createUnionSecretMasker([updateSecrets, secretNameBagFor(engine.secretsRun, logicalId)])
47723
+ }));
47724
+ } catch (deleteError) {
47725
+ const deleteMsg = describeAwsFailure(deleteError).detail;
47726
+ if (!isWaitAbandonedError(deleteError) && !isInterruptedWaitError(deleteError) && !isMarkedNonRetryable(deleteError) && (deleteMsg.includes("does not exist") || deleteMsg.includes("not found") || deleteMsg.includes("NotFound"))) engine.logger.debug(safeMsg`Old resource ${logicalId} already gone, proceeding with CREATE`);
47727
+ else throw deleteError;
47728
+ }
47729
+ reportDeleteGuards(fallbackDeleteResult, {
46814
47730
  physicalId: currentResource.physicalId,
46815
- oldProperties: currentResource.properties,
46816
- newProperties: resolvedProps
46817
- }),
46818
- snapshotPolicy: template?.Resources?.[logicalId]?.UpdateReplacePolicy ?? currentResource.updateReplacePolicy,
46819
- deletePolicy: template?.Resources?.[logicalId]?.UpdateReplacePolicy ?? currentResource.updateReplacePolicy,
46820
- trigger: "the provisioning layer cannot update it in place",
46821
- noEchoDeleteValues
46822
- }) : await engine.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replProvider.create(logicalId, resourceType, replProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replProvider);
46823
- } catch (createError) {
46824
- if (createFirst) throw createError;
46825
- if (!retainOldOnReplace) {
46826
- const shownSecrets = unionOfSecretBags([updateSecrets, printingSecretsFor(engine.secretsRun, logicalId)]);
46827
- throw new Error(safeMsg`Failed to create ${maskSecretsInText(logicalId, shownSecrets)} after the ` + safeMsg`UPDATE-not-supported replacement: the old resource (${maskSecretsInText(currentResource.physicalId, shownSecrets)}) ` + safeMsg`is now gone. Re-run the deploy to create it fresh. Cause: ${asIsMessage(maskSecretsInText(describeAwsFailure(createError).detail, shownSecrets))}`, { cause: createError instanceof Error ? createError : void 0 });
47731
+ resourceType,
47732
+ provisionedBy: updateDecision.provisionedBy
47733
+ });
47734
+ const fallbackSkipReason = deleteSkipReason(fallbackDeleteResult);
47735
+ if (fallbackSkipReason !== void 0) throw new Error(deleteSkippedMessage(logicalId, currentResource.physicalId, fallbackSkipReason, "during the UPDATE-not-supported replacement"));
47736
+ engine.replacementRun.oldDeletedBeforeCreate.add(logicalId);
47737
+ await updateProvider.waitForNameReleased?.(logicalId, currentResource.physicalId, resourceType, {
47738
+ isInterrupted: () => engine.userInterrupted,
47739
+ maskSecrets: createSecretMasker(updateSecrets)
47740
+ });
46828
47741
  }
46829
- if (!isNameCollisionErrorFrom(createError, logicalId)) throw createError;
46830
- const nameHeldElsewhere = replacementRequestsDifferentName({
46831
- oldResourceType: resourceType,
46832
- newResourceType: resourceType,
46833
- desiredProperties: resolvedProps,
46834
- recorded: currentResource.properties,
46835
- observed: currentResource.observedProperties,
46836
- physicalId: currentResource.physicalId
46837
- });
46838
- if (nameHeldElsewhere !== void 0) throw markNonRetryable(new CdkdError(safeMsg`${logicalId} (${resourceType}) requires replacement because the ` + `provisioning layer cannot update it in place, but the create collided. ` + safeMsg`${renderNameHeldElsewhere(nameHeldElsewhere)} — so removing ` + "UpdateReplacePolicy: Retain would delete this resource and still collide. Choose a name no other resource holds, or delete the resource holding it if it is yours.", "NAMED_REPLACEMENT_COLLISION", createError instanceof Error ? createError : void 0));
46839
- const nameOrigin = replacementNameOrigin(logicalId, currentResource.physicalId);
46840
- throw markNonRetryable(new CdkdError(safeMsg`${logicalId} (${resourceType}) requires replacement because the ` + "provisioning layer cannot update it in place — but its physical name is still held by the existing resource AND UpdateReplacePolicy: Retain pins that resource in place. " + safeMsg`${nameOrigin.descriptor}. ${nameOrigin.remedy} — with Retain, the old ` + "resource keeps the name, so a same-name replacement can never proceed. Removing UpdateReplacePolicy: Retain lets cdkd delete the old resource first, which destroys it and any data it holds.", "NAMED_REPLACEMENT_COLLISION", createError instanceof Error ? createError : void 0));
46841
- }
46842
- if (!retainOldOnReplace && !createFirst && createResult.physicalId === currentResource.physicalId && !equalIdNamesDifferentResources({
46843
- resourceType,
46844
- physicalId: currentResource.physicalId,
46845
- oldProperties: currentResource.properties,
46846
- newProperties: resolvedProps
46847
- })) engine.replacementRun.recreatedUnderSameId.add(logicalId);
46848
- if (retainOldOnReplace) {
46849
- if (createResult.physicalId === currentResource.physicalId && !equalIdNamesDifferentResources({
47742
+ let retainedSurvivorReason;
47743
+ let createResult;
47744
+ try {
47745
+ createResult = createFirst && fallbackNameChange !== void 0 ? await createFirstThenDeleteOld(engine.replacementRun, engine.replacementDeps(), {
47746
+ stackName,
47747
+ createdVia: replDecision.provisionedBy,
47748
+ resolvedProps,
47749
+ logicalId,
47750
+ resourceType,
47751
+ oldResourceType: resourceType,
47752
+ currentResource,
47753
+ createProvider: replProvider,
47754
+ createProps: replProps,
47755
+ deleteProvider: updateProvider,
47756
+ deleteProvisionedBy: updateDecision.provisionedBy,
47757
+ deleteProperties: currentProps,
47758
+ secrets: updateSecrets,
47759
+ change: fallbackNameChange,
47760
+ equalIdIsSameResource: !equalIdNamesDifferentResources({
47761
+ resourceType,
47762
+ physicalId: currentResource.physicalId,
47763
+ oldProperties: currentResource.properties,
47764
+ newProperties: resolvedProps
47765
+ }),
47766
+ snapshotPolicy: template?.Resources?.[logicalId]?.UpdateReplacePolicy ?? currentResource.updateReplacePolicy,
47767
+ deletePolicy: template?.Resources?.[logicalId]?.UpdateReplacePolicy ?? currentResource.updateReplacePolicy,
47768
+ trigger: "the provisioning layer cannot update it in place",
47769
+ noEchoDeleteValues
47770
+ }) : await guardedReplacementCreate(engine, {
47771
+ logicalId,
47772
+ resourceType,
47773
+ stackName,
47774
+ createdVia: replDecision.provisionedBy,
47775
+ resolvedProps
47776
+ }, () => engine.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => replProvider.create(logicalId, resourceType, replProps, { maskSecrets: createSecretMasker(updateSecrets) })), logicalId, void 0, void 0, replProvider, !retainOldOnReplace));
47777
+ } catch (createError) {
47778
+ if (createFirst) throw createError;
47779
+ if (!retainOldOnReplace) {
47780
+ const shownSecrets = unionOfSecretBags([updateSecrets, printingSecretsFor(engine.secretsRun, logicalId)]);
47781
+ throw new Error(safeMsg`Failed to create ${maskSecretsInText(logicalId, shownSecrets)} after the ` + safeMsg`UPDATE-not-supported replacement: the old resource (${maskSecretsInText(currentResource.physicalId, shownSecrets)}) ` + safeMsg`is now gone. Re-run the deploy to create it fresh. Cause: ${asIsMessage(maskSecretsInText(describeAwsFailure(createError).detail, shownSecrets))}`, { cause: createError instanceof Error ? createError : void 0 });
47782
+ }
47783
+ if (!isNameCollisionErrorFrom(createError, logicalId)) throw createError;
47784
+ const nameHeldElsewhere = replacementRequestsDifferentName({
47785
+ oldResourceType: resourceType,
47786
+ newResourceType: resourceType,
47787
+ desiredProperties: resolvedProps,
47788
+ recorded: currentResource.properties,
47789
+ observed: currentResource.observedProperties,
47790
+ physicalId: currentResource.physicalId
47791
+ });
47792
+ if (nameHeldElsewhere !== void 0) throw markNonRetryable(new CdkdError(safeMsg`${logicalId} (${resourceType}) requires replacement because the ` + `provisioning layer cannot update it in place, but the create collided. ` + safeMsg`${renderNameHeldElsewhere(nameHeldElsewhere)} — so removing ` + "UpdateReplacePolicy: Retain would delete this resource and still collide. Choose a name no other resource holds, or delete the resource holding it if it is yours.", "NAMED_REPLACEMENT_COLLISION", createError instanceof Error ? createError : void 0));
47793
+ const nameOrigin = replacementNameOrigin(logicalId, currentResource.physicalId);
47794
+ throw markNonRetryable(new CdkdError(safeMsg`${logicalId} (${resourceType}) requires replacement because the ` + "provisioning layer cannot update it in place — but its physical name is still held by the existing resource AND UpdateReplacePolicy: Retain pins that resource in place. " + safeMsg`${nameOrigin.descriptor}. ${nameOrigin.remedy} — with Retain, the old ` + "resource keeps the name, so a same-name replacement can never proceed. Removing UpdateReplacePolicy: Retain lets cdkd delete the old resource first, which destroys it and any data it holds.", "NAMED_REPLACEMENT_COLLISION", createError instanceof Error ? createError : void 0));
47795
+ }
47796
+ if (!retainOldOnReplace && !createFirst && createResult.physicalId === currentResource.physicalId && !equalIdNamesDifferentResources({
46850
47797
  resourceType,
46851
47798
  physicalId: currentResource.physicalId,
46852
47799
  oldProperties: currentResource.properties,
46853
47800
  newProperties: resolvedProps
46854
- })) {
46855
- const idempotentNameOrigin = replacementNameOrigin(logicalId, currentResource.physicalId);
46856
- throw markNonRetryable(new CdkdError(safeMsg`${logicalId} (${resourceType}) requires replacement, but its Create ` + `API is name-idempotent: the create returned the existing resource ` + safeMsg`(${currentResource.physicalId}) instead of creating a new one, and ` + `UpdateReplacePolicy: Retain pins that resource in place, so the new ` + safeMsg`properties were not applied. ${idempotentNameOrigin.descriptor}. ` + safeMsg`${idempotentNameOrigin.remedy} — with Retain, the old resource keeps ` + `the name, so a same-name replacement can never proceed.`, "NAMED_REPLACEMENT_IDEMPOTENT_CREATE"));
47801
+ })) engine.replacementRun.recreatedUnderSameId.add(logicalId);
47802
+ if (retainOldOnReplace) {
47803
+ if (createResult.physicalId === currentResource.physicalId && !equalIdNamesDifferentResources({
47804
+ resourceType,
47805
+ physicalId: currentResource.physicalId,
47806
+ oldProperties: currentResource.properties,
47807
+ newProperties: resolvedProps
47808
+ })) {
47809
+ const idempotentNameOrigin = replacementNameOrigin(logicalId, currentResource.physicalId);
47810
+ throw markNonRetryable(new CdkdError(safeMsg`${logicalId} (${resourceType}) requires replacement, but its Create ` + `API is name-idempotent: the create returned the existing resource ` + safeMsg`(${currentResource.physicalId}) instead of creating a new one, and ` + `UpdateReplacePolicy: Retain pins that resource in place, so the new ` + safeMsg`properties were not applied. ${idempotentNameOrigin.descriptor}. ` + safeMsg`${idempotentNameOrigin.remedy} — with Retain, the old resource keeps ` + `the name, so a same-name replacement can never proceed.`, "NAMED_REPLACEMENT_IDEMPOTENT_CREATE"));
47811
+ }
47812
+ engine.replacementRun.retainedOldOnReplacement.add(logicalId);
47813
+ engine.logger.warn(safeMsg` ⚠ ${logicalId} has UpdateReplacePolicy: Retain — the old physical ` + safeMsg`resource (${currentResource.physicalId}) is RETAINED and is no longer ` + "tracked by cdkd: it keeps running and incurring cost, and `cdkd destroy` will not remove it. Delete it yourself once you no longer need its data.");
47814
+ retainedSurvivorReason = `UpdateReplacePolicy: Retain kept the old ${resourceType} (${currentResource.physicalId}), now untracked by cdkd`;
46857
47815
  }
46858
- engine.replacementRun.retainedOldOnReplacement.add(logicalId);
46859
- engine.logger.warn(safeMsg` ⚠ ${logicalId} has UpdateReplacePolicy: Retain — the old physical ` + safeMsg`resource (${currentResource.physicalId}) is RETAINED and is no longer ` + "tracked by cdkd: it keeps running and incurring cost, and `cdkd destroy` will not remove it. Delete it yourself once you no longer need its data.");
46860
- retainedSurvivorReason = `UpdateReplacePolicy: Retain kept the old ${resourceType} (${currentResource.physicalId}), now untracked by cdkd`;
46861
- }
46862
- const replacementResult = {
46863
- physicalId: createResult.physicalId,
46864
- wasReplaced: true,
46865
- ...createResult.attributes && { attributes: createResult.attributes },
46866
- ...createResult.noEchoAttributes === true && { noEchoAttributes: true },
46867
- ...createResult.noEchoAttributeNames && { noEchoAttributeNames: createResult.noEchoAttributeNames },
46868
- ...createResult.secretNamedAttributeNames && { secretNamedAttributeNames: createResult.secretNamedAttributeNames },
46869
- ...retainedSurvivorReason !== void 0 ? {
46870
- outcome: "partial",
46871
- reason: retainedSurvivorReason
46872
- } : { outcome: "updated" }
47816
+ const replacementResult = {
47817
+ physicalId: createResult.physicalId,
47818
+ wasReplaced: true,
47819
+ ...createResult.attributes && { attributes: createResult.attributes },
47820
+ ...createResult.noEchoAttributes === true && { noEchoAttributes: true },
47821
+ ...createResult.noEchoAttributeNames && { noEchoAttributeNames: createResult.noEchoAttributeNames },
47822
+ ...createResult.secretNamedAttributeNames && { secretNamedAttributeNames: createResult.secretNamedAttributeNames },
47823
+ ...retainedSurvivorReason !== void 0 ? {
47824
+ outcome: "partial",
47825
+ reason: retainedSurvivorReason
47826
+ } : { outcome: "updated" }
47827
+ };
47828
+ if (createResult.effectiveProperties) replacementResult.effectiveProperties = createResult.effectiveProperties;
47829
+ return {
47830
+ result: replacementResult,
47831
+ provisionedBy: replDecision.provisionedBy,
47832
+ captureProvider: replProvider
47833
+ };
46873
47834
  };
46874
- if (createResult.effectiveProperties) replacementResult.effectiveProperties = createResult.effectiveProperties;
46875
- result = replacementResult;
46876
- resultProvisionedBy = replDecision.provisionedBy;
46877
- captureProvider = replProvider;
47835
+ const fallbackOutcome = await (fallbackGeneration === void 0 ? replaceFallback() : withNameGeneration({
47836
+ logicalId,
47837
+ generation: fallbackGeneration
47838
+ }, replaceFallback));
47839
+ result = fallbackOutcome.result;
47840
+ resultProvisionedBy = fallbackOutcome.provisionedBy;
47841
+ captureProvider = fallbackOutcome.captureProvider;
47842
+ replacedAtGeneration = fallbackGeneration;
46878
47843
  } else {
46879
47844
  if (currentResource.provisionedBy !== "cc-api" && updateDecision.ccRouteReason !== void 0 && updateError instanceof Error && !isInterruptedWaitError(updateError) && !isWaitAbandonedError(updateError)) updateError.message += ccAutoRouteUpdateFailureRemedy(logicalId, resourceType, updateDecision.ccRouteReason.properties, engine.options.parentStackInfo !== void 0);
46880
47845
  throw updateError;
@@ -46905,6 +47870,7 @@ async function updateInPlace(engine, { conditions, counts, currentProps, current
46905
47870
  if (result.wasReplaced) engine.noEchoRun.noEchoExactEchoes.delete(logicalId);
46906
47871
  stateResources[logicalId] = {
46907
47872
  physicalId: result.physicalId,
47873
+ ...replacedAtGeneration === void 0 ? nameGenerationCarriedFrom(currentResource) : nameGenerationField(replacedAtGeneration),
46908
47874
  resourceType,
46909
47875
  properties: recordedProperties,
46910
47876
  ...acceptedCreateOnlyDropsField(recordedProperties, resourceType, resultProvisionedBy, dischargedByReplacement ? "new-resource" : "in-place", currentResource),
@@ -47595,30 +48561,39 @@ async function provisionUpdate(engine, logicalId, change, stateResources, stackN
47595
48561
  engine.replacementRun.restoredLostChildren.add(logicalId);
47596
48562
  return outcome;
47597
48563
  };
47598
- if (needsReplacement) return markRestored(await updateByReplacement(engine, {
47599
- change,
47600
- counts,
47601
- currentProps,
47602
- currentResource,
47603
- dependencies,
47604
- logicalId,
47605
- oldResourceType,
47606
- progress,
47607
- propertyDrivenReplacement,
47608
- recreateFlagged,
47609
- recreateViaCcApi,
47610
- recreateViaSdkProvider,
47611
- renderer,
47612
- resolvedProps,
47613
- resourceType,
47614
- stackName,
47615
- stateResources,
47616
- template,
47617
- typeChanged,
47618
- updateReplacePolicy,
47619
- updateSecrets,
47620
- lostWithParent
47621
- }));
48564
+ if (needsReplacement) {
48565
+ const { generation: nextGeneration, fields: nameGenerationFields } = replacementNameGeneration(currentResource, logicalId, getCurrentStackInstanceId(), lostWithParent !== void 0);
48566
+ if (nextGeneration !== void 0) engine.replacementRun.attemptedNameGeneration.set(logicalId, nextGeneration);
48567
+ const replace = () => updateByReplacement(engine, {
48568
+ change,
48569
+ counts,
48570
+ currentProps,
48571
+ currentResource,
48572
+ dependencies,
48573
+ logicalId,
48574
+ oldResourceType,
48575
+ progress,
48576
+ propertyDrivenReplacement,
48577
+ recreateFlagged,
48578
+ recreateViaCcApi,
48579
+ recreateViaSdkProvider,
48580
+ renderer,
48581
+ resolvedProps,
48582
+ resourceType,
48583
+ stackName,
48584
+ stateResources,
48585
+ template,
48586
+ typeChanged,
48587
+ updateReplacePolicy,
48588
+ updateSecrets,
48589
+ lostWithParent,
48590
+ nameGenerationFields
48591
+ });
48592
+ return markRestored(await (nextGeneration === void 0 ? replace() : withNameGeneration({
48593
+ logicalId,
48594
+ generation: nextGeneration
48595
+ }, replace)));
48596
+ }
47622
48597
  const serviceTokenRefusal = serviceTokenUpdateRefusal({
47623
48598
  logicalId,
47624
48599
  resourceType,
@@ -47902,7 +48877,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
47902
48877
  saveChain = saveChain.then(async () => {
47903
48878
  try {
47904
48879
  const partialState = {
47905
- version: 12,
48880
+ version: 13,
47906
48881
  region: engine.stackRegion,
47907
48882
  stackName: currentState.stackName,
47908
48883
  resources: newResources,
@@ -47910,6 +48885,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
47910
48885
  ...exportNamesCarriedFrom(currentState),
47911
48886
  ...skippedOutputsCarriedFrom(currentState),
47912
48887
  ...orphansCarriedFrom(currentState),
48888
+ ...stackInstanceIdCarriedFrom(currentState),
47913
48889
  ...crossStackReadsForPartialSave(currentState, engine.recordedImports, engine.recordedOutputReads, engine.crossStackReadKeyNormalizer()),
47914
48890
  lastModified: Date.now()
47915
48891
  };
@@ -47932,6 +48908,12 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
47932
48908
  const inFlightWrites = /* @__PURE__ */ new Map();
47933
48909
  engine.stackRecordsView = deployStackRecordsView(newResources, currentState.resources, deleteChanges, (logicalId) => startedUpdates.has(logicalId) && !settledUpdates.has(logicalId), () => [...inFlightWrites.values()].map(({ write }) => write));
47934
48910
  engine.replacementRun.deferredReplacedDeletes = /* @__PURE__ */ new Map();
48911
+ engine.replacementRun.supersededHost = currentState;
48912
+ const carriedSuperseded = supersededResourcesOf(currentState).filter((entry) => {
48913
+ if (!isSupersededHeldBySameType(entry, currentState.resources)) return true;
48914
+ removeSuperseded(currentState, entry);
48915
+ return false;
48916
+ });
47935
48917
  try {
47936
48918
  const createUpdateIds = [];
47937
48919
  for (const [id, change] of changes.entries()) {
@@ -48025,6 +49007,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48025
49007
  engine.interrupted = true;
48026
49008
  engine.interruptCause ??= "sibling-failure";
48027
49009
  const refused = isRefusedBeforeApplying(provisionError, logicalId);
49010
+ const attemptedGeneration = change.changeType === "UPDATE" && !refused && !isReplacementNameRefusal(provisionError, logicalId) ? engine.replacementRun.attemptedNameGeneration.get(logicalId) : void 0;
48028
49011
  const statePhysicalId = newResources[logicalId]?.physicalId ?? previousState?.physicalId;
48029
49012
  if (refused && change.changeType === "CREATE" && statePhysicalId === void 0) throw provisionError;
48030
49013
  const createdId = change.changeType === "CREATE" && statePhysicalId === void 0 ? createdBeforeFailure(provisionError, logicalId, change.resourceType) : void 0;
@@ -48056,10 +49039,14 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48056
49039
  deletionPolicy: journaledOrphanPolicy(extractTemplateAttributes(template, logicalId).deletionPolicy)
48057
49040
  },
48058
49041
  ...change.changeType === "UPDATE" && engine.replacementRun.oldDeletedBeforeCreate.has(logicalId) && { oldDeletedBeforeCreate: true },
49042
+ ...attemptedGeneration !== void 0 && { nameGeneration: attemptedGeneration },
49043
+ ...change.changeType === "CREATE" && getCurrentStackInstanceId() !== void 0 && { nameGeneration: currentNameGeneration(logicalId) ?? 0 },
48059
49044
  ...orphanedBy !== void 0 && { replacementOrphaned: engine.replacementRun.oldDeletedBeforeCreate.has(logicalId) ? "delete-first" : "create-first" },
48060
49045
  ...!refused && { attemptedProperties: engine.attemptedResolvedProps.get(logicalId) }
48061
49046
  };
48062
49047
  failedOperations.push(failedOp);
49048
+ const heldNow = newResources[logicalId];
49049
+ if (attemptedGeneration !== void 0 && heldNow !== void 0) newResources[logicalId] = withNameGenerationReached(heldNow, logicalId, attemptedGeneration);
48063
49050
  let replacementOrphanOp;
48064
49051
  if (orphanedBy !== void 0) {
48065
49052
  replacementOrphanOp = {
@@ -48106,7 +49093,8 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48106
49093
  },
48107
49094
  ...change.changeType === "UPDATE" && engine.replacementRun.replacedOldMaySurvive.has(logicalId) && { oldResourceMaySurvive: engine.replacementRun.replacedOldMaySurvive.get(logicalId) },
48108
49095
  ...change.changeType === "UPDATE" && engine.replacementRun.updateWasReplaced.has(logicalId) && { wasReplaced: engine.replacementRun.updateWasReplaced.get(logicalId) },
48109
- ...change.changeType === "UPDATE" && previousState !== void 0 && { previousResourceType: previousState.resourceType }
49096
+ ...change.changeType === "UPDATE" && previousState !== void 0 && { previousResourceType: previousState.resourceType },
49097
+ ...change.changeType === "UPDATE" && engine.replacementRun.attemptedNameGeneration.has(logicalId) && newResources[logicalId]?.nameGeneration !== void 0 && { nameGeneration: newResources[logicalId].nameGeneration }
48110
49098
  });
48111
49099
  saveStateAfterResource(logicalId);
48112
49100
  if (engine.replacementRun.recreatedUnderSameId.has(logicalId)) enqueueLostChildren(createUpdateExecutor);
@@ -48157,6 +49145,10 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48157
49145
  provisionedBy: previousState?.provisionedBy,
48158
49146
  previousState
48159
49147
  });
49148
+ if (previousState !== void 0 && newResources[logicalId] === void 0) Object.assign(currentState, retiredNameGenerationsAfter(currentState, [{
49149
+ logicalId,
49150
+ record: previousState
49151
+ }]));
48160
49152
  saveStateAfterResource(logicalId);
48161
49153
  }, () => engine.interrupted);
48162
49154
  } finally {
@@ -48165,15 +49157,19 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48165
49157
  if (engine.interrupted && hasPending(deleteExecutor)) throw new InterruptedError(engine.interruptCause ?? "user");
48166
49158
  }
48167
49159
  if (engine.interrupted) warnUnretriedReplacedDeletes(engine.replacementRun, engine.replacementDeps(), "interrupted");
48168
- else try {
48169
- await retryDeferredReplacedDeletes(engine.replacementRun, engine.replacementDeps(), stackName, actualCounts);
48170
- } finally {
48171
- for (const op of completedOperations) {
48172
- if (op.changeType !== "UPDATE") continue;
48173
- const verdict = engine.replacementRun.replacedOldMaySurvive.get(op.logicalId);
48174
- if (verdict !== void 0) op.oldResourceMaySurvive = verdict;
48175
- else delete op.oldResourceMaySurvive;
49160
+ else {
49161
+ try {
49162
+ await retryDeferredReplacedDeletes(engine.replacementRun, engine.replacementDeps(), stackName, actualCounts);
49163
+ } finally {
49164
+ for (const op of completedOperations) {
49165
+ if (op.changeType !== "UPDATE") continue;
49166
+ const verdict = engine.replacementRun.replacedOldMaySurvive.get(op.logicalId);
49167
+ if (verdict !== void 0) op.oldResourceMaySurvive = verdict;
49168
+ else delete op.oldResourceMaySurvive;
49169
+ }
48176
49170
  }
49171
+ const releasedSomething = deleteChanges.size > 0 || completedOperations.some((op) => op.changeType === "UPDATE" && op.previousState !== void 0 && op.physicalId !== void 0 && op.physicalId !== op.previousState.physicalId);
49172
+ await retryCarriedSupersededResources(engine, currentState, carriedSuperseded, newResources, { waitInUse: releasedSomething });
48177
49173
  }
48178
49174
  } catch (error) {
48179
49175
  warnUnretriedReplacedDeletes(engine.replacementRun, engine.replacementDeps(), engine.interruptCause === "user" ? "interrupted" : "failed");
@@ -48232,7 +49228,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48232
49228
  }
48233
49229
  try {
48234
49230
  const preRollbackState = {
48235
- version: 12,
49231
+ version: 13,
48236
49232
  region: engine.stackRegion,
48237
49233
  stackName: currentState.stackName,
48238
49234
  resources: newResources,
@@ -48240,6 +49236,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48240
49236
  ...exportNamesCarriedFrom(currentState),
48241
49237
  ...skippedOutputsCarriedFrom(currentState),
48242
49238
  ...orphansCarriedFrom(currentState),
49239
+ ...stackInstanceIdCarriedFrom(currentState),
48243
49240
  ...crossStackReadsForPartialSave(currentState, engine.recordedImports, engine.recordedOutputReads, engine.crossStackReadKeyNormalizer()),
48244
49241
  lastModified: Date.now()
48245
49242
  };
@@ -48257,6 +49254,8 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48257
49254
  let autoRollbackClean = false;
48258
49255
  let autoRollbackJournaled = false;
48259
49256
  let rollbackOrphans = [];
49257
+ let rollbackCreates = [];
49258
+ let rollbackSuperseded = [];
48260
49259
  let rollbackSettledNested = /* @__PURE__ */ new Map();
48261
49260
  let rollbackRemainingFailedOps = failedOperations;
48262
49261
  if (error instanceof InterruptedError || isInterruptedWaitError(error) || engine.interruptCause === "user") {
@@ -48271,7 +49270,14 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48271
49270
  } else {
48272
49271
  autoRollbackJournaled = await writeRollbackJournalSegment(engine.rollbackDeps(), stackName, completedOperations, failedOperations, "auto-rollback-started", initialDeploy);
48273
49272
  const rollbackResult = await performRollback(engine.rollbackDeps(), completedOperations, newResources, stackName, currentState, failedOperations, currentState.orphans ?? []);
48274
- autoRollbackClean = autoRollbackJournaled && rollbackResult.failures === 0 && rollbackResult.skipped === 0;
49273
+ autoRollbackClean = autoRollbackJournaled && rollbackResult.failures === 0 && rollbackResult.skipped === 0 && !rollbackResult.interrupted;
49274
+ if (rollbackResult.interrupted && rollbackResult.failures === 0 && rollbackResult.skipped === 0) {
49275
+ const remedy = autoRollbackJournaled ? recoveryHint(engine.rollbackDeps(), "The rollback journal keeps them; finish the rollback with: " + pasteableCommand("cdkd rollback", [{
49276
+ value: stackName,
49277
+ hole: "stack"
49278
+ }]).command) : "";
49279
+ engine.logger.warn(safeMsg`The automatic rollback was interrupted before it reverted every operation. ${remedy}`);
49280
+ }
48275
49281
  if (rollbackResult.failures === 0 && rollbackResult.skipped > 0) {
48276
49282
  engine.logger.warn(safeMsg`The automatic rollback could not revert ${rollbackResult.skipped} operation(s) ` + `(see the warnings above; each is recorded as a ROLLBACK_RESOURCE_SKIPPED event).` + (autoRollbackJournaled ? ` The rollback journal keeps them.` : ""));
48277
49283
  if (autoRollbackJournaled && engine.options.parentStackInfo === void 0 && rollbackResult.remainingFailedOps.some((op) => op.changeType !== "DELETE")) engine.logger.warn(safeMsg`The record of the operation that failed is kept too. Revert it with: ${pasteableCommand("cdkd rollback", [{
@@ -48280,12 +49286,14 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48280
49286
  }, { literal: "--revert-failed" }]).command}`);
48281
49287
  }
48282
49288
  rollbackOrphans = rollbackResult.orphaned;
49289
+ rollbackCreates = rollbackResult.rolledBackCreates;
49290
+ rollbackSuperseded = rollbackResult.superseded;
48283
49291
  rollbackSettledNested = rollbackResult.settledNested;
48284
49292
  rollbackRemainingFailedOps = rollbackResult.remainingFailedOps;
48285
49293
  }
48286
49294
  try {
48287
49295
  const postRollbackState = {
48288
- version: 12,
49296
+ version: 13,
48289
49297
  region: engine.stackRegion,
48290
49298
  stackName: currentState.stackName,
48291
49299
  resources: newResources,
@@ -48293,6 +49301,9 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48293
49301
  ...exportNamesCarriedFrom(currentState),
48294
49302
  ...skippedOutputsCarriedFrom(currentState),
48295
49303
  ...orphansAfterRollback(currentState, rollbackOrphans),
49304
+ ...stackInstanceIdCarriedFrom(currentState),
49305
+ ...supersededAfterRollback(currentState, { supersededResources: rollbackSuperseded }),
49306
+ ...retiredAfterRollback(currentState, rollbackOrphans, rollbackCreates),
48296
49307
  ...crossStackReadsForPartialSave(currentState, engine.recordedImports, engine.recordedOutputReads, engine.crossStackReadKeyNormalizer()),
48297
49308
  lastModified: Date.now()
48298
49309
  };
@@ -48304,7 +49315,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48304
49315
  try {
48305
49316
  const freshEtag = (await engine.stateBackend.getState(stackName, engine.stackRegion))?.etag;
48306
49317
  const postRollbackState = {
48307
- version: 12,
49318
+ version: 13,
48308
49319
  region: engine.stackRegion,
48309
49320
  stackName: currentState.stackName,
48310
49321
  resources: newResources,
@@ -48312,6 +49323,9 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48312
49323
  ...exportNamesCarriedFrom(currentState),
48313
49324
  ...skippedOutputsCarriedFrom(currentState),
48314
49325
  ...orphansAfterRollback(currentState, rollbackOrphans),
49326
+ ...stackInstanceIdCarriedFrom(currentState),
49327
+ ...supersededAfterRollback(currentState, { supersededResources: rollbackSuperseded }),
49328
+ ...retiredAfterRollback(currentState, rollbackOrphans, rollbackCreates),
48315
49329
  ...crossStackReadsForPartialSave(currentState, engine.recordedImports, engine.recordedOutputReads, engine.crossStackReadKeyNormalizer()),
48316
49330
  lastModified: Date.now()
48317
49331
  };
@@ -48320,6 +49334,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48320
49334
  if (autoRollbackClean) await settleNestedChildrenAfterCleanRollback(engine.rollbackDeps(), stackName, rollbackSettledNested, await settleJournalAfterCleanRollback(engine.rollbackDeps(), stackName, rollbackRemainingFailedOps, initialDeploy));
48321
49335
  } catch (retryError) {
48322
49336
  engine.logger.warn(safeMsg`Failed to save state after rollback: ${asIsMessage(describeAwsFailure(retryError).detail)}`);
49337
+ for (const entry of rollbackSuperseded) withPrintingSecrets(unionOfSecretBags([secretNameBagFor(engine.secretsRun, entry.logicalId), orphanRecordsPrintingBag([entry])]), () => engine.logger.warn(safeMsg` ${entry.logicalId}'s new ${entry.state.resourceType} ` + safeMsg`(${entry.state.physicalId}) the rollback left to delete is NOT recorded: ` + "delete it manually."));
48323
49338
  }
48324
49339
  }
48325
49340
  throw error;
@@ -48337,11 +49352,12 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48337
49352
  }
48338
49353
  return {
48339
49354
  state: {
48340
- version: 12,
49355
+ version: 13,
48341
49356
  region: engine.stackRegion,
48342
49357
  stackName: currentState.stackName,
48343
49358
  resources: newResources,
48344
49359
  ...orphansCarriedFrom(currentState),
49360
+ ...stackInstanceIdCarriedFrom(currentState),
48345
49361
  outputs,
48346
49362
  exportNames: [...engine.outputsRun.resolvedExportNames],
48347
49363
  ...engine.outputsRun.skippedOutputs && { skippedOutputs: { ...engine.outputsRun.skippedOutputs } },
@@ -48355,7 +49371,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
48355
49371
  }
48356
49372
  async function persistStateAfterOutputFailure(engine, stackName, currentState, newResources, currentEtag, pendingMigration) {
48357
49373
  const buildState = () => ({
48358
- version: 12,
49374
+ version: 13,
48359
49375
  region: engine.stackRegion,
48360
49376
  stackName: currentState.stackName,
48361
49377
  resources: newResources,
@@ -48363,6 +49379,7 @@ async function persistStateAfterOutputFailure(engine, stackName, currentState, n
48363
49379
  ...exportNamesCarriedFrom(currentState),
48364
49380
  ...skippedOutputsCarriedFrom(currentState),
48365
49381
  ...orphansCarriedFrom(currentState),
49382
+ ...stackInstanceIdCarriedFrom(currentState),
48366
49383
  ...crossStackReadsForPartialSave(currentState, engine.recordedImports, engine.recordedOutputReads, engine.crossStackReadKeyNormalizer()),
48367
49384
  lastModified: Date.now()
48368
49385
  });
@@ -48398,12 +49415,14 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48398
49415
  const renderer = getLiveRenderer();
48399
49416
  engine.interrupted = false;
48400
49417
  engine.interruptCause = null;
49418
+ engine.userInterrupted = false;
48401
49419
  const sigintHandler = () => {
48402
49420
  renderer.printAbove(() => {
48403
49421
  process.stderr.write("\nInterrupted — saving partial state after current operations complete...\n");
48404
49422
  });
48405
49423
  engine.interrupted = true;
48406
49424
  engine.interruptCause ??= "user";
49425
+ engine.userInterrupted = true;
48407
49426
  };
48408
49427
  process.on("SIGINT", sigintHandler);
48409
49428
  try {
@@ -48421,7 +49440,7 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48421
49440
  const currentStateData = await engine.stateBackend.getState(stackName, engine.stackRegion);
48422
49441
  noteDeployStateRecord(currentStateData?.state !== void 0);
48423
49442
  const currentState = currentStateData?.state ?? {
48424
- version: 12,
49443
+ version: 13,
48425
49444
  region: engine.stackRegion,
48426
49445
  stackName,
48427
49446
  resources: {},
@@ -48430,6 +49449,19 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48430
49449
  lastModified: Date.now()
48431
49450
  };
48432
49451
  const currentEtag = currentStateData?.etag;
49452
+ stackInstanceIdOf(currentState, displayStackName(stackName));
49453
+ const loadedNameGenerations = nameGenerationsOf(currentState);
49454
+ const nameScope = () => {
49455
+ const stackInstanceId = stackInstanceIdOf(currentState, displayStackName(stackName));
49456
+ return {
49457
+ stackName,
49458
+ stackInstanceId,
49459
+ nameGenerations: stackInstanceId === void 0 ? void 0 : loadedNameGenerations
49460
+ };
49461
+ };
49462
+ const idArrivesLater = (currentStateData === null || currentStateData === void 0) && currentState.stackInstanceId === void 0;
49463
+ const retainedAtFirstDeploy = idArrivesLater && !engine.options.dryRun ? Promise.resolve().then(() => engine.stateBackend.loadRetainedRecord(stackName, engine.stackRegion)) : void 0;
49464
+ const retainedForWarning = retainedAtFirstDeploy?.catch(() => null);
48433
49465
  engine.rebaseline(currentState.resources ?? {});
48434
49466
  engine.runProducerRegionEvidence = () => producerRegionEvidence(engine.rollbackDeps(), currentState);
48435
49467
  refuseMalformedOutputs(currentState, stackName, engine.stackRegion, engine.options.refusalRecovery);
@@ -48473,6 +49505,7 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48473
49505
  command: "deploy",
48474
49506
  logger: engine.logger,
48475
49507
  stateResources: currentState.resources,
49508
+ stackInstanceId: currentStateData?.state === void 0 ? () => engine.stateBackend.readStackInstanceSibling(stackName, engine.stackRegion) : nameScope().stackInstanceId,
48476
49509
  resume: (op, identifier) => {
48477
49510
  const attempted = op.attemptedProperties;
48478
49511
  if (template.Resources?.[op.logicalId]?.Type !== op.resourceType || attempted === void 0 || carriesSecretMask(attempted) || op.pendingCloudControlRequest === void 0 || Object.values(currentState.resources).some((r) => r.physicalId === identifier && r.resourceType === op.resourceType)) return false;
@@ -48634,6 +49667,11 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48634
49667
  firstDeployStateGate = void 0;
48635
49668
  await gate;
48636
49669
  }
49670
+ const resolveStackInstanceId = async () => {
49671
+ if (currentStateData !== null && currentStateData !== void 0) return;
49672
+ if (engine.options.dryRun || currentState.stackInstanceId !== void 0) return;
49673
+ currentState.stackInstanceId = await engine.stateBackend.stackInstanceIdForFirstWrite(stackName, engine.stackRegion, { writeAhead: true });
49674
+ };
48637
49675
  const startProvenanceCapture = () => {
48638
49676
  if (engine.options.dryRun || isKnownTokenFreeState(currentStateData?.state)) return;
48639
49677
  engine.provenanceCapture.kickOffProvenanceCapture({
@@ -48648,6 +49686,7 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48648
49686
  if (!engine.diffCalculator.hasChanges(changes)) {
48649
49687
  engine.logger.info("No changes detected. Stack is up to date.");
48650
49688
  startProvenanceCapture();
49689
+ const supersededChanged = engine.options.dryRun ? false : await retryCarriedSupersededResources(engine, currentState, supersededResourcesOf(currentState), currentState.resources);
48651
49690
  let persistedOutputs = currentState.outputs ?? {};
48652
49691
  if (!engine.options.dryRun) {
48653
49692
  const resolvedOutputs = redactOutputs(engine.maskingDeps(), await withSharedDrainBudget(() => resolveOutputs(engine.outputsRun, engine.outputsDeps(), effectiveTemplate, currentState.resources, stackName, outputsDigestSource, parameterValues, conditions)));
@@ -48686,37 +49725,41 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48686
49725
  stackName
48687
49726
  });
48688
49727
  const outputProvenanceBackfill = !outputsChanged && currentState.outputReferenceProvenance === void 0 && engine.provenanceBaseline?.tokenFree === false && engine.outputReferenceProvenanceFor(persistedOutputs, redactOutputs(engine.maskingDeps(), persistedOutputs)) !== void 0;
48689
- if (observedRefresh || outputProvenanceBackfill || maskedFingerprintsBackfilled || conditionVerdictsChanged || outputsChanged || exportSetChanged || skippedOutputsChanged || orphansChanged || healedAttributesPending) try {
48690
- const refreshedState = {
48691
- version: 12,
48692
- region: engine.stackRegion,
48693
- stackName: currentState.stackName,
48694
- resources: currentState.resources,
48695
- ...orphansCarriedFrom(currentState),
48696
- outputs: outputsChanged ? outputsToPersist : persistedOutputs,
48697
- ...exportNamesToPersist === void 0 ? exportNamesCarriedFrom(currentState) : { exportNames: [...exportNamesToPersist] },
48698
- ...engine.outputsRun.skippedOutputs && { skippedOutputs: { ...engine.outputsRun.skippedOutputs } },
48699
- ...crossStackReadsForPartialSave(currentState, engine.recordedImports, engine.recordedOutputReads, engine.crossStackReadKeyNormalizer()),
48700
- ...conditionVerdicts && { conditionVerdicts },
48701
- lastModified: Date.now()
48702
- };
48703
- const saveOptions = {};
48704
- if (currentEtag !== void 0) saveOptions.expectedEtag = currentEtag;
48705
- if (migrationPending) saveOptions.migrateLegacy = true;
48706
- await engine.stateBackend.saveState(stackName, engine.stackRegion, engine.withParentInfo(refreshedState), saveOptions);
48707
- if (outputsChanged || exportSetChanged) {
48708
- persistedOutputs = refreshedState.outputs;
48709
- if (outputsChanged) engine.logger.info("Persisted Outputs-only change (no resource diff).");
48710
- else engine.logger.debug("Persisted export-set change (no outputs-value diff, no-change path)");
48711
- if (engine.exportIndexStore) await engine.exportIndexStore.updateForStack(stackName, engine.stackRegion, importableOutputs({
48712
- ...refreshedState,
48713
- outputs: redactOutputs(engine.maskingDeps(), refreshedState.outputs)
48714
- }));
48715
- } else if (observedRefresh) engine.logger.debug("Persisted refreshed observedProperties (no-change path)");
48716
- else if (healedAttributesPending) engine.logger.debug("Persisted attributes re-read from AWS for a stale record (no-change path)");
48717
- else engine.logger.debug("Persisted skipped-outputs record (no outputs-value diff, no-change path)");
48718
- } catch (saveError) {
48719
- engine.logger.warn(safeMsg`Failed to persist no-change state update: ${asIsMessage(describeAwsFailure(saveError).detail)} — drift baseline / outputs will be re-resolved on next deploy.`);
49728
+ if (observedRefresh || outputProvenanceBackfill || maskedFingerprintsBackfilled || conditionVerdictsChanged || outputsChanged || exportSetChanged || skippedOutputsChanged || orphansChanged || supersededChanged || healedAttributesPending) {
49729
+ await resolveStackInstanceId();
49730
+ try {
49731
+ const refreshedState = {
49732
+ version: 13,
49733
+ region: engine.stackRegion,
49734
+ stackName: currentState.stackName,
49735
+ resources: currentState.resources,
49736
+ ...orphansCarriedFrom(currentState),
49737
+ ...stackInstanceIdCarriedFrom(currentState),
49738
+ outputs: outputsChanged ? outputsToPersist : persistedOutputs,
49739
+ ...exportNamesToPersist === void 0 ? exportNamesCarriedFrom(currentState) : { exportNames: [...exportNamesToPersist] },
49740
+ ...engine.outputsRun.skippedOutputs && { skippedOutputs: { ...engine.outputsRun.skippedOutputs } },
49741
+ ...crossStackReadsForPartialSave(currentState, engine.recordedImports, engine.recordedOutputReads, engine.crossStackReadKeyNormalizer()),
49742
+ ...conditionVerdicts && { conditionVerdicts },
49743
+ lastModified: Date.now()
49744
+ };
49745
+ const saveOptions = {};
49746
+ if (currentEtag !== void 0) saveOptions.expectedEtag = currentEtag;
49747
+ if (migrationPending) saveOptions.migrateLegacy = true;
49748
+ await engine.stateBackend.saveState(stackName, engine.stackRegion, engine.withParentInfo(refreshedState), saveOptions);
49749
+ if (outputsChanged || exportSetChanged) {
49750
+ persistedOutputs = refreshedState.outputs;
49751
+ if (outputsChanged) engine.logger.info("Persisted Outputs-only change (no resource diff).");
49752
+ else engine.logger.debug("Persisted export-set change (no outputs-value diff, no-change path)");
49753
+ if (engine.exportIndexStore) await engine.exportIndexStore.updateForStack(stackName, engine.stackRegion, importableOutputs({
49754
+ ...refreshedState,
49755
+ outputs: redactOutputs(engine.maskingDeps(), refreshedState.outputs)
49756
+ }));
49757
+ } else if (observedRefresh) engine.logger.debug("Persisted refreshed observedProperties (no-change path)");
49758
+ else if (healedAttributesPending) engine.logger.debug("Persisted attributes re-read from AWS for a stale record (no-change path)");
49759
+ else engine.logger.debug("Persisted skipped-outputs record (no outputs-value diff, no-change path)");
49760
+ } catch (saveError) {
49761
+ engine.logger.warn(safeMsg`Failed to persist no-change state update: ${asIsMessage(describeAwsFailure(saveError).detail)} — drift baseline / outputs will be re-resolved on next deploy.`);
49762
+ }
48720
49763
  }
48721
49764
  }
48722
49765
  return {
@@ -48756,7 +49799,7 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48756
49799
  }
48757
49800
  const abandonedRunAt = engine.lockManager.abandonedRunEndedBy?.(stackName, engine.stackRegion);
48758
49801
  if (abandonedRunAt !== void 0) await noteAbandonedRun(abandonedRunAt);
48759
- engine.generatedNameGuard = GeneratedNameGuard.start({
49802
+ const generatedNameGuardInput = {
48760
49803
  stackName,
48761
49804
  region: engine.stackRegion,
48762
49805
  changes: changes.values(),
@@ -48767,7 +49810,7 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48767
49810
  records: currentState.resources,
48768
49811
  orphans: currentState.orphans,
48769
49812
  loadJournal: () => engine.stateBackend.loadRollbackJournal(stackName, engine.stackRegion),
48770
- loadRetained: () => engine.stateBackend.loadRetainedRecord(stackName, engine.stackRegion),
49813
+ loadRetained: () => retainedAtFirstDeploy ?? engine.stateBackend.loadRetainedRecord(stackName, engine.stackRegion),
48771
49814
  loadKeptInHistory: () => {
48772
49815
  const reader = new DeploymentEventsReader(engine.stateBackend);
48773
49816
  return loadKeptInHistory({
@@ -48779,8 +49822,24 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48779
49822
  accountInfo: () => getAccountInfo(engine.stackRegion),
48780
49823
  warn: (message) => engine.logger.warn(message),
48781
49824
  ...abandonedRunAt !== void 0 && { abandonedRunAt }
48782
- });
48783
- if (engine.generatedNameGuard !== void 0) engine.logger.debug(safeMsg`Generated-name check: looking up ${String(engine.generatedNameGuard.size)} planned create(s)`);
49825
+ };
49826
+ const startGeneratedNameGuard = () => {
49827
+ const scope = nameScope();
49828
+ const lifetimeId = scope.stackInstanceId;
49829
+ engine.generatedNameGuard = withStackScope(scope, () => GeneratedNameGuard.start({
49830
+ ...generatedNameGuardInput,
49831
+ ...lifetimeId !== void 0 && {
49832
+ newScheme: true,
49833
+ replacementGeneration: (change) => {
49834
+ const record = currentState.resources[change.logicalId];
49835
+ if (record === void 0 || record.resourceType !== change.resourceType || !((change.propertyChanges ?? []).some((pc) => pc.requiresReplacement) || recreateTargetIdsFor(engine.options.recreateTargets, stackName)?.has(change.logicalId) === true)) return;
49836
+ return nextNameGeneration(record, change.logicalId, lifetimeId);
49837
+ }
49838
+ }
49839
+ }));
49840
+ if (engine.generatedNameGuard !== void 0) engine.logger.debug(safeMsg`Generated-name check: looking up ${String(engine.generatedNameGuard.size)} planned create(s)`);
49841
+ };
49842
+ if (!idArrivesLater) startGeneratedNameGuard();
48784
49843
  await checkDestructivePlan({
48785
49844
  options: engine.options,
48786
49845
  stackName,
@@ -48799,13 +49858,19 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
48799
49858
  secretMask: () => diffLogMasker(engine.secretsRun, engine.maskingDeps(), diffResolverContext.recordedSecretValues, effectiveTemplate, parameterValues, currentState.resources)
48800
49859
  })) engine.generatedNameGuard?.noteApprovalPrompted();
48801
49860
  startProvenanceCapture();
48802
- engine.generatedNameGuard?.recordPlannedIntents();
48803
49861
  engine.resolver.resetPhysicalIdFallbackCount();
49862
+ await resolveStackInstanceId();
49863
+ if (idArrivesLater) {
49864
+ startGeneratedNameGuard();
49865
+ const kept = await retainedForWarning ?? [];
49866
+ if (kept.length > 0) engine.logger.warn(safeMsg`An earlier deployment of ${displayStackName(stackName)} kept ${String(kept.length)} ` + "resource(s) here (DeletionPolicy: Retain). This deploy does not take them back: it creates new resources under new names, as CloudFormation does. To manage a kept resource again, adopt it with 'cdkd import'.");
49867
+ }
49868
+ engine.generatedNameGuard?.recordPlannedIntents();
48804
49869
  const progress = {
48805
49870
  current: 0,
48806
49871
  total: createChanges.length + updateChanges.length + deleteChanges.length
48807
49872
  };
48808
- const { state: newState, actualCounts, completedOperations } = await withProducerRegions(() => producerRegionEvidence(engine.rollbackDeps(), currentState), () => executeDeployment(engine, effectiveTemplate, currentState, changes, dag, executionLevels, stackName, outputsDigestSource, parameterValues, conditions, currentEtag, progress, migrationPending));
49873
+ const { state: newState, actualCounts, completedOperations } = await withProducerRegions(() => producerRegionEvidence(engine.rollbackDeps(), currentState), () => withStackScope(nameScope(), () => executeDeployment(engine, effectiveTemplate, currentState, changes, dag, executionLevels, stackName, outputsDigestSource, parameterValues, conditions, currentEtag, progress, migrationPending)));
48809
49874
  try {
48810
49875
  engine.stateBackend.warmConnections(stackName, engine.stackRegion, TAIL_WARM_CONNECTIONS);
48811
49876
  } catch {}
@@ -48916,6 +49981,7 @@ var DeployEngine = class {
48916
49981
  resolver;
48917
49982
  interrupted = false;
48918
49983
  interruptCause = null;
49984
+ userInterrupted = false;
48919
49985
  absentJournalVersionPurge;
48920
49986
  noEchoCeilingReadbackTimeoutMs = 3e4;
48921
49987
  observedCapture;
@@ -49048,10 +50114,13 @@ var DeployEngine = class {
49048
50114
  deployStateResources: () => this.deployStateResources,
49049
50115
  interrupted: () => this.interrupted,
49050
50116
  interruptCause: () => this.interruptCause,
50117
+ userInterrupted: () => this.userInterrupted,
49051
50118
  withRetry: (...args) => this.withRetry(...args),
49052
50119
  maskingRetryLoggerFor: (...args) => this.maskingRetryLoggerFor(...args),
49053
50120
  inlinePolicyClaimedFor: (...args) => this.inlinePolicyClaimedFor(...args),
49054
- recordEvent: (...args) => this.recordEvent(...args)
50121
+ recordEvent: (...args) => this.recordEvent(...args),
50122
+ guardedReplacementCreate: (input, create) => guardedReplacementCreate(this, input, create),
50123
+ generatedNameGuarded: (logicalId) => this.generatedNameGuard?.candidate(logicalId) !== void 0
49055
50124
  };
49056
50125
  }
49057
50126
  resolverContextDeps() {
@@ -49103,6 +50172,7 @@ var DeployEngine = class {
49103
50172
  },
49104
50173
  absentJournalVersionPurge: () => this.absentJournalVersionPurge,
49105
50174
  interrupted: () => this.interrupted,
50175
+ userInterrupted: () => this.userInterrupted,
49106
50176
  noEchoDeps: () => this.noEchoDeps(),
49107
50177
  recordEvent: (...args) => this.recordEvent(...args),
49108
50178
  crossStackReadKeyNormalizer: (...args) => this.crossStackReadKeyNormalizer(...args)
@@ -49129,7 +50199,7 @@ var DeployEngine = class {
49129
50199
  this.inlinePolicyWriters = /* @__PURE__ */ new Map();
49130
50200
  this.resolver.resetPhysicalIdFallbackCount();
49131
50201
  const ledger = ledgerForStack(this.stateBackend, stackName, this.stackRegion);
49132
- return withStackName(stackName, () => this.options.dryRun ? this.doDeploy(stackName, template) : withCreateTokenLedger(ledger, () => this.doDeploy(stackName, template)));
50202
+ return withStackScopeBeforeStateRead(stackName, () => this.options.dryRun ? this.doDeploy(stackName, template) : withCreateTokenLedger(ledger, () => this.doDeploy(stackName, template)));
49133
50203
  }
49134
50204
  static maskedRecordRemedyFor = maskedRecordRemedyFor;
49135
50205
  redactStateForPersist(state) {
@@ -49142,23 +50212,35 @@ var DeployEngine = class {
49142
50212
  const noEchoScrubbed = applyNoEchoPersist(this.noEchoRun, this.noEchoDeps(), logicalId, record, withNoEchoExactEchoes(this.noEchoRun, logicalId, scrubbed), templateProps, state.resources, secrets);
49143
50213
  resources[logicalId] = withReferenceProvenance(withConstructPath(withMaskedPropertyFingerprints(noEchoScrubbed, record.properties, templateProps, secrets, this.secretsRun.fingerprintNoEchoValues, this.secretsRun.perResourceInputFingerprints.get(logicalId)), constructPathOf(this.noEchoRun.constructPathTemplate, logicalId)), this.referenceProvenanceToPersist(logicalId, record, noEchoScrubbed, secrets));
49144
50214
  }
49145
- const orphans = state.orphans?.map((entry) => {
50215
+ const orphanEntries = state.orphans;
50216
+ const scrubDroppedRecord = (entry) => {
49146
50217
  const sameResource = this.secretsRun.perResourceResolvedType.get(entry.logicalId) === entry.state.resourceType;
49147
50218
  const orphanTemplateProps = sameResource ? this.secretsRun.perResourceTemplateProps.get(entry.logicalId) : void 0;
49148
- return {
50219
+ return withMaskedPropertyFingerprints(applyNoEchoPersist(this.noEchoRun, this.noEchoDeps(), entry.logicalId, entry.state, scrubResourceRecord(entry.state, (sameResource ? this.secretsRun.perResourceSecrets.get(entry.logicalId) : void 0) ?? /* @__PURE__ */ new Map(), orphanTemplateProps, void 0, sameGenerationClaimsOf(entry.state)), orphanTemplateProps, state.resources), entry.state.properties, orphanTemplateProps, sameResource ? this.secretsRun.perResourceSecrets.get(entry.logicalId) : void 0, sameResource ? this.secretsRun.fingerprintNoEchoValues : void 0, sameResource ? this.secretsRun.perResourceInputFingerprints.get(entry.logicalId) : void 0);
50220
+ };
50221
+ const orphans = orphanEntries?.map((entry) => ({
50222
+ ...entry,
50223
+ state: scrubDroppedRecord(entry)
50224
+ }));
50225
+ const superseded = Array.isArray(state.supersededResources) ? state.supersededResources.flatMap((entry) => {
50226
+ if (!isSupersededResourceRecord(entry)) return [entry];
50227
+ if (isSupersededHeldBySameType(entry, state.resources)) return [];
50228
+ return [{
49149
50229
  ...entry,
49150
- state: withMaskedPropertyFingerprints(applyNoEchoPersist(this.noEchoRun, this.noEchoDeps(), entry.logicalId, entry.state, scrubResourceRecord(entry.state, (sameResource ? this.secretsRun.perResourceSecrets.get(entry.logicalId) : void 0) ?? /* @__PURE__ */ new Map(), orphanTemplateProps, void 0, sameGenerationClaimsOf(entry.state)), orphanTemplateProps, state.resources), entry.state.properties, orphanTemplateProps, sameResource ? this.secretsRun.perResourceSecrets.get(entry.logicalId) : void 0, sameResource ? this.secretsRun.fingerprintNoEchoValues : void 0, sameResource ? this.secretsRun.perResourceInputFingerprints.get(entry.logicalId) : void 0)
49151
- };
49152
- });
50230
+ state: scrubDroppedRecord(entry)
50231
+ }];
50232
+ }) : void 0;
49153
50233
  const outputs = redactOutputs(this.maskingDeps(), state.outputs);
49154
50234
  const crossStackReads = this.redactCrossStackReads(state);
49155
- const { outputReferenceProvenance: _incoming, ...rest } = state;
50235
+ const { outputReferenceProvenance: _incoming, supersededResources: _superseded, ...rest } = state;
49156
50236
  const outputReferenceProvenance = this.outputReferenceProvenanceFor(state.outputs, outputs);
49157
50237
  return {
49158
50238
  ...rest,
50239
+ ...stackInstanceIdCarriedFrom(withoutSuperseded(state)),
49159
50240
  resources,
49160
50241
  outputs,
49161
50242
  ...orphans === void 0 ? {} : { orphans },
50243
+ ...superseded === void 0 ? _superseded !== void 0 && { supersededResources: _superseded } : superseded.length > 0 && { supersededResources: superseded },
49162
50244
  ...crossStackReads,
49163
50245
  ...outputReferenceProvenance !== void 0 && { outputReferenceProvenance }
49164
50246
  };
@@ -49231,6 +50313,7 @@ var DeployEngine = class {
49231
50313
  const { parentStack, parentLogicalId, parentRegion } = this.options.parentStackInfo;
49232
50314
  return {
49233
50315
  ...redacted,
50316
+ ...stackInstanceIdCarriedFrom(redacted),
49234
50317
  parentStack,
49235
50318
  parentLogicalId,
49236
50319
  parentRegion
@@ -49278,14 +50361,14 @@ var DeployEngine = class {
49278
50361
  }
49279
50362
  };
49280
50363
  }
49281
- async withRetry(operation, logicalId, maxRetries, initialDelayMs, provider) {
50364
+ async withRetry(operation, logicalId, maxRetries, initialDelayMs, provider, interruptOnlyByUser) {
49282
50365
  if (provider?.disableOuterRetry) return operation();
49283
50366
  return withRetry(operation, logicalId, {
49284
50367
  ...maxRetries !== void 0 && { maxRetries },
49285
50368
  ...initialDelayMs !== void 0 && { initialDelayMs },
49286
50369
  logger: this.maskingRetryLogger(logicalId),
49287
- isInterrupted: () => this.interrupted,
49288
- onInterrupted: () => new InterruptedError(this.interruptCause ?? "user")
50370
+ isInterrupted: () => interruptOnlyByUser === true ? this.userInterrupted : this.interrupted,
50371
+ onInterrupted: () => new InterruptedError(interruptOnlyByUser === true ? "user" : this.interruptCause ?? "user")
49289
50372
  });
49290
50373
  }
49291
50374
  maskingRetryLogger(logicalId) {
@@ -49306,5 +50389,5 @@ function sameGenerationClaimsOf(record) {
49306
50389
  }
49307
50390
 
49308
50391
  //#endregion
49309
- export { DeploymentEventsStore as $, repairMalformedOrphanRecordsForReadOnly as $a, runDockerStreaming as $c, UNREADABLE_ORPHANS_CONTAINER_ROW as $i, ATOMIC_FINAL_SNAPSHOT_TYPES as $n, noEchoOutputsComparison as $o, reDisableInstanceApiTermination as $r, CrossPrefixReadError as $s, updatePartialReason as $t, inheritedProvenanceForChildDiff as A, refuseMalformedNestedChildOutputs as Aa, getBootstrapMarkerKey as Ac, producerRegionsFromState as Ai, StageLoadError as Al, bold as An, configStringRefusal as Ao, TemplateNoEchoReresolver as Ar, pathCrossesDottedKey as As, replayFailedOperations as At, conditionFingerprint as B, refuseMalformedResourceEntriesForDeploy as Ba, describeDockerExecFailure as Bc, keepsSecretReferenceToken as Bi, renderAssemblyPathEscape as Bl, createReadOnlyAttributeHealerFactory as Bn, canonicalLambdaFunctionName as Bo, unchangedBehindSecretReference as Br, provenPublicValue as Bs, recordUnderIdIsNotOwn as Bt, hasCdkAutoDeleteTag as C, malformedResourceEntriesWarning as Ca, createAssetRedirectResolver as Cc, sendableAssumeRoleCommand as Ci, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Cl, findDestructiveChanges as Cn, isWarmThroughputDecrease as Co, stringifyIfAssigned as Cr, maskSecretsInText as Cs, makeForeignHolderScan as Ct, IMPLICIT_DELETE_DEPENDENCIES as D, malformedStateRefusalMessage as Da, BOOTSTRAP_MARKER_PREFIX as Dc, envCredentialsAreAssumedRole as Di, canonicalizeRegion as Dl, getStackRecords as Dn, coerceCfnInteger as Do, isCustomResource as Dr, DYNAMIC_REFERENCE_TOKEN_SCAN as Ds, isAccessDeniedError as Dt, markRefusedBeforeApplying as E, malformedScrubResourceEntriesRefusalMessage as Ea, AssetModeResolver as Ec, callerEnvCredentials as Ei, PARTITION_TABLE as El, destroyStackRecordsView as En, coerceCfnBoolean as Eo, ccBrokenReason as Er, withoutPhysicalNameCopies as Es, chunks as Et, findNestedTemplateTreeDefect as F, refuseMalformedOrphansForOrphan as Fa, validateContainerRepoName as Fc, getAccountInfo as Fi, nullPrototypeRecord as Fl, yellow as Fn, requireConfigString as Fo, CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID as Fr, physicalNameCopiesOf as Fs, isJournaledOrphan as Ft, diffSecurity as G, refuseMalformedResourcePropertiesForDestroy as Ga, getDockerCmd as Gc, parseWebACLArn as Gi, resolveBucketRegion as Gl, orphanRecordsPrintingBag as Gn, canonicalCoordinates as Go, deleteSkipReason as Gr, recordProvenPublicExpression as Gs, findNestedStackTypeChanges as Gt, parentSuppliedValues as H, refuseMalformedResourceEntriesForImport as Ha, dockerSpawnEnvWithSensitive as Hc, cfnRefValueFromPhysicalId as Hi, injectAwsRegion as Hl, journaledOrphanPrintingBag as Hn, sameLambdaFunctionAddress as Ho, UNSPECIFIED_SKIP_REASON as Hr, recordMaskOnlyValuesIn as Hs, resolveReplacementOldType as Ht, isAbsoluteAssetPath as I, refuseMalformedOutputs as Ia, buildDenyExternalAccessPolicy as Ic, isImpossibleEmptyStoredAttribute as Ii, ownValue as Il, noEchoAttributeNamesOf as In, prefetchCreateOnlyPropertyPaths as Io, applyCustomResourceResponseExpiration as Ir, recordAttributeIdCopy as Is, isReplacementOrphan as It, mergeNoChangeOutputs as J, refuseMalformedResourcePropertiesForOrphan as Ja, partitionSensitiveEnv as Jc, passedParameterClassesOf as Ji, secretNamedAttributeNamesOf as Jn, maskReadbackAtCoordinates as Jo, markWaitAbandoned as Jr, isSingleDynamicReferenceToken as Js, REDACTED_DELETE_ADDRESS_SKIP_REASON as Jt, isSecretBearingReferenceString as K, refuseMalformedResourcePropertiesForDrift as Ka, isDockerClientEnvKey as Kc, withSharedDrainBudget as Ki, secretNamePrintingBag as Kn, isMarkedCoordinate as Ko, withIndeterminateGuard as Kr, wholeStringLeavesOf as Ks, getCurrentProducerRegions as Kt, listNestedTemplateRows as L, refuseMalformedOutputsForDestroy as La, buildDockerImage as Lc, carriesDynamicReference as Li, absoluteAssemblyPathEscape as Ll, noEchoComparisonForTemplate as Ln, templateResourceTypes as Lo, customResourceResponseExpirationWarning as Lr, recordPhysicalNameCopy as Ls, planFailedOps as Lt, findServiceTokenRefusals as M, refuseMalformedOrphanRecordsForDestroy as Ma, parseBootstrapMarker as Mc, coerceParameterTypedValue as Mi, defineOwnKey as Ml, gray as Mn, replayWarn as Mo, isCustomResourceType as Mr, inheritNestedStackParameterAssociations as Ms, removeProtectionTypeList as Mt, serviceTokenBlockingReason as N, refuseMalformedOrphans as Na, readBootstrapMarkerBody as Nc, isUnboundTemplateParameter as Ni, hasOwnKey as Nl, green as Nn, requireConfigArray as No, getCurrentResourceSecrets as Nr, recordNestedStackParameterExpressions as Ns, recordAfterRollbackUpdate as Nt, computeImplicitDeleteEdges as O, previewableOrphanRecords as Oa, assertAssetBucketRegion as Oc, classifyRecordedSecretRegion as Oi, derivePartitionAndUrlSuffix as Ol, withStackRecords as On, configBooleanRefusal as Oo, wouldReturnToSdkProvider as Or, dynamicReferenceTokens as Os, lookupEachName as Ot, childTemplateLoader as P, refuseMalformedOrphansForDestroy as Pa, validateAssetBucketName as Pc, parameterTypeMayLoseSecretIdentity as Pi, hasPlainPrototype$1 as Pl, red as Pn, requireConfigObject as Po, withPrintingSecrets as Pr, recoverMaskedOutput as Ps, demoteSupersededOrphans as Pt, DeploymentEventsReader as Q, refuseMalformedState as Qa, runDockerForeground as Qc, STATE_RESOURCES_MALFORMED as Qi, extractDeploymentEventError as Qn, noEchoLeavesOf as Qo, observeThenDisableInstanceApiTermination as Qr, rebuildClientForBucketRegion as Qs, updatePartialMessage as Qt, renderNestedTemplateTreeDefect as R, refuseMalformedResourceAttributesForOrphan as Ra, resolveDockerContextDirectory as Rc, carriesFetchableDynamicReference as Ri, describeFileReadFailure as Rl, noEchoExactEchoLeavesOf as Rn, describeTypeWithThrottleRetry as Ro, CloudControlProvider as Rr, splitGetAttStringForm as Rs, planRollback as Rt, S3_AUTO_DELETE_OBJECTS_TAG as S, malformedRenderedContainersWarning as Sa, buildAssetRedirectMap as Sc, isIamRoleArn as Si, uploadCfnTemplate as Sl, constructPathOf as Sn, coerceWarmThroughput as So, definedAttributes as Sr, maskSecretsInError as Ss, loadJournaledOrphans as St, getPriorAttempts as T, malformedResourcesWarning as Ta, rewriteTemplateAssetReferences as Tc, applyCallerIdentityCredentials as Ti, expectedOwnerParam as Tl, awaitInFlightSibling as Tn, toFiniteNumber as To, ProviderRegistry as Tr, withPhysicalNameCopies as Ts, formatResourceLine as Tt, readRecordedConditionVerdicts as U, refuseMalformedResourceEntriesForImportSave as Ua, finchSecretArgvRefusal as Uc, isStalePlaceholderArnAttribute as Ui, injectedAwsRegionValue as Ul, maskEventTextWithBoundBags as Un, DagBuilder as Uo, deleteIndeterminateGuards as Ur, recordNoEchoAttributeValues as Us, seedsDeleteFirstGuard as Ut, conditionInputsFrom as V, refuseMalformedResourceEntriesForDestroy as Va, describeDockerFailure as Vc, AWS_NO_VALUE as Vi, resolveAssemblyPath as Vl, completedReplayEntries as Vn, lambdaFunctionNameForMask as Vo, RollbackInlinePolicyWriters as Vr, recordMaskOnlyValue as Vs, replacementNeverSwapped as Vt, withResourceDeadline as W, refuseMalformedResourceEntriesForOrphan as Wa, formatDockerLoginError as Wc, refStateLookupFromResource as Wi, clearBucketRegionCache as Wl, namingSecretsWithRecordedNoEcho as Wn, TemplateParser as Wo, deleteLeftInPlace as Wr, recordNoEchoParameterFreshValue as Ws, orphanNeedsIdentity as Wt, makeSiblingClaimReader as X, refuseMalformedResourcesForDestroy as Xa, redactedCause as Xc, JSON_LISTING_HOLE_VALUE as Xi, stateSecretNameNeedles as Xn, maskedLeafCoordinatesOf as Xo, ec2InstanceProtectionSite as Xr, isLockInfoExpired as Xs, redactedDeleteAddressFields as Xt, makeCanonicalizePropertiesFn as Y, refuseMalformedResourcesForDeploy as Ya, redactDockerArgvValues as Yc, declaresNoEcho as Yi, secretNamedRecordNeedles as Yn, maskWholeValue as Yo, disableInstanceApiTermination as Yr, LockManager as Ys, isRedactedRecordedValue as Yt, planOrphanAdoption as Z, refuseMalformedResourcesForExport as Za, redactedDockerCause as Zc, STATE_REGION_DIVERGED as Zi, storedSecretNameNeedles as Zn, noEchoCoordinatesOf as Zo, isTerminationProtectionPropagationError as Zr, S3StateBackend as Zs, redactedDeleteAddressSkip as Zt, deleteTableWithIndexBusyRetry as _, malformedOrphanRowsKeptWarning as _a, shouldRetainResource as _c, recordedReferenceRegions as _i, ssmResolvedValueType as _l, isExportAliasCollision as _n, MULTI_REGION_RECREATE_BLOCKED_TYPES as _o, planTagDiff as _r, recordLogOnlyValue as _s, deleteJournaledOrphans as _t, isProtectionValueActive as a, hasReadableOutputs as aa, splitImportedOps as ac, isSettledInstanceState as ai, getDefaultStateBucketName as al, displayTextOrWithheld as an, unpreviewableOrphanRecords as ao, isFinalSnapshotError as ar, liveMatchesUnresolvedTokenFrame as as, displacedOpClause as at, waitForIndexesSettled as b, malformedOutputsRefusalMessage as ba, stringifyValue as bc, assertSendableRoleArn as bi, MIGRATE_TMP_PREFIX as bl, DEFAULT_RESOURCE_WARN_AFTER_MS as bn, renderStatefulReason as bo, tagMapAsList as br, createSecretMasker as bs, isHandledOrphan as bt, DynamoDBGlobalTableProvider as c, isReadableResourceEntry as ca, exportNamesCarriedFrom as cc, s3BucketDualStackDomainName as ci, resolveApp as cl, secretBearingStateKeyWarning as cn, withheldAccountClause as co, earliestDefined as cr, recordReferenceProvenanceEntry as cs, getNestedRevertRun as ct, compensateRemovedDeletionProtection as d, malformedExportSourceWarning as da, hasUnverifiableParameterRefusal as dc, resolveDynamicReferences as di, resolveSkipPrefix as dl, exportNameNoEchoParameters as dn, unwrittenCreateOnlyReplacement as do, withCreateTokenLedger as dr, createUnionSecretMasker as ds, revertNestedChildFromJournal as dt, UNREADABLE_RESOURCES_MAP_ROW as ea, CrossPrefixScanCache as ec, reEnableInstanceApiTermination as ei, warnFinchArgvExposure as el, computeParameterTaint as en, repairMalformedOrphansForReadOnly as eo, PRE_DELETE_SNAPSHOT_TYPES as er, passedNoEchoParametersOf as es, pendingRequestCount as et, deleteBudgetKey as f, malformedLocalOutputsWarning as fa, importableOutputKeys as fc, producerLookupOver as fi, resolveStateBucketWithDefault as fl, exportNameSecretExposure as fn, withoutSilentDropProperties as fo, acquireIdempotencyToken as fr, hasMaskableValues as fs, revertedNestedRowIds as ft, INDEX_SETTLE_POLL_INTERVAL_MS as g, malformedOrphanRecordsWarning as ga, orphansCarriedFrom as gc, recordedOutputReferenceRegions as gi, warnDeprecatedNoPrefixCliFlag as gl, collectPublishedOutputNames as gn, shownType as go, DBPROXY_TAG_OPTIONS as gr, recordLogOnlyParameterValue as gs, withNestedStackContext as gt, DELETE_INDEX_WAIT_PROCEED_NOTE as h, malformedOrphanRecordsRefusalMessage as ha, orphansAfterRollback as hc, outputReferenceProvenanceOf as hi, stateBucketExistenceConfirmed as hl, collectDeclaredOutputNames as hn, findReplacedReadersOfRecreateTargets as ho, DBPROXY_TAGS_WHAT as hr, printingCorpusOf as hs, getCurrentNestedStackContext as ht, PROTECTION_PROPERTY_BY_TYPE as i, hasReadableOrphans as ia, isNotImplemented as ic, poisonRenderedSpellingsCollidingIn as ii, synthesisStatusMessage as il, WITHHELD_NAME_DISPLAY as in, repairMalformedResourcesForReadOnly as io, effectiveDeletionPolicy as ir, valueAtCoordinate as is, NESTED_PENDING_PARENT_REASON as it, deferredServiceTokenWarning as j, refuseMalformedOrphanRecords as ja, isCrossRegionRedirect as jc, regionLessSecretName as ji, processStackMessages as jl, cyan as jn, readConfigString as jo, readsNoEchoDeleteValues as jr, identityKeyFor as js, replayRollback as jt, crossStackOutputProvenanceSource as k, refuseDivergentRecordRegionForDestroy as ka, ensureAssetStorage as kc, classifyReplaySecretRegion as ki, AssemblyReader as kl, replacedDeleteFailureVerdict as kn, configIntegerRefusal as ko, waitForLambdaFunctionActive as kr, isUncertifiedBaselineMaskPosition as ks, withApiLimit as kt, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as l, malformedDriftResourcePropertiesWarning as la, hasReadableExportSet as lc, s3BucketRegionalDomainName as li, resolveAutoAssetStorage as ll, secretSafeKeyDisplay as ln, findActionableSilentDrops as lo, ledgerForStack as lr, snapshotPassProvenance as ls, nestedChildStackName as lt, resolveDynamoDbDeleteBudgetMs as m, malformedLocalResourcesWarning as ma, isReadableBag as mc, keepHeldTokenProvenance as mi, resolveUseCdkBootstrapAssets as ml, noEchoParameterValueSeed as mn, hasNoCloudControlHandlers as mo, markDeleteStarted as mr, logOnlyValueCount as ms, collectNestedChildUnaddressed as mt, recordedProtectionEvidence as n, deployRefusesOrphanRowsReason as na, crossPrefixDeniedWarning as nc, INTRINSIC_KEYS as ni, getDockerImageBySourceHash as nl, reachableDivergentParameters as nn, repairMalformedResourceEntriesForReadOnly as no, ccRoutedFinalSnapshotError as nr, readsNoEchoSource as ns, keptForReadoption as nt, perType as o, hasReadableResources as oa, acceptedCreateOnlyDropsOf as oc, s3BucketArn as oi, getLegacyStateBucketName as ol, exportAliasCollisionScrubWarning as on, unreadableOrphanRecords as oo, refusesFinalSnapshot as or, markSameGenerationBag as os, displacedPhysicalIdShown as ot, resolveDynamoDbDeleteBudgetClock as p, malformedLocalResourceEntriesWarning as pa, importableOutputs as pc, refuseUnreadableCdkCrossAccountRefs as pi, resolveStateBucketWithDefaultAndSource as pl, isWholeDynamicReferenceValue as pn, NO_CC_HANDLERS_REASON as po, isRefusedByName as pr, literalSplitDelimitersOf as ps, withNestedRevertRun as pt, keptWholeReasonText as q, refuseMalformedResourcePropertiesForExport as qa, isMalformedEnvKey as qc, parameterInputsFor as qi, secretNamePrintingBags as qn, maskAtCoordinates as qo, isWaitAbandonedError as qr, WHOLE_DYNAMIC_REFERENCE_PATTERN as qs, inheritProducerRegions as qt, recordedProtectionNote as r, displayLogicalId as ra, isAccessDenied$1 as rc, IntrinsicFunctionResolver as ri, Synthesizer as rl, resourcesNamingDeclaredParameter as rn, repairMalformedResourcePropertiesForReadOnly as ro, createPreDeleteFinalSnapshot as rr, recordedNoEchoValuesOf as rs, recordRetainedForReadoption as rt, readProtection as s, isReadableOrphanRecord as sa, describeRegionValueKind as sc, s3BucketDomainName as si, loadCdkJson as sl, secretBearing as sn, unreadableResourceEntries as so, unsupportedFinalSnapshotError as sr, redactForState as ss, dropSettledNestedJournals as st, DeployEngine as t, accountArgs as ta, applyCrossPrefixScan as tc, DiffCalculator as ti, AssetManifestLoader as tl, namesAnyDeclaredParameter as tn, repairMalformedOutputsForReadOnly as to, buildFinalSnapshotIdentifier as tr, readbackPathFor as ts, resolvePendingCloudControlRequests as tt, beginDeleteWait as u, malformedExportNamesWarning as ua, hasReasonlessBaselineRefusal as uc, s3BucketWebsiteUrl as ui, resolveCaptureObservedState as ul, carriedExportAliasExposure as un, findSilentDropProperties as uo, reserveStackCreateToken as ur, carryLogOnlyValues as us, recordDisplacedSkips as ut, maskedLogger as v, malformedOrphansRefusalMessage as va, AssetPublisher as vc, applyRoleArnIfSet as vi, CFN_TEMPLATE_BODY_LIMIT as vl, bindingSkippedOutputs as vn, isStatefulRecreateTargetForReplace as vo, readTagList as vr, shareLogOnlyValues as vs, dropFailedCommands as vt, isTruthyCfnBoolean as w, malformedResourcePropertiesWarning as wa, loadPublishableAssetManifest as wc, AWS_CREDENTIAL_ENV_KEYS as wi, decodeListingKey as wl, formatDestructiveChange as wn, toCfnInteger as wo, CC_BROKEN_REASON as wr, scrubResourceRecord as ws, sameJournaledOrphans as wt, ECR_AUTO_DELETE_IMAGES_TAG as x, malformedOutputsWarning as xa, WorkGraph as xc, explicitRoleArnOrThrow as xi, findLargeInlineResources as xl, maskingRetryLogger as xn, WARM_THROUGHPUT_MEMBERS as xo, tagPlanWarning as xr, errorCauseChain as xs, journaledOrphanLines as xt, relayedIndexBusyDelete as y, malformedOrphansWarning as ya, isSensitiveAttributeName as yc, assertFlagRoleArn as yi, CFN_TEMPLATE_URL_LIMIT as yl, DEFAULT_RESOURCE_TIMEOUT_MS as yn, isStatefulRecreateTargetSync as yo, refuseMalformedDesiredTags as yr, unionOfSecretBags as ys, dropFailedHint as yt, templateIdentity as z, refuseMalformedResourceEntries as za, describeDockerCapturedOutput as zc, isNamelessDynamicReferenceError as zi, displayAssemblyPath as zl, noEchoParameterNamesOf as zn, withRetry as zo, slowCcOperationTimeoutMs as zr, carriesSecretMask as zs, recheckFailedPlan as zt };
49310
- //# sourceMappingURL=deploy-engine-B0ObJCy0.js.map
50392
+ export { DeploymentEventsStore as $, refuseMalformedOutputsForDestroy as $a, validateAssetBucketName as $c, carriesDynamicReference as $i, hasPlainPrototype$1 as $l, noEchoComparisonForTemplate as $n, templateResourceTypes as $o, customResourceResponseExpirationWarning as $r, recordPhysicalNameCopy as $s, updatePartialReason as $t, inheritedProvenanceForChildDiff as A, malformedLocalResourcesWarning as Aa, importableOutputKeys as Ac, keepHeldTokenProvenance as Ai, resolveSkipPrefix as Al, formatDestructiveChange as An, hasNoCloudControlHandlers as Ao, markDeleteStarted as Ar, logOnlyValueCount as As, replayFailedOperations as At, conditionFingerprint as B, malformedResourcePropertiesWarning as Ba, WorkGraph as Bc, AWS_CREDENTIAL_ENV_KEYS as Bi, findLargeInlineResources as Bl, red as Bn, toCfnInteger as Bo, CC_BROKEN_REASON as Br, scrubResourceRecord as Bs, recordUnderIdIsNotOwn as Bt, hasCdkAutoDeleteTag as C, isReadableOrphanRecord as Ca, splitImportedOps as Cc, s3BucketDomainName as Ci, synthesisStatusMessage as Cl, isExportAliasCollision as Cn, unreadableResourceEntries as Co, unsupportedFinalSnapshotError as Cr, redactForState as Cs, makeForeignHolderScan as Ct, IMPLICIT_DELETE_DEPENDENCIES as D, malformedExportSourceWarning as Da, hasReadableExportSet as Dc, resolveDynamicReferences as Di, resolveApp as Dl, maskingRetryLogger as Dn, unwrittenCreateOnlyReplacement as Do, withCreateTokenLedger as Dr, createUnionSecretMasker as Ds, isAccessDeniedError as Dt, markRefusedBeforeApplying as E, malformedExportNamesWarning as Ea, exportNamesCarriedFrom as Ec, s3BucketWebsiteUrl as Ei, loadCdkJson as El, DEFAULT_RESOURCE_WARN_AFTER_MS as En, findSilentDropProperties as Eo, reserveStackCreateToken as Er, carryLogOnlyValues as Es, chunks as Et, findNestedTemplateTreeDefect as F, malformedOrphansWarning as Fa, shouldRetainResource as Fc, assertFlagRoleArn as Fi, warnDeprecatedNoPrefixCliFlag as Fl, replacedDeleteFailureVerdict as Fn, isStatefulRecreateTargetSync as Fo, refuseMalformedDesiredTags as Fr, unionOfSecretBags as Fs, isJournaledOrphan as Ft, diffSecurity as G, refuseDivergentRecordRegionForDestroy as Ga, AssetModeResolver as Gc, classifyReplaySecretRegion as Gi, PARTITION_TABLE as Gl, isSupersededResourceRecord as Gn, configIntegerRefusal as Go, waitForLambdaFunctionActive as Gr, isUncertifiedBaselineMaskPosition as Gs, findNestedStackTypeChanges as Gt, parentSuppliedValues as H, malformedScrubResourceEntriesRefusalMessage as Ha, createAssetRedirectResolver as Hc, callerEnvCredentials as Hi, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Hl, addSuperseded as Hn, coerceCfnBoolean as Ho, ccBrokenReason as Hr, withoutPhysicalNameCopies as Hs, resolveReplacementOldType as Ht, isAbsoluteAssetPath as I, malformedOutputsRefusalMessage as Ia, stackInstanceIdCarriedFrom as Ic, assertSendableRoleArn as Ii, ssmResolvedValueType as Il, bold as In, renderStatefulReason as Io, tagMapAsList as Ir, createSecretMasker as Is, isReplacementOrphan as It, mergeNoChangeOutputs as J, refuseMalformedOrphanRecordsForDestroy as Ja, ensureAssetStorage as Jc, coerceParameterTypedValue as Ji, AssemblyReader as Jl, supersededHeldByOtherTypeWarning as Jn, replayWarn as Jo, isCustomResourceType as Jr, inheritNestedStackParameterAssociations as Js, REDACTED_DELETE_ADDRESS_SKIP_REASON as Jt, isSecretBearingReferenceString as K, refuseMalformedNestedChildOutputs as Ka, BOOTSTRAP_MARKER_PREFIX as Kc, producerRegionsFromState as Ki, canonicalizeRegion as Kl, removeSuperseded as Kn, configStringRefusal as Ko, TemplateNoEchoReresolver as Kr, pathCrossesDottedKey as Ks, getCurrentProducerRegions as Kt, listNestedTemplateRows as L, malformedOutputsWarning as La, AssetPublisher as Lc, explicitRoleArnOrThrow as Li, CFN_TEMPLATE_BODY_LIMIT as Ll, cyan as Ln, WARM_THROUGHPUT_MEMBERS as Lo, tagPlanWarning as Lr, errorCauseChain as Ls, planFailedOps as Lt, findServiceTokenRefusals as M, malformedOrphanRecordsWarning as Ma, isReadableBag as Mc, recordedOutputReferenceRegions as Mi, resolveStateBucketWithDefaultAndSource as Ml, destroyStackRecordsView as Mn, shownType as Mo, DBPROXY_TAG_OPTIONS as Mr, recordLogOnlyParameterValue as Ms, removeProtectionTypeList as Mt, serviceTokenBlockingReason as N, malformedOrphanRowsKeptWarning as Na, orphansAfterRollback as Nc, recordedReferenceRegions as Ni, resolveUseCdkBootstrapAssets as Nl, getStackRecords as Nn, MULTI_REGION_RECREATE_BLOCKED_TYPES as No, planTagDiff as Nr, recordLogOnlyValue as Ns, recordAfterRollbackUpdate as Nt, computeImplicitDeleteEdges as O, malformedLocalOutputsWarning as Oa, hasReasonlessBaselineRefusal as Oc, producerLookupOver as Oi, resolveAutoAssetStorage as Ol, constructPathOf as On, withoutSilentDropProperties as Oo, acquireIdempotencyToken as Or, hasMaskableValues as Os, lookupEachName as Ot, childTemplateLoader as P, malformedOrphansRefusalMessage as Pa, orphansCarriedFrom as Pc, applyRoleArnIfSet as Pi, stateBucketExistenceConfirmed as Pl, withStackRecords as Pn, isStatefulRecreateTargetForReplace as Po, readTagList as Pr, shareLogOnlyValues as Ps, demoteSupersededOrphans as Pt, DeploymentEventsReader as Q, refuseMalformedOutputs as Qa, readBootstrapMarkerBody as Qc, isImpossibleEmptyStoredAttribute as Qi, hasOwnKey as Ql, noEchoAttributeNamesOf as Qn, prefetchCreateOnlyPropertyPaths as Qo, applyCustomResourceResponseExpiration as Qr, recordAttributeIdCopy as Qs, updatePartialMessage as Qt, renderNestedTemplateTreeDefect as R, malformedRenderedContainersWarning as Ra, isSensitiveAttributeName as Rc, isIamRoleArn as Ri, CFN_TEMPLATE_URL_LIMIT as Rl, gray as Rn, coerceWarmThroughput as Ro, definedAttributes as Rr, maskSecretsInError as Rs, planRollback as Rt, S3_AUTO_DELETE_OBJECTS_TAG as S, hasReadableResources as Sa, withStackInstanceIdWithheld as Sc, s3BucketArn as Si, Synthesizer as Sl, collectPublishedOutputNames as Sn, unreadableOrphanRecords as So, refusesFinalSnapshot as Sr, markSameGenerationBag as Ss, loadJournaledOrphans as St, getPriorAttempts as T, malformedDriftResourcePropertiesWarning as Ta, describeRegionValueKind as Tc, s3BucketRegionalDomainName as Ti, getLegacyStateBucketName as Tl, DEFAULT_RESOURCE_TIMEOUT_MS as Tn, findActionableSilentDrops as To, ledgerForStack as Tr, snapshotPassProvenance as Ts, formatResourceLine as Tt, readRecordedConditionVerdicts as U, malformedStateRefusalMessage as Ua, loadPublishableAssetManifest as Uc, envCredentialsAreAssumedRole as Ui, decodeListingKey as Ul, deleteSupersededEntry as Un, coerceCfnInteger as Uo, isCustomResource as Ur, DYNAMIC_REFERENCE_TOKEN_SCAN as Us, seedsDeleteFirstGuard as Ut, conditionInputsFrom as V, malformedResourcesWarning as Va, buildAssetRedirectMap as Vc, applyCallerIdentityCredentials as Vi, uploadCfnTemplate as Vl, yellow as Vn, toFiniteNumber as Vo, ProviderRegistry as Vr, withPhysicalNameCopies as Vs, replacementNeverSwapped as Vt, withResourceDeadline as W, previewableOrphanRecords as Wa, rewriteTemplateAssetReferences as Wc, classifyRecordedSecretRegion as Wi, expectedOwnerParam as Wl, holdsSupersededResources as Wn, configBooleanRefusal as Wo, wouldReturnToSdkProvider as Wr, dynamicReferenceTokens as Ws, orphanNeedsIdentity as Wt, makeSiblingClaimReader as X, refuseMalformedOrphansForDestroy as Xa, isCrossRegionRedirect as Xc, parameterTypeMayLoseSecretIdentity as Xi, processStackMessages as Xl, supersededResourcesOf as Xn, requireConfigObject as Xo, withPrintingSecrets as Xr, recoverMaskedOutput as Xs, redactedDeleteAddressFields as Xt, makeCanonicalizePropertiesFn as Y, refuseMalformedOrphans as Ya, getBootstrapMarkerKey as Yc, isUnboundTemplateParameter as Yi, StageLoadError as Yl, supersededHolderOf as Yn, requireConfigArray as Yo, getCurrentResourceSecrets as Yr, recordNestedStackParameterExpressions as Ys, isRedactedRecordedValue as Yt, planOrphanAdoption as Z, refuseMalformedOrphansForOrphan as Za, parseBootstrapMarker as Zc, getAccountInfo as Zi, defineOwnKey as Zl, withoutSuperseded as Zn, requireConfigString as Zo, CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID as Zr, physicalNameCopiesOf as Zs, redactedDeleteAddressSkip as Zt, deleteTableWithIndexBusyRetry as _, accountArgs as _a, applyCrossPrefixScan as _c, DiffCalculator as _i, runDockerForeground as _l, exportNameNoEchoParameters as _n, repairMalformedOutputsForReadOnly as _o, buildFinalSnapshotIdentifier as _r, readbackPathFor as _s, deleteJournaledOrphans as _t, isProtectionValueActive as a, isStalePlaceholderArnAttribute as aa, recordNoEchoAttributeValues as ac, deleteIndeterminateGuards as ai, describeDockerExecFailure as al, retiredNameGenerationsLeaving as an, refuseMalformedResourceEntriesForImportSave as ao, maskEventTextWithBoundBags as ar, DagBuilder as as, displacedOpClause as at, renderAssemblyPathEscape as au, waitForIndexesSettled as b, hasReadableOrphans as ba, isNotImplemented as bc, poisonRenderedSpellingsCollidingIn as bi, AssetManifestLoader as bl, noEchoParameterValueSeed as bn, repairMalformedResourcesForReadOnly as bo, effectiveDeletionPolicy as br, valueAtCoordinate as bs, isHandledOrphan as bt, DynamoDBGlobalTableProvider as c, withSharedDrainBudget as ca, wholeStringLeavesOf as cc, withIndeterminateGuard as ci, finchSecretArgvRefusal as cl, reachableDivergentParameters as cn, refuseMalformedResourcePropertiesForDrift as co, secretNamePrintingBag as cr, isMarkedCoordinate as cs, getNestedRevertRun as ct, injectedAwsRegionValue as cu, compensateRemovedDeletionProtection as d, declaresNoEcho as da, LockManager as dc, disableInstanceApiTermination as di, isDockerClientEnvKey as dl, displayTextOrWithheld as dn, refuseMalformedResourcesForDeploy as do, secretNamedRecordNeedles as dr, maskWholeValue as ds, revertNestedChildFromJournal as dt, carriesFetchableDynamicReference as ea, splitGetAttStringForm as ec, CloudControlProvider as ei, validateContainerRepoName as el, nameGenerationCarriedFrom as en, refuseMalformedResourceAttributesForOrphan as eo, noEchoExactEchoLeavesOf as er, describeTypeWithThrottleRetry as es, pendingRequestCount as et, nullPrototypeRecord as eu, deleteBudgetKey as f, JSON_LISTING_HOLE_VALUE as fa, isLockInfoExpired as fc, ec2InstanceProtectionSite as fi, isMalformedEnvKey as fl, exportAliasCollisionScrubWarning as fn, refuseMalformedResourcesForDestroy as fo, stateSecretNameNeedles as fr, maskedLeafCoordinatesOf as fs, revertedNestedRowIds as ft, INDEX_SETTLE_POLL_INTERVAL_MS as g, UNREADABLE_RESOURCES_MAP_ROW as ga, CrossPrefixScanCache as gc, reEnableInstanceApiTermination as gi, redactedDockerCause as gl, carriedExportAliasExposure as gn, repairMalformedOrphansForReadOnly as go, PRE_DELETE_SNAPSHOT_TYPES as gr, passedNoEchoParametersOf as gs, withNestedStackContext as gt, DELETE_INDEX_WAIT_PROCEED_NOTE as h, UNREADABLE_ORPHANS_CONTAINER_ROW as ha, CrossPrefixReadError as hc, reDisableInstanceApiTermination as hi, redactedCause as hl, secretSafeKeyDisplay as hn, repairMalformedOrphanRecordsForReadOnly as ho, ATOMIC_FINAL_SNAPSHOT_TYPES as hr, noEchoOutputsComparison as hs, getCurrentNestedStackContext as ht, PROTECTION_PROPERTY_BY_TYPE as i, cfnRefValueFromPhysicalId as ia, recordMaskOnlyValuesIn as ic, UNSPECIFIED_SKIP_REASON as ii, describeDockerCapturedOutput as il, retiredNameGenerationsAfter as in, refuseMalformedResourceEntriesForImport as io, journaledOrphanPrintingBag as ir, sameLambdaFunctionAddress as is, NESTED_PENDING_PARENT_REASON as it, displayAssemblyPath as iu, deferredServiceTokenWarning as j, malformedOrphanRecordsRefusalMessage as ja, importableOutputs as jc, outputReferenceProvenanceOf as ji, resolveStateBucketWithDefault as jl, awaitInFlightSibling as jn, findReplacedReadersOfRecreateTargets as jo, DBPROXY_TAGS_WHAT as jr, printingCorpusOf as js, replayRollback as jt, crossStackOutputProvenanceSource as k, malformedLocalResourceEntriesWarning as ka, hasUnverifiableParameterRefusal as kc, refuseUnreadableCdkCrossAccountRefs as ki, resolveCaptureObservedState as kl, findDestructiveChanges as kn, NO_CC_HANDLERS_REASON as ko, isRefusedByName as kr, literalSplitDelimitersOf as ks, withApiLimit as kt, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as l, parameterInputsFor as la, WHOLE_DYNAMIC_REFERENCE_PATTERN as lc, isWaitAbandonedError as li, formatDockerLoginError as ll, resourcesNamingDeclaredParameter as ln, refuseMalformedResourcePropertiesForExport as lo, secretNamePrintingBags as lr, maskAtCoordinates as ls, nestedChildStackName as lt, clearBucketRegionCache as lu, resolveDynamoDbDeleteBudgetMs as m, STATE_RESOURCES_MALFORMED as ma, rebuildClientForBucketRegion as mc, observeThenDisableInstanceApiTermination as mi, redactDockerArgvValues as ml, secretBearingStateKeyWarning as mn, refuseMalformedState as mo, extractDeploymentEventError as mr, noEchoLeavesOf as ms, collectNestedChildUnaddressed as mt, recordedProtectionEvidence as n, keepsSecretReferenceToken as na, provenPublicValue as nc, unchangedBehindSecretReference as ni, buildDockerImage as nl, nameScopeOf as nn, refuseMalformedResourceEntriesForDeploy as no, createReadOnlyAttributeHealerFactory as nr, canonicalLambdaFunctionName as ns, keptForRetainedRecord as nt, absoluteAssemblyPathEscape as nu, perType as o, refStateLookupFromResource as oa, recordNoEchoParameterFreshValue as oc, deleteLeftInPlace as oi, describeDockerFailure as ol, computeParameterTaint as on, refuseMalformedResourceEntriesForOrphan as oo, namingSecretsWithRecordedNoEcho as or, TemplateParser as os, displacedPhysicalIdShown as ot, resolveAssemblyPath as ou, resolveDynamoDbDeleteBudgetClock as p, STATE_REGION_DIVERGED as pa, S3StateBackend as pc, isTerminationProtectionPropagationError as pi, partitionSensitiveEnv as pl, secretBearing as pn, refuseMalformedResourcesForExport as po, storedSecretNameNeedles as pr, noEchoCoordinatesOf as ps, withNestedRevertRun as pt, keptWholeReasonText as q, refuseMalformedOrphanRecords as qa, assertAssetBucketRegion as qc, regionLessSecretName as qi, derivePartitionAndUrlSuffix as ql, supersededAfterRollback as qn, readConfigString as qo, readsNoEchoDeleteValues as qr, identityKeyFor as qs, inheritProducerRegions as qt, recordedProtectionNote as r, AWS_NO_VALUE as ra, recordMaskOnlyValue as rc, RollbackInlinePolicyWriters as ri, resolveDockerContextDirectory as rl, retiredAfterRollback as rn, refuseMalformedResourceEntriesForDestroy as ro, completedReplayEntries as rr, lambdaFunctionNameForMask as rs, recordRetainedForReadoption as rt, describeFileReadFailure as ru, readProtection as s, parseWebACLArn as sa, recordProvenPublicExpression as sc, deleteSkipReason as si, dockerSpawnEnvWithSensitive as sl, namesAnyDeclaredParameter as sn, refuseMalformedResourcePropertiesForDestroy as so, orphanRecordsPrintingBag as sr, canonicalCoordinates as ss, dropSettledNestedJournals as st, injectAwsRegion as su, DeployEngine as t, isNamelessDynamicReferenceError as ta, carriesSecretMask as tc, slowCcOperationTimeoutMs as ti, buildDenyExternalAccessPolicy as tl, nameGenerationHighWaterOf as tn, refuseMalformedResourceEntries as to, noEchoParameterNamesOf as tr, withRetry as ts, resolvePendingCloudControlRequests as tt, ownValue as tu, beginDeleteWait as u, passedParameterClassesOf as ua, isSingleDynamicReferenceToken as uc, markWaitAbandoned as ui, getDockerCmd as ul, WITHHELD_NAME_DISPLAY as un, refuseMalformedResourcePropertiesForOrphan as uo, secretNamedAttributeNamesOf as ur, maskReadbackAtCoordinates as us, recordDisplacedSkips as ut, resolveBucketRegion as uu, maskedLogger as v, deployRefusesOrphanRowsReason as va, crossPrefixDeniedWarning as vc, INTRINSIC_KEYS as vi, runDockerStreaming as vl, exportNameSecretExposure as vn, repairMalformedResourceEntriesForReadOnly as vo, ccRoutedFinalSnapshotError as vr, readsNoEchoSource as vs, dropFailedCommands as vt, isTruthyCfnBoolean as w, isReadableResourceEntry as wa, acceptedCreateOnlyDropsOf as wc, s3BucketDualStackDomainName as wi, getDefaultStateBucketName as wl, bindingSkippedOutputs as wn, withheldAccountClause as wo, earliestDefined as wr, recordReferenceProvenanceEntry as ws, sameJournaledOrphans as wt, ECR_AUTO_DELETE_IMAGES_TAG as x, hasReadableOutputs as xa, stackInstanceIdOf as xc, isSettledInstanceState as xi, getDockerImageBySourceHash as xl, collectDeclaredOutputNames as xn, unpreviewableOrphanRecords as xo, isFinalSnapshotError as xr, liveMatchesUnresolvedTokenFrame as xs, journaledOrphanLines as xt, relayedIndexBusyDelete as y, displayLogicalId as ya, isAccessDenied$1 as yc, IntrinsicFunctionResolver as yi, warnFinchArgvExposure as yl, isWholeDynamicReferenceValue as yn, repairMalformedResourcePropertiesForReadOnly as yo, createPreDeleteFinalSnapshot as yr, recordedNoEchoValuesOf as ys, dropFailedHint as yt, templateIdentity as z, malformedResourceEntriesWarning as za, stringifyValue as zc, sendableAssumeRoleCommand as zi, MIGRATE_TMP_PREFIX as zl, green as zn, isWarmThroughputDecrease as zo, stringifyIfAssigned as zr, maskSecretsInText as zs, recheckFailedPlan as zt };
50393
+ //# sourceMappingURL=deploy-engine-DU0BoQqo.js.map