@go-to-k/cdkd 0.296.13 → 0.296.15

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 (29) hide show
  1. package/dist/{asg-provider-DeeIdM5B.js → asg-provider-BbWC_1l5.js} +4 -4
  2. package/dist/{asg-provider-DeeIdM5B.js.map → asg-provider-BbWC_1l5.js.map} +1 -1
  3. package/dist/{logger-DAaB7GFO.js → aws-failure-text-BaWeCWRz.js} +45 -2
  4. package/dist/aws-failure-text-BaWeCWRz.js.map +1 -0
  5. package/dist/cli.js +2 -2
  6. package/dist/{deploy-engine-FDsHckZR.js → deploy-engine-CjLZZzyn.js} +553 -481
  7. package/dist/deploy-engine-CjLZZzyn.js.map +1 -0
  8. package/dist/{iam-policy-targets-elNafvpb.js → iam-policy-targets-BoZuWtxK.js} +43 -49
  9. package/dist/iam-policy-targets-BoZuWtxK.js.map +1 -0
  10. package/dist/{iam-role-provider-BuWI_oJp.js → iam-role-provider-DAqNwSNR.js} +4 -4
  11. package/dist/{iam-role-provider-BuWI_oJp.js.map → iam-role-provider-DAqNwSNR.js.map} +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +4 -4
  14. package/dist/{neptune-provider-Bdc1YYxL.js → neptune-provider-DlSon_pZ.js} +4 -4
  15. package/dist/{neptune-provider-Bdc1YYxL.js.map → neptune-provider-DlSon_pZ.js.map} +1 -1
  16. package/dist/{program-1S4fU3m4.js → program-CqKPsOUR.js} +175 -119
  17. package/dist/program-CqKPsOUR.js.map +1 -0
  18. package/dist/{provider-classes-hW6X0dKh.js → provider-classes-Drnm0GAz.js} +193 -74
  19. package/dist/provider-classes-Drnm0GAz.js.map +1 -0
  20. package/dist/{rds-provider-Q1U7N7ee.js → rds-provider-e6XtJAGl.js} +4 -4
  21. package/dist/{rds-provider-Q1U7N7ee.js.map → rds-provider-e6XtJAGl.js.map} +1 -1
  22. package/dist/{version-B9EuX7Oh.js → version-Bdg2mYAM.js} +2 -2
  23. package/dist/{version-B9EuX7Oh.js.map → version-Bdg2mYAM.js.map} +1 -1
  24. package/package.json +1 -1
  25. package/dist/deploy-engine-FDsHckZR.js.map +0 -1
  26. package/dist/iam-policy-targets-elNafvpb.js.map +0 -1
  27. package/dist/logger-DAaB7GFO.js.map +0 -1
  28. package/dist/program-1S4fU3m4.js.map +0 -1
  29. package/dist/provider-classes-hW6X0dKh.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  import { r as getAwsClients, s as __exportAll } from "./aws-clients-CnmtbrxD.js";
2
- import { A as displayIdent, C as withoutGeneratedFallbackName, D as UNRENDERABLE, E as STACK_REF_MAX_CODE_POINTS, F as plainIdentOr, I as safeMsg, M as displayStackName, N as isPasteableIdent, R as truncateCodePoints, S as withStackName, T as SECRET_REF_MAX_CODE_POINTS, _ as generateResourceNameWithFallback, b as looksLikeCdkdGeneratedName, c as installLogLineMaskerSource, g as generateResourceName, h as explicitNamePropertyFor, j as displaySafe, k as displayAwsMessage, l as getLiveRenderer, n as getLogger, p as applyDefaultNameForFallback, r as isStdoutReservedForPayload, s as currentLogLineMasker, v as getCurrentSkipPrefix, x as withSkipPrefix, y as getCurrentStackName } from "./logger-DAaB7GFO.js";
3
- import { $n as retryClassificationText, A as refusalTypeShown, An as pasteableCommand, At as UNREPRODUCIBLE_LOCK_CLAUSE, B as protectionFlipKey, Bn as hasReplayMayCollide, Bt as injectiveKey, C as assertRegionMatch, Ct as createdBeforeFailure, D as isQuotableImportValue, Dn as commandHole, Dt as isAuxiliaryMarkOf, En as UNSHOWABLE_VALUE, Et as isAuxiliaryFailure, F as compensateProtectionFlip, Fn as shellQuote, Ft as formatLockOperation, G as DELETION_PROTECTION_DOC_POINTER, Gt as withPasteableAwsProfile, H as runDeleteAttempt, Hn as isNameCooldownError, I as deleteWithProtectionCompensation, In as withheldTargetClause, It as formatLockOwner, Jn as isAmbiguousCcHandlerErrorCode, Jt as clientDefaultsFor, Kn as markReplayMayCollide, Kt as ambientClientDefaults, L as isTerminalDeleteFailure, Lt as sanitizeRecoveryValue, M as resolveExplicitPhysicalId, Mn as plainOrDescribed, Nn as quotedOrDescribed, O as normalizeAwsTagsToCfn, Ot as markAuxiliaryFailure, P as ProtectionFlipRegistry, Pn as shellBoundedDisplay, Pt as formatLockExpiry, Qn as isTransientServerError, Qt as CdkdError, Rt as CUSTOM_RESOURCE_RESPONSE_PREFIX, S as RESOURCE_NOT_FOUND, Tn as SHELL_ACTIVE_WHY, Tt as hasCreatedBeforeFailure, Un as isRecreateRetryableError, Ut as producerRecordKey, Vn as isNameCollisionErrorFrom, Wn as isReplayedNameCollisionFrom, X as protectedReplacementAdvice, Xn as isIamPropagationError, Xt as AccountIdUnavailableError, Y as pasteableAwsCommand, Yn as isAmbiguousOutcomeError, Yt as credentialFingerprint, Zn as isRetryableTransientError, Zt as AssetError, _n as StateError, _t as maskDeep, ar as isThrottlingError, at as canonicalizeRoute53QueryName, bt as RETRY_AUXILIARY_OWNER, cn as MacroExpansionError, cr as wrapMaskedAwsError, d as prepareRemovalForUpdate, dt as resourceTypeShown, en as CrossAccountSecretRefusalError, er as describeAwsFailure, f as removalWarning, fn as ProvisioningError, ft as segmentAfterAnchor, gt as isSecretDerivedValue, ht as createMaskedRetryLogger, i as holdsSecretDerivedEntry, in as IntrinsicResolutionRefusalError, ir as isMarkedNonRetryable, it as monotonicNowMs, jn as physicalIdShownBesideCommand, jt as buildForceUnlockCommand, k as quotedRemedyLogicalId, kn as isInertUnquoted, kt as markCreatedBeforeFailure, l as withUnchangedSecretPrincipalLists, ln as MalformedProducerRecordRefusalError, lt as logicalIdShown, m as withoutInjectedRemovals, mn as ResourceUpdateNotSupportedError, mt as createMaskedLogSinks, nr as safeStringify$1, nt as startInterruptWatch, or as markNonRetryable, pn as ResourceTimeoutError, pt as stateOrphanRecordRemedy, qn as formatRetryClassificationSignals, qt as ambientCredentialConfig, rn as DynamicReferenceRegionAmbiguousError, rt as ElapsedBudgetRegistry, sn as LockError, sr as markRedactedCause, st as compositeIdSeparatorRefusal, tn as DependencyError, tt as isInterruptedWaitError, vn as SynthesisError, vt as maskerOrIdentity, wn as SHELL_ACTIVE, wt as createdResourceIdentityBeforeFailure, x as withoutServerErrorRetries, xn as normalizeAwsError, xt as carryCreatedBeforeFailure, yt as withDerivedNameMasks, z as observeThenDisableProtection, zn as isUpdateUnsupportedError, zt as DEFAULT_STATE_PREFIX } from "./iam-policy-targets-elNafvpb.js";
2
+ import { A as UNRENDERABLE, C as looksLikeCdkdGeneratedName, E as withoutGeneratedFallbackName, F as displayStackName, I as isPasteableIdent, M as displayAwsMessage, N as displayIdent, O as SECRET_REF_MAX_CODE_POINTS, P as displaySafe, R as plainIdentOr, S as getCurrentStackName, T as withStackName, V as truncateCodePoints, a as getLogger, b as generateResourceNameWithFallback, d as installLogLineMaskerSource, f as getLiveRenderer, g as applyDefaultNameForFallback, k as STACK_REF_MAX_CODE_POINTS, o as isStdoutReservedForPayload, r as safeStringify$1, t as describeAwsFailure, u as currentLogLineMasker, v as explicitNamePropertyFor, w as withSkipPrefix, x as getCurrentSkipPrefix, y as generateResourceName, z as safeMsg } from "./aws-failure-text-BaWeCWRz.js";
3
+ import { $ as protectedReplacementAdvice, $n as isIamPropagationError, $t as AccountIdUnavailableError, A as isQuotableImportValue, An as commandHole, At as isAuxiliaryMarkOf, B as isTerminalDeleteFailure, Bt as sanitizeRecoveryValue, Ct as RETRY_AUXILIARY_OWNER, Dn as SHELL_ACTIVE, Dt as createdResourceIdentityBeforeFailure, E as assertRegionMatch, Et as createdBeforeFailure, F as resolveExplicitPhysicalId, Fn as plainOrDescribed, G as runDeleteAttempt, Gn as isNameCooldownError, H as observeThenDisableProtection, Hn as isUpdateUnsupportedError, Ht as DEFAULT_STATE_PREFIX, In as quotedOrDescribed, J as DELETION_PROTECTION_DOC_POINTER, Jt as withPasteableAwsProfile, Kn as isRecreateRetryableError, Kt as producerRecordKey, L as ProtectionFlipRegistry, Ln as shellBoundedDisplay, Lt as formatLockExpiry, M as quotedRemedyLogicalId, Mn as isInertUnquoted, Mt as markCreatedBeforeFailure, N as refusalTypeShown, Nn as pasteableCommand, Nt as UNREPRODUCIBLE_LOCK_CLAUSE, On as SHELL_ACTIVE_WHY, Ot as hasCreatedBeforeFailure, Pn as physicalIdShownBesideCommand, Pt as buildForceUnlockCommand, Q as pasteableAwsCommand, Qn as isAmbiguousOutcomeError, Qt as credentialFingerprint, R as compensateProtectionFlip, Rn as shellQuote, Rt as formatLockOperation, St as withDerivedNameMasks, T as RESOURCE_NOT_FOUND, U as protectionFlipKey, Un as hasReplayMayCollide, Ut as injectiveKey, Vt as CUSTOM_RESOURCE_RESPONSE_PREFIX, Wn as isNameCollisionErrorFrom, Xn as formatRetryClassificationSignals, Xt as ambientCredentialConfig, Yn as markReplayMayCollide, Yt as ambientClientDefaults, Zn as isAmbiguousCcHandlerErrorCode, Zt as clientDefaultsFor, _n as ResourceUpdateNotSupportedError, _t as createMaskedLogSinks, ar as isThrottlingError, at as startInterruptWatch, bn as StateError, bt as maskDeep, cr as wrapMaskedAwsError, ct as canonicalizeRoute53QueryName, d as prepareRemovalForUpdate, dn as MacroExpansionError, en as AssetError, er as isRetryableTransientError, f as removalWarning, fn as MalformedProducerRecordRefusalError, ft as logicalIdShown, gn as ResourceTimeoutError, gt as stateOrphanRecordRemedy, hn as ProvisioningError, ht as segmentAfterAnchor, i as holdsSecretDerivedEntry, in as DependencyError, ir as isMarkedNonRetryable, it as isInterruptedWaitError, j as normalizeAwsTagsToCfn, jt as markAuxiliaryFailure, kn as UNSHOWABLE_VALUE, kt as isAuxiliaryFailure, l as withUnchangedSecretPrincipalLists, m as withoutInjectedRemovals, mt as resourceTypeShown, nr as retryClassificationText, on as DynamicReferenceRegionAmbiguousError, or as markNonRetryable, ot as ElapsedBudgetRegistry, qn as isReplayedNameCollisionFrom, rn as CrossAccountSecretRefusalError, sn as IntrinsicResolutionRefusalError, sr as markRedactedCause, st as monotonicNowMs, tn as CdkdError, tr as isTransientServerError, un as LockError, ut as compositeIdSeparatorRefusal, vt as createMaskedRetryLogger, w as withoutServerErrorRetries, wn as normalizeAwsError, wt as carryCreatedBeforeFailure, xn as SynthesisError, xt as maskerOrIdentity, yt as isSecretDerivedValue, z as deleteWithProtectionCompensation, zn as withheldTargetClause, zt as formatLockOwner } from "./iam-policy-targets-BoZuWtxK.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-D0q0z4dG.js";
5
- import { t as getCdkdVersion } from "./version-B9EuX7Oh.js";
5
+ import { t as getCdkdVersion } from "./version-Bdg2mYAM.js";
6
6
  import { createHash, randomUUID } from "node:crypto";
7
7
  import { AsyncLocalStorage } from "node:async_hooks";
