@go-to-k/cdkd 0.308.1 → 0.309.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/{asg-provider-B7pAjRIc.js → asg-provider-DQoKGfKH.js} +2 -2
  2. package/dist/{asg-provider-B7pAjRIc.js.map → asg-provider-DQoKGfKH.js.map} +1 -1
  3. package/dist/cli.js +2 -2
  4. package/dist/{deploy-engine-CDjAtIrn.js → deploy-engine-tQ0aqZMo.js} +1235 -247
  5. package/dist/deploy-engine-tQ0aqZMo.js.map +1 -0
  6. package/dist/iam-policy-targets-D94wh05t.js.map +1 -1
  7. package/dist/{iam-role-provider-DbtvFel_.js → iam-role-provider-BI8Acvps.js} +2 -2
  8. package/dist/{iam-role-provider-DbtvFel_.js.map → iam-role-provider-BI8Acvps.js.map} +1 -1
  9. package/dist/index.d.ts +7 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +2 -2
  12. package/dist/{neptune-provider-Y3Ii8oYI.js → neptune-provider-DmVmx69p.js} +2 -2
  13. package/dist/{neptune-provider-Y3Ii8oYI.js.map → neptune-provider-DmVmx69p.js.map} +1 -1
  14. package/dist/{program-Ymf7svYk.js → program-Bnt3Yt0k.js} +100 -256
  15. package/dist/program-Bnt3Yt0k.js.map +1 -0
  16. package/dist/{provider-classes-BxfIHcea.js → provider-classes-DYke4HKr.js} +724 -133
  17. package/dist/provider-classes-DYke4HKr.js.map +1 -0
  18. package/dist/{rds-provider-CZhBLQgJ.js → rds-provider-Qpf09VQv.js} +27 -13
  19. package/dist/rds-provider-Qpf09VQv.js.map +1 -0
  20. package/dist/{version-BWqrjGBS.js → version-9LVuCtBU.js} +2 -2
  21. package/dist/{version-BWqrjGBS.js.map → version-9LVuCtBU.js.map} +1 -1
  22. package/package.json +2 -2
  23. package/dist/deploy-engine-CDjAtIrn.js.map +0 -1
  24. package/dist/program-Ymf7svYk.js.map +0 -1
  25. package/dist/provider-classes-BxfIHcea.js.map +0 -1
  26. package/dist/rds-provider-CZhBLQgJ.js.map +0 -1
@@ -2,7 +2,7 @@ import { c as __exportAll, r as getAwsClients } from "./aws-clients-Bu9EMILF.js"
2
2
  import { A as isNameGeneration, B as SECRET_REF_MAX_CODE_POINTS, D as getCurrentStackInstanceId, E as getCurrentSkipPrefix, F as withSkipPrefix, G as displayAwsMessage, H as UNRENDERABLE, I as withStackScope, J as displayStackName, K as displayIdent, L as withStackScopeBeforeStateRead, N as stackInstanceNameSuffix, O as getCurrentStackName, P as withNameGeneration, Q as safeMsg, R as withoutGeneratedFallbackName, S as fallbackNamePropertyFor, T as generatedNameFor, U as asIsMessage, V as STACK_REF_MAX_CODE_POINTS, Y as isPasteableIdent, Z as plainIdentOr, a as safeStringify$1, c as isStdoutReservedForPayload, et as terminalSafe, f as currentLogLineMasker, j as looksLikeCdkdGeneratedName, m as getLiveRenderer, n as describeAwsFailure, p as installLogLineMaskerSource, q as displaySafe, s as getLogger, t as VERBOSE_POINTER, tt as truncateCodePoints, v as applyDefaultNameForFallback, w as generateResourceNameWithFallback, x as explicitNamePropertyFor, y as currentNameGeneration, z as SAFE_MSG_ALTERED_CHAR } from "./aws-failure-text-NSBdKPYK.js";
3
3
  import { $n as isUpdateUnsupportedError, An as StateError, At as carryCreatedBeforeFailure, B as compensateProtectionFlip, Bn as UNSHOWABLE_VALUE, Bt as replayMadeAnotherResource, Cr as markNonRetryable, Ct as createMaskedLogSinks, D as markNotGone, Dn as ResourceUpdateNotSupportedError, Dt as maskerOrIdentity, E as isMarkedNotGone, En as ResourceTimeoutError, Et as maskDeep, F as refusalTypeShown, Fn as normalizeAwsError, Ft as isAuxiliaryFailure, Gn as physicalIdShownBesideCommand, Gt as formatLockExpiry, H as deleteWithProtectionCompensation, Ht as buildForceUnlockCommand, It as isAuxiliaryMarkOf, J as observeThenDisableProtection, Jn as shellBoundedDisplay, Jt as recoveryCommandFlags, K as isTerminalDeleteFailure, Kn as plainOrDescribed, Kt as formatLockOperation, L as resolveExplicitPhysicalId, Lt as markAuxiliaryFailure, M as isQuotableImportValue, Mt as createdBeforeFailure, N as normalizeAwsTagsToCfn, Nt as createdResourceIdentityBeforeFailure, O as assertRegionMatch, Ot as withDerivedNameMasks, P as quotedRemedyLogicalId, Pn as isSoftAbort, Pt as hasCreatedBeforeFailure, Qt as injectiveKey, Rn as SHELL_ACTIVE, Rt as markCreatedBeforeFailure, Sn as MalformedProducerRecordRefusalError, Sr as isThrottlingError, St as stateOrphanRecordRemedy, T as RESOURCE_NOT_FOUND, Tn as ProvisioningError, Tr as wrapMaskedAwsError, Tt as isSecretDerivedValue, Un as isInertUnquoted, Vn as commandHole, Vt as UNREPRODUCIBLE_LOCK_CLAUSE, Wn as pasteableCommand, Xn as withheldTargetClause, Xt as CUSTOM_RESOURCE_RESPONSE_PREFIX, Y as protectionFlipKey, Yn as shellQuote, Yt as sanitizeRecoveryValue, Z as runDeleteAttempt, Zt as DEFAULT_STATE_PREFIX, _n as IntrinsicResolutionRefusalError, _r as isRetryableTransientError, an as ambientCredentialConfig, at as protectedReplacementAdvice, bn as LockError, bt as resourceTypeShown, cn as AccountIdUnavailableError, cr as escapeRegExp$3, ct as monotonicNowMs, d as prepareRemovalForUpdate, er as hasReplayMayCollide, et as DELETION_PROTECTION_DOC_POINTER, f as removalWarning, fn as CrossAccountSecretRefusalError, fr as formatRetryClassificationSignals, ft as isInterruptedWaitError, gn as DynamicReferenceRegionAmbiguousError, gr as isIamPropagationError, gt as compositeIdSeparatorRefusal, hn as DeploymentNotApprovedError, i as holdsSecretDerivedEntry, in as ambientClientDefaults, ir as isReplayedNameCollisionFrom, it as pasteableAwsCommand, jn as SynthesisError, kt as RETRY_AUXILIARY_OWNER, l as withUnchangedSecretPrincipalLists, ln as AssetError, lr as stripControlChars, m as withoutInjectedRemovals, mr as isAmbiguousOutcomeError, mt as canonicalizeRoute53QueryName, nr as isNameCooldownError, on as clientDefaultsFor, or as markReplayMayCollide, pn as DependencyError, pr as isAmbiguousCcHandlerErrorCode, pt as startInterruptWatch, qn as quotedOrDescribed, qt as formatLockOwner, rn as withPasteableAwsProfile, rr as isRecreateRetryableError, sn as credentialFingerprint, sr as relayedNameCollision, st as ElapsedBudgetRegistry, tn as producerRecordKey, tr as isNameCollisionErrorFrom, un as CdkdError, vr as isTransientServerError, vt as logicalIdShown, w as withoutServerErrorRetries, wr as markRedactedCause, wt as createMaskedRetryLogger, xn as MacroExpansionError, xr as isMarkedNonRetryable, xt as segmentAfterAnchor, yr as retryClassificationText, z as ProtectionFlipRegistry, zn as SHELL_ACTIVE_WHY } from "./iam-policy-targets-D94wh05t.js";
4
4
  import { a as setAssumedRoleCredentials, c as ambientRegion, i as getPreAssumeEnvCredentials, n as awsClientDefaults, o as setPreAssumeEnvCredentials, r as getAssumedRoleCredentials, s as quietS3Logger, t as SECOND_ROLE_PUBLISH_REFUSAL } from "./aws-client-defaults-BX9Y_fKp.js";
5
- import { t as getCdkdVersion } from "./version-BWqrjGBS.js";
5
+ import { t as getCdkdVersion } from "./version-9LVuCtBU.js";
6
6
  import { createHash, randomUUID } from "node:crypto";
7
7
  import { AsyncLocalStorage } from "node:async_hooks";
8
8
  import { CreateBucketCommand, DeleteObjectCommand, DeleteObjectsCommand, GetBucketLifecycleConfigurationCommand, GetBucketLocationCommand, GetBucketReplicationCommand, GetObjectCommand, HeadBucketCommand, HeadObjectCommand, ListObjectVersionsCommand, ListObjectsV2Command, NoSuchKey, PutBucketEncryptionCommand, PutBucketLifecycleConfigurationCommand, PutBucketPolicyCommand, PutObjectCommand, PutPublicAccessBlockCommand, S3Client, S3ServiceException } from "@aws-sdk/client-s3";
@@ -4986,7 +4986,8 @@ const STATE_SCHEMA_VERSIONS_READABLE = [
4986
4986
  10,
4987
4987
  11,
4988
4988
  12,
4989
- 13
4989
+ 13,
4990
+ 14
4990
4991
  ];
4991
4992
  function hasUnverifiableParameterRefusal(record) {
4992
4993
  return record?.observedBaselineRefused === true && record.observedBaselineRefusalReason === "unverifiable-parameter";
@@ -6046,7 +6047,7 @@ var S3StateBackend = class S3StateBackend {
6046
6047
  const body = {
6047
6048
  ...state,
6048
6049
  ...stackInstanceIdCarriedFrom(state),
6049
- version: 13,
6050
+ version: 14,
6050
6051
  stackName,
6051
6052
  region
6052
6053
  };
@@ -7845,7 +7846,7 @@ const WHOLE_DYNAMIC_REFERENCE_PATTERN = new RegExp(`^\\{\\{resolve:${DYNAMIC_REF
7845
7846
  function isSingleDynamicReferenceToken(value) {
7846
7847
  return WHOLE_DYNAMIC_REFERENCE_PATTERN.test(value);
7847
7848
  }
7848
- function isPlainObject$9(value) {
7849
+ function isPlainObject$11(value) {
7849
7850
  return value !== null && typeof value === "object" && !Array.isArray(value);
7850
7851
  }
7851
7852
 
@@ -8101,7 +8102,7 @@ function crossStackSourceKey(source) {
8101
8102
  }
8102
8103
  if (key === "Fn::GetStackOutput") {
8103
8104
  const args = source[key];
8104
- if (!isPlainObject$9(args)) return void 0;
8105
+ if (!isPlainObject$11(args)) return void 0;
8105
8106
  const stackName = Object.hasOwn(args, "StackName") ? literalStringOrUndefined(args["StackName"]) : void 0;
8106
8107
  const outputName = Object.hasOwn(args, "OutputName") ? literalStringOrUndefined(args["OutputName"]) : void 0;
8107
8108
  if (stackName === void 0 || outputName === void 0) return void 0;
@@ -8147,7 +8148,7 @@ function crossStackSourceKey(source) {
8147
8148
  let template;
8148
8149
  let variables;
8149
8150
  if (typeof raw === "string") template = raw;
8150
- else if (Array.isArray(raw) && raw.length === 2 && isPlainObject$9(raw[1])) {
8151
+ else if (Array.isArray(raw) && raw.length === 2 && isPlainObject$11(raw[1])) {
8151
8152
  if (typeof raw[0] !== "string") return void 0;
8152
8153
  template = raw[0];
8153
8154
  variables = raw[1];
@@ -8441,12 +8442,12 @@ const UNFRAMED_SPELLING = Symbol("cdkd.nested-parameter.unframed-spelling");
8441
8442
  function recordNestedStackParameterExpressions(secrets, resourceType, resolvedProperties, sourceProperties, provenance = "template-derived") {
8442
8443
  if (resourceType !== NESTED_STACK_RESOURCE_TYPE$4) return;
8443
8444
  if (secrets.size === 0) return;
8444
- if (!isPlainObject$9(resolvedProperties) || !isPlainObject$9(sourceProperties)) return;
8445
+ if (!isPlainObject$11(resolvedProperties) || !isPlainObject$11(sourceProperties)) return;
8445
8446
  if (!Object.hasOwn(resolvedProperties, "Parameters")) return;
8446
8447
  if (!Object.hasOwn(sourceProperties, "Parameters")) return;
8447
8448
  const resolvedParameters = resolvedProperties["Parameters"];
8448
8449
  const sourceParameters = sourceProperties["Parameters"];
8449
- if (!isPlainObject$9(resolvedParameters) || !isPlainObject$9(sourceParameters)) return;
8450
+ if (!isPlainObject$11(resolvedParameters) || !isPlainObject$11(sourceParameters)) return;
8450
8451
  const positioned = redactAtProvenance({ ...resolvedParameters }, secrets, sourceParameters, provenance, true);
8451
8452
  let table = nestedStackParameterExpressions.get(secrets);
8452
8453
  for (const [name, resolvedValue] of Object.entries(resolvedParameters)) {
@@ -8495,7 +8496,7 @@ function recordNestedStackParameterExpressions(secrets, resourceType, resolvedPr
8495
8496
  if (typeof resolvedValue !== "string") return void 0;
8496
8497
  const sourceLeaf = sourceParameters[name];
8497
8498
  if (typeof sourceLeaf === "string") return sourceLeaf;
8498
- if (!isPlainObject$9(sourceLeaf)) return void 0;
8499
+ if (!isPlainObject$11(sourceLeaf)) return void 0;
8499
8500
  const written = positioned[name];
8500
8501
  if (typeof written !== "string") return void 0;
8501
8502
  const rendered = intrinsicSkeletonSegments(sourceLeaf)?.map((s) => s === UNKNOWN_PART ? "\0" : s).join("");
@@ -8832,7 +8833,7 @@ function evaluatePureRead(node, bind, pseudo, split, choose, depth = 0) {
8832
8833
  }
8833
8834
  return { value: out };
8834
8835
  }
8835
- if (!isPlainObject$9(node)) return void 0;
8836
+ if (!isPlainObject$11(node)) return void 0;
8836
8837
  const keys = Object.keys(node);
8837
8838
  if (keys.length !== 1) return void 0;
8838
8839
  const key = keys[0];
@@ -8873,7 +8874,7 @@ function evaluatePureRead(node, bind, pseudo, split, choose, depth = 0) {
8873
8874
  }
8874
8875
  function evaluatePureSub(args, bind, pseudo, evaluate) {
8875
8876
  const [text, variables] = typeof args === "string" ? [args, {}] : Array.isArray(args) && args.length === 2 ? [args[0], args[1]] : [void 0, void 0];
8876
- if (typeof text !== "string" || text.includes("{{resolve:") || !isPlainObject$9(variables)) return;
8877
+ if (typeof text !== "string" || text.includes("{{resolve:") || !isPlainObject$11(variables)) return;
8877
8878
  const bound = /* @__PURE__ */ new Map();
8878
8879
  for (const [name, variable] of Object.entries(variables)) {
8879
8880
  const evaluated = evaluate(variable);
@@ -8906,7 +8907,7 @@ function bindReadName(name, bind, pseudo) {
8906
8907
  function collectRereadConditions(node, names, depth = 0) {
8907
8908
  if (depth > MAX_REREAD_DEPTH) return false;
8908
8909
  if (Array.isArray(node)) return node.every((element) => collectRereadConditions(element, names, depth + 1));
8909
- if (!isPlainObject$9(node)) return true;
8910
+ if (!isPlainObject$11(node)) return true;
8910
8911
  if (Object.hasOwn(node, "Fn::If")) {
8911
8912
  const args = node["Fn::If"];
8912
8913
  if (!Array.isArray(args) || typeof args[0] !== "string") return false;
@@ -8917,7 +8918,7 @@ function collectRereadConditions(node, names, depth = 0) {
8917
8918
  function holdsRereadTrigger(node, depth = 0) {
8918
8919
  if (depth > MAX_REREAD_DEPTH) return false;
8919
8920
  if (Array.isArray(node)) return node.some((element) => holdsRereadTrigger(element, depth + 1));
8920
- if (!isPlainObject$9(node)) return false;
8921
+ if (!isPlainObject$11(node)) return false;
8921
8922
  return Object.entries(node).some(([key, child]) => REREAD_TRIGGERS.has(key) || holdsRereadTrigger(child, depth + 1));
8922
8923
  }
8923
8924
  function rendersReadTo(spelling, parentSecrets, value) {
@@ -8960,7 +8961,7 @@ function namesParameterOnBranches(node, choose, isParameter, depth = 0) {
8960
8961
  if (depth > MAX_REREAD_DEPTH) return true;
8961
8962
  if (typeof node === "string") return node.includes("{{resolve:");
8962
8963
  if (Array.isArray(node)) return node.some((element) => namesParameterOnBranches(element, choose, isParameter, depth + 1));
8963
- if (!isPlainObject$9(node)) return false;
8964
+ if (!isPlainObject$11(node)) return false;
8964
8965
  if (Object.hasOwn(node, "Fn::If")) {
8965
8966
  const args = node["Fn::If"];
8966
8967
  if (Object.keys(node).length !== 1) return true;
@@ -9073,7 +9074,7 @@ function appendValuePlaceholderParts(value, out, budget, depth) {
9073
9074
  if (budget.exhausted) return;
9074
9075
  const literal = joinPartLiteralText(value);
9075
9076
  if (literal !== void 0) return pushPlaceholderPart(out, literal, budget);
9076
- if (isPlainObject$9(value) && Object.keys(value).length === 1) {
9077
+ if (isPlainObject$11(value) && Object.keys(value).length === 1) {
9077
9078
  const ref = value["Ref"];
9078
9079
  if (typeof ref === "string" && ref !== "") return pushPlaceholderPart(out, keyedPart({ Ref: ref }), budget);
9079
9080
  if (depth >= MAX_PLACEHOLDER_DEPTH) {
@@ -9105,7 +9106,7 @@ function appendParameterPlaceholderParts(source, out, budget, depth) {
9105
9106
  let template;
9106
9107
  let variables = {};
9107
9108
  if (typeof args === "string") template = args;
9108
- else if (Array.isArray(args) && args.length === 2 && isPlainObject$9(args[1])) {
9109
+ else if (Array.isArray(args) && args.length === 2 && isPlainObject$11(args[1])) {
9109
9110
  template = args[0];
9110
9111
  variables = args[1];
9111
9112
  } else return false;
@@ -9268,7 +9269,7 @@ function isUniquelyKeyedBy(items, key) {
9268
9269
  if (items.length === 0) return false;
9269
9270
  const seen = /* @__PURE__ */ new Set();
9270
9271
  for (const item of items) {
9271
- if (!isPlainObject$9(item) || !Object.hasOwn(item, key)) return false;
9272
+ if (!isPlainObject$11(item) || !Object.hasOwn(item, key)) return false;
9272
9273
  const id = item[key];
9273
9274
  if (typeof id !== "string" || id === "") return false;
9274
9275
  if (seen.has(id)) return false;
@@ -9296,7 +9297,7 @@ const NEVER_DROPPING_INTRINSICS = /* @__PURE__ */ new Set([
9296
9297
  ]);
9297
9298
  function arrayElementDrop(element, depth = 0) {
9298
9299
  if (depth > 16) return "unknown";
9299
- if (!isPlainObject$9(element)) return "never";
9300
+ if (!isPlainObject$11(element)) return "never";
9300
9301
  if (Object.hasOwn(element, "Ref")) return element["Ref"] === "AWS::NoValue" ? "always" : "never";
9301
9302
  const keys = Object.keys(element);
9302
9303
  if (keys.filter((key) => key.startsWith("Fn::") || key === "Condition").length === 0) return "never";
@@ -9332,7 +9333,7 @@ function keptLiteralsCorroborate(kept, bag, secrets) {
9332
9333
  return kept.every((element, i) => keptElementCorroborates(element, bag[i], secrets));
9333
9334
  }
9334
9335
  function isIntrinsicNode(value) {
9335
- if (!isPlainObject$9(value)) return false;
9336
+ if (!isPlainObject$11(value)) return false;
9336
9337
  const keys = Object.keys(value);
9337
9338
  return keys.length === 1 && (keys[0] === "Ref" || keys[0].startsWith("Fn::"));
9338
9339
  }
@@ -9345,7 +9346,7 @@ function keptElementCorroborates(source, bag, secrets, depth = 0) {
9345
9346
  if (source === null || typeof source !== "object") return source === bag;
9346
9347
  if (isIntrinsicNode(source)) return true;
9347
9348
  if (Array.isArray(source)) return Array.isArray(bag) && bag.length === source.length && source.every((element, i) => keptElementCorroborates(element, bag[i], secrets, depth + 1));
9348
- if (!isPlainObject$9(source) || !isPlainObject$9(bag)) return false;
9349
+ if (!isPlainObject$11(source) || !isPlainObject$11(bag)) return false;
9349
9350
  if (Object.keys(bag).some((key) => !Object.hasOwn(source, key))) return false;
9350
9351
  return Object.entries(source).every(([key, value]) => Object.hasOwn(bag, key) ? keptElementCorroborates(value, bag[key], secrets, depth + 1) : arrayElementDrop(value) === "always" || arrayElementDrop(value) === "maybe");
9351
9352
  }
@@ -9355,12 +9356,12 @@ function corroboratesWhateverResolves(source, depth = 0) {
9355
9356
  if (source === null || typeof source !== "object") return true;
9356
9357
  if (isIntrinsicNode(source)) return true;
9357
9358
  if (Array.isArray(source)) return source.every((element) => arrayElementDrop(element) === "never" && corroboratesWhateverResolves(element, depth + 1));
9358
- if (!isPlainObject$9(source)) return false;
9359
+ if (!isPlainObject$11(source)) return false;
9359
9360
  if (Object.keys(source).some((key) => key === "Ref" || key.startsWith("Fn::"))) return false;
9360
9361
  return Object.values(source).every((value) => arrayElementDrop(value) !== "unknown" && corroboratesWhateverResolves(value, depth + 1));
9361
9362
  }
9362
9363
  function arrayPairsWhateverDrops(source) {
9363
- if (!source.some((element) => isPlainObject$9(element) && (Object.hasOwn(element, "Fn::If") || element["Ref"] === "AWS::NoValue" || Array.isArray(element["Fn::FindInMap"]) && element["Fn::FindInMap"].length > 3))) return true;
9364
+ if (!source.some((element) => isPlainObject$11(element) && (Object.hasOwn(element, "Fn::If") || element["Ref"] === "AWS::NoValue" || Array.isArray(element["Fn::FindInMap"]) && element["Fn::FindInMap"].length > 3))) return true;
9364
9365
  return source.every((element) => corroboratesWhateverResolves(element));
9365
9366
  }
9366
9367
  function redactByPath(bag, source, secrets, rules, secretExpressions, bagIsSameGeneration) {
@@ -9377,13 +9378,13 @@ function redactByPath(bag, source, secrets, rules, secretExpressions, bagIsSameG
9377
9378
  }
9378
9379
  return positionByEmbeddedSpan(bag, source, secrets, bagIsSameGeneration);
9379
9380
  }
9380
- if ((typeof bag === "string" || Array.isArray(bag)) && isPlainObject$9(source)) {
9381
+ if ((typeof bag === "string" || Array.isArray(bag)) && isPlainObject$11(source)) {
9381
9382
  const inherited = positionByInheritedParameter(bag, source, secrets);
9382
9383
  if (inherited !== void 0) return inherited;
9383
9384
  const reread = positionByParameterReread(bag, source, secrets);
9384
9385
  if (reread !== void 0) return reread;
9385
9386
  }
9386
- if (typeof bag === "string" && isPlainObject$9(source)) {
9387
+ if (typeof bag === "string" && isPlainObject$11(source)) {
9387
9388
  const certified = positionByCrossStackSource(bag, source, secrets);
9388
9389
  if (certified !== void 0) return certified;
9389
9390
  const placeheld = positionByParameterPlaceholders(bag, source, secrets);
@@ -9393,7 +9394,7 @@ function redactByPath(bag, source, secrets, rules, secretExpressions, bagIsSameG
9393
9394
  const framed = positionByIntrinsicFrame(bag, source, secrets, secretExpressions, bagIsSameGeneration);
9394
9395
  if (framed !== void 0) return framed;
9395
9396
  }
9396
- if (Array.isArray(bag) && isPlainObject$9(source)) {
9397
+ if (Array.isArray(bag) && isPlainObject$11(source)) {
9397
9398
  const positionedList = positionListByCrossStackSource(bag, source, secrets);
9398
9399
  if (positionedList !== void 0) return positionedList;
9399
9400
  }
@@ -9428,7 +9429,7 @@ function redactByPath(bag, source, secrets, rules, secretExpressions, bagIsSameG
9428
9429
  if (kept !== void 0 && keptLiteralsCorroborate(kept, bag, secrets)) return bag.map((item, i) => redactByPath(item, kept[i], secrets, rules, secretExpressions, bagIsSameGeneration));
9429
9430
  }
9430
9431
  }
9431
- if (isPlainObject$9(bag) && hasPlainPrototype(bag) && isPlainObject$9(source)) {
9432
+ if (isPlainObject$11(bag) && hasPlainPrototype(bag) && isPlainObject$11(source)) {
9432
9433
  const out = Object.create(null);
9433
9434
  for (const [k, v] of Object.entries(bag)) {
9434
9435
  out[k] = Object.hasOwn(source, k) ? redactByPath(v, source[k], secrets, rules, secretExpressions, bagIsSameGeneration) : redactForState(v, {
@@ -9450,7 +9451,7 @@ function isReadbackProjectedFromState(rules) {
9450
9451
  function subtreeHasDynamicReference(value) {
9451
9452
  if (isDynamicReferenceString(value)) return true;
9452
9453
  if (Array.isArray(value)) return value.some(subtreeHasDynamicReference);
9453
- if (isPlainObject$9(value)) return Object.values(value).some(subtreeHasDynamicReference);
9454
+ if (isPlainObject$11(value)) return Object.values(value).some(subtreeHasDynamicReference);
9454
9455
  return false;
9455
9456
  }
9456
9457
  function pathCrossesDottedKey(bag, path) {
@@ -9487,7 +9488,7 @@ function nameScalarSecrets(value, secrets) {
9487
9488
  return secrets.has(String(node)) || byValue.has(node) ? "***" : node;
9488
9489
  }
9489
9490
  if (Array.isArray(node)) return node.map(walk);
9490
- if (isPlainObject$9(node) && hasPlainPrototype(node)) {
9491
+ if (isPlainObject$11(node) && hasPlainPrototype(node)) {
9491
9492
  const out = Object.create(null);
9492
9493
  for (const [k, v] of Object.entries(node)) out[k] = walk(v);
9493
9494
  return out;
@@ -9504,13 +9505,13 @@ function substitutionIsSecret(value) {
9504
9505
  function sentinelDefinitionOf(source) {
9505
9506
  const subs = source["DefinitionSubstitutions"];
9506
9507
  const values = /* @__PURE__ */ new Map();
9507
- if (isPlainObject$9(subs)) {
9508
+ if (isPlainObject$11(subs)) {
9508
9509
  for (const [name, value] of Object.entries(subs)) if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") values.set(name, String(value));
9509
9510
  }
9510
9511
  for (const key of ["DefinitionString", "Definition"]) {
9511
9512
  if (!Object.hasOwn(source, key)) continue;
9512
9513
  const raw = source[key];
9513
- const body = typeof raw === "string" ? raw : isPlainObject$9(raw) ? JSON.stringify(raw) : void 0;
9514
+ const body = typeof raw === "string" ? raw : isPlainObject$11(raw) ? JSON.stringify(raw) : void 0;
9514
9515
  if (body === void 0) continue;
9515
9516
  if (body.includes(SENTINEL_IN_STRING) || body.includes(SENTINEL_OUT_OF_STRING) || /\\u[eE]00[01]/.test(body)) continue;
9516
9517
  const names = [];
@@ -9581,7 +9582,7 @@ function sentinelDefinitionOf(source) {
9581
9582
  node.forEach((item, i) => walk(item, [...path, i], [...shapes, node.length]));
9582
9583
  return;
9583
9584
  }
9584
- if (isPlainObject$9(node)) {
9585
+ if (isPlainObject$11(node)) {
9585
9586
  const own = new Set(Object.keys(node).map(written));
9586
9587
  for (const [k, v] of Object.entries(node)) {
9587
9588
  if (!marked(k)) keys.add(k);
@@ -9609,7 +9610,7 @@ function alignedSecretLeaf(root, leaf) {
9609
9610
  if (!Array.isArray(cursor) || cursor.length !== shape) return void 0;
9610
9611
  cursor = cursor[segment];
9611
9612
  } else {
9612
- if (!isPlainObject$9(cursor)) return void 0;
9613
+ if (!isPlainObject$11(cursor)) return void 0;
9613
9614
  const own = Object.keys(cursor);
9614
9615
  if (own.length !== shape.size || own.some((k) => !shape.has(k))) return void 0;
9615
9616
  if (!Object.hasOwn(cursor, segment)) return void 0;
@@ -9620,7 +9621,7 @@ function alignedSecretLeaf(root, leaf) {
9620
9621
  }
9621
9622
  function collectObjectKeys(value, into) {
9622
9623
  if (Array.isArray(value)) for (const item of value) collectObjectKeys(item, into);
9623
- else if (isPlainObject$9(value)) for (const [k, v] of Object.entries(value)) {
9624
+ else if (isPlainObject$11(value)) for (const [k, v] of Object.entries(value)) {
9624
9625
  into.add(k);
9625
9626
  collectObjectKeys(v, into);
9626
9627
  }
@@ -9633,7 +9634,7 @@ function spelledKeysOf(properties) {
9633
9634
  }
9634
9635
  function someKeyIsUnspelled(value, spelled) {
9635
9636
  if (Array.isArray(value)) return value.some((item) => someKeyIsUnspelled(item, spelled));
9636
- if (isPlainObject$9(value)) return Object.entries(value).some(([k, v]) => !spelled(k) || someKeyIsUnspelled(v, spelled));
9637
+ if (isPlainObject$11(value)) return Object.entries(value).some(([k, v]) => !spelled(k) || someKeyIsUnspelled(v, spelled));
9637
9638
  return false;
9638
9639
  }
9639
9640
  function nameDefinitionSecrets(value, source, secrets) {
@@ -9728,8 +9729,8 @@ function deepEqualJsonValue(a, b) {
9728
9729
  if (!Array.isArray(b) || a.length !== b.length) return false;
9729
9730
  return a.every((item, i) => deepEqualJsonValue(item, b[i]));
9730
9731
  }
9731
- if (isPlainObject$9(a)) {
9732
- if (!isPlainObject$9(b)) return false;
9732
+ if (isPlainObject$11(a)) {
9733
+ if (!isPlainObject$11(b)) return false;
9733
9734
  if (!hasPlainPrototype(a) || !hasPlainPrototype(b)) return false;
9734
9735
  const keys = Object.keys(a);
9735
9736
  if (keys.length !== Object.keys(b).length) return false;
@@ -9746,7 +9747,7 @@ function renderedDefinitionLiterals(source) {
9746
9747
  const keyKeep = /* @__PURE__ */ new Set();
9747
9748
  const subs = source["DefinitionSubstitutions"];
9748
9749
  const scalars = [];
9749
- if (isPlainObject$9(subs)) {
9750
+ if (isPlainObject$11(subs)) {
9750
9751
  for (const [name, value] of Object.entries(subs)) if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
9751
9752
  scalars.push([name, String(value)]);
9752
9753
  if (typeof value === "string") keep.add(value);
@@ -9758,7 +9759,7 @@ function renderedDefinitionLiterals(source) {
9758
9759
  if (!Object.hasOwn(source, key)) continue;
9759
9760
  const body = source[key];
9760
9761
  if (typeof body === "string") bodies.push(body);
9761
- else if (isPlainObject$9(body)) bodies.push(JSON.stringify(body));
9762
+ else if (isPlainObject$11(body)) bodies.push(JSON.stringify(body));
9762
9763
  }
9763
9764
  for (const body of bodies) {
9764
9765
  let rendered = body;
@@ -9809,7 +9810,7 @@ function collectScalarLeaves(value, into) {
9809
9810
  return;
9810
9811
  }
9811
9812
  if (Array.isArray(value)) for (const item of value) collectScalarLeaves(item, into);
9812
- else if (isPlainObject$9(value)) for (const item of Object.values(value)) collectScalarLeaves(item, into);
9813
+ else if (isPlainObject$11(value)) for (const item of Object.values(value)) collectScalarLeaves(item, into);
9813
9814
  }
9814
9815
  function refuseUncertifiedSubtree(value, sourceLiterals, mark, scalarLiterals, seen = /* @__PURE__ */ new Map()) {
9815
9816
  if (scalarLiterals !== void 0 && (typeof value === "number" || typeof value === "boolean") && !scalarLiterals.has(value)) return mark ? POSITION_UNCERTIFIED : "***";
@@ -9827,7 +9828,7 @@ function refuseUncertifiedSubtree(value, sourceLiterals, mark, scalarLiterals, s
9827
9828
  for (const item of value) out.push(refuseUncertifiedSubtree(item, sourceLiterals, mark, scalarLiterals, seen));
9828
9829
  return out;
9829
9830
  }
9830
- if (isPlainObject$9(value) && hasPlainPrototype(value)) {
9831
+ if (isPlainObject$11(value) && hasPlainPrototype(value)) {
9831
9832
  const out = Object.create(null);
9832
9833
  seen.set(value, out);
9833
9834
  for (const [k, v] of Object.entries(value)) out[k] = refuseUncertifiedSubtree(v, sourceLiterals, mark, scalarLiterals, seen);
@@ -9854,7 +9855,7 @@ function refuseUncertifiedReadbackPositions(bag, source, secrets, failClosed, le
9854
9855
  if (learn) learnMixedLeafNeedle(learn, bag, source);
9855
9856
  return mark ? POSITION_DECIDED : source;
9856
9857
  }
9857
- if (failClosed === true && isPlainObject$9(bag) && hasPlainPrototype(bag) && isPlainObject$9(source) && Object.keys(bag).some((k) => RENDERED_DEFINITION_KEYS.has(k)) && definitionSourceCarriesSecret(source)) {
9858
+ if (failClosed === true && isPlainObject$11(bag) && hasPlainPrototype(bag) && isPlainObject$11(source) && Object.keys(bag).some((k) => RENDERED_DEFINITION_KEYS.has(k)) && definitionSourceCarriesSecret(source)) {
9858
9859
  const keep = renderedDefinitionLiterals(source);
9859
9860
  const out = Object.create(null);
9860
9861
  const rest = Object.create(null);
@@ -9888,7 +9889,7 @@ function refuseUncertifiedReadbackPositions(bag, source, secrets, failClosed, le
9888
9889
  return out;
9889
9890
  }
9890
9891
  if (!subtreeHasDynamicReference(source)) return bag;
9891
- if (isPlainObject$9(bag) && hasPlainPrototype(bag) && isPlainObject$9(source)) {
9892
+ if (isPlainObject$11(bag) && hasPlainPrototype(bag) && isPlainObject$11(source)) {
9892
9893
  const out = Object.create(null);
9893
9894
  for (const [k, v] of Object.entries(bag)) out[k] = Object.hasOwn(source, k) ? refuseUncertifiedReadbackPositions(v, source[k], secrets, failClosed, learn, mark) : v;
9894
9895
  return out;
@@ -9915,14 +9916,14 @@ function refuseUncertifiedReadbackPositions(bag, source, secrets, failClosed, le
9915
9916
  function isDistinguishingAnchor(value) {
9916
9917
  if (typeof value === "string") return value !== "";
9917
9918
  if (Array.isArray(value)) return value.some(isDistinguishingAnchor);
9918
- if (isPlainObject$9(value)) return Object.values(value).some(isDistinguishingAnchor);
9919
+ if (isPlainObject$11(value)) return Object.values(value).some(isDistinguishingAnchor);
9919
9920
  return false;
9920
9921
  }
9921
9922
  const ANCHOR_REFERENCE_MASK = "<ref>";
9922
9923
  function anchorSignature(source) {
9923
9924
  if (isDynamicReferenceString(source)) return ANCHOR_REFERENCE_MASK;
9924
9925
  if (Array.isArray(source)) return `[${source.map(anchorSignature).sort().join(",")}]`;
9925
- if (isPlainObject$9(source)) return `{${Object.keys(source).sort().map((k) => `${JSON.stringify(k)}:${anchorSignature(source[k])}`).join(",")}}`;
9926
+ if (isPlainObject$11(source)) return `{${Object.keys(source).sort().map((k) => `${JSON.stringify(k)}:${anchorSignature(source[k])}`).join(",")}}`;
9926
9927
  return JSON.stringify(source) ?? "undefined";
9927
9928
  }
9928
9929
  function anchorsCorroboratePairing(bag, source, anchors) {
@@ -9932,8 +9933,8 @@ function anchorsCorroboratePairing(bag, source, anchors) {
9932
9933
  return true;
9933
9934
  }
9934
9935
  if (isDynamicReferenceString(source)) return typeof bag === "string";
9935
- if (isPlainObject$9(source)) {
9936
- if (!isPlainObject$9(bag)) return false;
9936
+ if (isPlainObject$11(source)) {
9937
+ if (!isPlainObject$11(bag)) return false;
9937
9938
  return Object.keys(source).every((k) => Object.hasOwn(bag, k) && anchorsCorroboratePairing(bag[k], source[k], anchors));
9938
9939
  }
9939
9940
  if (Array.isArray(source)) {
@@ -10024,13 +10025,13 @@ function learnMixedLeafNeedle(collector, bag, source) {
10024
10025
  learnNeedle(collector, plaintext, token);
10025
10026
  }
10026
10027
  function asChild(marks, key) {
10027
- return isPlainObject$9(marks) && hasPlainPrototype(marks) ? marks[key] : void 0;
10028
+ return isPlainObject$11(marks) && hasPlainPrototype(marks) ? marks[key] : void 0;
10028
10029
  }
10029
10030
  function asIndex(marks, index) {
10030
10031
  return Array.isArray(marks) ? marks[index] : void 0;
10031
10032
  }
10032
10033
  function preferPositionDecisions(scanned, refused, bag, marks, inferred) {
10033
- if (isPlainObject$9(bag) && hasPlainPrototype(bag) && isPlainObject$9(refused) && isPlainObject$9(scanned)) {
10034
+ if (isPlainObject$11(bag) && hasPlainPrototype(bag) && isPlainObject$11(refused) && isPlainObject$11(scanned)) {
10034
10035
  const out = Object.create(null);
10035
10036
  for (const [k, v] of Object.entries(refused)) out[k] = preferPositionDecisions(scanned[k], v, bag[k], asChild(marks, k), inferred);
10036
10037
  return out;
@@ -11520,7 +11521,7 @@ function readsNoEchoSource(node, sources) {
11520
11521
  if (typeof argument === "string") return subStringReadsNoEcho(argument, void 0, sources);
11521
11522
  if (Array.isArray(argument)) {
11522
11523
  const [text, variables] = argument;
11523
- const vars = isPlainObject$9(variables) ? variables : void 0;
11524
+ const vars = isPlainObject$11(variables) ? variables : void 0;
11524
11525
  if (typeof text === "string" && subStringReadsNoEcho(text, vars, sources)) return true;
11525
11526
  return vars !== void 0 && Object.values(vars).some(walk);
11526
11527
  }
@@ -11554,7 +11555,7 @@ function noEchoCoordinatesOf(template, resolved, sources, onCoordinate) {
11554
11555
  parameters: sources.parameters,
11555
11556
  ...sources.conditions !== void 0 && { conditions: sources.conditions }
11556
11557
  };
11557
- const isBareDeclaredGetAtt = (node) => isPlainObject$9(node) && intrinsicKeyOf(node) === "Fn::GetAtt" && getAttReadsNoEcho(node["Fn::GetAtt"], sources);
11558
+ const isBareDeclaredGetAtt = (node) => isPlainObject$11(node) && intrinsicKeyOf(node) === "Fn::GetAtt" && getAttReadsNoEcho(node["Fn::GetAtt"], sources);
11558
11559
  const walk = (source, value, path) => {
11559
11560
  if (value === void 0) return;
11560
11561
  if (source === null || typeof source !== "object") return;
@@ -11570,7 +11571,7 @@ function noEchoCoordinatesOf(template, resolved, sources, onCoordinate) {
11570
11571
  const record = source;
11571
11572
  const intrinsic = intrinsicKeyOf(record);
11572
11573
  if (intrinsic === void 0) {
11573
- if (!isPlainObject$9(value)) {
11574
+ if (!isPlainObject$11(value)) {
11574
11575
  if (readsNoEchoSource(record, parametersOnly)) push(path, source);
11575
11576
  return;
11576
11577
  }
@@ -11619,7 +11620,7 @@ function noEchoParameterNodesAt(templateProperties, shape, noEchoParameters, con
11619
11620
  noEchoCoordinatesOf(templateProperties ?? {}, shape, {
11620
11621
  parameters: noEchoParameters,
11621
11622
  ...conditions !== void 0 && { conditions }
11622
- }, (coordinate, node) => nodes.set(canonicalJson$4(coordinate), {
11623
+ }, (coordinate, node) => nodes.set(canonicalJson$5(coordinate), {
11623
11624
  coordinate,
11624
11625
  node
11625
11626
  }));
@@ -11631,7 +11632,7 @@ function recordedNoEchoValuesOf(templateProperties, record, noEchoParameterNames
11631
11632
  if (properties === null || typeof properties !== "object") return bag;
11632
11633
  const coordinates = /* @__PURE__ */ new Map();
11633
11634
  if (noEchoParameterNames.size > 0 && templateProperties !== void 0) for (const [key, { coordinate }] of noEchoParameterNodesAt(templateProperties, properties, noEchoParameterNames, conditions)) coordinates.set(key, coordinate);
11634
- for (const coordinate of noEchoLeavesOf(record ?? {}) ?? []) coordinates.set(canonicalJson$4(coordinate), coordinate);
11635
+ for (const coordinate of noEchoLeavesOf(record ?? {}) ?? []) coordinates.set(canonicalJson$5(coordinate), coordinate);
11635
11636
  const recordLeaf = (leaf) => {
11636
11637
  if (typeof leaf === "string") {
11637
11638
  if (leaf === "***" || leaf.includes("{{resolve:")) return;
@@ -11655,7 +11656,7 @@ function maskWholeValue(value) {
11655
11656
  if (value === null || value === void 0) return value;
11656
11657
  if (typeof value === "string" && isSingleDynamicReferenceToken(value)) return value;
11657
11658
  if (Array.isArray(value)) return value.map(maskWholeValue);
11658
- if (isPlainObject$9(value)) {
11659
+ if (isPlainObject$11(value)) {
11659
11660
  const out = {};
11660
11661
  for (const [key, child] of Object.entries(value)) Object.defineProperty(out, key, {
11661
11662
  value: maskWholeValue(child),
@@ -11678,7 +11679,7 @@ function readAt(bag, coordinate) {
11678
11679
  node = node[segment];
11679
11680
  continue;
11680
11681
  }
11681
- if (!isPlainObject$9(node) || !Object.hasOwn(node, segment)) return {
11682
+ if (!isPlainObject$11(node) || !Object.hasOwn(node, segment)) return {
11682
11683
  found: false,
11683
11684
  value: void 0
11684
11685
  };
@@ -11694,7 +11695,7 @@ function valueAtCoordinate(bag, coordinate) {
11694
11695
  }
11695
11696
  function cloneContainer(node) {
11696
11697
  if (Array.isArray(node)) return [...node];
11697
- if (isPlainObject$9(node)) return { ...node };
11698
+ if (isPlainObject$11(node)) return { ...node };
11698
11699
  return node;
11699
11700
  }
11700
11701
  function maskAtCoordinates(bag, coordinates) {
@@ -11761,20 +11762,20 @@ function readbackPathFor(readback, properties, coordinate) {
11761
11762
  if (!Array.isArray(live)) return path.length === 0 ? void 0 : path;
11762
11763
  const key = Array.isArray(desired) ? identityKeyFor(live, desired) : void 0;
11763
11764
  const element = Array.isArray(desired) ? desired[segment] : void 0;
11764
- if (key === void 0 || !isPlainObject$9(element)) return path;
11765
+ if (key === void 0 || !isPlainObject$11(element)) return path;
11765
11766
  const identity = element[key];
11766
- const index = live.findIndex((item) => isPlainObject$9(item) && item[key] === identity);
11767
+ const index = live.findIndex((item) => isPlainObject$11(item) && item[key] === identity);
11767
11768
  if (index < 0) return path;
11768
11769
  path.push(index);
11769
11770
  live = live[index];
11770
11771
  desired = element;
11771
11772
  continue;
11772
11773
  }
11773
- if (!isPlainObject$9(live)) return path.length === 0 ? void 0 : path;
11774
+ if (!isPlainObject$11(live)) return path.length === 0 ? void 0 : path;
11774
11775
  if (!Object.hasOwn(live, segment)) return void 0;
11775
11776
  path.push(segment);
11776
11777
  live = live[segment];
11777
- desired = isPlainObject$9(desired) ? desired[segment] : void 0;
11778
+ desired = isPlainObject$11(desired) ? desired[segment] : void 0;
11778
11779
  }
11779
11780
  return path;
11780
11781
  }
@@ -11803,7 +11804,7 @@ function witnessNormalize(stored, today, v11) {
11803
11804
  const confirmed = [];
11804
11805
  const differing = [];
11805
11806
  const walk = (s, t, v, path) => {
11806
- if (v !== "***" && containsMask(v) && (Array.isArray(v) ? !Array.isArray(s) || s.length !== v.length : isPlainObject$9(v) ? !isPlainObject$9(s) : false)) {
11807
+ if (v !== "***" && containsMask(v) && (Array.isArray(v) ? !Array.isArray(s) || s.length !== v.length : isPlainObject$11(v) ? !isPlainObject$11(s) : false)) {
11807
11808
  if (s === void 0 || containsMask(s)) return s;
11808
11809
  if (jsonEqual(s, t)) {
11809
11810
  confirmed.push(path);
@@ -11832,8 +11833,8 @@ function witnessNormalize(stored, today, v11) {
11832
11833
  });
11833
11834
  return changed ? out : s;
11834
11835
  }
11835
- if (isPlainObject$9(v) && isPlainObject$9(s)) {
11836
- const tt = isPlainObject$9(t) ? t : {};
11836
+ if (isPlainObject$11(v) && isPlainObject$11(s)) {
11837
+ const tt = isPlainObject$11(t) ? t : {};
11837
11838
  let out;
11838
11839
  for (const key of Object.keys(v)) {
11839
11840
  if (!Object.hasOwn(s, key)) continue;
@@ -11856,13 +11857,13 @@ function witnessNormalize(stored, today, v11) {
11856
11857
  function containsMask(value) {
11857
11858
  if (value === "***") return true;
11858
11859
  if (Array.isArray(value)) return value.some(containsMask);
11859
- if (isPlainObject$9(value)) return Object.values(value).some(containsMask);
11860
+ if (isPlainObject$11(value)) return Object.values(value).some(containsMask);
11860
11861
  return false;
11861
11862
  }
11862
11863
  function jsonEqual(a, b) {
11863
- return canonicalJson$4(a) === canonicalJson$4(b);
11864
+ return canonicalJson$5(a) === canonicalJson$5(b);
11864
11865
  }
11865
- function canonicalJson$4(value) {
11866
+ function canonicalJson$5(value) {
11866
11867
  return JSON.stringify(value, (_key, node) => {
11867
11868
  if (node === null || typeof node !== "object" || Array.isArray(node)) return node;
11868
11869
  const sorted = Object.create(null);
@@ -11900,7 +11901,7 @@ function noEchoComparison(options) {
11900
11901
  const out = node.map(walk);
11901
11902
  return out.some((item, i) => item !== node[i]) ? out : node;
11902
11903
  }
11903
- if (isPlainObject$9(node)) {
11904
+ if (isPlainObject$11(node)) {
11904
11905
  let out;
11905
11906
  for (const [key, child] of Object.entries(node)) {
11906
11907
  const next = walk(child);
@@ -11943,8 +11944,8 @@ function noEchoOutputsComparison(templateValues, sources) {
11943
11944
  return (current, desired) => {
11944
11945
  const coordinates = noEchoCoordinatesOf(templateValues, desired, sources);
11945
11946
  const maskedKeys = new Set(coordinates.map((coordinate) => coordinate[0]).filter((key) => typeof key === "string"));
11946
- const maskedValues = new Set([...maskedKeys].map((key) => canonicalJson$4(desired[key])));
11947
- for (const key of Object.keys(desired)) if (!Object.hasOwn(templateValues, key) && maskedValues.has(canonicalJson$4(desired[key]))) maskedKeys.add(key);
11947
+ const maskedValues = new Set([...maskedKeys].map((key) => canonicalJson$5(desired[key])));
11948
+ for (const key of Object.keys(desired)) if (!Object.hasOwn(templateValues, key) && maskedValues.has(canonicalJson$5(desired[key]))) maskedKeys.add(key);
11948
11949
  if (maskedKeys.size === 0) return {
11949
11950
  current,
11950
11951
  desired,
@@ -11958,7 +11959,7 @@ function noEchoOutputsComparison(templateValues, sources) {
11958
11959
  const stored = current[key];
11959
11960
  if (containsMask(stored)) continue;
11960
11961
  normalized = { ...normalized ?? {} };
11961
- normalized[key] = canonicalJson$4(stored) === canonicalJson$4(desired[key]) ? maskedDesired[key] : PREVIOUS_NOECHO_VALUE;
11962
+ normalized[key] = canonicalJson$5(stored) === canonicalJson$5(desired[key]) ? maskedDesired[key] : PREVIOUS_NOECHO_VALUE;
11962
11963
  }
11963
11964
  return {
11964
11965
  current: normalized,
@@ -12622,6 +12623,10 @@ function attributeTypeChangedForSharedAttribute(oldValue, newValue) {
12622
12623
  }
12623
12624
  return false;
12624
12625
  }
12626
+ function globalTableLocalSecondaryIndexesRemoved(oldValue, newValue) {
12627
+ const declares = (value) => Array.isArray(value) && value.length > 0;
12628
+ return declares(oldValue) && (newValue === void 0 || newValue === null || Array.isArray(newValue) && newValue.length === 0);
12629
+ }
12625
12630
  function budgetNameChanged(oldValue, newValue) {
12626
12631
  const nameOf = (value) => {
12627
12632
  if (value === null || typeof value !== "object") return void 0;
@@ -12680,10 +12685,43 @@ function emrInstancesReplacingPart(value) {
12680
12685
  strip("TaskInstanceFleets", EMR_FLEET_IN_PLACE_MEMBERS);
12681
12686
  return instances;
12682
12687
  }
12688
+ function elastiCachePreferredAvailabilityZonesMovedToDisjoint(oldValue, newValue) {
12689
+ if (!Array.isArray(oldValue) || !Array.isArray(newValue)) return false;
12690
+ if (oldValue.length === 0 || newValue.length === 0) return false;
12691
+ if (![...oldValue, ...newValue].every((z) => typeof z === "string")) return false;
12692
+ return !newValue.some((z) => oldValue.includes(z));
12693
+ }
12683
12694
  function emrClusterInstancesReplaced(oldValue, newValue) {
12684
12695
  if (oldValue === void 0 && newValue === void 0) return true;
12685
12696
  return !isDeepStrictEqual(emrInstancesReplacingPart(oldValue), emrInstancesReplacingPart(newValue));
12686
12697
  }
12698
+ const AURORA = "aurora";
12699
+ const AURORA_MYSQL = "aurora-mysql";
12700
+ const DEPRECATED_ORACLE_SE_ENGINES = /* @__PURE__ */ new Set(["oracle-se", "oracle-se1"]);
12701
+ const ORACLE_SE2 = "oracle-se2";
12702
+ const ORACLE_CDB_CONVERSIONS = /* @__PURE__ */ new Map([["oracle-ee", "oracle-ee-cdb"], ["oracle-se2", "oracle-se2-cdb"]]);
12703
+ const ORACLE_CDB_ENGINES = new Set(ORACLE_CDB_CONVERSIONS.values());
12704
+ function enginePair(oldValue, newValue) {
12705
+ return typeof oldValue === "string" && typeof newValue === "string" ? [oldValue, newValue] : void 0;
12706
+ }
12707
+ function dbClusterEngineChangeReplaces(oldValue, newValue) {
12708
+ const pair = enginePair(oldValue, newValue);
12709
+ if (pair === void 0) return false;
12710
+ const [before, after] = pair;
12711
+ return !(before === after || before === AURORA && after === AURORA_MYSQL);
12712
+ }
12713
+ function dbInstanceEngineChangeIsInPlace(oldValue, newValue) {
12714
+ const pair = enginePair(oldValue, newValue);
12715
+ if (pair === void 0) return false;
12716
+ const [before, after] = pair;
12717
+ const from = before.toLowerCase();
12718
+ const to = after.toLowerCase();
12719
+ return before === after || before === AURORA && after === AURORA_MYSQL || DEPRECATED_ORACLE_SE_ENGINES.has(from) && to === ORACLE_SE2 || ORACLE_CDB_CONVERSIONS.get(from) === to || from === to && ORACLE_CDB_ENGINES.has(to);
12720
+ }
12721
+ function dbInstanceEngineChangeReplaces(oldValue, newValue) {
12722
+ if (enginePair(oldValue, newValue) === void 0) return false;
12723
+ return !dbInstanceEngineChangeIsInPlace(oldValue, newValue);
12724
+ }
12687
12725
  var ReplacementRulesRegistry = class {
12688
12726
  logger = getLogger().child("ReplacementRulesRegistry");
12689
12727
  rules = /* @__PURE__ */ new Map();
@@ -12782,6 +12820,10 @@ var ReplacementRulesRegistry = class {
12782
12820
  "DestinationConfig"
12783
12821
  ])
12784
12822
  });
12823
+ this.rules.set("AWS::DynamoDB::GlobalTable", {
12824
+ replacementProperties: /* @__PURE__ */ new Set(),
12825
+ conditionalReplacements: /* @__PURE__ */ new Map([["LocalSecondaryIndexes", globalTableLocalSecondaryIndexesRemoved]])
12826
+ });
12785
12827
  this.rules.set("AWS::DynamoDB::Table", {
12786
12828
  replacementProperties: /* @__PURE__ */ new Set(["TableName", "KeySchema"]),
12787
12829
  updateableProperties: /* @__PURE__ */ new Set([
@@ -13001,6 +13043,14 @@ var ReplacementRulesRegistry = class {
13001
13043
  ]),
13002
13044
  conditionalReplacements: /* @__PURE__ */ new Map([["InstanceTenancy", vpcInstanceTenancyChangeReplaces]])
13003
13045
  });
13046
+ this.rules.set("AWS::RDS::DBCluster", {
13047
+ replacementProperties: /* @__PURE__ */ new Set(),
13048
+ conditionalReplacements: /* @__PURE__ */ new Map([["Engine", dbClusterEngineChangeReplaces]])
13049
+ });
13050
+ this.rules.set("AWS::RDS::DBInstance", {
13051
+ replacementProperties: /* @__PURE__ */ new Set(),
13052
+ conditionalReplacements: /* @__PURE__ */ new Map([["Engine", dbInstanceEngineChangeReplaces]])
13053
+ });
13004
13054
  this.rules.set("AWS::EC2::Subnet", {
13005
13055
  replacementProperties: /* @__PURE__ */ new Set([
13006
13056
  "VpcId",
@@ -13057,6 +13107,10 @@ var ReplacementRulesRegistry = class {
13057
13107
  replacementProperties: /* @__PURE__ */ new Set(),
13058
13108
  conditionalReplacements: /* @__PURE__ */ new Map([["LaunchType", ecsServiceLaunchTypeSetOrChanged]])
13059
13109
  });
13110
+ this.rules.set("AWS::ElastiCache::CacheCluster", {
13111
+ replacementProperties: /* @__PURE__ */ new Set(),
13112
+ conditionalReplacements: /* @__PURE__ */ new Map([["PreferredAvailabilityZones", elastiCachePreferredAvailabilityZonesMovedToDisjoint]])
13113
+ });
13060
13114
  this.rules.set("AWS::EMR::Cluster", {
13061
13115
  replacementProperties: /* @__PURE__ */ new Set(),
13062
13116
  conditionalReplacements: /* @__PURE__ */ new Map([["Instances", emrClusterInstancesReplaced]])
@@ -14940,7 +14994,7 @@ function probeFoundSameId(resourceType, a, b) {
14940
14994
  //#region src/provisioning/config-shape.ts
14941
14995
  function readConfigString(container, key, fallback, containerPath, options) {
14942
14996
  if (container === void 0 || container === null) return fallback;
14943
- if (!isPlainObject$8(container) || isUnresolvedIntrinsicContainer(container)) {
14997
+ if (!isPlainObject$10(container) || isUnresolvedIntrinsicContainer(container)) {
14944
14998
  const detail = malformedShapeDetail(container);
14945
14999
  if (options?.onUnusable) {
14946
15000
  const named = fallback === "" ? "" : ` (${fallback})`;
@@ -14980,7 +15034,7 @@ function requireConfigArray(value, path, options) {
14980
15034
  return value;
14981
15035
  }
14982
15036
  function requireConfigObject(value, path, options) {
14983
- if (!isPlainObject$8(value) || isUnresolvedIntrinsicContainer(value)) {
15037
+ if (!isPlainObject$10(value) || isUnresolvedIntrinsicContainer(value)) {
14984
15038
  const detail = malformedShapeDetail(value);
14985
15039
  if (options?.onUnusable) {
14986
15040
  options.onUnusable(`${path} must be an object ${detail}. Leaving this configuration unapplied here; the same value is REFUSED on a template-path create.`);
@@ -14992,7 +15046,7 @@ function requireConfigObject(value, path, options) {
14992
15046
  }
14993
15047
  function configStringRefusal(container, key, fallback, containerPath, options) {
14994
15048
  if (container === void 0 || container === null) return void 0;
14995
- if (!isPlainObject$8(container) || isUnresolvedIntrinsicContainer(container)) return `${containerPath} must be an object ${malformedShapeDetail(container)}`;
15049
+ if (!isPlainObject$10(container) || isUnresolvedIntrinsicContainer(container)) return `${containerPath} must be an object ${malformedShapeDetail(container)}`;
14996
15050
  return configValueRefusal(container[key], fallback, `${containerPath}.${key}`, options);
14997
15051
  }
14998
15052
  function coerceCfnBoolean(value) {
@@ -15005,7 +15059,7 @@ function coerceCfnBoolean(value) {
15005
15059
  }
15006
15060
  function configBooleanRefusal(container, key, containerPath) {
15007
15061
  if (container === void 0 || container === null) return void 0;
15008
- if (!isPlainObject$8(container) || isUnresolvedIntrinsicContainer(container)) return `${containerPath} must be an object ${malformedShapeDetail(container)}`;
15062
+ if (!isPlainObject$10(container) || isUnresolvedIntrinsicContainer(container)) return `${containerPath} must be an object ${malformedShapeDetail(container)}`;
15009
15063
  const value = container[key];
15010
15064
  if (value === void 0) return void 0;
15011
15065
  if (coerceCfnBoolean(value) !== void 0) return void 0;
@@ -15019,7 +15073,7 @@ function coerceCfnInteger(value) {
15019
15073
  }
15020
15074
  function configIntegerRefusal(container, key, containerPath, min, max) {
15021
15075
  if (container === void 0 || container === null) return void 0;
15022
- if (!isPlainObject$8(container) || isUnresolvedIntrinsicContainer(container)) return `${containerPath} must be an object ${malformedShapeDetail(container)}`;
15076
+ if (!isPlainObject$10(container) || isUnresolvedIntrinsicContainer(container)) return `${containerPath} must be an object ${malformedShapeDetail(container)}`;
15023
15077
  const value = container[key];
15024
15078
  if (value === void 0) return void 0;
15025
15079
  const n = coerceCfnInteger(value);
@@ -15033,10 +15087,10 @@ function configValueRefusal(value, fallback, path, options) {
15033
15087
  if (typeof value !== "string" || value.trim() === "") return `${path} must be a non-empty string ${malformedShapeDetail(value)}`;
15034
15088
  }
15035
15089
  function malformedShapeDetail(value) {
15036
- if (isPlainObject$8(value) && isUnresolvedIntrinsicContainer(value)) return `(got ${describe(value)} — nothing substituted it before this call)`;
15090
+ if (isPlainObject$10(value) && isUnresolvedIntrinsicContainer(value)) return `(got ${describe(value)} — nothing substituted it before this call)`;
15037
15091
  return `(got ${describe(value)}) — check for an unresolved intrinsic or a mis-nested template value`;
15038
15092
  }
15039
- function isPlainObject$8(value) {
15093
+ function isPlainObject$10(value) {
15040
15094
  return typeof value === "object" && value !== null && !Array.isArray(value);
15041
15095
  }
15042
15096
  const NAMEABLE_INTRINSIC_KEYS = /* @__PURE__ */ new Set([
@@ -15063,7 +15117,7 @@ function describe(value) {
15063
15117
  if (value === null) return "null";
15064
15118
  if (Array.isArray(value)) return "an array";
15065
15119
  if (typeof value === "string") return value.trim() === "" ? "a blank string" : "a string";
15066
- if (isPlainObject$8(value) && isUnresolvedIntrinsicContainer(value)) {
15120
+ if (isPlainObject$10(value) && isUnresolvedIntrinsicContainer(value)) {
15067
15121
  const key = Object.keys(value)[0];
15068
15122
  return NAMEABLE_INTRINSIC_KEYS.has(key) ? `an unresolved ${key} intrinsic` : "an unresolved intrinsic";
15069
15123
  }
@@ -20069,12 +20123,12 @@ function declaresNoEcho(definition) {
20069
20123
  //#region src/deployment/masked-property-fingerprints.ts
20070
20124
  const FINGERPRINT_LAYOUT$1 = 1;
20071
20125
  const INPUT_FINGERPRINT_LAYOUT = 2;
20072
- function canonicalJson$3(value) {
20126
+ function canonicalJson$4(value) {
20073
20127
  if (value === void 0) return "null";
20074
- if (Array.isArray(value)) return `[${value.map(canonicalJson$3).join(",")}]`;
20128
+ if (Array.isArray(value)) return `[${value.map(canonicalJson$4).join(",")}]`;
20075
20129
  if (value !== null && typeof value === "object") {
20076
20130
  const record = value;
20077
- return `{${Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson$3(record[key])}`).join(",")}}`;
20131
+ return `{${Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson$4(record[key])}`).join(",")}}`;
20078
20132
  }
20079
20133
  return JSON.stringify(value) ?? "null";
20080
20134
  }
@@ -20095,7 +20149,7 @@ function splitInputFingerprint(entry) {
20095
20149
  };
20096
20150
  }
20097
20151
  function templateCarriesNeedle(templateValue, secrets) {
20098
- const text = canonicalJson$3(templateValue);
20152
+ const text = canonicalJson$4(templateValue);
20099
20153
  for (const needle of printingCorpusOf(secrets).keys()) {
20100
20154
  if (needle.length < 4) continue;
20101
20155
  if (text.includes(needle) || text.includes(JSON.stringify(needle).slice(1, -1))) return true;
@@ -20103,14 +20157,14 @@ function templateCarriesNeedle(templateValue, secrets) {
20103
20157
  return false;
20104
20158
  }
20105
20159
  function maskedPropertyFingerprint(templateValue) {
20106
- const digest = createHash("sha256").update(canonicalJson$3({
20160
+ const digest = createHash("sha256").update(canonicalJson$4({
20107
20161
  layout: FINGERPRINT_LAYOUT$1,
20108
20162
  value: templateValue
20109
20163
  })).digest("hex");
20110
20164
  return `${FINGERPRINT_PREFIX}${digest}`;
20111
20165
  }
20112
20166
  var UnknownInput = class extends Error {};
20113
- function isPlainObject$7(value) {
20167
+ function isPlainObject$9(value) {
20114
20168
  return value !== null && typeof value === "object" && !Array.isArray(value);
20115
20169
  }
20116
20170
  const DYNAMIC_REFERENCE_OPEN = "{{resolve:";
@@ -20118,7 +20172,7 @@ const NESTED_STACK_TYPE$4 = "AWS::CloudFormation::Stack";
20118
20172
  const NESTED_OUTPUT_PREFIX = "Outputs.";
20119
20173
  function carriesSecretValue(value, corpora) {
20120
20174
  if (carriesSecretMask(value)) return true;
20121
- const text = canonicalJson$3(value);
20175
+ const text = canonicalJson$4(value);
20122
20176
  if (text.includes(DYNAMIC_REFERENCE_OPEN)) return true;
20123
20177
  for (const corpus of corpora) {
20124
20178
  if (corpus === void 0) continue;
@@ -20130,7 +20184,7 @@ function carriesSecretValue(value, corpora) {
20130
20184
  return false;
20131
20185
  }
20132
20186
  function parameterInputsFor(args) {
20133
- const declared = isPlainObject$7(args.template.Parameters) ? args.template.Parameters : {};
20187
+ const declared = isPlainObject$9(args.template.Parameters) ? args.template.Parameters : {};
20134
20188
  const values = args.values ?? {};
20135
20189
  const inputs = /* @__PURE__ */ new Map();
20136
20190
  const bound = {};
@@ -20141,7 +20195,7 @@ function parameterInputsFor(args) {
20141
20195
  continue;
20142
20196
  }
20143
20197
  const value = values[name];
20144
- let secret = isPlainObject$7(definition) && declaresNoEcho(definition) || carriesSecretValue(value, []);
20198
+ let secret = isPlainObject$9(definition) && declaresNoEcho(definition) || carriesSecretValue(value, []);
20145
20199
  if (!secret && args.nestedChild === true && args.supplied !== void 0) {
20146
20200
  if (Object.hasOwn(args.supplied, name)) {
20147
20201
  const passed = args.passedClasses?.get(name);
@@ -20192,7 +20246,7 @@ function intrinsicKey(value) {
20192
20246
  const OPAQUE_ATTRIBUTE_TYPES = /* @__PURE__ */ new Set(["AWS::CloudFormation::CustomResource", NESTED_STACK_TYPE$4]);
20193
20247
  function hasOpaqueAttributes(logicalId, walk) {
20194
20248
  const definition = walk.resources[logicalId];
20195
- const type = isPlainObject$7(definition) ? definition["Type"] : void 0;
20249
+ const type = isPlainObject$9(definition) ? definition["Type"] : void 0;
20196
20250
  return typeof type === "string" && (type.startsWith("Custom::") || OPAQUE_ATTRIBUTE_TYPES.has(type));
20197
20251
  }
20198
20252
  function getAttTarget(operand) {
@@ -20217,7 +20271,7 @@ function taintOf(logicalId, walk) {
20217
20271
  const visit = (value) => {
20218
20272
  if (typeof value === "string") return value.includes(DYNAMIC_REFERENCE_OPEN);
20219
20273
  if (Array.isArray(value)) return value.some(visit);
20220
- if (!isPlainObject$7(value)) return false;
20274
+ if (!isPlainObject$9(value)) return false;
20221
20275
  const key = intrinsicKey(value);
20222
20276
  const operand = key === void 0 ? void 0 : value[key];
20223
20277
  let verdict = "clean";
@@ -20229,7 +20283,7 @@ function taintOf(logicalId, walk) {
20229
20283
  else if (key === "Fn::FindInMap" && mapReadClass(operand, walk.sources.template) !== "clean") verdict = "tainted";
20230
20284
  else if (key === "Fn::Sub") {
20231
20285
  const text = Array.isArray(operand) ? operand[0] : operand;
20232
- const vars = Array.isArray(operand) && isPlainObject$7(operand[1]) ? operand[1] : {};
20286
+ const vars = Array.isArray(operand) && isPlainObject$9(operand[1]) ? operand[1] : {};
20233
20287
  if (typeof text === "string") for (const name of subPlaceholders(text)) {
20234
20288
  if (Object.hasOwn(vars, name)) continue;
20235
20289
  const owner = name.includes(".") ? name.split(".")[0] : name;
@@ -20243,7 +20297,7 @@ function taintOf(logicalId, walk) {
20243
20297
  return Object.values(value).some(visit);
20244
20298
  };
20245
20299
  const definition = walk.resources[logicalId];
20246
- const result = visit(isPlainObject$7(definition) ? definition["Properties"] : void 0) ? "tainted" : unknown ? "unknown" : "clean";
20300
+ const result = visit(isPlainObject$9(definition) ? definition["Properties"] : void 0) ? "tainted" : unknown ? "unknown" : "clean";
20247
20301
  walk.inProgress.delete(logicalId);
20248
20302
  walk.taint.set(logicalId, result);
20249
20303
  return result;
@@ -20259,7 +20313,7 @@ function conditionInput(name, walk) {
20259
20313
  return typeof verdict === "boolean" ? verdict : "unknown";
20260
20314
  }
20261
20315
  function conditionClosure(name, walk) {
20262
- const definitions = isPlainObject$7(walk.sources.template.Conditions) ? walk.sources.template.Conditions : {};
20316
+ const definitions = isPlainObject$9(walk.sources.template.Conditions) ? walk.sources.template.Conditions : {};
20263
20317
  let secret = false;
20264
20318
  let unknown = false;
20265
20319
  let unread = false;
@@ -20274,7 +20328,7 @@ function conditionClosure(name, walk) {
20274
20328
  value.forEach(visit);
20275
20329
  return;
20276
20330
  }
20277
- if (!isPlainObject$7(value)) return;
20331
+ if (!isPlainObject$9(value)) return;
20278
20332
  const keys = Object.keys(value);
20279
20333
  if (keys.length === 1 && keys[0] === "Condition" && typeof value["Condition"] === "string") {
20280
20334
  pending.push(value["Condition"]);
@@ -20307,7 +20361,7 @@ function conditionClosure(name, walk) {
20307
20361
  if (key === "Fn::Sub") {
20308
20362
  const operand = value["Fn::Sub"];
20309
20363
  const text = Array.isArray(operand) ? operand[0] : operand;
20310
- const vars = Array.isArray(operand) && isPlainObject$7(operand[1]) ? operand[1] : {};
20364
+ const vars = Array.isArray(operand) && isPlainObject$9(operand[1]) ? operand[1] : {};
20311
20365
  if (typeof text === "string") for (const name of subPlaceholders(text)) {
20312
20366
  if (Object.hasOwn(vars, name)) continue;
20313
20367
  if (name.includes(".") && !name.startsWith("AWS::")) secret = true;
@@ -20336,8 +20390,8 @@ function mapReadClass(operand, template) {
20336
20390
  const mapName = Array.isArray(operand) ? operand[0] : void 0;
20337
20391
  if (typeof mapName !== "string") return "unknown";
20338
20392
  const mappings = template.Mappings;
20339
- const map = isPlainObject$7(mappings) && Object.hasOwn(mappings, mapName) ? mappings[mapName] : void 0;
20340
- if (!isPlainObject$7(map)) return "unknown";
20393
+ const map = isPlainObject$9(mappings) && Object.hasOwn(mappings, mapName) ? mappings[mapName] : void 0;
20394
+ if (!isPlainObject$9(map)) return "unknown";
20341
20395
  return carriesSecretValue(map, []) ? "secret" : "clean";
20342
20396
  }
20343
20397
  async function resolvedInput(node, walk) {
@@ -20405,7 +20459,7 @@ async function inputForm(value, walk) {
20405
20459
  concrete: parts.every((p) => p.concrete)
20406
20460
  };
20407
20461
  }
20408
- if (!isPlainObject$7(value)) return {
20462
+ if (!isPlainObject$9(value)) return {
20409
20463
  form: value,
20410
20464
  concrete: true
20411
20465
  };
@@ -20468,7 +20522,7 @@ async function inputForm(value, walk) {
20468
20522
  concrete: false
20469
20523
  };
20470
20524
  }
20471
- const explicit = Array.isArray(operand) && isPlainObject$7(operand[1]) ? operand[1] : {};
20525
+ const explicit = Array.isArray(operand) && isPlainObject$9(operand[1]) ? operand[1] : {};
20472
20526
  const vars = await inputForm(explicit, walk);
20473
20527
  const placeholders = [];
20474
20528
  let concrete = vars.concrete && !text.includes(DYNAMIC_REFERENCE_OPEN);
@@ -20521,8 +20575,8 @@ function newWalk(sources, nested = {
20521
20575
  }) {
20522
20576
  return {
20523
20577
  sources,
20524
- resources: isPlainObject$7(sources.template.Resources) ? sources.template.Resources : {},
20525
- parameters: isPlainObject$7(sources.template.Parameters) ? sources.template.Parameters : {},
20578
+ resources: isPlainObject$9(sources.template.Resources) ? sources.template.Resources : {},
20579
+ parameters: isPlainObject$9(sources.template.Parameters) ? sources.template.Parameters : {},
20526
20580
  taint: /* @__PURE__ */ new Map(),
20527
20581
  inProgress: /* @__PURE__ */ new Set(),
20528
20582
  stackChain: nested.stackChain,
@@ -20546,34 +20600,34 @@ function passedKey(passed) {
20546
20600
  function isNestedStackRow(logicalId, walk) {
20547
20601
  if (!Object.hasOwn(walk.resources, logicalId)) return false;
20548
20602
  const definition = walk.resources[logicalId];
20549
- return isPlainObject$7(definition) && definition["Type"] === NESTED_STACK_TYPE$4;
20603
+ return isPlainObject$9(definition) && definition["Type"] === NESTED_STACK_TYPE$4;
20550
20604
  }
20551
20605
  function getAttAttribute(operand, target) {
20552
20606
  if (Array.isArray(operand)) return operand.length === 2 && typeof operand[1] === "string" ? operand[1] : void 0;
20553
20607
  return typeof operand === "string" ? operand.slice(target.length + 1) : void 0;
20554
20608
  }
20555
20609
  function rowParameters(definition) {
20556
- const properties = isPlainObject$7(definition) ? definition["Properties"] : void 0;
20610
+ const properties = isPlainObject$9(definition) ? definition["Properties"] : void 0;
20557
20611
  if (properties === void 0) return {};
20558
- if (!isPlainObject$7(properties)) return "unknown";
20612
+ if (!isPlainObject$9(properties)) return "unknown";
20559
20613
  const parameters = properties["Parameters"];
20560
20614
  if (parameters === void 0) return {};
20561
- if (!isPlainObject$7(parameters) || intrinsicKey(parameters) !== void 0) return "unknown";
20615
+ if (!isPlainObject$9(parameters) || intrinsicKey(parameters) !== void 0) return "unknown";
20562
20616
  return parameters;
20563
20617
  }
20564
20618
  function childParameterInputs(template, passed) {
20565
- const declared = isPlainObject$7(template.Parameters) ? template.Parameters : {};
20619
+ const declared = isPlainObject$9(template.Parameters) ? template.Parameters : {};
20566
20620
  const inputs = /* @__PURE__ */ new Map();
20567
20621
  for (const name of Object.keys(declared)) {
20568
20622
  const definition = declared[name];
20569
- if (isPlainObject$7(definition) && declaresNoEcho(definition)) inputs.set(name, { kind: "secret" });
20623
+ if (isPlainObject$9(definition) && declaresNoEcho(definition)) inputs.set(name, { kind: "secret" });
20570
20624
  else if (passed.has(name)) {
20571
20625
  const passedClass = passed.get(name);
20572
20626
  inputs.set(name, passedClass === "clean" ? {
20573
20627
  kind: "value",
20574
20628
  value: void 0
20575
20629
  } : passedClass === "unknown" ? { kind: "unknown" } : { kind: "secret" });
20576
- } else if (isPlainObject$7(definition) && Object.hasOwn(definition, "Default") && !carriesSecretValue(definition["Default"], [])) inputs.set(name, {
20630
+ } else if (isPlainObject$9(definition) && Object.hasOwn(definition, "Default") && !carriesSecretValue(definition["Default"], [])) inputs.set(name, {
20577
20631
  kind: "value",
20578
20632
  value: definition["Default"]
20579
20633
  });
@@ -20590,7 +20644,7 @@ function closureClass(closure) {
20590
20644
  return closure.unread ? "unread" : "clean";
20591
20645
  }
20592
20646
  async function childOutputClass(loaded, outputName, passed, chain, shared) {
20593
- if (loaded === void 0 || !isPlainObject$7(loaded.template)) return "unknown";
20647
+ if (loaded === void 0 || !isPlainObject$9(loaded.template)) return "unknown";
20594
20648
  const scopeKey = JSON.stringify([loaded.identity, passedKey(passed)]);
20595
20649
  const memoKey = JSON.stringify([scopeKey, outputName]);
20596
20650
  const memo = shared.outputs.get(memoKey);
@@ -20603,8 +20657,8 @@ async function classifyChildOutput(loaded, outputName, passed, chain, shared, sc
20603
20657
  if (++shared.steps > MAX_NESTED_OUTPUT_STEPS) return "unknown";
20604
20658
  if (chain.includes(loaded.identity) || chain.length >= MAX_NESTED_OUTPUT_DEPTH) return "unknown";
20605
20659
  const template = loaded.template;
20606
- const output = (isPlainObject$7(template.Outputs) ? template.Outputs : {})[outputName];
20607
- if (!isPlainObject$7(output) || !Object.hasOwn(output, "Value")) return "unknown";
20660
+ const output = (isPlainObject$9(template.Outputs) ? template.Outputs : {})[outputName];
20661
+ if (!isPlainObject$9(output) || !Object.hasOwn(output, "Value")) return "unknown";
20608
20662
  const scope = {
20609
20663
  walk: newWalk({
20610
20664
  template,
@@ -20676,7 +20730,7 @@ async function expressionClass(value, scope) {
20676
20730
  return result;
20677
20731
  };
20678
20732
  if (Array.isArray(value)) return all(value);
20679
- if (!isPlainObject$7(value)) return "clean";
20733
+ if (!isPlainObject$9(value)) return "clean";
20680
20734
  const key = intrinsicKey(value);
20681
20735
  if (key === void 0) return all(Object.values(value));
20682
20736
  const operand = value[key];
@@ -20691,7 +20745,7 @@ async function expressionClass(value, scope) {
20691
20745
  case "Fn::Sub": {
20692
20746
  const text = Array.isArray(operand) ? operand[0] : operand;
20693
20747
  if (typeof text !== "string") return worseOf("unknown", await expressionClass(operand, scope));
20694
- const vars = Array.isArray(operand) && isPlainObject$7(operand[1]) ? operand[1] : {};
20748
+ const vars = Array.isArray(operand) && isPlainObject$9(operand[1]) ? operand[1] : {};
20695
20749
  let result = text.includes(DYNAMIC_REFERENCE_OPEN) ? "secret" : "clean";
20696
20750
  result = worseOf(result, await all(Object.values(vars)));
20697
20751
  for (const name of subPlaceholders(text)) {
@@ -20755,7 +20809,7 @@ async function maskedInputFingerprint(templateValue, sources) {
20755
20809
  if (error instanceof UnknownInput) return void 0;
20756
20810
  throw error;
20757
20811
  }
20758
- const digest = createHash("sha256").update(canonicalJson$3({
20812
+ const digest = createHash("sha256").update(canonicalJson$4({
20759
20813
  layout: INPUT_FINGERPRINT_LAYOUT,
20760
20814
  value: form
20761
20815
  })).digest("hex");
@@ -20769,7 +20823,7 @@ async function classifyPassedParameters(parameters, sources) {
20769
20823
  }
20770
20824
  async function classifyPassed(parameters, sources, nested) {
20771
20825
  const classes = /* @__PURE__ */ new Map();
20772
- if (!isPlainObject$7(parameters)) return classes;
20826
+ if (!isPlainObject$9(parameters)) return classes;
20773
20827
  for (const [name, expression] of Object.entries(parameters)) {
20774
20828
  let passedClass;
20775
20829
  try {
@@ -20810,13 +20864,13 @@ function possiblyMaskedKeys(resolvedProps, corpora) {
20810
20864
  const wholeShortLeaf = (value) => {
20811
20865
  if (typeof value === "string") return short.includes(value);
20812
20866
  if (Array.isArray(value)) return value.some(wholeShortLeaf);
20813
- if (isPlainObject$7(value)) return Object.values(value).some(wholeShortLeaf);
20867
+ if (isPlainObject$9(value)) return Object.values(value).some(wholeShortLeaf);
20814
20868
  return false;
20815
20869
  };
20816
20870
  return Object.keys(resolvedProps).filter((key) => {
20817
20871
  const value = resolvedProps[key];
20818
20872
  if (carriesSecretMask(value) || wholeShortLeaf(value)) return true;
20819
- const text = canonicalJson$3(value);
20873
+ const text = canonicalJson$4(value);
20820
20874
  return long.some((needle) => text.includes(needle) || text.includes(JSON.stringify(needle).slice(1, -1)));
20821
20875
  });
20822
20876
  }
@@ -20841,7 +20895,7 @@ function maskedPropertyFingerprintsOf(record) {
20841
20895
  const read = /* @__PURE__ */ new Map();
20842
20896
  if (record === null || typeof record !== "object") return read;
20843
20897
  const field = record.maskedPropertyFingerprints;
20844
- if (!isPlainObject$7(field)) return read;
20898
+ if (!isPlainObject$9(field)) return read;
20845
20899
  for (const [key, value] of Object.entries(field)) if (typeof value === "string" && value.startsWith(FINGERPRINT_PREFIX)) read.set(key, value);
20846
20900
  return read;
20847
20901
  }
@@ -20849,7 +20903,7 @@ function maskedPropertyInputFingerprintsOf(record) {
20849
20903
  const read = /* @__PURE__ */ new Map();
20850
20904
  if (record === null || typeof record !== "object") return read;
20851
20905
  const field = record.maskedPropertyInputFingerprints;
20852
- if (!isPlainObject$7(field)) return read;
20906
+ if (!isPlainObject$9(field)) return read;
20853
20907
  const text = maskedPropertyFingerprintsOf(record);
20854
20908
  for (const [key, value] of Object.entries(field)) {
20855
20909
  if (typeof value !== "string" || !value.startsWith(INPUT_FINGERPRINT_PREFIX)) continue;
@@ -20896,7 +20950,7 @@ async function movedMaskedProperties(record, templateProps, fingerprinter, onReb
20896
20950
  function withRebaselinedFingerprints(record, fingerprints) {
20897
20951
  const text = maskedPropertyFingerprintsOf(record);
20898
20952
  const field = record.maskedPropertyInputFingerprints;
20899
- const next = isPlainObject$7(field) ? Object.entries(field) : [];
20953
+ const next = isPlainObject$9(field) ? Object.entries(field) : [];
20900
20954
  let changed = false;
20901
20955
  for (const [key, value] of Object.entries(fingerprints)) {
20902
20956
  if (text.get(key) !== splitInputFingerprint(value).text) continue;
@@ -20929,10 +20983,10 @@ function withMaskedPropertyFingerprints(scrubbed, writtenBag, templateProps, sec
20929
20983
  fingerprints = maskedPropertyFingerprintsFor(scrubbed.properties, templateProps);
20930
20984
  inputs = boundInputFingerprints(fingerprints, inputFingerprints);
20931
20985
  } else {
20932
- if (!isPlainObject$7(previous)) return scrubbed;
20986
+ if (!isPlainObject$9(previous)) return scrubbed;
20933
20987
  if (corpora.length === 0) return scrubbed;
20934
20988
  fingerprints = { ...previous };
20935
- inputs = isPlainObject$7(previousInputs) ? { ...previousInputs } : void 0;
20989
+ inputs = isPlainObject$9(previousInputs) ? { ...previousInputs } : void 0;
20936
20990
  }
20937
20991
  if (fingerprints !== void 0 && corpora.length > 0) {
20938
20992
  const refused = Object.keys(fingerprints).filter((key) => Object.hasOwn(templateProps, key) && corpora.some((corpus) => templateCarriesNeedle(templateProps[key], corpus)));
@@ -22273,11 +22327,11 @@ function validReferenceRegion(region) {
22273
22327
  if (typeof region !== "string") return void 0;
22274
22328
  return canonicalizeRegion(region) === region && isClientSafeRegion(region) ? region : void 0;
22275
22329
  }
22276
- function isPlainObject$6(value) {
22330
+ function isPlainObject$8(value) {
22277
22331
  return value !== null && typeof value === "object" && !Array.isArray(value);
22278
22332
  }
22279
22333
  function validateReferenceProvenance(token, raw) {
22280
- if (!isSingleDynamicReferenceToken(token) || !isPlainObject$6(raw)) return void 0;
22334
+ if (!isSingleDynamicReferenceToken(token) || !isPlainObject$8(raw)) return void 0;
22281
22335
  const versionsRaw = Object.hasOwn(raw, "versions") ? raw["versions"] : void 0;
22282
22336
  const readRaw = Object.hasOwn(raw, "readVersions") ? raw["readVersions"] : void 0;
22283
22337
  if (readRaw !== void 0) {
@@ -22295,11 +22349,11 @@ function validateReferenceProvenance(token, raw) {
22295
22349
  return out;
22296
22350
  }
22297
22351
  function referenceProvenanceOf(record) {
22298
- if (!isPlainObject$6(record) || !Object.hasOwn(record, "referenceProvenance")) return void 0;
22352
+ if (!isPlainObject$8(record) || !Object.hasOwn(record, "referenceProvenance")) return void 0;
22299
22353
  return validatedBag(record["referenceProvenance"]);
22300
22354
  }
22301
22355
  function validatedBag(field) {
22302
- if (!isPlainObject$6(field)) return void 0;
22356
+ if (!isPlainObject$8(field)) return void 0;
22303
22357
  const out = Object.create(null);
22304
22358
  for (const [token, raw] of Object.entries(field)) {
22305
22359
  const entry = validateReferenceProvenance(token, raw);
@@ -22308,9 +22362,9 @@ function validatedBag(field) {
22308
22362
  return { ...out };
22309
22363
  }
22310
22364
  function recordedProvenanceOf(record, token) {
22311
- if (!isPlainObject$6(record) || !Object.hasOwn(record, "referenceProvenance")) return void 0;
22365
+ if (!isPlainObject$8(record) || !Object.hasOwn(record, "referenceProvenance")) return void 0;
22312
22366
  const field = record["referenceProvenance"];
22313
- if (!isPlainObject$6(field) || !Object.hasOwn(field, token)) return void 0;
22367
+ if (!isPlainObject$8(field) || !Object.hasOwn(field, token)) return void 0;
22314
22368
  return validateReferenceProvenance(token, field[token]);
22315
22369
  }
22316
22370
  function recordedReferenceRegions(record) {
@@ -22332,7 +22386,7 @@ function regionsOf(field) {
22332
22386
  function keepHeldTokenProvenance(record) {
22333
22387
  if (!hasReferenceProvenanceField(record)) return record;
22334
22388
  const field = record.referenceProvenance;
22335
- if (!isPlainObject$6(field)) return record;
22389
+ if (!isPlainObject$8(field)) return record;
22336
22390
  const held = recordReferenceTokens(record);
22337
22391
  const keys = Object.keys(field);
22338
22392
  if (keys.every((token) => held.has(token))) return record;
@@ -22344,12 +22398,12 @@ function keepHeldTokenProvenance(record) {
22344
22398
  };
22345
22399
  }
22346
22400
  function hasReferenceProvenanceField(record) {
22347
- return isPlainObject$6(record) && Object.hasOwn(record, "referenceProvenance") && record["referenceProvenance"] !== void 0;
22401
+ return isPlainObject$8(record) && Object.hasOwn(record, "referenceProvenance") && record["referenceProvenance"] !== void 0;
22348
22402
  }
22349
22403
  function outputReferenceProvenanceOf(state, outputKey) {
22350
- if (!isPlainObject$6(state) || !Object.hasOwn(state, "outputReferenceProvenance")) return;
22404
+ if (!isPlainObject$8(state) || !Object.hasOwn(state, "outputReferenceProvenance")) return;
22351
22405
  const field = state["outputReferenceProvenance"];
22352
- if (!isPlainObject$6(field) || !Object.hasOwn(field, outputKey)) return void 0;
22406
+ if (!isPlainObject$8(field) || !Object.hasOwn(field, outputKey)) return void 0;
22353
22407
  return validatedBag(field[outputKey]);
22354
22408
  }
22355
22409
  function persistable(token, entry) {
@@ -22367,7 +22421,7 @@ function tokensUnderPaths(properties, paths) {
22367
22421
  for (const item of value) descend(item, path, next);
22368
22422
  return;
22369
22423
  }
22370
- if (isPlainObject$6(value) && Object.hasOwn(value, path[at])) descend(value[path[at]], path, at + 1);
22424
+ if (isPlainObject$8(value) && Object.hasOwn(value, path[at])) descend(value[path[at]], path, at + 1);
22371
22425
  };
22372
22426
  for (const path of paths) descend(properties, path, 0);
22373
22427
  return out;
@@ -22410,7 +22464,7 @@ function unionWithPrevious(pass, before) {
22410
22464
  }
22411
22465
  function outputProvenanceForPersist(args) {
22412
22466
  const { outputs, resolvedThisRun, carriedFrom, sinkOf } = args;
22413
- if (!resolvedThisRun) return carriedFrom !== void 0 && isPlainObject$6(carriedFrom.outputReferenceProvenance) ? carriedFrom.outputReferenceProvenance : void 0;
22467
+ if (!resolvedThisRun) return carriedFrom !== void 0 && isPlainObject$8(carriedFrom.outputReferenceProvenance) ? carriedFrom.outputReferenceProvenance : void 0;
22414
22468
  let out;
22415
22469
  for (const [outputKey, value] of Object.entries(outputs)) {
22416
22470
  const sink = sinkOf(outputKey);
@@ -25930,19 +25984,49 @@ var IntrinsicFunctionResolver = class IntrinsicFunctionResolver {
25930
25984
  }
25931
25985
  };
25932
25986
 
25987
+ //#endregion
25988
+ //#region src/state/unsettled-properties.ts
25989
+ function unsettledPropertiesOf(record) {
25990
+ if (record === null || typeof record !== "object") return /* @__PURE__ */ new Set();
25991
+ const value = record.unsettledProperties;
25992
+ if (!Array.isArray(value)) return /* @__PURE__ */ new Set();
25993
+ return new Set(value.filter((entry) => typeof entry === "string" && entry !== ""));
25994
+ }
25995
+ function withUnsettledProperties(record, names) {
25996
+ const merged = new Set(unsettledPropertiesOf(record));
25997
+ const before = merged.size;
25998
+ for (const name of names) if (typeof name === "string" && name !== "") merged.add(name);
25999
+ if (merged.size === before && Array.isArray(record.unsettledProperties)) return record;
26000
+ if (merged.size === 0) return withoutUnsettledProperties(record);
26001
+ return {
26002
+ ...record,
26003
+ unsettledProperties: [...merged].sort()
26004
+ };
26005
+ }
26006
+ function withoutUnsettledProperties(record) {
26007
+ if (!Object.hasOwn(record, "unsettledProperties")) return record;
26008
+ const { unsettledProperties: _cleared, ...rest } = record;
26009
+ return rest;
26010
+ }
26011
+ function unsettledContextOf(...records) {
26012
+ const names = /* @__PURE__ */ new Set();
26013
+ for (const record of records) for (const name of unsettledPropertiesOf(record)) names.add(name);
26014
+ return names.size > 0 ? { unsettledProperties: names } : {};
26015
+ }
26016
+
25933
26017
  //#endregion
25934
26018
  //#region src/analyzer/read-provenance-promotion.ts
25935
- function isPlainObject$5(value) {
26019
+ function isPlainObject$7(value) {
25936
26020
  return value !== null && typeof value === "object" && !Array.isArray(value);
25937
26021
  }
25938
26022
  function readsAcrossStacks(value) {
25939
26023
  if (Array.isArray(value)) return value.some(readsAcrossStacks);
25940
- if (!isPlainObject$5(value)) return false;
26024
+ if (!isPlainObject$7(value)) return false;
25941
26025
  if (Object.hasOwn(value, "Fn::ImportValue") || Object.hasOwn(value, "Fn::GetStackOutput")) return true;
25942
26026
  return Object.values(value).some(readsAcrossStacks);
25943
26027
  }
25944
26028
  function recordedReadVersions(record) {
25945
- if (!isPlainObject$5(record) || !Object.hasOwn(record, "referenceProvenance")) return void 0;
26029
+ if (!isPlainObject$7(record) || !Object.hasOwn(record, "referenceProvenance")) return void 0;
25946
26030
  const field = referenceProvenanceOf(record);
25947
26031
  if (field === void 0) return void 0;
25948
26032
  let out;
@@ -25953,7 +26037,7 @@ async function readProvenancePromotions(args) {
25953
26037
  const { currentState, desiredTemplate, sources } = args;
25954
26038
  const parser = args.parser ?? new TemplateParser();
25955
26039
  const records = currentState.resources;
25956
- const parameters = isPlainObject$5(desiredTemplate.Parameters) ? desiredTemplate.Parameters : void 0;
26040
+ const parameters = isPlainObject$7(desiredTemplate.Parameters) ? desiredTemplate.Parameters : void 0;
25957
26041
  const out = [];
25958
26042
  for (const { logicalId, changeType } of args.rows) {
25959
26043
  if (changeType !== "NO_CHANGE" && changeType !== "UPDATE") continue;
@@ -25961,7 +26045,7 @@ async function readProvenancePromotions(args) {
25961
26045
  const readVersions = recordedReadVersions(record);
25962
26046
  if (readVersions === void 0) continue;
25963
26047
  const resource = Object.hasOwn(desiredTemplate.Resources, logicalId) ? desiredTemplate.Resources[logicalId] : void 0;
25964
- const properties = isPlainObject$5(resource?.Properties) ? resource.Properties : {};
26048
+ const properties = isPlainObject$7(resource?.Properties) ? resource.Properties : {};
25965
26049
  const reads = [];
25966
26050
  for (const [key, value] of Object.entries(properties)) {
25967
26051
  const referenced = [...parser.extractReferences(value)].filter((id) => id !== logicalId);
@@ -26004,7 +26088,7 @@ async function readProvenancePromotions(args) {
26004
26088
  if (recorded.some((version) => !domain.has(version))) moved.push(token);
26005
26089
  }
26006
26090
  if (moved.length === 0) continue;
26007
- const recordProperties = isPlainObject$5(record?.properties) ? record.properties : {};
26091
+ const recordProperties = isPlainObject$7(record?.properties) ? record.properties : {};
26008
26092
  const keys = [];
26009
26093
  for (const r of reads) {
26010
26094
  if (!Object.hasOwn(recordProperties, r.key)) continue;
@@ -26174,6 +26258,18 @@ var DiffCalculator = class DiffCalculator {
26174
26258
  });
26175
26259
  this.logger.debug(safeMsg`${logicalId}: ${key} is recorded masked and its template expression or a resolved input changed`);
26176
26260
  }
26261
+ const listed = new Set(propertyChanges.map((pc) => pc.path));
26262
+ for (const key of unsettledPropertiesOf(currentResource)) {
26263
+ if (listed.has(key)) continue;
26264
+ propertyChanges.push({
26265
+ path: key,
26266
+ oldValue: currentCompared[key],
26267
+ newValue: desiredCompared[key],
26268
+ requiresReplacement: false,
26269
+ unsettled: true
26270
+ });
26271
+ this.logger.debug(safeMsg`${logicalId}: ${key} is unsettled after a failed update and is sent again`);
26272
+ }
26177
26273
  const attributeChanges = this.compareAttributes(currentResource, desiredResource);
26178
26274
  if (propertyChanges.length > 0 || attributeChanges.length > 0) {
26179
26275
  changes.set(logicalId, {
@@ -27593,8 +27689,8 @@ function compare(desired, previous, mask) {
27593
27689
  if (!Array.isArray(desired) || desired.length !== previous.length) return "differs";
27594
27690
  return combine(previous.map((item, i) => compare(desired[i], item, mask)));
27595
27691
  }
27596
- if (isPlainObject$4(previous)) {
27597
- if (!isPlainObject$4(desired)) return "differs";
27692
+ if (isPlainObject$6(previous)) {
27693
+ if (!isPlainObject$6(desired)) return "differs";
27598
27694
  if (!Object.keys(desired).every((k) => Object.prototype.hasOwnProperty.call(previous, k))) return "differs";
27599
27695
  return combine(Object.keys(previous).map((k) => compare(desired[k], previous[k], mask)));
27600
27696
  }
@@ -27620,7 +27716,7 @@ function resolvesReference(desired, previous, mask) {
27620
27716
  const pattern = literals.map(escapeRegExp$1).join("[\\s\\S]*");
27621
27717
  return new RegExp(`^${pattern}$`).test(desired);
27622
27718
  }
27623
- function isPlainObject$4(value) {
27719
+ function isPlainObject$6(value) {
27624
27720
  return typeof value === "object" && value !== null && !Array.isArray(value);
27625
27721
  }
27626
27722
  function escapeRegExp$1(text) {
@@ -28573,7 +28669,7 @@ var CloudControlProvider = class {
28573
28669
  const indeterminateGuard = await this.confirmDeleteTargetIdentity(logicalId, resourceType, physicalId, context);
28574
28670
  if (context?.removeProtection === true && resourceType === "AWS::AutoScaling::AutoScalingGroup") {
28575
28671
  this.logger.debug(`Delegating protected AutoScalingGroup ${logicalId} delete to the SDK ASGProvider (Cloud Control cannot force-delete a protected ASG)`);
28576
- const { ASGProvider } = await import("./asg-provider-B7pAjRIc.js");
28672
+ const { ASGProvider } = await import("./asg-provider-DQoKGfKH.js");
28577
28673
  const delegateRegion = ambientRegion();
28578
28674
  let asgProvider = this.asgDeleteDelegates.get(delegateRegion);
28579
28675
  if (asgProvider === void 0) {
@@ -28682,7 +28778,7 @@ var CloudControlProvider = class {
28682
28778
  const family = SDK_DELETE_FAMILIES.get(resourceType);
28683
28779
  const cached = this.sdkDeleteDelegates.get(family);
28684
28780
  if (cached !== void 0 && cached.region === ccRegion) return cached.provider;
28685
- const provider = family === "rds" ? new (await (import("./rds-provider-CZhBLQgJ.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-Y3Ii8oYI.js"))).NeptuneProvider({ region: ccRegion });
28781
+ const provider = family === "rds" ? new (await (import("./rds-provider-Qpf09VQv.js"))).RDSProvider({ region: ccRegion }) : new (await (import("./neptune-provider-DmVmx69p.js"))).NeptuneProvider({ region: ccRegion });
28686
28782
  this.sdkDeleteDelegates.set(family, {
28687
28783
  region: ccRegion,
28688
28784
  provider
@@ -29838,11 +29934,11 @@ function applyNoEchoDeleteValues(properties, recordedLeaves, values) {
29838
29934
  payload: properties,
29839
29935
  unresolved: []
29840
29936
  };
29841
- const byKey = new Map((values?.leaves ?? []).map((leaf) => [canonicalJson$4(leaf.coordinate), leaf]));
29937
+ const byKey = new Map((values?.leaves ?? []).map((leaf) => [canonicalJson$5(leaf.coordinate), leaf]));
29842
29938
  const entries = [];
29843
29939
  const unresolved = [];
29844
29940
  for (const coordinate of masked) {
29845
- const leaf = byKey.get(canonicalJson$4(coordinate));
29941
+ const leaf = byKey.get(canonicalJson$5(coordinate));
29846
29942
  if (leaf === void 0) unresolved.push(coordinate);
29847
29943
  else entries.push({
29848
29944
  coordinate,
@@ -29893,7 +29989,7 @@ async function noEchoDeleteValuesFromResolved(options) {
29893
29989
  const fingerprinter = options.inputSources === void 0 ? void 0 : inputFingerprinter(templateProps, options.inputSources);
29894
29990
  const leaves = [];
29895
29991
  for (const coordinate of masked) {
29896
- if (!nodes.has(canonicalJson$4(coordinate))) continue;
29992
+ if (!nodes.has(canonicalJson$5(coordinate))) continue;
29897
29993
  if (!await fingerprintsUnchanged(record, templateProps, coordinate, fingerprinter)) continue;
29898
29994
  const value = valueAtCoordinate(resolvedProperties, coordinate);
29899
29995
  if (value === void 0 || carriesSecretMask(value)) continue;
@@ -30072,7 +30168,7 @@ var TemplateNoEchoReresolver = class TemplateNoEchoReresolver {
30072
30168
  const bag = await this.noEchoNeedles();
30073
30169
  const leaves = [];
30074
30170
  for (const coordinate of masked) {
30075
- const key = canonicalJson$4(coordinate);
30171
+ const key = canonicalJson$5(coordinate);
30076
30172
  if (!nodes.has(key)) continue;
30077
30173
  const node = nodes.get(key)?.node;
30078
30174
  if (!readsParametersOnly(node, declared, refused)) continue;
@@ -37163,7 +37259,7 @@ const DEFAULT_RESOURCE_TIMEOUT_MS = 18e5;
37163
37259
 
37164
37260
  //#endregion
37165
37261
  //#region src/analyzer/skipped-outputs.ts
37166
- function canonicalJson$2(value) {
37262
+ function canonicalJson$3(value) {
37167
37263
  return JSON.stringify(value, (_key, v) => {
37168
37264
  if (v !== null && typeof v === "object" && !Array.isArray(v)) {
37169
37265
  const sorted = Object.create(null);
@@ -37193,7 +37289,7 @@ function skippedOutputDigest(template, outputKey) {
37193
37289
  sections[section] = section === "Parameters" ? withNoEchoDefaultsMasked(body) : body;
37194
37290
  }
37195
37291
  const entry = template.Outputs?.[outputKey];
37196
- return createHash("sha256").update(canonicalJson$2({
37292
+ return createHash("sha256").update(canonicalJson$3({
37197
37293
  output: entry,
37198
37294
  template: sections
37199
37295
  })).digest("hex");
@@ -38555,9 +38651,9 @@ function sameIdReversalDone(op, current) {
38555
38651
  const now = current.properties ?? {};
38556
38652
  if (forward === void 0) return "undecidable";
38557
38653
  const own = (bag, key) => Object.hasOwn(bag, key) ? bag[key] : void 0;
38558
- const changed = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(forward)])].filter((key) => !deepEqual$1(own(before, key), own(forward, key)));
38559
- if (changed.length === 0) return holdsRedactedLeaf(before) ? "undecidable" : deepEqual$1(now, before);
38560
- return changed.every((key) => deepEqual$1(own(now, key), own(before, key)));
38654
+ const changed = [.../* @__PURE__ */ new Set([...Object.keys(before), ...Object.keys(forward)])].filter((key) => !deepEqual$2(own(before, key), own(forward, key)));
38655
+ if (changed.length === 0) return holdsRedactedLeaf(before) ? "undecidable" : deepEqual$2(now, before);
38656
+ return changed.every((key) => deepEqual$2(own(now, key), own(before, key)));
38561
38657
  }
38562
38658
  function holdsRedactedLeaf(value) {
38563
38659
  if (typeof value === "string") return value.includes("***");
@@ -38567,14 +38663,14 @@ function holdsRedactedLeaf(value) {
38567
38663
  function sameIdReversalUndecidable(op, current) {
38568
38664
  return sameIdRecreated(op) && current !== void 0 && sameIdReversalDone(op, current) === "undecidable";
38569
38665
  }
38570
- function deepEqual$1(a, b) {
38666
+ function deepEqual$2(a, b) {
38571
38667
  if (a === b) return true;
38572
38668
  if (a == null || b == null) return a === b;
38573
38669
  if (typeof a !== typeof b) return false;
38574
38670
  if (typeof a !== "object") return false;
38575
38671
  if (Array.isArray(a) || Array.isArray(b)) {
38576
38672
  if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
38577
- return a.every((v, i) => deepEqual$1(v, b[i]));
38673
+ return a.every((v, i) => deepEqual$2(v, b[i]));
38578
38674
  }
38579
38675
  const ao = a;
38580
38676
  const bo = b;
@@ -38582,7 +38678,7 @@ function deepEqual$1(a, b) {
38582
38678
  if (ak.length !== Object.keys(bo).length) return false;
38583
38679
  for (const k of ak) {
38584
38680
  if (!Object.prototype.hasOwnProperty.call(bo, k)) return false;
38585
- if (!deepEqual$1(ao[k], bo[k])) return false;
38681
+ if (!deepEqual$2(ao[k], bo[k])) return false;
38586
38682
  }
38587
38683
  return true;
38588
38684
  }
@@ -38621,13 +38717,13 @@ function classifyRollbackOp(op, stateResources, orphanLogicalIds) {
38621
38717
  return "reverse-replacement-readopt";
38622
38718
  }
38623
38719
  if (op.physicalId !== void 0 && current.physicalId !== op.physicalId) {
38624
- if (sameTypeAsOld && deepEqual$1(current.properties, op.previousState.properties)) return "skip-already-done";
38720
+ if (sameTypeAsOld && deepEqual$2(current.properties, op.previousState.properties)) return "skip-already-done";
38625
38721
  return "skip-mismatch";
38626
38722
  }
38627
38723
  if (!resolveReplacementOldType(op).ok) return "refuse-replacement-routing";
38628
38724
  return op.oldResourceRetained ?? op.previousState.updateReplacePolicy === "Retain" ? "reverse-replacement-readopt" : "reverse-replacement";
38629
38725
  }
38630
- if (op.previousState && deepEqual$1(current.properties, op.previousState.properties)) return "skip-already-done";
38726
+ if (op.previousState && deepEqual$2(current.properties, op.previousState.properties)) return "skip-already-done";
38631
38727
  return "revert";
38632
38728
  }
38633
38729
  function classifyFailedOp(op, stateResources, siblings = []) {
@@ -38977,7 +39073,7 @@ function replaceAtCoordinate(bag, coordinate, value) {
38977
39073
  });
38978
39074
  return root;
38979
39075
  }
38980
- async function readLive(live, baseline, marked, logicalId, ctx) {
39076
+ async function readLive$1(live, baseline, marked, logicalId, ctx) {
38981
39077
  let readCurrentState;
38982
39078
  try {
38983
39079
  const { provider } = ctx.providerRegistry.getProviderFor({
@@ -39018,7 +39114,7 @@ async function substituteMarkedNoEchoLeaves(input) {
39018
39114
  ...identity,
39019
39115
  inert: pending
39020
39116
  };
39021
- const read = await readLive(live, baseline, pending, logicalId, ctx);
39117
+ const read = await readLive$1(live, baseline, pending, logicalId, ctx);
39022
39118
  if ("failure" in read) throw unreadableNoEchoLeafRefusal(logicalId, pending, read.failure);
39023
39119
  const values = [];
39024
39120
  const unreadable = [];
@@ -39066,7 +39162,7 @@ function maskRestoredNoEchoRecord(record, baseline, substituted = []) {
39066
39162
  const marked = noEchoLeavesOf(baseline) ?? [];
39067
39163
  const names = declaredNoEchoAttributeNames(baseline);
39068
39164
  if (marked.length === 0 && names.length === 0 && substituted.length === 0) return record;
39069
- const echoes = (name, value) => value !== record.physicalId && substituted.some((leaf) => leaf.coordinate[0] === name && canonicalJson$4(leaf.value) === canonicalJson$4(value));
39165
+ const echoes = (name, value) => value !== record.physicalId && substituted.some((leaf) => leaf.coordinate[0] === name && canonicalJson$5(leaf.value) === canonicalJson$5(value));
39070
39166
  let attributes = record.attributes;
39071
39167
  if (attributes !== void 0 && attributes !== null && typeof attributes === "object") for (const [name, value] of Object.entries(attributes)) {
39072
39168
  if (!names.includes(name) && !echoes(name, value)) continue;
@@ -39077,7 +39173,7 @@ function maskRestoredNoEchoRecord(record, baseline, substituted = []) {
39077
39173
  const list = coordinate.findIndex((segment) => typeof segment === "number");
39078
39174
  if (list < 0) return false;
39079
39175
  const path = coordinate.slice(0, list);
39080
- return canonicalJson$4(valueAtCoordinate(byIndex, path)) !== canonicalJson$4(valueAtCoordinate(baseline.properties, path));
39176
+ return canonicalJson$5(valueAtCoordinate(byIndex, path)) !== canonicalJson$5(valueAtCoordinate(baseline.properties, path));
39081
39177
  });
39082
39178
  const properties = reshaped.length === 0 ? byIndex : maskReadbackAtCoordinates(byIndex, baseline.properties, reshaped);
39083
39179
  const widened = reshaped.map((coordinate) => readbackPathFor(byIndex, baseline.properties, coordinate)).filter((path, i) => path !== void 0 && path.length < reshaped[i].length);
@@ -39191,6 +39287,355 @@ function refuseMaskedReplayBaseline(props, logicalId, inert = []) {
39191
39287
  throw new CdkdError(`Cannot roll ${shownLogicalId(logicalId)} back: its recorded baseline holds the redaction mask ('${"***"}'), so cdkd would write that literal to the live resource. There are five ways a baseline comes to hold it. (1) A NoEcho custom-resource value was resolved there: restore the property with 'cdkd deploy' AFTER forcing that custom resource to update (change one of its properties, e.g. a nonce), so its handler runs again and supplies the real value — an ordinary re-deploy leaves the resource unchanged, so the handler does not run and the mask stays. (2) The Fn::Base64 encoding of a secret value (a {{resolve:...}} dynamic reference under Fn::Base64, such as EC2 UserData), which cdkd never records: restore the property with a 'cdkd deploy' that changes this resource, which sends it the encoded value again — a re-deploy that leaves this resource unchanged sends it nothing. Every rollback to such a baseline refuses, so to end this, stop encoding the secret into the property (have the resource read the secret at run time instead — not by writing the secret's plaintext into the template, which cdkd would then record in state in the clear). (3) The value was SPLICED from a masked record of ANOTHER resource — by 'cdkd orphan --force', or by 'cdkd import' resolving an Fn::GetAtt or a Ref over a value the Cloud Control fallback had masked. Repair the record that HOLDS the mask ('cdkd import <stack> --resource <logicalId>=<physicalId> --force', granting cloudformation:DescribeType first if the import warned that it could not read the schema), then re-run whichever command wrote this property. (4) A NoEcho template parameter's value, which cdkd stores only as the mask: restore the property with 'cdkd deploy', which sends the parameter's value again. (5) Two secret values cdkd resolved overlap inside the value, so no single {{resolve:...}} reference renders it and cdkd stored the mask rather than part of a secret: restore the property with a 'cdkd deploy' that changes this resource, which sends it the value again. Every rollback to such a baseline refuses while the two values still overlap there, so to end this, change the property (or rotate one of the secrets) so that they no longer overlap. See https://github.com/go-to-k/cdkd/issues/2449.`, "ROLLBACK_REDACTED_BASELINE");
39192
39288
  }
39193
39289
 
39290
+ //#endregion
39291
+ //#region src/analyzer/drift-normalize.ts
39292
+ function canonicalizeTagListsDeep(v) {
39293
+ if (Array.isArray(v)) {
39294
+ const mapped = v.map(canonicalizeTagListsDeep);
39295
+ if (mapped.length > 0 && mapped.every((t) => t && typeof t === "object" && typeof t.Key === "string")) return [...mapped].sort((a, b) => {
39296
+ const ka = a.Key;
39297
+ const kb = b.Key;
39298
+ if (ka !== kb) return ka < kb ? -1 : 1;
39299
+ return JSON.stringify(a) < JSON.stringify(b) ? -1 : 1;
39300
+ });
39301
+ return mapped;
39302
+ }
39303
+ if (v && typeof v === "object") {
39304
+ if (!hasPlainPrototype$1(v)) return v;
39305
+ const out = nullPrototypeRecord();
39306
+ for (const [k, val] of Object.entries(v)) out[k] = canonicalizeTagListsDeep(val);
39307
+ return out;
39308
+ }
39309
+ return v;
39310
+ }
39311
+ const ID_RE = /^[a-z][a-z0-9]*-[0-9a-f]{6,}$/;
39312
+ const isIdLike = (s) => typeof s === "string" && (s.startsWith("arn:") || ID_RE.test(s));
39313
+ function canonicalizeIdArraysDeep(v) {
39314
+ if (Array.isArray(v)) {
39315
+ const mapped = v.map(canonicalizeIdArraysDeep);
39316
+ if (mapped.length > 1 && mapped.every(isIdLike)) return [...mapped].sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
39317
+ return mapped;
39318
+ }
39319
+ if (v && typeof v === "object") {
39320
+ if (!hasPlainPrototype$1(v)) return v;
39321
+ const out = nullPrototypeRecord();
39322
+ for (const [k, val] of Object.entries(v)) out[k] = canonicalizeIdArraysDeep(val);
39323
+ return out;
39324
+ }
39325
+ return v;
39326
+ }
39327
+ const LEAF_ONLY_PATH_SUFFIX = "[]";
39328
+ function matchesPathPrefix(path, entries) {
39329
+ for (const entry of entries) {
39330
+ if (entry.endsWith("[]")) {
39331
+ const leaf = entry.slice(0, -2);
39332
+ if (leaf !== "" && path === leaf) return true;
39333
+ continue;
39334
+ }
39335
+ if (path === entry) return true;
39336
+ if (path.startsWith(`${entry}.`)) return true;
39337
+ }
39338
+ return false;
39339
+ }
39340
+ function canonicalizeUnorderedArraysAtPaths(v, paths) {
39341
+ if (paths.length === 0) return v;
39342
+ return walkUnordered(v, "", paths);
39343
+ }
39344
+ function canonicalJson$2(v) {
39345
+ if (Array.isArray(v)) return `[${v.map(canonicalJson$2).join(",")}]`;
39346
+ if (v && typeof v === "object") {
39347
+ const bag = v;
39348
+ return `{${Object.keys(bag).filter((k) => bag[k] !== void 0).sort().map((k) => `${JSON.stringify(k)}:${canonicalJson$2(bag[k])}`).join(",")}}`;
39349
+ }
39350
+ return JSON.stringify(v) ?? "null";
39351
+ }
39352
+ const isPlainObjectElement = (el) => el !== null && typeof el === "object" && !Array.isArray(el);
39353
+ function walkUnordered(v, path, paths) {
39354
+ if (Array.isArray(v)) {
39355
+ const mapped = v.map((el) => Array.isArray(el) ? el : walkUnordered(el, path, paths));
39356
+ if (mapped.length > 1 && matchesPathPrefix(path, paths)) {
39357
+ if (mapped.every((el) => typeof el === "string")) return [...mapped].sort((a, b) => a < b ? -1 : a > b ? 1 : 0);
39358
+ if (mapped.every(isPlainObjectElement)) {
39359
+ const keyed = mapped.map((el) => ({
39360
+ el,
39361
+ key: canonicalJson$2(el)
39362
+ }));
39363
+ keyed.sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
39364
+ return keyed.map((k) => k.el);
39365
+ }
39366
+ }
39367
+ return mapped;
39368
+ }
39369
+ if (v && typeof v === "object") {
39370
+ if (!hasPlainPrototype$1(v)) return v;
39371
+ const out = nullPrototypeRecord();
39372
+ for (const [k, val] of Object.entries(v)) out[k] = walkUnordered(val, path === "" ? k : `${path}.${k}`, paths);
39373
+ return out;
39374
+ }
39375
+ return v;
39376
+ }
39377
+
39378
+ //#endregion
39379
+ //#region src/analyzer/drift-calculator.ts
39380
+ function calculateResourceDrift(stateProperties, awsProperties, options) {
39381
+ const drifts = [];
39382
+ const ignore = options?.ignorePaths ?? [];
39383
+ const union = options?.unionWalkObjects ?? false;
39384
+ const unordered = options?.unorderedPaths ?? [];
39385
+ stateProperties = canonicalizeUnorderedArraysAtPaths(canonicalizeIdArraysDeep(canonicalizeTagListsDeep(stateProperties)), unordered);
39386
+ awsProperties = canonicalizeUnorderedArraysAtPaths(canonicalizeIdArraysDeep(canonicalizeTagListsDeep(awsProperties)), unordered);
39387
+ for (const key of Object.keys(stateProperties)) {
39388
+ if (isIgnoredPath(key, ignore)) continue;
39389
+ diffAt(key, stateProperties[key], awsProperties[key], drifts, ignore, union);
39390
+ }
39391
+ return drifts;
39392
+ }
39393
+ function undeclaredEmptyObservedKeys(observed, declared) {
39394
+ const keys = [];
39395
+ for (const key of Object.keys(observed)) {
39396
+ if (Object.hasOwn(declared, key)) continue;
39397
+ const value = observed[key];
39398
+ if (value === null || value === void 0 || Array.isArray(value) && value.length === 0 || isPlainObject$5(value) && Object.keys(value).length === 0) keys.push(key);
39399
+ }
39400
+ return keys;
39401
+ }
39402
+ function isIgnoredPath(path, ignorePaths) {
39403
+ return matchesPathPrefix(path, ignorePaths);
39404
+ }
39405
+ function diffAt(path, stateValue, awsValue, out, ignorePaths, unionWalkObjects) {
39406
+ const stateForm = jsonForm(stateValue);
39407
+ const awsForm = jsonForm(awsValue);
39408
+ if (deepEqual$1(stateForm, awsForm)) return;
39409
+ if (typeof stateValue === "string" && stateValue.includes("{{resolve:")) return;
39410
+ if (isPlainObject$5(stateForm) && isPlainObject$5(awsForm) && !Array.isArray(stateForm) && !Array.isArray(awsForm)) {
39411
+ const keys = unionWalkObjects ? /* @__PURE__ */ new Set([...Object.keys(stateForm), ...Object.keys(awsForm)]) : Object.keys(stateForm);
39412
+ for (const key of keys) {
39413
+ const childPath = `${path}.${key}`;
39414
+ if (isIgnoredPath(childPath, ignorePaths)) continue;
39415
+ diffAt(childPath, stateForm[key], awsForm[key], out, ignorePaths, unionWalkObjects);
39416
+ }
39417
+ return;
39418
+ }
39419
+ out.push({
39420
+ path,
39421
+ stateValue,
39422
+ awsValue
39423
+ });
39424
+ }
39425
+ function jsonForm(value) {
39426
+ if (value === null || typeof value !== "object" || hasPlainPrototype$1(value)) return value;
39427
+ const toJSON = value.toJSON;
39428
+ return typeof toJSON === "function" ? toJSON.call(value) : value;
39429
+ }
39430
+ function deepEqual$1(a, b) {
39431
+ a = jsonForm(a);
39432
+ b = jsonForm(b);
39433
+ if (a === b) return true;
39434
+ if (a === null || b === null || a === void 0 || b === void 0) return a === b;
39435
+ if (typeof a !== typeof b) return false;
39436
+ if (typeof a !== "object") return false;
39437
+ if (Array.isArray(a) || Array.isArray(b)) {
39438
+ if (!Array.isArray(a) || !Array.isArray(b)) return false;
39439
+ if (a.length !== b.length) return false;
39440
+ return a.every((v, i) => deepEqual$1(v, b[i]));
39441
+ }
39442
+ const aObj = a;
39443
+ const bObj = b;
39444
+ const aKeys = Object.keys(aObj);
39445
+ const bKeys = Object.keys(bObj);
39446
+ if (aKeys.length !== bKeys.length) return false;
39447
+ for (const key of aKeys) {
39448
+ if (!Object.prototype.hasOwnProperty.call(bObj, key)) return false;
39449
+ if (!deepEqual$1(aObj[key], bObj[key])) return false;
39450
+ }
39451
+ return true;
39452
+ }
39453
+ function equalModuloMask(state, aws, mask) {
39454
+ const a = jsonForm(state);
39455
+ const b = jsonForm(aws);
39456
+ if (a === mask && b !== null && b !== void 0) return true;
39457
+ if (a === b) return true;
39458
+ if (a === null || b === null || a === void 0 || b === void 0) return a === b;
39459
+ if (typeof a !== typeof b || typeof a !== "object") return false;
39460
+ if (Array.isArray(a) || Array.isArray(b)) {
39461
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
39462
+ return a.every((v, i) => equalModuloMask(v, b[i], mask));
39463
+ }
39464
+ const aObj = a;
39465
+ const bObj = b;
39466
+ const aKeys = Object.keys(aObj);
39467
+ if (aKeys.length !== Object.keys(bObj).length) return false;
39468
+ return aKeys.every((key) => Object.prototype.hasOwnProperty.call(bObj, key) && equalModuloMask(aObj[key], bObj[key], mask));
39469
+ }
39470
+ function equalModuloMarkedMask(state, aws, mask, coordinate, isMarked, isWithinMarked = isMarked) {
39471
+ const a = jsonForm(state);
39472
+ const b = jsonForm(aws);
39473
+ if (isMarked(coordinate) && b !== void 0 && b !== null) {
39474
+ if (a === mask) return true;
39475
+ if (isWithinMarked(coordinate) ? isWhollyMask$1(a, mask) : sameJson(a, wholeMaskOf(b, mask))) return holdsMask(a, mask);
39476
+ }
39477
+ if (a === mask && (typeof b === "string" || typeof b === "number" || typeof b === "boolean")) return true;
39478
+ if (a === b) return true;
39479
+ if (a === null || b === null || a === void 0 || b === void 0) return a === b;
39480
+ if (typeof a !== typeof b || typeof a !== "object") return false;
39481
+ if (Array.isArray(a) || Array.isArray(b)) {
39482
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
39483
+ return a.every((v, i) => equalModuloMarkedMask(v, b[i], mask, [...coordinate, i], isMarked, isWithinMarked));
39484
+ }
39485
+ const aObj = a;
39486
+ const bObj = b;
39487
+ const aKeys = Object.keys(aObj);
39488
+ if (aKeys.length !== Object.keys(bObj).length) return false;
39489
+ return aKeys.every((key) => Object.prototype.hasOwnProperty.call(bObj, key) && equalModuloMarkedMask(aObj[key], bObj[key], mask, [...coordinate, key], isMarked, isWithinMarked));
39490
+ }
39491
+ function wholeMaskOf(value, mask) {
39492
+ if (value === null || value === void 0) return value;
39493
+ if (Array.isArray(value)) return value.map((v) => wholeMaskOf(v, mask));
39494
+ if (isPlainObject$5(value)) return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, wholeMaskOf(v, mask)]));
39495
+ return mask;
39496
+ }
39497
+ function isWhollyMask$1(value, mask) {
39498
+ const walk = (node) => {
39499
+ if (node === mask || node === null) return true;
39500
+ if (Array.isArray(node)) return node.every(walk);
39501
+ if (isPlainObject$5(node)) return Object.values(node).every(walk);
39502
+ return false;
39503
+ };
39504
+ return walk(value) && holdsMask(value, mask);
39505
+ }
39506
+ function holdsMask(value, mask) {
39507
+ if (value === mask) return true;
39508
+ if (Array.isArray(value)) return value.some((v) => holdsMask(v, mask));
39509
+ if (isPlainObject$5(value)) return Object.values(value).some((v) => holdsMask(v, mask));
39510
+ return false;
39511
+ }
39512
+ function sameJson(a, b) {
39513
+ if (a === b) return true;
39514
+ if (a === null || b === null || typeof a !== "object" || typeof b !== "object") return false;
39515
+ if (Array.isArray(a) || Array.isArray(b)) {
39516
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
39517
+ return a.every((v, i) => sameJson(v, b[i]));
39518
+ }
39519
+ const aObj = a;
39520
+ const bObj = b;
39521
+ const keys = Object.keys(aObj);
39522
+ return keys.length === Object.keys(bObj).length && keys.every((k) => Object.prototype.hasOwnProperty.call(bObj, k) && sameJson(aObj[k], bObj[k]));
39523
+ }
39524
+ function isPlainObject$5(value) {
39525
+ return typeof value === "object" && value !== null;
39526
+ }
39527
+
39528
+ //#endregion
39529
+ //#region src/deployment/unsettled-convergence.ts
39530
+ const MERGE_SEMANTICS_KEYS = /* @__PURE__ */ new Set(["Tags"]);
39531
+ async function readLive(args, names) {
39532
+ const { provider, physicalId, logicalId, resourceType, recordedProperties } = args;
39533
+ let live;
39534
+ if (provider.readUnsettled !== void 0) live = await provider.readUnsettled(physicalId, logicalId, resourceType, names, recordedProperties, args.desired);
39535
+ else if (provider.readCurrentState !== void 0) live = await provider.readCurrentState(physicalId, logicalId, resourceType, recordedProperties);
39536
+ else return;
39537
+ if (typeof live !== "object" || live === null || Array.isArray(live)) return "unreadable";
39538
+ return live;
39539
+ }
39540
+ function refusal(args, names, why) {
39541
+ const list = [...names].sort().join(", ");
39542
+ return new ProvisioningError(`${args.logicalId} (${args.resourceType}): an earlier failed update left ${list} unsettled, and ${why} — nothing was updated. Re-run the deploy once the resource has settled` + (args.provider.readCurrentState !== void 0 ? ", or, to keep what AWS holds instead, run 'cdkd drift --accept' once it has." : "."), args.resourceType, args.logicalId, args.physicalId);
39543
+ }
39544
+ async function settleUnsettledPrevious(args) {
39545
+ const { names, previous, provider } = args;
39546
+ if (names.size === 0) return previous;
39547
+ if (provider.unsettledInTransition !== void 0) {
39548
+ const moving = await provider.unsettledInTransition(args.physicalId, args.logicalId, args.resourceType, names, args.recordedProperties);
39549
+ if (moving.size > 0) throw refusal(args, moving, "AWS is still changing it or cdkd could not confirm it settled");
39550
+ }
39551
+ const substituted = new Set([...names].filter((name) => !MERGE_SEMANTICS_KEYS.has(name)));
39552
+ if (substituted.size === 0) return previous;
39553
+ let live;
39554
+ try {
39555
+ live = await readLive(args, substituted);
39556
+ } catch (error) {
39557
+ if (error instanceof ProvisioningError) throw error;
39558
+ const wrapped = refusal(args, substituted, "the resource could not be read to converge it");
39559
+ if (error instanceof Error) wrapped.cause = error;
39560
+ throw wrapped;
39561
+ }
39562
+ if (live === void 0) return previous;
39563
+ if (live === "unreadable") throw refusal(args, substituted, "the resource could not be read to converge it");
39564
+ const out = { ...previous };
39565
+ for (const name of substituted) if (Object.hasOwn(live, name) && live[name] !== void 0) out[name] = live[name];
39566
+ else delete out[name];
39567
+ return out;
39568
+ }
39569
+ function tagsHeld(desired, live) {
39570
+ const asMap = (value) => {
39571
+ if (value === void 0 || value === null) return /* @__PURE__ */ new Map();
39572
+ if (Array.isArray(value)) {
39573
+ const map = /* @__PURE__ */ new Map();
39574
+ for (const entry of value) {
39575
+ if (typeof entry !== "object" || entry === null) return void 0;
39576
+ const { Key, Value } = entry;
39577
+ if (typeof Key !== "string") return void 0;
39578
+ map.set(Key, Value);
39579
+ }
39580
+ return map;
39581
+ }
39582
+ if (typeof value === "object") return new Map(Object.entries(value));
39583
+ };
39584
+ const want = asMap(desired);
39585
+ const have = asMap(live);
39586
+ if (want === void 0 || have === void 0) return false;
39587
+ for (const [key, value] of want) if (!have.has(key) || JSON.stringify(have.get(key)) !== JSON.stringify(value)) return false;
39588
+ return true;
39589
+ }
39590
+ async function unsettledAfterUpdate(args) {
39591
+ const { names, desired, provider } = args;
39592
+ if (names.size === 0) return [];
39593
+ try {
39594
+ const moving = provider.unsettledInTransition === void 0 ? /* @__PURE__ */ new Set() : await provider.unsettledInTransition(args.physicalId, args.logicalId, args.resourceType, names, args.recordedProperties);
39595
+ const live = await readLive(args, names);
39596
+ if (live === void 0) return [...moving].sort();
39597
+ if (live === "unreadable") return [...names].sort();
39598
+ const ignorePaths = provider.getDriftUnknownPaths?.(args.resourceType) ?? [];
39599
+ const unorderedPaths = provider.getDriftUnorderedPaths?.(args.resourceType) ?? [];
39600
+ const kept = [];
39601
+ for (const name of names) {
39602
+ if (moving.has(name)) {
39603
+ kept.push(name);
39604
+ continue;
39605
+ }
39606
+ if (MERGE_SEMANTICS_KEYS.has(name)) {
39607
+ if (!tagsHeld(desired[name], live[name])) kept.push(name);
39608
+ continue;
39609
+ }
39610
+ if (!Object.hasOwn(live, name) || desired[name] === void 0) continue;
39611
+ if (calculateResourceDrift({ [name]: desired[name] }, { [name]: live[name] }, {
39612
+ ignorePaths,
39613
+ unorderedPaths
39614
+ }).length > 0) kept.push(name);
39615
+ }
39616
+ return kept.sort();
39617
+ } catch {
39618
+ return [...names].sort();
39619
+ }
39620
+ }
39621
+ async function withUnprovenUnsettled(record, args, warn) {
39622
+ const kept = await unsettledAfterUpdate(args);
39623
+ if (kept.length === 0) return record;
39624
+ warn(safeMsg`${args.logicalId} (${args.resourceType}): the update succeeded, but AWS does not yet show the requested ${kept.join(", ")}; cdkd keeps ${kept.length === 1 ? "it" : "them"} unsettled and converges again on the next deploy.`);
39625
+ return withUnsettledProperties(record, kept);
39626
+ }
39627
+ function splitUnhandledRemovals(unhandled, recordedPrevious, unsettled) {
39628
+ const addedByFailedUpdate = unhandled.filter((name) => unsettled.has(name) && !Object.hasOwn(recordedPrevious, name));
39629
+ return {
39630
+ removedFromTemplate: unhandled.filter((name) => !addedByFailedUpdate.includes(name)),
39631
+ addedByFailedUpdate
39632
+ };
39633
+ }
39634
+ function addedByFailedUpdateWarning(logicalId, resourceType, names) {
39635
+ const one = names.length === 1;
39636
+ return safeMsg`${logicalId} (${resourceType}): ${one ? "property" : "properties"} ${names.join(", ")} ${one ? "is" : "are"} set on the resource but in no template: an earlier failed update applied ${one ? "it" : "them"}. cdkd has no default to reset ${one ? "it" : "them"} to, so the value stays; remove it by hand if it should not be there.`;
39637
+ }
39638
+
39194
39639
  //#endregion