8
8
  import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -1279,7 +1279,7 @@ var ContextProviderRegistry = class {
1279
1279
  results[entry.key] = value;
1280
1280
  this.logger.debug(`Resolved context: ${shownKey}`);
1281
1281
  } catch (error) {
1282
- const message = displayAwsMessage(error instanceof Error ? error.message : String(error));
1282
+ const message = displayAwsMessage(describeAwsFailure(error).detail);
1283
1283
  this.logger.error(`Context provider '${shownProvider}' failed: ${message}`);
1284
1284
  results[entry.key] = {
1285
1285
  [PROVIDER_ERROR_KEY]: message,
@@ -1423,6 +1423,9 @@ const PARTITION_TABLE = [
1423
1423
  function canonicalizeRegion(region) {
1424
1424
  return typeof region === "string" ? region.toLowerCase() : region;
1425
1425
  }
1426
+ function sameRegion(a, b) {
1427
+ return canonicalizeRegion(a) === canonicalizeRegion(b);
1428
+ }
1426
1429
  function derivePartitionAndUrlSuffix(region) {
1427
1430
  const canonical = canonicalizeRegion(region);
1428
1431
  for (const { prefix, partition, urlSuffix } of PARTITION_TABLE) if (canonical.startsWith(prefix)) return {
@@ -1493,7 +1496,7 @@ function resolveExpectedBucketOwner(client) {
1493
1496
  secretAccessKey: credentials.secretAccessKey
1494
1497
  });
1495
1498
  } catch (error) {
1496
- getLogger().debug(`ExpectedBucketOwner resolution skipped (header omitted): ${String(error)}`);
1499
+ getLogger().debug(`ExpectedBucketOwner resolution skipped (header omitted): ${safeStringify$1(error)}`);
1497
1500
  clientCache.delete(client);
1498
1501
  return;
1499
1502
  }
@@ -1510,7 +1513,7 @@ async function recordResolvedAccountId(client, accountId) {
1510
1513
  if (credentialsCache.has(accessKeyId)) return;
1511
1514
  credentialsCache.set(accessKeyId, Promise.resolve(accountId));
1512
1515
  } catch (error) {
1513
- getLogger().debug(`ExpectedBucketOwner seed skipped: ${String(error)}`);
1516
+ getLogger().debug(`ExpectedBucketOwner seed skipped: ${safeStringify$1(error)}`);
1514
1517
  }
1515
1518
  }
1516
1519
  async function expectedOwnerParam(client) {
@@ -1674,7 +1677,7 @@ function recordFailure(failed, key, reason) {
1674
1677
  if (existing) existing.push(reason);
1675
1678
  else failed.set(key, [reason]);
1676
1679
  }
1677
- const describe$1 = (error) => error instanceof Error ? error.message : String(error);
1680
+ const describe$1 = (error) => describeAwsFailure(error).detail;
1678
1681
  const PREFIX_HANDLE_SUFFIX = "* (every key under this prefix)";
1679
1682
  async function purgeNoncurrentVersionsUnderPrefix(s3Client, bucket, prefix, options = {}) {
1680
1683
  const logger = options.logger ?? getLogger().child("s3-version-purge");
@@ -2159,7 +2162,7 @@ function parseTemplateBody(body) {
2159
2162
  return parsed;
2160
2163
  }
2161
2164
  function formatErr(err) {
2162
- return displayAwsMessage(err instanceof Error ? err.message : String(err));
2165
+ return displayAwsMessage(describeAwsFailure(err).detail);
2163
2166
  }
2164
2167
 
2165
2168
  //#endregion
@@ -4113,7 +4116,7 @@ var AssetModeResolver = class {
4113
4116
  marker
4114
4117
  };
4115
4118
  } catch (error) {
4116
- const message = error instanceof Error ? error.message : String(error);
4119
+ const message = describeAwsFailure(error).detail;
4117
4120
  this.logger.warn(`Failed to auto-create cdkd asset storage for region ${quotedIfPlain(region, "that is not a plain identifier")}: ${message} Falling back to the CDK bootstrap destinations for this run — opt the region in with S3/ECR create permissions.\nBootstrap with: ${pasteableCommand("cdkd bootstrap", [{
4118
4121
  flag: "--region",
4119
4122
  value: region,
@@ -4445,7 +4448,7 @@ var WorkGraph = class {
4445
4448
  nodeId: node.id,
4446
4449
  error
4447
4450
  });
4448
- this.logger.error(`Failed: ${node.id}: ${error instanceof Error ? error.message : String(error)}`);
4451
+ this.logger.error(`Failed: ${node.id}: ${describeAwsFailure(error).detail}`);
4449
4452
  }).finally(() => {
4450
4453
  active[node.type]--;
4451
4454
  dispatch();
@@ -4459,7 +4462,7 @@ var WorkGraph = class {
4459
4462
  }
4460
4463
  if (errors.length > 0) {
4461
4464
  const skippedCount = [...this.nodes.values()].filter((n) => n.state === "skipped").length;
4462
- const msg = errors.map((e) => ` - ${e.nodeId}: ${e.error instanceof Error ? e.error.message : String(e.error)}`).join("\n");
4465
+ const msg = errors.map((e) => ` - ${e.nodeId}: ${describeAwsFailure(e.error).detail}`).join("\n");
4463
4466
  reject(/* @__PURE__ */ new Error(`${errors.length} node(s) failed${skippedCount > 0 ? `, ${skippedCount} skipped` : ""}:\n${msg}`));
4464
4467
  return;
4465
4468
  }
@@ -8656,7 +8659,7 @@ function canonicalJson$3(value) {
8656
8659
  });
8657
8660
  }
8658
8661
  const PREVIOUS_NOECHO_VALUE = "(previous NoEcho value)";
8659
- function parametersReadBy(node, sources) {
8662
+ function noEchoParametersReadBy(node, sources) {
8660
8663
  return [...sources.parameters].filter((name) => readsNoEchoSource(node, {
8661
8664
  parameters: /* @__PURE__ */ new Set([name]),
8662
8665
  ...sources.conditions !== void 0 && { conditions: sources.conditions }
@@ -8667,7 +8670,7 @@ function noEchoComparison(options) {
8667
8670
  return ({ templateProperties, desired, current, record }) => {
8668
8671
  const coordinates = noEchoCoordinatesOf(templateProperties, desired, sources);
8669
8672
  const needles = [];
8670
- for (const name of parametersReadBy(templateProperties, sources)) {
8673
+ for (const name of noEchoParametersReadBy(templateProperties, sources)) {
8671
8674
  const value = values[name];
8672
8675
  const leaves = Array.isArray(value) ? value : [value];
8673
8676
  for (const leaf of leaves) if (typeof leaf === "string" && leaf.length >= minNeedleLength && !isSingleDynamicReferenceToken(leaf)) needles.push(leaf);
@@ -10910,6 +10913,14 @@ const CASE_INSENSITIVE_NAME_TYPES = /* @__PURE__ */ new Set([
10910
10913
  "AWS::RDS::DBSubnetGroup"
10911
10914
  ]);
10912
10915
  const ASCII_CASE_INSENSITIVE_NAME_TYPES = /* @__PURE__ */ new Set(["AWS::Glue::Table"]);
10916
+ function physicalIdKey(resourceType, physicalId) {
10917
+ if (CASE_INSENSITIVE_NAME_TYPES.has(resourceType)) return physicalId.toLowerCase();
10918
+ if (ASCII_CASE_INSENSITIVE_NAME_TYPES.has(resourceType)) return physicalId.replace(/[A-Z]/g, (c) => c.toLowerCase());
10919
+ return physicalId;
10920
+ }
10921
+ function samePhysicalId(resourceType, a, b) {
10922
+ return physicalIdKey(resourceType, a) === physicalIdKey(resourceType, b);
10923
+ }
10913
10924
  const NO_PHYSICAL_ID_NAME_PROOF = /* @__PURE__ */ new Set(["AWS::Glue::Table"]);
10914
10925
  const GENERATED_NAME_VERBATIM = /* @__PURE__ */ new Set([
10915
10926
  "AWS::CloudWatch::Alarm",
@@ -12162,6 +12173,10 @@ const CHILD_STORED_IN_PARENT = {
12162
12173
  properties: ["GroupName"],
12163
12174
  parentTypes: [IAM_GROUP]
12164
12175
  },
12176
+ "AWS::ApplicationAutoScaling::ScalingPolicy": {
12177
+ properties: ["ScalingTargetId"],
12178
+ parentTypes: ["AWS::ApplicationAutoScaling::ScalableTarget"]
12179
+ },
12165
12180
  "AWS::IAM::Policy": {
12166
12181
  properties: [
12167
12182
  "Roles",
@@ -19025,7 +19040,7 @@ async function resolveImportValue(importValueArg, context) {
19025
19040
  }
19026
19041
  function recordImport(context, exportName, producerStack, producerRegion) {
19027
19042
  if (!context.recordedImports) return;
19028
- if (context.recordedImports.some((e) => e.exportName === exportName && e.sourceStack === producerStack && e.sourceRegion === producerRegion)) return;
19043
+ if (context.recordedImports.some((e) => e.exportName === exportName && e.sourceStack === producerStack && sameRegion(e.sourceRegion, producerRegion))) return;
19029
19044
  context.recordedImports.push({
19030
19045
  exportName,
19031
19046
  sourceStack: producerStack,
@@ -19077,7 +19092,7 @@ async function fetchAllCfnExports() {
19077
19092
  return exports;
19078
19093
  }
19079
19094
  async function lookupCfnStackOutputs(stackName, region, context, loggedRegionText) {
19080
- const cacheKey = injectiveKey(region, stackName, credentialFingerprint(ambientCredentialConfig()));
19095
+ const cacheKey = injectiveKey(canonicalizeRegion(region), stackName, credentialFingerprint(ambientCredentialConfig()));
19081
19096
  let fetch = this.cfnStackOutputsCache.get(cacheKey);
19082
19097
  if (!fetch) {
19083
19098
  fetch = this.fetchCfnStackOutputs(stackName, region);
@@ -19107,7 +19122,8 @@ async function fetchCfnStackOutputs(stackName, region) {
19107
19122
  throw error;
19108
19123
  }
19109
19124
  }
19110
- function getCfnClient(region) {
19125
+ function getCfnClient(rawRegion) {
19126
+ const region = canonicalizeRegion(rawRegion);
19111
19127
  const credentialConfig = ambientCredentialConfig();
19112
19128
  const key = clientCacheKey(region, credentialConfig);
19113
19129
  let client = this.cfnClients.get(key);
@@ -19149,7 +19165,7 @@ async function resolveGetStackOutput(arg, context) {
19149
19165
  if (typeof raw !== "string" || raw === "") throw markNonRetryable(/* @__PURE__ */ new Error(`Fn::GetStackOutput: RoleArn must be a literal string in the template (no Ref / Fn::GetAtt / Fn::Sub allowed for cross-account references). Got ${raw === null ? "null" : Array.isArray(raw) ? "array" : typeof raw}${typeof raw === "object" ? ` (intrinsic shape: ${this.displayMasked(JSON.stringify(raw).slice(0, 80), context)})` : ""}.`));
19150
19166
  roleArn = raw;
19151
19167
  }
19152
- if (!roleArn && context.stackName && context.stackName === stackName && canonicalizeRegion(region) === canonicalizeRegion(this.resolverRegion)) throw markNonRetryable(/* @__PURE__ */ new Error(`Fn::GetStackOutput: cannot reference own stack ${this.displayMaskedIdent(stackName, context, STACK_REF_MAX_CODE_POINTS)} in the same region ${this.displayMaskedIdent(loggedRegionText, context)}`));
19168
+ if (!roleArn && context.stackName && context.stackName === stackName && sameRegion(region, this.resolverRegion)) throw markNonRetryable(/* @__PURE__ */ new Error(`Fn::GetStackOutput: cannot reference own stack ${this.displayMaskedIdent(stackName, context, STACK_REF_MAX_CODE_POINTS)} in the same region ${this.displayMaskedIdent(loggedRegionText, context)}`));
19153
19169
  const loggedStackName = this.displayMaskedIdent(stackName, context, STACK_REF_MAX_CODE_POINTS);
19154
19170
  const loggedOutputName = this.displayMaskedIdent(outputName, context);
19155
19171
  const loggedRegion = this.displayMasked(loggedRegionText, context);
@@ -19195,7 +19211,7 @@ async function resolveGetStackOutput(arg, context) {
19195
19211
  }
19196
19212
  function recordOutputRead(context, producerStack, producerRegion, outputName) {
19197
19213
  if (!context.recordedOutputReads) return;
19198
- if (context.recordedOutputReads.some((e) => e.sourceStack === producerStack && e.sourceRegion === producerRegion && e.outputName === outputName)) return;
19214
+ if (context.recordedOutputReads.some((e) => e.sourceStack === producerStack && sameRegion(e.sourceRegion, producerRegion) && e.outputName === outputName)) return;
19199
19215
  context.recordedOutputReads.push({
19200
19216
  sourceStack: producerStack,
19201
19217
  sourceRegion: producerRegion,
@@ -20926,7 +20942,7 @@ function clientsForRegion(targetRegion, targetLogText) {
20926
20942
  const cacheKey = clientCacheKey(target, ambient.credentialConfig ?? {});
20927
20943
  const cached = this.regionScopedClients.get(cacheKey);
20928
20944
  if (cached) return cached;
20929
- if (canonicalizeRegion(ambient.configuredRegion) === target) return ambient;
20945
+ if (sameRegion(ambient.configuredRegion, target)) return ambient;
20930
20946
  const scoped = ambient.withRegion(target);
20931
20947
  this.regionScopedClients.set(cacheKey, scoped);
20932
20948
  this.logger.debug(`Using region-scoped AWS clients for ${displaySafe(loggedTarget)}`);
@@ -21067,7 +21083,7 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
21067
21083
  resolverForProducerRegion(producerRegion, context, producerRegionLogText) {
21068
21084
  if (!producerRegion) return this;
21069
21085
  const target = canonicalizeRegion(producerRegion);
21070
- if (target === canonicalizeRegion(this.explicitRegion)) return this;
21086
+ if (sameRegion(target, this.explicitRegion)) return this;
21071
21087
  const regionText = producerRegionLogText !== void 0 ? canonicalizeRegion(producerRegionLogText) : this.regionLogText(producerRegion, context);
21072
21088
  const guestRegionText = this.displayMasked(regionText, context);
21073
21089
  const cached = this.producerRegionResolvers.get(target);
@@ -22700,7 +22716,7 @@ var CloudControlProvider = class {
22700
22716
  const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
22701
22717
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
22702
22718
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
22703
- const { ASGProvider } = await import("./asg-provider-DeeIdM5B.js");
22719
+ const { ASGProvider } = await import("./asg-provider-BbWC_1l5.js");
22704
22720
  const delegateRegion = ambientRegion();
22705
22721
  let asgProvider = this.asgDeleteDelegates.get(delegateRegion);
22706
22722
  if (asgProvider === void 0) {
@@ -22806,7 +22822,7 @@ var CloudControlProvider = class {
22806
22822
  const family = SDK_DELETE_FAMILIES.get(resourceType);
22807
22823
  const cached = this.sdkDeleteDelegates.get(family);
22808
22824
  if (cached !== void 0 && cached.region === ccRegion) return cached.provider;
22809
- const provider = family === "rds" ? new (await (import("./rds-provider-Q1U7N7ee.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-Bdc1YYxL.js"))).NeptuneProvider({ region: ccRegion });
22825
+ const provider = family === "rds" ? new (await (import("./rds-provider-e6XtJAGl.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-DlSon_pZ.js"))).NeptuneProvider({ region: ccRegion });
22810
22826
  this.sdkDeleteDelegates.set(family, {
22811
22827
  region: ccRegion,
22812
22828
  provider
@@ -27520,6 +27536,20 @@ function exportNameSecretExposure(exportName, substitutedIntoName, recordedThisP
27520
27536
  }
27521
27537
  return exposure.size > 0 ? exposure : void 0;
27522
27538
  }
27539
+ function carriedExportAliasExposure(exportName, recordedThisPass, noEchoParameterValues) {
27540
+ const carried = /* @__PURE__ */ new Map();
27541
+ shareLogOnlyValues(carried, recordedThisPass);
27542
+ const exposure = exportNameSecretExposure(exportName, carried, recordedThisPass, noEchoParameterValues);
27543
+ if (exposure === void 0) return void 0;
27544
+ return {
27545
+ exposure,
27546
+ noEchoOnly: isNoEchoOnlyExposure(exposure, carried, recordedThisPass)
27547
+ };
27548
+ }
27549
+ function exportNameNoEchoParameters(exportName, sources) {
27550
+ if (sources === void 0 || exportName === null || typeof exportName !== "object") return [];
27551
+ return noEchoParametersReadBy(exportName, sources);
27552
+ }
27523
27553
  function isNoEchoOnlyExposure(exposure, substitutedIntoName, recordedThisPass) {
27524
27554
  for (const plaintext of exposure.keys()) if (substitutedIntoName.has(plaintext) || recordedThisPass?.has(plaintext) === true) return false;
27525
27555
  return exposure.size > 0;
@@ -27569,6 +27599,11 @@ function secretBearingExportNameWarning(outputKey, exportName, exposure, secrets
27569
27599
  if (noEchoOnly) return `Output ${owner} has an Export.Name that resolves to a value containing a secret ${shown}— skipping the export alias. The name contains the value of a NoEcho template parameter, or a value derived from one: the whole name at any length, or embedded at 4 or more characters, even where the match is a coincidence. An export name becomes a key in state.json and in the exports index, where the value would be stored in plaintext. An existing Fn::ImportValue of this name stops resolving. Rename the export, or choose a NoEcho value the name does not contain.`;
27570
27600
  return `Output ${owner} has an Export.Name that resolves to a value containing a secret ${shown}— skipping the export alias. An export name becomes a key in state.json and in the exports index, and redaction rewrites VALUES only, so publishing it would persist the secret in plaintext. Use a non-secret Export.Name.`;
27571
27601
  }
27602
+ function noEchoParameterExportNameWarning(outputKey, parameterNames, secrets) {
27603
+ const owner = displayTextOrWithheld(secretSafeKeyDisplay(outputKey, printingCorpusOf(secrets)));
27604
+ const names = parameterNames.map((name) => displayIdent(name, { listMember: true })).join(", ");
27605
+ return `Output ${owner} has an Export.Name that reads the NoEcho template ${parameterNames.length === 1 ? "parameter" : "parameters"} ${names} — skipping the export alias. An export name becomes a key in state.json and in the exports index, where the value would be stored in plaintext, so a name built from a NoEcho parameter is refused whatever the value's length. An existing Fn::ImportValue of this name stops resolving. Build the Export.Name without the NoEcho parameter.`;
27606
+ }
27572
27607
  function mergedExposure(a, b) {
27573
27608
  if (a === void 0) return b;
27574
27609
  if (b === void 0) return a;
@@ -27653,6 +27688,7 @@ function handleOutputResolutionFailure(error, outputKey, outputs, secrets, inher
27653
27688
  }
27654
27689
  async function resolveOutputs(template, resources, stackName, digestSource, parameterValues, conditions) {
27655
27690
  this.resolvedExportNames = [];
27691
+ this.carriedExportAliasRefusal = void 0;
27656
27692
  if (!template.Outputs) return {};
27657
27693
  const outputs = Object.create(null);
27658
27694
  const context = this.buildResolverContext({
@@ -27692,6 +27728,12 @@ async function resolveOutputs(template, resources, stackName, digestSource, para
27692
27728
  }
27693
27729
  }
27694
27730
  const noEchoSeed = noEchoParameterValueSeed(template.Parameters, parameterValues, context.inheritedSecrets, this.options.parameters);
27731
+ const noEchoSources = this.noEchoPositionSources(resources, template, conditions);
27732
+ this.carriedExportAliasRefusal = (outputKey, exportName) => {
27733
+ const verdict = carriedExportAliasExposure(exportName, outputsPassSecrets, noEchoSeed);
27734
+ if (verdict === void 0) return void 0;
27735
+ return secretBearingExportNameWarning(outputKey, exportName, verdict.exposure, context.recordedSecretValues, verdict.noEchoOnly);
27736
+ };
27695
27737
  const resolvedNames = [];
27696
27738
  for (const [outputKey, output] of Object.entries(template.Outputs)) {
27697
27739
  if (isOutputSuppressedByCondition(output, conditions)) continue;
@@ -27719,12 +27761,15 @@ async function resolveOutputs(template, resources, stackName, digestSource, para
27719
27761
  exportName,
27720
27762
  value,
27721
27763
  outputValue: output.Value,
27764
+ nameSource: output.Export.Name,
27722
27765
  nameSecrets
27723
27766
  });
27724
27767
  }
27725
- for (const { outputKey, exportName, value, outputValue, nameSecrets } of resolvedNames) {
27726
- const exposure = exportNameSecretExposure(exportName, nameSecrets, context.recordedSecretValues, noEchoSeed);
27727
- if (exposure) this.logger.warn(secretBearingExportNameWarning(outputKey, exportName, exposure, context.recordedSecretValues, isNoEchoOnlyExposure(exposure, nameSecrets, context.recordedSecretValues)));
27768
+ for (const { outputKey, exportName, value, outputValue, nameSource, nameSecrets } of resolvedNames) {
27769
+ const noEchoParameters = exportNameNoEchoParameters(nameSource, noEchoSources);
27770
+ const exposure = noEchoParameters.length > 0 ? void 0 : exportNameSecretExposure(exportName, nameSecrets, context.recordedSecretValues, noEchoSeed);
27771
+ if (noEchoParameters.length > 0) this.logger.warn(noEchoParameterExportNameWarning(outputKey, noEchoParameters, outputsPassSecrets));
27772
+ else if (exposure) this.logger.warn(secretBearingExportNameWarning(outputKey, exportName, exposure, context.recordedSecretValues, isNoEchoOnlyExposure(exposure, nameSecrets, context.recordedSecretValues)));
27728
27773
  else if (isExportAliasCollision(exportName, outputKey, publishedOutputNames)) this.logger.warn(exportAliasCollisionWarning(outputKey, exportName, outputsPassSecrets));
27729
27774
  else {
27730
27775
  outputs[exportName] = value;
@@ -27897,7 +27942,7 @@ var DeploymentEventsStore = class {
27897
27942
  }
27898
27943
  enqueueWrite(op) {
27899
27944
  const next = this.writeChain.then(op).catch((err) => {
27900
- this.warnOnce(`Failed to persist deployment events for run ${this.runId}: ${err instanceof Error ? err.message : String(err)}`);
27945
+ this.warnOnce(`Failed to persist deployment events for run ${this.runId}: ${describeAwsFailure(err).detail}`);
27901
27946
  });
27902
27947
  this.writeChain = next;
27903
27948
  return next;
@@ -27918,7 +27963,7 @@ var DeploymentEventsStore = class {
27918
27963
  if (Array.isArray(parsed.runs)) return parsed.runs;
27919
27964
  }
27920
27965
  } catch (err) {
27921
- this.logger.debug(`Deployment-events index unreadable, rewriting: ${err instanceof Error ? err.message : String(err)}`);
27966
+ this.logger.debug(`Deployment-events index unreadable, rewriting: ${describeAwsFailure(err).detail}`);
27922
27967
  }
27923
27968
  return [];
27924
27969
  }
@@ -29305,7 +29350,7 @@ function classifyFailedOp(op, stateResources, siblings = []) {
29305
29350
  if (op.physicalIdRecoveredFromError === false) return "skip-failed-superseded";
29306
29351
  if (op.physicalIdRecoveredFromError === true) {
29307
29352
  if (current) {
29308
- if (current.physicalId === op.physicalId) return "skip-failed-noop";
29353
+ if (current.physicalId === op.physicalId || current.resourceType === op.resourceType && typeof current.physicalId === "string" && samePhysicalId(op.resourceType, current.physicalId, op.physicalId)) return "skip-failed-noop";
29309
29354
  if (!isReplacedRecord(op, current) && !isProvenDistinctRecord(op, current)) return "skip-failed-mismatch";
29310
29355
  }
29311
29356
  if (stateHoldsPhysicalId(stateResources, op.resourceType, op.physicalId)) return "skip-failed-noop";
@@ -29356,14 +29401,14 @@ function replacedResourceDeleted(op, siblings) {
29356
29401
  return siblings.some((s) => s !== op && isReplacementOrphan(s) && s.logicalId === op.logicalId && s.replacedPhysicalId === op.physicalId && s.replacedResourceDeleted === true);
29357
29402
  }
29358
29403
  function stateHoldsPhysicalId(stateResources, resourceType, physicalId) {
29359
- return Object.values(stateResources).some((r) => r?.resourceType === resourceType && r.physicalId === physicalId);
29404
+ return Object.values(stateResources).some((r) => r?.resourceType === resourceType && typeof r.physicalId === "string" && samePhysicalId(resourceType, r.physicalId, physicalId));
29360
29405
  }
29361
29406
  function demoteSupersededOrphans(segments, orphans = []) {
29362
29407
  let demoted = 0;
29363
29408
  segments.forEach((segment, s) => {
29364
29409
  for (const op of segment.failedOperations ?? []) {
29365
29410
  if (op.changeType !== "CREATE" || op.physicalIdRecoveredFromError !== true) continue;
29366
- if (segments.slice(s + 1).some((t) => (t.operations ?? []).some((o) => mayOwn(o, op, true)) || (t.failedOperations ?? []).some((o) => mayOwn(o, op, false))) || segments.slice(s).some((t) => t.supersededLogicalIds?.includes(op.logicalId) === true) || orphans.some((o) => o?.logicalId === op.logicalId || o?.state?.resourceType === op.resourceType && o.state?.physicalId === op.physicalId)) {
29411
+ if (segments.slice(s + 1).some((t) => (t.operations ?? []).some((o) => mayOwn(o, op, true)) || (t.failedOperations ?? []).some((o) => mayOwn(o, op, false))) || segments.slice(s).some((t) => t.supersededLogicalIds?.includes(op.logicalId) === true) || orphans.some((o) => o?.logicalId === op.logicalId || o?.state?.resourceType === op.resourceType && holdsSameId(op.resourceType, o.state?.physicalId, op.physicalId))) {
29367
29412
  op.physicalIdRecoveredFromError = false;
29368
29413
  demoted++;
29369
29414
  }
@@ -29374,8 +29419,12 @@ function demoteSupersededOrphans(segments, orphans = []) {
29374
29419
  function mayOwn(o, orphan, completed) {
29375
29420
  if (o?.resourceType !== orphan.resourceType) return false;
29376
29421
  if (completed && o.changeType === "CREATE") return true;
29377
- if (o.physicalId === orphan.physicalId) return true;
29378
- return o.previousState?.physicalId === orphan.physicalId;
29422
+ if (holdsSameId(orphan.resourceType, o.physicalId, orphan.physicalId)) return true;
29423
+ return holdsSameId(orphan.resourceType, o.previousState?.physicalId, orphan.physicalId);
29424
+ }
29425
+ function holdsSameId(resourceType, held, orphanId) {
29426
+ if (typeof held !== "string" || typeof orphanId !== "string") return held === orphanId;
29427
+ return samePhysicalId(resourceType, held, orphanId);
29379
29428
  }
29380
29429
  function isJournaledOrphan(op) {
29381
29430
  return op.changeType === "CREATE" && typeof op.physicalIdRecoveredFromError === "boolean";
@@ -30044,7 +30093,7 @@ async function deleteMarkedRecreate(error, s) {
30044
30093
  if (madeId === void 0) return false;
30045
30094
  const shown = `${shownLogicalId(s.op.logicalId)} (${refusalResourceType(s.oldType)})`;
30046
30095
  const id = s.mask(madeId);
30047
- if (Object.values(s.stateResources).some((r) => r?.resourceType === s.oldType && r.physicalId === madeId)) return false;
30096
+ if (Object.values(s.stateResources).some((r) => r?.resourceType === s.oldType && typeof r.physicalId === "string" && samePhysicalId(s.oldType, r.physicalId, madeId))) return false;
30048
30097
  if (s.deletionPolicy === "Retain" || s.deletionPolicy === "Snapshot") {
30049
30098
  s.logger.warn(safeMsg` Rollback: the failed re-create of ${shown} made ${id} before failing; ` + safeMsg`it is left in AWS (DeletionPolicy: ${s.deletionPolicy}) and no record holds it — delete it yourself if it is not needed`);
30050
30099
  return false;
@@ -33318,6 +33367,439 @@ async function replayFailedOperations(...args) {
33318
33367
  return await withProducerRegions(() => replayProducerRegionEvidence(args[3]), () => withStackRecords(replayStackRecordsView(args[1]), () => replayFailedOperationsUnbound(...args)));
33319
33368
  }
33320
33369
 
33370
+ //#endregion
33371
+ //#region src/deployment/rollback-executor/journaled-orphans.ts
33372
+ const NONE = {
33373
+ segments: [],
33374
+ count: 0
33375
+ };
33376
+ async function loadJournaledOrphans(stateBackend, stackName, region, rollbackOrphans, logger, options = {}) {
33377
+ let segments;
33378
+ try {
33379
+ const journal = await stateBackend.loadRollbackJournal(stackName, region);
33380
+ if (!journal) return NONE;
33381
+ segments = journal.segments;
33382
+ } catch (err) {
33383
+ const detail = err instanceof Error ? err.message : String(err);
33384
+ logger.warn(safeMsg`Could not read the stack's rollback journal (${displaySafe(detail)}); ` + safeMsg`no resource it records for a failed CREATE is deleted, and ${options.unreadableOutcome ?? "a destroy that proceeds removes the journal with the state"}.`);
33385
+ return {
33386
+ ...NONE,
33387
+ unreadable: true
33388
+ };
33389
+ }
33390
+ const physicalIdOnly = (ops) => ops.filter((op) => op.changeType !== "CREATE");
33391
+ const evidence = segments.map((segment) => options.deployRunId !== void 0 && segment.reason === "nested-pending-parent" && segment.runId === options.deployRunId ? {
33392
+ ...segment,
33393
+ operations: physicalIdOnly(segment.operations)
33394
+ } : segment);
33395
+ const newer = options.newerOperations ?? [];
33396
+ if (newer.length > 0) evidence.push({ operations: physicalIdOnly(newer) });
33397
+ demoteSupersededOrphans(evidence, Array.isArray(rollbackOrphans) ? rollbackOrphans : []);
33398
+ const deployLogicalIds = new Set(newer.map((op) => op.logicalId));
33399
+ for (const segment of segments) if (options.deployRunId !== void 0 && segment.reason === "nested-pending-parent" && segment.runId === options.deployRunId) for (const op of segment.operations) deployLogicalIds.add(op.logicalId);
33400
+ const out = [];
33401
+ let count = 0;
33402
+ for (let s = segments.length - 1; s >= 0; s--) {
33403
+ const segment = segments[s];
33404
+ if (segment.reason === "nested-pending-parent") continue;
33405
+ const replay = splitImportedOps(segment.failedOperations ?? [], segment).replay;
33406
+ const ops = replay.filter(isJournaledOrphan);
33407
+ if (ops.length === 0) continue;
33408
+ const companions = replay.filter((op) => op.changeType === "UPDATE" && replacementNeverSwapped(op, ops));
33409
+ out.push({
33410
+ segment,
33411
+ ops,
33412
+ ...companions.length > 0 && { companions }
33413
+ });
33414
+ count += ops.length;
33415
+ }
33416
+ return {
33417
+ segments: out,
33418
+ count,
33419
+ deployLogicalIds
33420
+ };
33421
+ }
33422
+ function journaledOrphanLines(orphans, logger) {
33423
+ return orphans.segments.flatMap(({ ops }) => ops.map((op) => ` - ${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}) ${displacedPhysicalIdShown(op, logger) ?? "a physical id"}`));
33424
+ }
33425
+ function dropFailedCommands(stackName, region, logicalIds) {
33426
+ const ids = [...new Set(logicalIds)];
33427
+ if (ids.length === 0) return void 0;
33428
+ const built = ids.map((id) => pasteableCommand("cdkd rollback", [
33429
+ {
33430
+ value: stackName,
33431
+ hole: "stack",
33432
+ opts: { plainIdent: true }
33433
+ },
33434
+ {
33435
+ flag: "--stack-region",
33436
+ value: region,
33437
+ hole: "region",
33438
+ opts: { plainIdent: true }
33439
+ },
33440
+ {
33441
+ flag: "--drop-failed",
33442
+ value: id,
33443
+ hole: "logical-id",
33444
+ opts: { plainIdent: true }
33445
+ }
33446
+ ]));
33447
+ const idWithheld = built.some((b) => b.withheld.some((w) => w.hole === "logical-id"));
33448
+ return {
33449
+ intro: `If cdkd can never delete ${ids.length === 1 ? "it" : "one of them"} (a cause you cannot fix), check the resource by hand, then drop just its rollback-journal entry; every other entry is kept.` + withheldTargetClause(built[0], "stack", "cdkd rollback", "This stack's name") + withheldTargetClause(built[0], "region", "cdkd rollback", "This stack's region") + (idWithheld ? " A logical id that is not a plain identifier is not named in the command below; read it from the stack's rollback-journal.json (next to its state.json)." : ""),
33450
+ commands: built.map((b) => b.command)
33451
+ };
33452
+ }
33453
+ function dropFailedHint(stackName, region, logicalIds) {
33454
+ const hint = dropFailedCommands(stackName, region, logicalIds);
33455
+ if (hint === void 0) return "";
33456
+ return `\n${hint.intro}` + hint.commands.map((c) => `\nDrop with: ${c}`).join("");
33457
+ }
33458
+ function warnDropFailed(logger, stackName, region, logicalIds) {
33459
+ const hint = dropFailedCommands(stackName, region, logicalIds);
33460
+ if (hint === void 0) return;
33461
+ logger.warn(safeMsg`${hint.intro}`);
33462
+ for (const command of hint.commands) logger.warn(safeMsg`Drop with: ${command}`);
33463
+ }
33464
+ async function deleteJournaledOrphans(orphans, stateResources, stackName, ctx, options = {}) {
33465
+ const total = {
33466
+ failures: 0,
33467
+ warnings: 0,
33468
+ interrupted: false,
33469
+ handled: [],
33470
+ leftInPlace: 0,
33471
+ failedLogicalIds: []
33472
+ };
33473
+ const inlinePolicyWriters = new RollbackInlinePolicyWriters();
33474
+ const failedIds = total.failedLogicalIds;
33475
+ const record = ctx.recordEvent;
33476
+ const printing = journaledOrphanPrintingBag(orphans.segments.flatMap(({ ops, companions }) => [...companions ?? [], ...ops]), stateResources);
33477
+ const maskedCtx = record === void 0 ? ctx : {
33478
+ ...ctx,
33479
+ recordEvent: (event) => record(maskEventTextWithBoundBags(event))
33480
+ };
33481
+ for (const { segment, ops: orphanOps, companions } of orphans.segments) {
33482
+ if (options.isInterrupted?.()) {
33483
+ total.interrupted = true;
33484
+ break;
33485
+ }
33486
+ const ops = [...companions ?? [], ...orphanOps];
33487
+ const replay = () => withPrintingSecrets(printing, () => withStackName(stackName, () => replayFailedOperations(ops, stateResources, stackName, maskedCtx, {
33488
+ emitEnvelope: false,
33489
+ inlinePolicyWriters,
33490
+ forDestroy: true,
33491
+ ...options.isInterrupted && { isInterrupted: options.isInterrupted }
33492
+ })));
33493
+ const result = segment.skipPrefix === void 0 ? await replay() : await withSkipPrefix(segment.skipPrefix, replay);
33494
+ total.failures += result.failures;
33495
+ total.warnings += result.warnings;
33496
+ total.leftInPlace += result.leftInPlace;
33497
+ const pending = new Set(result.remainingFailedOps);
33498
+ for (const op of ops) if (!pending.has(op)) total.handled.push({
33499
+ segment,
33500
+ op
33501
+ });
33502
+ if (result.interrupted) {
33503
+ total.interrupted = true;
33504
+ break;
33505
+ }
33506
+ for (const op of orphanOps) if (pending.has(op)) failedIds.push(op.logicalId);
33507
+ }
33508
+ if (options.pointAtDrop !== false && failedIds.length > 0) {
33509
+ ctx.logger.warn(safeMsg`${failedIds.length} resource(s) a failed deploy of stack ${displayIdent(stackName)} created ` + "could not be deleted (see above); the rollback journal, their only record, keeps them for a re-run.");
33510
+ warnDropFailed(ctx.logger, stackName, ctx.region, failedIds);
33511
+ }
33512
+ return total;
33513
+ }
33514
+ async function settleJournaledOrphansOnSuccess(args) {
33515
+ const { stateBackend, stackName, region, stateResources, newerOperations, ctx, logger } = args;
33516
+ const stack = displayIdent(stackName);
33517
+ const newerIds = newerOperations.map((op) => op.logicalId);
33518
+ let orphans;
33519
+ try {
33520
+ orphans = await loadJournaledOrphans(stateBackend, stackName, region, args.rollbackOrphans, logger, {
33521
+ newerOperations,
33522
+ ...args.deployRunId !== void 0 && { deployRunId: args.deployRunId },
33523
+ unreadableOutcome: "the successful deploy removes the journal"
33524
+ });
33525
+ } catch (err) {
33526
+ logger.warn(safeMsg`Could not act on the rollback journal of stack ${stack}: ${errorDetail(err)}. It is kept.`);
33527
+ await markSuperseded(stateBackend, stackName, region, newerIds);
33528
+ return {
33529
+ unaddressed: 1,
33530
+ keepJournal: true
33531
+ };
33532
+ }
33533
+ if (orphans.count === 0) return {
33534
+ unaddressed: 0,
33535
+ keepJournal: false
33536
+ };
33537
+ const all = orphans.segments.flatMap(({ segment, ops }) => ops.map((op) => ({
33538
+ segment,
33539
+ op
33540
+ })));
33541
+ let kept = all;
33542
+ let failedDeletes = [];
33543
+ let leftInPlace = 0;
33544
+ if (stateResources === void 0) logger.warn(safeMsg`The rollback journal of stack ${stack} records ${all.length} resource(s) a failed deploy ` + `created, but the stack's state cannot be read, so whether a record now owns them is unknown: none is deleted.`);
33545
+ else {
33546
+ logger.info(safeMsg`The rollback journal of stack ${stack} records ${all.length} resource(s) a failed deploy ` + `created that no state record holds; acting on them per their DeletionPolicy before the journal is removed:`);
33547
+ for (const line of journaledOrphanLines(orphans, logger)) logger.info(line);
33548
+ try {
33549
+ const { unreadable, tracked } = await applySuccessRule(orphans, stateResources, orphans.deployLogicalIds ?? /* @__PURE__ */ new Set(), args.foreignHolder, stack, logger, args.isInterrupted, ctx);
33550
+ const acting = {
33551
+ segments: orphans.segments.map(({ segment, ops }) => ({
33552
+ segment,
33553
+ ops: ops.filter((op) => !unreadable.has(op) && !tracked.has(op))
33554
+ })).filter(({ ops }) => ops.length > 0),
33555
+ count: orphans.count - unreadable.size - tracked.size
33556
+ };
33557
+ 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");
33558
+ const outcome = await deleteJournaledOrphans(acting, { ...stateResources }, stackName, {
33559
+ ...ctx,
33560
+ writtenThisRun
33561
+ }, {
33562
+ pointAtDrop: false,
33563
+ ...args.isInterrupted && { isInterrupted: args.isInterrupted }
33564
+ });
33565
+ leftInPlace = outcome.leftInPlace;
33566
+ failedDeletes = outcome.failedLogicalIds;
33567
+ kept = all.filter(({ segment, op }) => unreadable.has(op) || !tracked.has(op) && !isHandledOrphan(outcome.handled, segment, op));
33568
+ } catch (err) {
33569
+ logger.warn(safeMsg`Acting on the journaled resources of stack ${stack} failed: ${errorDetail(err)}`);
33570
+ }
33571
+ }
33572
+ const keptOps = new Set(kept.map(({ op }) => op));
33573
+ const skipped = all.filter(({ op }) => !keptOps.has(op) && op.physicalIdRecoveredFromError === false).length;
33574
+ const clearedOrphans = all.filter(({ op }) => !keptOps.has(op));
33575
+ const cleared = [...clearedOrphans, ...orphans.segments.flatMap(({ segment, companions }) => (companions ?? []).filter((c) => replacementNeverSwapped(c, clearedOrphans.filter((o) => o.segment === segment).map((o) => o.op))).map((op) => ({
33576
+ segment,
33577
+ op
33578
+ })))];
33579
+ const stripCleared = cleared.length === 0 ? void 0 : async () => {
33580
+ try {
33581
+ await stateBackend.dropRollbackJournalFailedOperations(stackName, region, (op, segment) => isHandledOrphan(cleared, segment, op));
33582
+ } catch (err) {
33583
+ logger.warn(safeMsg`Failed to remove the settled entries from the rollback journal of stack ${stack}: ` + safeMsg`${errorDetail(err)}. A cdkd rollback or cdkd destroy could act on them again; run a ` + "successful cdkd deploy of the stack first, which settles them again.");
33584
+ }
33585
+ };
33586
+ if (kept.length === 0) return {
33587
+ unaddressed: skipped + leftInPlace,
33588
+ keepJournal: false,
33589
+ ...stripCleared && { stripCleared }
33590
+ };
33591
+ const keptIds = new Set(kept.map(({ op }) => op.logicalId));
33592
+ const supersededIds = newerIds.filter((id) => !keptIds.has(id));
33593
+ const demoted = kept.filter(({ op }) => op.physicalIdRecoveredFromError === false);
33594
+ const reduce = () => stateBackend.reduceRollbackJournalToFailedOperations(stackName, region, (op, segment) => isHandledOrphan(kept, segment, op), supersededIds, (op, segment) => isHandledOrphan(demoted, segment, op));
33595
+ let reduced = false;
33596
+ for (let attempt = 0; attempt < 2 && !reduced; attempt++) try {
33597
+ await reduce();
33598
+ reduced = true;
33599
+ } catch (err) {
33600
+ if (attempt === 1) logger.warn(safeMsg`Failed to reduce the rollback journal of stack ${stack} to its undeleted resources: ` + safeMsg`${errorDetail(err)}. The whole journal is kept.`);
33601
+ }
33602
+ if (!reduced) {
33603
+ await markSuperseded(stateBackend, stackName, region, supersededIds);
33604
+ await stripCleared?.();
33605
+ }
33606
+ logger.warn(safeMsg`${kept.length} resource(s) a failed deploy of stack ${stack} created were not deleted ` + (reduced ? "(see above). The rollback journal, their only record, is kept with just them; the next " : "(see above). The rollback journal, their only record, is kept; the next ") + "successful deploy retries.");
33607
+ warnDropFailed(logger, stackName, region, failedDeletes);
33608
+ return {
33609
+ unaddressed: kept.length + skipped + leftInPlace,
33610
+ keepJournal: true
33611
+ };
33612
+ }
33613
+ async function applySuccessRule(orphans, stateResources, deployLogicalIds, foreignHolder, stack, logger, isInterrupted, identityCtx) {
33614
+ const unreadable = /* @__PURE__ */ new Set();
33615
+ const tracked = /* @__PURE__ */ new Set();
33616
+ let interrupted = false;
33617
+ for (const { ops } of orphans.segments) for (const op of ops) {
33618
+ if (op.physicalIdRecoveredFromError !== true || !op.physicalId) continue;
33619
+ if (interrupted || isInterrupted?.()) {
33620
+ interrupted = true;
33621
+ unreadable.add(op);
33622
+ continue;
33623
+ }
33624
+ const opId = op.physicalId;
33625
+ if (Object.values(stateResources).some((r) => r?.resourceType === op.resourceType && typeof r.physicalId === "string" && samePhysicalId(op.resourceType, r.physicalId, opId))) {
33626
+ tracked.add(op);
33627
+ continue;
33628
+ }
33629
+ const hasRecord = Object.prototype.hasOwnProperty.call(stateResources, op.logicalId);
33630
+ const record = hasRecord ? stateResources[op.logicalId] : void 0;
33631
+ const recordUnderId = hasRecord && !isReplacedRecord(op, record);
33632
+ if (recordUnderId || deployLogicalIds.has(op.logicalId)) {
33633
+ const verdict = recordUnderId ? await recordIdentity(op, record, identityCtx, logger) : "unknown";
33634
+ if (verdict === "same") {
33635
+ tracked.add(op);
33636
+ continue;
33637
+ }
33638
+ if (verdict !== "different") {
33639
+ op.physicalIdRecoveredFromError = false;
33640
+ continue;
33641
+ }
33642
+ markProvenDistinctFromRecord(op, record);
33643
+ }
33644
+ const holding = await foreignHolder(op.resourceType, op.physicalId);
33645
+ if (holding === void 0) {
33646
+ const created = await createdResourceStillThere(op, identityCtx);
33647
+ if (created === "gone") {
33648
+ logger.info(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is already gone: nothing to delete.`);
33649
+ tracked.add(op);
33650
+ } else if (created === "mismatch") {
33651
+ logger.warn(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is not deleted: the resource now under its physical id is another ` + "one (its identity differs from the one that deploy recorded, so its name was reused).");
33652
+ op.physicalIdRecoveredFromError = false;
33653
+ } else if (created === "unproven") {
33654
+ logger.warn(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is not deleted: nothing proves the resource now under its physical ` + "id is the one that deploy created (it may have been deleted and its name reused).");
33655
+ op.physicalIdRecoveredFromError = false;
33656
+ }
33657
+ continue;
33658
+ }
33659
+ if (holding.kind === "held") {
33660
+ logger.warn(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is not deleted: ${holding.by} holds a resource of that type under ` + "the same physical id.");
33661
+ op.physicalIdRecoveredFromError = false;
33662
+ continue;
33663
+ }
33664
+ logger.warn(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is not deleted: ${holding.what}, so whether another stack holds it is unknown.`);
33665
+ unreadable.add(op);
33666
+ }
33667
+ return {
33668
+ unreadable,
33669
+ tracked
33670
+ };
33671
+ }
33672
+ async function recordIdentity(op, record, ctx, logger) {
33673
+ if (typeof record !== "object" || record === null || record.resourceType !== op.resourceType || typeof record.physicalId !== "string" || record.physicalId === "" || !op.physicalId) return "unknown";
33674
+ try {
33675
+ const { provider } = ctx.providerRegistry.getProviderFor({
33676
+ resourceType: op.resourceType,
33677
+ provisionedBy: op.provisionedBy
33678
+ });
33679
+ if (typeof provider.isSameResource !== "function") return "unknown";
33680
+ return await provider.isSameResource(op.physicalId, {
33681
+ physicalId: record.physicalId,
33682
+ ...record.provisionedBy !== void 0 && { provisionedBy: record.provisionedBy }
33683
+ }, op.resourceType, { expectedRegion: ctx.region });
33684
+ } catch (err) {
33685
+ logger.debug(safeMsg`Could not compare ${logicalIdShown(op.logicalId)}'s journaled resource with its state record (${displaySafe(err instanceof Error ? err.name : typeof err)}).`);
33686
+ return "unknown";
33687
+ }
33688
+ }
33689
+ async function createdResourceStillThere(op, ctx) {
33690
+ if (op.deletionPolicy === "Retain") return "proven";
33691
+ if (!orphanDeleteNeedsIdentity(op.resourceType)) return "proven";
33692
+ const physicalId = op.physicalId;
33693
+ if (!physicalId) return "unproven";
33694
+ const live = await readResourceIdentity(ctx.providerRegistry, {
33695
+ resourceType: op.resourceType,
33696
+ physicalId,
33697
+ provisionedBy: op.provisionedBy
33698
+ }, ctx.region);
33699
+ if (live === RESOURCE_NOT_FOUND) return "gone";
33700
+ const journaled = op.createdResourceIdentity;
33701
+ if (typeof journaled !== "string" || journaled === "" || typeof live !== "string") return "unproven";
33702
+ return live === journaled ? "proven" : "mismatch";
33703
+ }
33704
+ function makeForeignHolderScan(stateBackend) {
33705
+ let scan;
33706
+ const key = (type, id) => JSON.stringify([type, physicalIdKey(type, id)]);
33707
+ const run = async () => {
33708
+ const holders = /* @__PURE__ */ new Map();
33709
+ let refs;
33710
+ try {
33711
+ refs = await stateBackend.listStacks();
33712
+ } catch {
33713
+ return {
33714
+ holders,
33715
+ unreadable: "the state bucket listing (it could not be read)"
33716
+ };
33717
+ }
33718
+ let unreadable;
33719
+ await Promise.all(refs.map(async (ref) => {
33720
+ const named = (why) => safeMsg`the state record of stack ${displayIdent(ref.stackName)} (${why})`;
33721
+ if (ref.region === void 0) {
33722
+ unreadable ??= named("its region cannot be read");
33723
+ return;
33724
+ }
33725
+ const region = ref.region;
33726
+ let state;
33727
+ try {
33728
+ state = (await stateBackend.getState(ref.stackName, region))?.state;
33729
+ } catch {
33730
+ unreadable ??= named("it could not be read");
33731
+ return;
33732
+ }
33733
+ if (state === void 0) return;
33734
+ const resources = state.resources;
33735
+ if (resources !== void 0 && (typeof resources !== "object" || resources === null || Array.isArray(resources))) {
33736
+ unreadable ??= named("its resources cannot be read");
33737
+ return;
33738
+ }
33739
+ if (!hasReadableOrphans(state) || unreadableOrphanRecords(state).length > 0) {
33740
+ unreadable ??= named("its rollback-orphan records cannot be read");
33741
+ return;
33742
+ }
33743
+ const held = [...Object.values(resources ?? {}), ...(state.orphans ?? []).map((record) => record.state)];
33744
+ for (const record of held) {
33745
+ const r = record;
33746
+ if (typeof r?.resourceType !== "string" || typeof r.physicalId !== "string") continue;
33747
+ const k = key(r.resourceType, r.physicalId);
33748
+ const list = holders.get(k) ?? [];
33749
+ list.push({
33750
+ stackName: ref.stackName,
33751
+ region
33752
+ });
33753
+ holders.set(k, list);
33754
+ }
33755
+ }));
33756
+ return {
33757
+ holders,
33758
+ ...unreadable !== void 0 && { unreadable }
33759
+ };
33760
+ };
33761
+ return (self) => async (resourceType, physicalId) => {
33762
+ scan ??= run();
33763
+ const { holders, unreadable } = await scan;
33764
+ const other = (holders.get(key(resourceType, physicalId)) ?? []).find((h) => !(h.stackName === self.stackName && h.region === self.region));
33765
+ if (other) return {
33766
+ kind: "held",
33767
+ by: safeMsg`the state record of stack ${displayIdent(other.stackName)} (${displaySafe(other.region)})`
33768
+ };
33769
+ return unreadable === void 0 ? void 0 : {
33770
+ kind: "unreadable",
33771
+ what: unreadable
33772
+ };
33773
+ };
33774
+ }
33775
+ async function markSuperseded(stateBackend, stackName, region, ids) {
33776
+ try {
33777
+ await stateBackend.markRollbackJournalSuperseded(stackName, region, ids);
33778
+ } catch {}
33779
+ }
33780
+ function errorDetail(err) {
33781
+ return displaySafe(err instanceof Error ? err.message : String(err));
33782
+ }
33783
+ function isHandledOrphan(handled, segment, op) {
33784
+ return handled.some((h) => h.segment.timestamp === segment.timestamp && h.segment.runId === segment.runId && h.op.logicalId === op.logicalId && h.op.changeType === op.changeType && h.op.resourceType === op.resourceType && h.op.physicalId === op.physicalId);
33785
+ }
33786
+ function orphanKey(segment, op) {
33787
+ return JSON.stringify([
33788
+ segment.timestamp,
33789
+ segment.runId ?? null,
33790
+ op.logicalId,
33791
+ op.changeType,
33792
+ op.resourceType,
33793
+ op.physicalId ?? null
33794
+ ]);
33795
+ }
33796
+ function sameJournaledOrphans(a, b) {
33797
+ const keys = (o) => o.segments.flatMap(({ segment, ops }) => ops.map((op) => orphanKey(segment, op))).sort();
33798
+ const ka = keys(a);
33799
+ const kb = keys(b);
33800
+ return ka.length === kb.length && ka.every((k, i) => k === kb[i]);
33801
+ }
33802
+
33321
33803
  //#endregion
33322
33804
  //#region src/provisioning/nested-stack-context.ts
33323
33805
  const storage$1 = new AsyncLocalStorage();
@@ -33417,7 +33899,7 @@ function getNestedRevertRun() {
33417
33899
  return revertRunStorage.getStore();
33418
33900
  }
33419
33901
  function errorText(error) {
33420
- return displaySafe(error instanceof Error ? error.message : String(error));
33902
+ return displaySafe(describeAwsFailure(error).detail);
33421
33903
  }
33422
33904
  function isPlainRecord(value) {
33423
33905
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -33590,6 +34072,13 @@ async function revertNestedChildFromJournal(args) {
33590
34072
  ...ctx.options?.eventRecorder && { recordEvent: (event) => ctx.options.eventRecorder.record(maskEventTextWithBoundBags(event)) },
33591
34073
  finalSnapshotClients: ctx.options?.finalSnapshotClients,
33592
34074
  skipFinalSnapshot: ctx.options?.skipFinalSnapshot === true || ctx.destroyOptions?.skipFinalSnapshot === true,
34075
+ ...ctx.destroyOptions?.removeProtection === true && {
34076
+ removeProtection: true,
34077
+ foreignHolder: makeForeignHolderScan(ctx.stateBackend)({
34078
+ stackName: childStackName,
34079
+ region
34080
+ })
34081
+ },
33593
34082
  importedProducerRegions: producerRegions.regions,
33594
34083
  producerRegionsIncomplete: !producerRegions.complete,
33595
34084
  nestedChildRevert: true
@@ -33674,7 +34163,7 @@ async function planOrphanAdoption(params) {
33674
34163
  provider = params.getProvider(state.resourceType, state.provisionedBy);
33675
34164
  } catch (error) {
33676
34165
  outcome.remaining.push(record);
33677
- outcome.notices.push(`${shownId} (${shownType}) is still in AWS as ${shownPhysicalId} from an earlier rollback, but this build cannot route that type (${displayAwsMessage(error instanceof Error ? error.message : String(error))}) — cdkd is not adopting it.`);
34166
+ outcome.notices.push(`${shownId} (${shownType}) is still in AWS as ${shownPhysicalId} from an earlier rollback, but this build cannot route that type (${displayAwsMessage(describeAwsFailure(error).detail)}) — cdkd is not adopting it.`);
33678
34167
  continue;
33679
34168
  }
33680
34169
  if (!provider.import) {
@@ -33693,7 +34182,7 @@ async function planOrphanAdoption(params) {
33693
34182
  knownPhysicalId: state.physicalId
33694
34183
  });
33695
34184
  } catch (error) {
33696
- outcome.notices.push(`${shownId} (${shownType}) is recorded as left in AWS as ${shownPhysicalId}, but cdkd could not confirm it exists (${displayAwsMessage(error instanceof Error ? error.message : String(error))}) — keeping the record and not adopting it this run.`);
34185
+ outcome.notices.push(`${shownId} (${shownType}) is recorded as left in AWS as ${shownPhysicalId}, but cdkd could not confirm it exists (${displayAwsMessage(describeAwsFailure(error).detail)}) — keeping the record and not adopting it this run.`);
33697
34186
  outcome.remaining.push(record);
33698
34187
  continue;
33699
34188
  }
@@ -33746,7 +34235,7 @@ function makeSiblingClaimReader(params) {
33746
34235
  try {
33747
34236
  refs = await stateBackend.listStacks();
33748
34237
  } catch (error) {
33749
- logger.debug(`orphan adoption: could not list sibling stacks — ${displayAwsMessage(error instanceof Error ? error.message : String(error))}`);
34238
+ logger.debug(`orphan adoption: could not list sibling stacks — ${displayAwsMessage(describeAwsFailure(error).detail)}`);
33750
34239
  return claimed;
33751
34240
  }
33752
34241
  for (const ref of refs) {
@@ -33772,445 +34261,13 @@ function makeSiblingClaimReader(params) {
33772
34261
  logger.debug(safeMsg`orphan adoption: ${displayStackName(ref.stackName)} holds ${unreadable.length} ` + safeMsg`resource record(s) with no readable physical id — ${named}` + safeMsg`${rest > 0 ? ` and ${rest} more` : ""} — skipped; the claim set is a lower ` + `bound without them`);
33773
34262
  }
33774
34263
  } catch (error) {
33775
- logger.debug(`orphan adoption: skipping unreadable state for ${displayStackName(ref.stackName)} — ${displayAwsMessage(error instanceof Error ? error.message : String(error))}`);
34264
+ logger.debug(`orphan adoption: skipping unreadable state for ${displayStackName(ref.stackName)} — ${displayAwsMessage(describeAwsFailure(error).detail)}`);
33776
34265
  }
33777
34266
  }
33778
34267
  return claimed;
33779
34268
  };
33780
34269
  }
33781
34270
 
33782
- //#endregion
33783
- //#region src/deployment/rollback-executor/journaled-orphans.ts
33784
- const NONE = {
33785
- segments: [],
33786
- count: 0
33787
- };
33788
- async function loadJournaledOrphans(stateBackend, stackName, region, rollbackOrphans, logger, options = {}) {
33789
- let segments;
33790
- try {
33791
- const journal = await stateBackend.loadRollbackJournal(stackName, region);
33792
- if (!journal) return NONE;
33793
- segments = journal.segments;
33794
- } catch (err) {
33795
- const detail = err instanceof Error ? err.message : String(err);
33796
- logger.warn(safeMsg`Could not read the stack's rollback journal (${displaySafe(detail)}); ` + safeMsg`no resource it records for a failed CREATE is deleted, and ${options.unreadableOutcome ?? "a destroy that proceeds removes the journal with the state"}.`);
33797
- return {
33798
- ...NONE,
33799
- unreadable: true
33800
- };
33801
- }
33802
- const physicalIdOnly = (ops) => ops.filter((op) => op.changeType !== "CREATE");
33803
- const evidence = segments.map((segment) => options.deployRunId !== void 0 && segment.reason === "nested-pending-parent" && segment.runId === options.deployRunId ? {
33804
- ...segment,
33805
- operations: physicalIdOnly(segment.operations)
33806
- } : segment);
33807
- const newer = options.newerOperations ?? [];
33808
- if (newer.length > 0) evidence.push({ operations: physicalIdOnly(newer) });
33809
- demoteSupersededOrphans(evidence, Array.isArray(rollbackOrphans) ? rollbackOrphans : []);
33810
- const deployLogicalIds = new Set(newer.map((op) => op.logicalId));
33811
- for (const segment of segments) if (options.deployRunId !== void 0 && segment.reason === "nested-pending-parent" && segment.runId === options.deployRunId) for (const op of segment.operations) deployLogicalIds.add(op.logicalId);
33812
- const out = [];
33813
- let count = 0;
33814
- for (let s = segments.length - 1; s >= 0; s--) {
33815
- const segment = segments[s];
33816
- if (segment.reason === "nested-pending-parent") continue;
33817
- const replay = splitImportedOps(segment.failedOperations ?? [], segment).replay;
33818
- const ops = replay.filter(isJournaledOrphan);
33819
- if (ops.length === 0) continue;
33820
- const companions = replay.filter((op) => op.changeType === "UPDATE" && replacementNeverSwapped(op, ops));
33821
- out.push({
33822
- segment,
33823
- ops,
33824
- ...companions.length > 0 && { companions }
33825
- });
33826
- count += ops.length;
33827
- }
33828
- return {
33829
- segments: out,
33830
- count,
33831
- deployLogicalIds
33832
- };
33833
- }
33834
- function journaledOrphanLines(orphans, logger) {
33835
- return orphans.segments.flatMap(({ ops }) => ops.map((op) => ` - ${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}) ${displacedPhysicalIdShown(op, logger) ?? "a physical id"}`));
33836
- }
33837
- function dropFailedCommands(stackName, region, logicalIds) {
33838
- const ids = [...new Set(logicalIds)];
33839
- if (ids.length === 0) return void 0;
33840
- const built = ids.map((id) => pasteableCommand("cdkd rollback", [
33841
- {
33842
- value: stackName,
33843
- hole: "stack",
33844
- opts: { plainIdent: true }
33845
- },
33846
- {
33847
- flag: "--stack-region",
33848
- value: region,
33849
- hole: "region",
33850
- opts: { plainIdent: true }
33851
- },
33852
- {
33853
- flag: "--drop-failed",
33854
- value: id,
33855
- hole: "logical-id",
33856
- opts: { plainIdent: true }
33857
- }
33858
- ]));
33859
- const idWithheld = built.some((b) => b.withheld.some((w) => w.hole === "logical-id"));
33860
- return {
33861
- intro: `If cdkd can never delete ${ids.length === 1 ? "it" : "one of them"} (a cause you cannot fix), check the resource by hand, then drop just its rollback-journal entry; every other entry is kept.` + withheldTargetClause(built[0], "stack", "cdkd rollback", "This stack's name") + withheldTargetClause(built[0], "region", "cdkd rollback", "This stack's region") + (idWithheld ? " A logical id that is not a plain identifier is not named in the command below; read it from the stack's rollback-journal.json (next to its state.json)." : ""),
33862
- commands: built.map((b) => b.command)
33863
- };
33864
- }
33865
- function dropFailedHint(stackName, region, logicalIds) {
33866
- const hint = dropFailedCommands(stackName, region, logicalIds);
33867
- if (hint === void 0) return "";
33868
- return `\n${hint.intro}` + hint.commands.map((c) => `\nDrop with: ${c}`).join("");
33869
- }
33870
- function warnDropFailed(logger, stackName, region, logicalIds) {
33871
- const hint = dropFailedCommands(stackName, region, logicalIds);
33872
- if (hint === void 0) return;
33873
- logger.warn(safeMsg`${hint.intro}`);
33874
- for (const command of hint.commands) logger.warn(safeMsg`Drop with: ${command}`);
33875
- }
33876
- async function deleteJournaledOrphans(orphans, stateResources, stackName, ctx, options = {}) {
33877
- const total = {
33878
- failures: 0,
33879
- warnings: 0,
33880
- interrupted: false,
33881
- handled: [],
33882
- leftInPlace: 0,
33883
- failedLogicalIds: []
33884
- };
33885
- const inlinePolicyWriters = new RollbackInlinePolicyWriters();
33886
- const failedIds = total.failedLogicalIds;
33887
- const record = ctx.recordEvent;
33888
- const printing = journaledOrphanPrintingBag(orphans.segments.flatMap(({ ops, companions }) => [...companions ?? [], ...ops]), stateResources);
33889
- const maskedCtx = record === void 0 ? ctx : {
33890
- ...ctx,
33891
- recordEvent: (event) => record(maskEventTextWithBoundBags(event))
33892
- };
33893
- for (const { segment, ops: orphanOps, companions } of orphans.segments) {
33894
- if (options.isInterrupted?.()) {
33895
- total.interrupted = true;
33896
- break;
33897
- }
33898
- const ops = [...companions ?? [], ...orphanOps];
33899
- const replay = () => withPrintingSecrets(printing, () => withStackName(stackName, () => replayFailedOperations(ops, stateResources, stackName, maskedCtx, {
33900
- emitEnvelope: false,
33901
- inlinePolicyWriters,
33902
- forDestroy: true,
33903
- ...options.isInterrupted && { isInterrupted: options.isInterrupted }
33904
- })));
33905
- const result = segment.skipPrefix === void 0 ? await replay() : await withSkipPrefix(segment.skipPrefix, replay);
33906
- total.failures += result.failures;
33907
- total.warnings += result.warnings;
33908
- total.leftInPlace += result.leftInPlace;
33909
- const pending = new Set(result.remainingFailedOps);
33910
- for (const op of ops) if (!pending.has(op)) total.handled.push({
33911
- segment,
33912
- op
33913
- });
33914
- if (result.interrupted) {
33915
- total.interrupted = true;
33916
- break;
33917
- }
33918
- for (const op of orphanOps) if (pending.has(op)) failedIds.push(op.logicalId);
33919
- }
33920
- if (options.pointAtDrop !== false && failedIds.length > 0) {
33921
- ctx.logger.warn(safeMsg`${failedIds.length} resource(s) a failed deploy of stack ${displayIdent(stackName)} created ` + "could not be deleted (see above); the rollback journal, their only record, keeps them for a re-run.");
33922
- warnDropFailed(ctx.logger, stackName, ctx.region, failedIds);
33923
- }
33924
- return total;
33925
- }
33926
- async function settleJournaledOrphansOnSuccess(args) {
33927
- const { stateBackend, stackName, region, stateResources, newerOperations, ctx, logger } = args;
33928
- const stack = displayIdent(stackName);
33929
- const newerIds = newerOperations.map((op) => op.logicalId);
33930
- let orphans;
33931
- try {
33932
- orphans = await loadJournaledOrphans(stateBackend, stackName, region, args.rollbackOrphans, logger, {
33933
- newerOperations,
33934
- ...args.deployRunId !== void 0 && { deployRunId: args.deployRunId },
33935
- unreadableOutcome: "the successful deploy removes the journal"
33936
- });
33937
- } catch (err) {
33938
- logger.warn(safeMsg`Could not act on the rollback journal of stack ${stack}: ${errorDetail(err)}. It is kept.`);
33939
- await markSuperseded(stateBackend, stackName, region, newerIds);
33940
- return {
33941
- unaddressed: 1,
33942
- keepJournal: true
33943
- };
33944
- }
33945
- if (orphans.count === 0) return {
33946
- unaddressed: 0,
33947
- keepJournal: false
33948
- };
33949
- const all = orphans.segments.flatMap(({ segment, ops }) => ops.map((op) => ({
33950
- segment,
33951
- op
33952
- })));
33953
- let kept = all;
33954
- let failedDeletes = [];
33955
- let leftInPlace = 0;
33956
- if (stateResources === void 0) logger.warn(safeMsg`The rollback journal of stack ${stack} records ${all.length} resource(s) a failed deploy ` + `created, but the stack's state cannot be read, so whether a record now owns them is unknown: none is deleted.`);
33957
- else {
33958
- logger.info(safeMsg`The rollback journal of stack ${stack} records ${all.length} resource(s) a failed deploy ` + `created that no state record holds; acting on them per their DeletionPolicy before the journal is removed:`);
33959
- for (const line of journaledOrphanLines(orphans, logger)) logger.info(line);
33960
- try {
33961
- const { unreadable, tracked } = await applySuccessRule(orphans, stateResources, orphans.deployLogicalIds ?? /* @__PURE__ */ new Set(), args.foreignHolder, stack, logger, args.isInterrupted, ctx);
33962
- const acting = {
33963
- segments: orphans.segments.map(({ segment, ops }) => ({
33964
- segment,
33965
- ops: ops.filter((op) => !unreadable.has(op) && !tracked.has(op))
33966
- })).filter(({ ops }) => ops.length > 0),
33967
- count: orphans.count - unreadable.size - tracked.size
33968
- };
33969
- 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");
33970
- const outcome = await deleteJournaledOrphans(acting, { ...stateResources }, stackName, {
33971
- ...ctx,
33972
- writtenThisRun
33973
- }, {
33974
- pointAtDrop: false,
33975
- ...args.isInterrupted && { isInterrupted: args.isInterrupted }
33976
- });
33977
- leftInPlace = outcome.leftInPlace;
33978
- failedDeletes = outcome.failedLogicalIds;
33979
- kept = all.filter(({ segment, op }) => unreadable.has(op) || !tracked.has(op) && !isHandledOrphan(outcome.handled, segment, op));
33980
- } catch (err) {
33981
- logger.warn(safeMsg`Acting on the journaled resources of stack ${stack} failed: ${errorDetail(err)}`);
33982
- }
33983
- }
33984
- const keptOps = new Set(kept.map(({ op }) => op));
33985
- const skipped = all.filter(({ op }) => !keptOps.has(op) && op.physicalIdRecoveredFromError === false).length;
33986
- const clearedOrphans = all.filter(({ op }) => !keptOps.has(op));
33987
- const cleared = [...clearedOrphans, ...orphans.segments.flatMap(({ segment, companions }) => (companions ?? []).filter((c) => replacementNeverSwapped(c, clearedOrphans.filter((o) => o.segment === segment).map((o) => o.op))).map((op) => ({
33988
- segment,
33989
- op
33990
- })))];
33991
- const stripCleared = cleared.length === 0 ? void 0 : async () => {
33992
- try {
33993
- await stateBackend.dropRollbackJournalFailedOperations(stackName, region, (op, segment) => isHandledOrphan(cleared, segment, op));
33994
- } catch (err) {
33995
- logger.warn(safeMsg`Failed to remove the settled entries from the rollback journal of stack ${stack}: ` + safeMsg`${errorDetail(err)}. A cdkd rollback or cdkd destroy could act on them again; run a ` + "successful cdkd deploy of the stack first, which settles them again.");
33996
- }
33997
- };
33998
- if (kept.length === 0) return {
33999
- unaddressed: skipped + leftInPlace,
34000
- keepJournal: false,
34001
- ...stripCleared && { stripCleared }
34002
- };
34003
- const keptIds = new Set(kept.map(({ op }) => op.logicalId));
34004
- const supersededIds = newerIds.filter((id) => !keptIds.has(id));
34005
- const demoted = kept.filter(({ op }) => op.physicalIdRecoveredFromError === false);
34006
- const reduce = () => stateBackend.reduceRollbackJournalToFailedOperations(stackName, region, (op, segment) => isHandledOrphan(kept, segment, op), supersededIds, (op, segment) => isHandledOrphan(demoted, segment, op));
34007
- let reduced = false;
34008
- for (let attempt = 0; attempt < 2 && !reduced; attempt++) try {
34009
- await reduce();
34010
- reduced = true;
34011
- } catch (err) {
34012
- if (attempt === 1) logger.warn(safeMsg`Failed to reduce the rollback journal of stack ${stack} to its undeleted resources: ` + safeMsg`${errorDetail(err)}. The whole journal is kept.`);
34013
- }
34014
- if (!reduced) {
34015
- await markSuperseded(stateBackend, stackName, region, supersededIds);
34016
- await stripCleared?.();
34017
- }
34018
- logger.warn(safeMsg`${kept.length} resource(s) a failed deploy of stack ${stack} created were not deleted ` + (reduced ? "(see above). The rollback journal, their only record, is kept with just them; the next " : "(see above). The rollback journal, their only record, is kept; the next ") + "successful deploy retries.");
34019
- warnDropFailed(logger, stackName, region, failedDeletes);
34020
- return {
34021
- unaddressed: kept.length + skipped + leftInPlace,
34022
- keepJournal: true
34023
- };
34024
- }
34025
- async function applySuccessRule(orphans, stateResources, deployLogicalIds, foreignHolder, stack, logger, isInterrupted, identityCtx) {
34026
- const unreadable = /* @__PURE__ */ new Set();
34027
- const tracked = /* @__PURE__ */ new Set();
34028
- let interrupted = false;
34029
- for (const { ops } of orphans.segments) for (const op of ops) {
34030
- if (op.physicalIdRecoveredFromError !== true || !op.physicalId) continue;
34031
- if (interrupted || isInterrupted?.()) {
34032
- interrupted = true;
34033
- unreadable.add(op);
34034
- continue;
34035
- }
34036
- if (Object.values(stateResources).some((r) => r?.resourceType === op.resourceType && r.physicalId === op.physicalId)) {
34037
- tracked.add(op);
34038
- continue;
34039
- }
34040
- const hasRecord = Object.prototype.hasOwnProperty.call(stateResources, op.logicalId);
34041
- const record = hasRecord ? stateResources[op.logicalId] : void 0;
34042
- const recordUnderId = hasRecord && !isReplacedRecord(op, record);
34043
- if (recordUnderId || deployLogicalIds.has(op.logicalId)) {
34044
- const verdict = recordUnderId ? await recordIdentity(op, record, identityCtx, logger) : "unknown";
34045
- if (verdict === "same") {
34046
- tracked.add(op);
34047
- continue;
34048
- }
34049
- if (verdict !== "different") {
34050
- op.physicalIdRecoveredFromError = false;
34051
- continue;
34052
- }
34053
- markProvenDistinctFromRecord(op, record);
34054
- }
34055
- const holding = await foreignHolder(op.resourceType, op.physicalId);
34056
- if (holding === void 0) {
34057
- const created = await createdResourceStillThere(op, identityCtx);
34058
- if (created === "gone") {
34059
- logger.info(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is already gone: nothing to delete.`);
34060
- tracked.add(op);
34061
- } else if (created === "mismatch") {
34062
- logger.warn(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is not deleted: the resource now under its physical id is another ` + "one (its identity differs from the one that deploy recorded, so its name was reused).");
34063
- op.physicalIdRecoveredFromError = false;
34064
- } else if (created === "unproven") {
34065
- logger.warn(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is not deleted: nothing proves the resource now under its physical ` + "id is the one that deploy created (it may have been deleted and its name reused).");
34066
- op.physicalIdRecoveredFromError = false;
34067
- }
34068
- continue;
34069
- }
34070
- if (holding.kind === "held") {
34071
- logger.warn(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is not deleted: ${holding.by} holds a resource of that type under ` + "the same physical id.");
34072
- op.physicalIdRecoveredFromError = false;
34073
- continue;
34074
- }
34075
- logger.warn(safeMsg`${logicalIdShown(op.logicalId)} (${resourceTypeShown(op.resourceType)}), which a failed deploy ` + safeMsg`of stack ${stack} created, is not deleted: ${holding.what}, so whether another stack holds it is unknown.`);
34076
- unreadable.add(op);
34077
- }
34078
- return {
34079
- unreadable,
34080
- tracked
34081
- };
34082
- }
34083
- async function recordIdentity(op, record, ctx, logger) {
34084
- if (typeof record !== "object" || record === null || record.resourceType !== op.resourceType || typeof record.physicalId !== "string" || record.physicalId === "" || !op.physicalId) return "unknown";
34085
- try {
34086
- const { provider } = ctx.providerRegistry.getProviderFor({
34087
- resourceType: op.resourceType,
34088
- provisionedBy: op.provisionedBy
34089
- });
34090
- if (typeof provider.isSameResource !== "function") return "unknown";
34091
- return await provider.isSameResource(op.physicalId, {
34092
- physicalId: record.physicalId,
34093
- ...record.provisionedBy !== void 0 && { provisionedBy: record.provisionedBy }
34094
- }, op.resourceType, { expectedRegion: ctx.region });
34095
- } catch (err) {
34096
- logger.debug(safeMsg`Could not compare ${logicalIdShown(op.logicalId)}'s journaled resource with its state record (${displaySafe(err instanceof Error ? err.name : typeof err)}).`);
34097
- return "unknown";
34098
- }
34099
- }
34100
- async function createdResourceStillThere(op, ctx) {
34101
- if (op.deletionPolicy === "Retain") return "proven";
34102
- if (!orphanDeleteNeedsIdentity(op.resourceType)) return "proven";
34103
- const physicalId = op.physicalId;
34104
- if (!physicalId) return "unproven";
34105
- const live = await readResourceIdentity(ctx.providerRegistry, {
34106
- resourceType: op.resourceType,
34107
- physicalId,
34108
- provisionedBy: op.provisionedBy
34109
- }, ctx.region);
34110
- if (live === RESOURCE_NOT_FOUND) return "gone";
34111
- const journaled = op.createdResourceIdentity;
34112
- if (typeof journaled !== "string" || journaled === "" || typeof live !== "string") return "unproven";
34113
- return live === journaled ? "proven" : "mismatch";
34114
- }
34115
- function makeForeignHolderScan(stateBackend) {
34116
- let scan;
34117
- const key = (type, id) => JSON.stringify([type, id]);
34118
- const run = async () => {
34119
- const holders = /* @__PURE__ */ new Map();
34120
- let refs;
34121
- try {
34122
- refs = await stateBackend.listStacks();
34123
- } catch {
34124
- return {
34125
- holders,
34126
- unreadable: "the state bucket listing (it could not be read)"
34127
- };
34128
- }
34129
- let unreadable;
34130
- await Promise.all(refs.map(async (ref) => {
34131
- const named = (why) => safeMsg`the state record of stack ${displayIdent(ref.stackName)} (${why})`;
34132
- if (ref.region === void 0) {
34133
- unreadable ??= named("its region cannot be read");
34134
- return;
34135
- }
34136
- const region = ref.region;
34137
- let state;
34138
- try {
34139
- state = (await stateBackend.getState(ref.stackName, region))?.state;
34140
- } catch {
34141
- unreadable ??= named("it could not be read");
34142
- return;
34143
- }
34144
- if (state === void 0) return;
34145
- const resources = state.resources;
34146
- if (resources !== void 0 && (typeof resources !== "object" || resources === null || Array.isArray(resources))) {
34147
- unreadable ??= named("its resources cannot be read");
34148
- return;
34149
- }
34150
- if (!hasReadableOrphans(state) || unreadableOrphanRecords(state).length > 0) {
34151
- unreadable ??= named("its rollback-orphan records cannot be read");
34152
- return;
34153
- }
34154
- const held = [...Object.values(resources ?? {}), ...(state.orphans ?? []).map((record) => record.state)];
34155
- for (const record of held) {
34156
- const r = record;
34157
- if (typeof r?.resourceType !== "string" || typeof r.physicalId !== "string") continue;
34158
- const k = key(r.resourceType, r.physicalId);
34159
- const list = holders.get(k) ?? [];
34160
- list.push({
34161
- stackName: ref.stackName,
34162
- region
34163
- });
34164
- holders.set(k, list);
34165
- }
34166
- }));
34167
- return {
34168
- holders,
34169
- ...unreadable !== void 0 && { unreadable }
34170
- };
34171
- };
34172
- return (self) => async (resourceType, physicalId) => {
34173
- scan ??= run();
34174
- const { holders, unreadable } = await scan;
34175
- const other = (holders.get(key(resourceType, physicalId)) ?? []).find((h) => !(h.stackName === self.stackName && h.region === self.region));
34176
- if (other) return {
34177
- kind: "held",
34178
- by: safeMsg`the state record of stack ${displayIdent(other.stackName)} (${displaySafe(other.region)})`
34179
- };
34180
- return unreadable === void 0 ? void 0 : {
34181
- kind: "unreadable",
34182
- what: unreadable
34183
- };
34184
- };
34185
- }
34186
- async function markSuperseded(stateBackend, stackName, region, ids) {
34187
- try {
34188
- await stateBackend.markRollbackJournalSuperseded(stackName, region, ids);
34189
- } catch {}
34190
- }
34191
- function errorDetail(err) {
34192
- return displaySafe(err instanceof Error ? err.message : String(err));
34193
- }
34194
- function isHandledOrphan(handled, segment, op) {
34195
- return handled.some((h) => h.segment.timestamp === segment.timestamp && h.segment.runId === segment.runId && h.op.logicalId === op.logicalId && h.op.changeType === op.changeType && h.op.resourceType === op.resourceType && h.op.physicalId === op.physicalId);
34196
- }
34197
- function orphanKey(segment, op) {
34198
- return JSON.stringify([
34199
- segment.timestamp,
34200
- segment.runId ?? null,
34201
- op.logicalId,
34202
- op.changeType,
34203
- op.resourceType,
34204
- op.physicalId ?? null
34205
- ]);
34206
- }
34207
- function sameJournaledOrphans(a, b) {
34208
- const keys = (o) => o.segments.flatMap(({ segment, ops }) => ops.map((op) => orphanKey(segment, op))).sort();
34209
- const ka = keys(a);
34210
- const kb = keys(b);
34211
- return ka.length === kb.length && ka.every((k, i) => k === kb[i]);
34212
- }
34213
-
34214
34271
  //#endregion
34215
34272
  //#region src/deployment/deploy-engine/rollback.ts
34216
34273
  function redactOperationsForJournal(operations) {
@@ -35755,8 +35812,8 @@ function buildResolverContext(base, stackName) {
35755
35812
  ...base.redactedAttributeReads && { redactedAttributeReads: base.redactedAttributeReads }
35756
35813
  };
35757
35814
  }
35758
- function printNestedStackReadsOnly(context, resourceType) {
35759
- if (resourceType === "AWS::CloudFormation::Stack") context.printingSecrets = /* @__PURE__ */ new Map();
35815
+ function printNestedStackReadsOnly(context, resourceType, rowPrintingRegistry) {
35816
+ if (resourceType === "AWS::CloudFormation::Stack") context.printingSecrets = rowPrintingRegistry;
35760
35817
  }
35761
35818
  function getAttTargetOf(node) {
35762
35819
  if (node === null || typeof node !== "object" || Array.isArray(node)) return void 0;
@@ -35824,7 +35881,7 @@ async function provisionCreate(logicalId, change, stateResources, stackName, tem
35824
35881
  if (context.recordedSecretValues) this.perResourceSecrets.set(logicalId, context.recordedSecretValues);
35825
35882
  const noEchoOverrides = await this.noEchoAttributeOverridesFor(desiredProps, stateResources, stackName);
35826
35883
  if (noEchoOverrides !== void 0) context.noEchoAttributeOverrides = noEchoOverrides;
35827
- printNestedStackReadsOnly(context, resourceType);
35884
+ printNestedStackReadsOnly(context, resourceType, this.secretNameBagFor(logicalId));
35828
35885
  const resolvedProps = await this.resolver.resolve(desiredProps, context);
35829
35886
  this.noteSecretNamedRecord(logicalId, {
35830
35887
  resourceType,
@@ -36036,7 +36093,7 @@ async function provisionUpdate(logicalId, change, stateResources, stackName, tem
36036
36093
  this.perResourceSecrets.set(logicalId, updateSecrets);
36037
36094
  const noEchoOverrides = await this.noEchoAttributeOverridesFor(desiredProps, stateResources, stackName);
36038
36095
  if (noEchoOverrides !== void 0) context.noEchoAttributeOverrides = noEchoOverrides;
36039
- printNestedStackReadsOnly(context, resourceType);
36096
+ printNestedStackReadsOnly(context, resourceType, this.secretNameBagFor(logicalId));
36040
36097
  const resolvedProps = await this.resolver.resolve(desiredProps, context);
36041
36098
  this.noteSecretNamedRecord(logicalId, {
36042
36099
  resourceType,
@@ -38156,7 +38213,7 @@ function hasOwn(bag, key) {
38156
38213
  return Object.prototype.hasOwnProperty.call(bag, key);
38157
38214
  }
38158
38215
  function mergeNoChangeOutputs(input) {
38159
- const { persisted, resolved, declaredOutputs, previousExportNames, resolvedExportNames } = input;
38216
+ const { persisted, resolved, declaredOutputs, previousExportNames, resolvedExportNames, refusesCarriedAlias } = input;
38160
38217
  const failedKeys = Object.keys(resolved).filter((key) => resolved[key] === void 0);
38161
38218
  const exportNameOf = (outputKey) => declaredOutputs !== void 0 && hasOwn(declaredOutputs, outputKey) ? declaredOutputs[outputKey]?.Export?.Name : void 0;
38162
38219
  for (const outputKey of failedKeys) {
@@ -38173,15 +38230,26 @@ function mergeNoChangeOutputs(input) {
38173
38230
  const addExport = (name) => {
38174
38231
  exportNames.push(name);
38175
38232
  };
38233
+ const refusedAliases = [];
38234
+ const carryAllowed = (outputKey, exportName) => {
38235
+ const reason = refusesCarriedAlias(outputKey, exportName);
38236
+ if (reason === void 0) return true;
38237
+ refusedAliases.push({
38238
+ outputKey,
38239
+ exportName,
38240
+ reason
38241
+ });
38242
+ return false;
38243
+ };
38176
38244
  for (const outputKey of failedKeys) {
38177
38245
  const exportName = exportNameOf(outputKey);
38178
38246
  if (hasOwn(persisted, outputKey)) {
38179
38247
  outputs[outputKey] = persisted[outputKey];
38180
38248
  carriedKeys.push(outputKey);
38181
- if (exportName === outputKey && previousExportNames.has(outputKey)) addExport(outputKey);
38249
+ if (exportName === outputKey && previousExportNames.has(outputKey) && carryAllowed(outputKey, outputKey)) addExport(outputKey);
38182
38250
  }
38183
38251
  if (typeof exportName !== "string") continue;
38184
- if (previousExportNames.has(exportName) && hasOwn(persisted, exportName) && !hasOwn(resolved, exportName) && !hasOwn(outputs, exportName)) {
38252
+ if (previousExportNames.has(exportName) && hasOwn(persisted, exportName) && !hasOwn(resolved, exportName) && !hasOwn(outputs, exportName) && carryAllowed(outputKey, exportName)) {
38185
38253
  outputs[exportName] = persisted[exportName];
38186
38254
  carriedKeys.push(exportName);
38187
38255
  addExport(exportName);
@@ -38195,7 +38263,8 @@ function mergeNoChangeOutputs(input) {
38195
38263
  kind: "merged",
38196
38264
  outputs,
38197
38265
  exportNames,
38198
- carriedKeys
38266
+ carriedKeys,
38267
+ refusedAliases
38199
38268
  };
38200
38269
  }
38201
38270
  function keptWholeReasonText(reason) {
@@ -38891,7 +38960,8 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
38891
38960
  resolved: resolvedOutputs,
38892
38961
  declaredOutputs: effectiveTemplate.Outputs,
38893
38962
  previousExportNames: currentEffectiveExports,
38894
- resolvedExportNames: this.resolvedExportNames
38963
+ resolvedExportNames: this.resolvedExportNames,
38964
+ refusesCarriedAlias: (outputKey, exportName) => this.carriedExportAliasRefusal === void 0 ? "An export alias was not carried: no export-name verdict is available." : this.carriedExportAliasRefusal(outputKey, exportName)
38895
38965
  }) : void 0;
38896
38966
  if (merge?.kind === "merged") {
38897
38967
  for (const key of merge.carriedKeys) Reflect.deleteProperty(this.outputsTemplateSource, key);
@@ -38901,6 +38971,7 @@ async function doDeployWithPrefetch(stackName, template, createOnlyPrefetch) {
38901
38971
  };
38902
38972
  }
38903
38973
  if (merge?.kind === "kept") this.outputsSourceUsable = false;
38974
+ if (merge?.kind === "merged") for (const { reason } of merge.refusedAliases) this.logger.warn(reason);
38904
38975
  const outputsToPersist = merge === void 0 ? resolvedOutputs : merge.kind === "merged" ? merge.outputs : persistedOutputs;
38905
38976
  const exportNamesToPersist = merge === void 0 ? this.resolvedExportNames : merge.kind === "merged" ? merge.exportNames : void 0;
38906
38977
  const outputsChanged = !outputMapsEqual(persistedOutputs, outputsToPersist);
@@ -39276,6 +39347,7 @@ var DeployEngine = class {
39276
39347
  outputsPassSecretMaps = [];
39277
39348
  outputsTemplateSource = Object.create(null);
39278
39349
  resolvedExportNames = [];
39350
+ carriedExportAliasRefusal;
39279
39351
  skippedOutputs;
39280
39352
  constructPathTemplate;
39281
39353
  outputsSourceUsable = true;
@@ -39559,5 +39631,5 @@ DeployEngine.prototype.replacementNameOrigin = replacementNameOrigin;
39559
39631
  DeployEngine.prototype.orphanedNameCollisionAdvice = orphanedNameCollisionAdvice;
39560
39632
 
39561
39633
  //#endregion
39562
- export { recordDisplacedSkips as $, noEchoLeavesOf as $a, refuseMalformedResourcesForDeploy as $i, withPrintingSecrets as $n, importableOutputs as $o, passedParameterClassesOf as $r, resolveStateBucketWithDefault as $s, secretNamePrintingBag as $t, gray as A, coerceCfnBoolean as Aa, resolveBucketRegion as Ac, malformedScrubResourceEntriesRefusalMessage as Ai, findDestructiveChanges as An, recordMaskOnlyValue as Ao, envCredentialsAreAssumedRole as Ar, formatDockerLoginError as As, removeProtectionTypeList as At, isHandledOrphan as B, prefetchCreateOnlyPropertyPaths as Ba, refuseMalformedOutputs as Bi, planTagDiff as Bn, isSingleDynamicReferenceToken as Bo, getAccountInfo as Br, escapeRegExp$3 as Bs, findNestedStackTypeChanges as Bt, recordedProtectionNote as C, isStatefulRecreateTargetSync as Ca, ownValue as Cc, malformedOrphansWarning as Ci, collectPublishedOutputNames as Cn, pathCrossesDottedKey as Co, assertSendableRoleArn as Cr, buildDockerImage as Cs, INDEX_SETTLE_POLL_INTERVAL_MS as Ct, createReadOnlyAttributeHealerFactory as D, isWarmThroughputDecrease as Da, renderAssemblyPathEscape as Dc, malformedResourceEntriesWarning as Di, DEFAULT_RESOURCE_WARN_AFTER_MS as Dn, identityKeyFor as Do, AWS_CREDENTIAL_ENV_KEYS as Dr, describeDockerFailure as Ds, S3_AUTO_DELETE_OBJECTS_TAG as Dt, formatResourceLine as E, coerceWarmThroughput as Ea, displayAssemblyPath as Ec, malformedRenderedContainersWarning as Ei, DEFAULT_RESOURCE_TIMEOUT_MS as En, recoverMaskedOutput as Eo, sendableAssumeRoleCommand as Er, describeDockerExecFailure as Es, ECR_AUTO_DELETE_IMAGES_TAG as Et, namesAnyDeclaredParameter as F, readConfigString as Fa, refuseMalformedOrphanRecords as Fi, reserveStackCreateToken as Fn, STATE_SOURCED_BASELINE_RULES as Fo, s3BucketRegionalDomainName as Fr, redactDockerArgvValues as Fs, isReplacementOrphan as Ft, makeSiblingClaimReader as G, lambdaFunctionNameForMask as Ga, refuseMalformedResourceEntriesForDestroy as Gi, definedAttributes as Gn, splitImportedOps as Go, keepsSecretReferenceToken as Gr, synthesisStatusMessage as Gs, redactedDeleteAddressFields as Gt, loadJournaledOrphans as H, describeTypeWithThrottleRetry as Ha, refuseMalformedResourceAttributesForOrphan as Hi, refuseMalformedDesiredTags as Hn, isLockInfoExpired as Ho, carriesDynamicReference as Hr, AssetManifestLoader as Hs, inheritProducerRegions as Ht, reachableDivergentParameters as I, replayWarn as Ia, refuseMalformedOrphanRecordsForDestroy as Ii, withCreateTokenLedger as In, STATE_SOURCED_CROSS_GENERATION_RULES as Io, s3BucketWebsiteUrl as Ir, redactedDockerCause as Is, planFailedOps as It, displacedOpClause as J, TemplateParser as Ja, refuseMalformedResourceEntriesForOrphan as Ji, ProviderRegistry as Jn, exportNamesCarriedFrom as Jo, isStalePlaceholderArnAttribute as Jr, loadCdkJson as Js, updatePartialReason as Jt, planOrphanAdoption as K, sameLambdaFunctionAddress as Ka, refuseMalformedResourceEntriesForImport as Ki, stringifyIfAssigned as Kn, acceptedCreateOnlyDropsOf as Ko, AWS_NO_VALUE as Kr, getDefaultStateBucketName as Ks, redactedDeleteAddressSkip as Kt, resourcesNamingDeclaredParameter as L, requireConfigArray as La, refuseMalformedOrphans as Li, acquireIdempotencyToken as Ln, STATE_SOURCED_READBACK_RULES as Lo, coerceParameterTypedValue as Lr, runDockerForeground as Ls, planRollback as Lt, red as M, configBooleanRefusal as Ma, previewableOrphanRecords as Mi, RollbackInlinePolicyWriters as Mn, recordNoEchoAttributeValues as Mo, s3BucketArn as Mr, isDockerClientEnvKey as Ms, recordAfterRollbackUpdate as Mt, yellow as N, configIntegerRefusal as Na, refuseDivergentRecordRegionForDestroy as Ni, earliestDefined as Nn, recordProvenPublicExpression as No, s3BucketDomainName as Nr, isMalformedEnvKey as Ns, demoteSupersededOrphans as Nt, bold as O, toCfnInteger as Oa, resolveAssemblyPath as Oc, malformedResourcePropertiesWarning as Oi, maskingRetryLogger as On, carriesSecretMask as Oo, applyCallerIdentityCredentials as Or, dockerSpawnEnvWithSensitive as Os, hasCdkAutoDeleteTag as Ot, computeParameterTaint as P, configStringRefusal as Pa, refuseMalformedNestedChildOutputs as Pi, ledgerForStack as Pn, wholeStringLeavesOf as Po, s3BucketDualStackDomainName as Pr, partitionSensitiveEnv as Ps, isJournaledOrphan as Pt, nestedChildStackName as Q, maskedLeafCoordinatesOf as Qa, refuseMalformedResourcePropertiesForOrphan as Qi, getCurrentResourceSecrets as Qn, importableOutputKeys as Qo, parameterInputsFor as Qr, resolveSkipPrefix as Qs, orphanRecordsPrintingBag as Qt, deleteJournaledOrphans as R, requireConfigObject as Ra, refuseMalformedOrphansForDestroy as Ri, DBPROXY_TAGS_WHAT as Rn, TEMPLATE_SOURCED_RULES as Ro, isUnboundTemplateParameter as Rr, runDockerStreaming as Rs, replacementNeverSwapped as Rt, recordedProtectionEvidence as S, isStatefulRecreateTargetForReplace as Sa, nullPrototypeRecord as Sc, malformedOrphansRefusalMessage as Si, collectDeclaredOutputNames as Sn, isUncertifiedBaselineMaskPosition as So, assertFlagRoleArn as Sr, buildDenyExternalAccessPolicy as Ss, DELETE_INDEX_WAIT_PROCEED_NOTE as St, markRefusedBeforeApplying as T, WARM_THROUGHPUT_MEMBERS as Ta, describeFileReadFailure as Tc, malformedOutputsWarning as Ti, bindingSkippedOutputs as Tn, recordNestedStackParameterExpressions as To, isIamRoleArn as Tr, describeDockerCapturedOutput as Ts, waitForIndexesSettled as Tt, makeForeignHolderScan as U, withRetry as Ua, refuseMalformedResourceEntries as Ui, tagMapAsList as Un, S3StateBackend as Uo, carriesFetchableDynamicReference as Ur, getDockerImageBySourceHash as Us, REDACTED_DELETE_ADDRESS_SKIP_REASON as Ut, journaledOrphanLines as V, templateResourceTypes as Va, refuseMalformedOutputsForDestroy as Vi, readTagList as Vn, LockManager as Vo, isImpossibleEmptyStoredAttribute as Vr, stripControlChars as Vs, getCurrentProducerRegions as Vt, sameJournaledOrphans as W, canonicalLambdaFunctionName as Wa, refuseMalformedResourceEntriesForDeploy as Wi, tagPlanWarning as Wn, rebuildClientForBucketRegion as Wo, isNamelessDynamicReferenceError as Wr, Synthesizer as Ws, isRedactedRecordedValue as Wt, dropSettledNestedJournals as X, maskReadbackAtCoordinates as Xa, refuseMalformedResourcePropertiesForDrift as Xi, wouldReturnToSdkProvider as Xn, hasReasonlessBaselineRefusal as Xo, parseWebACLArn as Xr, resolveAutoAssetStorage as Xs, journaledOrphanPrintingBag as Xt, displacedPhysicalIdShown as Y, isMarkedCoordinate as Ya, refuseMalformedResourcePropertiesForDestroy as Yi, ccBrokenReason as Yn, hasReadableExportSet as Yo, refStateLookupFromResource as Yr, resolveApp as Ys, completedReplayEntries as Yt, getNestedRevertRun as Z, maskWholeValue as Za, refuseMalformedResourcePropertiesForExport as Zi, isCustomResourceType as Zn, hasUnverifiableParameterRefusal as Zo, withSharedDrainBudget as Zr, resolveCaptureObservedState as Zs, maskEventTextWithBoundBags as Zt, makeCanonicalizePropertiesFn as _, NO_CC_HANDLERS_REASON as _a, StageLoadError as _c, malformedLocalResourceEntriesWarning as _i, secretBearingStateKeyWarning as _n, markSameGenerationBag as _o, IntrinsicFunctionResolver as _r, isCrossRegionRedirect as _s, beginDeleteWait as _t, findNestedTemplateTreeDefect as a, repairMalformedOutputsForReadOnly as aa, CFN_TEMPLATE_BODY_LIMIT as ac, accountArgs as ai, createPreDeleteFinalSnapshot as an, createUnionSecretMasker as ao, deleteSkipReason as ar, isSensitiveAttributeName as as, replayFailedOperations as at, noEchoParameterNamesOf as b, shownType as ba, hasOwnKey as bc, malformedOrphanRecordsWarning as bi, isWholeDynamicReferenceValue as bn, DYNAMIC_REFERENCE_TOKEN_SCAN as bo, regionLessSecretName as br, validateAssetBucketName as bs, resolveDynamoDbDeleteBudgetClock as bt, renderNestedTemplateTreeDefect as c, repairMalformedResourcesForReadOnly as ca, findLargeInlineResources as cc, hasReadableOrphans as ci, refusesFinalSnapshot as cn, logOnlyValueCount as co, markWaitAbandoned as cr, buildAssetRedirectMap as cs, destroyStackRecordsView as ct, conditionInputsFrom as d, unreadableResourceEntries as da, decodeListingKey as dc, isReadableOrphanRecord as di, DeploymentEventsStore as dn, recordLogOnlyValue as do, isTerminationProtectionPropagationError as dr, rewriteTemplateAssetReferences as ds, PROTECTION_PROPERTY_BY_TYPE as dt, refuseMalformedResourcesForDestroy as ea, resolveStateBucketWithDefaultAndSource as ec, JSON_LISTING_HOLE_VALUE as ei, stateSecretNameNeedles as en, noEchoOutputsComparison as eo, CloudControlProvider as er, isReadableBag as es, revertNestedChildFromJournal as et, parentSuppliedValues as f, withheldAccountClause as fa, expectedOwnerParam as fc, isReadableResourceEntry as fi, extractDeploymentEventError as fn, shareLogOnlyValues as fo, observeThenDisableInstanceApiTermination as fr, AssetModeResolver as fs, isProtectionValueActive as ft, mergeNoChangeOutputs as g, withoutSilentDropProperties as ga, AssemblyReader as gc, malformedLocalOutputsWarning as gi, secretBearing as gn, maskSecretsInText as go, INTRINSIC_KEYS as gr, getBootstrapMarkerKey as gs, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as gt, keptWholeReasonText as h, unwrittenCreateOnlyReplacement as ha, derivePartitionAndUrlSuffix as hc, malformedExportSourceWarning as hi, exportAliasCollisionScrubWarning as hn, maskSecretsInError as ho, DiffCalculator as hr, ensureAssetStorage as hs, DynamoDBGlobalTableProvider as ht, childTemplateLoader as i, repairMalformedOrphansForReadOnly as ia, ssmResolvedValueType as ic, UNREADABLE_RESOURCES_MAP_ROW as ii, ccRoutedFinalSnapshotError as in, carryLogOnlyValues as io, deleteIndeterminateGuards as ir, AssetPublisher as is, withNestedStackContext as it, green as j, coerceCfnInteger as ja, malformedStateRefusalMessage as ji, formatDestructiveChange as jn, recordMaskOnlyValuesIn as jo, isSettledInstanceState as jr, getDockerCmd as js, orphanDeleteNeedsIdentity as jt, cyan as k, toFiniteNumber as ka, clearBucketRegionCache as kc, malformedResourcesWarning as ki, constructPathOf as kn, provenPublicValue as ko, callerEnvCredentials as kr, finchSecretArgvRefusal as ks, isTruthyCfnBoolean as kt, templateIdentity as l, unpreviewableOrphanRecords as la, uploadCfnTemplate as lc, hasReadableOutputs as li, unsupportedFinalSnapshotError as ln, printingCorpusOf as lo, disableInstanceApiTermination as lr, createAssetRedirectResolver as ls, getStackRecords as lt, isSecretBearingReferenceString as m, findSilentDropProperties as ma, canonicalizeRegion as mc, malformedExportNamesWarning as mi, displayTextOrWithheld as mn, errorCauseChain as mo, reEnableInstanceApiTermination as mr, assertAssetBucketRegion as ms, readProtection as mt, IMPLICIT_DELETE_DEPENDENCIES as n, refuseMalformedState as na, stateBucketExistenceConfirmed as nc, STATE_RESOURCES_MALFORMED as ni, PRE_DELETE_SNAPSHOT_TYPES as nn, readsNoEchoSource as no, unchangedBehindSecretReference as nr, orphansCarriedFrom as ns, withNestedRevertRun as nt, isAbsoluteAssetPath as o, repairMalformedResourceEntriesForReadOnly as oa, CFN_TEMPLATE_URL_LIMIT as oc, deployRefusesOrphanRowsReason as oi, effectiveDeletionPolicy as on, hasMaskableValues as oo, withIndeterminateGuard as or, stringifyValue as os, replayRollback as ot, readRecordedConditionVerdicts as p, findActionableSilentDrops as pa, PARTITION_TABLE as pc, malformedDriftResourcePropertiesWarning as pi, WITHHELD_NAME_DISPLAY as pn, createSecretMasker as po, reDisableInstanceApiTermination as pr, BOOTSTRAP_MARKER_PREFIX as ps, perType as pt, NESTED_PENDING_PARENT_REASON as q, DagBuilder as qa, refuseMalformedResourceEntriesForImportSave as qi, CC_BROKEN_REASON as qn, describeRegionValueKind as qo, cfnRefValueFromPhysicalId as qr, getLegacyStateBucketName as qs, updatePartialMessage as qt, computeImplicitDeleteEdges as r, repairMalformedOrphanRecordsForReadOnly as ra, warnDeprecatedNoPrefixCliFlag as rc, UNREADABLE_ORPHANS_CONTAINER_ROW as ri, buildFinalSnapshotIdentifier as rn, liveMatchesUnresolvedTokenFrame as ro, UNSPECIFIED_SKIP_REASON as rr, shouldRetainResource as rs, getCurrentNestedStackContext as rt, listNestedTemplateRows as s, repairMalformedResourcePropertiesForReadOnly as sa, MIGRATE_TMP_PREFIX as sc, displayLogicalId as si, isFinalSnapshotError as sn, literalSplitDelimitersOf as so, isWaitAbandonedError as sr, WorkGraph as ss, awaitInFlightSibling as st, DeployEngine as t, refuseMalformedResourcesForExport as ta, resolveUseCdkBootstrapAssets as tc, STATE_REGION_DIVERGED as ti, ATOMIC_FINAL_SNAPSHOT_TYPES as tn, passedNoEchoParametersOf as to, slowCcOperationTimeoutMs as tr, orphansAfterRollback as ts, revertedNestedRowIds as tt, conditionFingerprint as u, unreadableOrphanRecords as ua, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as uc, hasReadableResources as ui, DeploymentEventsReader as un, recordLogOnlyParameterValue as uo, ec2InstanceProtectionSite as ur, loadPublishableAssetManifest as us, withStackRecords as ut, noEchoAttributeNamesOf as v, hasNoCloudControlHandlers as va, processStackMessages as vc, malformedLocalResourcesWarning as vi, secretSafeKeyDisplay as vn, redactSecretsForState as vo, classifyReplaySecretRegion as vr, parseBootstrapMarker as vs, compensateRemovedDeletionProtection as vt, getPriorAttempts as w, renderStatefulReason as wa, absoluteAssemblyPathEscape as wc, malformedOutputsRefusalMessage as wi, isExportAliasCollision as wn, inheritNestedStackParameterAssociations as wo, explicitRoleArnOrThrow as wr, resolveDockerContextDirectory as ws, deleteTableWithIndexBusyRetry as wt, withResourceDeadline as x, MULTI_REGION_RECREATE_BLOCKED_TYPES as xa, hasPlainPrototype$1 as xc, malformedOrphanRowsKeptWarning as xi, noEchoParameterValueSeed as xn, dynamicReferenceTokens as xo, applyRoleArnIfSet as xr, validateContainerRepoName as xs, resolveDynamoDbDeleteBudgetMs as xt, noEchoComparisonForTemplate as y, findReplacedReadersOfRecreateTargets as ya, defineOwnKey as yc, malformedOrphanRecordsRefusalMessage as yi, exportNameSecretExposure as yn, scrubResourceRecord as yo, producerRegionsFromState as yr, readBootstrapMarkerBody as ys, deleteBudgetKey as yt, dropFailedHint as z, requireConfigString as za, refuseMalformedOrphansForOrphan as zi, DBPROXY_TAG_OPTIONS as zn, WHOLE_DYNAMIC_REFERENCE_PATTERN as zo, parameterTypeMayLoseSecretIdentity as zr, warnFinchArgvExposure as zs, resolveReplacementOldType as zt };
39563
- //# sourceMappingURL=deploy-engine-FDsHckZR.js.map
39634
+ export { dropFailedHint as $, maskReadbackAtCoordinates as $a, refuseMalformedResourcePropertiesForDrift as $i, wouldReturnToSdkProvider as $n, hasReasonlessBaselineRefusal as $o, parseWebACLArn as $r, resolveAutoAssetStorage as $s, secretNamePrintingBag as $t, gray as A, isWarmThroughputDecrease as Aa, renderAssemblyPathEscape as Ac, malformedResourceEntriesWarning as Ai, maskingRetryLogger as An, identityKeyFor as Ao, AWS_CREDENTIAL_ENV_KEYS as Ar, describeDockerFailure as As, removeProtectionTypeList as At, NESTED_PENDING_PARENT_REASON as B, requireConfigArray as Ba, refuseMalformedOrphans as Bi, DBPROXY_TAGS_WHAT as Bn, STATE_SOURCED_READBACK_RULES as Bo, coerceParameterTypedValue as Br, runDockerForeground as Bs, findNestedStackTypeChanges as Bt, recordedProtectionNote as C, shownType as Ca, hasOwnKey as Cc, malformedOrphanRecordsWarning as Ci, noEchoParameterValueSeed as Cn, DYNAMIC_REFERENCE_TOKEN_SCAN as Co, regionLessSecretName as Cr, validateAssetBucketName as Cs, INDEX_SETTLE_POLL_INTERVAL_MS as Ct, createReadOnlyAttributeHealerFactory as D, renderStatefulReason as Da, absoluteAssemblyPathEscape as Dc, malformedOutputsRefusalMessage as Di, bindingSkippedOutputs as Dn, inheritNestedStackParameterAssociations as Do, explicitRoleArnOrThrow as Dr, resolveDockerContextDirectory as Ds, S3_AUTO_DELETE_OBJECTS_TAG as Dt, formatResourceLine as E, isStatefulRecreateTargetSync as Ea, ownValue as Ec, malformedOrphansWarning as Ei, isExportAliasCollision as En, pathCrossesDottedKey as Eo, assertSendableRoleArn as Er, buildDockerImage as Es, ECR_AUTO_DELETE_IMAGES_TAG as Et, namesAnyDeclaredParameter as F, configBooleanRefusal as Fa, previewableOrphanRecords as Fi, earliestDefined as Fn, recordNoEchoAttributeValues as Fo, s3BucketArn as Fr, isDockerClientEnvKey as Fs, isReplacementOrphan as Ft, nestedChildStackName as G, describeTypeWithThrottleRetry as Ga, refuseMalformedResourceAttributesForOrphan as Gi, tagMapAsList as Gn, isLockInfoExpired as Go, carriesDynamicReference as Gr, AssetManifestLoader as Gs, redactedDeleteAddressFields as Gt, displacedPhysicalIdShown as H, requireConfigString as Ha, refuseMalformedOrphansForOrphan as Hi, planTagDiff as Hn, WHOLE_DYNAMIC_REFERENCE_PATTERN as Ho, parameterTypeMayLoseSecretIdentity as Hr, warnFinchArgvExposure as Hs, inheritProducerRegions as Ht, reachableDivergentParameters as I, configIntegerRefusal as Ia, refuseDivergentRecordRegionForDestroy as Ii, ledgerForStack as In, recordProvenPublicExpression as Io, s3BucketDomainName as Ir, isMalformedEnvKey as Is, planFailedOps as It, revertedNestedRowIds as J, lambdaFunctionNameForMask as Ja, refuseMalformedResourceEntriesForDestroy as Ji, stringifyIfAssigned as Jn, splitImportedOps as Jo, keepsSecretReferenceToken as Jr, synthesisStatusMessage as Js, updatePartialReason as Jt, recordDisplacedSkips as K, withRetry as Ka, refuseMalformedResourceEntries as Ki, tagPlanWarning as Kn, S3StateBackend as Ko, carriesFetchableDynamicReference as Kr, getDockerImageBySourceHash as Ks, redactedDeleteAddressSkip as Kt, resourcesNamingDeclaredParameter as L, configStringRefusal as La, refuseMalformedNestedChildOutputs as Li, reserveStackCreateToken as Ln, wholeStringLeavesOf as Lo, s3BucketDualStackDomainName as Lr, partitionSensitiveEnv as Ls, planRollback as Lt, red as M, toFiniteNumber as Ma, clearBucketRegionCache as Mc, malformedResourcesWarning as Mi, findDestructiveChanges as Mn, provenPublicValue as Mo, callerEnvCredentials as Mr, finchSecretArgvRefusal as Ms, recordAfterRollbackUpdate as Mt, yellow as N, coerceCfnBoolean as Na, resolveBucketRegion as Nc, malformedScrubResourceEntriesRefusalMessage as Ni, formatDestructiveChange as Nn, recordMaskOnlyValue as No, envCredentialsAreAssumedRole as Nr, formatDockerLoginError as Ns, demoteSupersededOrphans as Nt, bold as O, WARM_THROUGHPUT_MEMBERS as Oa, describeFileReadFailure as Oc, malformedOutputsWarning as Oi, DEFAULT_RESOURCE_TIMEOUT_MS as On, recordNestedStackParameterExpressions as Oo, isIamRoleArn as Or, describeDockerCapturedOutput as Os, hasCdkAutoDeleteTag as Ot, computeParameterTaint as P, coerceCfnInteger as Pa, malformedStateRefusalMessage as Pi, RollbackInlinePolicyWriters as Pn, recordMaskOnlyValuesIn as Po, isSettledInstanceState as Pr, getDockerCmd as Ps, isJournaledOrphan as Pt, deleteJournaledOrphans as Q, isMarkedCoordinate as Qa, refuseMalformedResourcePropertiesForDestroy as Qi, isCustomResource as Qn, hasReadableExportSet as Qo, refStateLookupFromResource as Qr, resolveApp as Qs, orphanRecordsPrintingBag as Qt, makeSiblingClaimReader as R, readConfigString as Ra, refuseMalformedOrphanRecords as Ri, withCreateTokenLedger as Rn, STATE_SOURCED_BASELINE_RULES as Ro, s3BucketRegionalDomainName as Rr, redactDockerArgvValues as Rs, replacementNeverSwapped as Rt, recordedProtectionEvidence as S, findReplacedReadersOfRecreateTargets as Sa, defineOwnKey as Sc, malformedOrphanRecordsRefusalMessage as Si, isWholeDynamicReferenceValue as Sn, scrubResourceRecord as So, producerRegionsFromState as Sr, readBootstrapMarkerBody as Ss, DELETE_INDEX_WAIT_PROCEED_NOTE as St, markRefusedBeforeApplying as T, isStatefulRecreateTargetForReplace as Ta, nullPrototypeRecord as Tc, malformedOrphansRefusalMessage as Ti, collectPublishedOutputNames as Tn, isUncertifiedBaselineMaskPosition as To, assertFlagRoleArn as Tr, buildDenyExternalAccessPolicy as Ts, waitForIndexesSettled as Tt, dropSettledNestedJournals as U, prefetchCreateOnlyPropertyPaths as Ua, refuseMalformedOutputs as Ui, readTagList as Un, isSingleDynamicReferenceToken as Uo, getAccountInfo as Ur, escapeRegExp$3 as Us, REDACTED_DELETE_ADDRESS_SKIP_REASON as Ut, displacedOpClause as V, requireConfigObject as Va, refuseMalformedOrphansForDestroy as Vi, DBPROXY_TAG_OPTIONS as Vn, TEMPLATE_SOURCED_RULES as Vo, isUnboundTemplateParameter as Vr, runDockerStreaming as Vs, getCurrentProducerRegions as Vt, getNestedRevertRun as W, templateResourceTypes as Wa, refuseMalformedOutputsForDestroy as Wi, refuseMalformedDesiredTags as Wn, LockManager as Wo, isImpossibleEmptyStoredAttribute as Wr, stripControlChars as Ws, isRedactedRecordedValue as Wt, getCurrentNestedStackContext as X, DagBuilder as Xa, refuseMalformedResourceEntriesForImportSave as Xi, ProviderRegistry as Xn, describeRegionValueKind as Xo, cfnRefValueFromPhysicalId as Xr, getLegacyStateBucketName as Xs, journaledOrphanPrintingBag as Xt, withNestedRevertRun as Y, sameLambdaFunctionAddress as Ya, refuseMalformedResourceEntriesForImport as Yi, CC_BROKEN_REASON as Yn, acceptedCreateOnlyDropsOf as Yo, AWS_NO_VALUE as Yr, getDefaultStateBucketName as Ys, completedReplayEntries as Yt, withNestedStackContext as Z, TemplateParser as Za, refuseMalformedResourceEntriesForOrphan as Zi, ccBrokenReason as Zn, exportNamesCarriedFrom as Zo, isStalePlaceholderArnAttribute as Zr, loadCdkJson as Zs, maskEventTextWithBoundBags as Zt, makeCanonicalizePropertiesFn as _, findSilentDropProperties as _a, canonicalizeRegion as _c, malformedExportNamesWarning as _i, secretBearingStateKeyWarning as _n, errorCauseChain as _o, reEnableInstanceApiTermination as _r, assertAssetBucketRegion as _s, beginDeleteWait as _t, findNestedTemplateTreeDefect as a, refuseMalformedState as aa, stateBucketExistenceConfirmed as ac, STATE_RESOURCES_MALFORMED as ai, createPreDeleteFinalSnapshot as an, readsNoEchoSource as ao, unchangedBehindSecretReference as ar, orphansCarriedFrom as as, replayFailedOperations as at, noEchoParameterNamesOf as b, NO_CC_HANDLERS_REASON as ba, StageLoadError as bc, malformedLocalResourceEntriesWarning as bi, exportNameNoEchoParameters as bn, markSameGenerationBag as bo, IntrinsicFunctionResolver as br, isCrossRegionRedirect as bs, resolveDynamoDbDeleteBudgetClock as bt, renderNestedTemplateTreeDefect as c, repairMalformedOutputsForReadOnly as ca, CFN_TEMPLATE_BODY_LIMIT as cc, accountArgs as ci, refusesFinalSnapshot as cn, createUnionSecretMasker as co, deleteSkipReason as cr, isSensitiveAttributeName as cs, destroyStackRecordsView as ct, conditionInputsFrom as d, repairMalformedResourcesForReadOnly as da, findLargeInlineResources as dc, hasReadableOrphans as di, DeploymentEventsStore as dn, logOnlyValueCount as do, markWaitAbandoned as dr, buildAssetRedirectMap as ds, PROTECTION_PROPERTY_BY_TYPE as dt, refuseMalformedResourcePropertiesForExport as ea, resolveCaptureObservedState as ec, withSharedDrainBudget as ei, stateSecretNameNeedles as en, maskWholeValue as eo, isCustomResourceType as er, hasUnverifiableParameterRefusal as es, isHandledOrphan as et, parentSuppliedValues as f, unpreviewableOrphanRecords as fa, uploadCfnTemplate as fc, hasReadableOutputs as fi, extractDeploymentEventError as fn, printingCorpusOf as fo, disableInstanceApiTermination as fr, createAssetRedirectResolver as fs, isProtectionValueActive as ft, mergeNoChangeOutputs as g, findActionableSilentDrops as ga, PARTITION_TABLE as gc, malformedDriftResourcePropertiesWarning as gi, secretBearing as gn, createSecretMasker as go, reDisableInstanceApiTermination as gr, BOOTSTRAP_MARKER_PREFIX as gs, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as gt, keptWholeReasonText as h, withheldAccountClause as ha, expectedOwnerParam as hc, isReadableResourceEntry as hi, exportAliasCollisionScrubWarning as hn, shareLogOnlyValues as ho, observeThenDisableInstanceApiTermination as hr, AssetModeResolver as hs, DynamoDBGlobalTableProvider as ht, childTemplateLoader as i, refuseMalformedResourcesForExport as ia, resolveUseCdkBootstrapAssets as ic, STATE_REGION_DIVERGED as ii, ccRoutedFinalSnapshotError as in, passedNoEchoParametersOf as io, slowCcOperationTimeoutMs as ir, orphansAfterRollback as is, sameJournaledOrphans as it, green as j, toCfnInteger as ja, resolveAssemblyPath as jc, malformedResourcePropertiesWarning as ji, constructPathOf as jn, carriesSecretMask as jo, applyCallerIdentityCredentials as jr, dockerSpawnEnvWithSensitive as js, orphanDeleteNeedsIdentity as jt, cyan as k, coerceWarmThroughput as ka, displayAssemblyPath as kc, malformedRenderedContainersWarning as ki, DEFAULT_RESOURCE_WARN_AFTER_MS as kn, recoverMaskedOutput as ko, sendableAssumeRoleCommand as kr, describeDockerExecFailure as ks, isTruthyCfnBoolean as kt, templateIdentity as l, repairMalformedResourceEntriesForReadOnly as la, CFN_TEMPLATE_URL_LIMIT as lc, deployRefusesOrphanRowsReason as li, unsupportedFinalSnapshotError as ln, hasMaskableValues as lo, withIndeterminateGuard as lr, stringifyValue as ls, getStackRecords as lt, isSecretBearingReferenceString as m, unreadableResourceEntries as ma, decodeListingKey as mc, isReadableOrphanRecord as mi, displayTextOrWithheld as mn, recordLogOnlyValue as mo, isTerminationProtectionPropagationError as mr, rewriteTemplateAssetReferences as ms, readProtection as mt, IMPLICIT_DELETE_DEPENDENCIES as n, refuseMalformedResourcesForDeploy as na, resolveStateBucketWithDefault as nc, passedParameterClassesOf as ni, PRE_DELETE_SNAPSHOT_TYPES as nn, noEchoLeavesOf as no, withPrintingSecrets as nr, importableOutputs as ns, loadJournaledOrphans as nt, isAbsoluteAssetPath as o, repairMalformedOrphanRecordsForReadOnly as oa, warnDeprecatedNoPrefixCliFlag as oc, UNREADABLE_ORPHANS_CONTAINER_ROW as oi, effectiveDeletionPolicy as on, liveMatchesUnresolvedTokenFrame as oo, UNSPECIFIED_SKIP_REASON as or, shouldRetainResource as os, replayRollback as ot, readRecordedConditionVerdicts as p, unreadableOrphanRecords as pa, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as pc, hasReadableResources as pi, WITHHELD_NAME_DISPLAY as pn, recordLogOnlyParameterValue as po, ec2InstanceProtectionSite as pr, loadPublishableAssetManifest as ps, perType as pt, revertNestedChildFromJournal as q, canonicalLambdaFunctionName as qa, refuseMalformedResourceEntriesForDeploy as qi, definedAttributes as qn, rebuildClientForBucketRegion as qo, isNamelessDynamicReferenceError as qr, Synthesizer as qs, updatePartialMessage as qt, computeImplicitDeleteEdges as r, refuseMalformedResourcesForDestroy as ra, resolveStateBucketWithDefaultAndSource as rc, JSON_LISTING_HOLE_VALUE as ri, buildFinalSnapshotIdentifier as rn, noEchoOutputsComparison as ro, CloudControlProvider as rr, isReadableBag as rs, makeForeignHolderScan as rt, listNestedTemplateRows as s, repairMalformedOrphansForReadOnly as sa, ssmResolvedValueType as sc, UNREADABLE_RESOURCES_MAP_ROW as si, isFinalSnapshotError as sn, carryLogOnlyValues as so, deleteIndeterminateGuards as sr, AssetPublisher as ss, awaitInFlightSibling as st, DeployEngine as t, refuseMalformedResourcePropertiesForOrphan as ta, resolveSkipPrefix as tc, parameterInputsFor as ti, ATOMIC_FINAL_SNAPSHOT_TYPES as tn, maskedLeafCoordinatesOf as to, getCurrentResourceSecrets as tr, importableOutputKeys as ts, journaledOrphanLines as tt, conditionFingerprint as u, repairMalformedResourcePropertiesForReadOnly as ua, MIGRATE_TMP_PREFIX as uc, displayLogicalId as ui, DeploymentEventsReader as un, literalSplitDelimitersOf as uo, isWaitAbandonedError as ur, WorkGraph as us, withStackRecords as ut, noEchoAttributeNamesOf as v, unwrittenCreateOnlyReplacement as va, derivePartitionAndUrlSuffix as vc, malformedExportSourceWarning as vi, secretSafeKeyDisplay as vn, maskSecretsInError as vo, DiffCalculator as vr, ensureAssetStorage as vs, compensateRemovedDeletionProtection as vt, getPriorAttempts as w, MULTI_REGION_RECREATE_BLOCKED_TYPES as wa, hasPlainPrototype$1 as wc, malformedOrphanRowsKeptWarning as wi, collectDeclaredOutputNames as wn, dynamicReferenceTokens as wo, applyRoleArnIfSet as wr, validateContainerRepoName as ws, deleteTableWithIndexBusyRetry as wt, withResourceDeadline as x, hasNoCloudControlHandlers as xa, processStackMessages as xc, malformedLocalResourcesWarning as xi, exportNameSecretExposure as xn, redactSecretsForState as xo, classifyReplaySecretRegion as xr, parseBootstrapMarker as xs, resolveDynamoDbDeleteBudgetMs as xt, noEchoComparisonForTemplate as y, withoutSilentDropProperties as ya, AssemblyReader as yc, malformedLocalOutputsWarning as yi, carriedExportAliasExposure as yn, maskSecretsInText as yo, INTRINSIC_KEYS as yr, getBootstrapMarkerKey as ys, deleteBudgetKey as yt, planOrphanAdoption as z, replayWarn as za, refuseMalformedOrphanRecordsForDestroy as zi, acquireIdempotencyToken as zn, STATE_SOURCED_CROSS_GENERATION_RULES as zo, s3BucketWebsiteUrl as zr, redactedDockerCause as zs, resolveReplacementOldType as zt };
39635
+ //# sourceMappingURL=deploy-engine-CjLZZzyn.js.map