39195
39640
  //#region src/deployment/rollback-executor/replay-retry.ts
39196
39641
  const RECREATE_RETRY_SCHEDULE = {
@@ -39199,7 +39644,17 @@ const RECREATE_RETRY_SCHEDULE = {
39199
39644
  maxDelayMs: 1e4
39200
39645
  };
39201
39646
  async function updateWithRollbackRetry(provider, args, logicalId, logger, isInterrupted, secrets, mask) {
39202
- const [, , resourceType, desired, previous, context] = args;
39647
+ const [, , resourceType, desired, recordedPrevious, context] = args;
39648
+ const previous = await settleUnsettledPrevious({
39649
+ provider,
39650
+ logicalId: args[0],
39651
+ physicalId: args[1],
39652
+ resourceType,
39653
+ recordedProperties: recordedPrevious,
39654
+ names: context?.unsettledProperties ?? /* @__PURE__ */ new Set(),
39655
+ previous: recordedPrevious,
39656
+ desired
39657
+ });
39203
39658
  const removal = prepareRemovalForUpdate(provider, resourceType, desired, previous);
39204
39659
  const revertArgs = [
39205
39660
  args[0],
@@ -39213,7 +39668,9 @@ async function updateWithRollbackRetry(provider, args, logicalId, logger, isInte
39213
39668
  }
39214
39669
  ];
39215
39670
  const recorded = (result) => {
39216
- if (removal.unhandled.length > 0) logger.warn(mask(removalWarning(logicalId, resourceType, removal.unhandled, "rollback")));
39671
+ const unhandledByCause = splitUnhandledRemovals(removal.unhandled, recordedPrevious, context?.unsettledProperties ?? /* @__PURE__ */ new Set());
39672
+ if (unhandledByCause.removedFromTemplate.length > 0) logger.warn(mask(removalWarning(logicalId, resourceType, unhandledByCause.removedFromTemplate, "rollback")));
39673
+ if (unhandledByCause.addedByFailedUpdate.length > 0) logger.warn(mask(addedByFailedUpdateWarning(logicalId, resourceType, unhandledByCause.addedByFailedUpdate)));
39217
39674
  return result === void 0 ? void 0 : withoutInjectedRemovals(result, removal.injected);
39218
39675
  };
39219
39676
  if (provider.disableOuterRetry) return recorded(await withCurrentResourceSecrets(secrets, () => provider.update(...revertArgs)));
@@ -39246,6 +39703,9 @@ async function createWithRollbackRetry(provider, create, logicalId, logger, isIn
39246
39703
  });
39247
39704
  }
39248
39705
  function recordAfterRollbackUpdate(restored, result) {
39706
+ return withoutUnsettledProperties(recordAfterRollbackUpdateUnsettled(restored, result));
39707
+ }
39708
+ function recordAfterRollbackUpdateUnsettled(restored, result) {
39249
39709
  if (result === void 0) return restored;
39250
39710
  const returned = result.attributes;
39251
39711
  const replacedId = result.wasReplaced && typeof result.physicalId === "string" && result.physicalId !== "" ? result.physicalId : void 0;
@@ -39537,12 +39997,22 @@ async function replayRevert(s) {
39537
39997
  expectedRegion: ctx.region,
39538
39998
  replayingState: true,
39539
39999
  recordedAttributes: current.attributes,
39540
- ...revertClaimed && { inlinePolicyClaimed: revertClaimed }
40000
+ ...revertClaimed && { inlinePolicyClaimed: revertClaimed },
40001
+ ...unsettledContextOf(current, previousState)
39541
40002
  }
39542
40003
  ], op.logicalId, logger, isInterrupted, secrets, mask));
39543
40004
  if (revertResult) recordNoEchoAttributeValues(revertResult, secrets, desiredProps);
39544
40005
  stateResources[op.logicalId] = maskRestoredNoEchoRecord(redactRollbackRecord(recordAfterRollbackUpdate(previousState, revertResult), secrets, previousState.properties, previousState.attributes), previousState, noEcho.substituted);
39545
- if (updatePartialReason(revertResult) === void 0) inlinePolicyWriters.record(op.logicalId, "update", stateResources[op.logicalId], !deepEqual$1(previousState.properties?.["Policies"], current.properties?.["Policies"]), revertVia);
40006
+ stateResources[op.logicalId] = await withUnprovenUnsettled(stateResources[op.logicalId], {
40007
+ provider,
40008
+ logicalId: op.logicalId,
40009
+ physicalId: current.physicalId,
40010
+ resourceType: op.resourceType,
40011
+ recordedProperties: current.properties ?? {},
40012
+ names: unsettledContextOf(current, previousState).unsettledProperties ?? /* @__PURE__ */ new Set(),
40013
+ desired: desiredProps ?? {}
40014
+ }, (message) => logger.warn(mask(message)));
40015
+ if (updatePartialReason(revertResult) === void 0) inlinePolicyWriters.record(op.logicalId, "update", stateResources[op.logicalId], !deepEqual$2(previousState.properties?.["Policies"], current.properties?.["Policies"]), revertVia);
39546
40016
  const rollbackPartial = updatePartialReason(revertResult);
39547
40017
  if (rollbackPartial !== void 0) logger.warn(mask(` Rollback: ${safe(op.logicalId)} restored, ${updatePartialMessage(rollbackPartial)}`));
39548
40018
  else logger.info(` Rollback: ${safe(op.logicalId)} restored successfully`);
@@ -40484,12 +40954,22 @@ async function replayFailedOperationsUnbound(failedOps, stateResources, stackNam
40484
40954
  expectedRegion: ctx.region,
40485
40955
  replayingState: true,
40486
40956
  recordedAttributes: current.attributes,
40487
- ...revertFailedClaimed && { inlinePolicyClaimed: revertFailedClaimed }
40957
+ ...revertFailedClaimed && { inlinePolicyClaimed: revertFailedClaimed },
40958
+ ...unsettledContextOf(current, prev)
40488
40959
  }
40489
40960
  ], op.logicalId, logger, options.isInterrupted, secrets, mask));
40490
40961
  if (revertFailedResult) recordNoEchoAttributeValues(revertFailedResult, secrets, desiredProps);
40491
40962
  stateResources[op.logicalId] = maskRestoredNoEchoRecord(redactRollbackRecord(withNameGenerationReached(recordAfterRollbackUpdate(prev, revertFailedResult), op.logicalId, op.nameGeneration), secrets, prev.properties, prev.attributes), prev, noEcho.substituted);
40492
- if (updatePartialReason(revertFailedResult) === void 0) inlinePolicyWriters.record(op.logicalId, "update", stateResources[op.logicalId], !deepEqual$1(prev.properties?.["Policies"], (op.attemptedProperties ?? current.properties)?.["Policies"]), revertVia);
40963
+ stateResources[op.logicalId] = await withUnprovenUnsettled(stateResources[op.logicalId], {
40964
+ provider,
40965
+ logicalId: op.logicalId,
40966
+ physicalId: current.physicalId,
40967
+ resourceType: op.resourceType,
40968
+ recordedProperties: current.properties ?? {},
40969
+ names: unsettledContextOf(current, prev).unsettledProperties ?? /* @__PURE__ */ new Set(),
40970
+ desired: desiredProps ?? {}
40971
+ }, (message) => logger.warn(mask(message)));
40972
+ if (updatePartialReason(revertFailedResult) === void 0) inlinePolicyWriters.record(op.logicalId, "update", stateResources[op.logicalId], !deepEqual$2(prev.properties?.["Policies"], (op.attemptedProperties ?? current.properties)?.["Policies"]), revertVia);
40493
40973
  const revertFailedPartial = updatePartialReason(revertFailedResult);
40494
40974
  if (revertFailedPartial !== void 0) logger.warn(mask(` Rollback: ${safe(op.logicalId)} reverted, ${updatePartialMessage(revertFailedPartial)}`));
40495
40975
  else logger.info(` Rollback: ${safe(op.logicalId)} reverted successfully`);
@@ -42403,7 +42883,7 @@ async function revertNestedChildFromJournal(args) {
42403
42883
  ...carried,
42404
42884
  ...stackInstanceIdCarriedFrom(base),
42405
42885
  ...supersededAfterRollback(base, supersededHost),
42406
- version: 13,
42886
+ version: 14,
42407
42887
  region,
42408
42888
  resources: { ...stateResources },
42409
42889
  ...orphansAfterRollback(base, mintedOrphans),
@@ -44546,7 +45026,7 @@ function stdoutSupportsColor(env = process.env, argv = process.argv, isTTY = pro
44546
45026
  //#endregion
44547
45027
  //#region src/analyzer/security-diff.ts
44548
45028
  function isSyntheticChange(pc) {
44549
- return pc.replacementPropagated === true || pc.inPlacePropagated === true || pc.noEchoPromoted === true;
45029
+ return pc.replacementPropagated === true || pc.inPlacePropagated === true || pc.noEchoPromoted === true || pc.unsettled === true;
44550
45030
  }
44551
45031
  function withChanges(base, changes, side) {
44552
45032
  const props = { ...base ?? {} };
@@ -44926,18 +45406,18 @@ function conditionInputsFrom(args) {
44926
45406
  };
44927
45407
  }
44928
45408
  const FINGERPRINT_LAYOUT = 1;
44929
- function isPlainObject$3(value) {
45409
+ function isPlainObject$4(value) {
44930
45410
  return value !== null && typeof value === "object" && !Array.isArray(value);
44931
45411
  }
44932
45412
  function canonicalJson$1(value) {
44933
45413
  if (Array.isArray(value)) return `[${value.map(canonicalJson$1).join(",")}]`;
44934
- if (isPlainObject$3(value)) return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson$1(value[key])}`).join(",")}}`;
45414
+ if (isPlainObject$4(value)) return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson$1(value[key])}`).join(",")}}`;
44935
45415
  const encoded = JSON.stringify(value);
44936
45416
  return encoded === void 0 ? "undefined" : encoded;
44937
45417
  }
44938
45418
  function walkModelledDefinition(value, declaredParameters, parameters, conditions) {
44939
45419
  if (typeof value === "string") return !carriesDynamicReference(value);
44940
- if (!isPlainObject$3(value)) return false;
45420
+ if (!isPlainObject$4(value)) return false;
44941
45421
  const keys = Object.keys(value);
44942
45422
  if (keys.length !== 1) return false;
44943
45423
  const [key] = keys;
@@ -44960,8 +45440,8 @@ function walkModelledDefinition(value, declaredParameters, parameters, condition
44960
45440
  }
44961
45441
  function conditionFingerprint(template, name, inputOf) {
44962
45442
  const definitions = template.Conditions;
44963
- if (!isPlainObject$3(definitions)) return void 0;
44964
- const declared = isPlainObject$3(template.Parameters) ? template.Parameters : {};
45443
+ if (!isPlainObject$4(definitions)) return void 0;
45444
+ const declared = isPlainObject$4(template.Parameters) ? template.Parameters : {};
44965
45445
  const declaredNames = new Set(Object.keys(declared));
44966
45446
  const closure = nullPrototypeRecord();
44967
45447
  const parameters = /* @__PURE__ */ new Set();
@@ -44983,7 +45463,7 @@ function conditionFingerprint(template, name, inputOf) {
44983
45463
  let hasToken = false;
44984
45464
  for (const parameter of parameters) {
44985
45465
  const definition = declared[parameter];
44986
- const type = isPlainObject$3(definition) ? definition["Type"] : void 0;
45466
+ const type = isPlainObject$4(definition) ? definition["Type"] : void 0;
44987
45467
  if (typeof type !== "string") return void 0;
44988
45468
  const input = inputOf(parameter);
44989
45469
  if (input === void 0) return void 0;
@@ -45014,7 +45494,7 @@ function collectIfConditionNames(value, names, conditions) {
45014
45494
  for (const element of value) collectIfConditionNames(element, names, conditions);
45015
45495
  return;
45016
45496
  }
45017
- if (!isPlainObject$3(value)) return;
45497
+ if (!isPlainObject$4(value)) return;
45018
45498
  const ifArgs = value["Fn::If"];
45019
45499
  if (Array.isArray(ifArgs) && typeof ifArgs[0] === "string") {
45020
45500
  names.add(ifArgs[0]);
@@ -45028,9 +45508,9 @@ function collectIfConditionNames(value, names, conditions) {
45028
45508
  function conditionsReadByDiff(template, conditions) {
45029
45509
  const names = /* @__PURE__ */ new Set();
45030
45510
  for (const section of [template.Resources, template.Outputs]) {
45031
- if (!isPlainObject$3(section)) continue;
45511
+ if (!isPlainObject$4(section)) continue;
45032
45512
  for (const entry of Object.values(section)) {
45033
- if (!isPlainObject$3(entry)) continue;
45513
+ if (!isPlainObject$4(entry)) continue;
45034
45514
  const gate = entry["Condition"];
45035
45515
  if (typeof gate === "string") {
45036
45516
  names.add(gate);
@@ -45062,10 +45542,10 @@ function buildConditionVerdictRecord(template, conditions, inputOf) {
45062
45542
  function readRecordedConditionVerdicts(state) {
45063
45543
  const read = nullPrototypeRecord();
45064
45544
  const field = state?.conditionVerdicts;
45065
- if (!isPlainObject$3(field)) return read;
45545
+ if (!isPlainObject$4(field)) return read;
45066
45546
  for (const name of Object.keys(field)) {
45067
45547
  const entry = field[name];
45068
- if (isPlainObject$3(entry) && typeof entry["verdict"] === "boolean" && typeof entry["fingerprint"] === "string") read[name] = {
45548
+ if (isPlainObject$4(entry) && typeof entry["verdict"] === "boolean" && typeof entry["fingerprint"] === "string") read[name] = {
45069
45549
  verdict: entry["verdict"],
45070
45550
  fingerprint: entry["fingerprint"]
45071
45551
  };
@@ -45111,11 +45591,11 @@ function deployConditionInputs(parameterValues, inheritedSecrets, shadowedBy = /
45111
45591
  function parentSuppliedValues(template, supplied, tokens) {
45112
45592
  const names = /* @__PURE__ */ new Set();
45113
45593
  if (supplied === void 0) return names;
45114
- const declared = isPlainObject$3(template.Parameters) ? template.Parameters : {};
45594
+ const declared = isPlainObject$4(template.Parameters) ? template.Parameters : {};
45115
45595
  for (const [name, value] of Object.entries(supplied)) {
45116
45596
  if (tokens.has(name)) continue;
45117
45597
  const definition = declared[name];
45118
- const fallback = isPlainObject$3(definition) ? definition["Default"] : void 0;
45598
+ const fallback = isPlainObject$4(definition) ? definition["Default"] : void 0;
45119
45599
  if (fallback === void 0 || String(fallback) !== String(value)) names.add(name);
45120
45600
  }
45121
45601
  return names;
@@ -45450,7 +45930,7 @@ function deferredServiceTokenWarning(row) {
45450
45930
 
45451
45931
  //#endregion
45452
45932
  //#region src/deployment/read-provenance-sources.ts
45453
- function isPlainObject$2(value) {
45933
+ function isPlainObject$3(value) {
45454
45934
  return value !== null && typeof value === "object" && !Array.isArray(value);
45455
45935
  }
45456
45936
  function crossStackNodes(value, into = []) {
@@ -45458,7 +45938,7 @@ function crossStackNodes(value, into = []) {
45458
45938
  for (const item of value) crossStackNodes(item, into);
45459
45939
  return into;
45460
45940
  }
45461
- if (!isPlainObject$2(value)) return into;
45941
+ if (!isPlainObject$3(value)) return into;
45462
45942
  const keys = Object.keys(value);
45463
45943
  if (keys.length === 1 && (keys[0] === "Fn::ImportValue" || keys[0] === "Fn::GetStackOutput")) into.push(value);
45464
45944
  for (const item of Object.values(value)) crossStackNodes(item, into);
@@ -45482,11 +45962,11 @@ function crossStackOutputProvenanceSource(reads, scope, stateBackend) {
45482
45962
  function inheritedProvenanceForChildDiff(args) {
45483
45963
  const { row, rowRecord, parentRecords, parentTemplate } = args;
45484
45964
  if (!args.rowProvisioned || rowRecord === void 0) return void 0;
45485
- const recordedParameters = isPlainObject$2(rowRecord.properties) ? rowRecord.properties["Parameters"] : void 0;
45965
+ const recordedParameters = isPlainObject$3(rowRecord.properties) ? rowRecord.properties["Parameters"] : void 0;
45486
45966
  const tokens = referenceTokensIn(recordedParameters);
45487
45967
  if (tokens.size === 0) return void 0;
45488
45968
  const own = referenceProvenanceOf(rowRecord);
45489
- const upstreams = [...new TemplateParser().extractReferences(isPlainObject$2(row.Properties) ? row.Properties["Parameters"] : void 0)].filter((id) => Object.hasOwn(parentTemplate.Resources, id) && Object.hasOwn(parentRecords, id));
45969
+ const upstreams = [...new TemplateParser().extractReferences(isPlainObject$3(row.Properties) ? row.Properties["Parameters"] : void 0)].filter((id) => Object.hasOwn(parentTemplate.Resources, id) && Object.hasOwn(parentRecords, id));
45490
45970
  const out = /* @__PURE__ */ new Map();
45491
45971
  for (const token of tokens) {
45492
45972
  const versions = /* @__PURE__ */ new Set();
@@ -46720,7 +47200,10 @@ const CI_PATH = `Replicas[].${CONTRIBUTOR_INSIGHTS_KEY}`;
46720
47200
  const KINESIS_PATH = `Replicas[].${KINESIS_KEY}`;
46721
47201
  const TABLE_POLICY_PATH = `Replicas[].${TABLE_POLICY_KEY}`;
46722
47202
  const STREAM_POLICY_PATH = `Replicas[].${REPLICA_STREAM_KEY}.ResourcePolicy`;
46723
- function isPlainObject$1(value) {
47203
+ const INDEX_CI_PATH = `Replicas[].${INDEX_CONTRIBUTOR_INSIGHTS_PATH}`;
47204
+ const STREAM_TAGS_PATH = `Replicas[].${REPLICA_STREAM_KEY}.Tags`;
47205
+ const REPLICA_INDEXES_KEY = "GlobalSecondaryIndexes";
47206
+ function isPlainObject$2(value) {
46724
47207
  return typeof value === "object" && value !== null && !Array.isArray(value);
46725
47208
  }
46726
47209
  function readPitrSpec(value) {
@@ -46767,7 +47250,7 @@ function readKinesisSpec(value) {
46767
47250
  }
46768
47251
  function readPolicyBlock(value, path) {
46769
47252
  if (value === void 0 || value === null) return { kind: "absent" };
46770
- if (!isPlainObject$1(value)) return {
47253
+ if (!isPlainObject$2(value)) return {
46771
47254
  kind: "unusable",
46772
47255
  reason: `${path} must be an object with a PolicyDocument`
46773
47256
  };
@@ -46779,7 +47262,7 @@ function readPolicyBlock(value, path) {
46779
47262
  kind: "usable",
46780
47263
  document
46781
47264
  };
46782
- if (!isPlainObject$1(document)) return {
47265
+ if (!isPlainObject$2(document)) return {
46783
47266
  kind: "unusable",
46784
47267
  reason: `${path}.PolicyDocument must be a policy object or a JSON string`
46785
47268
  };
@@ -46799,20 +47282,49 @@ function readTablePolicy(replica) {
46799
47282
  function readStreamPolicy$1(replica) {
46800
47283
  const stream = replica?.[REPLICA_STREAM_KEY];
46801
47284
  if (stream === void 0 || stream === null) return { kind: "absent" };
46802
- if (!isPlainObject$1(stream)) return {
47285
+ if (!isPlainObject$2(stream)) return {
46803
47286
  kind: "unusable",
46804
47287
  reason: `Replicas[].${REPLICA_STREAM_KEY} must be an object`
46805
47288
  };
46806
47289
  return readPolicyBlock(stream["ResourcePolicy"], STREAM_POLICY_PATH);
46807
47290
  }
47291
+ function readStreamTags$1(replica) {
47292
+ const stream = replica?.[REPLICA_STREAM_KEY];
47293
+ if (stream === void 0 || stream === null) return {
47294
+ kind: "tags",
47295
+ tags: []
47296
+ };
47297
+ if (!isPlainObject$2(stream)) return {
47298
+ kind: "unusable",
47299
+ reason: `Replicas[].${REPLICA_STREAM_KEY} must be an object`
47300
+ };
47301
+ const read = readTagList(stream["Tags"], "desired");
47302
+ return read.kind === "tags" ? {
47303
+ kind: "tags",
47304
+ tags: read.tags
47305
+ } : {
47306
+ kind: "unusable",
47307
+ reason: `${STREAM_TAGS_PATH} must be a list of tags with a non-empty string Key and a scalar Value`
47308
+ };
47309
+ }
47310
+ function replicaIndexInsightsRefusals(replica) {
47311
+ const indexes = replica?.[REPLICA_INDEXES_KEY];
47312
+ if (!Array.isArray(indexes)) return [];
47313
+ return indexes.flatMap((entry, position) => {
47314
+ if (!isPlainObject$2(entry)) return [];
47315
+ const read = readContributorInsightsSpec(entry[CONTRIBUTOR_INSIGHTS_KEY], `Replicas[].${REPLICA_INDEXES_KEY}[${position}].${CONTRIBUTOR_INSIGHTS_KEY}`);
47316
+ return read.kind === "unusable" ? [read.reason] : [];
47317
+ });
47318
+ }
46808
47319
  function replicaSettingRefusals(replica) {
46809
- return [
47320
+ return [...[
46810
47321
  readPitrSpec(replica?.[PITR_KEY]),
46811
47322
  readContributorInsightsSpec(replica?.[CONTRIBUTOR_INSIGHTS_KEY], CI_PATH),
46812
47323
  readKinesisSpec(replica?.[KINESIS_KEY]),
46813
47324
  readTablePolicy(replica),
46814
- readStreamPolicy$1(replica)
46815
- ].flatMap((read) => read.kind === "unusable" ? [read.reason] : []);
47325
+ readStreamPolicy$1(replica),
47326
+ readStreamTags$1(replica)
47327
+ ].flatMap((read) => read.kind === "unusable" ? [read.reason] : []), ...replicaIndexInsightsRefusals(replica)];
46816
47328
  }
46817
47329
  function settingOf(op) {
46818
47330
  switch (op.kind) {
@@ -46825,6 +47337,9 @@ function settingOf(op) {
46825
47337
  case "putTablePolicy": return "tablePolicy";
46826
47338
  case "deleteStreamPolicy":
46827
47339
  case "putStreamPolicy": return "streamPolicy";
47340
+ case "indexContributorInsights": return "indexContributorInsights";
47341
+ case "untagStream":
47342
+ case "tagStream": return "streamTags";
46828
47343
  }
46829
47344
  }
46830
47345
  const SETTING_MEMBER = {
@@ -46832,7 +47347,9 @@ const SETTING_MEMBER = {
46832
47347
  contributorInsights: CONTRIBUTOR_INSIGHTS_KEY,
46833
47348
  kinesis: KINESIS_KEY,
46834
47349
  tablePolicy: TABLE_POLICY_KEY,
46835
- streamPolicy: `${REPLICA_STREAM_KEY}.ResourcePolicy`
47350
+ streamPolicy: `${REPLICA_STREAM_KEY}.ResourcePolicy`,
47351
+ indexContributorInsights: INDEX_CONTRIBUTOR_INSIGHTS_PATH,
47352
+ streamTags: `${REPLICA_STREAM_KEY}.Tags`
46836
47353
  };
46837
47354
  function samePolicyDocument$1(left, right) {
46838
47355
  if (left === right) return true;
@@ -46929,6 +47446,51 @@ function planReplicaSettingOps(desired, previous, options, onUnusable) {
46929
47446
  kind: "putStreamPolicy",
46930
47447
  document
46931
47448
  }), { kind: "deleteStreamPolicy" }, "streamPolicy");
47449
+ if (options.tableIndexNames !== void 0) ops.push(...planReplicaIndexInsightsOps(desired, previous, {
47450
+ fresh: options.fresh,
47451
+ tableIndexNames: options.tableIndexNames,
47452
+ removes
47453
+ }, onUnusable));
47454
+ const wantTags = readStreamTags$1(desired);
47455
+ if (wantTags.kind === "unusable") onUnusable(wantTags.reason);
47456
+ else {
47457
+ const hadTags = options.streamReplaced === true ? {
47458
+ kind: "tags",
47459
+ tags: []
47460
+ } : readStreamTags$1(prev);
47461
+ const plan = planTagDiff(hadTags.kind === "tags" ? hadTags.tags : [], wantTags.tags);
47462
+ if (plan.remove.length > 0 && removes("streamTags")) ops.push({
47463
+ kind: "untagStream",
47464
+ keys: plan.remove
47465
+ });
47466
+ if (plan.set.size > 0) ops.push({
47467
+ kind: "tagStream",
47468
+ tags: [...plan.set].map(([Key, Value]) => ({
47469
+ Key,
47470
+ Value
47471
+ }))
47472
+ });
47473
+ }
47474
+ return ops;
47475
+ }
47476
+ function planReplicaIndexInsightsOps(desired, previous, options, onUnusable) {
47477
+ const prev = options.fresh ? void 0 : previous;
47478
+ const ops = [];
47479
+ const desiredIndexes = indexEntriesByName(desired?.[REPLICA_INDEXES_KEY]);
47480
+ const prevIndexes = indexEntriesByName(prev?.[REPLICA_INDEXES_KEY]);
47481
+ for (const indexName of /* @__PURE__ */ new Set([...desiredIndexes.keys(), ...prevIndexes.keys()])) {
47482
+ if (!options.tableIndexNames.has(indexName)) continue;
47483
+ const want = readContributorInsightsSpec(desiredIndexes.get(indexName)?.[CONTRIBUTOR_INSIGHTS_KEY], INDEX_CI_PATH);
47484
+ const op = planContributorInsightsOp(want, readContributorInsightsSpec(prevIndexes.get(indexName)?.[CONTRIBUTOR_INSIGHTS_KEY], INDEX_CI_PATH), onUnusable);
47485
+ if (op === void 0) continue;
47486
+ if (options.fresh && op.action === "DISABLE") continue;
47487
+ if (want.kind === "absent" && !options.removes("indexContributorInsights")) continue;
47488
+ ops.push({
47489
+ kind: "indexContributorInsights",
47490
+ indexName,
47491
+ ...op
47492
+ });
47493
+ }
46932
47494
  return ops;
46933
47495
  }
46934
47496
  function planReplicaSettingCorrections(desired, live, only) {
@@ -46975,8 +47537,43 @@ function planReplicaSettingCorrections(desired, live, only) {
46975
47537
  kind: "putStreamPolicy",
46976
47538
  document: streamPolicy.document
46977
47539
  });
47540
+ if (only.has("indexContributorInsights") && live.indexContributorInsightsEnabled !== void 0) for (const [indexName, entry] of declaredIndexInsights(desired)) {
47541
+ const enabled = live.indexContributorInsightsEnabled.get(indexName);
47542
+ if (enabled === void 0 || enabled === entry.enabled) continue;
47543
+ ops.push(!entry.enabled ? {
47544
+ kind: "indexContributorInsights",
47545
+ indexName,
47546
+ action: "DISABLE"
47547
+ } : entry.mode === void 0 ? {
47548
+ kind: "indexContributorInsights",
47549
+ indexName,
47550
+ action: "ENABLE"
47551
+ } : {
47552
+ kind: "indexContributorInsights",
47553
+ indexName,
47554
+ action: "ENABLE",
47555
+ mode: entry.mode
47556
+ });
47557
+ }
47558
+ const streamTags = readStreamTags$1(desired);
47559
+ if (only.has("streamTags") && streamTags.kind === "tags" && live.streamTags !== void 0) {
47560
+ const liveTags = live.streamTags;
47561
+ const missing = streamTags.tags.filter((t) => liveTags.get(t.Key) !== t.Value);
47562
+ if (missing.length > 0) ops.push({
47563
+ kind: "tagStream",
47564
+ tags: missing
47565
+ });
47566
+ }
46978
47567
  return ops;
46979
47568
  }
47569
+ function declaredIndexInsights(desired) {
47570
+ const out = /* @__PURE__ */ new Map();
47571
+ for (const [indexName, entry] of indexEntriesByName(desired?.[REPLICA_INDEXES_KEY])) {
47572
+ const read = readContributorInsightsSpec(entry[CONTRIBUTOR_INSIGHTS_KEY], INDEX_CI_PATH);
47573
+ if (read.kind === "usable") out.set(indexName, read);
47574
+ }
47575
+ return out;
47576
+ }
46980
47577
  function declaredReplicaSettings(desired) {
46981
47578
  const declared = /* @__PURE__ */ new Set();
46982
47579
  if (readPitrSpec(desired?.["PointInTimeRecoverySpecification"]).kind === "usable") declared.add("pitr");
@@ -46984,6 +47581,9 @@ function declaredReplicaSettings(desired) {
46984
47581
  if (readKinesisSpec(desired?.["KinesisStreamSpecification"]).kind === "usable") declared.add("kinesis");
46985
47582
  if (readTablePolicy(desired).kind === "usable") declared.add("tablePolicy");
46986
47583
  if (readStreamPolicy$1(desired).kind === "usable") declared.add("streamPolicy");
47584
+ if (declaredIndexInsights(desired).size > 0) declared.add("indexContributorInsights");
47585
+ const tags = readStreamTags$1(desired);
47586
+ if (tags.kind === "tags" && tags.tags.length > 0) declared.add("streamTags");
46987
47587
  return declared;
46988
47588
  }
46989
47589
  function enabledForReadStatus(status) {
@@ -47030,7 +47630,7 @@ const READBACK_5381_NESTED = [[
47030
47630
  function isPre5381ReplicaBaseline(baseline) {
47031
47631
  if ("TableClass" in baseline || "DeletionProtectionEnabled" in baseline) return true;
47032
47632
  const replicas = baseline["Replicas"];
47033
- return Array.isArray(replicas) && replicas.some((r) => isPlainObject$1(r) && "KMSMasterKeyId" in r);
47633
+ return Array.isArray(replicas) && replicas.some((r) => isPlainObject$2(r) && "KMSMasterKeyId" in r);
47034
47634
  }
47035
47635
  function canonicalizePre5381ReplicaBaseline(baseline, aws, localRegion, localFromReadback = false) {
47036
47636
  if (!isPre5381ReplicaBaseline(baseline)) return baseline;
@@ -47044,7 +47644,7 @@ function canonicalizePre5381ReplicaBaseline(baseline, aws, localRegion, localFro
47044
47644
  if (!Array.isArray(replicas)) return result;
47045
47645
  const awsReplicas = Array.isArray(aws["Replicas"]) ? aws["Replicas"] : [];
47046
47646
  result["Replicas"] = replicas.map((element) => {
47047
- if (!isPlainObject$1(element)) return element;
47647
+ if (!isPlainObject$2(element)) return element;
47048
47648
  const region = element["Region"];
47049
47649
  const entry = { ...element };
47050
47650
  if (region === localRegion && localRegion !== "") {
@@ -47055,13 +47655,13 @@ function canonicalizePre5381ReplicaBaseline(baseline, aws, localRegion, localFro
47055
47655
  delete entry["KMSMasterKeyId"];
47056
47656
  if (!("SSESpecification" in entry)) entry["SSESpecification"] = { KMSMasterKeyId: key };
47057
47657
  }
47058
- const live = awsReplicas.find((r) => isPlainObject$1(r) && r["Region"] === region);
47658
+ const live = awsReplicas.find((r) => isPlainObject$2(r) && r["Region"] === region);
47059
47659
  if (live !== void 0) {
47060
47660
  for (const member of READBACK_5381_MEMBERS) if (!(member in entry) && member in live) entry[member] = structuredClone(live[member]);
47061
47661
  for (const [block, member, flag] of READBACK_5381_NESTED) {
47062
47662
  const mine = entry[block];
47063
47663
  const theirs = live[block];
47064
- if (isPlainObject$1(mine) && isPlainObject$1(theirs) && !(member in mine) && member in theirs && mine[flag] === theirs[flag]) entry[block] = {
47664
+ if (isPlainObject$2(mine) && isPlainObject$2(theirs) && !(member in mine) && member in theirs && mine[flag] === theirs[flag]) entry[block] = {
47065
47665
  ...mine,
47066
47666
  [member]: theirs[member]
47067
47667
  };
@@ -47074,18 +47674,19 @@ function canonicalizePre5381ReplicaBaseline(baseline, aws, localRegion, localFro
47074
47674
  const UNREAD_REPLICA_MEMBERS = [
47075
47675
  "TableClass",
47076
47676
  "DeletionProtectionEnabled",
47077
- "SSESpecification"
47677
+ "SSESpecification",
47678
+ "GlobalTableSettingsReplicationMode"
47078
47679
  ];
47079
47680
  function keepUnreadReplicaMembers(desired, previous) {
47080
47681
  const replicas = desired["Replicas"];
47081
47682
  const prevReplicas = previous["Replicas"];
47082
47683
  if (!Array.isArray(replicas) || !Array.isArray(prevReplicas)) return desired;
47083
47684
  const sse = desired["SSESpecification"];
47084
- const sseOn = isPlainObject$1(sse) && coerceCfnBoolean(sse["SSEEnabled"]) !== false;
47685
+ const sseOn = isPlainObject$2(sse) && coerceCfnBoolean(sse["SSEEnabled"]) !== false;
47085
47686
  let changed = false;
47086
47687
  const completed = replicas.map((element) => {
47087
- if (!isPlainObject$1(element)) return element;
47088
- const live = prevReplicas.find((r) => isPlainObject$1(r) && r["Region"] === element["Region"]);
47688
+ if (!isPlainObject$2(element)) return element;
47689
+ const live = prevReplicas.find((r) => isPlainObject$2(r) && r["Region"] === element["Region"]);
47089
47690
  if (live === void 0) return element;
47090
47691
  const entry = { ...element };
47091
47692
  let touched = false;
@@ -47099,7 +47700,7 @@ function keepUnreadReplicaMembers(desired, previous) {
47099
47700
  const pitr = entry[PITR_KEY];
47100
47701
  const wantPitr = readPitrSpec(pitr);
47101
47702
  const livePitr = readPitrSpec(live[PITR_KEY]);
47102
- if (isPlainObject$1(pitr) && wantPitr.kind === "usable" && wantPitr.enabled && wantPitr.recoveryPeriodInDays === void 0 && livePitr.kind === "usable" && livePitr.enabled && livePitr.recoveryPeriodInDays !== void 0) {
47703
+ if (isPlainObject$2(pitr) && wantPitr.kind === "usable" && wantPitr.enabled && wantPitr.recoveryPeriodInDays === void 0 && livePitr.kind === "usable" && livePitr.enabled && livePitr.recoveryPeriodInDays !== void 0) {
47103
47704
  entry[PITR_KEY] = {
47104
47705
  ...pitr,
47105
47706
  RecoveryPeriodInDays: livePitr.recoveryPeriodInDays
@@ -47123,7 +47724,7 @@ const STREAM_POLICY_KEY = "ResourcePolicy";
47123
47724
  const STREAM_TAGS_KEY = "Tags";
47124
47725
  const POLICY_PATH = `${STREAM_SPECIFICATION_KEY$1}.${STREAM_POLICY_KEY}`;
47125
47726
  const TAGS_PATH = `${STREAM_SPECIFICATION_KEY$1}.${STREAM_TAGS_KEY}`;
47126
- function isPlainObject(value) {
47727
+ function isPlainObject$1(value) {
47127
47728
  return typeof value === "object" && value !== null && !Array.isArray(value);
47128
47729
  }
47129
47730
  function refusalOf(guard) {
@@ -47135,7 +47736,7 @@ function refusalOf(guard) {
47135
47736
  }
47136
47737
  }
47137
47738
  function blockMembers(block) {
47138
- return isPlainObject(block) ? block : {};
47739
+ return isPlainObject$1(block) ? block : {};
47139
47740
  }
47140
47741
  function readStreamPolicy(block) {
47141
47742
  const value = blockMembers(block)[STREAM_POLICY_KEY];
@@ -47310,7 +47911,7 @@ function streamTagsMatchDeclared(liveTags, desiredBlock) {
47310
47911
  }
47311
47912
  function canonicalJson(value) {
47312
47913
  if (Array.isArray(value)) return `[${value.map(canonicalJson).join(",")}]`;
47313
- if (isPlainObject(value)) return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(",")}}`;
47914
+ if (isPlainObject$1(value)) return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(",")}}`;
47314
47915
  return JSON.stringify(value) ?? "null";
47315
47916
  }
47316
47917
 
@@ -47326,6 +47927,93 @@ const DRIFT_STRIPPED_INDEX_MEMBERS = [{
47326
47927
  function maskLeafValue(value, maskSecrets) {
47327
47928
  return maskDeep(value, maskSecrets);
47328
47929
  }
47930
+ function isPlainObject(value) {
47931
+ return typeof value === "object" && value !== null && !Array.isArray(value);
47932
+ }
47933
+ const IDENTITY_KEYS = [
47934
+ "Region",
47935
+ "IndexName",
47936
+ "AttributeName"
47937
+ ];
47938
+ function identityKeyOf(...lists) {
47939
+ const entries = lists.flat();
47940
+ if (entries.length === 0) return void 0;
47941
+ const key = IDENTITY_KEYS.find((candidate) => entries.every((entry) => isPlainObject(entry) && typeof entry[candidate] === "string"));
47942
+ if (key !== void 0) return { key };
47943
+ return entries.some((entry) => isPlainObject(entry) && IDENTITY_KEYS.some((candidate) => typeof entry[candidate] === "string")) ? "ambiguous" : void 0;
47944
+ }
47945
+ const POSITIONAL_LIST_KEYS = /* @__PURE__ */ new Set(["KeySchema"]);
47946
+ function projectNamed(live, own, wanted, path, unnamed) {
47947
+ if (isPlainObject(live) && (isPlainObject(own) || isPlainObject(wanted))) {
47948
+ const ownBag = isPlainObject(own) ? own : void 0;
47949
+ const wantedBag = isPlainObject(wanted) ? wanted : void 0;
47950
+ const out = {};
47951
+ for (const key of IDENTITY_KEYS) if (Object.hasOwn(live, key)) out[key] = live[key];
47952
+ const named = /* @__PURE__ */ new Set([...Object.keys(ownBag ?? {}), ...Object.keys(wantedBag ?? {})]);
47953
+ for (const key of named) {
47954
+ if (IDENTITY_KEYS.includes(key)) continue;
47955
+ if (key === "Tags") {
47956
+ if (ownBag !== void 0 && Object.hasOwn(ownBag, "Tags")) out["Tags"] = ownBag["Tags"];
47957
+ continue;
47958
+ }
47959
+ if (!Object.hasOwn(live, key) || live[key] === void 0) continue;
47960
+ out[key] = POSITIONAL_LIST_KEYS.has(key) ? live[key] : projectNamed(live[key], ownBag?.[key], wantedBag?.[key], `${path}.${key}`, unnamed);
47961
+ }
47962
+ return out;
47963
+ }
47964
+ if (Array.isArray(live)) {
47965
+ const ownList = Array.isArray(own) ? own : [];
47966
+ const wantedList = Array.isArray(wanted) ? wanted : [];
47967
+ const identity = identityKeyOf(live, ownList, wantedList);
47968
+ if (identity === void 0) return live;
47969
+ if (identity === "ambiguous") {
47970
+ unnamed.push({
47971
+ identity: "unkeyed entries",
47972
+ value: "some",
47973
+ path,
47974
+ ambiguous: true
47975
+ });
47976
+ return own;
47977
+ }
47978
+ const id = identity.key;
47979
+ const byId = (list) => new Map(list.map((entry) => [entry[id], entry]));
47980
+ const ownById = byId(ownList);
47981
+ const wantedById = byId(wantedList);
47982
+ return live.flatMap((entry) => {
47983
+ const value = entry[id];
47984
+ const ownEntry = ownById.get(value);
47985
+ const wantedEntry = wantedById.get(value);
47986
+ if (ownEntry === void 0 && wantedEntry === void 0) {
47987
+ unnamed.push({
47988
+ identity: id,
47989
+ value,
47990
+ path
47991
+ });
47992
+ return [];
47993
+ }
47994
+ return [projectNamed(entry, ownEntry, wantedEntry, `${path}[${value}]`, unnamed)];
47995
+ });
47996
+ }
47997
+ return live;
47998
+ }
47999
+ const strictReadScope = new AsyncLocalStorage();
48000
+ function strictFor(key) {
48001
+ return strictReadScope.getStore()?.has(key) === true;
48002
+ }
48003
+ function replicaStrictness(status) {
48004
+ const current = strictReadScope.getStore() ?? /* @__PURE__ */ new Set();
48005
+ if (status === void 0 || status === "ACTIVE" || status === "UPDATING") return current;
48006
+ return new Set([...current].filter((key) => key !== "Replicas"));
48007
+ }
48008
+ const unsettledScope = new AsyncLocalStorage();
48009
+ function markUnsettled(...keys) {
48010
+ const scope = unsettledScope.getStore();
48011
+ if (scope === void 0) return;
48012
+ for (const key of keys) scope.mark(key);
48013
+ }
48014
+ function isUnsettled(key) {
48015
+ return unsettledScope.getStore()?.unsettled.has(key) === true;
48016
+ }
47329
48017
  function sentence(text) {
47330
48018
  return text.endsWith(".") ? text : `${text}.`;
47331
48019
  }
@@ -47548,6 +48236,8 @@ var DynamoDBGlobalTableProvider = class {
47548
48236
  }
47549
48237
  if (sdkIndexes.length > 0) createParams.GlobalSecondaryIndexes = sdkIndexes;
47550
48238
  if (properties["LocalSecondaryIndexes"]) createParams.LocalSecondaryIndexes = properties["LocalSecondaryIndexes"];
48239
+ const createMode = readReplicationMode(properties);
48240
+ if (createMode.kind === "usable") createParams.GlobalTableSettingsReplicationMode = createMode.mode;
47551
48241
  const sseEnabledRefusal = configBooleanRefusal(properties["SSESpecification"], "SSEEnabled", "AWS::DynamoDB::GlobalTable SSESpecification");
47552
48242
  if (sseEnabledRefusal !== void 0) {
47553
48243
  const onReplay = replayWarn(log, context).onUnusable;
@@ -47697,6 +48387,7 @@ var DynamoDBGlobalTableProvider = class {
47697
48387
  if (tableClass !== void 0) create.TableClassOverride = tableClass;
47698
48388
  const replicaUpdates = [{ Create: create }];
47699
48389
  for (let attempt = 1;; attempt++) try {
48390
+ markUnsettled("Replicas");
47700
48391
  await this.dynamoDBClient.send(new UpdateTableCommand({
47701
48392
  TableName: tableName,
47702
48393
  ReplicaUpdates: replicaUpdates
@@ -47722,6 +48413,7 @@ var DynamoDBGlobalTableProvider = class {
47722
48413
  await this.writeReplicaDeletionProtection(tableName, region, enabled);
47723
48414
  }
47724
48415
  async writeReplicaDeletionProtection(tableName, region, enabled) {
48416
+ markUnsettled("Replicas");
47725
48417
  await this.getRegionalClient(region).send(new UpdateTableCommand({
47726
48418
  TableName: tableName,
47727
48419
  DeletionProtectionEnabled: enabled
@@ -47796,6 +48488,7 @@ var DynamoDBGlobalTableProvider = class {
47796
48488
  }
47797
48489
  this.logger.debug(maskSecrets(`Bringing the ${region} replica of ${tableName} to its declared table class`));
47798
48490
  try {
48491
+ markUnsettled("Replicas");
47799
48492
  await this.dynamoDBClient.send(new UpdateTableCommand({
47800
48493
  TableName: tableName,
47801
48494
  ReplicaUpdates: [{ Update: {
@@ -47843,6 +48536,7 @@ var DynamoDBGlobalTableProvider = class {
47843
48536
  request = built;
47844
48537
  }
47845
48538
  try {
48539
+ markUnsettled("SSESpecification", "Replicas");
47846
48540
  await this.dynamoDBClient.send(new UpdateTableCommand(request));
47847
48541
  await this.waitForGlobalTableSettled(tableName, logicalId, maskSecrets);
47848
48542
  } catch (keyError) {
@@ -47885,6 +48579,7 @@ var DynamoDBGlobalTableProvider = class {
47885
48579
  }
47886
48580
  async applyReplicaSettings(tableName, logicalId, currentRegion, properties, previousProperties, freshRegions, streamReplaced, replaying, keepOnRemoval, previousLocalStreamArn, warn, maskSecrets) {
47887
48581
  const desired = Array.isArray(properties["Replicas"]) ? properties["Replicas"] : [];
48582
+ const tableIndexNames = previousProperties === void 0 ? new Set(indexEntriesByName(properties["GlobalSecondaryIndexes"]).keys()) : void 0;
47888
48583
  for (const entry of desired) {
47889
48584
  const replica = asRecord(entry);
47890
48585
  const region = replica?.["Region"];
@@ -47894,13 +48589,15 @@ var DynamoDBGlobalTableProvider = class {
47894
48589
  const ops = planReplicaSettingOps(replica, previous, {
47895
48590
  fresh,
47896
48591
  streamReplaced,
47897
- keepOnRemoval
48592
+ keepOnRemoval,
48593
+ ...tableIndexNames !== void 0 && { tableIndexNames }
47898
48594
  }, (reason) => warn(`The ${region} replica of ${tableName}: ${reason}, so that setting was left as it is. ` + (replaying ? `The value came from a recorded state, which a template edit cannot reach.` : `Fix the template value and re-deploy.`)));
47899
48595
  if (!fresh && keepOnRemoval.has("pitr") && replica?.["PointInTimeRecoverySpecification"] == null && (() => {
47900
48596
  const prior = readPitrSpec(previous?.["PointInTimeRecoverySpecification"]);
47901
48597
  return prior.kind === "usable" && prior.enabled;
47902
48598
  })()) warn(`The ${region} replica of ${tableName}: point-in-time recovery was not turned off, although the properties being applied (a rollback's recorded state, or a drift --revert read-back) declare none — turning it off would delete every recovery point. Turn it off by hand if that is intended.`);
47903
48599
  const unchanged = fresh ? /* @__PURE__ */ new Set() : declaredReplicaSettings(replica);
48600
+ unchanged.delete("indexContributorInsights");
47904
48601
  for (const op of ops) unchanged.delete(settingOf(op));
47905
48602
  if (ops.length === 0 && unchanged.size === 0) continue;
47906
48603
  const client = region === currentRegion ? this.dynamoDBClient : this.getRegionalClient(region);
@@ -47927,7 +48624,7 @@ var DynamoDBGlobalTableProvider = class {
47927
48624
  const streamPolicyChanged = priorStreamPolicy.kind !== "absent" && desiredStreamPolicy.kind !== "unusable" && !(desiredStreamPolicy.kind === "absent" && keepOnRemoval.has("streamPolicy")) && !(priorStreamPolicy.kind === "usable" && desiredStreamPolicy.kind === "usable" && samePolicyDocument$1(priorStreamPolicy.document, desiredStreamPolicy.document));
47928
48625
  if (region === currentRegion && streamReplaced && previousLocalStreamArn !== void 0 && streamPolicyChanged && (await describe()).streamArn !== previousLocalStreamArn) await this.deleteOldStreamPolicy(client, previousLocalStreamArn, tableName, warn, maskSecrets);
47929
48626
  if (unchanged.size === 0) continue;
47930
- const live = await this.readLiveReplicaSettings(client, tableName, region, unchanged, describe, maskSecrets);
48627
+ const live = await this.readLiveReplicaSettings(client, tableName, region, unchanged, describe, maskSecrets, replica);
47931
48628
  for (const op of planReplicaSettingCorrections(replica, live, unchanged)) {
47932
48629
  const member = SETTING_MEMBER[settingOf(op)];
47933
48630
  this.logger.debug(maskSecrets(`Bringing the ${region} replica of ${tableName} to its declared ${member}`));
@@ -47941,7 +48638,60 @@ var DynamoDBGlobalTableProvider = class {
47941
48638
  }
47942
48639
  }
47943
48640
  }
47944
- async readLiveReplicaSettings(client, tableName, region, wanted, describe, maskSecrets) {
48641
+ async sendReplicationMode(tableName, logicalId, mode, maskSecrets, fromTemplate = true) {
48642
+ this.logger.debug(maskSecrets(`Setting GlobalTableSettingsReplicationMode of ${tableName} to ${mode}`));
48643
+ await this.sendLocalSettingUpdate({
48644
+ TableName: tableName,
48645
+ GlobalTableSettingsReplicationMode: mode
48646
+ }, fromTemplate, "GlobalTableSettingsReplicationMode", tableName, logicalId, maskSecrets);
48647
+ }
48648
+ async applyReplicaIndexInsights(tableName, logicalId, currentRegion, properties, previousProperties, freshRegions, keepOnRemoval, replaying, warn, maskSecrets) {
48649
+ const tableIndexNames = new Set(indexEntriesByName(properties["GlobalSecondaryIndexes"]).keys());
48650
+ if (tableIndexNames.size === 0) return;
48651
+ const desired = Array.isArray(properties["Replicas"]) ? properties["Replicas"] : [];
48652
+ for (const entry of desired) {
48653
+ const replica = asRecord(entry);
48654
+ const region = replica?.["Region"];
48655
+ if (typeof region !== "string" || region === "") continue;
48656
+ const fresh = freshRegions.has(region);
48657
+ const ops = planReplicaIndexInsightsOps(replica, localReplicaEntry(previousProperties, region), {
48658
+ fresh,
48659
+ tableIndexNames,
48660
+ removes: (setting) => !keepOnRemoval.has(setting)
48661
+ }, (reason) => warn(`The ${region} replica of ${tableName}: ${reason}, so that setting was left as it is. ` + (replaying ? `The value came from a recorded state, which a template edit cannot reach.` : `Fix the template value and re-deploy.`)));
48662
+ const addressed = new Set(ops.flatMap((op) => op.kind === "indexContributorInsights" ? [op.indexName] : []));
48663
+ const declared = declaredIndexInsights(replica);
48664
+ const unchanged = fresh ? [] : [...declared.keys()].filter((name) => tableIndexNames.has(name) && !addressed.has(name));
48665
+ if (ops.length === 0 && unchanged.length === 0) continue;
48666
+ const client = region === currentRegion ? this.dynamoDBClient : this.getRegionalClient(region);
48667
+ await this.waitForGlobalTableSettled(tableName, logicalId, maskSecrets, { ...region !== currentRegion && { region } });
48668
+ await waitForIndexesSettled({
48669
+ tableName,
48670
+ logicalId,
48671
+ logger: maskedLogger(this.logger, maskSecrets, tableName),
48672
+ describeTable: () => client.send(new DescribeTableCommand({ TableName: tableName })),
48673
+ maxAttempts: 900,
48674
+ proceedNote: `setting the index's Contributor Insights may be refused.`
48675
+ });
48676
+ const describe = () => Promise.resolve({});
48677
+ for (const op of ops) await this.sendReplicaSettingOp(client, tableName, region, logicalId, op, describe, maskSecrets);
48678
+ if (unchanged.length === 0) continue;
48679
+ const replicaIndexes = indexEntriesByName(replica?.["GlobalSecondaryIndexes"]);
48680
+ const onlyUnchanged = {
48681
+ ...replica,
48682
+ GlobalSecondaryIndexes: unchanged.map((name) => replicaIndexes.get(name))
48683
+ };
48684
+ const only = /* @__PURE__ */ new Set(["indexContributorInsights"]);
48685
+ const live = await this.readLiveReplicaSettings(client, tableName, region, only, describe, maskSecrets, onlyUnchanged);
48686
+ for (const op of planReplicaSettingCorrections(onlyUnchanged, live, only)) try {
48687
+ await this.sendReplicaSettingOp(client, tableName, region, logicalId, op, describe, maskSecrets);
48688
+ } catch (convergeError) {
48689
+ if (isInterruptedWaitError(convergeError)) throw convergeError;
48690
+ this.logger.warn(maskSecrets(`The ${region} replica of ${tableName} does not hold the declared ${SETTING_MEMBER.indexContributorInsights} of an index, and setting it failed (${describeAwsFailure(convergeError).summary}). The next deploy that updates this table tries again.`));
48691
+ }
48692
+ }
48693
+ }
48694
+ async readLiveReplicaSettings(client, tableName, region, wanted, describe, maskSecrets, declared) {
47945
48695
  const live = {};
47946
48696
  const attempt = async (what, read) => {
47947
48697
  try {
@@ -47984,10 +48734,37 @@ var DynamoDBGlobalTableProvider = class {
47984
48734
  const answer = await hasPolicy((await describe()).streamArn);
47985
48735
  if (answer !== void 0) live.hasStreamPolicy = answer;
47986
48736
  });
48737
+ if (wanted.has("indexContributorInsights")) {
48738
+ const perIndex = /* @__PURE__ */ new Map();
48739
+ for (const indexName of declaredIndexInsights(declared).keys()) await attempt(`Contributor Insights of an index`, async () => {
48740
+ const status = (await client.send(new DescribeContributorInsightsCommand({
48741
+ TableName: tableName,
48742
+ IndexName: indexName
48743
+ }))).ContributorInsightsStatus;
48744
+ if (status === "ENABLED" || status === "DISABLED") perIndex.set(indexName, status === "ENABLED");
48745
+ });
48746
+ live.indexContributorInsightsEnabled = perIndex;
48747
+ }
48748
+ if (wanted.has("streamTags")) await attempt("the stream tags", async () => {
48749
+ const arn = (await describe()).streamArn;
48750
+ if (arn === void 0) return;
48751
+ const tags = /* @__PURE__ */ new Map();
48752
+ let nextToken;
48753
+ do {
48754
+ const out = await client.send(new ListTagsOfResourceCommand({
48755
+ ResourceArn: arn,
48756
+ NextToken: nextToken
48757
+ }));
48758
+ for (const t of out.Tags ?? []) if (t.Key !== void 0) tags.set(t.Key, t.Value ?? "");
48759
+ nextToken = out.NextToken;
48760
+ } while (nextToken !== void 0);
48761
+ live.streamTags = tags;
48762
+ });
47987
48763
  return live;
47988
48764
  }
47989
48765
  async deleteOldStreamPolicy(client, streamArn, tableName, warn, maskSecrets) {
47990
48766
  try {
48767
+ markUnsettled("Replicas");
47991
48768
  await this.retrySettlingRefusal(() => client.send(new DeleteResourcePolicyCommand({ ResourceArn: streamArn })), `delete the policy of the retired stream of ${tableName}`, maskSecrets);
47992
48769
  } catch (error) {
47993
48770
  if (isInterruptedWaitError(error)) throw error;
@@ -48038,7 +48815,10 @@ var DynamoDBGlobalTableProvider = class {
48038
48815
  if (arn === void 0 || arn === "") throw new ProvisioningError(maskSecrets(`Cannot apply ${SETTING_MEMBER[settingOf(op)]} to ${scope}: DescribeTable returned no ${which === "tableArn" ? "TableArn" : "LatestStreamArn (the table has no stream)"}`), "AWS::DynamoDB::GlobalTable", logicalId, tableName);
48039
48816
  return arn;
48040
48817
  };
48041
- const send = (call) => this.retrySettlingRefusal(call, `${op.kind} on ${scope}`, maskSecrets);
48818
+ const send = (call) => {
48819
+ markUnsettled("Replicas");
48820
+ return this.retrySettlingRefusal(call, `${op.kind} on ${scope}`, maskSecrets);
48821
+ };
48042
48822
  switch (op.kind) {
48043
48823
  case "pitr":
48044
48824
  await send(() => client.send(new UpdateContinuousBackupsCommand({
@@ -48106,6 +48886,31 @@ var DynamoDBGlobalTableProvider = class {
48106
48886
  }
48107
48887
  break;
48108
48888
  }
48889
+ case "indexContributorInsights":
48890
+ await send(() => client.send(new UpdateContributorInsightsCommand({
48891
+ TableName: tableName,
48892
+ IndexName: op.indexName,
48893
+ ContributorInsightsAction: op.action,
48894
+ ...op.mode !== void 0 && { ContributorInsightsMode: op.mode }
48895
+ })));
48896
+ break;
48897
+ case "untagStream": {
48898
+ if ((await describe()).streamArn === void 0) break;
48899
+ const arn = await arnFor("streamArn");
48900
+ await send(() => client.send(new UntagResourceCommand$2({
48901
+ ResourceArn: arn,
48902
+ TagKeys: op.keys
48903
+ })));
48904
+ break;
48905
+ }
48906
+ case "tagStream": {
48907
+ const arn = await arnFor("streamArn");
48908
+ await send(() => client.send(new TagResourceCommand$2({
48909
+ ResourceArn: arn,
48910
+ Tags: op.tags
48911
+ })));
48912
+ break;
48913
+ }
48109
48914
  }
48110
48915
  this.logger.debug(maskSecrets(`Applied ${op.kind} to ${scope}`));
48111
48916
  }
@@ -48131,6 +48936,7 @@ var DynamoDBGlobalTableProvider = class {
48131
48936
  }
48132
48937
  async sendLocalSettingUpdate(input, fromTemplate, what, tableName, logicalId, maskSecrets) {
48133
48938
  try {
48939
+ markUnsettled(input.SSESpecification !== void 0 ? "SSESpecification" : "Replicas");
48134
48940
  await this.dynamoDBClient.send(new UpdateTableCommand(input));
48135
48941
  await this.waitForGlobalTableSettled(tableName, logicalId, maskSecrets);
48136
48942
  } catch (error) {
@@ -48237,6 +49043,12 @@ var DynamoDBGlobalTableProvider = class {
48237
49043
  }
48238
49044
  }
48239
49045
  async update(logicalId, physicalId, resourceType, properties, previousProperties, context) {
49046
+ return unsettledScope.run({
49047
+ mark: (key) => context?.markUnsettled?.(key),
49048
+ unsettled: context?.unsettledProperties ?? /* @__PURE__ */ new Set()
49049
+ }, () => this.updateInScope(logicalId, physicalId, resourceType, properties, previousProperties, context));
49050
+ }
49051
+ async updateInScope(logicalId, physicalId, resourceType, properties, previousProperties, context) {
48240
49052
  if (context?.desiredFromAwsReadback === true) properties = keepUnreadReplicaMembers(properties, previousProperties);
48241
49053
  const log = this.operationSinks(context, [[properties["TableName"], physicalId], [previousProperties["TableName"], physicalId]]);
48242
49054
  const maskSecrets = log.mask;
@@ -48283,7 +49095,7 @@ var DynamoDBGlobalTableProvider = class {
48283
49095
  physicalName: physicalId
48284
49096
  })) throw new ProvisioningError(log.mask(`TableName is immutable on AWS::DynamoDB::GlobalTable; ${await replaceRemedy()}`), resourceType, logicalId, physicalId);
48285
49097
  if (properties["KeySchema"] !== void 0 && previousProperties["KeySchema"] !== void 0 && !deepEqual(properties["KeySchema"], previousProperties["KeySchema"])) throw new ProvisioningError(log.mask(`KeySchema is immutable on AWS::DynamoDB::GlobalTable; ${await replaceRemedy()}`), resourceType, logicalId, physicalId);
48286
- if (properties["LocalSecondaryIndexes"] !== void 0 && previousProperties["LocalSecondaryIndexes"] !== void 0 && !deepEqual(properties["LocalSecondaryIndexes"], previousProperties["LocalSecondaryIndexes"])) throw new ProvisioningError(log.mask(`LocalSecondaryIndexes is immutable on AWS::DynamoDB::GlobalTable; ${await replaceRemedy()}`), resourceType, logicalId, physicalId);
49098
+ if (!deepEqual(lsiListOrEmpty(properties["LocalSecondaryIndexes"]), lsiListOrEmpty(previousProperties["LocalSecondaryIndexes"]))) throw new ProvisioningError(log.mask(`LocalSecondaryIndexes is immutable on AWS::DynamoDB::GlobalTable; ${await replaceRemedy()}`), resourceType, logicalId, physicalId);
48287
49099
  const oldAttrs = previousProperties["AttributeDefinitions"] ?? [];
48288
49100
  const newAttrs = properties["AttributeDefinitions"] ?? [];
48289
49101
  const desiredKeyAttrNames = collectDesiredKeyAttributeNames(properties);
@@ -48463,6 +49275,9 @@ var DynamoDBGlobalTableProvider = class {
48463
49275
  flatChanged = true;
48464
49276
  }
48465
49277
  if (flatChanged) {
49278
+ if (flatUpdate.DeletionProtectionEnabled !== void 0) markUnsettled("Replicas");
49279
+ if (flatUpdate.StreamSpecification !== void 0) markUnsettled("StreamSpecification");
49280
+ if (flatUpdate.OnDemandThroughput !== void 0) markUnsettled("WriteOnDemandThroughputSettings");
48466
49281
  await this.dynamoDBClient.send(new UpdateTableCommand(flatUpdate));
48467
49282
  await this.waitForTableActiveAfterUpdate(physicalId, logicalId, void 0, void 0, maskSecrets);
48468
49283
  }
@@ -48518,10 +49333,13 @@ var DynamoDBGlobalTableProvider = class {
48518
49333
  }
48519
49334
  if (indexUpdates.length > 0) billingUpdate.GlobalSecondaryIndexUpdates = indexUpdates;
48520
49335
  }
49336
+ markUnsettled("BillingMode", "WriteProvisionedThroughputSettings");
49337
+ if (billingUpdate.GlobalSecondaryIndexUpdates !== void 0) markUnsettled("GlobalSecondaryIndexes");
48521
49338
  await this.dynamoDBClient.send(new UpdateTableCommand(billingUpdate));
48522
49339
  await this.waitForTableActiveAfterUpdate(physicalId, logicalId, void 0, void 0, maskSecrets);
48523
49340
  }
48524
49341
  if (deferCeilingsPastFlip) {
49342
+ markUnsettled("WriteOnDemandThroughputSettings");
48525
49343
  await this.dynamoDBClient.send(new UpdateTableCommand({
48526
49344
  TableName: physicalId,
48527
49345
  OnDemandThroughput: onDemandPayload
@@ -48539,6 +49357,8 @@ var DynamoDBGlobalTableProvider = class {
48539
49357
  region: currentRegion
48540
49358
  }));
48541
49359
  }
49360
+ const modeUpdate = replicationModeUpdate(properties, previousProperties);
49361
+ if (modeUpdate === "DISABLED" && readReplicationMode(properties).kind === "absent") await this.sendReplicationMode(physicalId, logicalId, modeUpdate, maskSecrets);
48542
49362
  const replicaDiff = diffReplicas(previousProperties["Replicas"] ?? [], properties["Replicas"] ?? []);
48543
49363
  for (const replica of replicaDiff.removed) {
48544
49364
  const region = replica["Region"];
@@ -48552,6 +49372,7 @@ var DynamoDBGlobalTableProvider = class {
48552
49372
  region
48553
49373
  }));
48554
49374
  }
49375
+ markUnsettled("Replicas");
48555
49376
  await this.dynamoDBClient.send(new UpdateTableCommand({
48556
49377
  TableName: physicalId,
48557
49378
  ReplicaUpdates: [{ Delete: { RegionName: region } }]
@@ -48611,6 +49432,7 @@ var DynamoDBGlobalTableProvider = class {
48611
49432
  debug(`Cross-region replica ${region} of ${maskSecrets(physicalId)}: only Tags-style changes detected; UpdateReplica skipped (AWS rejects empty Update actions). Tags propagation handled above via per-region client.`);
48612
49433
  continue;
48613
49434
  }
49435
+ markUnsettled("Replicas");
48614
49436
  await this.dynamoDBClient.send(new UpdateTableCommand({
48615
49437
  TableName: physicalId,
48616
49438
  ReplicaUpdates: [{ Update: updateAction }]
@@ -48618,16 +49440,24 @@ var DynamoDBGlobalTableProvider = class {
48618
49440
  await this.waitForReplicaActive(physicalId, region, logicalId, void 0, maskSecrets);
48619
49441
  }
48620
49442
  const addedReplicaRegions = new Set(replicaDiff.added.map((r) => r["Region"]));
49443
+ if (modeUpdate !== void 0 && readReplicationMode(properties).kind === "usable") await this.sendReplicationMode(physicalId, logicalId, modeUpdate, maskSecrets);
49444
+ else {
49445
+ const correction = replicationModeCorrection(properties, previousProperties, describeResp.Table?.GlobalTableSettingsReplicationMode);
49446
+ if (correction !== void 0) await this.sendReplicationMode(physicalId, logicalId, correction, maskSecrets, false);
49447
+ }
48621
49448
  await this.convergeReplicaDeletionProtection(physicalId, logicalId, currentRegion, previousProperties, properties, addedReplicaRegions, context?.desiredFromAwsReadback === true, warn, maskSecrets);
48622
49449
  await this.convergeReplicaSettings(physicalId, logicalId, currentRegion, properties, addedReplicaRegions, maskSecrets);
48623
49450
  await this.applyReplicaKeys(physicalId, logicalId, currentRegion, properties, previousProperties, addedReplicaRegions, deferredSseUpdate, deferredSseFromTemplate, keylessSseFromTemplate, maskSecrets);
48624
- await this.applyReplicaSettings(physicalId, logicalId, currentRegion, properties, previousProperties, addedReplicaRegions, !deepEqual(asRecord(properties["StreamSpecification"])?.["StreamViewType"], asRecord(previousProperties["StreamSpecification"])?.["StreamViewType"]), context?.replayingState === true || context?.desiredFromAwsReadback === true, new Set(context?.desiredFromAwsReadback === true ? [
49451
+ const replicaKeepOnRemoval = new Set(context?.desiredFromAwsReadback === true ? [
48625
49452
  "pitr",
48626
49453
  "contributorInsights",
48627
49454
  "kinesis",
48628
49455
  "tablePolicy",
48629
- "streamPolicy"
48630
- ] : context?.replayingState === true ? ["pitr"] : []), describeResp.Table?.LatestStreamArn, warn, maskSecrets);
49456
+ "streamPolicy",
49457
+ "indexContributorInsights",
49458
+ "streamTags"
49459
+ ] : context?.replayingState === true ? ["pitr"] : []);
49460
+ await this.applyReplicaSettings(physicalId, logicalId, currentRegion, properties, previousProperties, addedReplicaRegions, !deepEqual(asRecord(properties["StreamSpecification"])?.["StreamViewType"], asRecord(previousProperties["StreamSpecification"])?.["StreamViewType"]), context?.replayingState === true || context?.desiredFromAwsReadback === true, replicaKeepOnRemoval, describeResp.Table?.LatestStreamArn, warn, maskSecrets);
48631
49461
  const previousTranslatedIndexes = toSdkGlobalSecondaryIndexes(previousProperties, currentRegion, oldBilling, "min", void 0, onUnusablePreviousGsiBlock, maskSecrets);
48632
49462
  const previousSdkIndexes = previousGsiUnusable ? buildLiveRecoveryGsiBaseline(desiredSdkIndexes, describeResp.Table?.GlobalSecondaryIndexes, {
48633
49463
  carryLiveValues: oldBilling === newBilling && liveBillingMode === newBilling,
@@ -48650,6 +49480,7 @@ var DynamoDBGlobalTableProvider = class {
48650
49480
  for (const gsi of gsiDiff.removed) {
48651
49481
  if (!gsi.IndexName) continue;
48652
49482
  const gsiUpdate = { Delete: { IndexName: gsi.IndexName } };
49483
+ markUnsettled("GlobalSecondaryIndexes");
48653
49484
  await this.dynamoDBClient.send(new UpdateTableCommand({
48654
49485
  TableName: physicalId,
48655
49486
  GlobalSecondaryIndexUpdates: [gsiUpdate]
@@ -48667,6 +49498,7 @@ var DynamoDBGlobalTableProvider = class {
48667
49498
  ...gsi.OnDemandThroughput && { OnDemandThroughput: gsi.OnDemandThroughput },
48668
49499
  ...addedWarmToSend && { WarmThroughput: addedWarmToSend }
48669
49500
  } };
49501
+ markUnsettled("GlobalSecondaryIndexes");
48670
49502
  await this.dynamoDBClient.send(new UpdateTableCommand({
48671
49503
  TableName: physicalId,
48672
49504
  AttributeDefinitions: newAttrs,
@@ -48707,6 +49539,7 @@ var DynamoDBGlobalTableProvider = class {
48707
49539
  continue;
48708
49540
  }
48709
49541
  const gsiUpdate = { Update: update };
49542
+ markUnsettled("GlobalSecondaryIndexes");
48710
49543
  await this.dynamoDBClient.send(new UpdateTableCommand({
48711
49544
  TableName: physicalId,
48712
49545
  GlobalSecondaryIndexUpdates: [gsiUpdate]
@@ -48720,6 +49553,7 @@ var DynamoDBGlobalTableProvider = class {
48720
49553
  if (gsiDiff.added.length > 0) await this.waitForIndexesActive(physicalId, logicalId, { maskSecrets });
48721
49554
  await this.reconcileAutoScalingTargets(physicalId, collectAutoScalingTargets(previousProperties, currentRegion), newBilling === "PAY_PER_REQUEST" ? [] : collectAutoScalingTargets(properties, currentRegion), currentRegion, autoScalingApplied, maskSecrets);
48722
49555
  }
49556
+ await this.applyReplicaIndexInsights(physicalId, logicalId, currentRegion, properties, previousProperties, addedReplicaRegions, replicaKeepOnRemoval, context?.replayingState === true || context?.desiredFromAwsReadback === true, warn, maskSecrets);
48723
49557
  if (!deepEqual(properties["TimeToLiveSpecification"], previousProperties["TimeToLiveSpecification"])) {
48724
49558
  const sendTtl = async (cmd) => {
48725
49559
  try {
@@ -48754,13 +49588,16 @@ var DynamoDBGlobalTableProvider = class {
48754
49588
  attributeName: live.AttributeName
48755
49589
  };
48756
49590
  }
48757
- if (ttlTarget) await sendTtl(new UpdateTimeToLiveCommand({
48758
- TableName: physicalId,
48759
- TimeToLiveSpecification: {
48760
- Enabled: ttlTarget.enabled,
48761
- AttributeName: ttlTarget.attributeName
48762
- }
48763
- }));
49591
+ if (ttlTarget) {
49592
+ markUnsettled("TimeToLiveSpecification");
49593
+ await sendTtl(new UpdateTimeToLiveCommand({
49594
+ TableName: physicalId,
49595
+ TimeToLiveSpecification: {
49596
+ Enabled: ttlTarget.enabled,
49597
+ AttributeName: ttlTarget.attributeName
49598
+ }
49599
+ }));
49600
+ }
48764
49601
  }
48765
49602
  const finalDescribe = await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: physicalId }));
48766
49603
  const impliedStream = replicationImpliedStreamSpecification(properties);
@@ -48791,7 +49628,7 @@ var DynamoDBGlobalTableProvider = class {
48791
49628
  }
48792
49629
  async applyCrossRegionReplicaTagsDiff(tableArn, region, oldTags, newTags, resourceType, logicalId, physicalIdForLogs, maskSecrets = (text) => text) {
48793
49630
  const warn = (message) => this.logger.warn(maskSecrets(message));
48794
- if (deepEqual(oldTags, newTags)) return;
49631
+ if (deepEqual(oldTags, newTags) && !isUnsettled("Replicas")) return;
48795
49632
  if (!tableArn) {
48796
49633
  warn(`Local DescribeTable returned no TableArn — cannot propagate Tags to cross-region replica ${region} of ${physicalIdForLogs}`);
48797
49634
  return;
@@ -48812,11 +49649,12 @@ var DynamoDBGlobalTableProvider = class {
48812
49649
  const plan = planTagDiff(oldTagsRaw, newTagsRaw);
48813
49650
  const tagWarning = tagPlanWarning(plan, resourceType, id);
48814
49651
  if (tagWarning !== void 0) this.logger.warn(maskSecrets(tagWarning));
48815
- const tagsToAdd = [...plan.set].map(([k, v]) => ({
49652
+ const tagsToAdd = [...isUnsettled("Replicas") ? planTagDiff(void 0, newTagsRaw).set : plan.set].map(([k, v]) => ({
48816
49653
  Key: k,
48817
49654
  Value: v
48818
49655
  }));
48819
49656
  const tagsToRemove = plan.remove;
49657
+ if (tagsToRemove.length > 0 || tagsToAdd.length > 0) markUnsettled("Replicas");
48820
49658
  if (tagsToRemove.length > 0) {
48821
49659
  await client.send(new UntagResourceCommand$2({
48822
49660
  ResourceArn: tableArn,
@@ -48833,6 +49671,7 @@ var DynamoDBGlobalTableProvider = class {
48833
49671
  }
48834
49672
  }
48835
49673
  async applyAutoScalingDiff(tableName, dimension, oldSettings, newSettings, client, indexName, budget, maskSecrets = (text) => text, progress) {
49674
+ const autoScalingKey = indexName !== void 0 ? "GlobalSecondaryIndexes" : dimension.includes("Write") ? "WriteProvisionedThroughputSettings" : "Replicas";
48836
49675
  const warn = (message) => this.logger.warn(maskSecrets(message));
48837
49676
  const asMaxRetries = autoScalingRetriesWithinDeleteBudget(budget, 8);
48838
49677
  const metricType = dimension.endsWith("WriteCapacityUnits") ? "DynamoDBWriteCapacityUtilization" : "DynamoDBReadCapacityUtilization";
@@ -48852,6 +49691,7 @@ var DynamoDBGlobalTableProvider = class {
48852
49691
  return;
48853
49692
  }
48854
49693
  try {
49694
+ markUnsettled(autoScalingKey);
48855
49695
  await withRetry(() => asClient.send(new RegisterScalableTargetCommand({
48856
49696
  ServiceNamespace: "dynamodb",
48857
49697
  ResourceId: resourceId,
@@ -48892,6 +49732,7 @@ var DynamoDBGlobalTableProvider = class {
48892
49732
  }
48893
49733
  if (tttCfg["DisableScaleIn"] !== void 0) targetTrackingConfig["DisableScaleIn"] = Boolean(tttCfg["DisableScaleIn"]);
48894
49734
  try {
49735
+ markUnsettled(autoScalingKey);
48895
49736
  await withRetry(() => asClient.send(new PutScalingPolicyCommand({
48896
49737
  PolicyName: policyName,
48897
49738
  ServiceNamespace: "dynamodb",
@@ -48920,6 +49761,7 @@ var DynamoDBGlobalTableProvider = class {
48920
49761
  return name === "ObjectNotFoundException" || msg.includes("No scaling policy found") || msg.includes("No scalable target found");
48921
49762
  };
48922
49763
  try {
49764
+ markUnsettled(autoScalingKey);
48923
49765
  await withRetry(() => asClient.send(new DeleteScalingPolicyCommand({
48924
49766
  PolicyName: policyName,
48925
49767
  ServiceNamespace: "dynamodb",
@@ -48939,6 +49781,7 @@ var DynamoDBGlobalTableProvider = class {
48939
49781
  if (!isObjectNotFound(err)) warn(`Could not delete auto-scaling policy on ${tableName} (${dimension}): ${describeAwsFailure(err).detail}. Run: ${pasteableAwsCommand(maskSecrets)`aws application-autoscaling delete-scaling-policy --policy-name ${policyName} --service-namespace dynamodb --resource-id ${resourceId} --scalable-dimension ${dimension}`.render()}`);
48940
49782
  }
48941
49783
  try {
49784
+ markUnsettled(autoScalingKey);
48942
49785
  await withRetry(() => asClient.send(new DeregisterScalableTargetCommand({
48943
49786
  ServiceNamespace: "dynamodb",
48944
49787
  ResourceId: resourceId,
@@ -49243,6 +50086,44 @@ var DynamoDBGlobalTableProvider = class {
49243
50086
  throw err;
49244
50087
  }
49245
50088
  }
50089
+ async readUnsettled(physicalId, logicalId, resourceType, names, recordedProperties, desiredProperties) {
50090
+ const live = await strictReadScope.run(names, () => this.readCurrentState(physicalId, logicalId, resourceType, recordedProperties));
50091
+ if (typeof live !== "object" || live === null) return live;
50092
+ const out = { ...live };
50093
+ if (out["BillingMode"] === "PAY_PER_REQUEST") delete out["WriteProvisionedThroughputSettings"];
50094
+ const unnamed = [];
50095
+ for (const name of names) {
50096
+ if (!Object.hasOwn(out, name)) continue;
50097
+ out[name] = projectNamed(out[name], recordedProperties?.[name], desiredProperties?.[name], name, unnamed);
50098
+ }
50099
+ for (const entry of unnamed.filter((e) => e.ambiguous === true)) this.logger.warn(safeMsg`${logicalId} (${resourceType}): ${entry.path} on AWS has entries cdkd cannot key by an identity, so convergence keeps the recorded ${entry.path} rather than risk removing an entry neither the record nor the template declares. Check it with 'cdkd drift'.`);
50100
+ for (const entry of unnamed.filter((e) => e.ambiguous !== true)) this.logger.warn(safeMsg`${logicalId} (${resourceType}): ${entry.path} on AWS holds ${entry.identity} ${entry.value}, which neither the record nor the template declares, so cdkd leaves it in place. If the failed update added it and it should not be there, remove it by hand (for a replica: aws dynamodb update-table --replica-updates Delete; for an index: --global-secondary-index-updates Delete).`);
50101
+ return out;
50102
+ }
50103
+ async unsettledInTransition(physicalId, _logicalId, _resourceType, names) {
50104
+ const MOVING = /* @__PURE__ */ new Set([
50105
+ "CREATING",
50106
+ "UPDATING",
50107
+ "DELETING"
50108
+ ]);
50109
+ try {
50110
+ const table = (await this.dynamoDBClient.send(new DescribeTableCommand({ TableName: physicalId }))).Table;
50111
+ const moving = /* @__PURE__ */ new Set();
50112
+ if (table?.TableStatus !== void 0 && MOVING.has(table.TableStatus)) {
50113
+ for (const name of names) if (name !== "TimeToLiveSpecification") moving.add(name);
50114
+ }
50115
+ if (names.has("Replicas") && (table?.Replicas ?? []).some((replica) => replica.ReplicaStatus !== void 0 && MOVING.has(replica.ReplicaStatus))) moving.add("Replicas");
50116
+ if (names.has("GlobalSecondaryIndexes") && (table?.GlobalSecondaryIndexes ?? []).some((index) => index.IndexStatus !== void 0 && MOVING.has(index.IndexStatus))) moving.add("GlobalSecondaryIndexes");
50117
+ const sse = table?.SSEDescription?.Status;
50118
+ if (names.has("SSESpecification") && (sse === "ENABLING" || sse === "DISABLING" || sse === "UPDATING")) moving.add("SSESpecification");
50119
+ if (names.has("TimeToLiveSpecification")) {
50120
+ if ((await this.dynamoDBClient.send(new DescribeTimeToLiveCommand({ TableName: physicalId }))).TimeToLiveDescription?.TimeToLiveStatus === "ENABLING") moving.add("TimeToLiveSpecification");
50121
+ }
50122
+ return moving;
50123
+ } catch {
50124
+ return names;
50125
+ }
50126
+ }
49246
50127
  async readCurrentState(physicalId, _logicalId, _resourceType, properties, context) {
49247
50128
  const afterOwnWrite = context?.afterOwnWrite === true;
49248
50129
  try {
@@ -49267,7 +50148,7 @@ var DynamoDBGlobalTableProvider = class {
49267
50148
  const currentRegion = await this.dynamoDBClient.config.region() ?? "";
49268
50149
  const tableNameForSubs = table.TableName ?? physicalId;
49269
50150
  const sdkReplicas = table.Replicas && table.Replicas.length > 0 ? currentRegion && !table.Replicas.some((r) => r.RegionName === currentRegion) ? [...table.Replicas, { RegionName: currentRegion }] : table.Replicas : [{ RegionName: currentRegion }];
49270
- const replicas = await Promise.all(sdkReplicas.map(async (r) => {
50151
+ const replicas = await Promise.all(sdkReplicas.map(async (r) => strictReadScope.run(replicaStrictness(r.ReplicaStatus), async () => {
49271
50152
  const entry = { Region: r.RegionName };
49272
50153
  if (!r.RegionName) return entry;
49273
50154
  const isLocal = r.RegionName === currentRegion;
@@ -49290,6 +50171,7 @@ var DynamoDBGlobalTableProvider = class {
49290
50171
  protection = regional.Table?.DeletionProtectionEnabled;
49291
50172
  streamArn = regional.Table?.LatestStreamArn;
49292
50173
  } catch (err) {
50174
+ if (strictFor("Replicas") && !(err instanceof ResourceNotFoundException$1)) throw err;
49293
50175
  if (err instanceof ResourceNotFoundException$1) this.logger.debug(safeMsg`Cross-region replica ${regionLabel} returned RNF on DescribeTable; omitting its protection and stream policy`);
49294
50176
  else this.logger.debug(safeMsg`Could not read the ${regionLabel} replica of ${tableNameForSubs}: ${describeAwsFailure(err).detail}`);
49295
50177
  }
@@ -49299,6 +50181,7 @@ var DynamoDBGlobalTableProvider = class {
49299
50181
  const tagsResp = await client.send(new ListTagsOfResourceCommand({ ResourceArn: replicaArn }));
49300
50182
  entry["Tags"] = normalizeAwsTagsToCfn(tagsResp.Tags);
49301
50183
  } catch (tagErr) {
50184
+ if (strictFor("Replicas") && !(tagErr instanceof ResourceNotFoundException$1)) throw tagErr;
49302
50185
  if (tagErr instanceof ResourceNotFoundException$1) {
49303
50186
  if (isLocal) throw tagErr;
49304
50187
  this.logger.debug(`Cross-region replica ${regionLabel} returned RNF on ListTagsOfResource; omitting Tags`);
@@ -49315,7 +50198,7 @@ var DynamoDBGlobalTableProvider = class {
49315
50198
  if (readAutoScaling) entry["ReadProvisionedThroughputSettings"] = { ReadCapacityAutoScalingSettings: readAutoScaling };
49316
50199
  }
49317
50200
  return entry;
49318
- }));
50201
+ })));
49319
50202
  result["Replicas"] = replicas;
49320
50203
  const localReplica = replicas.find((r) => r["Region"] === currentRegion);
49321
50204
  if (table.GlobalSecondaryIndexes && table.GlobalSecondaryIndexes.length > 0) {
@@ -49371,6 +50254,7 @@ var DynamoDBGlobalTableProvider = class {
49371
50254
  };
49372
50255
  else if (ttlStatus === "DISABLED") {}
49373
50256
  } catch (ttlErr) {
50257
+ if (strictFor("TimeToLiveSpecification")) throw ttlErr;
49374
50258
  this.logger.debug(`Could not read TimeToLive for ${tableNameForSubs}: ${describeAwsFailure(ttlErr).detail}`);
49375
50259
  }
49376
50260
  return result;
@@ -49386,6 +50270,7 @@ var DynamoDBGlobalTableProvider = class {
49386
50270
  const block = reverseMapReplicaContributorInsights(ci.ContributorInsightsStatus, ci.ContributorInsightsMode, declaredReplica?.["ContributorInsightsSpecification"]);
49387
50271
  if (block !== void 0) out["ContributorInsightsSpecification"] = block;
49388
50272
  } catch (err) {
50273
+ if (strictFor("Replicas") && !(err instanceof ResourceNotFoundException$1)) throw err;
49389
50274
  this.logger.debug(`Could not read ContributorInsights for ${tableName} in ${regionLabel}: ${describeAwsFailure(err).detail}`);
49390
50275
  }
49391
50276
  try {
@@ -49393,6 +50278,7 @@ var DynamoDBGlobalTableProvider = class {
49393
50278
  const block = reverseMapReplicaPitr(description?.PointInTimeRecoveryStatus, description?.RecoveryPeriodInDays, declaredReplica?.["PointInTimeRecoverySpecification"]);
49394
50279
  if (block !== void 0) out["PointInTimeRecoverySpecification"] = block;
49395
50280
  } catch (err) {
50281
+ if (strictFor("Replicas") && !(err instanceof ResourceNotFoundException$1)) throw err;
49396
50282
  this.logger.debug(`Could not read PointInTimeRecovery for ${tableName} in ${regionLabel}: ${describeAwsFailure(err).detail}`);
49397
50283
  }
49398
50284
  try {
@@ -49403,6 +50289,7 @@ var DynamoDBGlobalTableProvider = class {
49403
50289
  out["KinesisStreamSpecification"] = ksOut;
49404
50290
  }
49405
50291
  } catch (err) {
50292
+ if (strictFor("Replicas") && !(err instanceof ResourceNotFoundException$1)) throw err;
49406
50293
  this.logger.debug(`Could not read KinesisStreamingDestination for ${tableName} in ${regionLabel}: ${describeAwsFailure(err).detail}`);
49407
50294
  }
49408
50295
  return out;
@@ -49440,6 +50327,7 @@ var DynamoDBGlobalTableProvider = class {
49440
50327
  }
49441
50328
  return reverseMapStreamPolicy(live, container);
49442
50329
  } catch (err) {
50330
+ if (strictFor("Replicas") && !(err instanceof ResourceNotFoundException$1)) throw err;
49443
50331
  this.logger.debug(safeMsg`Could not read the ${what} of the ${regionLabel} replica of ${tableName}: ${describeAwsFailure(err).detail}`);
49444
50332
  if (afterOwnWrite && last !== void 0 && last !== "") return reverseMapStreamPolicy(last, container);
49445
50333
  if (afterOwnWrite && (isThrottlingError(err) || isTransientServerError(err) || isAmbiguousOutcomeError(err) || err instanceof ResourceNotFoundException$1)) return declaredMember();
@@ -49488,6 +50376,7 @@ var DynamoDBGlobalTableProvider = class {
49488
50376
  TargetTrackingScalingPolicyConfiguration: tttConfig
49489
50377
  };
49490
50378
  } catch (err) {
50379
+ if (strictFor(indexName !== void 0 ? "GlobalSecondaryIndexes" : scalableDimension.includes("Write") ? "WriteProvisionedThroughputSettings" : "Replicas")) throw err;
49491
50380
  this.logger.debug(`Could not read application-autoscaling settings for ${resourceId} (${scalableDimension}): ${describeAwsFailure(err).detail}`);
49492
50381
  return null;
49493
50382
  }
@@ -49707,9 +50596,48 @@ const REPLICA_SETTING_MEMBERS = [
49707
50596
  "ContributorInsightsSpecification",
49708
50597
  "KinesisStreamSpecification",
49709
50598
  "ResourcePolicy",
49710
- "ReplicaStreamSpecification"
50599
+ "ReplicaStreamSpecification",
50600
+ "GlobalSecondaryIndexes"
49711
50601
  ];
50602
+ const REPLICATION_MODE_KEY = "GlobalTableSettingsReplicationMode";
50603
+ function readReplicationMode(properties) {
50604
+ const replicas = Array.isArray(properties["Replicas"]) ? properties["Replicas"] : [];
50605
+ const declared = replicas.map((entry) => asRecord(entry)?.[REPLICATION_MODE_KEY]).filter((value) => value !== void 0 && value !== null);
50606
+ if (declared.length === 0) return { kind: "absent" };
50607
+ const [first] = declared;
50608
+ if (typeof first !== "string" || first === "" || declared.some((v) => v !== first)) return {
50609
+ kind: "unusable",
50610
+ reason: `Replicas[].${REPLICATION_MODE_KEY} must be one non-empty string`
50611
+ };
50612
+ if (replicas.length !== 1) return {
50613
+ kind: "unusable",
50614
+ reason: `Replicas[].${REPLICATION_MODE_KEY} can be declared only on a table with exactly one replica, as CloudFormation refuses it ("GlobalTableSettingsReplicationMode can be specified when exactly one replica is present"); remove it, or keep one replica`
50615
+ };
50616
+ return {
50617
+ kind: "usable",
50618
+ mode: first
50619
+ };
50620
+ }
50621
+ function replicationModeShape(properties) {
50622
+ return (Array.isArray(properties["Replicas"]) ? properties["Replicas"] : []).map((entry) => asRecord(entry)?.[REPLICATION_MODE_KEY] ?? null);
50623
+ }
50624
+ function replicationModeUpdate(properties, previousProperties) {
50625
+ const want = readReplicationMode(properties);
50626
+ if (want.kind === "unusable") return void 0;
50627
+ const had = readReplicationMode(previousProperties);
50628
+ const desired = want.kind === "usable" ? want.mode : void 0;
50629
+ if (desired === (had.kind === "usable" ? had.mode : void 0)) return void 0;
50630
+ return desired ?? "DISABLED";
50631
+ }
50632
+ function replicationModeCorrection(properties, previousProperties, liveMode) {
50633
+ const want = readReplicationMode(properties);
50634
+ if (want.kind !== "usable") return void 0;
50635
+ if (replicationModeUpdate(properties, previousProperties) !== void 0) return void 0;
50636
+ return (liveMode ?? "DISABLED") === want.mode ? void 0 : want.mode;
50637
+ }
49712
50638
  function replicaSettingsRefusal(properties, previousProperties, currentRegion) {
50639
+ const mode = readReplicationMode(properties);
50640
+ if (mode.kind === "unusable" && (previousProperties === void 0 || !deepEqual(replicationModeShape(properties), replicationModeShape(previousProperties)))) return mode.reason;
49713
50641
  const desired = Array.isArray(properties["Replicas"]) ? properties["Replicas"] : [];
49714
50642
  const crossRegionCreate = previousProperties === void 0 && desired.some((entry) => {
49715
50643
  const region = asRecord(entry)?.["Region"];
@@ -50386,7 +51314,7 @@ function buildLiveRecoveryGsiBaseline(desiredSdkIndexes, liveIndexes, options) {
50386
51314
  }
50387
51315
  function toSdkReplicaGlobalSecondaryIndexes(replicaIndexes, billingMode, diagnostics, maskSecrets = (text) => text) {
50388
51316
  if (!Array.isArray(replicaIndexes) || replicaIndexes.length === 0) return void 0;
50389
- return replicaIndexes.map((entry) => {
51317
+ const sendable = replicaIndexes.map((entry) => {
50390
51318
  const cfn = asRecord(entry);
50391
51319
  if (!cfn) return entry;
50392
51320
  const indexName = cfn["IndexName"];
@@ -50395,7 +51323,8 @@ function toSdkReplicaGlobalSecondaryIndexes(replicaIndexes, billingMode, diagnos
50395
51323
  if (overrides.ProvisionedThroughputOverride) sdk.ProvisionedThroughputOverride = overrides.ProvisionedThroughputOverride;
50396
51324
  if (overrides.OnDemandThroughputOverride) sdk.OnDemandThroughputOverride = overrides.OnDemandThroughputOverride;
50397
51325
  return sdk;
50398
- });
51326
+ }).filter((sdk) => asRecord(sdk) === void 0 || sdk.ProvisionedThroughputOverride !== void 0 || sdk.OnDemandThroughputOverride !== void 0);
51327
+ return sendable.length > 0 ? sendable : void 0;
50399
51328
  }
50400
51329
  function toSdkReplicaThroughputOverrides(cfn, billingMode, diagnostics, context, maskSecrets = (text) => text) {
50401
51330
  const explicitProvisioned = asRecord(cfn["ProvisionedThroughputOverride"]);
@@ -50513,6 +51442,10 @@ function deepEqual(a, b) {
50513
51442
  return false;
50514
51443
  }
50515
51444
  }
51445
+ function lsiListOrEmpty(value) {
51446
+ if (value === void 0 || value === null) return [];
51447
+ return value;
51448
+ }
50516
51449
 
50517
51450
  //#endregion
50518
51451
  //#region src/provisioning/protection-flags.ts
@@ -50942,31 +51875,63 @@ async function updateInPlace(engine, { changedProperties, conditions, counts, cu
50942
51875
  const previousForUpdate = reattached?.previous ?? previousWithSecretsDropped;
50943
51876
  const changedForProvider = new Set(changedProperties);
50944
51877
  for (const key of /* @__PURE__ */ new Set([...Object.keys(previousWithNoEchoHeld), ...Object.keys(previousForUpdate)])) if (keyOrderFreeJson(previousForUpdate[key]) !== keyOrderFreeJson(previousWithNoEchoHeld[key])) changedForProvider.add(key);
51878
+ const unsettled = unsettledPropertiesOf(currentResource);
50945
51879
  if (changedForProvider.size === 0) for (const key of /* @__PURE__ */ new Set([...Object.keys(updateProps), ...Object.keys(previousForUpdate)])) changedForProvider.add(key);
50946
51880
  if (reattached !== void 0) engine.logger.info(safeMsg` ${logicalId} (${resourceType}) lost its attachment to ${reattached.parents.join(", ")}, which this deploy re-created under the same name: attaching it again`);
50947
51881
  if (droppedPrincipalKinds.length > 0) {
50948
51882
  const kinds = droppedPrincipalKinds.join(" / ");
50949
51883
  engine.logger.warn(safeMsg`${logicalId} (${resourceType}): the recorded ${kinds} holds a secret reference the template still spells the same way, so cdkd re-applies it to the principals this deploy resolved it to and removes it from none of them. If that secret's value changed since the last deploy, a principal only the OLD value named still has the policy or membership: remove it from that principal by hand.`);
50950
51884
  }
50951
- const removal = prepareRemovalForUpdate(updateProvider, resourceType, updateProps, previousForUpdate);
51885
+ const unsettledIdentity = {
51886
+ provider: updateProvider,
51887
+ logicalId,
51888
+ physicalId: currentResource.physicalId,
51889
+ resourceType,
51890
+ recordedProperties: currentResource.properties ?? {}
51891
+ };
51892
+ const previousSettled = await settleUnsettledPrevious({
51893
+ ...unsettledIdentity,
51894
+ names: unsettled,
51895
+ previous: previousForUpdate,
51896
+ desired: updateProps
51897
+ });
51898
+ if (unsettled.has("Tags")) engine.logger.warn(safeMsg`${logicalId} (${resourceType}): an earlier failed update left Tags unsettled. cdkd re-applies the template's tags and removes only the recorded ones the template dropped; a tag that failed update added and no template declares is left on the resource. Remove it by hand if it should not be there.`);
51899
+ const removal = prepareRemovalForUpdate(updateProvider, resourceType, updateProps, previousSettled);
50952
51900
  let result;
50953
51901
  let resultProvisionedBy = updateDecision.provisionedBy;
50954
51902
  let captureProvider = updateProvider;
50955
51903
  let replacedAtGeneration;
50956
51904
  const inlinePolicyClaimed = engine.inlinePolicyClaimedFor(resourceType, logicalId, stateResources);
50957
51905
  try {
50958
- result = await engine.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => updateProvider.update(logicalId, currentResource.physicalId, resourceType, removal.properties, previousForUpdate, {
51906
+ result = await engine.withRetry(() => withCurrentResourceSecrets(updateSecrets, () => updateProvider.update(logicalId, currentResource.physicalId, resourceType, removal.properties, previousSettled, {
50959
51907
  maskSecrets: createSecretMasker(updateSecrets),
50960
51908
  expectedRegion: engine.stackRegion,
50961
51909
  recordedAttributes: currentResource.attributes,
50962
51910
  ...inlinePolicyClaimed && { inlinePolicyClaimed },
50963
51911
  ...removal.context,
50964
- changedProperties: changedForProvider
51912
+ changedProperties: changedForProvider,
51913
+ markUnsettled: (propertyName) => {
51914
+ if (typeof propertyName !== "string" || propertyName === "") return;
51915
+ if (!Object.hasOwn(resolvedProps, propertyName) && !Object.hasOwn(currentResource.properties ?? {}, propertyName)) {
51916
+ engine.logger.debug(safeMsg`${logicalId}: ignored an unsettled mark for ${propertyName}, which is not one of its properties`);
51917
+ return;
51918
+ }
51919
+ let marks = engine.unsettledMarks.get(logicalId);
51920
+ if (marks === void 0) {
51921
+ marks = /* @__PURE__ */ new Set();
51922
+ engine.unsettledMarks.set(logicalId, marks);
51923
+ }
51924
+ marks.add(propertyName);
51925
+ },
51926
+ ...unsettled.size > 0 && { unsettledProperties: unsettled }
50965
51927
  })), logicalId, void 0, void 0, updateProvider);
50966
51928
  if (result.sentNothing === true) engine.replacementRun.updatesThatSentNothing.add(logicalId);
51929
+ engine.unsettledMarks.delete(logicalId);
50967
51930
  if (result.wasReplaced === true && result.outcome === "partial") engine.replacementRun.replacedOldMaySurvive.set(logicalId, result.oldResourceSurvivor === "kept" ? "kept" : "unconfirmed");
50968
51931
  result = withoutInjectedRemovals(result, removal.injected);
50969
- if (removal.unhandled.length > 0) engine.logger.warn(removalWarning(logicalId, resourceType, removal.unhandled));
51932
+ const unhandledByCause = splitUnhandledRemovals(removal.unhandled, previousForUpdate, unsettled);
51933
+ if (unhandledByCause.removedFromTemplate.length > 0) engine.logger.warn(removalWarning(logicalId, resourceType, unhandledByCause.removedFromTemplate));
51934
+ if (unhandledByCause.addedByFailedUpdate.length > 0) engine.logger.warn(addedByFailedUpdateWarning(logicalId, resourceType, unhandledByCause.addedByFailedUpdate));
50970
51935
  } catch (updateError) {
50971
51936
  const ccUnsupported = isUpdateUnsupportedError(updateError, logicalId);
50972
51937
  const replaceOptIn = updateError instanceof ResourceUpdateNotSupportedError && engine.options.replace === true;
@@ -51146,6 +52111,7 @@ async function updateInPlace(engine, { changedProperties, conditions, counts, cu
51146
52111
  logicalId,
51147
52112
  generation: fallbackGeneration
51148
52113
  }, replaceFallback));
52114
+ engine.unsettledMarks.delete(logicalId);
51149
52115
  result = fallbackOutcome.result;
51150
52116
  resultProvisionedBy = fallbackOutcome.provisionedBy;
51151
52117
  captureProvider = fallbackOutcome.captureProvider;
@@ -51166,6 +52132,12 @@ async function updateInPlace(engine, { changedProperties, conditions, counts, cu
51166
52132
  throw updateError;
51167
52133
  }
51168
52134
  }
52135
+ const stillUnsettled = result.wasReplaced ? [] : await unsettledAfterUpdate({
52136
+ ...unsettledIdentity,
52137
+ names: unsettled,
52138
+ desired: updateProps
52139
+ });
52140
+ if (stillUnsettled.length > 0) engine.logger.warn(safeMsg`${logicalId} (${resourceType}): the update succeeded, but AWS does not yet show the template's ${stillUnsettled.join(", ")}; cdkd keeps ${stillUnsettled.length === 1 ? "it" : "them"} unsettled and converges again on the next deploy.`);
51169
52141
  engine.replacementRun.updateWasReplaced.set(logicalId, result.wasReplaced === true);
51170
52142
  if (result.wasReplaced !== true && (hasPassProvenance(updateSecrets) || referenceProvenanceOf(currentResource) !== void 0)) {
51171
52143
  const cached = cachedCreateOnlyPropertyPaths(resourceType);
@@ -51202,6 +52174,7 @@ async function updateInPlace(engine, { changedProperties, conditions, counts, cu
51202
52174
  ...dependencies && dependencies.length > 0 && { dependencies },
51203
52175
  ...extractTemplateAttributes(template, logicalId),
51204
52176
  provisionedBy: resultProvisionedBy,
52177
+ ...stillUnsettled.length > 0 && { unsettledProperties: stillUnsettled },
51205
52178
  ...keepsParameterRefusal && {
51206
52179
  observedBaselineRefused: true,
51207
52180
  observedBaselineRefusalReason: "unverifiable-parameter"
@@ -51610,6 +52583,7 @@ async function provisionUpdate(engine, logicalId, change, stateResources, stackN
51610
52583
  for (const path of provenanceMoved.paths) rewrittenPaths.add(path);
51611
52584
  if (provenanceMoved.paths.size > 0) engine.logger.info(safeMsg`${logicalId} is sent: ${[...provenanceMoved.paths].sort().join(", ")} read a secret-derived value at a newer version than ${logicalId} was deployed with (its upstream changed since then)`);
51612
52585
  const recordMatchesDesired = movedMasked.size === 0 && rewrittenPaths.size === 0 && keyOrderFreeJson(desiredForSkipCheckAsWritten) === keyOrderFreeJson(currentPropsAsWritten);
52586
+ const unsettledNames = unsettledPropertiesOf(currentResource);
51613
52587
  const movedAsWritten = (key) => movedMasked.has(key) || rewrittenPaths.has(key) || keyOrderFreeJson(desiredForSkipCheckAsWritten[key]) !== keyOrderFreeJson(currentPropsAsWritten[key]);
51614
52588
  const applyAttributeOnlyUpdate = (attributeChanges) => {
51615
52589
  const attrSummary = attributeChanges.map((a) => `${a.attribute}: ${a.oldValue ?? "(unset)"} → ${a.newValue ?? "(unset)"}`).join(", ");
@@ -51684,7 +52658,7 @@ async function provisionUpdate(engine, logicalId, change, stateResources, stackN
51684
52658
  const lateReplacementDeclined = /* @__PURE__ */ new Set();
51685
52659
  const differsWhy = (key) => !lateReplacementDeclined.has(key) ? "differs; the provider is not known to report this property exactly, so the difference may be its normalization" : lateCrossPrefixRefused ? "differs; the replacement was refused: see the state-prefix warning above" : `differs; the replacement was not approved (--require-approval=${engine.options.requireApproval ?? "never"})`;
51686
52660
  if (witnessMigrates && !typeChanged && echoCandidates.length > 0 && hasAddressablePhysicalId(currentResource)) await readOnce();
51687
- if (!typeChanged && !suppliesFreshMaskOnlyValue && lostChild === void 0 && recreateDirectionFor(engine.options, stackName, logicalId) === void 0 && recordMatchesDesired) {
52661
+ if (!typeChanged && !suppliesFreshMaskOnlyValue && lostChild === void 0 && recreateDirectionFor(engine.options, stackName, logicalId) === void 0 && recordMatchesDesired && unsettledNames.size === 0) {
51688
52662
  if (provenanceUnchanged.length > 0) stateResources[logicalId] = withRefreshedReadVersions(stateResources[logicalId] ?? currentResource, provenanceUnchanged);
51689
52663
  if (change.attributeChanges && change.attributeChanges.length > 0) {
51690
52664
  applyAttributeOnlyUpdate(change.attributeChanges);
@@ -51820,7 +52794,7 @@ async function provisionUpdate(engine, logicalId, change, stateResources, stackN
51820
52794
  }
51821
52795
  }
51822
52796
  const confirmedPaths = /* @__PURE__ */ new Set([...noEchoHeldPaths, ...parameterSettledPaths]);
51823
- if (confirmedPaths.size > 0 && !typeChanged && lostChild === void 0 && recreateDirectionFor(engine.options, stackName, logicalId) === void 0 && recordMatchesDesired && Object.keys(resolvedProps).every((key) => confirmedPaths.has(key) || otherFreshAt(key).length === 0 && !pendingParameterLeaves.has(key))) {
52797
+ if (confirmedPaths.size > 0 && !typeChanged && lostChild === void 0 && recreateDirectionFor(engine.options, stackName, logicalId) === void 0 && recordMatchesDesired && unsettledNames.size === 0 && Object.keys(resolvedProps).every((key) => confirmedPaths.has(key) || otherFreshAt(key).length === 0 && !pendingParameterLeaves.has(key))) {
51824
52798
  engine.logger.debug(safeMsg`Skipping ${logicalId}: AWS already holds every NoEcho value it carries, and nothing else changed`);
51825
52799
  const staleHeld = staleCoordinates.filter((coordinate) => typeof coordinate[0] === "string" && parameterHeldKeys.has(coordinate[0]));
51826
52800
  if (staleHeld.length > 0) {
@@ -51935,8 +52909,9 @@ async function provisionUpdate(engine, logicalId, change, stateResources, stackN
51935
52909
  const changedProperties = new Set([.../* @__PURE__ */ new Set([
51936
52910
  ...Object.keys(desiredForSkipCheckAsWritten),
51937
52911
  ...Object.keys(currentPropsAsWritten),
51938
- ...Object.keys(resolvedProps)
51939
- ])].filter((key) => movedAsWritten(key) || !confirmedPaths.has(key) && (pendingParameterLeaves.has(key) || otherFreshAt(key).length > 0)));
52912
+ ...Object.keys(resolvedProps),
52913
+ ...unsettledNames
52914
+ ])].filter((key) => unsettledNames.has(key) || movedAsWritten(key) || !confirmedPaths.has(key) && (pendingParameterLeaves.has(key) || otherFreshAt(key).length > 0)));
51940
52915
  let previousForProvider = currentPropsAsWritten;
51941
52916
  for (const coordinate of witness?.confirmed ?? []) {
51942
52917
  const value = valueAtCoordinate(resolvedProps, coordinate);
@@ -52223,7 +53198,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
52223
53198
  const savedFor = savedIds.join(", ");
52224
53199
  try {
52225
53200
  const partialState = {
52226
- version: 13,
53201
+ version: 14,
52227
53202
  region: engine.stackRegion,
52228
53203
  stackName: currentState.stackName,
52229
53204
  resources: newResources,
@@ -52352,6 +53327,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
52352
53327
  } catch (provisionError) {
52353
53328
  engine.interrupted = true;
52354
53329
  engine.interruptCause ??= "sibling-failure";
53330
+ if (change.changeType === "UPDATE") recordUnsettledMarks(engine, newResources, logicalId);
52355
53331
  const refused = isRefusedBeforeApplying(provisionError, logicalId);
52356
53332
  const attemptedGeneration = change.changeType === "UPDATE" && !refused && !isReplacementNameRefusal(provisionError, logicalId) ? engine.replacementRun.attemptedNameGeneration.get(logicalId) : void 0;
52357
53333
  const statePhysicalId = newResources[logicalId]?.physicalId ?? previousState?.physicalId;
@@ -52518,6 +53494,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
52518
53494
  await retryCarriedSupersededResources(engine, currentState, carriedSuperseded, newResources, { waitInUse: releasedSomething });
52519
53495
  }
52520
53496
  } catch (error) {
53497
+ recordUnsettledMarks(engine, newResources);
52521
53498
  warnUnretriedReplacedDeletes(engine.replacementRun, engine.replacementDeps(), engine.interruptCause === "user" ? "interrupted" : "failed");
52522
53499
  const initialDeploy = currentEtag === void 0;
52523
53500
  const written = /* @__PURE__ */ new Set([...engine.replacementRun.restoredLostChildren, ...completedOperations.map((op) => op.logicalId)]);
@@ -52574,7 +53551,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
52574
53551
  }
52575
53552
  try {
52576
53553
  const preRollbackState = {
52577
- version: 13,
53554
+ version: 14,
52578
53555
  region: engine.stackRegion,
52579
53556
  stackName: currentState.stackName,
52580
53557
  resources: newResources,
@@ -52637,9 +53614,10 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
52637
53614
  rollbackSettledNested = rollbackResult.settledNested;
52638
53615
  rollbackRemainingFailedOps = rollbackResult.remainingFailedOps;
52639
53616
  }
53617
+ recordUnsettledMarks(engine, newResources);
52640
53618
  try {
52641
53619
  const postRollbackState = {
52642
- version: 13,
53620
+ version: 14,
52643
53621
  region: engine.stackRegion,
52644
53622
  stackName: currentState.stackName,
52645
53623
  resources: newResources,
@@ -52660,8 +53638,9 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
52660
53638
  engine.logger.debug(safeMsg`Retrying state save after rollback (ETag mismatch): ${asIsMessage(describeAwsFailure(saveError).detail)}`);
52661
53639
  try {
52662
53640
  const freshEtag = (await engine.stateBackend.getState(stackName, engine.stackRegion))?.etag;
53641
+ recordUnsettledMarks(engine, newResources);
52663
53642
  const postRollbackState = {
52664
- version: 13,
53643
+ version: 14,
52665
53644
  region: engine.stackRegion,
52666
53645
  stackName: currentState.stackName,
52667
53646
  resources: newResources,
@@ -52698,7 +53677,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
52698
53677
  }
52699
53678
  return {
52700
53679
  state: {
52701
- version: 13,
53680
+ version: 14,
52702
53681
  region: engine.stackRegion,
52703
53682
  stackName: currentState.stackName,
52704
53683
  resources: newResources,
@@ -52717,7 +53696,7 @@ async function executeDeployment(engine, template, currentState, changes, dag, e
52717
53696
  }
52718
53697
  async function persistStateAfterOutputFailure(engine, stackName, currentState, newResources, currentEtag, pendingMigration) {
52719
53698
  const buildState = () => ({
52720
- version: 13,
53699
+ version: 14,
52721
53700
  region: engine.stackRegion,
52722
53701
  stackName: currentState.stackName,
52723
53702
  resources: newResources,
@@ -52751,6 +53730,13 @@ function journaledOrphanPolicy(policy) {
52751
53730
  if (policy === void 0) return void 0;
52752
53731
  return policy === "Delete" || policy === "Retain" || policy === "Snapshot" || policy === "RetainExceptOnCreate" ? policy : "Retain";
52753
53732
  }
53733
+ function recordUnsettledMarks(engine, newResources, only) {
53734
+ for (const [logicalId, marks] of engine.unsettledMarks) {
53735
+ if (only !== void 0 && logicalId !== only) continue;
53736
+ if (marks.size === 0 || !Object.hasOwn(newResources, logicalId)) continue;
53737
+ newResources[logicalId] = withUnsettledProperties(newResources[logicalId], marks);
53738
+ }
53739
+ }
52754
53740
 
52755
53741
  //#endregion
52756
53742
  //#region src/deployment/deploy-engine/deploy-flow.ts
@@ -52792,7 +53778,7 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
52792
53778
  clock.lap("state load");
52793
53779
  noteDeployStateRecord(currentStateData?.state !== void 0);
52794
53780
  const currentState = currentStateData?.state ?? {
52795
- version: 13,
53781
+ version: 14,
52796
53782
  region: engine.stackRegion,
52797
53783
  stackName,
52798
53784
  resources: {},
@@ -53095,7 +54081,7 @@ async function doDeployWithPrefetch(engine, stackName, template, createOnlyPrefe
53095
54081
  await resolveStackInstanceId();
53096
54082
  try {
53097
54083
  const refreshedState = {
53098
- version: 13,
54084
+ version: 14,
53099
54085
  region: engine.stackRegion,
53100
54086
  stackName: currentState.stackName,
53101
54087
  resources: currentState.resources,
@@ -53383,6 +54369,7 @@ var DeployEngine = class {
53383
54369
  replacementRun = new ReplacementRunState();
53384
54370
  outputsRun = new OutputsRunState();
53385
54371
  attemptedResolvedProps = /* @__PURE__ */ new Map();
54372
+ unsettledMarks = /* @__PURE__ */ new Map();
53386
54373
  resumedCreates = /* @__PURE__ */ new Map();
53387
54374
  generatedNameGuard;
53388
54375
  liveTaskLabels = /* @__PURE__ */ new Map();
@@ -53575,6 +54562,7 @@ var DeployEngine = class {
53575
54562
  this.noEchoRun = new NoEchoRunState();
53576
54563
  this.replacementRun = new ReplacementRunState();
53577
54564
  this.attemptedResolvedProps = /* @__PURE__ */ new Map();
54565
+ this.unsettledMarks = /* @__PURE__ */ new Map();
53578
54566
  this.resumedCreates = /* @__PURE__ */ new Map();
53579
54567
  this.generatedNameGuard = void 0;
53580
54568
  this.liveTaskLabels = /* @__PURE__ */ new Map();
@@ -53779,5 +54767,5 @@ function sameGenerationClaimsOf(record) {
53779
54767
  }
53780
54768
 
53781
54769
  //#endregion
53782
- export { computeImplicitDeleteEdges as $, AWS_NO_VALUE as $a, recordAttributeIdCopy as $c, RollbackInlinePolicyWriters as $i, getBootstrapMarkerKey as $l, carriedExportAliasExposure as $n, refuseMalformedResourceEntriesForDeploy as $o, namingSecretsWithRecordedNoEcho as $r, blockDeviceMappingsDifferOnlyInDeleteOnTermination as $s, lookupEachName as $t, StageLoadError as $u, beginDeleteWait as A, applyRoleArnIfSet as Aa, logOnlyValueCount as Ac, refuseMalformedDesiredTags as Ai, hasUnverifiableParameterRefusal as Al, REDACTED_DELETE_ADDRESS_SKIP_REASON as An, malformedOrphanRowsKeptWarning as Ao, cyan as Ar, MULTI_REGION_RECREATE_BLOCKED_TYPES as As, displacedOpClause as At, loadCdkJson as Au, waitForIndexesSettled as B, classifyRecordedSecretRegion as Ba, scrubResourceRecord as Bc, waitForLambdaFunctionActive as Bi, timePhase as Bl, retiredNameGenerationsAfter as Bn, malformedStateRefusalMessage as Bo, supersededAfterRollback as Br, coerceCfnInteger as Bs, getCurrentNestedStackContext as Bt, ssmResolvedValueType as Bu, planContributorInsightsOp as C, resolveDynamicReferences as Ca, redactForState as Cc, extractDeploymentEventError as Ci, withStackInstanceIdWithheld as Cl, replacementNeverSwapped as Cn, malformedExportNamesWarning as Co, proposeRenames as Cr, findSilentDropProperties as Cs, makeSiblingClaimReader as Ct, warnFinchArgvExposure as Cu, reverseMapTableContributorInsights as D, outputReferenceProvenanceOf as Da, createUnionSecretMasker as Dc, DBPROXY_TAG_OPTIONS as Di, exportNamesCarriedFrom as Dl, findNestedStackTypeChanges as Dn, malformedLocalResourcesWarning as Do, withStackRecords as Dr, hasNoCloudControlHandlers as Ds, keptForRetainedRecord as Dt, synthesisStatusMessage as Du, reverseMapIndexContributorInsights as E, keepHeldTokenProvenance as Ea, carryLogOnlyValues as Ec, DBPROXY_TAGS_WHAT as Ei, describeRegionValueKind as El, orphanNeedsIdentity as En, malformedLocalResourceEntriesWarning as Eo, getStackRecords as Er, NO_CC_HANDLERS_REASON as Es, resolvePendingCloudControlRequests as Et, Synthesizer as Eu, DELETE_INDEX_WAIT_PROCEED_NOTE as F, sendableAssumeRoleCommand as Fa, unionOfSecretBags as Fc, CC_BROKEN_REASON as Fi, orphansCarriedFrom as Fl, updatePartialReason as Fn, malformedRenderedContainersWarning as Fo, addSuperseded as Fr, coerceWarmThroughput as Fs, recordDisplacedSkips as Ft, resolveStateBucketWithDefault as Fu, sendTtlWaitingOutRateLimit as G, isUnboundTemplateParameter as Ga, isUncertifiedBaselineMaskPosition as Gc, withPrintingSecrets as Gi, buildAssetRedirectMap as Gl, reachableDivergentParameters as Gn, refuseMalformedOrphanRecordsForDestroy as Go, noEchoAttributeNamesOf as Gr, replayWarn as Gs, isHandledOrphan as Gt, uploadCfnTemplate as Gu, isTtlRateLimited as H, producerRegionsFromState as Ha, withoutPhysicalNameCopies as Hc, readsNoEchoDeleteValues as Hi, isSensitiveAttributeName as Hl, withNameGenerationReached as Hn, refuseDivergentRecordRegionForDestroy as Ho, supersededHolderOf as Hr, configIntegerRefusal as Hs, deleteJournaledOrphans as Ht, CFN_TEMPLATE_URL_LIMIT as Hu, INDEX_SETTLE_POLL_INTERVAL_MS as I, AWS_CREDENTIAL_ENV_KEYS as Ia, createSecretMasker as Ic, ProviderRegistry as Ii, shouldRetainResource as Il, nameGenerationCarriedFrom as In, malformedResourceEntriesWarning as Io, deleteSupersededEntry as Ir, isWarmThroughputDecrease as Is, revertNestedChildFromJournal as It, resolveStateBucketWithDefaultAndSource as Iu, hasCdkAutoDeleteTag as J, isImpossibleEmptyStoredAttribute as Ja, identityKeyFor as Jc, customResourceResponseExpirationWarning as Ji, rewriteTemplateAssetReferences as Jl, displayTextOrWithheld as Jn, refuseMalformedOrphansForOrphan as Jo, noEchoParameterNamesOf as Jr, requireConfigString as Js, makeForeignHolderScan as Jt, expectedOwnerParam as Ju, ECR_AUTO_DELETE_IMAGES_TAG as K, parameterTypeMayLoseSecretIdentity as Ka, pathCrossesDottedKey as Kc, CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID as Ki, createAssetRedirectResolver as Kl, resourcesNamingDeclaredParameter as Kn, refuseMalformedOrphans as Ko, noEchoComparisonForTemplate as Kr, requireConfigArray as Ks, journaledOrphanLines as Kt, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as Ku, deleteTableWithIndexBusyRetry as L, applyCallerIdentityCredentials as La, errorCauseChain as Lc, ccBrokenReason as Li, stackInstanceIdCarriedFrom as Ll, nameGenerationHighWaterOf as Ln, malformedResourcePropertiesWarning as Lo, holdsSupersededResources as Lr, toCfnInteger as Ls, revertedNestedRowIds as Lt, resolveUseCdkBootstrapAssets as Lu, deleteBudgetKey as M, assertSendableRoleArn as Ma, recordLogOnlyParameterValue as Mc, tagPlanWarning as Mi, importableOutputs as Ml, redactedDeleteAddressFields as Mn, malformedOrphansWarning as Mo, green as Mr, isStatefulRecreateTargetSync as Ms, dropSettledNestedJournals as Mt, resolveAutoAssetStorage as Mu, resolveDynamoDbDeleteBudgetClock as N, explicitRoleArnOrThrow as Na, recordLogOnlyValue as Nc, definedAttributes as Ni, isReadableBag as Nl, redactedDeleteAddressSkip as Nn, malformedOutputsRefusalMessage as No, red as Nr, renderStatefulReason as Ns, getNestedRevertRun as Nt, resolveCaptureObservedState as Nu, stripIndexContributorInsights as O, recordedOutputReferenceRegions as Oa, hasMaskableValues as Oc, planTagDiff as Oi, hasReadableExportSet as Ol, getCurrentProducerRegions as On, malformedOrphanRecordsRefusalMessage as Oo, replacedDeleteFailureVerdict as Or, findReplacedReadersOfRecreateTargets as Os, recordRetainedForReadoption as Ot, getDefaultStateBucketName as Ou, resolveDynamoDbDeleteBudgetMs as P, isIamRoleArn as Pa, shareLogOnlyValues as Pc, stringifyIfAssigned as Pi, orphansAfterRollback as Pl, updatePartialMessage as Pn, malformedOutputsWarning as Po, yellow as Pr, WARM_THROUGHPUT_MEMBERS as Ps, nestedChildStackName as Pt, resolveSkipPrefix as Pu, IMPLICIT_DELETE_DEPENDENCIES as Q, keepsSecretReferenceToken as Qa, physicalNameCopiesOf as Qc, unchangedBehindSecretReference as Qi, ensureAssetStorage as Ql, secretSafeKeyDisplay as Qn, refuseMalformedResourceEntries as Qo, maskEventTextWithBoundBags as Qr, withRetry as Qs, isAccessDeniedError as Qt, AssemblyReader as Qu, maskedLogger as R, callerEnvCredentials as Ra, maskSecretsInError as Rc, isCustomResource as Ri, PhaseClock as Rl, nameScopeOf as Rn, malformedResourcesWarning as Ro, isSupersededResourceRecord as Rr, toFiniteNumber as Rs, withNestedRevertRun as Rt, stateBucketExistenceConfirmed as Ru, indexDeclaresContributorInsights as S, s3BucketWebsiteUrl as Sa, markSameGenerationBag as Sc, DeploymentEventsStore as Si, stackInstanceIdOf as Sl, recordUnderIdIsNotOwn as Sn, malformedDriftResourcePropertiesWarning as So, parseMappingFile as Sr, findActionableSilentDrops as Ss, makeCanonicalizePropertiesFn as St, runDockerStreaming as Su, readContributorInsightsSpec as T, refuseUnreadableCdkCrossAccountRefs as Ta, snapshotPassProvenance as Tc, markDeleteStarted as Ti, acceptedCreateOnlyDropsOf as Tl, seedsDeleteFirstGuard as Tn, malformedLocalOutputsWarning as To, destroyStackRecordsView as Tr, withoutSilentDropProperties as Ts, pendingRequestCount as Tt, getDockerImageBySourceHash as Tu, planTimeToLive as U, regionLessSecretName as Ua, DYNAMIC_REFERENCE_TOKEN_SCAN as Uc, isCustomResourceType as Ui, stringifyValue as Ul, computeParameterTaint as Un, refuseMalformedNestedChildOutputs as Uo, supersededResourcesOf as Ur, configStringRefusal as Us, dropFailedCommands as Ut, MIGRATE_TMP_PREFIX as Uu, isTtlAlreadyDisabled as V, classifyReplaySecretRegion as Va, withPhysicalNameCopies as Vc, TemplateNoEchoReresolver as Vi, AssetPublisher as Vl, retiredNameGenerationsLeaving as Vn, previewableOrphanRecords as Vo, supersededHeldByOtherTypeWarning as Vr, configBooleanRefusal as Vs, withNestedStackContext as Vt, CFN_TEMPLATE_BODY_LIMIT as Vu, readTtlSpec as W, coerceParameterTypedValue as Wa, dynamicReferenceTokens as Wc, getCurrentResourceSecrets as Wi, WorkGraph as Wl, namesAnyDeclaredParameter as Wn, refuseMalformedOrphanRecords as Wo, withoutSuperseded as Wr, readConfigString as Ws, dropFailedHint as Wt, findLargeInlineResources as Wu, getPriorAttempts as X, carriesFetchableDynamicReference as Xa, recordNestedStackParameterExpressions as Xc, slowCcOperationTimeoutMs as Xi, BOOTSTRAP_MARKER_PREFIX as Xl, secretBearing as Xn, refuseMalformedOutputsForDestroy as Xo, completedReplayEntries as Xr, templateResourceTypes as Xs, formatResourceLine as Xt, canonicalizeRegion as Xu, isTruthyCfnBoolean as Y, carriesDynamicReference as Ya, inheritNestedStackParameterAssociations as Yc, CloudControlProvider as Yi, AssetModeResolver as Yl, exportAliasCollisionScrubWarning as Yn, refuseMalformedOutputs as Yo, createReadOnlyAttributeHealerFactory as Yr, prefetchCreateOnlyPropertyPaths as Ys, sameJournaledOrphans as Yt, PARTITION_TABLE as Yu, markRefusedBeforeApplying as Z, isNamelessDynamicReferenceError as Za, recoverMaskedOutput as Zc, onlySecretReferencesDiffer as Zi, assertAssetBucketRegion as Zl, secretBearingStateKeyWarning as Zn, refuseMalformedResourceAttributesForOrphan as Zo, journaledOrphanPrintingBag as Zr, describeTypeWithThrottleRetry as Zs, chunks as Zt, derivePartitionAndUrlSuffix as Zu, streamMemberRefusals as _, isSettledInstanceState as _a, readbackPathFor as _c, resolveBucketRegion as _d, ledgerForStack as _i, CrossPrefixScanCache as _l, isJournaledOrphan as _n, hasReadableOrphans as _o, rollbackOrphanIds as _r, repairMalformedResourcesForReadOnly as _s, withResourceDeadline as _t, partitionSensitiveEnv as _u, isProtectionValueActive as a, isWaitAbandonedError as aa, DagBuilder as ac, hasOwnKey as ad, stateSecretNameNeedles as ai, recordMaskOnlyValuesIn as al, refuseRefactorMarker as an, withSharedDrainBudget as ao, collectPublishedOutputNames as ar, refuseMalformedResourcePropertiesForDrift as as, childTemplateLoader as at, buildDenyExternalAccessPolicy as au, CONTRIBUTOR_INSIGHTS_KEY as b, s3BucketDualStackDomainName as ba, valueAtCoordinate as bc, acquireIdempotencyToken as bi, isAccessDenied$1 as bl, planRollback as bn, isReadableOrphanRecord as bo, looselyEqual as br, unreadableResourceEntries as bs, keptWholeReasonText as bt, redactedDockerCause as bu, DynamoDBGlobalTableProvider as c, ec2InstanceProtectionSite as ca, isMarkedCoordinate as cc, ownValue as cd, PRE_DELETE_SNAPSHOT_TYPES as ci, recordProvenPublicExpression as cl, hasPendingMovesOut as cn, declaresNoEcho as co, DEFAULT_RESOURCE_TIMEOUT_MS as cr, refuseMalformedResourcesForDeploy as cs, listNestedTemplateRows as ct, describeDockerCapturedOutput as cu, declaredStreamPolicyMember as d, reDisableInstanceApiTermination as da, maskWholeValue as dc, displayAssemblyPath as dd, createPreDeleteFinalSnapshot as di, isSingleDynamicReferenceToken as dl, refusePendingMovesOut as dn, STATE_RESOURCES_MALFORMED as do, constructPathOf as dr, refuseMalformedState as ds, conditionFingerprint as dt, dockerSpawnEnvWithSensitive as du, UNSPECIFIED_SKIP_REASON as ea, ecsServiceLaunchTypeSetOrChanged as ec, processStackMessages as ed, orphanRecordsPrintingBag as ei, recordPhysicalNameCopy as el, withApiLimit as en, cfnRefValueFromPhysicalId as eo, exportNameNoEchoParameters as er, refuseMalformedResourceEntriesForDestroy as es, crossStackOutputProvenanceSource as et, isCrossRegionRedirect as eu, declaredStreamTagsMember as f, reEnableInstanceApiTermination as fa, maskedLeafCoordinatesOf as fc, renderAssemblyPathEscape as fd, effectiveDeletionPolicy as fi, LockManager as fl, replayFailedOperations as fn, UNREADABLE_ORPHANS_CONTAINER_ROW as fo, findDestructiveChanges as fr, repairMalformedOrphanRecordsForReadOnly as fs, conditionInputsFrom as ft, finchSecretArgvRefusal as fu, streamDeclaresTags as g, poisonRenderedSpellingsCollidingIn as ga, passedNoEchoParametersOf as gc, clearBucketRegionCache as gd, earliestDefined as gi, CrossPrefixReadError as gl, demoteSupersededOrphans as gn, displayLogicalId as go, movedToHint as gr, repairMalformedResourcePropertiesForReadOnly as gs, enclosingDeadlineRemainingMs as gt, isMalformedEnvKey as gu, streamDeclaresPolicy as h, IntrinsicFunctionResolver as ha, noEchoOutputsComparison as hc, injectedAwsRegionValue as hd, unsupportedFinalSnapshotError as hi, rebuildClientForBucketRegion as hl, recordAfterRollbackUpdate as hn, deployRefusesOrphanRowsReason as ho, hintSidesOf as hr, repairMalformedResourceEntriesForReadOnly as hs, enclosingDeadlineExpired as ht, isDockerClientEnvKey as hu, PROTECTION_PROPERTY_BY_TYPE as i, withIndeterminateGuard as ia, sameLambdaFunctionAddress as ic, defineOwnKey as id, secretNamedRecordNeedles as ii, recordMaskOnlyValue as il, refactorMarkerRefusalMessage as in, parseWebACLArn as io, collectDeclaredOutputNames as ir, refuseMalformedResourcePropertiesForDestroy as is, serviceTokenBlockingReason as it, validateContainerRepoName as iu, compensateRemovedDeletionProtection as j, assertFlagRoleArn as ja, printingCorpusOf as jc, tagMapAsList as ji, importableOutputKeys as jl, isRedactedRecordedValue as jn, malformedOrphansRefusalMessage as jo, gray as jr, isStatefulRecreateTargetForReplace as js, displacedPhysicalIdShown as jt, resolveApp as ju, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as k, recordedReferenceRegions as ka, literalSplitDelimitersOf as kc, readTagList as ki, hasReasonlessBaselineRefusal as kl, inheritProducerRegions as kn, malformedOrphanRecordsWarning as ko, bold as kr, shownType as ks, NESTED_PENDING_PARENT_REASON as kt, getLegacyStateBucketName as ku, STREAM_POLICY_KEY as l, isTerminationProtectionPropagationError as la, maskAtCoordinates as lc, absoluteAssemblyPathEscape as ld, buildFinalSnapshotIdentifier as li, wholeStringLeavesOf as ll, pendingMovesOutOf as ln, JSON_LISTING_HOLE_VALUE as lo, DEFAULT_RESOURCE_WARN_AFTER_MS as lr, refuseMalformedResourcesForDestroy as ls, renderNestedTemplateTreeDefect as lt, describeDockerExecFailure as lu, reverseMapStreamPolicy as m, INTRINSIC_KEYS as ma, noEchoLeavesOf as mc, injectAwsRegion as md, refusesFinalSnapshot as mi, S3StateBackend as ml, removeProtectionTypeList as mn, accountArgs as mo, findRefactorHints as mr, repairMalformedOutputsForReadOnly as ms, readRecordedConditionVerdicts as mt, getDockerCmd as mu, recordedProtectionEvidence as n, deleteLeftInPlace as na, canonicalLambdaFunctionName as nc, parseFailureDebugDetail as nd, secretNamePrintingBags as ni, carriesSecretMask as nl, readRefactorMarkerOnce as nn, lacksRecordedTableArn as no, isWholeDynamicReferenceValue as nr, refuseMalformedResourceEntriesForImportSave as ns, deferredServiceTokenWarning as nt, readBootstrapMarkerBody as nu, perType as o, markWaitAbandoned as oa, TemplateParser as oc, hasPlainPrototype$1 as od, storedSecretNameNeedles as oi, recordNoEchoAttributeValues as ol, sameMove as on, parameterInputsFor as oo, isExportAliasCollision as or, refuseMalformedResourcePropertiesForExport as os, findNestedTemplateTreeDefect as ot, buildDockerImage as ou, planStreamMemberOps as p, DiffCalculator as pa, noEchoCoordinatesOf as pc, resolveAssemblyPath as pd, isFinalSnapshotError as pi, isLockInfoExpired as pl, replayRollback as pn, UNREADABLE_RESOURCES_MAP_ROW as po, formatDestructiveChange as pr, repairMalformedOrphansForReadOnly as ps, parentSuppliedValues as pt, formatDockerLoginError as pu, S3_AUTO_DELETE_OBJECTS_TAG as q, getAccountInfo as qa, spelledKeysOf as qc, applyCustomResourceResponseExpiration as qi, loadPublishableAssetManifest as ql, WITHHELD_NAME_DISPLAY as qn, refuseMalformedOrphansForDestroy as qo, noEchoExactEchoLeavesOf as qr, requireConfigObject as qs, loadJournaledOrphans as qt, decodeListingKey as qu, recordedProtectionNote as r, deleteSkipReason as ra, lambdaFunctionNameForMask as rc, utf8ByteLength as rd, secretNamedAttributeNamesOf as ri, provenPublicValue as rl, refactorMarkerMovesOf as rn, refStateLookupFromResource as ro, noEchoParameterValueSeed as rr, refuseMalformedResourceEntriesForOrphan as rs, findServiceTokenRefusals as rt, validateAssetBucketName as ru, readProtection as s, disableInstanceApiTermination as sa, canonicalCoordinates as sc, nullPrototypeRecord as sd, ATOMIC_FINAL_SNAPSHOT_TYPES as si, recordNoEchoParameterFreshValue as sl, updateRefactorMarker as sn, passedParameterClassesOf as so, bindingSkippedOutputs as sr, refuseMalformedResourcePropertiesForOrphan as ss, isAbsoluteAssetPath as st, resolveDockerContextDirectory as su, DeployEngine as t, deleteIndeterminateGuards as ta, emrClusterInstancesReplaced as tc, describeJsonParseFailure as td, secretNamePrintingBag as ti, splitGetAttStringForm as tl, readRefactorMarker as tn, isStalePlaceholderArnAttribute as to, exportNameSecretExposure as tr, refuseMalformedResourceEntriesForImport as ts, inheritedProvenanceForChildDiff as tt, parseBootstrapMarker as tu, STREAM_TAGS_KEY as u, observeThenDisableInstanceApiTermination as ua, maskReadbackAtCoordinates as uc, describeFileReadFailure as ud, ccRoutedFinalSnapshotError as ui, WHOLE_DYNAMIC_REFERENCE_PATTERN as ul, pendingMovesRefusalMessage as un, STATE_REGION_DIVERGED as uo, maskingRetryLogger as ur, refuseMalformedResourcesForExport as us, templateIdentity as ut, describeDockerFailure as uu, streamPolicyMatchesDeclared as v, s3BucketArn as va, readsNoEchoSource as vc, reserveStackCreateToken as vi, applyCrossPrefixScan as vl, isReplacementOrphan as vn, hasReadableOutputs as vo, withMovedTo as vr, unpreviewableOrphanRecords as vs, diffSecurity as vt, redactDockerArgvValues as vu, planIndexContributorInsightsOps as w, producerLookupOver as wa, recordReferenceProvenanceEntry as wc, isRefusedByName as wi, splitImportedOps as wl, resolveReplacementOldType as wn, malformedExportSourceWarning as wo, awaitInFlightSibling as wr, unwrittenCreateOnlyReplacement as ws, planOrphanAdoption as wt, AssetManifestLoader as wu, contributorInsightsRefusals as x, s3BucketRegionalDomainName as xa, liveMatchesUnresolvedTokenFrame as xc, DeploymentEventsReader as xi, isNotImplemented as xl, recheckFailedPlan as xn, isReadableResourceEntry as xo, mappingPairs as xr, withheldAccountClause as xs, mergeNoChangeOutputs as xt, runDockerForeground as xu, streamTagsMatchDeclared as y, s3BucketDomainName as ya, recordedNoEchoValuesOf as yc, withCreateTokenLedger as yi, crossPrefixDeniedWarning as yl, planFailedOps as yn, hasReadableResources as yo, isPairableType as yr, unreadableOrphanRecords as ys, isSecretBearingReferenceString as yt, redactedCause as yu, relayedIndexBusyDelete as z, envCredentialsAreAssumedRole as za, maskSecretsInText as zc, wouldReturnToSdkProvider as zi, renderPhaseTimings as zl, retiredAfterRollback as zn, malformedScrubResourceEntriesRefusalMessage as zo, removeSuperseded as zr, coerceCfnBoolean as zs, collectNestedChildUnaddressed as zt, warnDeprecatedNoPrefixCliFlag as zu };
53783
- //# sourceMappingURL=deploy-engine-CDjAtIrn.js.map
54770
+ export { computeImplicitDeleteEdges as $, coerceParameterTypedValue as $a, DYNAMIC_REFERENCE_TOKEN_SCAN as $c, applyCustomResourceResponseExpiration as $i, stringifyValue as $l, WITHHELD_NAME_DISPLAY as $n, refuseMalformedOrphanRecords as $o, noEchoExactEchoLeavesOf as $r, readConfigString as $s, lookupEachName as $t, MIGRATE_TMP_PREFIX as $u, beginDeleteWait as A, s3BucketRegionalDomainName as Aa, valueAtCoordinate as Ac, isRefusedByName as Ai, isAccessDenied$1 as Al, resolveReplacementOldType as An, isReadableResourceEntry as Ao, awaitInFlightSibling as Ar, withheldAccountClause as As, displacedOpClause as At, redactedDockerCause as Au, waitForIndexesSettled as B, assertFlagRoleArn as Ba, logOnlyValueCount as Bc, stringifyIfAssigned as Bi, hasUnverifiableParameterRefusal as Bl, updatePartialMessage as Bn, malformedOrphansRefusalMessage as Bo, yellow as Br, isStatefulRecreateTargetForReplace as Bs, getCurrentNestedStackContext as Bt, loadCdkJson as Bu, planContributorInsightsOp as C, withoutUnsettledProperties as Ca, noEchoCoordinatesOf as Cc, resolveAssemblyPath as Cd, ledgerForStack as Ci, isLockInfoExpired as Cl, isJournaledOrphan as Cn, accountArgs as Co, rollbackOrphanIds as Cr, repairMalformedOutputsForReadOnly as Cs, makeSiblingClaimReader as Ct, formatDockerLoginError as Cu, reverseMapTableContributorInsights as D, s3BucketArn as Da, readbackPathFor as Dc, resolveBucketRegion as Dd, DeploymentEventsReader as Di, CrossPrefixScanCache as Dl, recheckFailedPlan as Dn, hasReadableOutputs as Do, mappingPairs as Dr, unpreviewableOrphanRecords as Ds, keptForRetainedRecord as Dt, partitionSensitiveEnv as Du, reverseMapIndexContributorInsights as E, isSettledInstanceState as Ea, passedNoEchoParametersOf as Ec, clearBucketRegionCache as Ed, acquireIdempotencyToken as Ei, CrossPrefixReadError as El, planRollback as En, hasReadableOrphans as Eo, looselyEqual as Er, repairMalformedResourcesForReadOnly as Es, resolvePendingCloudControlRequests as Et, isMalformedEnvKey as Eu, DELETE_INDEX_WAIT_PROCEED_NOTE as F, keepHeldTokenProvenance as Fa, snapshotPassProvenance as Fc, readTagList as Fi, acceptedCreateOnlyDropsOf as Fl, inheritProducerRegions as Fn, malformedLocalResourceEntriesWarning as Fo, bold as Fr, NO_CC_HANDLERS_REASON as Fs, recordDisplacedSkips as Ft, getDockerImageBySourceHash as Fu, sendTtlWaitingOutRateLimit as G, AWS_CREDENTIAL_ENV_KEYS as Ga, unionOfSecretBags as Gc, wouldReturnToSdkProvider as Gi, orphansCarriedFrom as Gl, retiredAfterRollback as Gn, malformedResourceEntriesWarning as Go, removeSuperseded as Gr, isWarmThroughputDecrease as Gs, isHandledOrphan as Gt, resolveStateBucketWithDefault as Gu, isTtlRateLimited as H, explicitRoleArnOrThrow as Ha, recordLogOnlyParameterValue as Hc, ProviderRegistry as Hi, importableOutputs as Hl, nameGenerationCarriedFrom as Hn, malformedOutputsRefusalMessage as Ho, deleteSupersededEntry as Hr, renderStatefulReason as Hs, deleteJournaledOrphans as Ht, resolveAutoAssetStorage as Hu, INDEX_SETTLE_POLL_INTERVAL_MS as I, outputReferenceProvenanceOf as Ia, carryLogOnlyValues as Ic, refuseMalformedDesiredTags as Ii, describeRegionValueKind as Il, REDACTED_DELETE_ADDRESS_SKIP_REASON as In, malformedLocalResourcesWarning as Io, cyan as Ir, hasNoCloudControlHandlers as Is, revertNestedChildFromJournal as It, Synthesizer as Iu, hasCdkAutoDeleteTag as J, envCredentialsAreAssumedRole as Ja, maskSecretsInError as Jc, readsNoEchoDeleteValues as Ji, PhaseClock as Jl, withNameGenerationReached as Jn, malformedScrubResourceEntriesRefusalMessage as Jo, supersededHolderOf as Jr, coerceCfnBoolean as Js, makeForeignHolderScan as Jt, stateBucketExistenceConfirmed as Ju, ECR_AUTO_DELETE_IMAGES_TAG as K, applyCallerIdentityCredentials as Ka, createSecretMasker as Kc, waitForLambdaFunctionActive as Ki, shouldRetainResource as Kl, retiredNameGenerationsAfter as Kn, malformedResourcePropertiesWarning as Ko, supersededAfterRollback as Kr, toCfnInteger as Ks, journaledOrphanLines as Kt, resolveStateBucketWithDefaultAndSource as Ku, deleteTableWithIndexBusyRetry as L, recordedOutputReferenceRegions as La, createUnionSecretMasker as Lc, tagMapAsList as Li, exportNamesCarriedFrom as Ll, isRedactedRecordedValue as Ln, malformedOrphanRecordsRefusalMessage as Lo, gray as Lr, findReplacedReadersOfRecreateTargets as Ls, revertedNestedRowIds as Lt, synthesisStatusMessage as Lu, deleteBudgetKey as M, resolveDynamicReferences as Ma, markSameGenerationBag as Mc, DBPROXY_TAGS_WHAT as Mi, stackInstanceIdOf as Ml, orphanNeedsIdentity as Mn, malformedExportNamesWarning as Mo, getStackRecords as Mr, findSilentDropProperties as Ms, dropSettledNestedJournals as Mt, runDockerStreaming as Mu, resolveDynamoDbDeleteBudgetClock as N, producerLookupOver as Na, redactForState as Nc, DBPROXY_TAG_OPTIONS as Ni, withStackInstanceIdWithheld as Nl, findNestedStackTypeChanges as Nn, malformedExportSourceWarning as No, withStackRecords as Nr, unwrittenCreateOnlyReplacement as Ns, getNestedRevertRun as Nt, warnFinchArgvExposure as Nu, stripIndexContributorInsights as O, s3BucketDomainName as Oa, readsNoEchoSource as Oc, DeploymentEventsStore as Oi, applyCrossPrefixScan as Ol, recordUnderIdIsNotOwn as On, hasReadableResources as Oo, parseMappingFile as Or, unreadableOrphanRecords as Os, recordRetainedForReadoption as Ot, redactDockerArgvValues as Ou, resolveDynamoDbDeleteBudgetMs as P, refuseUnreadableCdkCrossAccountRefs as Pa, recordReferenceProvenanceEntry as Pc, planTagDiff as Pi, splitImportedOps as Pl, getCurrentProducerRegions as Pn, malformedLocalOutputsWarning as Po, replacedDeleteFailureVerdict as Pr, withoutSilentDropProperties as Ps, nestedChildStackName as Pt, AssetManifestLoader as Pu, IMPLICIT_DELETE_DEPENDENCIES as Q, regionLessSecretName as Qa, withoutPhysicalNameCopies as Qc, CUSTOM_RESOURCE_RESPONSE_LIFECYCLE_RULE_ID as Qi, isSensitiveAttributeName as Ql, resourcesNamingDeclaredParameter as Qn, refuseMalformedNestedChildOutputs as Qo, noEchoComparisonForTemplate as Qr, configStringRefusal as Qs, isAccessDeniedError as Qt, CFN_TEMPLATE_URL_LIMIT as Qu, maskedLogger as R, recordedReferenceRegions as Ra, hasMaskableValues as Rc, tagPlanWarning as Ri, hasReadableExportSet as Rl, redactedDeleteAddressFields as Rn, malformedOrphanRecordsWarning as Ro, green as Rr, shownType as Rs, withNestedRevertRun as Rt, getDefaultStateBucketName as Ru, indexDeclaresContributorInsights as S, withUnsettledProperties as Sa, maskedLeafCoordinatesOf as Sc, renderAssemblyPathEscape as Sd, earliestDefined as Si, LockManager as Sl, demoteSupersededOrphans as Sn, UNREADABLE_RESOURCES_MAP_ROW as So, movedToHint as Sr, repairMalformedOrphansForReadOnly as Ss, makeCanonicalizePropertiesFn as St, finchSecretArgvRefusal as Su, readContributorInsightsSpec as T, poisonRenderedSpellingsCollidingIn as Ta, noEchoOutputsComparison as Tc, injectedAwsRegionValue as Td, withCreateTokenLedger as Ti, rebuildClientForBucketRegion as Tl, planFailedOps as Tn, displayLogicalId as To, isPairableType as Tr, repairMalformedResourcePropertiesForReadOnly as Ts, pendingRequestCount as Tt, isDockerClientEnvKey as Tu, planTimeToLive as U, isIamRoleArn as Ua, recordLogOnlyValue as Uc, ccBrokenReason as Ui, isReadableBag as Ul, nameGenerationHighWaterOf as Un, malformedOutputsWarning as Uo, holdsSupersededResources as Ur, WARM_THROUGHPUT_MEMBERS as Us, dropFailedCommands as Ut, resolveCaptureObservedState as Uu, isTtlAlreadyDisabled as V, assertSendableRoleArn as Va, printingCorpusOf as Vc, CC_BROKEN_REASON as Vi, importableOutputKeys as Vl, updatePartialReason as Vn, malformedOrphansWarning as Vo, addSuperseded as Vr, isStatefulRecreateTargetSync as Vs, withNestedStackContext as Vt, resolveApp as Vu, readTtlSpec as W, sendableAssumeRoleCommand as Wa, shareLogOnlyValues as Wc, isCustomResource as Wi, orphansAfterRollback as Wl, nameScopeOf as Wn, malformedRenderedContainersWarning as Wo, isSupersededResourceRecord as Wr, coerceWarmThroughput as Ws, dropFailedHint as Wt, resolveSkipPrefix as Wu, getPriorAttempts as X, classifyReplaySecretRegion as Xa, scrubResourceRecord as Xc, getCurrentResourceSecrets as Xi, timePhase as Xl, namesAnyDeclaredParameter as Xn, previewableOrphanRecords as Xo, withoutSuperseded as Xr, configBooleanRefusal as Xs, formatResourceLine as Xt, ssmResolvedValueType as Xu, isTruthyCfnBoolean as Y, classifyRecordedSecretRegion as Ya, maskSecretsInText as Yc, isCustomResourceType as Yi, renderPhaseTimings as Yl, computeParameterTaint as Yn, malformedStateRefusalMessage as Yo, supersededResourcesOf as Yr, coerceCfnInteger as Ys, sameJournaledOrphans as Yt, warnDeprecatedNoPrefixCliFlag as Yu, markRefusedBeforeApplying as Z, producerRegionsFromState as Za, withPhysicalNameCopies as Zc, withPrintingSecrets as Zi, AssetPublisher as Zl, reachableDivergentParameters as Zn, refuseDivergentRecordRegionForDestroy as Zo, noEchoAttributeNamesOf as Zr, configIntegerRefusal as Zs, chunks as Zt, CFN_TEMPLATE_BODY_LIMIT as Zu, streamMemberRefusals as _, reDisableInstanceApiTermination as _a, canonicalCoordinates as _c, nullPrototypeRecord as _d, createPreDeleteFinalSnapshot as _i, recordNoEchoParameterFreshValue as _l, withUnprovenUnsettled as _n, declaresNoEcho as _o, constructPathOf as _r, refuseMalformedResourcesForDeploy as _s, withResourceDeadline as _t, resolveDockerContextDirectory as _u, isProtectionValueActive as a, RollbackInlinePolicyWriters as aa, templateResourceTypes as ac, PARTITION_TABLE as ad, namingSecretsWithRecordedNoEcho as ai, inheritNestedStackParameterAssociations as al, refuseRefactorMarker as an, carriesFetchableDynamicReference as ao, carriedExportAliasExposure as ar, refuseMalformedOutputsForDestroy as as, childTemplateLoader as at, AssetModeResolver as au, CONTRIBUTOR_INSIGHTS_KEY as b, INTRINSIC_KEYS as ba, maskReadbackAtCoordinates as bc, describeFileReadFailure as bd, refusesFinalSnapshot as bi, WHOLE_DYNAMIC_REFERENCE_PATTERN as bl, equalModuloMask as bn, STATE_RESOURCES_MALFORMED as bo, findRefactorHints as br, refuseMalformedState as bs, keptWholeReasonText as bt, describeDockerFailure as bu, DynamoDBGlobalTableProvider as c, deleteLeftInPlace as ca, blockDeviceMappingsDifferOnlyInDeleteOnTermination as cc, AssemblyReader as cd, secretNamePrintingBags as ci, physicalNameCopiesOf as cl, hasPendingMovesOut as cn, AWS_NO_VALUE as co, isWholeDynamicReferenceValue as cr, refuseMalformedResourceEntriesForDeploy as cs, listNestedTemplateRows as ct, ensureAssetStorage as cu, declaredStreamPolicyMember as d, isWaitAbandonedError as da, emrClusterInstancesReplaced as dc, describeJsonParseFailure as dd, stateSecretNameNeedles as di, splitGetAttStringForm as dl, refusePendingMovesOut as dn, lacksRecordedTableArn as do, collectPublishedOutputNames as dr, refuseMalformedResourceEntriesForImportSave as ds, conditionFingerprint as dt, parseBootstrapMarker as du, customResourceResponseExpirationWarning as ea, replayWarn as ec, findLargeInlineResources as ed, noEchoParameterNamesOf as ei, dynamicReferenceTokens as el, withApiLimit as en, isUnboundTemplateParameter as eo, displayTextOrWithheld as er, refuseMalformedOrphanRecordsForDestroy as es, crossStackOutputProvenanceSource as et, WorkGraph as eu, declaredStreamTagsMember as f, markWaitAbandoned as fa, canonicalLambdaFunctionName as fc, parseFailureDebugDetail as fd, storedSecretNameNeedles as fi, carriesSecretMask as fl, replayFailedOperations as fn, refStateLookupFromResource as fo, isExportAliasCollision as fr, refuseMalformedResourceEntriesForOrphan as fs, conditionInputsFrom as ft, readBootstrapMarkerBody as fu, streamDeclaresTags as g, observeThenDisableInstanceApiTermination as ga, TemplateParser as gc, hasPlainPrototype$1 as gd, ccRoutedFinalSnapshotError as gi, recordNoEchoAttributeValues as gl, settleUnsettledPrevious as gn, passedParameterClassesOf as go, maskingRetryLogger as gr, refuseMalformedResourcePropertiesForOrphan as gs, enclosingDeadlineRemainingMs as gt, buildDockerImage as gu, streamDeclaresPolicy as h, isTerminationProtectionPropagationError as ha, DagBuilder as hc, hasOwnKey as hd, buildFinalSnapshotIdentifier as hi, recordMaskOnlyValuesIn as hl, recordAfterRollbackUpdate as hn, parameterInputsFor as ho, DEFAULT_RESOURCE_WARN_AFTER_MS as hr, refuseMalformedResourcePropertiesForExport as hs, enclosingDeadlineExpired as ht, buildDenyExternalAccessPolicy as hu, PROTECTION_PROPERTY_BY_TYPE as i, unchangedBehindSecretReference as ia, prefetchCreateOnlyPropertyPaths as ic, expectedOwnerParam as id, maskEventTextWithBoundBags as ii, identityKeyFor as il, refactorMarkerRefusalMessage as in, carriesDynamicReference as io, secretSafeKeyDisplay as ir, refuseMalformedOutputs as is, serviceTokenBlockingReason as it, rewriteTemplateAssetReferences as iu, compensateRemovedDeletionProtection as j, s3BucketWebsiteUrl as ja, liveMatchesUnresolvedTokenFrame as jc, markDeleteStarted as ji, isNotImplemented as jl, seedsDeleteFirstGuard as jn, malformedDriftResourcePropertiesWarning as jo, destroyStackRecordsView as jr, findActionableSilentDrops as js, displacedPhysicalIdShown as jt, runDockerForeground as ju, DYNAMODB_DELETE_MIN_RESOURCE_TIMEOUT_MS as k, s3BucketDualStackDomainName as ka, recordedNoEchoValuesOf as kc, extractDeploymentEventError as ki, crossPrefixDeniedWarning as kl, replacementNeverSwapped as kn, isReadableOrphanRecord as ko, proposeRenames as kr, unreadableResourceEntries as ks, NESTED_PENDING_PARENT_REASON as kt, redactedCause as ku, STREAM_POLICY_KEY as l, deleteSkipReason as la, dbInstanceEngineChangeIsInPlace as lc, StageLoadError as ld, secretNamedAttributeNamesOf as li, recordAttributeIdCopy as ll, pendingMovesOutOf as ln, cfnRefValueFromPhysicalId as lo, noEchoParameterValueSeed as lr, refuseMalformedResourceEntriesForDestroy as ls, renderNestedTemplateTreeDefect as lt, getBootstrapMarkerKey as lu, reverseMapStreamPolicy as m, ec2InstanceProtectionSite as ma, sameLambdaFunctionAddress as mc, defineOwnKey as md, PRE_DELETE_SNAPSHOT_TYPES as mi, recordMaskOnlyValue as ml, removeProtectionTypeList as mn, withSharedDrainBudget as mo, DEFAULT_RESOURCE_TIMEOUT_MS as mr, refuseMalformedResourcePropertiesForDrift as ms, readRecordedConditionVerdicts as mt, validateContainerRepoName as mu, recordedProtectionEvidence as n, slowCcOperationTimeoutMs as na, requireConfigObject as nc, CUSTOM_RESOURCE_RESPONSE_OBJECT_DESCRIPTION as nd, completedReplayEntries as ni, pathCrossesDottedKey as nl, readRefactorMarkerOnce as nn, getAccountInfo as no, secretBearing as nr, refuseMalformedOrphansForDestroy as ns, deferredServiceTokenWarning as nt, createAssetRedirectResolver as nu, perType as o, UNSPECIFIED_SKIP_REASON as oa, describeTypeWithThrottleRetry as oc, canonicalizeRegion as od, orphanRecordsPrintingBag as oi, recordNestedStackParameterExpressions as ol, sameMove as on, isNamelessDynamicReferenceError as oo, exportNameNoEchoParameters as or, refuseMalformedResourceAttributesForOrphan as os, findNestedTemplateTreeDefect as ot, BOOTSTRAP_MARKER_PREFIX as ou, planStreamMemberOps as p, disableInstanceApiTermination as pa, lambdaFunctionNameForMask as pc, utf8ByteLength as pd, ATOMIC_FINAL_SNAPSHOT_TYPES as pi, provenPublicValue as pl, replayRollback as pn, parseWebACLArn as po, bindingSkippedOutputs as pr, refuseMalformedResourcePropertiesForDestroy as ps, parentSuppliedValues as pt, validateAssetBucketName as pu, S3_AUTO_DELETE_OBJECTS_TAG as q, callerEnvCredentials as qa, errorCauseChain as qc, TemplateNoEchoReresolver as qi, stackInstanceIdCarriedFrom as ql, retiredNameGenerationsLeaving as qn, malformedResourcesWarning as qo, supersededHeldByOtherTypeWarning as qr, toFiniteNumber as qs, loadJournaledOrphans as qt, resolveUseCdkBootstrapAssets as qu, recordedProtectionNote as r, onlySecretReferencesDiffer as ra, requireConfigString as rc, decodeListingKey as rd, journaledOrphanPrintingBag as ri, spelledKeysOf as rl, refactorMarkerMovesOf as rn, isImpossibleEmptyStoredAttribute as ro, secretBearingStateKeyWarning as rr, refuseMalformedOrphansForOrphan as rs, findServiceTokenRefusals as rt, loadPublishableAssetManifest as ru, readProtection as s, deleteIndeterminateGuards as sa, withRetry as sc, derivePartitionAndUrlSuffix as sd, secretNamePrintingBag as si, recoverMaskedOutput as sl, updateRefactorMarker as sn, keepsSecretReferenceToken as so, exportNameSecretExposure as sr, refuseMalformedResourceEntries as ss, isAbsoluteAssetPath as st, assertAssetBucketRegion as su, DeployEngine as t, CloudControlProvider as ta, requireConfigArray as tc, uploadCfnTemplate as td, createReadOnlyAttributeHealerFactory as ti, isUncertifiedBaselineMaskPosition as tl, readRefactorMarker as tn, parameterTypeMayLoseSecretIdentity as to, exportAliasCollisionScrubWarning as tr, refuseMalformedOrphans as ts, inheritedProvenanceForChildDiff as tt, buildAssetRedirectMap as tu, STREAM_TAGS_KEY as u, withIndeterminateGuard as ua, ecsServiceLaunchTypeSetOrChanged as uc, processStackMessages as ud, secretNamedRecordNeedles as ui, recordPhysicalNameCopy as ul, pendingMovesRefusalMessage as un, isStalePlaceholderArnAttribute as uo, collectDeclaredOutputNames as ur, refuseMalformedResourceEntriesForImport as us, templateIdentity as ut, isCrossRegionRedirect as uu, streamPolicyMatchesDeclared as v, reEnableInstanceApiTermination as va, isMarkedCoordinate as vc, ownValue as vd, effectiveDeletionPolicy as vi, recordProvenPublicExpression as vl, calculateResourceDrift as vn, JSON_LISTING_HOLE_VALUE as vo, findDestructiveChanges as vr, refuseMalformedResourcesForDestroy as vs, diffSecurity as vt, describeDockerCapturedOutput as vu, planIndexContributorInsightsOps as w, IntrinsicFunctionResolver as wa, noEchoLeavesOf as wc, injectAwsRegion as wd, reserveStackCreateToken as wi, S3StateBackend as wl, isReplacementOrphan as wn, deployRefusesOrphanRowsReason as wo, withMovedTo as wr, repairMalformedResourceEntriesForReadOnly as ws, planOrphanAdoption as wt, getDockerCmd as wu, contributorInsightsRefusals as x, unsettledPropertiesOf as xa, maskWholeValue as xc, displayAssemblyPath as xd, unsupportedFinalSnapshotError as xi, isSingleDynamicReferenceToken as xl, undeclaredEmptyObservedKeys as xn, UNREADABLE_ORPHANS_CONTAINER_ROW as xo, hintSidesOf as xr, repairMalformedOrphanRecordsForReadOnly as xs, mergeNoChangeOutputs as xt, dockerSpawnEnvWithSensitive as xu, streamTagsMatchDeclared as y, DiffCalculator as ya, maskAtCoordinates as yc, absoluteAssemblyPathEscape as yd, isFinalSnapshotError as yi, wholeStringLeavesOf as yl, equalModuloMarkedMask as yn, STATE_REGION_DIVERGED as yo, formatDestructiveChange as yr, refuseMalformedResourcesForExport as ys, isSecretBearingReferenceString as yt, describeDockerExecFailure as yu, relayedIndexBusyDelete as z, applyRoleArnIfSet as za, literalSplitDelimitersOf as zc, definedAttributes as zi, hasReasonlessBaselineRefusal as zl, redactedDeleteAddressSkip as zn, malformedOrphanRowsKeptWarning as zo, red as zr, MULTI_REGION_RECREATE_BLOCKED_TYPES as zs, collectNestedChildUnaddressed as zt, getLegacyStateBucketName as zu };
54771
+ //# sourceMappingURL=deploy-engine-tQ0aqZMo.js.map